11import shutil
22import platform
33import os
4- from typing import List , Optional , Union , Dict
4+ from typing import List , Dict
55import subprocess
66
77from ..executor import Executor
@@ -36,7 +36,10 @@ def _remove_old_docker(exec_obj: Executor) -> None:
3636 log .info ("Checking for and removing old/conflicting Docker packages..." )
3737
3838 # Comprehensive query command to find packages that need removal
39- query_cmd = "dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runc | cut -f1"
39+ query_cmd = (
40+ "dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc "
41+ "podman-docker containerd runc | cut -f1"
42+ )
4043
4144 try :
4245 # Execute the query command as root to get the list of packages to remove
@@ -51,15 +54,17 @@ def _remove_old_docker(exec_obj: Executor) -> None:
5154 # 2. Construct the removal command
5255 remove_cmd = ["apt" , "remove" , "-y" ] + packages_to_remove
5356
54- log .warning (f"Removing the following old/conflicting packages: { ', ' .join (packages_to_remove )} " )
57+ log .warning (
58+ f"Removing the following old/conflicting packages: { ', ' .join (packages_to_remove )} "
59+ )
5560
5661 # Execute the removal command
57- # We allow check=False in case some packages are listed by dpkg but apt fails to find them, though unlikely here .
62+ # check=False: dpkg may list packages that apt can't find; we continue regardless .
5863 exec_obj .run (remove_cmd , force_sudo = True , check = True )
5964 log .success ("Old Docker packages successfully removed." )
6065
6166 except Exception as e :
62- log .warning (f "Failed to execute package removal query or removal. Continuing installation." )
67+ log .warning ("Failed to execute package removal query or removal. Continuing installation." )
6368 log .debug (f"Removal error: { e } " )
6469 # We don't halt here, as the subsequent installation step will fail if necessary.
6570
@@ -91,21 +96,25 @@ def install_docker_and_add_users(exec_obj: Executor, *users_to_add: str) -> None
9196 codename = os_info .get ("VERSION_CODENAME" ) # e.g., 'noble' or 'bookworm'
9297
9398 if not os_id or not codename :
94- log .critical ("Could not detect OS ID or Codename from /etc/os-release. Aborting Docker setup." )
99+ log .critical (
100+ "Could not detect OS ID or Codename from /etc/os-release. Aborting Docker setup."
101+ )
95102 raise RuntimeError ("Cannot proceed without distribution details." )
96103
97104 log .info (f"Detected OS: { os_id } , Codename: { codename } " )
98105
99106 keyrings_dir = "/etc/apt/keyrings"
100- docker_gpg_path = os .path .join (keyrings_dir , "docker.gpg" ) # Modern standard uses .gpg binary
107+ docker_gpg_path = os .path .join (keyrings_dir , "docker.gpg" )
101108 list_file = "/etc/apt/sources.list.d/docker.list"
102109
103110 exec_obj .run (f"mkdir -p { keyrings_dir } " , force_sudo = True )
104111
105112 if not os .path .exists (docker_gpg_path ):
106113 log .info (f"Downloading and adding Docker GPG key for { os_id } ." )
107- # Note: We use gpg --dearmor to ensure a binary .gpg file for /etc/apt/keyrings compatibility
108- curl_cmd = f"curl -fsSL https://download.docker.com/linux/{ os_id } /gpg | gpg --dearmor -o { docker_gpg_path } "
114+ curl_cmd = (
115+ f"curl -fsSL https://download.docker.com/linux/{ os_id } /gpg "
116+ f"| gpg --dearmor -o { docker_gpg_path } "
117+ )
109118 exec_obj .run (curl_cmd , force_sudo = True )
110119 # Ensure proper read permissions for apt
111120 exec_obj .run (f"chmod a+r { docker_gpg_path } " , force_sudo = True )
@@ -122,7 +131,10 @@ def install_docker_and_add_users(exec_obj: Executor, *users_to_add: str) -> None
122131 display_arch = arch
123132
124133 # 2. Interpolate the correct ID, codename and arch into the repository line
125- repo_line = f"deb [arch={ display_arch } signed-by={ docker_gpg_path } ] https://download.docker.com/linux/{ os_id } { codename } stable"
134+ repo_line = (
135+ f"deb [arch={ display_arch } signed-by={ docker_gpg_path } ]"
136+ f" https://download.docker.com/linux/{ os_id } { codename } stable"
137+ )
126138
127139 log .info (f"Using APT repository line: { repo_line } " )
128140 ensure_apt_repo (exec_obj , list_file , repo_line )
@@ -144,7 +156,7 @@ def install_docker_and_add_users(exec_obj: Executor, *users_to_add: str) -> None
144156
145157def _verify_docker_installation (exec_obj : Executor ) -> None :
146158 """
147- Runs a simple Docker command (like 'docker run hello-world') and cleans up the resulting image/container .
159+ Runs 'docker info' and 'docker run hello-world' to verify installation, then cleans up .
148160 """
149161 log .info ("Running post-installation verification test..." )
150162
@@ -212,7 +224,12 @@ def check_docker_volume_exists(exec_obj: Executor, volume_name: str) -> bool:
212224 log .info (f"Checking for existence of Docker volume: { volume_name } " )
213225 try :
214226 # Use 'docker volume ls -q -f name=...' to check existence silently
215- result = exec_obj .run (["docker" , "volume" , "ls" , "-q" , "-f" , f"name=^{ volume_name } $" ], check = True , force_sudo = True , run_quiet = True )
227+ result = exec_obj .run (
228+ ["docker" , "volume" , "ls" , "-q" , "-f" , f"name=^{ volume_name } $" ],
229+ check = True ,
230+ force_sudo = True ,
231+ run_quiet = True ,
232+ )
216233 if result .stdout .strip () == volume_name :
217234 log .success (f"Docker volume '{ volume_name } ' exists." )
218235 return True
@@ -222,7 +239,9 @@ def check_docker_volume_exists(exec_obj: Executor, volume_name: str) -> bool:
222239 log .error (f"Error checking Docker volumes: { e .stderr } " )
223240 return False
224241
225- def are_docker_services_running (exec_obj : Executor , user : str , cwd : str , service_names : List [str ]) -> bool :
242+ def are_docker_services_running (
243+ exec_obj : Executor , user : str , cwd : str , service_names : List [str ]
244+ ) -> bool :
226245 """
227246 Checks if a list of specific Docker Compose services are currently in the 'running' state.
228247 Requires running as the user that owns the compose stack.
@@ -255,7 +274,7 @@ def are_docker_services_running(exec_obj: Executor, user: str, cwd: str, service
255274 return all_running
256275
257276 except subprocess .CalledProcessError as e :
258- log .warning (f "Failed to execute 'docker compose ps'. Stack may not exist." )
277+ log .warning ("Failed to execute 'docker compose ps'. Stack may not exist." )
259278 log .debug (f"PS error: { e .stderr } " )
260279 return False
261280 except Exception as e :
0 commit comments