Skip to content

Commit

Permalink
podman: retry pulling the image
Browse files Browse the repository at this point in the history
Move podman_check_native_image_architecture() to the later stage, so we
don't retry upon architecture mismatch.

Relates: containers/podman#19770
  • Loading branch information
praiskup committed Aug 29, 2023
1 parent 4263759 commit cb74219
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 6 deletions.
6 changes: 6 additions & 0 deletions mock/docs/site-defaults.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@
# package manager (e.g. using dnf --installroot).
#config_opts['bootstrap_image_fallback'] = True

# When 'use_bootstrap_image' is True, bootstrap image must be downloaded.
# Attempt to download the image may fail, and Mock will retry. Here you can
# configure how long should Mock keep re-trying (using exponential full jitter,
# see python-backoff docs for more info).
#config_opts['bootstrap_image_keep_getting'] = 120 # seconds

# anything you specify with 'bootstrap_*' will be copied to bootstrap config
# e.g. config_opts['bootstrap_system_yum_command'] = '/usr/bin/yum-deprecated' will become
# config_opts['system_yum_command'] = '/usr/bin/yum-deprecated' for bootstrap config
Expand Down
2 changes: 1 addition & 1 deletion mock/py/mockbuild/buildroot.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ def _fallback(message):
podman = Podman(self, self.bootstrap_image)

with _fallback("Can't initialize from bootstrap image"):
podman.pull_image()
podman.retry_image_pull(self.config["image_keep_getting"])
podman.cp(self.make_chroot_path(), self.config["tar_binary"])
file_util.unlink_if_exists(os.path.join(self.make_chroot_path(),
"etc/rpm/macros.image-language-conf"))
Expand Down
1 change: 1 addition & 0 deletions mock/py/mockbuild/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def setup_default_config_opts():
config_opts['bootstrap_image'] = 'fedora:latest'
config_opts['bootstrap_image_ready'] = False
config_opts['bootstrap_image_fallback'] = True
config_opts['bootstrap_image_keep_getting'] = 120

config_opts['internal_dev_setup'] = True

Expand Down
23 changes: 18 additions & 5 deletions mock/py/mockbuild/podman.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import subprocess
from contextlib import contextmanager

import backoff
from mockbuild.trace_decorator import getLog, traceLog
from mockbuild import util
from mockbuild.exception import BootstrapError
Expand Down Expand Up @@ -59,18 +60,23 @@ def __init__(self, buildroot, image):

@traceLog()
def pull_image(self):
""" pull the latest image """
""" pull the latest image, return True if successful """
logger = getLog()
logger.info("Pulling image: %s", self.image)
cmd = [self.podman_binary, "pull", self.image]
out, exit_status = util.do_with_status(cmd, env=self.buildroot.env,
raiseExc=False, returnOutput=1)
if exit_status:
logger.error(out)
return not int(exit_status)

if not podman_check_native_image_architecture(self.image, logger):
raise BootstrapError("Pulled image has invalid architecture")

def retry_image_pull(self, max_time):
""" Try pulling the image multiple times """
@backoff.on_predicate(backoff.expo, lambda x: not x,
max_time=max_time, jitter=backoff.full_jitter)
def _inner():
self.pull_image()
_inner()

@contextmanager
def mounted_image(self):
Expand All @@ -80,8 +86,10 @@ def mounted_image(self):
bootstrap chroot directory.
"""
logger = getLog()

cmd_mount = [self.podman_binary, "image", "mount", self.image]
cmd_umount = [self.podman_binary, "image", "umount", self.image]

result = subprocess.run(cmd_mount, capture_output=True, check=False, encoding="utf8")
if result.returncode:
message = "Podman mount failed: " + result.stderr
Expand All @@ -100,7 +108,12 @@ def mounted_image(self):
@traceLog()
def cp(self, destination, tar_cmd):
""" copy content of container to destination directory """
getLog().info("Copy content of container %s to %s", self.image, destination)
logger = getLog()
logger.info("Copy content of container %s to %s", self.image, destination)

if not podman_check_native_image_architecture(self.image, logger):
raise BootstrapError("Pulled image has invalid architecture")

with self.mounted_image() as mount_path:
# pipe-out the temporary mountpoint with the help of tar utility
cmd_podman = [tar_cmd, "-C", mount_path, "-c", "."]
Expand Down

0 comments on commit cb74219

Please sign in to comment.