mirror of
https://github.com/basnijholt/compose-farm.git
synced 2026-02-03 06:03:25 +00:00
fix: Don't remove multi-host stacks from state when host-filtered
When using `-H host` with a multi-host stack, we only stop one instance. The stack is still running on other hosts, so we shouldn't remove it from state entirely. This prevents issues where: - `cf apply` would try to re-start the stack - `cf ps` would show incorrect running status - Orphan detection would be confused Added tests to verify state is preserved for host-filtered multi-host operations and removed for full stack operations.
This commit is contained in:
@@ -132,11 +132,16 @@ def down(
|
||||
|
||||
# Remove from state on success
|
||||
# For multi-host stacks, result.stack is "stack@host", extract base name
|
||||
# Skip state removal for host-filtered multi-host stacks (only one instance was stopped)
|
||||
removed_stacks: set[str] = set()
|
||||
for result in results:
|
||||
if result.success:
|
||||
base_stack = result.stack.split("@")[0]
|
||||
if base_stack not in removed_stacks:
|
||||
# Don't remove multi-host stacks from state when host-filtered
|
||||
# because only one instance was stopped, the stack is still running elsewhere
|
||||
if host and cfg.is_multi_host(base_stack):
|
||||
continue
|
||||
remove_stack(cfg, base_stack)
|
||||
removed_stacks.add(base_stack)
|
||||
|
||||
|
||||
@@ -500,3 +500,69 @@ class TestHostFilterMultiHost:
|
||||
mock_run.assert_called_once()
|
||||
call_kwargs = mock_run.call_args.kwargs
|
||||
assert call_kwargs.get("filter_host") == "host1"
|
||||
|
||||
def test_down_host_filter_skips_state_removal_for_multi_host(self, tmp_path: Path) -> None:
|
||||
"""--host filter should NOT remove multi-host stacks from state.
|
||||
|
||||
When stopping only one instance of a multi-host stack, the stack is still
|
||||
running on other hosts, so it shouldn't be removed from state.
|
||||
"""
|
||||
cfg = self._make_multi_host_config(tmp_path)
|
||||
|
||||
with (
|
||||
patch("compose_farm.cli.lifecycle.load_config_or_exit", return_value=cfg),
|
||||
patch("compose_farm.cli.lifecycle.get_stacks") as mock_get_stacks,
|
||||
patch("compose_farm.cli.lifecycle.run_on_stacks"),
|
||||
patch(
|
||||
"compose_farm.cli.lifecycle.run_async",
|
||||
return_value=[_make_result("multi-host@host1")],
|
||||
),
|
||||
patch("compose_farm.cli.lifecycle.remove_stack") as mock_remove,
|
||||
patch("compose_farm.cli.lifecycle.maybe_regenerate_traefik"),
|
||||
patch("compose_farm.cli.lifecycle.report_results"),
|
||||
):
|
||||
mock_get_stacks.return_value = (["multi-host"], cfg)
|
||||
|
||||
down(
|
||||
stacks=None,
|
||||
all_stacks=False,
|
||||
orphaned=False,
|
||||
host="host1",
|
||||
config=None,
|
||||
)
|
||||
|
||||
# remove_stack should NOT be called for multi-host stacks with host filter
|
||||
mock_remove.assert_not_called()
|
||||
|
||||
def test_down_without_host_filter_removes_from_state(self, tmp_path: Path) -> None:
|
||||
"""Without --host filter, multi-host stacks SHOULD be removed from state."""
|
||||
cfg = self._make_multi_host_config(tmp_path)
|
||||
|
||||
with (
|
||||
patch("compose_farm.cli.lifecycle.load_config_or_exit", return_value=cfg),
|
||||
patch("compose_farm.cli.lifecycle.get_stacks") as mock_get_stacks,
|
||||
patch("compose_farm.cli.lifecycle.run_on_stacks"),
|
||||
patch(
|
||||
"compose_farm.cli.lifecycle.run_async",
|
||||
return_value=[
|
||||
_make_result("multi-host@host1"),
|
||||
_make_result("multi-host@host2"),
|
||||
_make_result("multi-host@host3"),
|
||||
],
|
||||
),
|
||||
patch("compose_farm.cli.lifecycle.remove_stack") as mock_remove,
|
||||
patch("compose_farm.cli.lifecycle.maybe_regenerate_traefik"),
|
||||
patch("compose_farm.cli.lifecycle.report_results"),
|
||||
):
|
||||
mock_get_stacks.return_value = (["multi-host"], cfg)
|
||||
|
||||
down(
|
||||
stacks=None,
|
||||
all_stacks=False,
|
||||
orphaned=False,
|
||||
host=None, # No host filter
|
||||
config=None,
|
||||
)
|
||||
|
||||
# remove_stack SHOULD be called when stopping all instances
|
||||
mock_remove.assert_called_once_with(cfg, "multi-host")
|
||||
|
||||
Reference in New Issue
Block a user