Merge pull request #15246 from TomSweeneyRedHat/dev/tsweeney/buildah1.27.0

Bump to Buildah v1.27.0
This commit is contained in:
OpenShift Merge Robot 2022-08-09 13:32:07 +00:00 committed by GitHub
commit a7af6ef632
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 863 additions and 248 deletions

View File

@ -18,6 +18,7 @@ import (
"github.com/containers/common/pkg/auth"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker/reference"
encconfig "github.com/containers/ocicrypt/config"
enchelpers "github.com/containers/ocicrypt/helpers"
"github.com/containers/podman/v4/cmd/podman/common"
@ -184,7 +185,6 @@ func buildFlags(cmd *cobra.Command) {
flags.SetNormalizeFunc(buildahCLI.AliasFlags)
if registry.IsRemote() {
_ = flags.MarkHidden("disable-content-trust")
_ = flags.MarkHidden("cache-from")
_ = flags.MarkHidden("sign-by")
_ = flags.MarkHidden("signature-policy")
_ = flags.MarkHidden("tls-verify")
@ -519,6 +519,27 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil
}
}
}
var cacheTo reference.Named
var cacheFrom reference.Named
if c.Flag("cache-to").Changed {
cacheTo, err = parse.RepoNameToNamedReference(flags.CacheTo)
if err != nil {
return nil, fmt.Errorf("unable to parse value provided `%s` to --cache-to: %w", flags.CacheTo, err)
}
}
if c.Flag("cache-from").Changed {
cacheFrom, err = parse.RepoNameToNamedReference(flags.CacheFrom)
if err != nil {
return nil, fmt.Errorf("unable to parse value provided `%s` to --cache-from: %w", flags.CacheTo, err)
}
}
var cacheTTL time.Duration
if c.Flag("cache-ttl").Changed {
cacheTTL, err = time.ParseDuration(flags.CacheTTL)
if err != nil {
return nil, fmt.Errorf("unable to parse value provided %q as --cache-ttl: %w", flags.CacheTTL, err)
}
}
opts := buildahDefine.BuildOptions{
AddCapabilities: flags.CapAdd,
@ -529,6 +550,9 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil
Args: args,
BlobDirectory: flags.BlobCache,
BuildOutput: flags.BuildOutput,
CacheFrom: cacheFrom,
CacheTo: cacheTo,
CacheTTL: cacheTTL,
CommonBuildOpts: commonOpts,
Compression: compression,
ConfigureNetwork: networkPolicy,

View File

@ -120,8 +120,43 @@ The value of [name] is matched with the following priority order:
#### **--cache-from**
Images to utilize as potential cache sources. Podman does not currently support
caching so this is a NOOP. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines)
Repository to utilize as a potential cache source. When specified, Buildah will try to look for
cache images in the specified repository and will attempt to pull cache images instead of actually
executing the build steps locally. Buildah will only attempt to pull previously cached images if they
are considered as valid cache hits.
Use the `--cache-to` option to populate a remote repository with cache content.
Example
```bash
# populate a cache and also consult it
buildah build -t test --layers --cache-to registry/myrepo/cache --cache-from registry/myrepo/cache .
```
Note: `--cache-from` option is ignored unless `--layers` is specified.
#### **--cache-to**
Set this flag to specify a remote repository that will be used to store cache images. Buildah will attempt to
push newly built cache image to the remote repository.
Note: Use the `--cache-from` option in order to use cache content in a remote repository.
Example
```bash
# populate a cache and also consult it
buildah build -t test --layers --cache-to registry/myrepo/cache --cache-from registry/myrepo/cache .
```
Note: `--cache-to` option is ignored unless `--layers` is specified.
#### **--cache-ttl**
Limit the use of cached images to only consider images with created timestamps less than *duration* ago.
For example if `--cache-ttl=1h` is specified, Buildah will only consider intermediate cache images which are created
under the duration of one hour, and intermediate cache images outside this duration will be ignored.
#### **--cap-add**=*CAP\_xxx*

2
go.mod
View File

@ -11,7 +11,7 @@ require (
github.com/container-orchestrated-devices/container-device-interface v0.4.0
github.com/containernetworking/cni v1.1.2
github.com/containernetworking/plugins v1.1.1
github.com/containers/buildah v1.26.1-0.20220716095526-d31d27c357ab
github.com/containers/buildah v1.27.0
github.com/containers/common v0.49.2-0.20220804143628-dc97077782d5
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.22.0

13
go.sum
View File

@ -392,15 +392,13 @@ github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRD
github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE=
github.com/containernetworking/plugins v1.1.1 h1:+AGfFigZ5TiQH00vhR8qPeSatj53eNGz0C1d3wVYlHE=
github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8=
github.com/containers/buildah v1.26.1-0.20220716095526-d31d27c357ab h1:NeI0DOkTf3Tn4OpdjMhMubAfTPs2oCO5jUY5wnpv4qk=
github.com/containers/buildah v1.26.1-0.20220716095526-d31d27c357ab/go.mod h1:iVtQtU6a+pbETBqIzg0oAWW3gTR1ItrAihJpLFFppmA=
github.com/containers/common v0.48.1-0.20220715075726-2ac10faca05a/go.mod h1:1dA7JPGoSi83kjf5H4NIrGANyLOULyvFqV1bwvYFEek=
github.com/containers/buildah v1.27.0 h1:LJ1ks7vKxwPzJGr5BWVvigbtVL9w7XeHtNEmiIOPJqI=
github.com/containers/buildah v1.27.0/go.mod h1:anH3ExvDXRNP9zLQCrOc1vWb5CrhqLF/aYFim4tslvA=
github.com/containers/common v0.49.1/go.mod h1:ueM5hT0itKqCQvVJDs+EtjornAQtrHYxQJzP2gxeGIg=
github.com/containers/common v0.49.2-0.20220804143628-dc97077782d5 h1:bOdbfjiOvj5n51dyeo8LF3qAtvaiflS13q70Cx4NA40=
github.com/containers/common v0.49.2-0.20220804143628-dc97077782d5/go.mod h1:ueM5hT0itKqCQvVJDs+EtjornAQtrHYxQJzP2gxeGIg=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.21.2-0.20220712113758-29aec5f7bbbf/go.mod h1:0+N0ZM9mgMmoZZc6uNcgnEsbX85Ne7b29cIW5lqWwVU=
github.com/containers/image/v5 v5.21.2-0.20220714132403-2bb3f3e44c5c/go.mod h1:ykVAVRj4DhQNMHZDVU+KCtXjWBKpqiUe669eF0WBEEc=
github.com/containers/image/v5 v5.22.0 h1:KemxPmD4D2YYOFZN2SgoTk7nBFcnwPiPW0MqjYtknSE=
github.com/containers/image/v5 v5.22.0/go.mod h1:D8Ksv2RNB8qLJ7xe1P3rgJJOSQpahA6amv2Ax++/YO4=
github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a h1:spAGlqziZjCJL25C6F1zsQY05tfCKE9F5YwtEWWe6hU=
@ -416,9 +414,6 @@ github.com/containers/psgo v1.7.2 h1:WbCvsY9w+nCv3j4der0mbD3PSRUv/W8l+G0YrZrdSDc
github.com/containers/psgo v1.7.2/go.mod h1:SLpqxsPOHtTqRygjutCPXmeU2PoEFzV3gzJplN4BMx0=
github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4=
github.com/containers/storage v1.38.0/go.mod h1:lBzt28gAk5ADZuRtwdndRJyqX22vnRaXmlF+7ktfMYc=
github.com/containers/storage v1.41.0/go.mod h1:Pb0l5Sm/89kolX3o2KolKQ5cCHk5vPNpJrhNaLcdS5s=
github.com/containers/storage v1.41.1-0.20220712184034-d26be7b27860/go.mod h1:uu6HCcijN30xRxW1ZuZRngwFGOlH5NpBWYiNBnDQNRw=
github.com/containers/storage v1.41.1-0.20220714115232-fc9b0ff5272a/go.mod h1:4DfR+cPpkXKhJnnyydD3z82DXrnTBT63y1k0QWtM2i4=
github.com/containers/storage v1.42.0 h1:zm2AQD4NDeTB3JQ8X+Wo5+VRqNB+b4ocEd7Qj6ylPJA=
github.com/containers/storage v1.42.0/go.mod h1:JiUJwOgOo1dr2DdOUc1MRe2GCAXABYoYmOdPF8yvH78=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
@ -1041,7 +1036,6 @@ github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.4/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/compress v1.15.7/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/compress v1.15.8/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
@ -1308,7 +1302,6 @@ github.com/opencontainers/runtime-spec v1.0.3-0.20211214071223-8958f93039ab h1:Y
github.com/opencontainers/runtime-spec v1.0.3-0.20211214071223-8958f93039ab/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/runtime-tools v0.0.0-20190417131837-cd1349b7c47e/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/runtime-tools v0.9.0/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/runtime-tools v0.9.1-0.20220714195903-17b3287fafb7 h1:Rf+QsQGxrYCia8mVyOPnoQZ+vJkZGL+ESWBDUM5s9cQ=
github.com/opencontainers/runtime-tools v0.9.1-0.20220714195903-17b3287fafb7/go.mod h1:/tgP02fPXGHkU3/qKK1Y0Db4yqNyGm03vLq/mzHzcS4=
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=

View File

@ -17,6 +17,7 @@ import (
"github.com/containers/buildah"
buildahDefine "github.com/containers/buildah/define"
"github.com/containers/buildah/pkg/parse"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/pkg/api/handlers/utils"
@ -78,6 +79,8 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
AppArmor string `schema:"apparmor"`
BuildArgs string `schema:"buildargs"`
CacheFrom string `schema:"cachefrom"`
CacheTo string `schema:"cacheto"`
CacheTTL string `schema:"cachettl"`
CgroupParent string `schema:"cgroupparent"`
Compression uint64 `schema:"compression"`
ConfigureNetwork string `schema:"networkmode"`
@ -386,6 +389,31 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
}
}
var cacheFrom reference.Named
if _, found := r.URL.Query()["cachefrom"]; found {
cacheFrom, err = parse.RepoNameToNamedReference(query.CacheFrom)
if err != nil {
utils.BadRequest(w, "cacheFrom", query.CacheFrom, err)
return
}
}
var cacheTo reference.Named
if _, found := r.URL.Query()["cacheto"]; found {
cacheTo, err = parse.RepoNameToNamedReference(query.CacheTo)
if err != nil {
utils.BadRequest(w, "cacheto", query.CacheTo, err)
return
}
}
var cacheTTL time.Duration
if _, found := r.URL.Query()["cachettl"]; found {
cacheTTL, err = time.ParseDuration(query.CacheTTL)
if err != nil {
utils.BadRequest(w, "cachettl", query.CacheTTL, err)
return
}
}
var buildArgs = map[string]string{}
if _, found := r.URL.Query()["buildargs"]; found {
if err := json.Unmarshal([]byte(query.BuildArgs), &buildArgs); err != nil {
@ -578,6 +606,9 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
AdditionalTags: additionalTags,
Annotations: annotations,
CPPFlags: cppflags,
CacheFrom: cacheFrom,
CacheTo: cacheTo,
CacheTTL: cacheTTL,
Args: buildArgs,
AllPlatforms: query.AllPlatforms,
CommonBuildOpts: &buildah.CommonBuildOptions{

View File

@ -224,6 +224,15 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
if len(options.Manifest) > 0 {
params.Set("manifest", options.Manifest)
}
if options.CacheFrom != nil {
params.Set("cachefrom", options.CacheFrom.String())
}
if options.CacheTo != nil {
params.Set("cacheto", options.CacheTo.String())
}
if int64(options.CacheTTL) != 0 {
params.Set("cachettl", options.CacheTTL.String())
}
if memSwap := options.CommonBuildOpts.MemorySwap; memSwap > 0 {
params.Set("memswap", strconv.Itoa(int(memSwap)))
}

View File

@ -152,6 +152,10 @@ errmsg "checking authfile: stat /tmp/nonexistent: no such file or directory" \
"Error: checking authfile: stat /tmp/nonexistent: no such file or directory" \
"bud with Containerfile should fail with nonexistent authfile"
errmsg "cannot find Containerfile or Dockerfile" \
"no such file or directory" \
"bud-github-context-from-commit"
###############################################################################
# BEGIN tests that don't make sense under podman due to fundamental differences
@ -216,7 +220,10 @@ skip_if_remote "--output option not implemented in podman-remote" \
"build with custom build output and output rootfs to tar" \
"build with custom build output and output rootfs to tar by pipe" \
"build with custom build output must fail for bad input" \
"build with custom build output and output rootfs to tar with no additional step"
"build with custom build output and output rootfs to tar with no additional step" \
"build with custom build output for single-stage-cached and output rootfs to directory" \
"build with custom build output for multi-stage-cached and output rootfs to directory" \
"build with custom build output for multi-stage and output rootfs to directory"
# https://github.com/containers/podman/issues/14544
skip_if_remote "logfile not implemented on remote" "bud-logfile-with-split-logfile-by-platform"

View File

@ -28,12 +28,12 @@ env:
# GCE project where images live
IMAGE_PROJECT: "libpod-218412"
FEDORA_NAME: "fedora-36"
PRIOR_FEDORA_NAME: "fedora-35"
#PRIOR_FEDORA_NAME: "fedora-35"
UBUNTU_NAME: "ubuntu-2204"
IMAGE_SUFFIX: "c6193881921355776"
IMAGE_SUFFIX: "c6013173500215296"
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}"
#PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}"
UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX}"
IN_PODMAN_IMAGE: "quay.io/libpod/fedora_podman:${IMAGE_SUFFIX}"
@ -66,15 +66,15 @@ meta_task:
alias: meta
container:
image: "quay.io/libpod/imgts:${IMAGE_SUFFIX}" # see contrib/imgts
image: "quay.io/libpod/imgts:latest"
cpu: 1
memory: 1
env:
# Space-separated list of images used by this repository state
# TODO: Re-add ${PRIOR_FEDORA_CACHE_IMAGE_NAME} when place back in use
IMGNAMES: |-
${FEDORA_CACHE_IMAGE_NAME}
${PRIOR_FEDORA_CACHE_IMAGE_NAME}
${UBUNTU_CACHE_IMAGE_NAME}
build-push-${IMAGE_SUFFIX}
BUILDID: "${CIRRUS_BUILD_ID}"
@ -215,10 +215,10 @@ integration_task:
DISTRO_NV: "${FEDORA_NAME}"
IMAGE_NAME: "${FEDORA_CACHE_IMAGE_NAME}"
STORAGE_DRIVER: 'vfs'
- env:
DISTRO_NV: "${PRIOR_FEDORA_NAME}"
IMAGE_NAME: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}"
STORAGE_DRIVER: 'vfs'
# - env:
# DISTRO_NV: "${PRIOR_FEDORA_NAME}"
# IMAGE_NAME: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}"
# STORAGE_DRIVER: 'vfs'
- env:
DISTRO_NV: "${UBUNTU_NAME}"
IMAGE_NAME: "${UBUNTU_CACHE_IMAGE_NAME}"
@ -228,10 +228,10 @@ integration_task:
DISTRO_NV: "${FEDORA_NAME}"
IMAGE_NAME: "${FEDORA_CACHE_IMAGE_NAME}"
STORAGE_DRIVER: 'overlay'
- env:
DISTRO_NV: "${PRIOR_FEDORA_NAME}"
IMAGE_NAME: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}"
STORAGE_DRIVER: 'overlay'
# - env:
# DISTRO_NV: "${PRIOR_FEDORA_NAME}"
# IMAGE_NAME: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}"
# STORAGE_DRIVER: 'overlay'
- env:
DISTRO_NV: "${UBUNTU_NAME}"
IMAGE_NAME: "${UBUNTU_CACHE_IMAGE_NAME}"
@ -272,11 +272,11 @@ integration_rootless_task:
IMAGE_NAME: "${FEDORA_CACHE_IMAGE_NAME}"
STORAGE_DRIVER: 'overlay'
PRIV_NAME: rootless
- env:
DISTRO_NV: "${PRIOR_FEDORA_NAME}"
IMAGE_NAME: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}"
STORAGE_DRIVER: 'overlay'
PRIV_NAME: rootless
# - env:
# DISTRO_NV: "${PRIOR_FEDORA_NAME}"
# IMAGE_NAME: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}"
# STORAGE_DRIVER: 'overlay'
# PRIV_NAME: rootless
- env:
DISTRO_NV: "${UBUNTU_NAME}"
IMAGE_NAME: "${UBUNTU_CACHE_IMAGE_NAME}"

