From e15e96a65664c89c5656d2f4fba0e71d18ed8386 Mon Sep 17 00:00:00 2001 From: Robin Syl Date: Sat, 23 Sep 2023 12:04:17 +0200 Subject: [PATCH 1/4] Use new Podman flags for healthcheck Relevant Podman documentation here: https://docs.podman.io/en/v5.4.0/markdown/podman-healthcheck-run.1.html Signed-off-by: Robin Syl Signed-off-by: Monika Kairaityte --- .../add-start_interval-in-healthcheck.misc | 2 ++ podman_compose.py | 14 +++++++------- tests/unit/test_container_to_args.py | 6 +++--- 3 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 newsfragments/add-start_interval-in-healthcheck.misc diff --git a/newsfragments/add-start_interval-in-healthcheck.misc b/newsfragments/add-start_interval-in-healthcheck.misc new file mode 100644 index 00000000..eba6270e --- /dev/null +++ b/newsfragments/add-start_interval-in-healthcheck.misc @@ -0,0 +1,2 @@ +Add support for `start_interval` option. +Rename healthcheck flags to be consistent with Podman options. diff --git a/podman_compose.py b/podman_compose.py index b4b24d54..147c65ef 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -1286,7 +1286,7 @@ async def container_to_args( if isinstance(healthcheck_test, str): # podman does not add shell to handle command with whitespace podman_args.extend([ - "--healthcheck-command", + "--health-cmd", json.dumps(["CMD-SHELL", healthcheck_test]), ]) elif is_list(healthcheck_test): @@ -1296,11 +1296,11 @@ async def container_to_args( if healthcheck_type == "NONE": podman_args.append("--no-healthcheck") elif healthcheck_type == "CMD": - podman_args.extend(["--healthcheck-command", json.dumps(healthcheck_test)]) + podman_args.extend(["--health-cmd", json.dumps(healthcheck_test)]) elif healthcheck_type == "CMD-SHELL": if len(healthcheck_test) != 1: raise ValueError("'CMD_SHELL' takes a single string after it") - podman_args.extend(["--healthcheck-command", json.dumps(healthcheck_test)]) + podman_args.extend(["--health-cmd", json.dumps(healthcheck_test)]) else: raise ValueError( f"unknown healthcheck test type [{healthcheck_type}],\ @@ -1311,15 +1311,15 @@ async def container_to_args( # interval, timeout and start_period are specified as durations. if "interval" in healthcheck: - podman_args.extend(["--healthcheck-interval", healthcheck["interval"]]) + podman_args.extend(["--health-interval", healthcheck["interval"]]) if "timeout" in healthcheck: - podman_args.extend(["--healthcheck-timeout", healthcheck["timeout"]]) + podman_args.extend(["--health-timeout", healthcheck["timeout"]]) if "start_period" in healthcheck: - podman_args.extend(["--healthcheck-start-period", healthcheck["start_period"]]) + podman_args.extend(["--health-start-period", healthcheck["start_period"]]) # convert other parameters to string if "retries" in healthcheck: - podman_args.extend(["--healthcheck-retries", str(healthcheck["retries"])]) + podman_args.extend(["--health-retries", str(healthcheck["retries"])]) # handle podman extension if 'x-podman' in cnt: diff --git a/tests/unit/test_container_to_args.py b/tests/unit/test_container_to_args.py index 3d035ae4..91490cd3 100644 --- a/tests/unit/test_container_to_args.py +++ b/tests/unit/test_container_to_args.py @@ -889,7 +889,7 @@ async def test_healthcheck_string(self) -> None: "--name=project_name_service_name1", "-d", "--network=bridge:alias=service_name", - "--healthcheck-command", + "--health-cmd", '["CMD-SHELL", "cmd arg1 arg2"]', "busybox", ], @@ -909,7 +909,7 @@ async def test_healthcheck_cmd_args(self) -> None: "--name=project_name_service_name1", "-d", "--network=bridge:alias=service_name", - "--healthcheck-command", + "--health-cmd", '["cmd", "arg1", "arg2"]', "busybox", ], @@ -929,7 +929,7 @@ async def test_healthcheck_cmd_shell(self) -> None: "--name=project_name_service_name1", "-d", "--network=bridge:alias=service_name", - "--healthcheck-command", + "--health-cmd", '["cmd arg1 arg2"]', "busybox", ], From 0ad781bf29ef2ebb0a4a0bb997dce500aa1270e6 Mon Sep 17 00:00:00 2001 From: Robin Syl Date: Sat, 23 Sep 2023 12:34:54 +0200 Subject: [PATCH 2/4] Add support for "start_interval" in healthcheck block Signed-off-by: Robin Syl Signed-off-by: Monika Kairaityte --- podman_compose.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/podman_compose.py b/podman_compose.py index 147c65ef..a155d4a6 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -1309,13 +1309,15 @@ async def container_to_args( else: raise ValueError("'healthcheck.test' either a string or a list") - # interval, timeout and start_period are specified as durations. + # interval, timeout, start_period, and start_interval are specified as durations. if "interval" in healthcheck: podman_args.extend(["--health-interval", healthcheck["interval"]]) if "timeout" in healthcheck: podman_args.extend(["--health-timeout", healthcheck["timeout"]]) if "start_period" in healthcheck: podman_args.extend(["--health-start-period", healthcheck["start_period"]]) + if "start_interval" in healthcheck: + podman_args.extend(["--health-startup-interval", healthcheck["start_interval"]]) # convert other parameters to string if "retries" in healthcheck: From 8af3cdbea731e40bf30831781a6fb97378fc03b1 Mon Sep 17 00:00:00 2001 From: Robin Syl Date: Mon, 11 Mar 2024 23:26:10 +0100 Subject: [PATCH 3/4] tests/integration: Add tests for healthcheck block Signed-off-by: Robin Syl Signed-off-by: Monika Kairaityte --- tests/integration/healthcheck/__init__.py | 1 + .../healthcheck/docker-compose.yml | 11 ++++ .../test_podman_compose_healthcheck.py | 59 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 tests/integration/healthcheck/__init__.py create mode 100644 tests/integration/healthcheck/docker-compose.yml create mode 100644 tests/integration/healthcheck/test_podman_compose_healthcheck.py diff --git a/tests/integration/healthcheck/__init__.py b/tests/integration/healthcheck/__init__.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/tests/integration/healthcheck/__init__.py @@ -0,0 +1 @@ + diff --git a/tests/integration/healthcheck/docker-compose.yml b/tests/integration/healthcheck/docker-compose.yml new file mode 100644 index 00000000..5c12b3c3 --- /dev/null +++ b/tests/integration/healthcheck/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3" +services: + healthcheck: + image: nopush/podman-compose-test + healthcheck: + test: [ "CMD-SHELL", "curl -f http://localhost || exit 1" ] + interval: 1m + timeout: 10s + retries: 3 + start_period: 10s + start_interval: 5s diff --git a/tests/integration/healthcheck/test_podman_compose_healthcheck.py b/tests/integration/healthcheck/test_podman_compose_healthcheck.py new file mode 100644 index 00000000..50aa3c49 --- /dev/null +++ b/tests/integration/healthcheck/test_podman_compose_healthcheck.py @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0 + +import json +import os +import unittest + +from tests.integration.test_utils import RunSubprocessMixin +from tests.integration.test_utils import podman_compose_path +from tests.integration.test_utils import test_path + + +def compose_yaml_path() -> str: + return os.path.join(os.path.join(test_path(), "healthcheck"), "docker-compose.yml") + + +class TestHealthecheck(unittest.TestCase, RunSubprocessMixin): + def test_healthcheck(self) -> None: + up_cmd = [ + "coverage", + "run", + podman_compose_path(), + "-f", + os.path.join(test_path(), "healthcheck", "docker-compose.yml"), + "up", + "-d", + ] + self.run_subprocess_assert_returncode(up_cmd) + + command_container_id = [ + "podman", + "ps", + "-a", + "--filter", + "label=io.podman.compose.project=healthcheck", + "--format", + '"{{.ID}}"', + ] + out, _ = self.run_subprocess_assert_returncode(command_container_id) + self.assertNotEqual(out, b"") + container_id = out.decode("utf-8").strip().replace('"', "") + + command_inspect = ["podman", "container", "inspect", container_id] + + out, _ = self.run_subprocess_assert_returncode(command_inspect) + out_string = out.decode("utf-8") + inspect = json.loads(out_string) + healthcheck_obj = inspect[0]["Config"]["Healthcheck"] + expected = { + "Test": ["CMD-SHELL", "curl -f http://localhost || exit 1"], + "StartPeriod": 10000000000, + "Interval": 60000000000, + "Timeout": 10000000000, + "Retries": 3, + } + self.assertEqual(healthcheck_obj, expected) + + # StartInterval is not available in the config object + create_obj = inspect[0]["Config"]["CreateCommand"] + self.assertIn("--health-startup-interval", create_obj) From 7ffea4ebbb635295124b97651ff581f3132d34e2 Mon Sep 17 00:00:00 2001 From: Monika Kairaityte Date: Mon, 4 Aug 2025 21:00:58 +0300 Subject: [PATCH 4/4] tests: Change github actions workflow to test with podman 5.4.2 Signed-off-by: Monika Kairaityte --- .github/workflows/test.yml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0d759578..d03aa07e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,10 +19,35 @@ jobs: options: --privileged --cgroupns=host steps: - uses: actions/checkout@v4 - - name: Install dependencies + - name: Download necessary .deb files from man-compose-test-data repository + shell: bash + run: | + BASE_URL="https://raw.githubusercontent.com/mokibit/podman-compose-test-data/tree/main/deb_files/podman-5.4.2" + + FILES=( + "podman_5.4.2+composetest-1_amd64.deb" + "podman-docker_5.4.2+composetest-1_amd64.deb" + "podman-remote_5.4.2+composetest-1_amd64.deb" + ) + for FILE in "${FILES[@]}"; do + URL="${BASE_URL}/${FILE}" + echo "Downloading: $URL" + curl -L -f -O "$URL" || { echo "Failed to download $FILE"; exit 1; } + done + - name: Install podman v5.4.2 from .deb packages + run: | + dpkg -i podman_5.4.2+composetest-1_amd64.deb + dpkg -i podman-docker_5.4.2+composetest-1_amd64.deb + dpkg -i podman-remote_5.4.2+composetest-1_amd64.deb + apt-get install -f -y + - name: Verify podman installation + run: | + podman --version + podman-remote --version + podman-docker version || echo "podman-docker not available" + - name: Install other test dependencies run: | set -e - apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y podman python -m pip install --upgrade pip pip install -r requirements.txt pip install -r test-requirements.txt