Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newsfragments/dry_run_no_network_volume_creation.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed ``--dry-run`` creating networks and volumes: ``podman-compose --dry-run up`` now only logs the ``network create``/``volume create`` commands instead of running them.
6 changes: 6 additions & 0 deletions podman_compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,9 @@ async def assert_volume(compose: PodmanCompose, mount_dict: dict[str, Any]) -> N
for opt, value in driver_opts.items():
args.extend(["--opt", f"{opt}={value}"])
args.append(vol_name)
if compose.podman.dry_run:
log.info("%s volume %s", compose.podman.podman_path, " ".join(args))
return
await compose.podman.output([], "volume", args)
await compose.podman.output([], "volume", ["inspect", vol_name])

Expand Down Expand Up @@ -1187,6 +1190,9 @@ async def assert_cnt_nets(compose: PodmanCompose, cnt: dict[str, Any]) -> None:
f"Create it first with: podman network create '{net_name}'"
) from e
args = get_network_create_args(net_desc, compose.project_name, net_name)
if compose.podman.dry_run:
log.info("%s network %s", compose.podman.podman_path, " ".join(args))
continue
await compose.podman.output([], "network", args)
await compose.podman.output([], "network", ["exists", net_name])

Expand Down
65 changes: 65 additions & 0 deletions tests/unit/test_dry_run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# SPDX-License-Identifier: GPL-2.0
import asyncio
import subprocess
from unittest import IsolatedAsyncioTestCase
from unittest import mock

from podman_compose import Podman
from podman_compose import PodmanCompose
from podman_compose import assert_cnt_nets
from podman_compose import assert_volume


def get_dry_run_compose() -> mock.MagicMock:
compose = mock.MagicMock(spec=PodmanCompose)
compose.project_name = "test_project"
compose.get_podman_args.return_value = []
compose.podman = Podman(compose, "podman", True, asyncio.Semaphore(1))
return compose


class TestDryRun(IsolatedAsyncioTestCase):
async def test_assert_volume_does_not_create_volume(self) -> None:
compose = get_dry_run_compose()
mount_dict = {
"type": "volume",
"source": "testvol",
"target": "/root",
"_vol": {"name": "test_project_testvol"},
}

with mock.patch.object(compose.podman, "output") as output:
output.side_effect = [
subprocess.CalledProcessError(1, "podman volume inspect"),
b"",
b"",
]
await assert_volume(compose, mount_dict)

self.assertEqual(
[args for args, _ in output.call_args_list],
[([], "volume", ["inspect", "test_project_testvol"])],
)

async def test_assert_cnt_nets_does_not_create_network(self) -> None:
compose = get_dry_run_compose()
compose.networks = {"srv": {}}
compose.default_net = "srv"
cnt = {"service_name": "alpine", "networks": ["srv"]}

with mock.patch.object(compose.podman, "output") as output:
output.side_effect = [
subprocess.CalledProcessError(1, "podman network exists"),
b"",
b"",
]
with mock.patch(
"podman_compose.default_network_name_for_project",
return_value="test_project_srv",
):
await assert_cnt_nets(compose, cnt)

self.assertEqual(
[args for args, _ in output.call_args_list],
[([], "network", ["exists", "test_project_srv"])],
)