mirror of
https://github.com/acedanger/shell.git
synced 2026-03-24 19:11:48 -07:00
Compare commits
2 Commits
07d9cc825f
...
e3b89032d4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3b89032d4 | ||
|
|
06ee3dd672 |
@@ -9,7 +9,10 @@ Usage Examples:
|
||||
1. List all running containers:
|
||||
$ dm list
|
||||
|
||||
2. Update a specific project (pulls latest images and recreates containers):
|
||||
2. List only stacks with updates available:
|
||||
$ dm list --update
|
||||
|
||||
3. Update a specific project (pulls latest images and recreates containers):
|
||||
$ dm update media-server
|
||||
|
||||
3. Stop all projects (with confirmation prompt):
|
||||
@@ -171,7 +174,7 @@ def run_command(cmd, cwd, capture_output=False):
|
||||
return None
|
||||
|
||||
|
||||
def list_containers(projects):
|
||||
def list_containers(projects, show_updates_only=False):
|
||||
"""List running containers for all projects."""
|
||||
table = Table(title="Docker Containers", box=box.ROUNDED)
|
||||
table.add_column("Project", style="cyan", no_wrap=True)
|
||||
@@ -186,6 +189,11 @@ def list_containers(projects):
|
||||
|
||||
found_any = False
|
||||
for name, path in sorted(projects.items()):
|
||||
|
||||
# Buffer for project rows
|
||||
project_rows = []
|
||||
project_has_update = False
|
||||
|
||||
# Get running container names
|
||||
cmd = ["docker", "compose", "ps", "--format", "json"]
|
||||
res = run_command(cmd, path, capture_output=True)
|
||||
@@ -204,8 +212,6 @@ def list_containers(projects):
|
||||
if not c_name:
|
||||
continue
|
||||
|
||||
found_any = True
|
||||
|
||||
# Get version and update status
|
||||
version = "unknown"
|
||||
update_status = ""
|
||||
@@ -214,7 +220,7 @@ def list_containers(projects):
|
||||
norm_image = image
|
||||
tag = "latest"
|
||||
|
||||
# Remove tag if present (heuristic: split on last colon, if right side has no slashes)
|
||||
# Remove tag if present
|
||||
if ":" in norm_image:
|
||||
base, sep, t = norm_image.rpartition(":")
|
||||
if sep and "/" not in t:
|
||||
@@ -231,27 +237,21 @@ def list_containers(projects):
|
||||
if norm_image in diun_info:
|
||||
image_tags = diun_info[norm_image]
|
||||
|
||||
# Only proceed if we have info for this specific tag
|
||||
if tag in image_tags:
|
||||
info = image_tags[tag]
|
||||
# Try to get version from Diun labels first
|
||||
version = get_image_version(info.get("labels", {}))
|
||||
|
||||
# Check for updates
|
||||
# First get the Image ID of the running container
|
||||
inspect_id_cmd = ["docker", "inspect", c_name, "--format", "{{.Image}}"]
|
||||
inspect_id_res = run_command(inspect_id_cmd, path, capture_output=True)
|
||||
|
||||
if inspect_id_res and inspect_id_res.returncode == 0:
|
||||
image_id = inspect_id_res.stdout.strip()
|
||||
|
||||
# Now inspect the Image ID to get RepoDigests
|
||||
inspect_digest_cmd = ["docker", "inspect", image_id, "--format", "{{if .RepoDigests}}{{index .RepoDigests 0}}{{end}}"]
|
||||
inspect_digest_res = run_command(inspect_digest_cmd, path, capture_output=True)
|
||||
|
||||
if inspect_digest_res and inspect_digest_res.returncode == 0:
|
||||
running_digest_full = inspect_digest_res.stdout.strip()
|
||||
# running_digest is like name@sha256:hash
|
||||
if "@" in running_digest_full:
|
||||
running_digest = running_digest_full.split("@")[1]
|
||||
latest_digest = info.get("digest", "")
|
||||
@@ -259,6 +259,7 @@ def list_containers(projects):
|
||||
if latest_digest:
|
||||
if running_digest != latest_digest:
|
||||
update_status = "[bold red]Update Available[/bold red]"
|
||||
project_has_update = True
|
||||
else:
|
||||
update_status = "[green]Up to Date[/green]"
|
||||
else:
|
||||
@@ -266,7 +267,6 @@ def list_containers(projects):
|
||||
else:
|
||||
update_status = "[dim]Not Monitored[/dim]"
|
||||
|
||||
# If version is still unknown, try to get from running container labels
|
||||
if version in ("latest", "unknown"):
|
||||
inspect_cmd = ["docker", "inspect", c_name, "--format", "{{json .Config.Labels}}"]
|
||||
inspect_res = run_command(inspect_cmd, path, capture_output=True)
|
||||
@@ -277,13 +277,23 @@ def list_containers(projects):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
table.add_row(name, c_name, state, image, version, update_status)
|
||||
project_rows.append((name, c_name, state, image, version, update_status))
|
||||
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
|
||||
# If not hiding, OR if update, add to table
|
||||
if not show_updates_only or project_has_update:
|
||||
if project_rows:
|
||||
found_any = True
|
||||
for row in project_rows:
|
||||
table.add_row(*row)
|
||||
|
||||
if found_any:
|
||||
console.print(table)
|
||||
else:
|
||||
if show_updates_only:
|
||||
console.print("[green]No updates available for running containers.[/green]")
|
||||
else:
|
||||
console.print("[yellow]No running containers found in managed projects.[/yellow]")
|
||||
|
||||
@@ -544,7 +554,8 @@ def main():
|
||||
dest="command", help="Command to execute")
|
||||
|
||||
# List command configuration
|
||||
subparsers.add_parser("list", help="List running containers")
|
||||
list_parser = subparsers.add_parser("list", help="List running containers")
|
||||
list_parser.add_argument("--update", action="store_true", help="Show only stacks that have updates available")
|
||||
|
||||
# Describe command configuration
|
||||
describe_parser = subparsers.add_parser("describe", help="Show details of a project's containers")
|
||||
@@ -596,7 +607,7 @@ def main():
|
||||
|
||||
# Dispatch commands
|
||||
if args.command == "list":
|
||||
list_containers(projects)
|
||||
list_containers(projects, show_updates_only=args.update)
|
||||
elif args.command == "describe":
|
||||
describe_project(projects, args.project)
|
||||
elif args.command == "volumes":
|
||||
|
||||
Reference in New Issue
Block a user