View File

@ -2,6 +2,36 @@
# Changelog
## v1.27.0 (2022-08-01)
build: support filtering cache by duration using `--cache-ttl`.
build: support building from commit when using git repo as build context.
build: clean up git repos correctly when using subdirs.
build: add support for distributing cache to remote sources using `--cache-to` and `--cache-from`.
imagebuildah: optimize cache hits for `COPY` and `ADD` instructions.
build: support OCI hooks for ephemeral build containers.
build: add support for `--userns=auto`.
copier: add NoOverwriteNonDirDir option .
add initial support for building images using Buildah on FreeBSD.
multistage: this now skips the computing of unwanted stages to improve performance.
multiarch: support splitting build logs for `--platform` using `--logsplit`.
build: add support for building images where the base image has no history.
commit: allow disabling image history with `--omit-history`.
build: add support for renaming a device in rootless setups.
build: now supports additionalBuildContext in builds via the `--build-context` option.
build: `--output` produces artifacts even if the build container is not committed.
build: now accepts `-cpp-flag`, allowing users to pass in CPP flags when processing a Containerfile with C Preprocessor-like syntax.
build: now accepts a branch and a subdirectory when the build context is a git repository.
build: output now shows a progress bar while pushing and pulling images
build: now errors out if the path to Containerfile is a directory.
build: support building container images on environments that are rootless and without any valid login sessions.
fix: `--output` now generates artifacts even if the entire build is cached.
fix: `--output` generates artifacts only for the target stage in multi-stage builds.
fix,add: now fails on a bad HTTP response instead of writing to container
fix,squash: never use build cache when computing the last step of the last stage
fix,build,run: allow reusing secret more than once in different RUN steps
fix: compatibility with Docker build by making its --label and --annotate options set empty labels and annotations when given a name but no `=` or label value.
## v1.26.0 (2022-05-04)
imagebuildah,build: move deepcopy of args before we spawn goroutine

View File

