From 4e79592cf38b14f55681df27b7dc5c74db53e488 Mon Sep 17 00:00:00 2001 From: Riccardo Paolo Bestetti Date: Sun, 5 Jan 2025 17:55:20 +0100 Subject: [PATCH] Add support for container initialization This commit contributes support for container initialization (i.e., the operation performed by `podman container init`.) Alongside that, it introduces: - unit test ContainersTestCase::test_init - integration subtest `Create-Init-Start Container` in ContainersIntegrationTest::test_container_crud A small fix to the docstring of Container.status has also been contributed to reflect the existance of the `created` and `initialized` states. Signed-off-by: Riccardo Paolo Bestetti --- podman/domain/containers.py | 7 ++++++- podman/tests/integration/test_containers.py | 18 ++++++++++++++++++ podman/tests/unit/test_container.py | 11 +++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/podman/domain/containers.py b/podman/domain/containers.py index c99ed926..f603a9c6 100644 --- a/podman/domain/containers.py +++ b/podman/domain/containers.py @@ -54,7 +54,7 @@ def labels(self): @property def status(self): - """Literal["running", "stopped", "exited", "unknown"]: Returns status of container.""" + """Literal["created", "initialized", "running", "stopped", "exited", "unknown"]: Returns status of container.""" with suppress(KeyError): return self.attrs["State"]["Status"] return "unknown" @@ -262,6 +262,11 @@ def get_archive( stat = api.decode_header(stat) return response.iter_content(chunk_size=chunk_size), stat + def init(self) -> None: + """Initialize the container.""" + response = self.client.post(f"/containers/{self.id}/init") + response.raise_for_status() + def inspect(self) -> Dict: """Inspect a container. diff --git a/podman/tests/integration/test_containers.py b/podman/tests/integration/test_containers.py index d92a7d7a..11b7ea81 100644 --- a/podman/tests/integration/test_containers.py +++ b/podman/tests/integration/test_containers.py @@ -143,6 +143,24 @@ def test_container_crud(self): top_ctnr.reload() self.assertIn(top_ctnr.status, ("exited", "stopped")) + with self.subTest("Create-Init-Start Container"): + top_ctnr = self.client.containers.create( + self.alpine_image, ["/usr/bin/top"], name="TestInitPs", detach=True + ) + self.assertEqual(top_ctnr.status, "created") + + top_ctnr.init() + top_ctnr.reload() + self.assertEqual(top_ctnr.status, "initialized") + + top_ctnr.start() + top_ctnr.reload() + self.assertEqual(top_ctnr.status, "running") + + top_ctnr.stop() + top_ctnr.reload() + self.assertIn(top_ctnr.status, ("exited", "stopped")) + with self.subTest("Prune Containers"): report = self.client.containers.prune() self.assertIn(top_ctnr.id, report["ContainersDeleted"]) diff --git a/podman/tests/unit/test_container.py b/podman/tests/unit/test_container.py index 5d0023e0..f2c41601 100644 --- a/podman/tests/unit/test_container.py +++ b/podman/tests/unit/test_container.py @@ -101,6 +101,17 @@ def test_start(self, mock): container.start() self.assertTrue(adapter.called_once) + @requests_mock.Mocker() + def test_init(self, mock): + adapter = mock.post( + tests.LIBPOD_URL + + "/containers/87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd/init", + status_code=204, + ) + container = Container(attrs=FIRST_CONTAINER, client=self.client.api) + container.init() + self.assertTrue(adapter.called_once) + @requests_mock.Mocker() def test_stats(self, mock): stream = [