fix(docker_refresh): Skip recreation for unchanged images
This commit is contained in:
1 parent
48fe3f025e
commit
e12feae399
2 files changed
+65
-11
No files matched your search
+27
-8
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env -S uv run --script
|
||||
# /// script
|
||||
# dependencies = []
|
||||
# ///
|
||||
@@ -22,6 +22,7 @@ class Project:
|
||||
files: tuple[Path, ...]
|
||||
environment_files: tuple[Path, ...]
|
||||
services: set[str] = field(default_factory=set)
|
||||
running_images: dict[str, set[str]] = field(default_factory=dict)
|
||||
|
||||
def command(self) -> list[str]:
|
||||
command = [
|
||||
@@ -116,6 +117,7 @@ def discover_projects(containers: list[dict[str, Any]], selected_projects: set[s
|
||||
if (existing.directory, existing.files, existing.environment_files) != (project.directory, project.files, project.environment_files):
|
||||
raise ValueError(f"Project {name}: containers have inconsistent Compose file labels")
|
||||
existing.services.add(service)
|
||||
existing.running_images.setdefault(service, set()).add(container.get("Image") or "")
|
||||
return sorted(projects.values(), key=lambda project: project.name)
|
||||
|
||||
|
||||
@@ -148,13 +150,30 @@ def refresh_project(project: Project, dry_run: bool) -> None:
|
||||
services.append(name)
|
||||
if not services:
|
||||
return
|
||||
for arguments in (
|
||||
["pull", "--policy", "always", *services],
|
||||
["up", "--detach", "--no-deps", "--no-build", "--pull", "never", *services],
|
||||
):
|
||||
logging.info("%s", shlex.join([*command, *arguments]))
|
||||
if not dry_run:
|
||||
subprocess.run(args=[*command, *arguments], cwd=project.directory, check=True)
|
||||
pull_command = [*command, "pull", "--policy", "always", *services]
|
||||
logging.info("%s", shlex.join(pull_command))
|
||||
if not dry_run:
|
||||
subprocess.run(args=pull_command, cwd=project.directory, check=True)
|
||||
changed_services = []
|
||||
for name in services:
|
||||
result = subprocess.run(
|
||||
args=["docker", "image", "inspect", "--format", "{{.Id}}", configured_services[name]["image"]],
|
||||
check=True, capture_output=True, text=True, timeout=60,
|
||||
)
|
||||
image_id = result.stdout.strip()
|
||||
if not image_id:
|
||||
raise ValueError(f"Project {project.name}: image ID is missing for service {name}")
|
||||
if project.running_images.get(name) == {image_id}:
|
||||
logging.info("Skipping %s/%s: running image is up to date", project.name, name)
|
||||
else:
|
||||
changed_services.append(name)
|
||||
services = changed_services
|
||||
if not services:
|
||||
return
|
||||
up_command = [*command, "up", "--detach", "--no-deps", "--no-build", "--pull", "never", *services]
|
||||
logging.info("%s", shlex.join(up_command))
|
||||
if not dry_run:
|
||||
subprocess.run(args=up_command, cwd=project.directory, check=True)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
|
||||
Reference in new issue
Block a user