Skip to content

Commit

Permalink
Merge pull request containers#4195 from flouthoc/config-retry-timeout
Browse files Browse the repository at this point in the history
buildah: add support for `--retry` and `--retry-delay` incase of `push/pull` failures.
  • Loading branch information
openshift-merge-robot authored Aug 23, 2022
2 parents 5ca2820 + f46ef3b commit ffbe0e4
Show file tree
Hide file tree
Showing 18 changed files with 152 additions and 15 deletions.
14 changes: 12 additions & 2 deletions cmd/buildah/addcopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"path/filepath"
"strings"
"time"

"github.com/containers/buildah"
"github.com/containers/buildah/internal/util"
Expand Down Expand Up @@ -34,6 +35,8 @@ type addCopyResults struct {
creds string
tlsVerify bool
certDir string
retry int
retryDelay string
}

func createCommand(addCopy string, desc string, short string, opts *addCopyResults) *cobra.Command {
Expand Down Expand Up @@ -78,6 +81,8 @@ func applyFlagVars(flags *pflag.FlagSet, opts *addCopyResults) {
}
flags.StringVar(&opts.ignoreFile, "ignorefile", "", "path to .containerignore file")
flags.StringVar(&opts.contextdir, "contextdir", "", "context directory path")
flags.IntVar(&opts.retry, "retry", buildahcli.MaxPullPushRetries, "number of times to retry in case of failure when performing pull")
flags.StringVar(&opts.retryDelay, "retry-delay", buildahcli.PullPushRetryDelay.String(), "delay between retries in case of pull failures")
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "don't output a digest of the newly-added/copied content")
flags.BoolVar(&opts.tlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing registries when pulling images. TLS verification cannot be used when talking to an insecure registry.")
if err := flags.MarkHidden("tls-verify"); err != nil {
Expand Down Expand Up @@ -165,13 +170,18 @@ func addAndCopyCmd(c *cobra.Command, args []string, verb string, iopts addCopyRe
if err2 != nil {
return fmt.Errorf("unable to obtain decrypt config: %w", err2)
}
var pullPushRetryDelay time.Duration
pullPushRetryDelay, err = time.ParseDuration(iopts.retryDelay)
if err != nil {
return fmt.Errorf("unable to parse value provided %q as --retry-delay: %w", iopts.retryDelay, err)
}
options := buildah.BuilderOptions{
FromImage: iopts.from,
BlobDirectory: iopts.blobCache,
SignaturePolicyPath: iopts.signaturePolicy,
SystemContext: systemContext,
MaxPullRetries: buildahcli.MaxPullPushRetries,
PullRetryDelay: buildahcli.PullPushRetryDelay,
MaxPullRetries: iopts.retry,
PullRetryDelay: pullPushRetryDelay,
OciDecryptConfig: decryptConfig,
}
if !iopts.quiet {
Expand Down
11 changes: 9 additions & 2 deletions cmd/buildah/from.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io/ioutil"
"os"
"strings"
"time"

"github.com/containers/buildah"
"github.com/containers/buildah/define"
Expand Down Expand Up @@ -301,6 +302,12 @@ func fromCmd(c *cobra.Command, args []string, iopts fromReply) error {
return fmt.Errorf("unable to obtain decrypt config: %w", err)
}

var pullPushRetryDelay time.Duration
pullPushRetryDelay, err = time.ParseDuration(iopts.RetryDelay)
if err != nil {
return fmt.Errorf("unable to parse value provided %q as --retry-delay: %w", iopts.RetryDelay, err)
}

options := buildah.BuilderOptions{
FromImage: args[0],
Container: iopts.name,
Expand All @@ -320,8 +327,8 @@ func fromCmd(c *cobra.Command, args []string, iopts fromReply) error {
Format: format,
BlobDirectory: iopts.BlobCache,
Devices: devices,
MaxPullRetries: buildahcli.MaxPullPushRetries,
PullRetryDelay: buildahcli.PullPushRetryDelay,
MaxPullRetries: iopts.Retry,
PullRetryDelay: pullPushRetryDelay,
OciDecryptConfig: decConfig,
}

Expand Down
14 changes: 12 additions & 2 deletions cmd/buildah/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"runtime"
"time"

"github.com/containers/buildah"
"github.com/containers/buildah/define"
Expand All @@ -28,6 +29,8 @@ type pullOptions struct {
tlsVerify bool
decryptionKeys []string
pullPolicy string
retry int
retryDelay string
}

func init() {
Expand Down Expand Up @@ -72,6 +75,8 @@ func init() {
flags.StringSlice("platform", []string{parse.DefaultPlatform()}, "prefer OS/ARCH instead of the current operating system and architecture for choosing images")
flags.String("variant", "", "override the `variant` of the specified image")
flags.BoolVar(&opts.tlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry.")
flags.IntVar(&opts.retry, "retry", buildahcli.MaxPullPushRetries, "number of times to retry in case of failure when performing pull")
flags.StringVar(&opts.retryDelay, "retry-delay", buildahcli.PullPushRetryDelay.String(), "delay between retries in case of pull failures")
if err := flags.MarkHidden("blob-cache"); err != nil {
panic(fmt.Sprintf("error marking blob-cache as hidden: %v", err))
}
Expand Down Expand Up @@ -119,6 +124,11 @@ func pullCmd(c *cobra.Command, args []string, iopts pullOptions) error {
if !ok {
return fmt.Errorf("unsupported pull policy %q", iopts.pullPolicy)
}
var pullPushRetryDelay time.Duration
pullPushRetryDelay, err = time.ParseDuration(iopts.retryDelay)
if err != nil {
return fmt.Errorf("unable to parse value provided %q as --retry-delay: %w", iopts.retryDelay, err)
}
options := buildah.PullOptions{
SignaturePolicyPath: iopts.signaturePolicy,
Store: store,
Expand All @@ -127,8 +137,8 @@ func pullCmd(c *cobra.Command, args []string, iopts pullOptions) error {
AllTags: iopts.allTags,
ReportWriter: os.Stderr,
RemoveSignatures: iopts.removeSignatures,
MaxRetries: buildahcli.MaxPullPushRetries,
RetryDelay: buildahcli.PullPushRetryDelay,
MaxRetries: iopts.retry,
RetryDelay: pullPushRetryDelay,
OciDecryptConfig: decConfig,
PullPolicy: policy,
}
Expand Down
15 changes: 13 additions & 2 deletions cmd/buildah/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io/ioutil"
"os"
"strings"
"time"

"errors"

Expand Down Expand Up @@ -36,6 +37,8 @@ type pushOptions struct {
format string
compressionFormat string
compressionLevel int
retry int
retryDelay string
rm bool
quiet bool
removeSignatures bool
Expand Down Expand Up @@ -88,6 +91,8 @@ func init() {
flags.StringVar(&opts.compressionFormat, "compression-format", "", "compression format to use")
flags.IntVar(&opts.compressionLevel, "compression-level", 0, "compression level to use")
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "don't output progress information when pushing images")
flags.IntVar(&opts.retry, "retry", buildahcli.MaxPullPushRetries, "number of times to retry in case of failure when performing push/pull")
flags.StringVar(&opts.retryDelay, "retry-delay", buildahcli.PullPushRetryDelay.String(), "delay between retries in case of push/pull failures")
flags.BoolVar(&opts.rm, "rm", false, "remove the manifest list if push succeeds")
flags.BoolVarP(&opts.removeSignatures, "remove-signatures", "", false, "don't copy signatures when pushing image")
flags.StringVar(&opts.signBy, "sign-by", "", "sign the image using a GPG key with the specified `FINGERPRINT`")
Expand Down Expand Up @@ -188,6 +193,12 @@ func pushCmd(c *cobra.Command, args []string, iopts pushOptions) error {
return fmt.Errorf("unable to obtain encryption config: %w", err)
}

var pullPushRetryDelay time.Duration
pullPushRetryDelay, err = time.ParseDuration(iopts.retryDelay)
if err != nil {
return fmt.Errorf("unable to parse value provided %q as --retry-delay: %w", iopts.retryDelay, err)
}

options := buildah.PushOptions{
Compression: compress,
ManifestType: manifestType,
Expand All @@ -197,8 +208,8 @@ func pushCmd(c *cobra.Command, args []string, iopts pushOptions) error {
BlobDirectory: iopts.blobCache,
RemoveSignatures: iopts.removeSignatures,
SignBy: iopts.signBy,
MaxRetries: buildahcli.MaxPullPushRetries,
RetryDelay: buildahcli.PullPushRetryDelay,
MaxRetries: iopts.retry,
RetryDelay: pullPushRetryDelay,
OciEncryptConfig: encConfig,
OciEncryptLayers: encLayers,
}
Expand Down
12 changes: 12 additions & 0 deletions docs/buildah-add.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ Path to an alternative .containerignore (.dockerignore) file. Requires \-\-conte

Refrain from printing a digest of the added content.

**--retry** *attempts*

Number of times to retry in case of failure when performing pull of images from registry.

Defaults to `3`.

**--retry-delay** *duration*

Duration of delay between retry attempts in case of failure when performing pull of images from registry.

Defaults to `2s`.

## EXAMPLE

buildah add containerID '/myapp/app.conf' '/myapp/app.conf'
Expand Down
12 changes: 12 additions & 0 deletions docs/buildah-build.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,18 @@ Suppress output messages which indicate which instruction is being processed,
and of progress when pulling images from a registry, and when writing the
output image.

**--retry** *attempts*

Number of times to retry in case of failure when performing push/pull of images to/from registry.

Defaults to `3`.

**--retry-delay** *duration*

Duration of delay between retry attempts in case of failure when performing push/pull of images to/from registry.

Defaults to `2s`.

**--rm** *bool-value*

Remove intermediate containers after a successful build (default true).
Expand Down
12 changes: 12 additions & 0 deletions docs/buildah-copy.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ Path to an alternative .containerignore (.dockerignore) file. Requires \-\-conte

Refrain from printing a digest of the copied content.

**--retry** *attempts*

Number of times to retry in case of failure when performing pull of images from registry.

Defaults to `3`.

**--retry-delay** *duration*

Duration of delay between retry attempts in case of failure when performing pull of images from registry.

Defaults to `2s`.

## EXAMPLE

buildah copy containerID '/myapp/app.conf' '/myapp/app.conf'
Expand Down
12 changes: 12 additions & 0 deletions docs/buildah-from.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,18 @@ Defaults to *true*.

If an image needs to be pulled from the registry, suppress progress output.

**--retry** *attempts*

Number of times to retry in case of failure when performing pull of images from registry.

Defaults to `3`.

**--retry-delay** *duration*

Duration of delay between retry attempts in case of failure when performing pull of images from registry.

Defaults to `2s`.

**--security-opt**=[]

Security Options
Expand Down
12 changes: 12 additions & 0 deletions docs/buildah-pull.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ If an image needs to be pulled from the registry, suppress progress output.

Don't copy signatures when pulling images.

**--retry** *attempts*

Number of times to retry in case of failure when performing pull of images from registry.

Defaults to `3`.

**--retry-delay** *duration*

Duration of delay between retry attempts in case of failure when performing pull of images from registry.

Defaults to `2s`.

**--tls-verify** *bool-value*

Require HTTPS and verification of certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry.
Expand Down
12 changes: 12 additions & 0 deletions docs/buildah-push.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ When writing the output image, suppress progress output.

Don't copy signatures when pushing images.

**--retry** *attempts*

Number of times to retry in case of failure when performing push of images to registry.

Defaults to `3`.

**--retry-delay** *duration*

Duration of delay between retry attempts in case of failure when performing push of images to registry.

Defaults to `2s`.

**--rm**

When pushing a manifest list or image index, delete them from local storage if pushing succeeds.
Expand Down
12 changes: 10 additions & 2 deletions pkg/cli/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,14 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) (
return options, nil, nil, fmt.Errorf("unable to parse value provided %q as --cache-ttl: %w", iopts.CacheTTL, err)
}
}
var pullPushRetryDelay time.Duration
pullPushRetryDelay, err = time.ParseDuration(iopts.RetryDelay)
if err != nil {
return options, nil, nil, fmt.Errorf("unable to parse value provided %q as --retry-delay: %w", iopts.RetryDelay, err)
}
// Following log line is used in integration test.
logrus.Debugf("Setting MaxPullPushRetries to %d and PullPushRetryDelay to %v", iopts.Retry, pullPushRetryDelay)

options = define.BuildOptions{
AddCapabilities: iopts.CapAdd,
AdditionalBuildContexts: additionalBuildContext,
Expand Down Expand Up @@ -349,7 +357,7 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) (
LogRusage: iopts.LogRusage,
LogSplitByPlatform: iopts.LogSplitByPlatform,
Manifest: iopts.Manifest,
MaxPullPushRetries: MaxPullPushRetries,
MaxPullPushRetries: iopts.Retry,
NamespaceOptions: namespaceOptions,
NoCache: iopts.NoCache,
OS: systemContext.OSChoice,
Expand All @@ -361,7 +369,7 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) (
OutputFormat: format,
Platforms: platforms,
PullPolicy: pullPolicy,
PullPushRetryDelay: PullPushRetryDelay,
PullPushRetryDelay: pullPushRetryDelay,
Quiet: iopts.Quiet,
RemoveIntermediateCtrs: iopts.Rm,
ReportWriter: reporter,
Expand Down
6 changes: 6 additions & 0 deletions pkg/cli/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ type FromAndBudResults struct {
Isolation string
Memory string
MemorySwap string
Retry int
RetryDelay string
SecurityOpt []string
ShmSize string
Ulimit []string
Expand Down Expand Up @@ -344,6 +346,8 @@ func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults,
fs.StringVar(&flags.Isolation, "isolation", DefaultIsolation(), "`type` of process isolation to use. Use BUILDAH_ISOLATION environment variable to override.")
fs.StringVarP(&flags.Memory, "memory", "m", "", "memory limit (format: <number>[<unit>], where unit = b, k, m or g)")
fs.StringVar(&flags.MemorySwap, "memory-swap", "", "swap limit equal to memory plus swap: '-1' to enable unlimited swap")
fs.IntVar(&flags.Retry, "retry", MaxPullPushRetries, "number of times to retry in case of failure when performing push/pull")
fs.StringVar(&flags.RetryDelay, "retry-delay", PullPushRetryDelay.String(), "delay between retries in case of push/pull failures")
fs.String("arch", runtime.GOARCH, "set the ARCH of the image to the provided value instead of the architecture of the host")
fs.String("os", runtime.GOOS, "prefer `OS` instead of the running OS when pulling images")
fs.StringSlice("platform", []string{parse.DefaultPlatform()}, "set the OS/ARCH/VARIANT of the image to the provided value instead of the current operating system and architecture of the host (for example `linux/arm`)")
Expand Down Expand Up @@ -386,6 +390,8 @@ func GetFromAndBudFlagsCompletions() commonComp.FlagCompletions {
flagCompletion["memory-swap"] = commonComp.AutocompleteNone
flagCompletion["os"] = commonComp.AutocompleteNone
flagCompletion["platform"] = commonComp.AutocompleteNone
flagCompletion["retry"] = commonComp.AutocompleteNone
flagCompletion["retry-delay"] = commonComp.AutocompleteNone
flagCompletion["security-opt"] = commonComp.AutocompleteNone
flagCompletion["shm-size"] = commonComp.AutocompleteNone
flagCompletion["ulimit"] = commonComp.AutocompleteNone
Expand Down
2 changes: 1 addition & 1 deletion tests/add.bats
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ load helpers
mkdir $root/subdir $root/other-subdir
# Copy a file to the working directory
run_buildah config --workingdir=/ $cid
run_buildah add $cid ${TEST_SCRATCH_DIR}/randomfile
run_buildah add --retry 4 --retry-delay 4s $cid ${TEST_SCRATCH_DIR}/randomfile
# Copy a file to a specific subdirectory
run_buildah add $cid ${TEST_SCRATCH_DIR}/randomfile /subdir
# Copy two files to a specific subdirectory
Expand Down
13 changes: 13 additions & 0 deletions tests/bud.bats
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,19 @@ _EOF
assert "$output" !~ "unwanted stage"
}

@test "build test --retry and --retry-delay" {
mkdir -p ${TEST_SCRATCH_DIR}/bud/platform

echo something > ${TEST_SCRATCH_DIR}/bud/platform/somefile
cat > ${TEST_SCRATCH_DIR}/bud/platform/Dockerfile << _EOF
FROM alpine
RUN echo hello
_EOF

run_buildah --log-level debug build --retry 4 --retry-delay 5s $WITH_POLICY_JSON --layers -t source -f ${TEST_SCRATCH_DIR}/bud/platform/Dockerfile ${TEST_SCRATCH_DIR}/bud/platform
expect_output --substring "Setting MaxPullPushRetries to 4 and PullPushRetryDelay to 5s"
}

# Test skipping unwanted stage with COPY from stage index
@test "build-test skipping unwanted stages with COPY from stage index" {
mkdir -p ${TEST_SCRATCH_DIR}/bud/platform
Expand Down
2 changes: 1 addition & 1 deletion tests/copy.bats
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ load helpers
root=$output
run_buildah config --workingdir / $cid
# copy ${TEST_SCRATCH_DIR}/randomfile to a file of the same name in the container's working directory
run_buildah copy $cid ${TEST_SCRATCH_DIR}/randomfile
run_buildah copy --retry 4 --retry-delay 4s $cid ${TEST_SCRATCH_DIR}/randomfile
# copy ${TEST_SCRATCH_DIR}/other-randomfile and ${TEST_SCRATCH_DIR}/third-randomfile to a new directory named ${TEST_SCRATCH_DIR}/randomfile in the container
run_buildah copy $cid ${TEST_SCRATCH_DIR}/other-randomfile ${TEST_SCRATCH_DIR}/third-randomfile ${TEST_SCRATCH_DIR}/randomfile
# try to copy ${TEST_SCRATCH_DIR}/other-randomfile and ${TEST_SCRATCH_DIR}/third-randomfile to a /randomfile, which already exists and is a file
Expand Down
2 changes: 1 addition & 1 deletion tests/from.bats
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ load helpers
elsewhere=${TEST_SCRATCH_DIR}/elsewhere-img
mkdir -p ${elsewhere}

run_buildah from --pull $WITH_POLICY_JSON scratch
run_buildah from --retry 4 --retry-delay 4s --pull $WITH_POLICY_JSON scratch
cid=$output
run_buildah commit $WITH_POLICY_JSON $cid dir:${elsewhere}
run_buildah rm $cid
Expand Down
Loading

0 comments on commit ffbe0e4

Please sign in to comment.