diff options
author | OpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com> | 2020-08-05 10:53:49 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-05 10:53:49 +0200 |
commit | 7a7c8e9911c17e4e1748bbf81ab4df27c78426ab (patch) | |
tree | c7779c4b444053f9cf29c0aa94a7171576cf86f8 /vendor | |
parent | 47971909ae7a54c3a0b0fe4ebe33197c9e291657 (diff) | |
parent | 42d756d77b646e965d29e23d898e303e77c4de5c (diff) | |
download | podman-7a7c8e9911c17e4e1748bbf81ab4df27c78426ab.tar.gz podman-7a7c8e9911c17e4e1748bbf81ab4df27c78426ab.tar.bz2 podman-7a7c8e9911c17e4e1748bbf81ab4df27c78426ab.zip |
Merge pull request #6905 from QiWang19/retry-pull
Retry pulling image
Diffstat (limited to 'vendor')
-rw-r--r-- | vendor/github.com/containers/common/pkg/retry/retry.go | 87 | ||||
-rw-r--r-- | vendor/modules.txt | 1 |
2 files changed, 88 insertions, 0 deletions
diff --git a/vendor/github.com/containers/common/pkg/retry/retry.go b/vendor/github.com/containers/common/pkg/retry/retry.go new file mode 100644 index 000000000..c20f900d8 --- /dev/null +++ b/vendor/github.com/containers/common/pkg/retry/retry.go @@ -0,0 +1,87 @@ +package retry + +import ( + "context" + "math" + "net" + "net/url" + "syscall" + "time" + + "github.com/docker/distribution/registry/api/errcode" + errcodev2 "github.com/docker/distribution/registry/api/v2" + "github.com/hashicorp/go-multierror" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +// RetryOptions defines the option to retry +type RetryOptions struct { + MaxRetry int // The number of times to possibly retry +} + +// RetryIfNecessary retries the operation in exponential backoff with the retryOptions +func RetryIfNecessary(ctx context.Context, operation func() error, retryOptions *RetryOptions) error { + err := operation() + for attempt := 0; err != nil && isRetryable(err) && attempt < retryOptions.MaxRetry; attempt++ { + delay := time.Duration(int(math.Pow(2, float64(attempt)))) * time.Second + logrus.Infof("Warning: failed, retrying in %s ... (%d/%d)", delay, attempt+1, retryOptions.MaxRetry) + select { + case <-time.After(delay): + break + case <-ctx.Done(): + return err + } + err = operation() + } + return err +} + +func isRetryable(err error) bool { + err = errors.Cause(err) + + if err == context.Canceled || err == context.DeadlineExceeded { + return false + } + + type unwrapper interface { + Unwrap() error + } + + switch e := err.(type) { + + case errcode.Error: + switch e.Code { + case errcode.ErrorCodeUnauthorized, errcodev2.ErrorCodeNameUnknown, errcodev2.ErrorCodeManifestUnknown: + return false + } + return true + case *net.OpError: + return isRetryable(e.Err) + case *url.Error: + return isRetryable(e.Err) + case syscall.Errno: + return e != syscall.ECONNREFUSED + case errcode.Errors: + // if this error is a group of errors, process them all in turn + for i := range e { + if !isRetryable(e[i]) { + return false + } + } + return true + case *multierror.Error: + // if this error is a group of errors, process them all in turn + for i := range e.Errors { + if !isRetryable(e.Errors[i]) { + return false + } + } + return true + case unwrapper: + err = e.Unwrap() + return isRetryable(err) + } + + return false +} diff --git a/vendor/modules.txt b/vendor/modules.txt index ac1e5036c..3f490616a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -90,6 +90,7 @@ github.com/containers/common/pkg/auth github.com/containers/common/pkg/capabilities github.com/containers/common/pkg/cgroupv2 github.com/containers/common/pkg/config +github.com/containers/common/pkg/retry github.com/containers/common/pkg/sysinfo github.com/containers/common/version # github.com/containers/conmon v2.0.19+incompatible |