Skip to content

Commit 3108c10

Browse files
committed
Updates to compose_down command to match docker compose behavior (Issue: containers#267)
Signed-off-by: Yashodhan Pise <[email protected]>
1 parent 95c6d0d commit 3108c10

File tree

1 file changed

+50
-26
lines changed

1 file changed

+50
-26
lines changed

podman_compose.py

+50-26
Original file line numberDiff line numberDiff line change
@@ -2869,12 +2869,30 @@ def get_volume_names(compose, cnt):
28692869

28702870
@cmd_run(podman_compose, "down", "tear down entire stack")
28712871
async def compose_down(compose: PodmanCompose, args):
2872+
# get_excluded fails as no-deps is not a supported cli arg
28722873
excluded = get_excluded(compose, args)
28732874
podman_args = []
28742875
timeout_global = getattr(args, "timeout", None)
28752876
containers = list(reversed(compose.containers))
28762877

2877-
down_tasks = []
2878+
# Get list of currently running containers
2879+
running_cnt_names = (
2880+
(
2881+
await compose.podman.output(
2882+
[],
2883+
"ps",
2884+
[
2885+
"--filter",
2886+
f"label=io.podman.compose.project={compose.project_name}",
2887+
"-a",
2888+
"--format",
2889+
"{{ .Names }}",
2890+
],
2891+
)
2892+
)
2893+
.decode("utf-8")
2894+
.splitlines()
2895+
)
28782896

28792897
for cnt in containers:
28802898
if cnt["_service"] in excluded:
@@ -2886,38 +2904,44 @@ async def compose_down(compose: PodmanCompose, args):
28862904
timeout = str_to_seconds(timeout_str)
28872905
if timeout is not None:
28882906
podman_stop_args.extend(["-t", str(timeout)])
2889-
down_tasks.append(
2890-
asyncio.create_task(
2891-
compose.podman.run([], "stop", [*podman_stop_args, cnt["name"]]), name=cnt["name"]
2892-
)
2893-
)
2894-
await asyncio.gather(*down_tasks)
2907+
await compose.podman.run([], "stop", [*podman_stop_args, cnt["name"]])
2908+
28952909
for cnt in containers:
28962910
if cnt["_service"] in excluded:
28972911
continue
28982912
await compose.podman.run([], "rm", [cnt["name"]])
2913+
if cnt["name"] in running_cnt_names:
2914+
running_cnt_names.remove(cnt["name"])
2915+
2916+
# The logic is updated based on docker compose documentation:
2917+
# `--remove-orphans`: Remove containers for services not defined in the Compose file
2918+
# Ref: https://docs.docker.com/reference/cli/docker/compose/down/#options
2919+
orphan_cnt_names = []
2920+
for cnt in running_cnt_names:
2921+
if not any(f"{compose.project_name}_{service}_" in cnt for service in compose.all_services):
2922+
orphan_cnt_names.append(cnt)
2923+
running_cnt_names.remove(cnt)
2924+
2925+
# We list the containers and remove them from running container list
2926+
# However, we stop them only if provided with CLI arg `--remove-orphans`
28992927
if args.remove_orphans:
2900-
names = (
2901-
(
2902-
await compose.podman.output(
2903-
[],
2904-
"ps",
2905-
[
2906-
"--filter",
2907-
f"label=io.podman.compose.project={compose.project_name}",
2908-
"-a",
2909-
"--format",
2910-
"{{ .Names }}",
2911-
],
2912-
)
2913-
)
2914-
.decode("utf-8")
2915-
.splitlines()
2916-
)
2917-
for name in names:
2928+
for name in orphan_cnt_names:
29182929
await compose.podman.run([], "stop", [*podman_args, name])
2919-
for name in names:
2930+
for name in orphan_cnt_names:
29202931
await compose.podman.run([], "rm", [name])
2932+
2933+
for cnt in running_cnt_names:
2934+
# This logic goes away if the containers list can be updated accordingly at source
2935+
# Clear containers not formed out of the current compose file definitions
2936+
# E.g.: By using CLI `up --scale <APP>=<NUM>` option
2937+
podman_stop_args = [*podman_args]
2938+
if timeout_global is not None:
2939+
podman_stop_args.extend(["-t", str(timeout_global)])
2940+
await compose.podman.run( [], "stop", [*podman_stop_args, cnt])
2941+
2942+
for cnt in running_cnt_names:
2943+
await compose.podman.run([], "rm", [cnt])
2944+
29212945
if args.volumes:
29222946
vol_names_to_keep = set()
29232947
for cnt in containers:

0 commit comments

Comments
 (0)