Bump Buildah to v1.44.0

Vendor in Buildah v1.44.0 in preparation for Podman v6.0

Signed-off-by: Tom Sweeney <tsweeney@redhat.com>
This commit is contained in:
Tom Sweeney
2026-05-27 17:52:48 -04:00
parent 2393c05d28
commit 6b02641f73
22 changed files with 1097 additions and 310 deletions

10
go.mod
View File

@@ -64,7 +64,7 @@ require (
github.com/vbauerster/mpb/v8 v8.12.1
github.com/vishvananda/netlink v1.3.1
go.etcd.io/bbolt v1.4.3
go.podman.io/buildah v1.42.1-0.20260501153811-377cf64e213b
go.podman.io/buildah v1.44.0
go.podman.io/common v0.68.0
go.podman.io/image/v5 v5.40.0
go.podman.io/storage v1.63.0
@@ -73,7 +73,7 @@ require (
golang.org/x/sync v0.20.0
golang.org/x/sys v0.45.0
golang.org/x/term v0.43.0
google.golang.org/grpc v1.81.0
google.golang.org/grpc v1.81.1
google.golang.org/protobuf v1.36.11
gopkg.in/inf.v0 v0.9.1
gopkg.in/yaml.v3 v3.0.1
@@ -138,7 +138,7 @@ require (
github.com/mdlayher/socket v0.5.1 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/mistifyio/go-zfs/v4 v4.0.0 // indirect
github.com/moby/buildkit v0.29.0 // indirect
github.com/moby/buildkit v0.30.0 // indirect
github.com/moby/go-archive v0.2.0 // indirect
github.com/moby/patternmatcher v0.6.1 // indirect
github.com/moby/sys/devices v0.1.0 // indirect
@@ -183,8 +183,8 @@ require (
golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/text v0.37.0 // indirect
golang.org/x/tools v0.44.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260406210006-6f92a3bedf2d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
tags.cncf.io/container-device-interface/specs-go v1.1.0 // indirect
)

20
go.sum
View File

@@ -247,8 +247,8 @@ github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/mistifyio/go-zfs/v4 v4.0.0 h1:sU0+5dX45tdDK5xNZ3HBi95nxUc48FS92qbIZEvpAg4=
github.com/mistifyio/go-zfs/v4 v4.0.0/go.mod h1:weotFtXTHvBwhr9Mv96KYnDkTPBOHFUbm9cBmQpesL0=
github.com/moby/buildkit v0.29.0 h1:wxLEFbCOJntEDjSNNN2YWd8zxltZxT5muDQ0LzpbtpU=
github.com/moby/buildkit v0.29.0/go.mod h1:Dmv2FeDe34t75QuzeU87rBoZpAAkcpT5zeu4hXzmASc=
github.com/moby/buildkit v0.30.0 h1:OsK8T3BaYH52UNStpKd7gytDtHWWt2Fawak/lAPWatU=
github.com/moby/buildkit v0.30.0/go.mod h1:k2wuw5ddaOqzh58RLt+mBn2XhK34gi6+gd0faONQ1xU=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8=
@@ -429,8 +429,8 @@ go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfC
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
go.podman.io/buildah v1.42.1-0.20260501153811-377cf64e213b h1:i8ntFzITajbJA3ojnA0ZdpbC+I+ccweZvZaGIhQb4i8=
go.podman.io/buildah v1.42.1-0.20260501153811-377cf64e213b/go.mod h1:hPvgsjBU09C+15fKoIZJvKvNaxR+c0QvMg/n4NgBS7A=
go.podman.io/buildah v1.44.0 h1:hxQh/fZtm/r1Xuo2UnDoQH0PRafCRJ53oUeDSDCtKkE=
go.podman.io/buildah v1.44.0/go.mod h1:RUdF9lLmMmdD7K9Y6eO64ptYuUMdDZ84SkPJc4008Jc=
go.podman.io/common v0.68.0 h1:6V8nZS33vLTPC047RfSGxARgS/Ui6CQtgdZXLo18qAc=
go.podman.io/common v0.68.0/go.mod h1:zVzufHkRpLueF6NW6N+fAs1C2METdzYcfD9zuw+oJKA=
go.podman.io/image/v5 v5.40.0 h1:gNQvj343Eb4juCitUBkuDz1T82Zpp6nhgMEXzNfCges=
@@ -556,12 +556,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA=
google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw=
google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
google.golang.org/genproto/googleapis/api v0.0.0-20260406210006-6f92a3bedf2d h1:/aDRtSZJjyLQzm75d+a1wOJaqyKBMvIAfeQmoa3ORiI=
google.golang.org/genproto/googleapis/api v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:etfGUgejTiadZAUaEP14NP97xi1RGeawqkjDARA/UOs=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d h1:wT2n40TBqFY6wiwazVK9/iTWbsQrgk5ZfCSVFLO9LQA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -2,6 +2,263 @@
# Changelog
## v1.44.0 (2026-05-27)
TEMPORARY: Skip a newly-added test
Restore the previous TempDirForURL API
TempDirForURL: return absolute context path instead of relative subdir
TempDirForURL: refactor if-chain into switch statement
Prevent symlink-based path traversal in build contexts
Bump c/common to v0.68.0, c/image v5.40.0, c/storage v1.63.0
fix(deps): update module golang.org/x/crypto to v0.52.0
fix(deps): update module golang.org/x/sys to v0.45.0
Don't report an error in a possible RPC server start/stop ordering
Fix a race in TestCannotChangeMultipleRequestsWithDifferentChroot
Correctly report archiveSource if we can't find it
copier: add Mkfile() for creating files with inline content
docs: document compression flags for commit, push and build
build: add --compression-format flags for build
commit: add --compression-format flag with containers.conf fallback
build: pass compression_format to --cache-to push
push: respect compression_format from containers.conf
add/copy: support AllowWildcard and AllowEmptyWildcard
copier.TestTarPut(): test both with and without chroot
imagebuildah.executor.getCreatedBy(): use digests for previous stages
Ignore .containerignore for git repositories in ADD
Fix stale cache when using bind mount with build stage
fix(deps): update module google.golang.org/grpc to v1.81.1
fix: duplicated "the" in define/types.go and pkg/sshagent comments
tmt: archive audit and journal logs after test execution
We don't have a 'nix' directory, but we do have one for 'rpm'
rpm/buildah.spec tests: require xz and /usr/bin/selinuxenabled
fix(deps): update module github.com/moby/buildkit to v0.30.0
deps: bump selinux to v1.14.1
Remove unused ReserveSELinuxLabels
fix(deps): update module golang.org/x/crypto to v0.51.0
fix(deps): update module golang.org/x/term to v0.43.0
copier: add AddAndCopyOptions.DirCopyContents
fix(deps): update module golang.org/x/sys to v0.44.0
fix(deps): update module google.golang.org/grpc to v1.81.0
fix(deps): update module github.com/openshift/imagebuilder to v1.2.21
Add RunOptions.ValidExitCodes and --valid-exit-codes flag
copier: add RemoveOptions.AllowWildcard
Packit: Only create dist-git PRs for rawhide
docs: Remove slirp for podman6
tests: Remove slirp for podman6
Remove slirp for podman6
Remove OWNERS file
vendor: update latest common, image, storage
Makefile: preserve entrypoint_amd64 and .gz in clean target
docs: Add note about the ssh mount options for non-root users
docs: update registries.conf references
tests: move registries.conf files to v2 format
remove old v1 registries.conf config from CI
Remove runc/libcontainer/devices dependency
define: switch away from runc/libct/devices
copier: Fix the bookkeeping of the requested root
copier: Fix some log messages
Update to use shared configfile implementation
RUN-4547: Move buildah import paths
fix(deps): update module github.com/moby/moby/client to v0.4.1
tests: remove dependencies on online apt repositories
fix(deps): update module github.com/containers/ocicrypt to v1.3.0
Update to use ordered network dependencies
fix(deps): update module github.com/docker/go-connections to v0.7.0
Fix the copier:get operation to properly gather symlink information
tests/helpers.bash: wait to determine the OCI runtime
Makefile: migrate the lint-entrypoint check to Go
Makefile: add some missing dependencies
fix(deps): update module github.com/mattn/go-shellwords to v1.0.13
Group global commands in global help output
copier: add MkdirOptions.MakeParents
copier: add RemoveOptions.AllowNotFound
fix(deps): update module golang.org/x/crypto to v0.50.0
fix(deps): update module golang.org/x/term to v0.42.0
fix(deps): update module golang.org/x/sys to v0.43.0
Enable failOnExtraFSContent on dockerignore and --exclude tests
COPY --exclude: make patterns context relative
docs: fix build tool tutorial with correct modules
fix(deps): update module github.com/moby/moby/client to v0.4.0
chore(deps): update module github.com/go-jose/go-jose/v4 to v4.1.4 [security]
fix(deps): update module github.com/opencontainers/runc to v1.4.2
Add additional caching diagnostics to stage executor
fix(deps): update module google.golang.org/grpc to v1.80.0
fix(deps): update module github.com/containerd/platforms to v1.0.0-rc.4
fix(deps): update github.com/opencontainers/runtime-tools digest to 8a4db57
fix(deps): update module github.com/moby/buildkit to v0.29.0
fix(deps): update module github.com/fsouza/go-dockerclient to v1.13.1
chore(deps): update module github.com/moby/moby/v2 to v2.0.0-beta.8 [security]
Fix panic in --secret flag parsing when key has no value
fix(deps): update common, image, and storage deps to 8af7873
fix(deps): update module github.com/moby/buildkit to v0.28.1 [security]
Makefile: run lint-entrypoint as part of validate
Makefile: add lint-entrypoint target
internal/mkcw/embed/entrypoint_amd64.gz: rebuild with native assembler
fix(deps): update common, image, and storage deps to 7e1f14c
New images 2026-03-19
fix(deps): update module github.com/containerd/platforms to v1.0.0-rc.3
Add /assign command GitHub Action
Support multiple ARGs in a single instruction
Fix ARG scope order so build-arg and stage override header
Fix COPY/ADD --from= with ARG in stage scope
go.mod: remove containernetworking/cni dependency
docs, tests: remove CNI references
deprecate CNI configuration fields and remove CLI flags
version: remove CNI spec and libcni version reporting
vendor container-libs w/o CNI
fix(deps): update module google.golang.org/grpc to v1.79.3
feat: add support for saving and labeling intermediate stages
fix(deps): update module github.com/opencontainers/runc to v1.4.1
fix(deps): update module golang.org/x/crypto to v0.49.0
fix(deps): update module github.com/moby/buildkit to v0.28.0
fix(deps): update module github.com/fsouza/go-dockerclient to v1.13.0
chore(deps): update module github.com/sigstore/fulcio to v1.8.5 [security]
fix(deps): update module golang.org/x/sync to v0.20.0
chore(deps): update dependency containers/automation_images to v20260310
Update tests/bud.bats
CI: use 1.25 for the vendor_task
tests: use jq to validate images --json structure
fix(deps): update module golang.org/x/term to v0.41.0
tests: remove cgroupsv1 checks and simplify cgroupsv2 conditionals
tests: Replace cat with bash input redirection
Update testing VM images
tests/conformance: do not set RootlessStoragePath
tests: fix storage.conf chroot read error
chroot: do not leak the CONTAINERS_CONF env var
resolve runtime outside of child reexec process
cmd/buildah: do not use init() for cobra commands
CI: collect logs for unit and conformance tests
chore(deps): update dependency golangci/golangci-lint to v2.11.1
fix(deps): update module google.golang.org/grpc to v1.79.2
Add packaging for newer test helpers
fix(deps): update module github.com/moby/moby/client to v0.3.0
fix(deps): update module google.golang.org/grpc to v1.79.1
tests: Introduce skip_unless_arch helper function
tests: Fix tests to run on other architectures
tests: Adapt test to work on systems with 64k page size
Builder.getSecretMount(): don't leak an fd
Add a more generic "prepend or append instructions" method
imagebuildah: avoid empty layer in single-layer build path
feat: support --mount=type=secret,id=foo,env=bar
chroot: error out on --network != host when $BUILDAH_ISOLATION
Rename package and variables to match upstream changes
Stop using the old github.com/docker/docker package paths
fix: support SHELL during RUN commands in image build
Add basic functionality to build Windows images
tests/from.bats "from cpu-shares test": update cgroupv2 weights
Address warnings from the new linter
imagebuildah.stageExecutor.Run(): pull images for transient mounts
chore(deps): update dependency golangci/golangci-lint to v2.10.1
ignore ErrLayerUnknown in cache lookup
tree: replace various nested append calls with slices.Concat
Fix the typo in bud test
Handle new `FROM --after` flag for explicit stage dependencies
Update docs/buildah-manifest-create.1.md
Add an undocumented general "run with RPC service"
Break up the internal/parse package
copier: drain tar stream to prevent broken pipe errors
chore(deps): update dependency golangci/golangci-lint to v2.9.0
fix setting of gid
fix call to chown
fix(deps): update module golang.org/x/crypto to v0.48.0
internal/mkcw: make errors easier to compare, update tests
Add a test where a default ARG value is a quoted string
manifest create: add --amend and --replace for non-list images
fix(deps): update module github.com/openshift/imagebuilder to v1.2.20
feat(build): add --mount option
fix(deps): update common, image, and storage deps to 28c83ab
return error in switch
fix stdout error message
use BuildOutputInvalid
update doc
fix doc
only process path for types that need it
simplify switch
use switch/case
feat(build): print error on build flag --output=type=something
docs: mention Containerfiles also
fix: use reference.ParseNormalizedNamed for image normalization
fix: document source policy processing order in man page
fix: default matchType to WILDCARD per BuildKit spec
fix(deps): update common, image, and storage deps to b5801a6
Update a source.bats test
Bump go.podman.io/{storage,image/v5,common} to main
Run: don't try to encode SystemContext with json
Add --source-policy-file flag for BuildKit-compatible source policies
chroot.bats(chroot with overlay root): ensure we can overlay
fix(deps): update module github.com/sirupsen/logrus to v1.9.4
tests: use cached images instead of fedoraproject.org
test: do not untar archive into fs when checking file names
integration: point places where we ADD http: locations to localhost
bud cache add-copy-chown: go local
bud --link ADD with remote URL consistent diffID: go local
Repack repository archives under `podman unshare`
bud with ADD with git repository source integration test: go local
fix(deps): update module golang.org/x/crypto to v0.47.0
integration tests: remove all "RUN apk ..." instructions
fix(deps): update module golang.org/x/sys to v0.40.0
chore(deps): update dependency golangci/golangci-lint to v2.8.0
conformance test cases: add a fsSkipCompatVolumesTrue field
TestCommit: expect EXPOSEd ports to have the implicit "/tcp" added
tests/conformance: identify ourselves as "current" clients to dockerd
chore(deps): update dependency containers/automation_images to v20251211
fix(deps): update module tags.cncf.io/container-device-interface to v1.1.0
fix(deps): update github.com/opencontainers/runtime-tools digest to 5e63903
fix(deps): update github.com/containers/luksy digest to ca09631
fix(deps): update module github.com/moby/buildkit to v0.26.3
fix(deps): update module golang.org/x/crypto to v0.46.0
fix(deps): update module golang.org/x/term to v0.38.0
fix(deps): update module golang.org/x/sys to v0.39.0
fix(deps): update module golang.org/x/sync to v0.19.0
chore(deps): update dependency golangci/golangci-lint to v2.7.2
chore(deps): update dependency golangci/golangci-lint to v2.7.1
fix(deps): update module github.com/spf13/cobra to v1.10.2
chore(deps): update dependency golangci/golangci-lint to v2.7.0
build: add --iidfile-raw CLI option
vendor: Update container-libs with cgv1 removed
commit-pull-push-signatures test: don't try to push to a failed dir:
fix(deps): update github.com/containers/luksy digest to e33b6d6
fix(deps): update common, image, and storage deps to 94e31d2
cirrus: bump go version as per go.mod
vendor: update latest common, image, storage
vendor: update container-libs, and runtime-spec
fix(deps): update module github.com/moby/buildkit to v0.26.2
fix(deps): update module golang.org/x/crypto to v0.45.0 [security]
fix(deps): update module github.com/moby/buildkit to v0.26.1
fix(deps): update module github.com/fsouza/go-dockerclient to v1.12.3
chore(deps): update dependency golangci/golangci-lint to v2.6.2
CI: block on runc jobs again
Update testing VM images
Suppress "meaningless package name" warnings for public APIs
Rename "types" packages to avoid "meaningless name" warnings
copier: fix linter warnings
Update golangci-lint to 2.6.1, add "fmt" target
Drop unused hack/Dockerfile
Drop 'toolchain go1.24.10' ...
fix(deps): update module github.com/moby/buildkit to v0.26.0
fix(deps): update module golang.org/x/crypto to v0.44.0
internal/mkcw/embed: cross-compile using Go
info.go: Remove Cgroups v1 logic
tests: Remove skips for Cgroups v1
fix(deps): update module github.com/docker/docker to v28.5.2+incompatible
fix(deps): update module github.com/moby/buildkit to v0.25.2
vendor: update to github.com/opencontainers/runc@v1.3.3
fix(deps): update module github.com/containerd/platforms to v1.0.0-rc.2
imagebuildah.stageExecutor.runStageMountPoints(): correct an error
imagebuildah: try to rein in use of transport names in image specs
imagebuildah: use a longer-lived overlay over the build context
overlay: chown()ing the upper dir: ignore EINVAL on overflow IDs
overlay: sync the upper directory's timestamp to the lower's, too
overlay: only chown the upper directory if we created it
fix(deps): update github.com/containers/luksy digest to adfea1d
fix(deps): update module github.com/opencontainers/cgroups to v0.0.6
Add --metadata-file
Introduce CommitResults(), which returns a results struct
imagebuildah: unexport the Executor and StageExecutor types
fix(build): make --tag oci-archive:xxx.tar work with simple images
Bump to v1.43.0-dev
RPM: build with sequoia on F43+
## v1.42.0 (2025-10-17)
Bump to storage v1.61.0, image v5.38.0, common v0.66.0

112
vendor/go.podman.io/buildah/add.go generated vendored
View File

@@ -29,13 +29,13 @@ import (
"go.podman.io/buildah/copier"
"go.podman.io/buildah/define"
"go.podman.io/buildah/internal/tmpdir"
"go.podman.io/buildah/internal/urlsource"
"go.podman.io/buildah/pkg/chrootuser"
"go.podman.io/common/pkg/retry"
"go.podman.io/image/v5/pkg/tlsclientconfig"
"go.podman.io/image/v5/types"
"go.podman.io/storage/pkg/fileutils"
"go.podman.io/storage/pkg/idtools"
"go.podman.io/storage/pkg/regexp"
)
// AddAndCopyOptions holds options for add and copy commands.
@@ -60,7 +60,8 @@ type AddAndCopyOptions struct {
// If the sources include directory trees, Hasher will be passed
// tar-format archives of the directory trees.
Hasher io.Writer
// Excludes is the contents of the .containerignore file.
// Excludes is a list of patterns to be excluded, which has the
// format of lines of .containerignore file.
Excludes []string
// IgnoreFile is the path to the .containerignore file.
IgnoreFile string
@@ -112,29 +113,15 @@ type AddAndCopyOptions struct {
// inheritAnnotations, newAnnotations). This field is internally managed and should
// not be set by external API users.
BuildMetadata string
}
// gitURLFragmentSuffix matches fragments to use as Git reference and build
// context from the Git repository e.g.
//
// github.com/containers/buildah.git
// github.com/containers/buildah.git#main
// github.com/containers/buildah.git#v1.35.0
var gitURLFragmentSuffix = regexp.Delayed(`\.git(?:#.+)?$`)
// sourceIsGit returns true if "source" is a git location.
func sourceIsGit(source string) bool {
return isURL(source) && gitURLFragmentSuffix.MatchString(source)
}
func isURL(url string) bool {
return strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://")
}
// sourceIsRemote returns true if "source" is a remote location
// and *not* a git repo. Certain github urls such as raw.github.* are allowed.
func sourceIsRemote(source string) bool {
return isURL(source) && !gitURLFragmentSuffix.MatchString(source)
// DirCopyContents copies the directory's contents instead of the
// directory with its contents below it, default true.
DirCopyContents types.OptionalBool
// AllowWildcard controls whether glob patterns are allowed in source
// paths. When false, they are rejected. Defaults to true.
AllowWildcard types.OptionalBool
// AllowEmptyWildcard controls whether the operation succeeds when all
// glob patterns match nothing. Defaults to false.
AllowEmptyWildcard types.OptionalBool
}
// getURL writes a tar archive containing the named content
@@ -349,11 +336,11 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
if src == "" {
return errors.New("empty source location")
}
if sourceIsRemote(src) {
if urlsource.IsRemote(src) {
remoteSources = append(remoteSources, src)
continue
}
if sourceIsGit(src) {
if urlsource.IsGit(src) {
gitSources = append(gitSources, src)
continue
}
@@ -375,7 +362,9 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
var localSourceStats []*copier.StatsForGlob
if len(localSources) > 0 {
statOptions := copier.StatOptions{
CheckForArchives: extract,
CheckForArchives: extract,
DisallowWildcard: options.AllowWildcard == types.OptionalBoolFalse,
AllowEmptyWildcard: options.AllowEmptyWildcard == types.OptionalBoolTrue,
}
localSourceStats, err = copier.Stat(contextDir, contextDir, statOptions, localSources)
if err != nil {
@@ -396,11 +385,17 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
return fmt.Errorf("checking on sources under %q: %v", contextDir, errorText)
}
if len(localSourceStat.Globbed) == 0 {
if options.AllowEmptyWildcard == types.OptionalBoolTrue {
continue
}
return fmt.Errorf("checking source under %q: no glob matches: %w", contextDir, syscall.ENOENT)
}
numLocalSourceItems += len(localSourceStat.Globbed)
}
if numLocalSourceItems+len(remoteSources)+len(gitSources) == 0 {
if options.AllowEmptyWildcard == types.OptionalBoolTrue {
return nil
}
return fmt.Errorf("no sources %v found: %w", sources, syscall.ENOENT)
}
@@ -448,7 +443,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
destCanBeFile := false
if len(sources) == 1 {
if len(remoteSources) == 1 {
destCanBeFile = sourceIsRemote(sources[0])
destCanBeFile = urlsource.IsRemote(sources[0])
}
if len(localSources) == 1 {
item := localSourceStats[0].Results[localSourceStats[0].Globbed[0]]
@@ -589,7 +584,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
var multiErr *multierror.Error
var getErr, closeErr, renameErr, putErr error
var wg sync.WaitGroup
if sourceIsRemote(src) || sourceIsGit(src) {
if urlsource.IsRemote(src) || urlsource.IsGit(src) {
pipeReader, pipeWriter := io.Pipe()
var srcDigest digest.Digest
if options.Checksum != "" {
@@ -600,28 +595,30 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
}
wg.Add(1)
if sourceIsGit(src) {
if urlsource.IsGit(src) {
go func() {
defer wg.Done()
defer pipeWriter.Close()
// TODO: the returned cloneDir is never cleaned up, leaking disk space.
var cloneDir, subdir string
cloneDir, subdir, getErr = define.TempDirForURL(tmpdir.GetTempDir(), "", src)
if getErr != nil {
return
}
getOptions := copier.GetOptions{
UIDMap: srcUIDMap,
GIDMap: srcGIDMap,
Excludes: options.Excludes,
ExpandArchives: extract,
ChownDirs: chownDirs,
ChmodDirs: chmodDirsFiles,
ChownFiles: chownFiles,
ChmodFiles: chmodDirsFiles,
StripSetuidBit: options.StripSetuidBit,
StripSetgidBit: options.StripSetgidBit,
StripStickyBit: options.StripStickyBit,
Timestamp: options.Timestamp,
UIDMap: srcUIDMap,
GIDMap: srcGIDMap,
Excludes: options.Excludes,
ExpandArchives: extract,
ChownDirs: chownDirs,
ChmodDirs: chmodDirsFiles,
ChownFiles: chownFiles,
ChmodFiles: chmodDirsFiles,
KeepDirectoryNames: options.DirCopyContents == types.OptionalBoolFalse,
StripSetuidBit: options.StripSetuidBit,
StripSetgidBit: options.StripSetgidBit,
StripStickyBit: options.StripStickyBit,
Timestamp: options.Timestamp,
}
writer := io.WriteCloser(pipeWriter)
repositoryDir := filepath.Join(cloneDir, subdir)
@@ -777,19 +774,22 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
return false, false, nil
})
getOptions := copier.GetOptions{
UIDMap: srcUIDMap,
GIDMap: srcGIDMap,
Excludes: options.Excludes,
ExpandArchives: extract,
ChownDirs: chownDirs,
ChmodDirs: chmodDirsFiles,
ChownFiles: chownFiles,
ChmodFiles: chmodDirsFiles,
StripSetuidBit: options.StripSetuidBit,
StripSetgidBit: options.StripSetgidBit,
StripStickyBit: options.StripStickyBit,
Parents: options.Parents,
Timestamp: options.Timestamp,
UIDMap: srcUIDMap,
GIDMap: srcGIDMap,
Excludes: options.Excludes,
ExpandArchives: extract,
ChownDirs: chownDirs,
ChmodDirs: chmodDirsFiles,
ChownFiles: chownFiles,
ChmodFiles: chmodDirsFiles,
KeepDirectoryNames: options.DirCopyContents == types.OptionalBoolFalse,
StripSetuidBit: options.StripSetuidBit,
StripSetgidBit: options.StripSetgidBit,
StripStickyBit: options.StripStickyBit,
Parents: options.Parents,
Timestamp: options.Timestamp,
DisallowWildcard: options.AllowWildcard == types.OptionalBoolFalse,
AllowEmptyWildcard: options.AllowEmptyWildcard == types.OptionalBoolTrue,
}
getErr = copier.Get(contextDir, contextDir, getOptions, []string{globbedToGlobbable(globbed)}, writer)
closeErr = writer.Close()

View File

@@ -1,3 +1,259 @@
- Changelog for v1.44.0 (2026-05-27)
* TEMPORARY: Skip a newly-added test
* Restore the previous TempDirForURL API
* TempDirForURL: return absolute context path instead of relative subdir
* TempDirForURL: refactor if-chain into switch statement
* Prevent symlink-based path traversal in build contexts
* Bump c/common to v0.68.0, c/image v5.40.0, c/storage v1.63.0
* fix(deps): update module golang.org/x/crypto to v0.52.0
* fix(deps): update module golang.org/x/sys to v0.45.0
* Don't report an error in a possible RPC server start/stop ordering
* Fix a race in TestCannotChangeMultipleRequestsWithDifferentChroot
* Correctly report archiveSource if we can't find it
* copier: add Mkfile() for creating files with inline content
* docs: document compression flags for commit, push and build
* build: add --compression-format flags for build
* commit: add --compression-format flag with containers.conf fallback
* build: pass compression_format to --cache-to push
* push: respect compression_format from containers.conf
* add/copy: support AllowWildcard and AllowEmptyWildcard
* copier.TestTarPut(): test both with and without chroot
* imagebuildah.executor.getCreatedBy(): use digests for previous stages
* Ignore .containerignore for git repositories in ADD
* Fix stale cache when using bind mount with build stage
* fix(deps): update module google.golang.org/grpc to v1.81.1
* fix: duplicated "the" in define/types.go and pkg/sshagent comments
* tmt: archive audit and journal logs after test execution
* We don't have a 'nix' directory, but we do have one for 'rpm'
* rpm/buildah.spec tests: require xz and /usr/bin/selinuxenabled
* fix(deps): update module github.com/moby/buildkit to v0.30.0
* deps: bump selinux to v1.14.1
* Remove unused ReserveSELinuxLabels
* fix(deps): update module golang.org/x/crypto to v0.51.0
* fix(deps): update module golang.org/x/term to v0.43.0
* copier: add AddAndCopyOptions.DirCopyContents
* fix(deps): update module golang.org/x/sys to v0.44.0
* fix(deps): update module google.golang.org/grpc to v1.81.0
* fix(deps): update module github.com/openshift/imagebuilder to v1.2.21
* Add RunOptions.ValidExitCodes and --valid-exit-codes flag
* copier: add RemoveOptions.AllowWildcard
* Packit: Only create dist-git PRs for rawhide
* docs: Remove slirp for podman6
* tests: Remove slirp for podman6
* Remove slirp for podman6
* Remove OWNERS file
* vendor: update latest common, image, storage
* Makefile: preserve entrypoint_amd64 and .gz in clean target
* docs: Add note about the ssh mount options for non-root users
* docs: update registries.conf references
* tests: move registries.conf files to v2 format
* remove old v1 registries.conf config from CI
* Remove runc/libcontainer/devices dependency
* define: switch away from runc/libct/devices
* copier: Fix the bookkeeping of the requested root
* copier: Fix some log messages
* Update to use shared configfile implementation
* RUN-4547: Move buildah import paths
* fix(deps): update module github.com/moby/moby/client to v0.4.1
* tests: remove dependencies on online apt repositories
* fix(deps): update module github.com/containers/ocicrypt to v1.3.0
* Update to use ordered network dependencies
* fix(deps): update module github.com/docker/go-connections to v0.7.0
* Fix the copier:get operation to properly gather symlink information
* tests/helpers.bash: wait to determine the OCI runtime
* Makefile: migrate the lint-entrypoint check to Go
* Makefile: add some missing dependencies
* fix(deps): update module github.com/mattn/go-shellwords to v1.0.13
* Group global commands in global help output
* copier: add MkdirOptions.MakeParents
* copier: add RemoveOptions.AllowNotFound
* fix(deps): update module golang.org/x/crypto to v0.50.0
* fix(deps): update module golang.org/x/term to v0.42.0
* fix(deps): update module golang.org/x/sys to v0.43.0
* Enable failOnExtraFSContent on dockerignore and --exclude tests
* COPY --exclude: make patterns context relative
* docs: fix build tool tutorial with correct modules
* fix(deps): update module github.com/moby/moby/client to v0.4.0
* chore(deps): update module github.com/go-jose/go-jose/v4 to v4.1.4 [security]
* fix(deps): update module github.com/opencontainers/runc to v1.4.2
* Add additional caching diagnostics to stage executor
* fix(deps): update module google.golang.org/grpc to v1.80.0
* fix(deps): update module github.com/containerd/platforms to v1.0.0-rc.4
* fix(deps): update github.com/opencontainers/runtime-tools digest to 8a4db57
* fix(deps): update module github.com/moby/buildkit to v0.29.0
* fix(deps): update module github.com/fsouza/go-dockerclient to v1.13.1
* chore(deps): update module github.com/moby/moby/v2 to v2.0.0-beta.8 [security]
* Fix panic in --secret flag parsing when key has no value
* fix(deps): update common, image, and storage deps to 8af7873
* fix(deps): update module github.com/moby/buildkit to v0.28.1 [security]
* Makefile: run lint-entrypoint as part of validate
* Makefile: add lint-entrypoint target
* internal/mkcw/embed/entrypoint_amd64.gz: rebuild with native assembler
* fix(deps): update common, image, and storage deps to 7e1f14c
* New images 2026-03-19
* fix(deps): update module github.com/containerd/platforms to v1.0.0-rc.3
* Add /assign command GitHub Action
* Support multiple ARGs in a single instruction
* Fix ARG scope order so build-arg and stage override header
* Fix COPY/ADD --from= with ARG in stage scope
* go.mod: remove containernetworking/cni dependency
* docs, tests: remove CNI references
* deprecate CNI configuration fields and remove CLI flags
* version: remove CNI spec and libcni version reporting
* vendor container-libs w/o CNI
* fix(deps): update module google.golang.org/grpc to v1.79.3
* feat: add support for saving and labeling intermediate stages
* fix(deps): update module github.com/opencontainers/runc to v1.4.1
* fix(deps): update module golang.org/x/crypto to v0.49.0
* fix(deps): update module github.com/moby/buildkit to v0.28.0
* fix(deps): update module github.com/fsouza/go-dockerclient to v1.13.0
* chore(deps): update module github.com/sigstore/fulcio to v1.8.5 [security]
* fix(deps): update module golang.org/x/sync to v0.20.0
* chore(deps): update dependency containers/automation_images to v20260310
* Update tests/bud.bats
* CI: use 1.25 for the vendor_task
* tests: use jq to validate images --json structure
* fix(deps): update module golang.org/x/term to v0.41.0
* tests: remove cgroupsv1 checks and simplify cgroupsv2 conditionals
* tests: Replace cat with bash input redirection
* Update testing VM images
* tests/conformance: do not set RootlessStoragePath
* tests: fix storage.conf chroot read error
* chroot: do not leak the CONTAINERS_CONF env var
* resolve runtime outside of child reexec process
* cmd/buildah: do not use init() for cobra commands
* CI: collect logs for unit and conformance tests
* chore(deps): update dependency golangci/golangci-lint to v2.11.1
* fix(deps): update module google.golang.org/grpc to v1.79.2
* Add packaging for newer test helpers
* fix(deps): update module github.com/moby/moby/client to v0.3.0
* fix(deps): update module google.golang.org/grpc to v1.79.1
* tests: Introduce skip_unless_arch helper function
* tests: Fix tests to run on other architectures
* tests: Adapt test to work on systems with 64k page size
* Builder.getSecretMount(): don't leak an fd
* Add a more generic "prepend or append instructions" method
* imagebuildah: avoid empty layer in single-layer build path
* feat: support --mount=type=secret,id=foo,env=bar
* chroot: error out on --network != host when $BUILDAH_ISOLATION
* Rename package and variables to match upstream changes
* Stop using the old github.com/docker/docker package paths
* fix: support SHELL during RUN commands in image build
* Add basic functionality to build Windows images
* tests/from.bats "from cpu-shares test": update cgroupv2 weights
* Address warnings from the new linter
* imagebuildah.stageExecutor.Run(): pull images for transient mounts
* chore(deps): update dependency golangci/golangci-lint to v2.10.1
* ignore ErrLayerUnknown in cache lookup
* tree: replace various nested append calls with slices.Concat
* Fix the typo in bud test
* Handle new `FROM --after` flag for explicit stage dependencies
* Update docs/buildah-manifest-create.1.md
* Add an undocumented general "run with RPC service"
* Break up the internal/parse package
* copier: drain tar stream to prevent broken pipe errors
* chore(deps): update dependency golangci/golangci-lint to v2.9.0
* fix setting of gid
* fix call to chown
* fix(deps): update module golang.org/x/crypto to v0.48.0
* internal/mkcw: make errors easier to compare, update tests
* Add a test where a default ARG value is a quoted string
* manifest create: add --amend and --replace for non-list images
* fix(deps): update module github.com/openshift/imagebuilder to v1.2.20
* feat(build): add --mount option
* fix(deps): update common, image, and storage deps to 28c83ab
* return error in switch
* fix stdout error message
* use BuildOutputInvalid
* update doc
* fix doc
* only process path for types that need it
* simplify switch
* use switch/case
* feat(build): print error on build flag --output=type=something
* docs: mention Containerfiles also
* fix: use reference.ParseNormalizedNamed for image normalization
* fix: document source policy processing order in man page
* fix: default matchType to WILDCARD per BuildKit spec
* fix(deps): update common, image, and storage deps to b5801a6
* Update a source.bats test
* Bump go.podman.io/{storage,image/v5,common} to main
* Run: don't try to encode SystemContext with json
* Add --source-policy-file flag for BuildKit-compatible source policies
* chroot.bats(chroot with overlay root): ensure we can overlay
* fix(deps): update module github.com/sirupsen/logrus to v1.9.4
* tests: use cached images instead of fedoraproject.org
* test: do not untar archive into fs when checking file names
* integration: point places where we ADD http: locations to localhost
* bud cache add-copy-chown: go local
* bud --link ADD with remote URL consistent diffID: go local
* Repack repository archives under `podman unshare`
* bud with ADD with git repository source integration test: go local
* fix(deps): update module golang.org/x/crypto to v0.47.0
* integration tests: remove all "RUN apk ..." instructions
* fix(deps): update module golang.org/x/sys to v0.40.0
* chore(deps): update dependency golangci/golangci-lint to v2.8.0
* conformance test cases: add a fsSkipCompatVolumesTrue field
* TestCommit: expect EXPOSEd ports to have the implicit "/tcp" added
* tests/conformance: identify ourselves as "current" clients to dockerd
* chore(deps): update dependency containers/automation_images to v20251211
* fix(deps): update module tags.cncf.io/container-device-interface to v1.1.0
* fix(deps): update github.com/opencontainers/runtime-tools digest to 5e63903
* fix(deps): update github.com/containers/luksy digest to ca09631
* fix(deps): update module github.com/moby/buildkit to v0.26.3
* fix(deps): update module golang.org/x/crypto to v0.46.0
* fix(deps): update module golang.org/x/term to v0.38.0
* fix(deps): update module golang.org/x/sys to v0.39.0
* fix(deps): update module golang.org/x/sync to v0.19.0
* chore(deps): update dependency golangci/golangci-lint to v2.7.2
* chore(deps): update dependency golangci/golangci-lint to v2.7.1
* fix(deps): update module github.com/spf13/cobra to v1.10.2
* chore(deps): update dependency golangci/golangci-lint to v2.7.0
* build: add --iidfile-raw CLI option
* vendor: Update container-libs with cgv1 removed
* commit-pull-push-signatures test: don't try to push to a failed dir:
* fix(deps): update github.com/containers/luksy digest to e33b6d6
* fix(deps): update common, image, and storage deps to 94e31d2
* cirrus: bump go version as per go.mod
* vendor: update latest common, image, storage
* vendor: update container-libs, and runtime-spec
* fix(deps): update module github.com/moby/buildkit to v0.26.2
* fix(deps): update module golang.org/x/crypto to v0.45.0 [security]
* fix(deps): update module github.com/moby/buildkit to v0.26.1
* fix(deps): update module github.com/fsouza/go-dockerclient to v1.12.3
* chore(deps): update dependency golangci/golangci-lint to v2.6.2
* CI: block on runc jobs again
* Update testing VM images
* Suppress "meaningless package name" warnings for public APIs
* Rename "types" packages to avoid "meaningless name" warnings
* copier: fix linter warnings
* Update golangci-lint to 2.6.1, add "fmt" target
* Drop unused hack/Dockerfile
* Drop 'toolchain go1.24.10' ...
* fix(deps): update module github.com/moby/buildkit to v0.26.0
* fix(deps): update module golang.org/x/crypto to v0.44.0
* internal/mkcw/embed: cross-compile using Go
* info.go: Remove Cgroups v1 logic
* tests: Remove skips for Cgroups v1
* fix(deps): update module github.com/docker/docker to v28.5.2+incompatible
* fix(deps): update module github.com/moby/buildkit to v0.25.2
* vendor: update to github.com/opencontainers/runc@v1.3.3
* fix(deps): update module github.com/containerd/platforms to v1.0.0-rc.2
* imagebuildah.stageExecutor.runStageMountPoints(): correct an error
* imagebuildah: try to rein in use of transport names in image specs
* imagebuildah: use a longer-lived overlay over the build context
* overlay: chown()ing the upper dir: ignore EINVAL on overflow IDs
* overlay: sync the upper directory's timestamp to the lower's, too
* overlay: only chown the upper directory if we created it
* fix(deps): update github.com/containers/luksy digest to adfea1d
* fix(deps): update module github.com/opencontainers/cgroups to v0.0.6
* Add --metadata-file
* Introduce CommitResults(), which returns a results struct
* imagebuildah: unexport the Executor and StageExecutor types
* fix(build): make --tag oci-archive:xxx.tar work with simple images
* Bump to v1.43.0-dev
* RPM: build with sequoia on F43+
- Changelog for v1.42.0 (2025-10-17)
* Bump to storage v1.61.0, image v5.38.0, common v0.66.0
* fix(deps): update module github.com/openshift/imagebuilder to v1.2.19

View File

@@ -22,6 +22,7 @@ import (
"go.podman.io/image/v5/docker"
"go.podman.io/image/v5/docker/reference"
"go.podman.io/image/v5/manifest"
"go.podman.io/image/v5/pkg/compression"
"go.podman.io/image/v5/signature"
is "go.podman.io/image/v5/storage"
"go.podman.io/image/v5/transports"
@@ -47,6 +48,14 @@ type CommitOptions struct {
// layer blobs. The default is to not use compression, but
// archive.Gzip is recommended.
Compression archive.Compression
// CompressionFormat is the format to use for the compression of the blobs.
CompressionFormat *compression.Algorithm
// CompressionLevel specifies what compression level is used.
CompressionLevel *int
// ForceCompressionFormat ensures that the compression algorithm set in
// CompressionFormat is used exclusively, and blobs of other compression
// algorithms are not reused.
ForceCompressionFormat bool
// SignaturePolicyPath specifies an override location for the signature
// policy which should be used for verifying the new image as it is
// being written. Except in specific circumstances, no value should be
@@ -456,12 +465,16 @@ func (b *Builder) CommitResults(ctx context.Context, dest types.ImageReference,
if options.Compression != archive.Uncompressed {
compress = types.Compress
}
cache, err := blobcache.NewBlobCache(src, options.BlobDirectory, compress)
var cacheOpts []blobcache.Option
if options.CompressionFormat != nil {
cacheOpts = append(cacheOpts, blobcache.WithCompressAlgorithm(options.CompressionFormat))
}
cache, err := blobcache.NewBlobCache(src, options.BlobDirectory, compress, cacheOpts...)
if err != nil {
return nil, fmt.Errorf("wrapping image reference %q in blob cache at %q: %w", transports.ImageName(src), options.BlobDirectory, err)
}
maybeCachedSrc = cache
cache, err = blobcache.NewBlobCache(dest, options.BlobDirectory, compress)
cache, err = blobcache.NewBlobCache(dest, options.BlobDirectory, compress, cacheOpts...)
if err != nil {
return nil, fmt.Errorf("wrapping image reference %q in blob cache at %q: %w", transports.ImageName(dest), options.BlobDirectory, err)
}
@@ -471,8 +484,9 @@ func (b *Builder) CommitResults(ctx context.Context, dest types.ImageReference,
switch options.Compression {
case archive.Uncompressed:
systemContext.OCIAcceptUncompressedLayers = true
case archive.Gzip:
default:
systemContext.DirForceCompress = true
systemContext.OCIAcceptUncompressedLayers = false
}
if systemContext.ArchitectureChoice != b.Architecture() {
@@ -482,8 +496,16 @@ func (b *Builder) CommitResults(ctx context.Context, dest types.ImageReference,
systemContext.OSChoice = b.OS()
}
copyOptions := getCopyOptions(b.store, options.ReportWriter, nil, systemContext, "", false, options.SignBy, options.OciEncryptLayers, options.OciEncryptConfig, nil, destinationTimestamp)
if options.CompressionFormat != nil {
copyOptions.DestinationCtx.CompressionFormat = options.CompressionFormat
copyOptions.DestinationCtx.CompressionLevel = options.CompressionLevel
}
if options.ForceCompressionFormat {
copyOptions.ForceCompressionFormat = true
}
var manifestBytes []byte
if manifestBytes, err = retryCopyImage(ctx, policyContext, maybeCachedDest, maybeCachedSrc, dest, getCopyOptions(b.store, options.ReportWriter, nil, systemContext, "", false, options.SignBy, options.OciEncryptLayers, options.OciEncryptConfig, nil, destinationTimestamp), options.MaxRetries, options.RetryDelay); err != nil {
if manifestBytes, err = retryCopyImage(ctx, policyContext, maybeCachedDest, maybeCachedSrc, dest, copyOptions, options.MaxRetries, options.RetryDelay); err != nil {
return nil, fmt.Errorf("copying layers and metadata for container %q: %w", b.ContainerID, err)
}
// If we've got more names to attach, and we know how to do that for

View File

@@ -344,9 +344,11 @@ func Eval(root string, directory string, _ EvalOptions) (string, error) {
// StatOptions controls parts of Stat()'s behavior.
type StatOptions struct {
UIDMap, GIDMap []idtools.IDMap // map from hostIDs to containerIDs when returning results
CheckForArchives bool // check for and populate the IsArchive bit in returned values
Excludes []string // contents to pretend don't exist, using the OS-specific path separator
UIDMap, GIDMap []idtools.IDMap // map from hostIDs to containerIDs when returning results
CheckForArchives bool // check for and populate the IsArchive bit in returned values
Excludes []string // contents to pretend don't exist, using the OS-specific path separator
DisallowWildcard bool // reject glob patterns in source paths
AllowEmptyWildcard bool // don't error when glob patterns match nothing
}
// Stat globs the specified pattern in the specified directory and returns its
@@ -399,6 +401,8 @@ type GetOptions struct {
IgnoreUnreadable bool // ignore errors reading items, instead of returning an error
NoCrossDevice bool // if a subdirectory is a mountpoint with a different device number, include it but skip its contents
Timestamp *time.Time // timestamp to force on all contents
DisallowWildcard bool // reject glob patterns in source paths
AllowEmptyWildcard bool // don't error when glob patterns match nothing
}
// Get produces an archive containing items that match the specified glob
@@ -420,7 +424,9 @@ func Get(root string, directory string, options GetOptions, globs []string, bulk
Directory: directory,
Globs: slices.Clone(globs),
StatOptions: StatOptions{
CheckForArchives: options.ExpandArchives,
CheckForArchives: options.ExpandArchives,
DisallowWildcard: options.DisallowWildcard,
AllowEmptyWildcard: options.AllowEmptyWildcard,
},
GetOptions: options,
}
@@ -516,10 +522,64 @@ func Mkdir(root string, directory string, options MkdirOptions) error {
return nil
}
// MkfileOptions controls parts of Mkfile()'s behavior.
type MkfileOptions struct {
UIDMap, GIDMap []idtools.IDMap // map from containerIDs to hostIDs when creating the file
ModTimeNew *time.Time // set mtime and atime of the newly-created file
ChownNew *idtools.IDPair // set ownership of the newly-created file
ChmodNew *os.FileMode // set permissions on the newly-created file
}
// Mkfile creates a file at the specified path under root with the given
// content, permissions, and ownership. It builds a tar archive containing
// a single entry and passes it to Put().
func Mkfile(root string, path string, options MkfileOptions, content []byte) error {
uid, gid := 0, 0
if options.ChownNew != nil {
uid, gid = options.ChownNew.UID, options.ChownNew.GID
}
mode := os.FileMode(0o644)
if options.ChmodNew != nil {
mode = *options.ChmodNew
}
modTime := time.Now()
if options.ModTimeNew != nil {
modTime = *options.ModTimeNew
}
var buf bytes.Buffer
tw := tar.NewWriter(&buf)
hdr := &tar.Header{
Name: cleanerReldirectory(path),
Size: int64(len(content)),
Mode: int64(mode),
Uid: uid,
Gid: gid,
ModTime: modTime,
Typeflag: tar.TypeReg,
}
if err := tw.WriteHeader(hdr); err != nil {
return fmt.Errorf("copier: mkfile: error writing tar header: %w", err)
}
if _, err := tw.Write(content); err != nil {
return fmt.Errorf("copier: mkfile: error writing tar content: %w", err)
}
if err := tw.Close(); err != nil {
return fmt.Errorf("copier: mkfile: error closing tar writer: %w", err)
}
putOptions := PutOptions{
UIDMap: options.UIDMap,
GIDMap: options.GIDMap,
}
return Put(root, root, putOptions, &buf)
}
// RemoveOptions controls parts of Remove()'s behavior.
type RemoveOptions struct {
All bool // if Directory is a directory, remove its contents as well
AllowNotFound bool // don't return an error if the item is already not present
AllowWildcard bool // expand the path as a glob pattern, removing each match. All must be set to remove matched non-empty directories
}
// Remove removes the specified directory or item, traversing any intermediate
@@ -1108,6 +1168,10 @@ func copierHandlerEval(req request) *response {
return &response{Eval: evalResponse{Evaluated: filepath.Join(req.rootPrefix, resolvedTarget)}}
}
func containsWildcards(path string) bool {
return strings.ContainsAny(path, "*?[")
}
func copierHandlerStat(req request, pm *fileutils.PatternMatcher, idMappings *idtools.IDMappings) *response {
errorResponse := func(fmtspec string, args ...any) *response {
return &response{Error: fmt.Sprintf(fmtspec, args...), Stat: statResponse{}}
@@ -1120,13 +1184,17 @@ func copierHandlerStat(req request, pm *fileutils.PatternMatcher, idMappings *id
s := StatsForGlob{
Glob: req.preservedGlobs[i],
}
// glob this pattern
hasWildcards := containsWildcards(glob)
if req.StatOptions.DisallowWildcard && hasWildcards {
s.Error = fmt.Sprintf("copier: stat: %q: wildcards are not allowed", glob)
stats = append(stats, &s)
continue
}
globMatched, err := extendedGlob(glob)
if err != nil {
s.Error = fmt.Sprintf("copier: stat: %q while matching glob pattern %q", err.Error(), glob)
}
if len(globMatched) == 0 && strings.ContainsAny(glob, "*?[") {
if len(globMatched) == 0 && hasWildcards {
continue
}
// collect the matches
@@ -1218,18 +1286,18 @@ func copierHandlerStat(req request, pm *fileutils.PatternMatcher, idMappings *id
result.IsArchive = isArchivePath(globbed)
}
}
// no unskipped matches -> error
if len(s.Globbed) == 0 {
s.Globbed = nil
s.Results = nil
s.Error = fmt.Sprintf("copier: stat: %q: %v", glob, syscall.ENOENT)
if !hasWildcards || !req.StatOptions.AllowEmptyWildcard {
s.Error = fmt.Sprintf("copier: stat: %q: %v", glob, syscall.ENOENT)
}
}
stats = append(stats, &s)
}
// no matches -> error
if len(stats) == 0 {
if len(stats) == 0 && !req.StatOptions.AllowEmptyWildcard {
s := StatsForGlob{
Error: fmt.Sprintf("copier: stat: %q: %v", req.Globs, syscall.ENOENT),
Error: fmt.Sprintf("copier: stat: globs %v matched nothing", req.Globs),
}
stats = append(stats, &s)
}
@@ -1307,10 +1375,20 @@ func copierHandlerGet(bulkWriter io.Writer, req request, pm *fileutils.PatternMa
var queue []queueItem
globMatchedCount := 0
for _, glob := range req.Globs {
hasWildcards := containsWildcards(glob)
if req.GetOptions.DisallowWildcard && hasWildcards {
return errorResponse("copier: get: %q: wildcards are not allowed", glob)
}
globMatched, err := extendedGlob(glob)
if err != nil {
return errorResponse("copier: get: glob %q: %v", glob, err)
}
if len(globMatched) == 0 {
if hasWildcards {
continue
}
return errorResponse("copier: get: %q: %v", glob, syscall.ENOENT)
}
for _, path := range globMatched {
var parents []string
if req.GetOptions.Parents {
@@ -1320,9 +1398,11 @@ func copierHandlerGet(bulkWriter io.Writer, req request, pm *fileutils.PatternMa
queue = append(queue, queueItem{glob: path, parents: parents})
}
}
// no matches -> error
if len(queue) == 0 {
return errorResponse("copier: get: globs %v matched nothing (%d filtered out): %v", req.Globs, globMatchedCount, syscall.ENOENT)
if req.GetOptions.AllowEmptyWildcard {
return &response{Stat: statResponse.Stat, Get: getResponse{}}, nil, nil
}
return errorResponse("copier: get: globs %v matched nothing (%d filtered out)", req.Globs, globMatchedCount)
}
topInfo, err := os.Stat(req.Directory)
if err != nil {
@@ -1555,7 +1635,7 @@ func copierHandlerGet(bulkWriter io.Writer, req request, pm *fileutils.PatternMa
itemsCopied++
}
}
if itemsCopied == 0 {
if itemsCopied == 0 && !req.GetOptions.AllowEmptyWildcard {
return fmt.Errorf("copier: get: copied no items: %w", syscall.ENOENT)
}
return nil
@@ -2297,20 +2377,30 @@ func copierHandlerRemove(req request) *response {
errorResponse := func(fmtspec string, args ...any) *response {
return &response{Error: fmt.Sprintf(fmtspec, args...), Remove: removeResponse{}}
}
resolvedTarget, err := resolvePath(req.Root, req.Directory, false, nil)
if err != nil {
return errorResponse("copier: remove: %v", err)
}
if req.RemoveOptions.All {
err = os.RemoveAll(resolvedTarget)
} else {
err = os.Remove(resolvedTarget)
if req.RemoveOptions.AllowNotFound && errors.Is(err, os.ErrNotExist) {
err = nil
targets := []string{req.Directory}
if req.RemoveOptions.AllowWildcard {
var err error
targets, err = extendedGlob(req.Directory)
if err != nil {
return errorResponse("copier: remove: glob %q: %v", req.Directory, err)
}
}
if err != nil {
return errorResponse("copier: remove %q: %v", req.Directory, err)
for _, target := range targets {
resolvedTarget, err := resolvePath(req.Root, target, false, nil)
if err != nil {
return errorResponse("copier: remove: %v", err)
}
if req.RemoveOptions.All {
err = os.RemoveAll(resolvedTarget)
} else {
err = os.Remove(resolvedTarget)
if req.RemoveOptions.AllowNotFound && errors.Is(err, os.ErrNotExist) {
err = nil
}
}
if err != nil {
return errorResponse("copier: remove %q: %v", target, err)
}
}
return &response{Error: "", Remove: removeResponse{}}
}

View File

@@ -8,6 +8,7 @@ import (
"go.podman.io/common/libimage/manifests"
nettypes "go.podman.io/common/libnetwork/types"
"go.podman.io/image/v5/docker/reference"
"go.podman.io/image/v5/pkg/compression"
"go.podman.io/image/v5/types"
"go.podman.io/storage/pkg/archive"
"golang.org/x/sync/semaphore"
@@ -165,6 +166,14 @@ type BuildOptions struct {
// layer blobs. The default is to not use compression, but
// archive.Gzip is recommended.
Compression archive.Compression
// CompressionFormat is the format to use for the compression of the blobs.
CompressionFormat *compression.Algorithm
// CompressionLevel specifies what compression level is used.
CompressionLevel *int
// ForceCompressionFormat ensures that the compression algorithm set in
// CompressionFormat is used exclusively, and blobs of other compression
// algorithms are not reused.
ForceCompressionFormat bool
// Arguments which can be interpolated into Dockerfiles
Args map[string]string
// Map of external additional build contexts

View File

@@ -7,20 +7,21 @@ import (
"fmt"
"io"
"net/http"
urlpkg "net/url"
neturl "net/url"
"os"
"os/exec"
"path"
"path/filepath"
"strings"
securejoin "github.com/cyphar/filepath-securejoin"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
"go.podman.io/buildah/internal/urlsource"
"go.podman.io/image/v5/manifest"
"go.podman.io/storage/pkg/archive"
"go.podman.io/storage/pkg/chrootarchive"
"go.podman.io/storage/pkg/ioutils"
"go.podman.io/storage/types"
)
@@ -29,7 +30,7 @@ const (
// identify working containers.
Package = "buildah"
// Version for the Package. Also used by .packit.sh for Packit builds.
Version = "1.43.0-dev"
Version = "1.44.0"
// DefaultRuntime if containers.conf fails.
DefaultRuntime = "runc"
@@ -124,7 +125,7 @@ func (s Secret) ResolveValue() ([]byte, error) {
}
}
// BuildOutputOptions contains the the outcome of parsing the value of a build --output flag
// BuildOutputOptions contains the outcome of parsing the value of a build --output flag
// Deprecated: This structure is now internal
type BuildOutputOption struct {
Path string // Only valid if !IsStdout
@@ -187,75 +188,79 @@ type SBOMScanOptions struct {
// TempDirForURL checks if the passed-in string looks like a URL or "-". If it
// is, TempDirForURL creates a temporary directory, arranges for its contents
// to be the contents of that URL, and returns the temporary directory's path,
// along with the relative name of a subdirectory which should be used as the
// build context (which may be empty or "."). Removal of the temporary
// directory is the responsibility of the caller. If the string doesn't look
// like a URL or "-", TempDirForURL returns empty strings and a nil error code.
func TempDirForURL(dir, prefix, url string) (name string, subdir string, err error) {
if !strings.HasPrefix(url, "http://") &&
!strings.HasPrefix(url, "https://") &&
// to be the contents of that URL, and returns the temporary directory's path
// (for cleanup) and a relative subdirectory to the build context within it.
// Removal of the temporary directory is the responsibility of the caller.
// If the string doesn't look like a URL or "-", TempDirForURL returns empty
// strings and a nil error code.
func TempDirForURL(dir, prefix, url string) (tempDir string, relativeContextDir string, err error) {
if !urlsource.IsHTTPOrHTTPS(url) &&
!strings.HasPrefix(url, "git://") &&
!strings.HasPrefix(url, "github.com/") &&
url != "-" {
return "", "", nil
}
name, err = os.MkdirTemp(dir, prefix)
tempDir, err = os.MkdirTemp(dir, prefix)
if err != nil {
return "", "", fmt.Errorf("creating temporary directory for %q: %w", url, err)
}
downloadDir := filepath.Join(name, "download")
succeeded := false
defer func() {
if !succeeded {
if err2 := os.RemoveAll(tempDir); err2 != nil {
logrus.Errorf("error removing temporary directory %q: %v", tempDir, err2)
}
}
}()
downloadDir := filepath.Join(tempDir, "download")
if err = os.MkdirAll(downloadDir, 0o700); err != nil {
return "", "", fmt.Errorf("creating directory %q for %q: %w", downloadDir, url, err)
}
urlParsed, err := urlpkg.Parse(url)
var contentSubdir string
urlParsed, parseErr := neturl.Parse(url)
if parseErr != nil {
return "", "", fmt.Errorf("parsing url %q: %w", url, parseErr)
}
isGitURL := urlParsed.Scheme == "git" || strings.HasSuffix(urlParsed.Path, ".git")
switch {
case isGitURL:
combinedOutput, gitSubDir, cloneErr := cloneToDirectory(url, downloadDir)
if cloneErr != nil {
return "", "", fmt.Errorf("cloning %q to %q:\n%s: %w", url, tempDir, string(combinedOutput), cloneErr)
}
contentSubdir = gitSubDir
case urlsource.IsHTTPOrHTTPS(url):
if err = downloadToDirectory(url, downloadDir); err != nil {
return "", "", err
}
case strings.HasPrefix(url, "github.com/"):
ghURL := url
contentSubdir = path.Base(ghURL) + "-master"
downloadURL := fmt.Sprintf("https://%s/archive/master.tar.gz", ghURL)
logrus.Debugf("resolving url %q to %q", ghURL, downloadURL)
if err = downloadToDirectory(downloadURL, downloadDir); err != nil {
return "", "", err
}
case url == "-":
if err = stdinToDirectory(downloadDir); err != nil {
return "", "", err
}
}
contextDir, err := securejoin.SecureJoin(downloadDir, contentSubdir)
if err != nil {
return "", "", fmt.Errorf("parsing url %q: %w", url, err)
return "", "", fmt.Errorf("resolving subdirectory %q in %q: %w", contentSubdir, downloadDir, err)
}
if strings.HasPrefix(url, "git://") || strings.HasSuffix(urlParsed.Path, ".git") {
combinedOutput, gitSubDir, err := cloneToDirectory(url, downloadDir)
if err != nil {
if err2 := os.RemoveAll(name); err2 != nil {
logrus.Debugf("error removing temporary directory %q: %v", name, err2)
}
return "", "", fmt.Errorf("cloning %q to %q:\n%s: %w", url, name, string(combinedOutput), err)
}
logrus.Debugf("Build context is at %q", filepath.Join(downloadDir, gitSubDir))
return name, filepath.Join(filepath.Base(downloadDir), gitSubDir), nil
relativeContextDir, err = filepath.Rel(tempDir, contextDir)
if err != nil {
return "", "", err
}
if strings.HasPrefix(url, "github.com/") {
ghurl := url
url = fmt.Sprintf("https://%s/archive/master.tar.gz", ghurl)
logrus.Debugf("resolving url %q to %q", ghurl, url)
subdir = path.Base(ghurl) + "-master"
}
if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
err = downloadToDirectory(url, downloadDir)
if err != nil {
if err2 := os.RemoveAll(name); err2 != nil {
logrus.Debugf("error removing temporary directory %q: %v", name, err2)
}
return "", "", err
}
logrus.Debugf("Build context is at %q", filepath.Join(downloadDir, subdir))
return name, filepath.Join(filepath.Base(downloadDir), subdir), nil
}
if url == "-" {
err = stdinToDirectory(downloadDir)
if err != nil {
if err2 := os.RemoveAll(name); err2 != nil {
logrus.Debugf("error removing temporary directory %q: %v", name, err2)
}
return "", "", err
}
logrus.Debugf("Build context is at %q", filepath.Join(downloadDir, subdir))
return name, filepath.Join(filepath.Base(downloadDir), subdir), nil
}
logrus.Debugf("don't know how to retrieve %q", url)
if err2 := os.RemoveAll(name); err2 != nil {
logrus.Debugf("error removing temporary directory %q: %v", name, err2)
}
return "", "", errors.New("unreachable code reached")
logrus.Debugf("Build context is at %q", contextDir)
succeeded = true
return tempDir, relativeContextDir, nil
}
// parseGitBuildContext parses git build context to `repo`, `sub-dir`
@@ -332,6 +337,8 @@ func downloadToDirectory(url, dir string) error {
if resp.ContentLength == 0 {
return fmt.Errorf("no contents in %q", url)
}
// Try to extract the response as a tar archive; if that fails,
// assume it is a raw Dockerfile and write it as such.
if err := chrootarchive.Untar(resp.Body, dir, nil); err != nil {
resp1, err := http.Get(url)
if err != nil {
@@ -342,10 +349,8 @@ func downloadToDirectory(url, dir string) error {
if err != nil {
return err
}
dockerfile := filepath.Join(dir, "Dockerfile")
// Assume this is a Dockerfile
if err := ioutils.AtomicWriteFile(dockerfile, body, 0o600); err != nil {
return fmt.Errorf("failed to write %q to %q: %w", url, dockerfile, err)
if err := writeFileInRoot(dir, "Dockerfile", body, 0o600); err != nil {
return fmt.Errorf("failed to write %q to %q: %w", url, filepath.Join(dir, "Dockerfile"), err)
}
}
return nil
@@ -358,13 +363,43 @@ func stdinToDirectory(dir string) error {
if err != nil {
return fmt.Errorf("failed to read from stdin: %w", err)
}
// Try to extract the buffered input as a tar archive; if that fails,
// assume it is a raw Dockerfile and write it as such.
reader := bytes.NewReader(b)
if err := chrootarchive.Untar(reader, dir, nil); err != nil {
dockerfile := filepath.Join(dir, "Dockerfile")
// Assume this is a Dockerfile
if err := ioutils.AtomicWriteFile(dockerfile, b, 0o600); err != nil {
return fmt.Errorf("failed to write bytes to %q: %w", dockerfile, err)
if err := writeFileInRoot(dir, "Dockerfile", b, 0o600); err != nil {
return fmt.Errorf("failed to write bytes to %q: %w", filepath.Join(dir, "Dockerfile"), err)
}
}
return nil
}
// writeFileInRoot safely writes data to a file inside root, without following
// symlinks that escape the root directory.
func writeFileInRoot(root, name string, data []byte, perm os.FileMode) error { //nolint:unparam,nolintlint
// Above:
// unparam: 'name' currently only receives "Dockerfile" but will potentially support other files later
// nolintlint: the unparam linter only triggers if there are ≥ 4 instances; we do have that
// with --tests defaulting to true, but not with --tests=false.
rootHandle, err := os.OpenRoot(root)
if err != nil {
return err
}
defer rootHandle.Close()
if err := rootHandle.Remove(name); err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
fileHandle, err := rootHandle.OpenFile(name, os.O_CREATE|os.O_EXCL|os.O_WRONLY, perm)
if err != nil {
return err
}
_, err = fileHandle.Write(data)
if closeErr := fileHandle.Close(); closeErr != nil && err == nil {
err = closeErr
}
return err
}

View File

@@ -33,6 +33,7 @@ import (
"go.podman.io/common/pkg/config"
"go.podman.io/image/v5/docker/reference"
"go.podman.io/image/v5/manifest"
"go.podman.io/image/v5/pkg/compression"
storageTransport "go.podman.io/image/v5/storage"
"go.podman.io/image/v5/transports"
"go.podman.io/image/v5/transports/alltransports"
@@ -84,6 +85,9 @@ type executor struct {
transientMounts []Mount
transientRunMounts []string
compression archive.Compression
compressionFormat *compression.Algorithm
compressionLevel *int
forceCompressionFormat bool
output string
outputFormat string
additionalTags []string
@@ -121,7 +125,8 @@ type executor struct {
useCache bool
removeIntermediateCtrs bool
forceRmIntermediateCtrs bool
imageMap map[string]string // Used to map images that we create to handle the AS construct.
imageMap map[string]string // Used to map images that we create to handle the AS construct (stage name to image ID).
imageDigestMap map[string]string // Used to map images that we create to handle the AS construct (stage name to image (manifest) digest).
containerMap map[string]*buildah.Builder // Used to map from image names to only-created-for-the-rootfs containers.
baseMap map[string]struct{} // Holds the names of every base image, as given.
rootfsMap map[string]struct{} // Holds the names of every stage whose rootfs is referenced in a COPY or ADD instruction.
@@ -286,6 +291,9 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o
transientMounts: transientMounts,
transientRunMounts: options.TransientRunMounts,
compression: options.Compression,
compressionFormat: options.CompressionFormat,
compressionLevel: options.CompressionLevel,
forceCompressionFormat: options.ForceCompressionFormat,
output: options.Output,
outputFormat: options.OutputFormat,
additionalTags: options.AdditionalTags,
@@ -325,6 +333,7 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o
removeIntermediateCtrs: options.RemoveIntermediateCtrs,
forceRmIntermediateCtrs: options.ForceRmIntermediateCtrs,
imageMap: make(map[string]string),
imageDigestMap: make(map[string]string),
containerMap: make(map[string]*buildah.Builder),
baseMap: make(map[string]struct{}),
rootfsMap: make(map[string]struct{}),
@@ -1162,6 +1171,7 @@ func (b *executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
// that we can look it up later.
if r.Index < len(stages)-1 && r.ImageID != "" {
b.imageMap[stage.Name] = r.ImageID
b.imageDigestMap[stage.Name] = r.CommitResults.Digest.String()
// We're not populating the cache with intermediate
// images, so add this one to the list of images that
// we'll remove later.

View File

@@ -32,6 +32,7 @@ import (
"go.podman.io/buildah/internal/output"
"go.podman.io/buildah/internal/sanitize"
"go.podman.io/buildah/internal/tmpdir"
"go.podman.io/buildah/internal/urlsource"
internalUtil "go.podman.io/buildah/internal/util"
"go.podman.io/buildah/pkg/parse"
"go.podman.io/buildah/pkg/rusage"
@@ -406,12 +407,12 @@ func (s *stageExecutor) performCopy(excludes []string, copies ...imagebuilder.Co
if err := s.volumeCacheInvalidate(copy.Dest); err != nil {
return err
}
var sources []string
// The From field says to read the content from another
// container. Update the ID mappings and
// all-content-comes-from-below-this-directory value.
var idMappingOptions *define.IDMappingOptions
var copyExcludes []string
var copyExcludesWithoutContainerIgnore []string
stripSetuid := false
stripSetgid := false
preserveOwnership := false
@@ -511,6 +512,7 @@ func (s *stageExecutor) performCopy(excludes []string, copies ...imagebuilder.Co
// additional context contains a tar file
// so download and explode tar to buildah
// temp and point context to that.
// TODO: the returned path is never cleaned up, leaking disk space.
path, subdir, err := define.TempDirForURL(tmpdir.GetTempDir(), internal.BuildahExternalArtifactsDir, additionalBuildContext.Value)
if err != nil {
return fmt.Errorf("unable to download context from external source %q: %w", additionalBuildContext.Value, err)
@@ -567,16 +569,24 @@ func (s *stageExecutor) performCopy(excludes []string, copies ...imagebuilder.Co
stripSetuid = true // did this change between 18.06 and 19.03?
stripSetgid = true // did this change between 18.06 and 19.03?
}
copyExcludesWithoutContainerIgnore = excludes
if copy.Download {
logrus.Debugf("ADD %#v, %#v", excludes, copy)
} else {
logrus.Debugf("COPY %#v, %#v", excludes, copy)
}
var gitSources []string
var nonGitSources []string
for _, src := range copy.Src {
if strings.HasPrefix(src, "http://") || strings.HasPrefix(src, "https://") {
if urlsource.IsHTTPOrHTTPS(src) {
// Source is a URL, allowed for ADD but not COPY.
if copy.Download {
sources = append(sources, src)
if urlsource.IsGit(src) {
gitSources = append(gitSources, src)
} else {
nonGitSources = append(nonGitSources, src)
}
} else {
// returns an error to be compatible with docker
return fmt.Errorf("source can't be a URL for COPY")
@@ -592,7 +602,7 @@ func (s *stageExecutor) performCopy(excludes []string, copies ...imagebuilder.Co
} else {
src = filepath.Join(contextDir, src)
}
sources = append(sources, src)
nonGitSources = append(nonGitSources, src)
}
}
labelsAndAnnotations := s.buildMetadata(s.isLastStep, true)
@@ -627,8 +637,21 @@ func (s *stageExecutor) performCopy(excludes []string, copies ...imagebuilder.Co
options.Excludes = nil
options.IgnoreFile = ""
}
if err := s.builder.Add(copy.Dest, copy.Download, options, sources...); err != nil {
return err
if len(nonGitSources) > 0 {
if err := s.builder.Add(copy.Dest, copy.Download, options, nonGitSources...); err != nil {
return err
}
}
// Special handling for Git sources, local .containerignore is not applied.
if len(gitSources) > 0 {
gitOptions := options
gitOptions.Excludes = copyExcludesWithoutContainerIgnore
gitOptions.IgnoreFile = ""
if err := s.builder.Add(copy.Dest, copy.Download, gitOptions, gitSources...); err != nil {
return err
}
}
}
if len(copiesExtend) > 0 {
@@ -710,6 +733,7 @@ func (s *stageExecutor) runStageMountPoints(mountList []string) (map[string]inte
// additional context contains a tar file
// so download and explode tar to buildah
// temp and point context to that.
// TODO: the returned path is never cleaned up, leaking disk space.
path, subdir, err := define.TempDirForURL(tmpdir.GetTempDir(), internal.BuildahExternalArtifactsDir, additionalBuildContext.Value)
if err != nil {
return nil, fmt.Errorf("unable to download context from external source %q: %w", additionalBuildContext.Value, err)
@@ -2053,8 +2077,13 @@ func (s *stageExecutor) getCreatedBy(node *parser.Node, addedContentSummary stri
}
// Source specified is part of stage, image or additional-build-context.
if mountOptionFrom != "" {
// If this is not a stage then get digest of image or additional build context
if _, ok := s.executor.stages[mountOptionFrom]; !ok {
if stage, ok := s.executor.stages[mountOptionFrom]; ok {
// If source is a previous stage then checksum is image digest for that stage
if image, isPreviousStage := s.executor.imageDigestMap[stage.name]; isPreviousStage {
mountCheckSum = image
}
} else {
// If this is not a stage then get digest of image or additional build context
if builder, ok := s.executor.containerMap[mountOptionFrom]; ok {
// Found valid image, get image digest.
mountCheckSum = builder.FromImageDigest
@@ -2363,14 +2392,17 @@ func (s *stageExecutor) pushCache(ctx context.Context, src, cacheKey string) err
for _, dest := range destList {
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.systemContext,
BlobDirectory: s.executor.blobDirectory,
SignBy: s.executor.signBy,
MaxRetries: s.executor.maxPullPushRetries,
RetryDelay: s.executor.retryPullPushDelay,
Compression: s.executor.compression,
CompressionFormat: s.executor.compressionFormat,
CompressionLevel: s.executor.compressionLevel,
ForceCompressionFormat: s.executor.forceCompressionFormat,
SignaturePolicyPath: s.executor.signaturePolicyPath,
Store: s.executor.store,
SystemContext: s.systemContext,
BlobDirectory: s.executor.blobDirectory,
SignBy: s.executor.signBy,
MaxRetries: s.executor.maxPullPushRetries,
RetryDelay: s.executor.retryPullPushDelay,
}
if s.executor.cachePushSourceLookupReferenceFunc != nil {
options.SourceLookupReferenceFunc = s.executor.cachePushSourceLookupReferenceFunc(dest)
@@ -2702,6 +2734,15 @@ func (s *stageExecutor) commit(ctx context.Context, createdBy string, emptyLayer
if finalInstruction {
options.ConfidentialWorkloadOptions = s.executor.confidentialWorkload
options.SBOMScanOptions = s.executor.sbomScanOptions
// Apply compression settings only when committing to a non-local
// transport (registry, dir:, oci-archive:, etc.). Local storage
// decompresses layers on write, so specifying compression there
// would have no effect.
if imageRef != nil && imageRef.Transport().Name() != is.Transport.Name() {
options.CompressionFormat = s.executor.compressionFormat
options.CompressionLevel = s.executor.compressionLevel
options.ForceCompressionFormat = s.executor.forceCompressionFormat
}
}
results, err := s.builder.CommitResults(ctx, imageRef, options)
if err != nil {

View File

@@ -211,7 +211,8 @@ func ImageName(transportName, restOfImageName, contextDir, tmpdir string) (newFr
case dockerArchiveTransport.Transport.Name(), ociArchiveTransport.Transport.Name(): // these are, basically, tarballs
// these take the form path[:stuff]
transportRef := restOfImageName
archiveSource, refLeftover, ok := strings.Cut(transportRef, ":")
as, refLeftover, ok := strings.Cut(transportRef, ":")
archiveSource = as
if ok {
refLeftover = ":" + refLeftover
}
@@ -241,7 +242,8 @@ func ImageName(transportName, restOfImageName, contextDir, tmpdir string) (newFr
case ociLayoutTransport.Transport.Name(): // this is a directory tree
// this takes the form path[:stuff]
transportRef := restOfImageName
archiveSource, refLeftover, ok := strings.Cut(transportRef, ":")
as, refLeftover, ok := strings.Cut(transportRef, ":")
archiveSource = as
if ok {
refLeftover = ":" + refLeftover
}

View File

@@ -0,0 +1,31 @@
package urlsource
import (
"strings"
"go.podman.io/storage/pkg/regexp"
)
// gitURLFragmentSuffix matches fragments to use as Git reference and build
// context from the Git repository e.g.
//
// github.com/containers/buildah.git
// github.com/containers/buildah.git#main
// github.com/containers/buildah.git#v1.35.0
var gitURLFragmentSuffix = regexp.Delayed(`\.git(?:#.+)?$`)
// IsHTTPOrHTTPS reports whether the source is an HTTP(S) URL.
func IsHTTPOrHTTPS(source string) bool {
return strings.HasPrefix(source, "http://") || strings.HasPrefix(source, "https://")
}
// IsGit reports whether the source is an HTTP(S) Git URL.
func IsGit(source string) bool {
return IsHTTPOrHTTPS(source) && gitURLFragmentSuffix.MatchString(source)
}
// IsRemote reports whether the source is a remote HTTP(S) URL
// and *not* a Git repository. Certain GitHub URLs such as raw.github.* are allowed.
func IsRemote(source string) bool {
return IsHTTPOrHTTPS(source) && !gitURLFragmentSuffix.MatchString(source)
}

View File

@@ -5,6 +5,13 @@ import (
"go.podman.io/image/v5/types"
)
// Option configures optional BlobCache behavior.
type Option = imageBlobCache.BlobCacheOption
// WithCompressAlgorithm sets compression algorithm for compressed blobs
// when compress is set to Compress.
var WithCompressAlgorithm = imageBlobCache.WithCompressAlgorithm
// BlobCache is an object which saves copies of blobs that are written to it while passing them
// through to some real destination, and which can be queried directly in order to read them
// back.
@@ -26,6 +33,7 @@ type BlobCache interface {
// as-is to the specified directory or a temporary directory.
// The compress argument controls whether or not the cache will try to substitute a compressed
// or different version of a blob when preparing the list of layers when reading an image.
func NewBlobCache(ref types.ImageReference, directory string, compress types.LayerCompression) (BlobCache, error) {
return imageBlobCache.NewBlobCache(ref, directory, compress)
// The optional Option values can further refine behavior.
func NewBlobCache(ref types.ImageReference, directory string, compress types.LayerCompression, opts ...Option) (BlobCache, error) {
return imageBlobCache.NewBlobCache(ref, directory, compress, opts...)
}

View File

@@ -25,7 +25,9 @@ import (
"go.podman.io/buildah/pkg/parse"
"go.podman.io/buildah/pkg/util"
"go.podman.io/common/pkg/auth"
"go.podman.io/common/pkg/config"
"go.podman.io/image/v5/docker/reference"
imgCompression "go.podman.io/image/v5/pkg/compression"
"go.podman.io/image/v5/types"
)
@@ -236,6 +238,40 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) (
compression = define.Uncompressed
}
var compressionFormat *imgCompression.Algorithm
forceCompressionFormat := iopts.ForceCompressionFormat
defaultContainerConfig, err := config.Default()
if err != nil {
return options, nil, nil, fmt.Errorf("failed to get container config: %w", err)
}
if iopts.CompressionFormat != "" {
algo, err := imgCompression.AlgorithmByName(iopts.CompressionFormat)
if err != nil {
return options, nil, nil, err
}
compressionFormat = &algo
compression = define.Gzip
if !c.Flag("force-compression").Changed {
forceCompressionFormat = true
}
} else if defaultContainerConfig.Engine.CompressionFormat != "" && defaultContainerConfig.Engine.CompressionFormat != "gzip" {
algo, err := imgCompression.AlgorithmByName(defaultContainerConfig.Engine.CompressionFormat)
if err != nil {
return options, nil, nil, fmt.Errorf("parsing compression_format from containers.conf: %w", err)
}
compressionFormat = &algo
compression = define.Gzip
if !c.Flag("force-compression").Changed {
forceCompressionFormat = true
}
}
var compressionLevel *int
if c.Flag("compression-level").Changed {
compressionLevel = &iopts.CompressionLevel
} else {
compressionLevel = defaultContainerConfig.Engine.CompressionLevel
}
if c.Flag("disable-content-trust").Changed {
logrus.Debugf("--disable-content-trust option specified but is ignored")
}
@@ -399,6 +435,9 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) (
CPPFlags: iopts.CPPFlags,
CommonBuildOpts: commonOpts,
Compression: compression,
CompressionFormat: compressionFormat,
CompressionLevel: compressionLevel,
ForceCompressionFormat: forceCompressionFormat,
ConfigureNetwork: networkPolicy,
ContextDirectory: contextDir,
CreatedAnnotation: createdAnnotation,

View File

@@ -57,85 +57,88 @@ type NameSpaceResults struct {
// BudResults represents the results for Build flags
type BudResults struct {
AllPlatforms bool
Annotation []string
Authfile string
BuildArg []string
BuildArgFile []string
BuildContext []string
CacheFrom []string
CacheTo []string
CacheTTL string
CertDir string
Compress bool
Creds string
CPPFlags []string
DisableCompression bool
DisableContentTrust bool
IgnoreFile string
File []string
Format string
From string
Iidfile string
IidfileRaw string
InheritLabels bool
InheritAnnotations bool
Label []string
LayerLabel []string
Logfile string
LogSplitByPlatform bool
Manifest string
MetadataFile string
NoHostname bool
NoHosts bool
NoCache bool
Timestamp int64
OmitHistory bool
OCIHooksDir []string
Pull string
PullAlways bool
PullNever bool
Quiet bool
IdentityLabel bool
Rm bool
Runtime string
RuntimeFlags []string
SbomPreset string
SbomScannerImage string
SbomScannerCommand []string
SbomMergeStrategy string
SbomOutput string
SbomImgOutput string
SbomPurlOutput string
SbomImgPurlOutput string
Secrets []string
SSH []string
SignaturePolicy string
SignBy string
Squash bool
SkipUnusedStages bool
Stdin bool
Tag []string
BuildOutputs []string
Target string
TLSVerify bool
Jobs int
LogRusage bool
RusageLogFile string
UnsetEnvs []string
UnsetLabels []string
UnsetAnnotations []string
Envs []string
OSFeatures []string
OSVersion string
CWOptions string
SBOMOptions []string
CompatVolumes bool
SourceDateEpoch string
RewriteTimestamp bool
CreatedAnnotation bool
SourcePolicyFile string
TransientRunMounts []string
AllPlatforms bool
Annotation []string
Authfile string
BuildArg []string
BuildArgFile []string
BuildContext []string
CacheFrom []string
CacheTo []string
CacheTTL string
CertDir string
Compress bool
Creds string
CPPFlags []string
CompressionFormat string
CompressionLevel int
ForceCompressionFormat bool
DisableCompression bool
DisableContentTrust bool
IgnoreFile string
File []string
Format string
From string
Iidfile string
IidfileRaw string
InheritLabels bool
InheritAnnotations bool
Label []string
LayerLabel []string
Logfile string
LogSplitByPlatform bool
Manifest string
MetadataFile string
NoHostname bool
NoHosts bool
NoCache bool
Timestamp int64
OmitHistory bool
OCIHooksDir []string
Pull string
PullAlways bool
PullNever bool
Quiet bool
IdentityLabel bool
Rm bool
Runtime string
RuntimeFlags []string
SbomPreset string
SbomScannerImage string
SbomScannerCommand []string
SbomMergeStrategy string
SbomOutput string
SbomImgOutput string
SbomPurlOutput string
SbomImgPurlOutput string
Secrets []string
SSH []string
SignaturePolicy string
SignBy string
Squash bool
SkipUnusedStages bool
Stdin bool
Tag []string
BuildOutputs []string
Target string
TLSVerify bool
Jobs int
LogRusage bool
RusageLogFile string
UnsetEnvs []string
UnsetLabels []string
UnsetAnnotations []string
Envs []string
OSFeatures []string
OSVersion string
CWOptions string
SBOMOptions []string
CompatVolumes bool
SourceDateEpoch string
RewriteTimestamp bool
CreatedAnnotation bool
SourcePolicyFile string
TransientRunMounts []string
}
// FromAndBugResults represents the results for common flags
@@ -250,6 +253,9 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
fs.BoolVar(&flags.CreatedAnnotation, "created-annotation", true, `set an "org.opencontainers.image.created" annotation in the image`)
fs.StringVar(&flags.Creds, "creds", "", "use `[username[:password]]` for accessing the registry")
fs.StringVarP(&flags.CWOptions, "cw", "", "", "confidential workload `options`")
fs.StringVar(&flags.CompressionFormat, "compression-format", "", "compression format to use for layers and cache")
fs.IntVar(&flags.CompressionLevel, "compression-level", 0, "compression level to use for layers and cache")
fs.BoolVar(&flags.ForceCompressionFormat, "force-compression", false, "use the specified compression algorithm even if the destination contains a differently-compressed variant already")
fs.BoolVarP(&flags.DisableCompression, "disable-compression", "D", true, "don't compress layers by default")
fs.BoolVar(&flags.DisableContentTrust, "disable-content-trust", false, "this is a Docker specific option and is a NOOP")
fs.StringArrayVar(&flags.Envs, "env", []string{}, "set environment variable for the image")
@@ -355,6 +361,8 @@ func GetBudFlagsCompletions() commonComp.FlagCompletions {
flagCompletion["cache-to"] = commonComp.AutocompleteNone
flagCompletion["cache-ttl"] = commonComp.AutocompleteNone
flagCompletion["cert-dir"] = commonComp.AutocompleteDefault
flagCompletion["compression-format"] = commonComp.AutocompleteNone
flagCompletion["compression-level"] = commonComp.AutocompleteNone
flagCompletion["cpp-flag"] = commonComp.AutocompleteNone
flagCompletion["creds"] = commonComp.AutocompleteNone
flagCompletion["cw"] = commonComp.AutocompleteNone

View File

@@ -70,7 +70,7 @@ func newAgentServerSocket(socketPath string) (*AgentServer, error) {
func (a *AgentServer) Serve(processLabel string) (string, error) {
// Calls to `selinux.SetSocketLabel` should be wrapped in
// runtime.LockOSThread()/runtime.UnlockOSThread() until
// the the socket is created to guarantee another goroutine
// the socket is created to guarantee another goroutine
// does not migrate to the current thread before execution
// is complete.
// Ref: https://github.com/opencontainers/selinux/blob/main/go-selinux/selinux.go#L158

12
vendor/go.podman.io/buildah/push.go generated vendored
View File

@@ -23,14 +23,14 @@ import (
// cacheLookupReferenceFunc wraps a BlobCache into a
// libimage.LookupReferenceFunc to allow for using a BlobCache during
// image-copy operations.
func cacheLookupReferenceFunc(directory string, compress types.LayerCompression) libimage.LookupReferenceFunc {
func cacheLookupReferenceFunc(directory string, compress types.LayerCompression, opts ...blobcache.Option) libimage.LookupReferenceFunc {
// Using a closure here allows us to reference a BlobCache without
// having to explicitly maintain it in the libimage API.
return func(ref types.ImageReference) (types.ImageReference, error) {
if directory == "" {
return ref, nil
}
ref, err := blobcache.NewBlobCache(ref, directory, compress)
ref, err := blobcache.NewBlobCache(ref, directory, compress, opts...)
if err != nil {
return nil, fmt.Errorf("using blobcache %q: %w", directory, err)
}
@@ -130,13 +130,17 @@ func Push(ctx context.Context, image string, dest types.ImageReference, options
}
compress := types.PreserveOriginal
if options.Compression == archive.Gzip {
if options.Compression != archive.Uncompressed {
compress = types.Compress
}
if options.SourceLookupReferenceFunc != nil {
libimageOptions.SourceLookupReferenceFunc = options.SourceLookupReferenceFunc
} else {
libimageOptions.SourceLookupReferenceFunc = cacheLookupReferenceFunc(options.BlobDirectory, compress)
var cacheOpts []blobcache.Option
if options.CompressionFormat != nil {
cacheOpts = append(cacheOpts, blobcache.WithCompressAlgorithm(options.CompressionFormat))
}
libimageOptions.SourceLookupReferenceFunc = cacheLookupReferenceFunc(options.BlobDirectory, compress, cacheOpts...)
}
libimageOptions.DestinationLookupReferenceFunc = options.DestinationLookupReferenceFunc

30
vendor/go.podman.io/buildah/util.go generated vendored
View File

@@ -10,7 +10,6 @@ import (
v1 "github.com/opencontainers/image-spec/specs-go/v1"
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux"
"github.com/sirupsen/logrus"
"go.podman.io/buildah/copier"
"go.podman.io/image/v5/docker/reference"
@@ -131,35 +130,6 @@ func isReferenceBlocked(ref types.ImageReference, sc *types.SystemContext) (bool
return false, nil
}
// ReserveSELinuxLabels reads containers storage and reserves SELinux contexts
// which are already being used by buildah containers.
func ReserveSELinuxLabels(store storage.Store, id string) error {
if selinuxGetEnabled() {
containers, err := store.Containers()
if err != nil {
return fmt.Errorf("getting list of containers: %w", err)
}
for _, c := range containers {
if id == c.ID {
continue
}
b, err := OpenBuilder(store, c.ID)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
// Ignore not exist errors since containers probably created by other tool
// TODO, we need to read other containers json data to reserve their SELinux labels
continue
}
return err
}
// Prevent different containers from using same MCS label
selinux.ReserveLabel(b.ProcessLabel)
}
}
return nil
}
// IsContainer identifies if the specified container id is a buildah container
// in the specified store.
func IsContainer(id string, store storage.Store) (bool, error) {

View File

@@ -238,6 +238,8 @@ type CommonLanguageSettings struct {
// The destination where API teams want this client library to be published.
Destinations []ClientLibraryDestination `protobuf:"varint,2,rep,packed,name=destinations,proto3,enum=google.api.ClientLibraryDestination" json:"destinations,omitempty"`
// Configuration for which RPCs should be generated in the GAPIC client.
//
// Note: This field should not be used in most cases.
SelectiveGapicGeneration *SelectiveGapicGeneration `protobuf:"bytes,3,opt,name=selective_gapic_generation,json=selectiveGapicGeneration,proto3" json:"selective_gapic_generation,omitempty"`
}
@@ -1249,6 +1251,8 @@ func (x *MethodSettings) GetBatching() *BatchingConfigProto {
// This message is used to configure the generation of a subset of the RPCs in
// a service for client libraries.
//
// Note: This feature should not be used in most cases.
type SelectiveGapicGeneration struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache

View File

@@ -19,4 +19,4 @@
package grpc
// Version is the current grpc version.
const Version = "1.81.0"
const Version = "1.81.1"

11
vendor/modules.txt vendored
View File

@@ -362,7 +362,7 @@ github.com/miekg/pkcs11
# github.com/mistifyio/go-zfs/v4 v4.0.0
## explicit; go 1.14
github.com/mistifyio/go-zfs/v4
# github.com/moby/buildkit v0.29.0
# github.com/moby/buildkit v0.30.0
## explicit; go 1.25.5
github.com/moby/buildkit/frontend/dockerfile/command
github.com/moby/buildkit/frontend/dockerfile/parser
@@ -698,7 +698,7 @@ go.opentelemetry.io/otel/trace
go.opentelemetry.io/otel/trace/embedded
go.opentelemetry.io/otel/trace/internal/telemetry
go.opentelemetry.io/otel/trace/noop
# go.podman.io/buildah v1.42.1-0.20260501153811-377cf64e213b
# go.podman.io/buildah v1.44.0
## explicit; go 1.25.6
go.podman.io/buildah
go.podman.io/buildah/bind
@@ -719,6 +719,7 @@ go.podman.io/buildah/internal/pty
go.podman.io/buildah/internal/sanitize
go.podman.io/buildah/internal/sbom
go.podman.io/buildah/internal/tmpdir
go.podman.io/buildah/internal/urlsource
go.podman.io/buildah/internal/util
go.podman.io/buildah/internal/volumes
go.podman.io/buildah/pkg/binfmt
@@ -1046,14 +1047,14 @@ golang.org/x/tools/internal/stdlib
golang.org/x/tools/internal/typeparams
golang.org/x/tools/internal/typesinternal
golang.org/x/tools/internal/versions
# google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9
# google.golang.org/genproto/googleapis/api v0.0.0-20260406210006-6f92a3bedf2d
## explicit; go 1.25.0
google.golang.org/genproto/googleapis/api
google.golang.org/genproto/googleapis/api/annotations
# google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9
# google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d
## explicit; go 1.25.0
google.golang.org/genproto/googleapis/rpc/status
# google.golang.org/grpc v1.81.0
# google.golang.org/grpc v1.81.1
## explicit; go 1.25.0
google.golang.org/grpc
google.golang.org/grpc/attributes