From 08a1c6d91e96e00eb3b16b52e9f7d93b1ef0f7e9 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Tue, 25 Mar 2025 12:50:41 +0100 Subject: [PATCH] Add support for Retry= and RetryDelay= to Podman Quadlet. This commit adds new Retry= and RetryDelay= options to quadlet.go which result in --retry and --retry-delay usage in podman run, image and build commands. This allows configuring the retry logic in the systemd files. Fixes: #25109 Signed-off-by: Jan Kaluza --- docs/source/markdown/podman-systemd.unit.5.md | 30 +++++++++++++++++++ pkg/systemd/quadlet/quadlet.go | 22 +++++++++++--- test/e2e/quadlet/retry.build | 8 +++++ test/e2e/quadlet/retry.container | 7 +++++ test/e2e/quadlet/retry.image | 7 +++++ test/e2e/quadlet_test.go | 3 ++ 6 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 test/e2e/quadlet/retry.build create mode 100644 test/e2e/quadlet/retry.container create mode 100644 test/e2e/quadlet/retry.image diff --git a/docs/source/markdown/podman-systemd.unit.5.md b/docs/source/markdown/podman-systemd.unit.5.md index 57329845a3..b5dfd8970e 100644 --- a/docs/source/markdown/podman-systemd.unit.5.md +++ b/docs/source/markdown/podman-systemd.unit.5.md @@ -332,6 +332,8 @@ Valid options for `[Container]` are listed below: | Pull=never | --pull never | | ReadOnly=true | --read-only | | ReadOnlyTmpfs=true | --read-only-tmpfs | +| Retry=5 | --retry=5 | +| RetryDelay=5s | --retry-delay=5s | | Rootfs=/var/lib/rootfs | --rootfs /var/lib/rootfs | | RunInit=true | --init | | SeccompProfile=/tmp/s.json | --security-opt seccomp=/tmp/s.json | @@ -781,6 +783,14 @@ If enabled, makes the image read-only. If ReadOnly is set to `true`, mount a read-write tmpfs on /dev, /dev/shm, /run, /tmp, and /var/tmp. +### `Retry=` + +Number of times to retry the image pull when a HTTP error occurs. Equivalent to the Podman `--retry` option. + +### `RetryDelay=` + +Delay between retries. Equivalent to the Podman `--retry-delay` option. + ### `Rootfs=` The rootfs to use for the container. Rootfs points to a directory on the system that contains the content to be run within the container. This option conflicts with the `Image` option. @@ -1611,6 +1621,8 @@ Valid options for `[Build]` are listed below: | Network=host | --network=host | | PodmanArgs=--pull never | --pull never | | Pull=never | --pull never | +| Retry=5 | --retry=5 | +| RetryDelay=10s | --retry-delay=10s | | Secret=secret | --secret=id=mysecret,src=path | | SetWorkingDirectory=unit | Set `WorkingDirectory` of systemd unit file | | Target=my-app | --target=my-app | @@ -1757,6 +1769,14 @@ Set the image pull policy. This is equivalent to the `--pull` option of `podman build`. +### `Retry=` + +Number of times to retry the image pull when a HTTP error occurs. Equivalent to the Podman `--retry` option. + +### `RetryDelay=` + +Delay between retries. Equivalent to the Podman `--retry-delay` option. + ### `Secret=` Pass secret information used in Containerfile build stages in a safe way. @@ -1843,6 +1863,8 @@ Valid options for `[Image]` are listed below: | ImageTag=quay\.io/centos/centos:latest | Use this name when resolving `.image` references | | OS=windows | --os=windows | | PodmanArgs=--os=linux | --os=linux | +| Retry=5 | --retry=5 | +| RetryDelay=10s | --retry-delay=10s | | TLSVerify=false | --tls-verify=false | | Variant=arm/v7 | --variant=arm/v7 | @@ -1941,6 +1963,14 @@ escaped to allow inclusion of whitespace and other control characters. This key can be listed multiple times. +### `Retry=` + +Number of times to retry the image pull when a HTTP error occurs. Equivalent to the Podman `--retry` option. + +### `RetryDelay=` + +Delay between retries. Equivalent to the Podman `--retry-delay` option. + ### `TLSVerify=` Require HTTPS and verification of certificates when contacting registries. diff --git a/pkg/systemd/quadlet/quadlet.go b/pkg/systemd/quadlet/quadlet.go index 3a51b22aba..e08550f4a8 100644 --- a/pkg/systemd/quadlet/quadlet.go +++ b/pkg/systemd/quadlet/quadlet.go @@ -143,6 +143,8 @@ const ( KeyRemapUid = "RemapUid" //nolint:stylecheck // deprecated KeyRemapUidSize = "RemapUidSize" //nolint:stylecheck // deprecated KeyRemapUsers = "RemapUsers" // deprecated + KeyRetry = "Retry" + KeyRetryDelay = "RetryDelay" KeyRootfs = "Rootfs" KeyRunInit = "RunInit" KeySeccompProfile = "SeccompProfile" @@ -258,6 +260,8 @@ var ( KeyRemapUid: true, KeyRemapUidSize: true, KeyRemapUsers: true, + KeyRetry: true, + KeyRetryDelay: true, KeyRootfs: true, KeyRunInit: true, KeySeccompProfile: true, @@ -362,6 +366,8 @@ var ( KeyImageTag: true, KeyOS: true, KeyPodmanArgs: true, + KeyRetry: true, + KeyRetryDelay: true, KeyServiceName: true, KeyTLSVerify: true, KeyVariant: true, @@ -386,6 +392,8 @@ var ( KeyNetwork: true, KeyPodmanArgs: true, KeyPull: true, + KeyRetry: true, + KeyRetryDelay: true, KeySecret: true, KeyServiceName: true, KeySetWorkingDirectory: true, @@ -641,6 +649,8 @@ func ConvertContainer(container *parser.UnitFile, isUser bool, unitsInfoMap map[ KeyStopTimeout: "--stop-timeout", KeyPull: "--pull", KeyMemory: "--memory", + KeyRetry: "--retry", + KeyRetryDelay: "--retry-delay", } lookupAndAddString(container, ContainerGroup, stringKeys, podman) @@ -1365,6 +1375,8 @@ func ConvertImage(image *parser.UnitFile, unitsInfoMap map[string]*UnitInfo, isU KeyDecryptionKey: "--decryption-key", KeyOS: "--os", KeyVariant: "--variant", + KeyRetry: "--retry", + KeyRetryDelay: "--retry-delay", } lookupAndAddString(image, ImageGroup, stringKeys, podman) @@ -1437,10 +1449,12 @@ func ConvertBuild(build *parser.UnitFile, unitsInfoMap map[string]*UnitInfo, isU } stringKeys := map[string]string{ - KeyArch: "--arch", - KeyAuthFile: "--authfile", - KeyTarget: "--target", - KeyVariant: "--variant", + KeyArch: "--arch", + KeyAuthFile: "--authfile", + KeyTarget: "--target", + KeyVariant: "--variant", + KeyRetry: "--retry", + KeyRetryDelay: "--retry-delay", } lookupAndAddString(build, BuildGroup, stringKeys, podman) diff --git a/test/e2e/quadlet/retry.build b/test/e2e/quadlet/retry.build new file mode 100644 index 0000000000..958fa27026 --- /dev/null +++ b/test/e2e/quadlet/retry.build @@ -0,0 +1,8 @@ +## assert-podman-args "--retry" "5" +## assert-podman-args "--retry-delay" "10s" + +[Build] +ImageTag=localhost/imagename +SetWorkingDirectory=unit +Retry=5 +RetryDelay=10s diff --git a/test/e2e/quadlet/retry.container b/test/e2e/quadlet/retry.container new file mode 100644 index 0000000000..3b90f096c9 --- /dev/null +++ b/test/e2e/quadlet/retry.container @@ -0,0 +1,7 @@ +## assert-podman-args "--retry" "5" +## assert-podman-args "--retry-delay" "10s" + +[Container] +Image=localhost/imagename +Retry=5 +RetryDelay=10s diff --git a/test/e2e/quadlet/retry.image b/test/e2e/quadlet/retry.image new file mode 100644 index 0000000000..87068cc1cd --- /dev/null +++ b/test/e2e/quadlet/retry.image @@ -0,0 +1,7 @@ +## assert-podman-args "--retry" "5" +## assert-podman-args "--retry-delay" "10s" + +[Image] +Image=localhost/imagename +Retry=5 +RetryDelay=10s diff --git a/test/e2e/quadlet_test.go b/test/e2e/quadlet_test.go index c7a541a143..b716441c6c 100644 --- a/test/e2e/quadlet_test.go +++ b/test/e2e/quadlet_test.go @@ -925,6 +925,7 @@ BOGUS=foo Entry("NetworkAlias", "network-alias.container"), Entry("CgroupMode", "cgroups-mode.container"), Entry("Container - No Default Dependencies", "no_deps.container"), + Entry("retry.container", "retry.container"), Entry("basic.volume", "basic.volume"), Entry("device-copy.volume", "device-copy.volume"), @@ -994,6 +995,7 @@ BOGUS=foo Entry("Image - Containers Conf Modules", "containersconfmodule.image"), Entry("Image - Unit After Override", "unit-after-override.image"), Entry("Image - No Default Dependencies", "no_deps.image"), + Entry("Image - Retry", "retry.image"), Entry("Build - Basic", "basic.build"), Entry("Build - Annotation Key", "annotation.build"), @@ -1028,6 +1030,7 @@ BOGUS=foo Entry("Build - TLSVerify Key", "tls-verify.build"), Entry("Build - Variant Key", "variant.build"), Entry("Build - No Default Dependencies", "no_deps.build"), + Entry("Build - Retry", "retry.build"), Entry("Pod - Basic", "basic.pod"), Entry("Pod - DNS", "dns.pod"),