mirror of https://github.com/containers/podman.git
Add support for podman push --retry --retry-delay
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
parent
e5ee0bb5f3
commit
c3c0c4ab96
|
@ -114,10 +114,10 @@ func pullFlags(cmd *cobra.Command) {
|
|||
_ = cmd.RegisterFlagCompletionFunc(decryptionKeysFlagName, completion.AutocompleteDefault)
|
||||
|
||||
retryFlagName := "retry"
|
||||
flags.Uint(retryFlagName, cli.MaxPullPushRetries, "number of times to retry in case of failure when performing pull")
|
||||
flags.Uint(retryFlagName, registry.RetryDefault(), "number of times to retry in case of failure when performing pull")
|
||||
_ = cmd.RegisterFlagCompletionFunc(retryFlagName, completion.AutocompleteNone)
|
||||
retryDelayFlagName := "retry-delay"
|
||||
flags.String(retryDelayFlagName, cli.PullPushRetryDelay.String(), "delay between retries in case of pull failures")
|
||||
flags.String(retryDelayFlagName, registry.RetryDelayDefault(), "delay between retries in case of pull failures")
|
||||
_ = cmd.RegisterFlagCompletionFunc(retryDelayFlagName, completion.AutocompleteNone)
|
||||
|
||||
if registry.IsRemote() {
|
||||
|
|
|
@ -111,6 +111,13 @@ func pushFlags(cmd *cobra.Command) {
|
|||
flags.BoolVarP(&pushOptions.Quiet, "quiet", "q", false, "Suppress output information when pushing images")
|
||||
flags.BoolVar(&pushOptions.RemoveSignatures, "remove-signatures", false, "Discard any pre-existing signatures in the image")
|
||||
|
||||
retryFlagName := "retry"
|
||||
flags.Uint(retryFlagName, registry.RetryDefault(), "number of times to retry in case of failure when performing push")
|
||||
_ = cmd.RegisterFlagCompletionFunc(retryFlagName, completion.AutocompleteNone)
|
||||
retryDelayFlagName := "retry-delay"
|
||||
flags.String(retryDelayFlagName, registry.RetryDelayDefault(), "delay between retries in case of push failures")
|
||||
_ = cmd.RegisterFlagCompletionFunc(retryDelayFlagName, completion.AutocompleteNone)
|
||||
|
||||
signByFlagName := "sign-by"
|
||||
flags.StringVar(&pushOptions.SignBy, signByFlagName, "", "Add a signature at the destination using the specified key")
|
||||
_ = cmd.RegisterFlagCompletionFunc(signByFlagName, completion.AutocompleteNone)
|
||||
|
@ -208,6 +215,24 @@ func imagePush(cmd *cobra.Command, args []string) error {
|
|||
pushOptions.OciEncryptConfig = encConfig
|
||||
pushOptions.OciEncryptLayers = encLayers
|
||||
|
||||
if cmd.Flags().Changed("retry") {
|
||||
retry, err := cmd.Flags().GetUint("retry")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pushOptions.Retry = &retry
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("retry-delay") {
|
||||
val, err := cmd.Flags().GetString("retry-delay")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pushOptions.RetryDelay = val
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("compression-level") {
|
||||
val, err := cmd.Flags().GetInt("compression-level")
|
||||
if err != nil {
|
||||
|
|
|
@ -166,3 +166,19 @@ func setXdgDirs() error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RetryDefault() uint {
|
||||
if IsRemote() {
|
||||
return 0
|
||||
}
|
||||
|
||||
return PodmanConfig().ContainersConfDefaultsRO.Engine.Retry
|
||||
}
|
||||
|
||||
func RetryDelayDefault() string {
|
||||
if IsRemote() {
|
||||
return ""
|
||||
}
|
||||
|
||||
return PodmanConfig().ContainersConfDefaultsRO.Engine.RetryDelay
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
####> This option file is used in:
|
||||
####> podman build, farm build, pull
|
||||
####> podman build, farm build, pull, push
|
||||
####> If file is edited, make sure the changes
|
||||
####> are applicable to all of those.
|
||||
#### **--retry-delay**=*duration*
|
||||
|
||||
Duration of delay between retry attempts in case of failure when performing pull of images from registry. Default is **2s**.
|
||||
Duration of delay between retry attempts when pulling or pushing images between
|
||||
the registry and local storage in case of failure. The default is to start at two seconds and then exponentially back off. The delay is used when this value is set, and no exponential back off occurs.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
####> This option file is used in:
|
||||
####> podman build, farm build, pull
|
||||
####> podman build, farm build, pull, push
|
||||
####> If file is edited, make sure the changes
|
||||
####> are applicable to all of those.
|
||||
#### **--retry**=*attempts*
|
||||
|
||||
Number of times to retry in case of failure when performing pull of
|
||||
images from registry. Default is **3**.
|
||||
Number of times to retry pulling or pushing images between the registry and
|
||||
local storage in case of failure. Default is **3**.
|
||||
|
|
|
@ -84,6 +84,10 @@ When writing the output image, suppress progress output
|
|||
|
||||
Discard any pre-existing signatures in the image.
|
||||
|
||||
@@option retry
|
||||
|
||||
@@option retry-delay
|
||||
|
||||
#### **--sign-by**=*key*
|
||||
|
||||
Add a “simple signing” signature at the destination using the specified key. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines)
|
||||
|
|
|
@ -32,6 +32,8 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
|
|||
Destination string `schema:"destination"`
|
||||
Format string `schema:"format"`
|
||||
RemoveSignatures bool `schema:"removeSignatures"`
|
||||
Retry uint `schema:"retry"`
|
||||
RetryDelay string `schema:"retryDelay"`
|
||||
TLSVerify bool `schema:"tlsVerify"`
|
||||
Quiet bool `schema:"quiet"`
|
||||
}{
|
||||
|
@ -83,9 +85,14 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
|
|||
Password: password,
|
||||
Quiet: query.Quiet,
|
||||
RemoveSignatures: query.RemoveSignatures,
|
||||
RetryDelay: query.RetryDelay,
|
||||
Username: username,
|
||||
}
|
||||
|
||||
if _, found := r.URL.Query()["retry"]; found {
|
||||
options.Retry = &query.Retry
|
||||
}
|
||||
|
||||
if _, found := r.URL.Query()["compressionFormat"]; found {
|
||||
if _, foundForceCompression := r.URL.Query()["forceCompressionFormat"]; !foundForceCompression {
|
||||
// If `compressionFormat` is set and no value for `forceCompressionFormat`
|
||||
|
|
|
@ -162,6 +162,10 @@ type PushOptions struct {
|
|||
SkipTLSVerify *bool `schema:"-"`
|
||||
// RemoveSignatures Discard any pre-existing signatures in the image.
|
||||
RemoveSignatures *bool
|
||||
// Retry number of times to retry push in case of failure
|
||||
Retry *uint
|
||||
// RetryDelay between retries in case of push failures
|
||||
RetryDelay *string
|
||||
// Username for authenticating against the registry.
|
||||
Username *string `schema:"-"`
|
||||
// Quiet can be specified to suppress progress when pushing.
|
||||
|
|
|
@ -198,6 +198,36 @@ func (o *PushOptions) GetRemoveSignatures() bool {
|
|||
return *o.RemoveSignatures
|
||||
}
|
||||
|
||||
// WithRetry set field Retry to given value
|
||||
func (o *PushOptions) WithRetry(value uint) *PushOptions {
|
||||
o.Retry = &value
|
||||
return o
|
||||
}
|
||||
|
||||
// GetRetry returns value of field Retry
|
||||
func (o *PushOptions) GetRetry() uint {
|
||||
if o.Retry == nil {
|
||||
var z uint
|
||||
return z
|
||||
}
|
||||
return *o.Retry
|
||||
}
|
||||
|
||||
// WithRetryDelay set field RetryDelay to given value
|
||||
func (o *PushOptions) WithRetryDelay(value string) *PushOptions {
|
||||
o.RetryDelay = &value
|
||||
return o
|
||||
}
|
||||
|
||||
// GetRetryDelay returns value of field RetryDelay
|
||||
func (o *PushOptions) GetRetryDelay() string {
|
||||
if o.RetryDelay == nil {
|
||||
var z string
|
||||
return z
|
||||
}
|
||||
return *o.RetryDelay
|
||||
}
|
||||
|
||||
// WithUsername set field Username to given value
|
||||
func (o *PushOptions) WithUsername(value string) *PushOptions {
|
||||
o.Username = &value
|
||||
|
|
|
@ -151,6 +151,10 @@ type ImagePushOptions struct {
|
|||
// RemoveSignatures, discard any pre-existing signatures in the image.
|
||||
// Ignored for remote calls.
|
||||
RemoveSignatures bool
|
||||
// Retry number of times to retry push in case of failure
|
||||
Retry *uint
|
||||
// RetryDelay between retries in case of push failures
|
||||
RetryDelay string
|
||||
// SignaturePolicy to use when pulling. Ignored for remote calls.
|
||||
SignaturePolicy string
|
||||
// Signers, if non-empty, asks for signatures to be added during the copy
|
||||
|
|
|
@ -254,8 +254,8 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
|
|||
pullOptions.InsecureSkipTLSVerify = options.SkipTLSVerify
|
||||
pullOptions.Writer = options.Writer
|
||||
pullOptions.OciDecryptConfig = options.OciDecryptConfig
|
||||
|
||||
pullOptions.MaxRetries = options.Retry
|
||||
|
||||
if options.RetryDelay != "" {
|
||||
duration, err := time.ParseDuration(options.RetryDelay)
|
||||
if err != nil {
|
||||
|
@ -343,6 +343,14 @@ func (ir *ImageEngine) Push(ctx context.Context, source string, destination stri
|
|||
pushOptions.OciEncryptLayers = options.OciEncryptLayers
|
||||
pushOptions.CompressionLevel = options.CompressionLevel
|
||||
pushOptions.ForceCompressionFormat = options.ForceCompressionFormat
|
||||
pushOptions.MaxRetries = options.Retry
|
||||
if options.RetryDelay != "" {
|
||||
duration, err := time.ParseDuration(options.RetryDelay)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pushOptions.RetryDelay = &duration
|
||||
}
|
||||
|
||||
compressionFormat := options.CompressionFormat
|
||||
if compressionFormat == "" {
|
||||
|
|
|
@ -273,6 +273,12 @@ func (ir *ImageEngine) Push(ctx context.Context, source string, destination stri
|
|||
options.WithSkipTLSVerify(false)
|
||||
}
|
||||
}
|
||||
if opts.Retry != nil {
|
||||
options.WithRetry(*opts.Retry)
|
||||
}
|
||||
if opts.RetryDelay != "" {
|
||||
options.WithRetryDelay(opts.RetryDelay)
|
||||
}
|
||||
if err := images.Push(ir.ClientCtx, source, destination, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -327,7 +327,7 @@ function _test_skopeo_credential_sharing() {
|
|||
|
||||
}
|
||||
|
||||
@test "podman images with retry" {
|
||||
@test "podman pull images with retry" {
|
||||
run_podman pull -q --retry 4 --retry-delay "10s" $IMAGE
|
||||
run_podman 125 pull -q --retry 4 --retry-delay "bogus" $IMAGE
|
||||
is "$output" 'Error: time: invalid duration "bogus"' "bad retry-delay"
|
||||
|
@ -367,6 +367,30 @@ function _test_skopeo_credential_sharing() {
|
|||
run_podman rmi $image1
|
||||
}
|
||||
|
||||
@test "podman containers.conf retry" {
|
||||
skip_if_remote "containers.conf settings not set for remote connections"
|
||||
run_podman pull --help
|
||||
assert "$output" =~ "--retry .*performing pull \(default 3\)"
|
||||
|
||||
run_podman push --help
|
||||
assert "$output" =~ "--retry .*performing push \(default 3\)"
|
||||
|
||||
containersConf=$PODMAN_TMPDIR/containers.conf
|
||||
cat >$containersConf <<EOF
|
||||
[engine]
|
||||
retry=10
|
||||
retry_delay="5s"
|
||||
EOF
|
||||
|
||||
CONTAINERS_CONF="$containersConf" run_podman pull --help
|
||||
assert "$output" =~ "--retry .*performing pull \(default 10\)"
|
||||
assert "$output" =~ "--retry-delay .*pull failures \(default \"5s\"\)"
|
||||
|
||||
CONTAINERS_CONF="$containersConf" run_podman push --help
|
||||
assert "$output" =~ "--retry .*performing push \(default 10\)"
|
||||
assert "$output" =~ "--retry-delay .*push failures \(default \"5s\"\)"
|
||||
}
|
||||
|
||||
# END cooperation with skopeo
|
||||
# END actual tests
|
||||
###############################################################################
|
||||
|
|
Loading…
Reference in New Issue