@ -50,7 +50,7 @@ endif
# Note: Uses the -N -l go compiler options to disable compiler optimizations
# and inlining. Using these build options allows you to subsequently
# use source debugging tools like delve.
all: bin/buildah bin/imgtype bin/copy docs
all: bin/buildah bin/imgtype bin/copy bin/tutorial docs
# Update nix/nixpkgs.json its latest stable commit
.PHONY: nixpkgs
@ -74,7 +74,8 @@ bin/buildah: $(SOURCES) cmd/buildah/*.go
.PHONY: buildah
buildah: bin/buildah
ALL_CROSS_TARGETS := $(addprefix bin/buildah.,$(subst /,.,$(shell $(GO) tool dist list)))
# TODO: remove `grep -v loong64` from `ALL_CROSS_TARGETS` once go.etcd.io/bbolt 1.3.7 is out.
ALL_CROSS_TARGETS := $(addprefix bin/buildah.,$(subst /,.,$(shell $(GO) tool dist list | grep -v loong64)))
LINUX_CROSS_TARGETS := $(filter bin/buildah.linux.%,$(ALL_CROSS_TARGETS))
DARWIN_CROSS_TARGETS := $(filter bin/buildah.darwin.%,$(ALL_CROSS_TARGETS))
WINDOWS_CROSS_TARGETS := $(addsuffix .exe,$(filter bin/buildah.windows.%,$(ALL_CROSS_TARGETS)))
@ -92,6 +93,9 @@ bin/imgtype: $(SOURCES) tests/imgtype/imgtype.go
bin/copy: $(SOURCES) tests/copy/copy.go
$(GO_BUILD) $(BUILDAH_LDFLAGS) -o $@ $(BUILDFLAGS) ./tests/copy/copy.go
bin/tutorial: $(SOURCES) tests/tutorial/tutorial.go
$(GO_BUILD) $(BUILDAH_LDFLAGS) -o $@ $(BUILDFLAGS) ./tests/tutorial/tutorial.go
.PHONY: clean
clean:
$(RM) -r bin tests/testreport/testreport
@ -108,7 +112,7 @@ gopath:
test $(shell pwd) = $(shell cd ../../../../src/github.com/containers/buildah ; pwd)
codespell:
codespell -S Makefile,build,buildah,buildah.spec,imgtype,copy,AUTHORS,bin,vendor,.git,go.sum,CHANGELOG.md,changelog.txt,seccomp.json,.cirrus.yml,"*.xz,*.gz,*.tar,*.tgz,*ico,*.png,*.1,*.5,*.orig,*.rej" -L uint,iff,od,ERRO -w
codespell -S Makefile,buildah.spec.rpkg,AUTHORS,bin,vendor,.git,go.mod,go.sum,CHANGELOG.md,changelog.txt,seccomp.json,.cirrus.yml,"*.xz,*.gz,*.tar,*.tgz,*ico,*.png,*.1,*.5,*.orig,*.rej" -L uint,iff,od,ERRO -w
.PHONY: validate
validate: install.tools

View File

@ -150,7 +150,7 @@ func SetupIntermediateMountNamespace(spec *specs.Spec, bundlePath string) (unmou
// Check if the source is a directory or something else.
info, err := os.Stat(spec.Mounts[i].Source)
if err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
logrus.Warnf("couldn't find %q on host to bind mount into container", spec.Mounts[i].Source)
continue
}
@ -269,7 +269,7 @@ func UnmountMountpoints(mountpoint string, mountpointsToRemove []string) error {
mount := getMountByID(id)
// check if this mountpoint is mounted
if err := unix.Lstat(mount.Mountpoint, &st); err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
logrus.Debugf("mountpoint %q is not present(?), skipping", mount.Mountpoint)
continue
}

View File

@ -3,6 +3,7 @@ package buildah
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
@ -445,7 +446,7 @@ func OpenBuilderByPath(store storage.Store, path string) (*Builder, error) {
}
buildstate, err := ioutil.ReadFile(filepath.Join(cdir, stateFile))
if err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
logrus.Debugf("error reading %q: %v, ignoring container %q", filepath.Join(cdir, stateFile), err, container.ID)
continue
}
@ -482,7 +483,7 @@ func OpenAllBuilders(store storage.Store) (builders []*Builder, err error) {
}
buildstate, err := ioutil.ReadFile(filepath.Join(cdir, stateFile))
if err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
logrus.Debugf("error reading %q: %v, ignoring container %q", filepath.Join(cdir, stateFile), err, container.ID)
continue
}

View File

@ -1,3 +1,32 @@
- Changelog for v1.27.0 (2022-08-01)
* build: support filtering cache by duration using `--cache-ttl`.
* build: support building from commit when using git repo as build context.
* build: clean up git repos correctly when using subdirs.
* build: add support for distributing cache to remote sources using `--cache-to` and `--cache-from`.
* imagebuildah: optimize cache hits for `COPY` and `ADD` instructions.
* build: support OCI hooks for ephemeral build containers.
* build: add support for `--userns=auto`.
* copier: add NoOverwriteNonDirDir option .
* add initial support for building images using Buildah on FreeBSD.
* multistage: this now skips the computing of unwanted stages to improve performance.
* multiarch: support splitting build logs for `--platform` using `--logsplit`.
* build: add support for building images where the base image has no history.
* commit: allow disabling image history with `--omit-history`.
* build: add support for renaming a device in rootless setups.
* build: now supports additionalBuildContext in builds via the `--build-context` option.
* build: `--output` produces artifacts even if the build container is not committed.
* build: now accepts `-cpp-flag`, allowing users to pass in CPP flags when processing a Containerfile with C Preprocessor-like syntax.
* build: now accepts a branch and a subdirectory when the build context is a git repository.
* build: output now shows a progress bar while pushing and pulling images
* build: now errors out if the path to Containerfile is a directory.
* build: support building container images on environments that are rootless and without any valid login sessions.
* fix: `--output` now generates artifacts even if the entire build is cached.
* fix: `--output` generates artifacts only for the target stage in multi-stage builds.
* fix,add: now fails on a bad HTTP response instead of writing to container
* fix,squash: never use build cache when computing the last step of the last stage
* fix,build,run: allow reusing secret more than once in different RUN steps
* fix: compatibility with Docker build by making its --label and --annotate options set empty labels and annotations when given a name but no `=` or label value.
- Changelog for v1.26.0 (2022-05-04)
* imagebuildah,build: move deepcopy of args before we spawn goroutine
* Vendor in containers/storage v1.40.2

View File

@ -6,6 +6,7 @@ package chroot
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
@ -1090,7 +1091,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func(
// Bind /dev read-only.
subDev := filepath.Join(spec.Root.Path, "/dev")
if err := unix.Mount("/dev", subDev, "bind", devFlags, ""); err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
err = os.Mkdir(subDev, 0755)
if err == nil {
err = unix.Mount("/dev", subDev, "bind", devFlags, "")
@ -1114,7 +1115,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func(
// Bind /proc read-only.
subProc := filepath.Join(spec.Root.Path, "/proc")
if err := unix.Mount("/proc", subProc, "bind", procFlags, ""); err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
err = os.Mkdir(subProc, 0755)
if err == nil {
err = unix.Mount("/proc", subProc, "bind", procFlags, "")
@ -1129,7 +1130,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func(
// Bind /sys read-only.
subSys := filepath.Join(spec.Root.Path, "/sys")
if err := unix.Mount("/sys", subSys, "bind", sysFlags, ""); err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
err = os.Mkdir(subSys, 0755)
if err == nil {
err = unix.Mount("/sys", subSys, "bind", sysFlags, "")
@ -1218,7 +1219,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func(
}
if err != nil {
// If the target can't be stat()ted, check the error.
if !os.IsNotExist(err) {
if !errors.Is(err, os.ErrNotExist) {
return undoBinds, fmt.Errorf("error examining %q for mounting in mount namespace: %w", target, err)
}
// The target isn't there yet, so create it.
@ -1304,7 +1305,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func(
r := filepath.Join(spec.Root.Path, roPath)
target, err := filepath.EvalSymlinks(r)
if err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
// No target, no problem.
continue
}
@ -1313,7 +1314,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func(
// Check if the location is already read-only.
var fs unix.Statfs_t
if err = unix.Statfs(target, &fs); err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
// No target, no problem.
continue
}
@ -1325,7 +1326,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func(
// Mount the location over itself, so that we can remount it as read-only.
roFlags := uintptr(unix.MS_NODEV | unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_RDONLY)
if err := unix.Mount(target, target, "", roFlags|unix.MS_BIND|unix.MS_REC, ""); err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
// No target, no problem.
continue
}
@ -1370,7 +1371,7 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func(
// Get some info about the target.
targetinfo, err := os.Stat(target)
if err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
// No target, no problem.
continue
}

View File

@ -1558,7 +1558,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM
} else {
// FreeBSD can return EISDIR for "mkdir /":
// https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=59739.
if !os.IsExist(err) && !errors.Is(err, syscall.EISDIR) {
if !errors.Is(err, os.ErrExist) && !errors.Is(err, syscall.EISDIR) {
return fmt.Errorf("copier: put: error checking directory %q: %w", path, err)
}
}
@ -1581,7 +1581,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM
}
createFile := func(path string, tr *tar.Reader) (int64, error) {
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC|os.O_EXCL, 0600)
if err != nil && os.IsExist(err) {
if err != nil && errors.Is(err, os.ErrExist) {
if req.PutOptions.NoOverwriteDirNonDir {
if st, err2 := os.Lstat(path); err2 == nil && st.IsDir() {
return 0, fmt.Errorf("copier: put: error creating file at %q: %w", path, err)
@ -1626,7 +1626,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM
return errorResponse("copier: put: %s (%s): exists but is not a directory", req.Directory, targetDirectory)
}
} else {
if !os.IsNotExist(err) {
if !errors.Is(err, os.ErrNotExist) {
return errorResponse("copier: put: %s: %v", req.Directory, err)
}
if err := ensureDirectoryUnderRoot(req.Directory); err != nil {
@ -1738,7 +1738,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM
if linkTarget, err = resolvePath(targetDirectory, filepath.Join(req.Root, filepath.FromSlash(hdr.Linkname)), true, nil); err != nil {
return fmt.Errorf("error resolving hardlink target path %q under root %q", hdr.Linkname, req.Root)
}
if err = os.Link(linkTarget, path); err != nil && os.IsExist(err) {
if err = os.Link(linkTarget, path); err != nil && errors.Is(err, os.ErrExist) {
if req.PutOptions.NoOverwriteDirNonDir {
if st, err := os.Lstat(path); err == nil && st.IsDir() {
break
@ -1753,7 +1753,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM
// todo: the general solution requires resolving to an absolute path, handling
// renaming, and then possibly converting back to a relative symlink
// }
if err = os.Symlink(filepath.FromSlash(hdr.Linkname), filepath.FromSlash(path)); err != nil && os.IsExist(err) {
if err = os.Symlink(filepath.FromSlash(hdr.Linkname), filepath.FromSlash(path)); err != nil && errors.Is(err, os.ErrExist) {
if req.PutOptions.NoOverwriteDirNonDir {
if st, err := os.Lstat(path); err == nil && st.IsDir() {
break
@ -1768,7 +1768,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM
ignoredItems[nameBeforeRenaming] = struct{}{}
goto nextHeader
}
if err = mknod(path, chrMode(0600), int(mkdev(devMajor, devMinor))); err != nil && os.IsExist(err) {
if err = mknod(path, chrMode(0600), int(mkdev(devMajor, devMinor))); err != nil && errors.Is(err, os.ErrExist) {
if req.PutOptions.NoOverwriteDirNonDir {
if st, err := os.Lstat(path); err == nil && st.IsDir() {
break
@ -1783,7 +1783,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM
ignoredItems[nameBeforeRenaming] = struct{}{}
goto nextHeader
}
if err = mknod(path, blkMode(0600), int(mkdev(devMajor, devMinor))); err != nil && os.IsExist(err) {
if err = mknod(path, blkMode(0600), int(mkdev(devMajor, devMinor))); err != nil && errors.Is(err, os.ErrExist) {
if req.PutOptions.NoOverwriteDirNonDir {
if st, err := os.Lstat(path); err == nil && st.IsDir() {
break
@ -1794,7 +1794,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM
}
}
case tar.TypeDir:
if err = os.Mkdir(path, 0700); err != nil && os.IsExist(err) {
if err = os.Mkdir(path, 0700); err != nil && errors.Is(err, os.ErrExist) {
if st, stErr := os.Lstat(path); stErr == nil && !st.IsDir() {
if req.PutOptions.NoOverwriteNonDirDir {
break
@ -1821,7 +1821,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM
// the archive more than once for whatever reason
directoryModes[path] = mode
case tar.TypeFifo:
if err = mkfifo(path, 0600); err != nil && os.IsExist(err) {
if err = mkfifo(path, 0600); err != nil && errors.Is(err, os.ErrExist) {
if req.PutOptions.NoOverwriteDirNonDir {
if st, err := os.Lstat(path); err == nil && st.IsDir() {
break
@ -1943,7 +1943,7 @@ func copierHandlerMkdir(req request, idMappings *idtools.IDMappings) (*response,
} else {
// FreeBSD can return EISDIR for "mkdir /":
// https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=59739.
if !os.IsExist(err) && !errors.Is(err, syscall.EISDIR) {
if !errors.Is(err, os.ErrExist) && !errors.Is(err, syscall.EISDIR) {
return errorResponse("copier: mkdir: error checking directory %q: %v", path, err)
}
}

View File

@ -5,6 +5,7 @@ import (
"time"
nettypes "github.com/containers/common/libnetwork/types"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/types"
encconfig "github.com/containers/ocicrypt/config"
"github.com/containers/storage/pkg/archive"
@ -136,6 +137,16 @@ type BuildOptions struct {
RuntimeArgs []string
// TransientMounts is a list of mounts that won't be kept in the image.
TransientMounts []string
// CacheFrom specifies any remote repository which can be treated as
// potential cache source.
CacheFrom reference.Named
// CacheTo specifies any remote repository which can be treated as
// potential cache destination.
CacheTo reference.Named
// CacheTTL specifies duration, if specified using `--cache-ttl` then
// cache intermediate images under this duration will be considered as
// valid cache sources and images outside this duration will be ignored.
CacheTTL time.Duration
// Compression specifies the type of compression which is applied to
// layer blobs. The default is to not use compression, but
// archive.Gzip is recommended.

View File

@ -30,7 +30,7 @@ const (
Package = "buildah"
// Version for the Package. Bump version in contrib/rpm/buildah.spec
// too.
Version = "1.27.0-dev"
Version = "1.27.0"
// DefaultRuntime if containers.conf fails.
DefaultRuntime = "runc"
@ -137,12 +137,7 @@ func TempDirForURL(dir, prefix, url string) (name string, subdir string, err err
}
return "", "", fmt.Errorf("cloning %q to %q:\n%s: %w", url, name, string(combinedOutput), err)
}
// Check if git url specifies any subdir
// if subdir is there switch to subdir.
if gitSubDir != "" {
name = filepath.Join(name, gitSubDir)
}
return name, "", nil
return name, gitSubDir, nil
}
if strings.HasPrefix(url, "github.com/") {
ghurl := url
@ -178,11 +173,13 @@ func TempDirForURL(dir, prefix, url string) (name string, subdir string, err err
return "", "", errors.New("unreachable code reached")
}
func cloneToDirectory(url, dir string) ([]byte, string, error) {
// parseGitBuildContext parses git build context to `repo`, `sub-dir`
// `branch/commit`, accepts GitBuildContext in the format of
// `repourl.git[#[branch-or-commit]:subdir]`.
func parseGitBuildContext(url string) (string, string, string) {
gitSubdir := ""
gitBranch := ""
gitBranchPart := strings.Split(url, "#")
var cmd *exec.Cmd
if len(gitBranchPart) > 1 {
// check if string contains path to a subdir
gitSubDirPart := strings.Split(gitBranchPart[1], ":")
@ -191,16 +188,52 @@ func cloneToDirectory(url, dir string) ([]byte, string, error) {
}
gitBranch = gitSubDirPart[0]
}
if gitBranch == "" {
logrus.Debugf("cloning %q to %q", gitBranchPart[0], dir)
cmd = exec.Command("git", "clone", "--recurse-submodules", gitBranchPart[0], dir)
} else {
logrus.Debugf("cloning repo %q and branch %q to %q", gitBranchPart[0], gitBranch, dir)
cmd = exec.Command("git", "clone", "--recurse-submodules", "-b", gitBranch, gitBranchPart[0], dir)
}
return gitBranchPart[0], gitSubdir, gitBranch
}
func cloneToDirectory(url, dir string) ([]byte, string, error) {
var cmd *exec.Cmd
gitRepo, gitSubdir, gitBranch := parseGitBuildContext(url)
// init repo
cmd = exec.Command("git", "init", dir)
combinedOutput, err := cmd.CombinedOutput()
return combinedOutput, gitSubdir, err
if err != nil {
return combinedOutput, gitSubdir, fmt.Errorf("failed while performing `git init`: %w", err)
}
// add origin
cmd = exec.Command("git", "remote", "add", "origin", gitRepo)
cmd.Dir = dir
combinedOutput, err = cmd.CombinedOutput()
if err != nil {
return combinedOutput, gitSubdir, fmt.Errorf("failed while performing `git remote add`: %w", err)
}
// fetch required branch or commit and perform checkout
// Always default to `HEAD` if nothing specified
fetch := "HEAD"
if gitBranch != "" {
fetch = gitBranch
}
logrus.Debugf("fetching repo %q and branch (or commit ID) %q to %q", gitRepo, fetch, dir)
cmd = exec.Command("git", "fetch", "--depth=1", "origin", "--", fetch)
cmd.Dir = dir
combinedOutput, err = cmd.CombinedOutput()
if err != nil {
return combinedOutput, gitSubdir, fmt.Errorf("failed while performing `git fetch`: %w", err)
}
if fetch == "HEAD" {
// We fetched default branch therefore
// we don't have any valid `branch` or
// `commit` name hence checkout detached
// `FETCH_HEAD`
fetch = "FETCH_HEAD"
}
cmd = exec.Command("git", "checkout", fetch)
cmd.Dir = dir
combinedOutput, err = cmd.CombinedOutput()
if err != nil {
return combinedOutput, gitSubdir, fmt.Errorf("failed while performing `git checkout`: %w", err)
}
return combinedOutput, gitSubdir, nil
}
func downloadToDirectory(url, dir string) error {

View File

@ -4,11 +4,11 @@ go 1.17
require (
github.com/containerd/containerd v1.6.6
github.com/containernetworking/cni v1.1.1
github.com/containers/common v0.48.1-0.20220715075726-2ac10faca05a
github.com/containers/image/v5 v5.21.2-0.20220714132403-2bb3f3e44c5c
github.com/containernetworking/cni v1.1.2
github.com/containers/common v0.49.1
github.com/containers/image/v5 v5.22.0
github.com/containers/ocicrypt v1.1.5
github.com/containers/storage v1.41.1-0.20220714115232-fc9b0ff5272a
github.com/containers/storage v1.42.0
github.com/docker/distribution v2.8.1+incompatible
github.com/docker/docker v20.10.17+incompatible
github.com/docker/go-units v0.4.0
@ -17,16 +17,16 @@ require (
github.com/hashicorp/go-multierror v1.1.1
github.com/mattn/go-shellwords v1.0.12
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.19.0
github.com/onsi/gomega v1.20.0
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198
github.com/opencontainers/runc v1.1.3
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
github.com/opencontainers/runtime-tools v0.9.0
github.com/opencontainers/runtime-tools v0.9.1-0.20220714195903-17b3287fafb7
github.com/opencontainers/selinux v1.10.1
github.com/openshift/imagebuilder v1.2.4-0.20220711175835-4151e43600df
github.com/seccomp/libseccomp-golang v0.10.0
github.com/sirupsen/logrus v1.8.1
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.5.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.0
@ -34,13 +34,13 @@ require (
go.etcd.io/bbolt v1.3.6
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f
golang.org/x/sys v0.0.0-20220624220833-87e55d714810
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467
)
require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/BurntSushi/toml v1.1.0 // indirect
github.com/BurntSushi/toml v1.2.0 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/Microsoft/hcsshim v0.9.3 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect
@ -63,6 +63,7 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/google/go-containerregistry v0.10.0 // indirect
github.com/google/go-intervals v0.0.2 // indirect
github.com/google/uuid v1.3.0 // indirect
@ -72,7 +73,7 @@ require (
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jinzhu/copier v0.3.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.15.8 // indirect
github.com/klauspost/compress v1.15.9 // indirect
github.com/klauspost/pgzip v1.2.5 // indirect
github.com/letsencrypt/boulder v0.0.0-20220331220046-b23ab962616e // indirect
github.com/manifoldco/promptui v0.9.0 // indirect
@ -100,7 +101,7 @@ require (
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 // indirect
github.com/sylabs/sif/v2 v2.7.1 // indirect
github.com/tchap/go-patricia v2.3.0+incompatible // indirect
github.com/theupdateframework/go-tuf v0.3.0 // indirect
github.com/theupdateframework/go-tuf v0.3.1 // indirect
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
github.com/ulikunitz/xz v0.5.10 // indirect
github.com/vbatts/tar-split v0.11.2 // indirect

View File

@ -92,8 +92,8 @@ github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=
github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
@ -183,6 +183,7 @@ github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngE
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
@ -219,7 +220,6 @@ github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
github.com/cilium/ebpf v0.9.0/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@ -338,18 +338,18 @@ github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y=
github.com/containernetworking/cni v1.1.1 h1:ky20T7c0MvKvbMOwS/FrlbNwjEoqJEUUYfsL4b0mc4k=
github.com/containernetworking/cni v1.1.1/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw=
github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl31EQbXALQ=
github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw=
github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE=
github.com/containernetworking/plugins v1.1.1 h1:+AGfFigZ5TiQH00vhR8qPeSatj53eNGz0C1d3wVYlHE=
github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8=
github.com/containers/common v0.48.1-0.20220715075726-2ac10faca05a h1:kdcruVl641VTIm8C3O58WRYcBTbnWCsh6AJymk28ScM=
github.com/containers/common v0.48.1-0.20220715075726-2ac10faca05a/go.mod h1:1dA7JPGoSi83kjf5H4NIrGANyLOULyvFqV1bwvYFEek=
github.com/containers/image/v5 v5.21.2-0.20220712113758-29aec5f7bbbf/go.mod h1:0+N0ZM9mgMmoZZc6uNcgnEsbX85Ne7b29cIW5lqWwVU=
github.com/containers/image/v5 v5.21.2-0.20220714132403-2bb3f3e44c5c h1:ms1Vyzs9Eb17J38aFKrL0+ig2pVwQq3OleaO7VmQuV0=
github.com/containers/image/v5 v5.21.2-0.20220714132403-2bb3f3e44c5c/go.mod h1:ykVAVRj4DhQNMHZDVU+KCtXjWBKpqiUe669eF0WBEEc=
github.com/containers/common v0.49.1 h1:6y4/s2WwYxrv+Cox7fotOo316wuZI+iKKPUQweCYv50=
github.com/containers/common v0.49.1/go.mod h1:ueM5hT0itKqCQvVJDs+EtjornAQtrHYxQJzP2gxeGIg=
github.com/containers/image/v5 v5.22.0 h1:KemxPmD4D2YYOFZN2SgoTk7nBFcnwPiPW0MqjYtknSE=
github.com/containers/image/v5 v5.22.0/go.mod h1:D8Ksv2RNB8qLJ7xe1P3rgJJOSQpahA6amv2Ax++/YO4=
github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a h1:spAGlqziZjCJL25C6F1zsQY05tfCKE9F5YwtEWWe6hU=
github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
@ -360,10 +360,8 @@ github.com/containers/ocicrypt v1.1.3/go.mod h1:xpdkbVAuaH3WzbEabUd5yDsl9SwJA5pA
github.com/containers/ocicrypt v1.1.5 h1:UO+gBnBXvMvC7HTXLh0bPgLslfW8HlY+oxYcoSHBcZQ=
github.com/containers/ocicrypt v1.1.5/go.mod h1:WgjxPWdTJMqYMjf3M6cuIFFA1/MpyyhIM99YInA+Rvc=
github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4=
github.com/containers/storage v1.41.0/go.mod h1:Pb0l5Sm/89kolX3o2KolKQ5cCHk5vPNpJrhNaLcdS5s=
github.com/containers/storage v1.41.1-0.20220712184034-d26be7b27860/go.mod h1:uu6HCcijN30xRxW1ZuZRngwFGOlH5NpBWYiNBnDQNRw=
github.com/containers/storage v1.41.1-0.20220714115232-fc9b0ff5272a h1:+arJAP0v8kEy5fKRPIELjarjpwUHhB7SyRE0uFXlyKY=
github.com/containers/storage v1.41.1-0.20220714115232-fc9b0ff5272a/go.mod h1:4DfR+cPpkXKhJnnyydD3z82DXrnTBT63y1k0QWtM2i4=
github.com/containers/storage v1.42.0 h1:zm2AQD4NDeTB3JQ8X+Wo5+VRqNB+b4ocEd7Qj6ylPJA=
github.com/containers/storage v1.42.0/go.mod h1:JiUJwOgOo1dr2DdOUc1MRe2GCAXABYoYmOdPF8yvH78=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@ -480,7 +478,6 @@ github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD
github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU=
github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
@ -859,8 +856,8 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.4/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/compress v1.15.7/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/compress v1.15.8 h1:JahtItbkWjf2jzm/T+qgMxkP9EMHsqEUA6vCMGmXvhA=
github.com/klauspost/compress v1.15.8/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@ -869,9 +866,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
@ -965,6 +961,7 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7sxOougM=
@ -973,7 +970,6 @@ github.com/moby/sys/mount v0.3.3/go.mod h1:PBaEorSNTLG5t/+4EgukEQVlAvVEc6ZjTySwK
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/sys/mountinfo v0.6.1/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg=
@ -1041,8 +1037,9 @@ github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+t
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q=
github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@ -1060,8 +1057,6 @@ github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runc v1.0.3/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
github.com/opencontainers/runc v1.1.1-0.20220607072441-a7a45d7d2721/go.mod h1:QvA0UNe48mC1JxcXq0sENIR38+/LdJMLNxuAvtFBhxA=
github.com/opencontainers/runc v1.1.1/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
github.com/opencontainers/runc v1.1.2/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w=
github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
@ -1070,15 +1065,17 @@ github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/
github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20201121164853-7413a7f753e1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc=
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/runtime-tools v0.9.0 h1:FYgwVsKRI/H9hU32MJ/4MLOzXWodKK5zsQavY8NPMkU=
github.com/opencontainers/runtime-tools v0.9.0/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/runtime-tools v0.9.1-0.20220714195903-17b3287fafb7 h1:Rf+QsQGxrYCia8mVyOPnoQZ+vJkZGL+ESWBDUM5s9cQ=
github.com/opencontainers/runtime-tools v0.9.1-0.20220714195903-17b3287fafb7/go.mod h1:/tgP02fPXGHkU3/qKK1Y0Db4yqNyGm03vLq/mzHzcS4=
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
github.com/opencontainers/selinux v1.8.5/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo=
github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/opencontainers/selinux v1.10.1 h1:09LIPVRP3uuZGQvgR+SgMSNBd1Eb3vlRbGqQpoHsF8w=
github.com/opencontainers/selinux v1.10.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
@ -1157,8 +1154,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
@ -1199,8 +1194,9 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
@ -1261,8 +1257,9 @@ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs=
github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
github.com/theupdateframework/go-tuf v0.3.0 h1:od2sc5+BSkKZhmUG2o2rmruy0BGSmhrbDhCnpxh87X8=
github.com/theupdateframework/go-tuf v0.3.0/go.mod h1:E5XP0wXitrFUHe4b8cUcAAdxBW4LbfnqF4WXXGLgWNo=
github.com/theupdateframework/go-tuf v0.3.1 h1:NkjMlCuLcDpHNtsWXY4lTmbbQQ5nOM7JSBbOKEEiI1c=
github.com/theupdateframework/go-tuf v0.3.1/go.mod h1:lhHZ3Vt2pdAh15h0Cc6gWdlI+Okn2ZznD3q/cNjd5jw=
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@ -1276,11 +1273,11 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
@ -1699,12 +1696,14 @@ golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810 h1:rHZQSjJdAI4Xf5Qzeh2bBc5YJIkPFVM6oDtMFYmgws0=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=

View File

@ -747,7 +747,7 @@ func (i *containerImageSource) GetBlob(ctx context.Context, blob types.BlobInfo,
}
layerFile.Close()
}
if !os.IsNotExist(err) {
if !errors.Is(err, os.ErrNotExist) {
logrus.Debugf("error checking for layer %q in %q: %v", blob.Digest.String(), blobDir, err)
}
}

View File

@ -185,7 +185,8 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B
options.Manifest = ""
type instance struct {
v1.Platform
ID string
ID string
Ref reference.Canonical
}
var instances []instance
var instancesLock sync.Mutex
@ -266,10 +267,10 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B
if err != nil {
return err
}
id, ref = thisID, thisRef
instancesLock.Lock()
instances = append(instances, instance{
ID: thisID,
Ref: thisRef,
Platform: platformSpec,
})
instancesLock.Unlock()
@ -284,6 +285,25 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B
return "", nil, merr.ErrorOrNil()
}
// Reasons for this id, ref assigment w.r.t to use-case:
//
// * Single-platform build: On single platform build we only
// have one built instance i.e on indice 0 of built instances,
// so assign that.
//
// * Multi-platform build with manifestList: If this is a build for
// multiple platforms ( more than one platform ) and --manifest
// option then this assignment is insignificant since it will be
// overriden anyways with the id and ref of manifest list later in
// in this code.
//
// * Multi-platform build without manifest list: If this is a build for
// multiple platforms without --manifest then we are free to return
// id and ref of any one of the image in the instance list so always
// return indice 0 for predictable output instead returning the id and
// ref of the go routine which completed at last.
id, ref = instances[0].ID, instances[0].Ref
if manifestList != "" {
rt, err := libimage.RuntimeFromStore(store, nil)
if err != nil {
@ -396,6 +416,7 @@ func buildDockerfilesOnce(ctx context.Context, store storage.Store, logger *logr
for i, d := range dockerfilecontents[1:] {
additionalNode, err := imagebuilder.ParseDockerfile(bytes.NewReader(d))
if err != nil {
dockerfiles := dockerfiles[1:]
return "", nil, fmt.Errorf("error parsing additional Dockerfile %s: %w", dockerfiles[i], err)
}
mainNode.Children = append(mainNode.Children, additionalNode.Children...)
@ -662,6 +683,7 @@ func baseImages(dockerfilenames []string, dockerfilecontents [][]byte, from stri
for i, d := range dockerfilecontents[1:] {
additionalNode, err := imagebuilder.ParseDockerfile(bytes.NewReader(d))
if err != nil {
dockerfilenames := dockerfilenames[1:]
return nil, fmt.Errorf("error parsing additional Dockerfile %s: %w", dockerfilenames[i], err)
}
mainNode.Children = append(mainNode.Children, additionalNode.Children...)

View File

@ -58,6 +58,9 @@ var builtinAllowedBuildArgs = map[string]bool{
// interface. It coordinates the entire build by using one or more
// StageExecutors to handle each stage of the build.
type Executor struct {
cacheFrom reference.Named
cacheTo reference.Named
cacheTTL time.Duration
containerSuffix string
logger *logrus.Logger
stages map[string]*StageExecutor
@ -212,6 +215,9 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o
}
exec := Executor{
cacheFrom: options.CacheFrom,
cacheTo: options.CacheTo,
cacheTTL: options.CacheTTL,
containerSuffix: options.ContainerSuffix,
logger: logger,
stages: make(map[string]*StageExecutor),

View File

@ -2,6 +2,8 @@ package imagebuildah
import (
"context"
"crypto/sha256"
"errors"
"fmt"
"io"
"os"
@ -22,6 +24,7 @@ import (
"github.com/containers/buildah/util"
config "github.com/containers/common/pkg/config"
cp "github.com/containers/image/v5/copy"
imagedocker "github.com/containers/image/v5/docker"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/manifest"
is "github.com/containers/image/v5/storage"
@ -35,6 +38,7 @@ import (
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/openshift/imagebuilder"
"github.com/openshift/imagebuilder/dockerfile/command"
"github.com/openshift/imagebuilder/dockerfile/parser"
"github.com/sirupsen/logrus"
)
@ -123,7 +127,7 @@ func (s *StageExecutor) Preserve(path string) error {
}
st, err := os.Stat(archivedPath)
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
createdDirPerms := os.FileMode(0755)
if err = copier.Mkdir(s.mountPoint, archivedPath, copier.MkdirOptions{ChmodNew: &createdDirPerms}); err != nil {
return fmt.Errorf("error ensuring volume path exists: %w", err)
@ -165,7 +169,7 @@ func (s *StageExecutor) Preserve(path string) error {
archivedPath := filepath.Join(s.mountPoint, cachedPath)
logrus.Debugf("no longer need cache of %q in %q", archivedPath, s.volumeCache[cachedPath])
if err := os.Remove(s.volumeCache[cachedPath]); err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
continue
}
return err
@ -186,7 +190,7 @@ func (s *StageExecutor) volumeCacheInvalidate(path string) error {
}
for _, cachedPath := range invalidated {
if err := os.Remove(s.volumeCache[cachedPath]); err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
continue
}
return err
@ -217,7 +221,7 @@ func (s *StageExecutor) volumeCacheSaveVFS() (mounts []specs.Mount, err error) {
logrus.Debugf("contents of volume %q are already cached in %q", archivedPath, cacheFile)
continue
}
if !os.IsNotExist(err) {
if !errors.Is(err, os.ErrNotExist) {
return nil, err
}
createdDirPerms := os.FileMode(0755)
@ -867,6 +871,21 @@ func (s *StageExecutor) getImageRootfs(ctx context.Context, image string) (mount
return builder.MountPoint, nil
}
// getContentSummary generates content summary for cases where we added content and need
// to get summary with updated digests.
func (s *StageExecutor) getContentSummaryAfterAddingContent() string {
contentType, digest := s.builder.ContentDigester.Digest()
summary := contentType
if digest != "" {
if summary != "" {
summary = summary + ":"
}
summary = summary + digest.Encoded()
logrus.Debugf("added content %s", summary)
}
return summary
}
// Execute runs each of the steps in the stage's parsed tree, in turn.
func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, ref reference.Canonical, err error) {
var resourceUsage rusage.Rusage
@ -945,6 +964,22 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
s.log(commitMessage)
}
}
// logCachePulled produces build log for cases when `--cache-from`
// is used and a valid intermediate image is pulled from remote source.
logCachePulled := func(cacheKey string) {
if !s.executor.quiet {
cacheHitMessage := "--> Cache pulled from remote"
fmt.Fprintf(s.executor.out, "%s %s\n", cacheHitMessage, fmt.Sprintf("%s:%s", s.executor.cacheFrom, cacheKey))
}
}
// logCachePush produces build log for cases when `--cache-to`
// is used and a valid intermediate image is pushed tp remote source.
logCachePush := func(cacheKey string) {
if !s.executor.quiet {
cacheHitMessage := "--> Pushing cache"
fmt.Fprintf(s.executor.out, "%s %s\n", cacheHitMessage, fmt.Sprintf("%s:%s", s.executor.cacheTo, cacheKey))
}
}
logCacheHit := func(cacheID string) {
if !s.executor.quiet {
cacheHitMessage := "--> Using cache"
@ -960,6 +995,17 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
}
}
// Parse and populate buildOutputOption if needed
var buildOutputOption define.BuildOutputOption
canGenerateBuildOutput := (s.executor.buildOutput != "" && lastStage)
if canGenerateBuildOutput {
logrus.Debugf("Generating custom build output with options %q", s.executor.buildOutput)
buildOutputOption, err = parse.GetBuildOutput(s.executor.buildOutput)
if err != nil {
return "", nil, fmt.Errorf("failed to parse build output: %w", err)
}
}
if len(children) == 0 {
// There are no steps.
if s.builder.FromImageID == "" || s.executor.squash {
@ -970,6 +1016,12 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
if imgID, ref, err = s.commit(ctx, s.getCreatedBy(nil, ""), false, s.output, s.executor.squash); err != nil {
return "", nil, fmt.Errorf("error committing base container: %w", err)
}
// Generate build output if needed.
if canGenerateBuildOutput {
if err := s.generateBuildOutput(buildOutputOption); err != nil {
return "", nil, err
}
}
} else if len(s.executor.labels) > 0 || len(s.executor.annotations) > 0 {
// The image would be modified by the labels passed
// via the command line, so we need to commit.
@ -977,6 +1029,12 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
if imgID, ref, err = s.commit(ctx, s.getCreatedBy(stage.Node, ""), true, s.output, s.executor.squash); err != nil {
return "", nil, err
}
// Generate build output if needed.
if canGenerateBuildOutput {
if err := s.generateBuildOutput(buildOutputOption); err != nil {
return "", nil, err
}
}
} else {
// We don't need to squash the base image, and the
// image wouldn't be modified by the command line
@ -985,22 +1043,16 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
if imgID, ref, err = s.tagExistingImage(ctx, s.builder.FromImageID, s.output); err != nil {
return "", nil, err
}
if s.executor.buildOutput != "" && lastStage {
// If we have reached this point then our build is just performing a tag
// and it contains no steps or instructions (i.e Containerfile only contains
// `FROM <imagename> and nothing else so we will never end up committing this
// but instead just re-tag image. For such use-cases if `-o` or `--output` was
// specified honor that and export the contents of the current build anyways.
logrus.Debugf("Generating custom build output with options %q", s.executor.buildOutput)
buildOutputOption, err := parse.GetBuildOutput(s.executor.buildOutput)
if err != nil {
return "", nil, fmt.Errorf("failed to parse build output: %w", err)
}
if err := s.generateBuildOutput(buildah.CommitOptions{}, buildOutputOption); err != nil {
// If we have reached this point then our build is just performing a tag
// and it contains no steps or instructions (i.e Containerfile only contains
// `FROM <imagename> and nothing else so we will never end up committing this
// but instead just re-tag image. For such use-cases if `-o` or `--output` was
// specified honor that and export the contents of the current build anyways.
if canGenerateBuildOutput {
if err := s.generateBuildOutput(buildOutputOption); err != nil {
return "", nil, err
}
}
}
logImageID(imgID)
}
@ -1101,15 +1153,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
return "", nil, fmt.Errorf("error building at STEP \"%s\": %w", step.Message, err)
}
// In case we added content, retrieve its digest.
addedContentType, addedContentDigest := s.builder.ContentDigester.Digest()
addedContentSummary := addedContentType
if addedContentDigest != "" {
if addedContentSummary != "" {
addedContentSummary = addedContentSummary + ":"
}
addedContentSummary = addedContentSummary + addedContentDigest.Encoded()
logrus.Debugf("added content %s", addedContentSummary)
}
addedContentSummary := s.getContentSummaryAfterAddingContent()
if moreInstructions {
// There are still more instructions to process
// for this stage. Make a note of the
@ -1134,6 +1178,12 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
return "", nil, fmt.Errorf("error committing container for step %+v: %w", *step, err)
}
logImageID(imgID)
// Generate build output if needed.
if canGenerateBuildOutput {
if err := s.generateBuildOutput(buildOutputOption); err != nil {
return "", nil, err
}
}
} else {
imgID = ""
}
@ -1143,19 +1193,33 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
// We're in a multi-layered build.
var (
commitName string
cacheID string
err error
rebase bool
addedContentSummary string
commitName string
cacheID string
cacheKey string
pulledAndUsedCacheImage bool
err error
rebase bool
addedContentSummary string
canMatchCacheOnlyAfterRun bool
)
needsCacheKey := (s.executor.cacheFrom != nil || s.executor.cacheTo != nil)
// If we have to commit for this instruction, only assign the
// stage's configured output name to the last layer.
if lastInstruction {
commitName = s.output
}
// If --cache-from or --cache-to is specified make sure to populate
// cacheKey since it will be used either while pulling or pushing the
// cache images.
if needsCacheKey {
cacheKey, err = s.generateCacheKey(ctx, node, addedContentSummary, s.stepRequiresLayer(step))
if err != nil {
return "", nil, fmt.Errorf("failed while generating cache key: %w", err)
}
}
// Check if there's already an image based on our parent that
// has the same change that we're about to make, so far as we
// can tell.
@ -1164,17 +1228,57 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
// determining if a cached layer with the same build args already exists
// and that is done in the if block below.
if checkForLayers && step.Command != "arg" && !(s.executor.squash && lastInstruction && lastStage) {
// For `COPY` and `ADD`, history entries include digests computed from
// the content that's copied in. We need to compute that information so that
// it can be used to evaluate the cache, which means we need to go ahead
// and copy the content.
canMatchCacheOnlyAfterRun = (step.Command == command.Add || step.Command == command.Copy)
if canMatchCacheOnlyAfterRun {
if err = ib.Run(step, s, noRunsRemaining); err != nil {
logrus.Debugf("Error building at step %+v: %v", *step, err)
return "", nil, fmt.Errorf("error building at STEP \"%s\": %w", step.Message, err)
}
// Retrieve the digest info for the content that we just copied
// into the rootfs.
addedContentSummary = s.getContentSummaryAfterAddingContent()
// regenerate cache key with updated content summary
if needsCacheKey {
cacheKey, err = s.generateCacheKey(ctx, node, addedContentSummary, s.stepRequiresLayer(step))
if err != nil {
return "", nil, fmt.Errorf("failed while generating cache key: %w", err)
}
}
}
cacheID, err = s.intermediateImageExists(ctx, node, addedContentSummary, s.stepRequiresLayer(step))
if err != nil {
return "", nil, fmt.Errorf("error checking if cached image exists from a previous build: %w", err)
}
// All the best effort to find cache on localstorage have failed try pulling
// cache from remote repo if `--cache-from` was configured.
if cacheID == "" && s.executor.cacheFrom != nil {
// only attempt to use cache again if pulling was successful
// otherwise do nothing and attempt to run the step, err != nil
// is ignored and will be automatically logged for --log-level debug
if id, err := s.pullCache(ctx, cacheKey); id != "" && err == nil {
logCachePulled(cacheKey)
cacheID, err = s.intermediateImageExists(ctx, node, addedContentSummary, s.stepRequiresLayer(step))
if err != nil {
return "", nil, fmt.Errorf("error checking if cached image exists from a previous build: %w", err)
}
if cacheID != "" {
pulledAndUsedCacheImage = true
}
}
}
}
// If we didn't find a cache entry, or we need to add content
// to find the digest of the content to check for a cached
// image, run the step so that we can check if the result
// matches a cache.
if cacheID == "" {
// We already called ib.Run() for the `canMatchCacheOnlyAfterRun`
// cases above, so we shouldn't do it again.
if cacheID == "" && !canMatchCacheOnlyAfterRun {
// Process the instruction directly.
if err = ib.Run(step, s, noRunsRemaining); err != nil {
logrus.Debugf("Error building at step %+v: %v", *step, err)
@ -1182,14 +1286,13 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
}
// In case we added content, retrieve its digest.
addedContentType, addedContentDigest := s.builder.ContentDigester.Digest()
addedContentSummary = addedContentType
if addedContentDigest != "" {
if addedContentSummary != "" {
addedContentSummary = addedContentSummary + ":"
addedContentSummary = s.getContentSummaryAfterAddingContent()
// regenerate cache key with updated content summary
if needsCacheKey {
cacheKey, err = s.generateCacheKey(ctx, node, addedContentSummary, s.stepRequiresLayer(step))
if err != nil {
return "", nil, fmt.Errorf("failed while generating cache key: %w", err)
}
addedContentSummary = addedContentSummary + addedContentDigest.Encoded()
logrus.Debugf("added content %s", addedContentSummary)
}
// Check if there's already an image based on our parent that
@ -1201,6 +1304,10 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
}
}
} else {
// This log line is majorly here so we can verify in tests
// that our cache is performing in the most optimal way for
// various cases.
logrus.Debugf("Found a cache hit in the first iteration with id %s", cacheID)
// If the instruction would affect our configuration,
// process the configuration change so that, if we fall
// off the cache path, the filesystem changes from the
@ -1246,15 +1353,61 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
if err != nil {
return "", nil, fmt.Errorf("error committing container for step %+v: %w", *step, err)
}
// Generate build output if needed.
if canGenerateBuildOutput {
if err := s.generateBuildOutput(buildOutputOption); err != nil {
return "", nil, err
}
}
}
// Create a squashed version of this image
// if we're supposed to create one and this
// is the last instruction of the last stage.
if s.executor.squash && lastInstruction && lastStage {
imgID, ref, err = s.commit(ctx, s.getCreatedBy(node, addedContentSummary), !s.stepRequiresLayer(step), commitName, true)
if err != nil {
return "", nil, fmt.Errorf("error committing final squash step %+v: %w", *step, err)
// Following step is just built and was not used from
// cache so check if --cache-to was specified if yes
// then attempt pushing this cache to remote repo and
// fail accordingly.
//
// Or
//
// Try to push this cache to remote repository only
// if cache was present on local storage and not
// pulled from remote source while processing this
if s.executor.cacheTo != nil && (!pulledAndUsedCacheImage || cacheID == "") {
logCachePush(cacheKey)
if err = s.pushCache(ctx, imgID, cacheKey); err != nil {
return "", nil, err
}
}
if lastInstruction && lastStage {
if s.executor.squash {
// Create a squashed version of this image
// if we're supposed to create one and this
// is the last instruction of the last stage.
imgID, ref, err = s.commit(ctx, s.getCreatedBy(node, addedContentSummary), !s.stepRequiresLayer(step), commitName, true)
if err != nil {
return "", nil, fmt.Errorf("error committing final squash step %+v: %w", *step, err)
}
// Generate build output if needed.
if canGenerateBuildOutput {
if err := s.generateBuildOutput(buildOutputOption); err != nil {
return "", nil, err
}
}
} else if cacheID != "" {
// If we found a valid cache hit and this is lastStage
// and not a squashed build then there is no opportunity
// for us to perform a `commit` later in the code since
// everything will be used from cache.
//
// If above statement is true and --output was provided
// then generate output manually since there is no opportunity
// for us to perform `commit` anywhere in the code.
// Generate build output if needed.
if canGenerateBuildOutput {
if err := s.generateBuildOutput(buildOutputOption); err != nil {
return "", nil, err
}
}
}
}
@ -1521,6 +1674,114 @@ func (s *StageExecutor) tagExistingImage(ctx context.Context, cacheID, output st
return img.ID, ref, nil
}
// generateCacheKey returns a computed digest for the current STEP
// running its history and diff against a hash algorithm and this
// generated CacheKey is further used by buildah to lock and decide
// tag for the intermeidate image which can be pushed and pulled to/from
// the remote repository.
func (s *StageExecutor) generateCacheKey(ctx context.Context, currNode *parser.Node, addedContentDigest string, buildAddsLayer bool) (string, error) {
hash := sha256.New()
var baseHistory []v1.History
var diffIDs []digest.Digest
var manifestType string
var err error
if s.builder.FromImageID != "" {
manifestType, baseHistory, diffIDs, err = s.executor.getImageTypeAndHistoryAndDiffIDs(ctx, s.builder.FromImageID)
if err != nil {
return "", fmt.Errorf("error getting history of base image %q: %w", s.builder.FromImageID, err)
}
for i := 0; i < len(diffIDs); i++ {
fmt.Fprintln(hash, diffIDs[i].String())
}
}
createdBy := s.getCreatedBy(currNode, addedContentDigest)
fmt.Fprintf(hash, "%t", buildAddsLayer)
fmt.Fprintln(hash, createdBy)
fmt.Fprintln(hash, manifestType)
for _, element := range baseHistory {
fmt.Fprintln(hash, element.CreatedBy)
fmt.Fprintln(hash, element.Author)
fmt.Fprintln(hash, element.Comment)
fmt.Fprintln(hash, element.Created)
fmt.Fprintf(hash, "%t", element.EmptyLayer)
fmt.Fprintln(hash)
}
return fmt.Sprintf("%x", hash.Sum(nil)), nil
}
// cacheImageReference is internal function which generates ImageReference from Named repo sources
// and a tag.
func cacheImageReference(repo reference.Named, cachekey string) (types.ImageReference, error) {
tagged, err := reference.WithTag(repo, cachekey)
if err != nil {
return nil, fmt.Errorf("failed generating tagged reference for %q: %w", repo, err)
}
dest, err := imagedocker.NewReference(tagged)
if err != nil {
return nil, fmt.Errorf("failed generating docker reference for %q: %w", tagged, err)
}
return dest, nil
}
// pushCache takes the image id of intermediate image and attempts
// to perform push at the remote repository with cacheKey as the tag.
// Returns error if fails otherwise returns nil.
func (s *StageExecutor) pushCache(ctx context.Context, src, cacheKey string) error {
dest, err := cacheImageReference(s.executor.cacheTo, cacheKey)
if err != nil {
return err
}
logrus.Debugf("trying to push cache to dest: %+v from src:%+v", dest, src)
options := buildah.PushOptions{
Compression: s.executor.compression,
SignaturePolicyPath: s.executor.signaturePolicyPath,
Store: s.executor.store,
SystemContext: s.executor.systemContext,
BlobDirectory: s.executor.blobDirectory,
SignBy: s.executor.signBy,
MaxRetries: s.executor.maxPullPushRetries,
RetryDelay: s.executor.retryPullPushDelay,
}
ref, digest, err := buildah.Push(ctx, src, dest, options)
if err != nil {
return fmt.Errorf("failed pushing cache to %q: %w", dest, err)
}
logrus.Debugf("successfully pushed cache to dest: %+v with ref:%+v and digest: %v", dest, ref, digest)
return nil
}
// pullCache takes the image source of the cache assuming tag
// already points to the valid cacheKey and pulls the image to
// local storage only if it was not already present on local storage
// or a newer version of cache was found in the upstream repo. If new
// image was pulled function returns image id otherwise returns empty
// string "" or error if any error was encontered while pulling the cache.
func (s *StageExecutor) pullCache(ctx context.Context, cacheKey string) (string, error) {
src, err := cacheImageReference(s.executor.cacheFrom, cacheKey)
if err != nil {
return "", err
}
logrus.Debugf("trying to pull cache from remote repo: %+v", src.DockerReference())
options := buildah.PullOptions{
SignaturePolicyPath: s.executor.signaturePolicyPath,
Store: s.executor.store,
SystemContext: s.executor.systemContext,
BlobDirectory: s.executor.blobDirectory,
MaxRetries: s.executor.maxPullPushRetries,
RetryDelay: s.executor.retryPullPushDelay,
AllTags: false,
ReportWriter: nil,
PullPolicy: define.PullIfNewer,
}
id, err := buildah.Pull(ctx, src.DockerReference().String(), options)
if err != nil {
logrus.Debugf("failed pulling cache from source %s: %v", src, err)
return "", fmt.Errorf("failed while pulling cache from %q: %w", src, err)
}
logrus.Debugf("successfully pulled cache from repo %s: %s", src, id)
return id, nil
}
// intermediateImageExists returns true if an intermediate image of currNode exists in the image store from a previous build.
// It verifies this by checking the parent of the top layer of the image and the history.
func (s *StageExecutor) intermediateImageExists(ctx context.Context, currNode *parser.Node, addedContentDigest string, buildAddsLayer bool) (string, error) {
@ -1538,6 +1799,17 @@ func (s *StageExecutor) intermediateImageExists(ctx context.Context, currNode *p
}
}
for _, image := range images {
// If s.executor.cacheTTL was specified
// then ignore processing image if it
// was created before the specified
// duration.
if int64(s.executor.cacheTTL) != 0 {
timeNow := time.Now()
imageDuration := timeNow.Sub(image.Created)
if s.executor.cacheTTL < imageDuration {
continue
}
}
var imageTopLayer *storage.Layer
var imageParentLayerID string
if image.TopLayer != "" {
@ -1590,15 +1862,6 @@ func (s *StageExecutor) intermediateImageExists(ctx context.Context, currNode *p
// or commit via any custom exporter if specified.
func (s *StageExecutor) commit(ctx context.Context, createdBy string, emptyLayer bool, output string, squash bool) (string, reference.Canonical, error) {
ib := s.stage.Builder
var buildOutputOption define.BuildOutputOption
if s.executor.buildOutput != "" {
var err error
logrus.Debugf("Generating custom build output with options %q", s.executor.buildOutput)
buildOutputOption, err = parse.GetBuildOutput(s.executor.buildOutput)
if err != nil {
return "", nil, fmt.Errorf("failed to parse build output: %w", err)
}
}
var imageRef types.ImageReference
if output != "" {
imageRef2, err := s.executor.resolveNameToImageRef(output)
@ -1739,12 +2002,6 @@ func (s *StageExecutor) commit(ctx context.Context, createdBy string, emptyLayer
HistoryTimestamp: s.executor.timestamp,
Manifest: s.executor.manifest,
}
// generate build output
if s.executor.buildOutput != "" {
if err := s.generateBuildOutput(buildah.CommitOptions{}, buildOutputOption); err != nil {
return "", nil, err
}
}
imgID, _, manifestDigest, err := s.builder.Commit(ctx, imageRef, options)
if err != nil {
return "", nil, err
@ -1760,7 +2017,7 @@ func (s *StageExecutor) commit(ctx context.Context, createdBy string, emptyLayer
return imgID, ref, nil
}
func (s *StageExecutor) generateBuildOutput(commitOpts buildah.CommitOptions, buildOutputOpts define.BuildOutputOption) error {
func (s *StageExecutor) generateBuildOutput(buildOutputOpts define.BuildOutputOption) error {
extractRootfsOpts := buildah.ExtractRootfsOptions{}
if unshare.IsRootless() {
// In order to maintain as much parity as possible
@ -1775,7 +2032,7 @@ func (s *StageExecutor) generateBuildOutput(commitOpts buildah.CommitOptions, bu
extractRootfsOpts.StripSetgidBit = true
extractRootfsOpts.StripXattrs = true
}
rc, errChan, err := s.builder.ExtractRootfs(commitOpts, extractRootfsOpts)
rc, errChan, err := s.builder.ExtractRootfs(buildah.CommitOptions{}, extractRootfsOpts)
if err != nil {
return fmt.Errorf("failed to extract rootfs from given container image: %w", err)
}

View File

@ -3,16 +3,14 @@ package buildah
import (
"bufio"
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"runtime"
"strconv"
"strings"
"time"
"github.com/containerd/containerd/platforms"
putil "github.com/containers/buildah/pkg/util"
"github.com/containers/buildah/util"
"github.com/containers/storage"
"github.com/containers/storage/pkg/system"
@ -83,22 +81,16 @@ func hostInfo() map[string]interface{} {
"version": hostDistributionInfo["Version"],
}
kv, err := readKernelVersion()
kv, err := putil.ReadKernelVersion()
if err != nil {
logrus.Error(err, "error reading kernel version")
}
info["kernel"] = kv
up, err := readUptime()
upDuration, err := putil.ReadUptime()
if err != nil {
logrus.Error(err, "error reading up time")
}
// Convert uptime in seconds to a human-readable format
upSeconds := up + "s"
upDuration, err := time.ParseDuration(upSeconds)
if err != nil {
logrus.Error(err, "error parsing system uptime")
}
hoursFound := false
var timeBuffer bytes.Buffer
@ -170,30 +162,6 @@ func storeInfo(store storage.Store) (map[string]interface{}, error) {
return info, nil
}
func readKernelVersion() (string, error) {
buf, err := ioutil.ReadFile("/proc/version")
if err != nil {
return "", err
}
f := bytes.Fields(buf)
if len(f) < 2 {
return string(bytes.TrimSpace(buf)), nil
}
return string(f[2]), nil
}
func readUptime() (string, error) {
buf, err := ioutil.ReadFile("/proc/uptime")
if err != nil {
return "", err
}
f := bytes.Fields(buf)
if len(f) < 1 {
return "", errors.New("invalid uptime")
}
return string(f[0]), nil
}
// getHostDistributionInfo returns a map containing the host's distribution and version
func getHostDistributionInfo() map[string]string {
dist := make(map[string]string)

View File

@ -19,6 +19,7 @@ import (
"github.com/containers/buildah/pkg/parse"
"github.com/containers/buildah/pkg/util"
"github.com/containers/common/pkg/auth"
"github.com/containers/image/v5/docker/reference"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@ -233,10 +234,6 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) (
return options, nil, nil, errors.New("'rm' and 'force-rm' can only be set with either 'layers' or 'no-cache'")
}
if c.Flag("cache-from").Changed {
logrus.Debugf("build --cache-from not enabled, has no effect")
}
if c.Flag("compress").Changed {
logrus.Debugf("--compress option specified but is ignored")
}
@ -290,6 +287,29 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) (
iopts.Quiet = true
}
}
var cacheTo reference.Named
var cacheFrom reference.Named
cacheTo = nil
cacheFrom = nil
if c.Flag("cache-to").Changed {
cacheTo, err = parse.RepoNameToNamedReference(iopts.CacheTo)
if err != nil {
return options, nil, nil, fmt.Errorf("unable to parse value provided `%s` to --cache-to: %w", iopts.CacheTo, err)
}
}
if c.Flag("cache-from").Changed {
cacheFrom, err = parse.RepoNameToNamedReference(iopts.CacheFrom)
if err != nil {
return options, nil, nil, fmt.Errorf("unable to parse value provided `%s` to --cache-from: %w", iopts.CacheTo, err)
}
}
var cacheTTL time.Duration
if c.Flag("cache-ttl").Changed {
cacheTTL, err = time.ParseDuration(iopts.CacheTTL)
if err != nil {
return options, nil, nil, fmt.Errorf("unable to parse value provided %q as --cache-ttl: %w", iopts.CacheTTL, err)
}
}
options = define.BuildOptions{
AddCapabilities: iopts.CapAdd,
AdditionalBuildContexts: additionalBuildContext,
@ -300,6 +320,9 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) (
Args: args,
BlobDirectory: iopts.BlobCache,
BuildOutput: iopts.BuildOutput,
CacheFrom: cacheFrom,
CacheTo: cacheTo,
CacheTTL: cacheTTL,
CNIConfigDir: iopts.CNIConfigDir,
CNIPluginPath: iopts.CNIPlugInPath,
CPPFlags: iopts.CPPFlags,

View File

@ -54,6 +54,8 @@ type BudResults struct {
BuildArg []string
BuildContext []string
CacheFrom string
CacheTo string
CacheTTL string
CertDir string
Compress bool
Creds string
@ -197,7 +199,9 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
fs.StringArrayVar(&flags.OCIHooksDir, "hooks-dir", []string{}, "set the OCI hooks directory path (may be set multiple times)")
fs.StringArrayVar(&flags.BuildArg, "build-arg", []string{}, "`argument=value` to supply to the builder")
fs.StringArrayVar(&flags.BuildContext, "build-context", []string{}, "`argument=value` to supply additional build context to the builder")
fs.StringVar(&flags.CacheFrom, "cache-from", "", "images to utilise as potential cache sources. The build process does not currently support caching so this is a NOOP.")
fs.StringVar(&flags.CacheFrom, "cache-from", "", "remote repository to utilise as potential cache source.")
fs.StringVar(&flags.CacheTo, "cache-to", "", "remote repository to utilise as potential cache destination.")
fs.StringVar(&flags.CacheTTL, "cache-ttl", "", "only consider cache images under specified duration.")
fs.StringVar(&flags.CertDir, "cert-dir", "", "use certificates at the specified path to access the registry")
fs.BoolVar(&flags.Compress, "compress", false, "this is a legacy option, which has no effect on the image")
fs.StringArrayVar(&flags.CPPFlags, "cpp-flag", []string{}, "set additional flag to pass to C preprocessor (cpp)")
@ -276,6 +280,8 @@ func GetBudFlagsCompletions() commonComp.FlagCompletions {
flagCompletion["build-arg"] = commonComp.AutocompleteNone
flagCompletion["build-context"] = commonComp.AutocompleteNone
flagCompletion["cache-from"] = commonComp.AutocompleteNone
flagCompletion["cache-to"] = commonComp.AutocompleteNone
flagCompletion["cache-ttl"] = commonComp.AutocompleteNone
flagCompletion["cert-dir"] = commonComp.AutocompleteDefault
flagCompletion["cpp-flag"] = commonComp.AutocompleteNone
flagCompletion["creds"] = commonComp.AutocompleteNone

View File

@ -250,7 +250,7 @@ func Unmount(contentDir string) error {
}
// Ignore EINVAL as the specified merge dir is not a mount point
if err := unix.Unmount(mergeDir, 0); err != nil && !os.IsNotExist(err) && err != unix.EINVAL {
if err := unix.Unmount(mergeDir, 0); err != nil && !errors.Is(err, os.ErrNotExist) && err != unix.EINVAL {
return fmt.Errorf("unmount overlay %s: %w", mergeDir, err)
}
return nil
@ -259,7 +259,7 @@ func Unmount(contentDir string) error {
func recreate(contentDir string) error {
st, err := system.Stat(contentDir)
if err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
return nil
}
return fmt.Errorf("failed to stat overlay upper directory: %w", err)
@ -293,7 +293,7 @@ func CleanupContent(containerDir string) (Err error) {
files, err := ioutil.ReadDir(contentDir)
if err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
return nil
}
return fmt.Errorf("read directory: %w", err)
@ -305,7 +305,7 @@ func CleanupContent(containerDir string) (Err error) {
}
}
if err := os.RemoveAll(contentDir); err != nil && !os.IsNotExist(err) {
if err := os.RemoveAll(contentDir); err != nil && !errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("failed to cleanup overlay directory: %w", err)
}
return nil

View File

@ -19,6 +19,7 @@ import (
internalParse "github.com/containers/buildah/internal/parse"
"github.com/containers/buildah/pkg/sshagent"
"github.com/containers/common/pkg/parse"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/types"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/unshare"
@ -48,6 +49,18 @@ const (
BuildahCacheDir = "buildah-cache"
)
// RepoNameToNamedReference parse the raw string to Named reference
func RepoNameToNamedReference(dest string) (reference.Named, error) {
named, err := reference.ParseNormalizedNamed(dest)
if err != nil {
return nil, fmt.Errorf("invalid repo %q: must contain registry and repository: %w", dest, err)
}
if !reference.IsNameOnly(named) {
return nil, fmt.Errorf("repository must contain neither a tag nor digest: %v", named)
}
return named, nil
}
// CommonBuildOptions parses the build options from the bud cli
func CommonBuildOptions(c *cobra.Command) (*define.CommonBuildOptions, error) {
return CommonBuildOptionsFromFlagSet(c.Flags(), c.Flag)
@ -232,11 +245,11 @@ func parseSecurityOpts(securityOpts []string, commonOpts *define.CommonBuildOpti
if _, err := os.Stat(SeccompOverridePath); err == nil {
commonOpts.SeccompProfilePath = SeccompOverridePath
} else {
if !os.IsNotExist(err) {
if !errors.Is(err, os.ErrNotExist) {
return err
}
if _, err := os.Stat(SeccompDefaultPath); err != nil {
if !os.IsNotExist(err) {
if !errors.Is(err, os.ErrNotExist) {
return err
}
} else {
@ -1059,11 +1072,11 @@ func ContainerIgnoreFile(contextDir, path string) ([]string, string, error) {
}
path = filepath.Join(contextDir, ".containerignore")
excludes, err := imagebuilder.ParseIgnore(path)
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
path = filepath.Join(contextDir, ".dockerignore")
excludes, err = imagebuilder.ParseIgnore(path)
}
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
return excludes, "", nil
}
return excludes, path, err

View File

@ -0,0 +1,10 @@
package util
import (
"errors"
"time"
)
func ReadUptime() (time.Duration, error) {
return 0, errors.New("readUptime not supported on darwin")
}

View File

@ -0,0 +1,25 @@
package util
import (
"time"
"unsafe"
"golang.org/x/sys/unix"
)
// For some reason, unix.ClockGettime isn't implemented by x/sys/unix on FreeBSD
func clockGettime(clockid int32, time *unix.Timespec) (err error) {
_, _, e1 := unix.Syscall(unix.SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0)
if e1 != 0 {
return e1
}
return nil
}
func ReadUptime() (time.Duration, error) {
var uptime unix.Timespec
if err := clockGettime(unix.CLOCK_UPTIME, &uptime); err != nil {
return 0, err
}
return time.Duration(unix.TimespecToNsec(uptime)), nil
}

View File

@ -0,0 +1,28 @@
package util
import (
"bytes"
"errors"
"io/ioutil"
"time"
)
func ReadUptime() (time.Duration, error) {
buf, err := ioutil.ReadFile("/proc/uptime")
if err != nil {
return 0, err
}
f := bytes.Fields(buf)
if len(f) < 1 {
return 0, errors.New("invalid uptime")
}
// Convert uptime in seconds to a human-readable format
up := string(f[0])
upSeconds := up + "s"
upDuration, err := time.ParseDuration(upSeconds)
if err != nil {
return 0, err
}
return upDuration, nil
}

View File

@ -0,0 +1,10 @@
package util
import (
"errors"
"time"
)
func ReadUptime() (time.Duration, error) {
return 0, errors.New("readUptime not supported on windows")
}

View File

@ -0,0 +1,19 @@
//go:build linux || freebsd || darwin
// +build linux freebsd darwin
package util
import (
"bytes"
"golang.org/x/sys/unix"
)
func ReadKernelVersion() (string, error) {
var uname unix.Utsname
if err := unix.Uname(&uname); err != nil {
return "", err
}
n := bytes.IndexByte(uname.Release[:], 0)
return string(uname.Release[:n]), nil
}

View File

@ -0,0 +1,10 @@
package util
import (
"errors"
)
func ReadKernelVersion() (string, error) {
return "", errors.New("readKernelVersion not supported on windows")
}

View File

@ -331,7 +331,7 @@ func DefaultNamespaceOptions() (define.NamespaceOptions, error) {
{Name: string(specs.MountNamespace), Host: false},
{Name: string(specs.NetworkNamespace), Host: cfg.NetNS() == "host"},
{Name: string(specs.PIDNamespace), Host: cfg.PidNS() == "host"},
{Name: string(specs.UserNamespace), Host: cfg.Containers.UserNS == "host"},
{Name: string(specs.UserNamespace), Host: cfg.Containers.UserNS == "" || cfg.Containers.UserNS == "host"},
{Name: string(specs.UTSNamespace), Host: cfg.UTSNS() == "host"},
}
return options, nil
@ -477,8 +477,10 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, moreCreateArgs [
if stdioPipe, err = runMakeStdioPipe(int(uid), int(gid)); err != nil {
return 1, err
}
if err = runLabelStdioPipes(stdioPipe, spec.Process.SelinuxLabel, spec.Linux.MountLabel); err != nil {
return 1, err
if spec.Linux != nil {
if err = runLabelStdioPipes(stdioPipe, spec.Process.SelinuxLabel, spec.Linux.MountLabel); err != nil {
return 1, err
}
}
errorFds = []int{stdioPipe[unix.Stdout][0], stdioPipe[unix.Stderr][0]}
closeBeforeReadingErrorFds = []int{stdioPipe[unix.Stdout][1], stdioPipe[unix.Stderr][1]}
@ -1147,7 +1149,7 @@ func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options Run
containerStartR.file, containerStartW.file, err = os.Pipe()
if err != nil {
return fmt.Errorf("error creating container create pipe: %w", err)
return fmt.Errorf("error creating container start pipe: %w", err)
}
defer containerStartR.Close()
defer containerStartW.Close()
@ -1365,7 +1367,7 @@ func runSetupBuiltinVolumes(mountLabel, mountPoint, containerDir string, builtin
// the volume contents. If we do need to create it, then we'll
// need to populate it, too, so make a note of that.
if _, err := os.Stat(volumePath); err != nil {
if !os.IsNotExist(err) {
if !errors.Is(err, os.ErrNotExist) {
return nil, err
}
logrus.Debugf("setting up built-in volume path at %q for %q", volumePath, volume)
@ -1391,7 +1393,7 @@ func runSetupBuiltinVolumes(mountLabel, mountPoint, containerDir string, builtin
return nil, fmt.Errorf("evaluating path %q: %w", srcPath, err)
}
stat, err := os.Stat(srcPath)
if err != nil && !os.IsNotExist(err) {
if err != nil && !errors.Is(err, os.ErrNotExist) {
return nil, err
}
// If we need to populate the mounted volume's contents with
@ -1844,7 +1846,7 @@ func (b *Builder) cleanupRunMounts(context *imageTypes.SystemContext, mountpoint
var prevErr error
for _, path := range artifacts.TmpFiles {
err := os.Remove(path)
if !os.IsNotExist(err) {
if !errors.Is(err, os.ErrNotExist) {
if prevErr != nil {
logrus.Error(prevErr)
}

View File

@ -251,6 +251,7 @@ func (b *Builder) Run(command []string, options RunOptions) error {
jconf.Set("enforce_statfs", 0)
jconf.Set("devfs_ruleset", 4)
jconf.Set("allow.raw_sockets", true)
jconf.Set("allow.chflags", true)
jconf.Set("allow.mount", true)
jconf.Set("allow.mount.devfs", true)
jconf.Set("allow.mount.nullfs", true)

View File

@ -381,7 +381,7 @@ func (b *Builder) setupOCIHooks(config *spec.Spec, hasVolumes bool) (map[string]
for _, hDir := range []string{hooks.DefaultDir, hooks.OverrideDir} {
manager, err := hooks.New(context.Background(), []string{hDir}, []string{})
if err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
continue
}
return nil, err
@ -690,7 +690,7 @@ func setupNamespaces(logger *logrus.Logger, g *generate.Generator, namespaceOpti
// by the kernel
p := filepath.Join("/proc/sys", strings.Replace(name, ".", "/", -1))
_, err := os.Stat(p)
if err != nil && !os.IsNotExist(err) {
if err != nil && !errors.Is(err, os.ErrNotExist) {
return false, nil, false, err
}
if err == nil {

View File

@ -4,6 +4,7 @@
package buildah
import (
"errors"
"fmt"
"os"
@ -33,7 +34,7 @@ func runLabelStdioPipes(stdioPipe [][]int, processLabel, mountLabel string) erro
}
for i := range stdioPipe {
pipeFdName := fmt.Sprintf("/proc/self/fd/%d", stdioPipe[i][0])
if err := selinux.SetFileLabel(pipeFdName, pipeContext); err != nil && !os.IsNotExist(err) {
if err := selinux.SetFileLabel(pipeFdName, pipeContext); err != nil && !errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("setting file label on %q: %w", pipeFdName, err)
}
}

View File

@ -187,7 +187,7 @@ func IsContainer(id string, store storage.Store) (bool, error) {
// Assuming that if the stateFile exists, that this is a Buildah
// container.
if _, err = os.Stat(filepath.Join(cdir, stateFile)); err != nil {
if os.IsNotExist(err) {
if errors.Is(err, os.ErrNotExist) {
return false, nil
}
return false, err

View File

@ -384,13 +384,15 @@ var (
// fileExistsAndNotADir - Check to see if a file exists
// and that it is not a directory.
func fileExistsAndNotADir(path string) bool {
func fileExistsAndNotADir(path string) (bool, error) {
file, err := os.Stat(path)
if file == nil || err != nil || os.IsNotExist(err) {
return false
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return false, nil
}
return false, err
}
return !file.IsDir()
return !file.IsDir(), nil
}
// FindLocalRuntime find the local runtime of the
@ -404,7 +406,11 @@ func FindLocalRuntime(runtime string) string {
return localRuntime
}
for _, val := range conf.Engine.OCIRuntimes[runtime] {
if fileExistsAndNotADir(val) {
exists, err := fileExistsAndNotADir(val)
if err != nil {
logrus.Errorf("Failed to determine if file exists and is not a directory: %v", err)
}
if exists {
localRuntime = val
break
}

2
vendor/modules.txt vendored
View File

@ -91,7 +91,7 @@ github.com/containernetworking/cni/pkg/version
# github.com/containernetworking/plugins v1.1.1
## explicit
github.com/containernetworking/plugins/pkg/ns
# github.com/containers/buildah v1.26.1-0.20220716095526-d31d27c357ab
# github.com/containers/buildah v1.27.0
## explicit
github.com/containers/buildah
github.com/containers/buildah/bind