Skip to content

Commit

Permalink
Fix the 'remove' and 'detach' usage.
Browse files Browse the repository at this point in the history
Signed-off-by: Milan Balazs <[email protected]>
  • Loading branch information
milanbalazs committed Sep 14, 2024
1 parent 0aa5915 commit 04dd546
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 4 deletions.
4 changes: 4 additions & 0 deletions podman/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ def post(
Keyword Args:
compatible: Will override the default path prefix with compatible prefix
verify: Whether to verify TLS certificates.
Raises:
APIError: when service returns an error
Expand Down Expand Up @@ -394,6 +395,7 @@ def _request(
Keyword Args:
compatible: Will override the default path prefix with compatible prefix
verify: Whether to verify TLS certificates.
Raises:
APIError: when service returns an error
Expand All @@ -412,6 +414,7 @@ def _request(
# TODO should we have an option for HTTPS support?
# Build URL for operation from base_url
uri = urllib.parse.ParseResult(
# TODO: Does it make sense: "https" if kwargs.get("verify", None) else "http" ?
"http",
self.base_url.netloc,
urllib.parse.urljoin(path_prefix, path),
Expand All @@ -429,6 +432,7 @@ def _request(
data=data,
headers=(headers or {}),
stream=stream,
verify=kwargs.get("verify", None),
**timeout_kw,
)
)
Expand Down
14 changes: 14 additions & 0 deletions podman/domain/containers_run.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Mixin to provide Container run() method."""

import logging
import threading
from contextlib import suppress
from typing import Generator, Iterator, List, Union

Expand Down Expand Up @@ -67,7 +68,20 @@ def run(
container.wait(condition=["running", "exited"])
container.reload()

def remove_container(container_object: Container) -> None:
"""
Wait the container to finish and remove it.
Args:
container_object: Container object
"""
container_object.wait() # Wait for the container to finish
container_object.remove() # Remove the container

if kwargs.get("detach", False):
if remove:
# Start a background thread to remove the container after finishing
threading.Thread(target=remove_container, args=(container,)).start()
return container

with suppress(KeyError):
Expand Down
20 changes: 18 additions & 2 deletions podman/domain/images_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from podman.domain.images_build import BuildMixin
from podman.domain.manager import Manager
from podman.domain.registry_data import RegistryData
from podman.errors import APIError, ImageNotFound
from podman.errors import APIError, ImageNotFound, PodmanError

try:
from rich.progress import (
Expand Down Expand Up @@ -113,18 +113,34 @@ def get_registry_data(
collection=self,
)

def load(self, data: bytes) -> Generator[Image, None, None]:
def load(
self, data: Optional[bytes] = None, file_path: Optional[str] = None
) -> Generator[Image, None, None]:
"""Restore an image previously saved.
Args:
data: Image to be loaded in tarball format.
file_path: Path of the Tarball.
Raises:
APIError: when service returns an error
"""
# TODO fix podman swagger cannot use this header!
# headers = {"Content-type": "application/x-www-form-urlencoded"}

if not data and not file_path:
raise PodmanError("The 'data' or 'file_path' parameter should be set.")

if data and file_path:
raise PodmanError(
"Only one parameter should be set from 'data' and 'file_path' parameters."
)

if file_path:
# Load a tarball containing the image
with open(file_path, "rb") as tarball_file:
data = tarball_file.read() # Read the tarball file as bytes

response = self.client.post(
"/images/load", data=data, headers={"Content-type": "application/x-tar"}
)
Expand Down
15 changes: 14 additions & 1 deletion podman/domain/system.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""SystemManager to provide system level information from Podman service."""

import logging
from typing import Any, Dict, Optional
from typing import Any, Dict, Optional, Union

from podman.api.client import APIClient
from podman import api
Expand Down Expand Up @@ -44,6 +44,10 @@ def login(
registry: Optional[str] = None,
reauth: Optional[bool] = False, # pylint: disable=unused-argument
dockercfg_path: Optional[str] = None, # pylint: disable=unused-argument
auth: Optional[str] = None,
identitytoken: Optional[str] = None,
registrytoken: Optional[str] = None,
tls_verify: Optional[Union[bool, str]] = None,
) -> Dict[str, Any]:
"""Log into Podman service.
Expand All @@ -55,20 +59,29 @@ def login(
reauth: Ignored: If True, refresh existing authentication. Default: False
dockercfg_path: Ignored: Path to custom configuration file.
https://quay.io/v2
auth = None,
identitytoken: IdentityToken is used to authenticate the user and
get an access token for the registry.
registrytoken: RegistryToken is a bearer token to be sent to a registry
tls_verify: Whether to verify TLS certificates.
"""

payload = {
"username": username,
"password": password,
"email": email,
"serveraddress": registry,
"auth": auth,
"identitytoken": identitytoken,
"registrytoken": registrytoken,
}
payload = api.prepare_body(payload)
response = self.client.post(
path="/auth",
headers={"Content-type": "application/json"},
data=payload,
compatible=True,
verify=tls_verify, # Pass tls_verify to the client
)
response.raise_for_status()
return response.json()
Expand Down
34 changes: 33 additions & 1 deletion podman/tests/unit/test_imagesmanager.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import types
import unittest
from unittest.mock import mock_open, patch

try:
# Python >= 3.10
Expand All @@ -13,7 +14,7 @@
from podman import PodmanClient, tests
from podman.domain.images import Image
from podman.domain.images_manager import ImagesManager
from podman.errors import APIError, ImageNotFound
from podman.errors import APIError, ImageNotFound, PodmanError

FIRST_IMAGE = {
"Id": "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab",
Expand Down Expand Up @@ -320,6 +321,37 @@ def test_remove(self, mock):

@requests_mock.Mocker()
def test_load(self, mock):
with self.assertRaises(PodmanError):
self.client.images.load()

with self.assertRaises(PodmanError):
self.client.images.load(b'data', b'file_path')

with self.assertRaises(PodmanError):
self.client.images.load(data=b'data', file_path=b'file_path')

with patch("builtins.open", mock_open(read_data=b"mock tarball data")) as mock_file:
mock.post(
tests.LIBPOD_URL + "/images/load",
json={"Names": ["quay.io/fedora:latest"]},
)
mock.get(
tests.LIBPOD_URL + "/images/quay.io%2ffedora%3Alatest/json",
json=FIRST_IMAGE,
)

# 3a. Test the case where only 'file_path' is provided
gntr = self.client.images.load(file_path="mock_file.tar")
self.assertIsInstance(gntr, types.GeneratorType)

report = list(gntr)
self.assertEqual(len(report), 1)
self.assertEqual(
report[0].id,
"sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab",
)
mock_file.assert_called_once_with("mock_file.tar", "rb")

mock.post(
tests.LIBPOD_URL + "/images/load",
json={"Names": ["quay.io/fedora:latest"]},
Expand Down

0 comments on commit 04dd546

Please sign in to comment.