diff --git a/devservices/commands/purge.py b/devservices/commands/purge.py index ae8700f..63b0fa9 100644 --- a/devservices/commands/purge.py +++ b/devservices/commands/purge.py @@ -15,6 +15,7 @@ from devservices.utils.console import Console from devservices.utils.console import Status from devservices.utils.docker import get_matching_containers +from devservices.utils.docker import get_matching_networks from devservices.utils.docker import get_volumes_for_containers from devservices.utils.docker import stop_containers from devservices.utils.state import State @@ -77,32 +78,24 @@ def purge(_args: Namespace) -> None: console.failure(f"Failed to remove devservices volumes {e.stderr}") console.warning("Removing any devservices networks") - devservices_networks = ( - subprocess.check_output( - [ - "docker", - "network", - "ls", - "--filter", - f"name={DOCKER_NETWORK_NAME}", - "--format", - "{{.ID}}", - ], - text=True, - stderr=subprocess.DEVNULL, - ) - .strip() - .splitlines() - ) + try: + devservices_networks = get_matching_networks(DOCKER_NETWORK_NAME) + except DockerError as e: + console.failure(f"Failed to get devservices networks {e.stderr}") + exit(1) if len(devservices_networks) == 0: console.success("No devservices networks found to remove") - for network in devservices_networks: - subprocess.run( - ["docker", "network", "rm", network], - check=True, - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL, - ) - console.success(f"Network {network} removed") + else: + try: + subprocess.run( + ["docker", "network", "rm", *devservices_networks], + check=True, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + console.success("All devservices networks removed") + except subprocess.CalledProcessError as e: + console.failure(f"Failed to remove devservices networks {e.stderr}") + exit(1) console.success("The local devservices cache and state has been purged") diff --git a/devservices/utils/docker.py b/devservices/utils/docker.py index b2f889e..e5efcc3 100644 --- a/devservices/utils/docker.py +++ b/devservices/utils/docker.py @@ -49,6 +49,38 @@ def get_matching_containers(label: str) -> list[str]: ) from e +def get_matching_networks(name: str) -> list[str]: + """ + Returns a list of network IDs with the given name + """ + check_docker_daemon_running() + try: + return ( + subprocess.check_output( + [ + "docker", + "network", + "ls", + "--filter", + f"name={name}", + "--format", + "{{.ID}}", + ], + text=True, + stderr=subprocess.DEVNULL, + ) + .strip() + .splitlines() + ) + except subprocess.CalledProcessError as e: + raise DockerError( + command=f"docker network ls --filter name={name} --format '{{.ID}}'", + returncode=e.returncode, + stdout=e.stdout, + stderr=e.stderr, + ) from e + + def get_volumes_for_containers(containers: list[str]) -> set[str]: """ Returns a set of volume names for the given containers. diff --git a/tests/commands/test_purge.py b/tests/commands/test_purge.py index 04d5c1d..e928ca4 100644 --- a/tests/commands/test_purge.py +++ b/tests/commands/test_purge.py @@ -349,19 +349,7 @@ def test_purge_with_cache_and_state_and_running_containers_with_networks_and_vol stderr=mock.ANY, ), mock.call( - ["docker", "network", "rm", "abc"], - check=True, - stdout=mock.ANY, - stderr=mock.ANY, - ), - mock.call( - ["docker", "network", "rm", "def"], - check=True, - stdout=mock.ANY, - stderr=mock.ANY, - ), - mock.call( - ["docker", "network", "rm", "ghe"], + ["docker", "network", "rm", "abc", "def", "ghe"], check=True, stdout=mock.ANY, stderr=mock.ANY,