From 915994f07b9f9f1c2674fda7269c0e1d939dc390 Mon Sep 17 00:00:00 2001 From: Elsa Date: Tue, 8 Apr 2025 20:25:37 +0800 Subject: [PATCH 1/2] Handle exit code when compose up -d Format Rename variables related to exit_code Move variable location Workaround for running test rootfully format Signed-off-by: Elsa --- podman_compose.py | 26 ++++++++++---- .../in_pod/test_podman_compose_in_pod.py | 34 ++++++++++++------- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/podman_compose.py b/podman_compose.py index 015880d..45d777f 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -2760,11 +2760,15 @@ def deps_from_container(args, cnt): @cmd_run(podman_compose, "up", "Create and start the entire stack or some of its services") async def compose_up(compose: PodmanCompose, args): excluded = get_excluded(compose, args) + if not args.no_build: # `podman build` does not cache, so don't always build build_args = argparse.Namespace(if_not_exists=(not args.build), **args.__dict__) - if await compose.commands["build"](compose, build_args) != 0: + build_exit_code = await compose.commands["build"](compose, build_args) + if build_exit_code != 0: log.error("Build command failed") + if not args.dry_run: + return build_exit_code hashes = ( ( @@ -2794,6 +2798,7 @@ async def compose_up(compose: PodmanCompose, args): podman_command = "run" if args.detach and not args.no_start else "create" await create_pods(compose, args) + exit_code = 0 for cnt in compose.containers: if cnt["_service"] in excluded: log.debug("** skipping: %s", cnt["name"]) @@ -2801,13 +2806,22 @@ async def compose_up(compose: PodmanCompose, args): podman_args = await container_to_args( compose, cnt, detached=args.detach, no_deps=args.no_deps ) - subproc = await compose.podman.run([], podman_command, podman_args) - if podman_command == "run" and subproc is not None: - await run_container( + subproc_exit_code = await compose.podman.run([], podman_command, podman_args) + if subproc_exit_code is not None and subproc_exit_code != 0: + exit_code = subproc_exit_code + + if podman_command == "run" and subproc_exit_code is not None: + container_exit_code = await run_container( compose, cnt["name"], deps_from_container(args, cnt), ([], "start", [cnt["name"]]) ) - if args.no_start or args.detach or args.dry_run: - return + if container_exit_code is not None and container_exit_code != 0: + exit_code = container_exit_code + + if args.dry_run: + return None + if args.no_start or args.detach: + return exit_code + # TODO: handle already existing # TODO: if error creating do not enter loop # TODO: colors if sys.stdout.isatty() diff --git a/tests/integration/in_pod/test_podman_compose_in_pod.py b/tests/integration/in_pod/test_podman_compose_in_pod.py index 88b1a40..736ad29 100644 --- a/tests/integration/in_pod/test_podman_compose_in_pod.py +++ b/tests/integration/in_pod/test_podman_compose_in_pod.py @@ -21,6 +21,16 @@ def podman_compose_path(): return os.path.join(base_path(), "podman_compose.py") +def is_root(): + return os.geteuid() == 0 + + +def failure_exitcode_when_rootful(): + if is_root(): + return 125 + return 0 + + # If a compose file has userns_mode set, setting in_pod to True, results in error. # Default in_pod setting is True, unless compose file provides otherwise. # Compose file provides custom in_pod option, which can be overridden by command line in_pod option. @@ -64,7 +74,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): ] try: - self.run_subprocess_assert_returncode(command_up) + self.run_subprocess_assert_returncode(command_up, failure_exitcode_when_rootful()) finally: self.run_subprocess_assert_returncode(down_cmd) @@ -96,7 +106,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): ] try: - out, err = self.run_subprocess_assert_returncode(command_up) + out, err = self.run_subprocess_assert_returncode(command_up, 125) self.assertEqual(b"Error: --userns and --pod cannot be set together" in err, True) finally: @@ -142,7 +152,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): ] try: - self.run_subprocess_assert_returncode(command_up) + self.run_subprocess_assert_returncode(command_up, failure_exitcode_when_rootful()) finally: self.run_subprocess_assert_returncode(down_cmd) @@ -188,7 +198,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): ] try: - self.run_subprocess_assert_returncode(command_up) + self.run_subprocess_assert_returncode(command_up, failure_exitcode_when_rootful()) finally: self.run_subprocess_assert_returncode(down_cmd) @@ -221,7 +231,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): ] try: - out, err = self.run_subprocess_assert_returncode(command_up) + out, err = self.run_subprocess_assert_returncode(command_up, 125) self.assertEqual(b"Error: --userns and --pod cannot be set together" in err, True) finally: @@ -255,7 +265,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): ] try: - out, err = self.run_subprocess_assert_returncode(command_up) + out, err = self.run_subprocess_assert_returncode(command_up, 125) self.assertEqual(b"Error: --userns and --pod cannot be set together" in err, True) finally: @@ -301,7 +311,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): ] try: - self.run_subprocess_assert_returncode(command_up) + self.run_subprocess_assert_returncode(command_up, failure_exitcode_when_rootful()) finally: self.run_subprocess_assert_returncode(down_cmd) @@ -334,7 +344,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): ] try: - out, err = self.run_subprocess_assert_returncode(command_up) + out, err = self.run_subprocess_assert_returncode(command_up, 125) self.assertEqual(b"Error: --userns and --pod cannot be set together" in err, True) finally: @@ -368,7 +378,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): ] try: - out, err = self.run_subprocess_assert_returncode(command_up) + out, err = self.run_subprocess_assert_returncode(command_up, 125) self.assertEqual(b"Error: --userns and --pod cannot be set together" in err, True) finally: @@ -402,7 +412,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): ] try: - out, err = self.run_subprocess_assert_returncode(command_up) + out, err = self.run_subprocess_assert_returncode(command_up, 125) self.assertEqual(b"Error: --userns and --pod cannot be set together" in err, True) finally: @@ -448,7 +458,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): ] try: - self.run_subprocess_assert_returncode(command_up) + self.run_subprocess_assert_returncode(command_up, failure_exitcode_when_rootful()) finally: self.run_subprocess_assert_returncode(down_cmd) @@ -482,7 +492,7 @@ class TestPodmanComposeInPod(unittest.TestCase, RunSubprocessMixin): ] try: - out, err = self.run_subprocess_assert_returncode(command_up) + out, err = self.run_subprocess_assert_returncode(command_up, 125) self.assertEqual(b"Error: --userns and --pod cannot be set together" in err, True) finally: From 646912f7a502093d42706709f453b48d48e11805 Mon Sep 17 00:00:00 2001 From: Elsa Date: Fri, 25 Apr 2025 10:22:59 +0800 Subject: [PATCH 2/2] Add news Signed-off-by: Elsa --- newsfragments/handle-up-detach-exitcode.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 newsfragments/handle-up-detach-exitcode.bugfix diff --git a/newsfragments/handle-up-detach-exitcode.bugfix b/newsfragments/handle-up-detach-exitcode.bugfix new file mode 100644 index 0000000..829eaf3 --- /dev/null +++ b/newsfragments/handle-up-detach-exitcode.bugfix @@ -0,0 +1 @@ +- Return non-zero exit_code on failure when `up -d`