From 1fd877bdae047bc8a54f3a14c1468d10b8e83efa Mon Sep 17 00:00:00 2001 From: Jeena Date: Thu, 24 Sep 2026 06:54:11 +0900 Subject: [PATCH] container: Recreate containers created from an outdated image Rebuilding the image no longer removes existing containers, and nothing checked whether a container still matched the current image, so stale containers kept running old builds. This surfaced when the pi installer refused to install into the container home because the old image's root-owned, system-wide pi still shadowed it. Compare image IDs before reuse and recreate the container when they differ, logging why. --- agent-container.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/agent-container.py b/agent-container.py index 2c06fe7..ba76ea3 100755 --- a/agent-container.py +++ b/agent-container.py @@ -161,6 +161,12 @@ class AgentContainer: if not self.image_exists(): self.build_image() + if self.container_exists() and not self._container_image_matches(): + logger.info( + "Recreating container: it was created from an outdated image" + ) + self.remove_container() + if not self.container_exists(): self.create_container() @@ -392,6 +398,24 @@ class AgentContainer: ] ) + def _container_image_matches(self) -> bool: + """Whether the existing container was created from the current image. + + After an image rebuild the old container keeps running the stale + image, so tools baked into previous builds (or missing from new + ones) linger. Comparing image IDs catches that.""" + container_image = subprocess.run( + ["docker", "container", "inspect", "-f", "{{.Image}}", self.container_name], + capture_output=True, + text=True, + ).stdout.strip() + current_image = subprocess.run( + ["docker", "image", "inspect", "-f", "{{.Id}}", self.IMAGE], + capture_output=True, + text=True, + ).stdout.strip() + return bool(container_image) and container_image == current_image + def start_container(self) -> bool: subprocess.run( ["docker", "start", self.container_name],