mirror of https://github.com/containers/podman.git
Merge pull request #23440 from TomSweeneyRedHat/dev/tsweeney/compat-volumes
Bump to Buildah v1.37.0 and wire in --compat-volumes option
This commit is contained in:
commit
ebc7debbb0
|
@ -520,6 +520,7 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *Buil
|
||||||
CacheTTL: cacheTTL,
|
CacheTTL: cacheTTL,
|
||||||
ConfidentialWorkload: confidentialWorkloadOptions,
|
ConfidentialWorkload: confidentialWorkloadOptions,
|
||||||
CommonBuildOpts: commonOpts,
|
CommonBuildOpts: commonOpts,
|
||||||
|
CompatVolumes: types.NewOptionalBool(flags.CompatVolumes),
|
||||||
Compression: compression,
|
Compression: compression,
|
||||||
ConfigureNetwork: networkPolicy,
|
ConfigureNetwork: networkPolicy,
|
||||||
ContextDirectory: contextDir,
|
ContextDirectory: contextDir,
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
####> This option file is used in:
|
||||||
|
####> podman build, farm build
|
||||||
|
####> If file is edited, make sure the changes
|
||||||
|
####> are applicable to all of those.
|
||||||
|
#### **--compat-volumes**
|
||||||
|
|
||||||
|
Handle directories marked using the VOLUME instruction (both in this build, and
|
||||||
|
those inherited from base images) such that their contents can only be modified
|
||||||
|
by ADD and COPY instructions. Any changes made in those locations by RUN
|
||||||
|
instructions will be reverted. Before the introduction of this option, this
|
||||||
|
behavior was the default, but it is now disabled by default.
|
|
@ -92,6 +92,8 @@ host. (Examples: arm, arm64, 386, amd64, ppc64le, s390x)
|
||||||
|
|
||||||
@@option cgroupns.image
|
@@option cgroupns.image
|
||||||
|
|
||||||
|
@@option compat-volumes
|
||||||
|
|
||||||
#### **--compress**
|
#### **--compress**
|
||||||
|
|
||||||
This option is added to be aligned with other containers CLIs.
|
This option is added to be aligned with other containers CLIs.
|
||||||
|
|
|
@ -57,6 +57,8 @@ Note: Since the images built are directly pushed to a registry, the user must pa
|
||||||
|
|
||||||
Remove built images from farm nodes on success (Default: false).
|
Remove built images from farm nodes on success (Default: false).
|
||||||
|
|
||||||
|
@@option compat-volumes
|
||||||
|
|
||||||
@@option cpp-flag
|
@@option cpp-flag
|
||||||
|
|
||||||
@@option cpu-period
|
@@option cpu-period
|
||||||
|
|
16
go.mod
16
go.mod
|
@ -12,15 +12,15 @@ require (
|
||||||
github.com/checkpoint-restore/checkpointctl v1.2.1
|
github.com/checkpoint-restore/checkpointctl v1.2.1
|
||||||
github.com/checkpoint-restore/go-criu/v7 v7.1.0
|
github.com/checkpoint-restore/go-criu/v7 v7.1.0
|
||||||
github.com/containernetworking/plugins v1.5.1
|
github.com/containernetworking/plugins v1.5.1
|
||||||
github.com/containers/buildah v1.36.1-0.20240715114330-4a82e0a3f382
|
github.com/containers/buildah v1.37.0
|
||||||
github.com/containers/common v0.59.1-0.20240717135212-fdbae3a180cb
|
github.com/containers/common v0.60.0
|
||||||
github.com/containers/conmon v2.0.20+incompatible
|
github.com/containers/conmon v2.0.20+incompatible
|
||||||
github.com/containers/gvisor-tap-vsock v0.7.4
|
github.com/containers/gvisor-tap-vsock v0.7.4
|
||||||
github.com/containers/image/v5 v5.31.1-0.20240711123249-1dbd8fbbe516
|
github.com/containers/image/v5 v5.32.0
|
||||||
github.com/containers/libhvee v0.7.1
|
github.com/containers/libhvee v0.7.1
|
||||||
github.com/containers/ocicrypt v1.2.0
|
github.com/containers/ocicrypt v1.2.0
|
||||||
github.com/containers/psgo v1.9.0
|
github.com/containers/psgo v1.9.0
|
||||||
github.com/containers/storage v1.54.1-0.20240724150347-86a0c425388b
|
github.com/containers/storage v1.55.0
|
||||||
github.com/containers/winquit v1.1.0
|
github.com/containers/winquit v1.1.0
|
||||||
github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09
|
github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09
|
||||||
github.com/coreos/stream-metadata-go v0.4.4
|
github.com/coreos/stream-metadata-go v0.4.4
|
||||||
|
@ -29,7 +29,7 @@ require (
|
||||||
github.com/cyphar/filepath-securejoin v0.3.1
|
github.com/cyphar/filepath-securejoin v0.3.1
|
||||||
github.com/digitalocean/go-qemu v0.0.0-20230711162256-2e3d0186973e
|
github.com/digitalocean/go-qemu v0.0.0-20230711162256-2e3d0186973e
|
||||||
github.com/docker/distribution v2.8.3+incompatible
|
github.com/docker/distribution v2.8.3+incompatible
|
||||||
github.com/docker/docker v27.1.0+incompatible
|
github.com/docker/docker v27.1.1+incompatible
|
||||||
github.com/docker/go-connections v0.5.0
|
github.com/docker/go-connections v0.5.0
|
||||||
github.com/docker/go-plugins-helpers v0.0.0-20211224144127-6eecb7beb651
|
github.com/docker/go-plugins-helpers v0.0.0-20211224144127-6eecb7beb651
|
||||||
github.com/docker/go-units v0.5.0
|
github.com/docker/go-units v0.5.0
|
||||||
|
@ -59,7 +59,7 @@ require (
|
||||||
github.com/opencontainers/runtime-spec v1.2.0
|
github.com/opencontainers/runtime-spec v1.2.0
|
||||||
github.com/opencontainers/runtime-tools v0.9.1-0.20230914150019-408c51e934dc
|
github.com/opencontainers/runtime-tools v0.9.1-0.20230914150019-408c51e934dc
|
||||||
github.com/opencontainers/selinux v1.11.0
|
github.com/opencontainers/selinux v1.11.0
|
||||||
github.com/openshift/imagebuilder v1.2.11
|
github.com/openshift/imagebuilder v1.2.14
|
||||||
github.com/rootless-containers/rootlesskit/v2 v2.2.0
|
github.com/rootless-containers/rootlesskit/v2 v2.2.0
|
||||||
github.com/shirou/gopsutil/v3 v3.24.5
|
github.com/shirou/gopsutil/v3 v3.24.5
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
|
@ -102,7 +102,7 @@ require (
|
||||||
github.com/containerd/log v0.1.0 // indirect
|
github.com/containerd/log v0.1.0 // indirect
|
||||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
|
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
|
||||||
github.com/containerd/typeurl/v2 v2.1.1 // indirect
|
github.com/containerd/typeurl/v2 v2.1.1 // indirect
|
||||||
github.com/containernetworking/cni v1.2.2 // indirect
|
github.com/containernetworking/cni v1.2.3 // indirect
|
||||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
|
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
|
||||||
github.com/containers/luksy v0.0.0-20240618143119-a8846e21c08c // indirect
|
github.com/containers/luksy v0.0.0-20240618143119-a8846e21c08c // indirect
|
||||||
github.com/coreos/go-oidc/v3 v3.10.0 // indirect
|
github.com/coreos/go-oidc/v3 v3.10.0 // indirect
|
||||||
|
@ -115,7 +115,7 @@ require (
|
||||||
github.com/docker/docker-credential-helpers v0.8.2 // indirect
|
github.com/docker/docker-credential-helpers v0.8.2 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||||
github.com/fsouza/go-dockerclient v1.11.0 // indirect
|
github.com/fsouza/go-dockerclient v1.11.1 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/gin-gonic/gin v1.9.1 // indirect
|
github.com/gin-gonic/gin v1.9.1 // indirect
|
||||||
|
|
40
go.sum
40
go.sum
|
@ -73,20 +73,20 @@ github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G
|
||||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
|
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
|
||||||
github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4=
|
github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4=
|
||||||
github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0=
|
github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0=
|
||||||
github.com/containernetworking/cni v1.2.2 h1:9IbP6KJQQxVKo4hhnm8r50YcVKrJbJu3Dqw+Rbt1vYk=
|
github.com/containernetworking/cni v1.2.3 h1:hhOcjNVUQTnzdRJ6alC5XF+wd9mfGIUaj8FuJbEslXM=
|
||||||
github.com/containernetworking/cni v1.2.2/go.mod h1:DuLgF+aPd3DzcTQTtp/Nvl1Kim23oFKdm2okJzBQA5M=
|
github.com/containernetworking/cni v1.2.3/go.mod h1:DuLgF+aPd3DzcTQTtp/Nvl1Kim23oFKdm2okJzBQA5M=
|
||||||
github.com/containernetworking/plugins v1.5.1 h1:T5ji+LPYjjgW0QM+KyrigZbLsZ8jaX+E5J/EcKOE4gQ=
|
github.com/containernetworking/plugins v1.5.1 h1:T5ji+LPYjjgW0QM+KyrigZbLsZ8jaX+E5J/EcKOE4gQ=
|
||||||
github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM=
|
github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM=
|
||||||
github.com/containers/buildah v1.36.1-0.20240715114330-4a82e0a3f382 h1:NUScZGjAC6Cd1KuPcnCac10Q/gz01PULzh7Em/VXZOc=
|
github.com/containers/buildah v1.37.0 h1:jvHwu1vIwIqnHyOSg9eef9Apdpry+5oWLrm43gdf8Rk=
|
||||||
github.com/containers/buildah v1.36.1-0.20240715114330-4a82e0a3f382/go.mod h1:HlwJHYRlP5j8siiPY46I8py00hlGxWPC/vCZZ/01EEU=
|
github.com/containers/buildah v1.37.0/go.mod h1:MKd79tkluMf6vtH06SedhBQK5OB7E0pFVIuiTTw3dJk=
|
||||||
github.com/containers/common v0.59.1-0.20240717135212-fdbae3a180cb h1:9OgHqOACzWRzPFewtx/lOSKnPvWAMMlW3ruvXQL4fP4=
|
github.com/containers/common v0.60.0 h1:QMNygqiiit9LU/yqee9Dv0N0oQ+rQq41ElfdOBQtw7w=
|
||||||
github.com/containers/common v0.59.1-0.20240717135212-fdbae3a180cb/go.mod h1:KrQ9y5qa7TBVzp7qs7I1MVi6Uxntu0hM5wjd5bmvMnM=
|
github.com/containers/common v0.60.0/go.mod h1:dtKVe11xkV89tqzRX9s/B0ORjeB2dy5UB46aGjunMn8=
|
||||||
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
|
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/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
|
||||||
github.com/containers/gvisor-tap-vsock v0.7.4 h1:iOtr/KEi+r599OOx1+9Qbss91jD5yxh1HO35MKTdths=
|
github.com/containers/gvisor-tap-vsock v0.7.4 h1:iOtr/KEi+r599OOx1+9Qbss91jD5yxh1HO35MKTdths=
|
||||||
github.com/containers/gvisor-tap-vsock v0.7.4/go.mod h1:orUOSdxU/IGEOxhecu2i7EzV7k7e2TgQlyCBfUngS0A=
|
github.com/containers/gvisor-tap-vsock v0.7.4/go.mod h1:orUOSdxU/IGEOxhecu2i7EzV7k7e2TgQlyCBfUngS0A=
|
||||||
github.com/containers/image/v5 v5.31.1-0.20240711123249-1dbd8fbbe516 h1:BVyB11XLbT7s0tMF1qzdc5R04gO2BRAdjbftRwNoLXM=
|
github.com/containers/image/v5 v5.32.0 h1:yjbweazPfr8xOzQ2hkkYm1A2V0jN96/kES6Gwyxj7hQ=
|
||||||
github.com/containers/image/v5 v5.31.1-0.20240711123249-1dbd8fbbe516/go.mod h1:iAUT9Iy/z0QPrYeILorryErMUxm4GlRzBE0Yz65l/uE=
|
github.com/containers/image/v5 v5.32.0/go.mod h1:x5e0RDfGaY6bnQ13gJ2LqbfHvzssfB/y5a8HduGFxJc=
|
||||||
github.com/containers/libhvee v0.7.1 h1:dWGF5GLq9DZvXo3P8aDp3cNieL5eCaSell4UmeA/jY4=
|
github.com/containers/libhvee v0.7.1 h1:dWGF5GLq9DZvXo3P8aDp3cNieL5eCaSell4UmeA/jY4=
|
||||||
github.com/containers/libhvee v0.7.1/go.mod h1:fRKB3AyIqHMvq6xaeYhTpckM2cdoq0oecolyoiuLP7M=
|
github.com/containers/libhvee v0.7.1/go.mod h1:fRKB3AyIqHMvq6xaeYhTpckM2cdoq0oecolyoiuLP7M=
|
||||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
|
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
|
||||||
|
@ -97,8 +97,8 @@ github.com/containers/ocicrypt v1.2.0 h1:X14EgRK3xNFvJEfI5O4Qn4T3E25ANudSOZz/sir
|
||||||
github.com/containers/ocicrypt v1.2.0/go.mod h1:ZNviigQajtdlxIZGibvblVuIFBKIuUI2M0QM12SD31U=
|
github.com/containers/ocicrypt v1.2.0/go.mod h1:ZNviigQajtdlxIZGibvblVuIFBKIuUI2M0QM12SD31U=
|
||||||
github.com/containers/psgo v1.9.0 h1:eJ74jzSaCHnWt26OlKZROSyUyRcGDf+gYBdXnxrMW4g=
|
github.com/containers/psgo v1.9.0 h1:eJ74jzSaCHnWt26OlKZROSyUyRcGDf+gYBdXnxrMW4g=
|
||||||
github.com/containers/psgo v1.9.0/go.mod h1:0YoluUm43Mz2UnBIh1P+6V6NWcbpTL5uRtXyOcH0B5A=
|
github.com/containers/psgo v1.9.0/go.mod h1:0YoluUm43Mz2UnBIh1P+6V6NWcbpTL5uRtXyOcH0B5A=
|
||||||
github.com/containers/storage v1.54.1-0.20240724150347-86a0c425388b h1:xWuoWniyeweN/rNmTQJTaGSth5rKQ3V6EcQ4V3XVa/A=
|
github.com/containers/storage v1.55.0 h1:wTWZ3YpcQf1F+dSP4KxG9iqDfpQY1otaUXjPpffuhgg=
|
||||||
github.com/containers/storage v1.54.1-0.20240724150347-86a0c425388b/go.mod h1:NbpcPTBSlREa7GfqzHqPaAD28CtBsZu+xsryPkOLnHg=
|
github.com/containers/storage v1.55.0/go.mod h1:28cB81IDk+y7ok60Of6u52RbCeBRucbFOeLunhER1RQ=
|
||||||
github.com/containers/winquit v1.1.0 h1:jArun04BNDQvt2W0Y78kh9TazN2EIEMG5Im6/JY7+pE=
|
github.com/containers/winquit v1.1.0 h1:jArun04BNDQvt2W0Y78kh9TazN2EIEMG5Im6/JY7+pE=
|
||||||
github.com/containers/winquit v1.1.0/go.mod h1:PsPeZlnbkmGGIToMPHF1zhWjBUkd8aHjMOr/vFcPxw8=
|
github.com/containers/winquit v1.1.0/go.mod h1:PsPeZlnbkmGGIToMPHF1zhWjBUkd8aHjMOr/vFcPxw8=
|
||||||
github.com/coreos/go-oidc/v3 v3.10.0 h1:tDnXHnLyiTVyT/2zLDGj09pFPkhND8Gl8lnTRhoEaJU=
|
github.com/coreos/go-oidc/v3 v3.10.0 h1:tDnXHnLyiTVyT/2zLDGj09pFPkhND8Gl8lnTRhoEaJU=
|
||||||
|
@ -132,12 +132,12 @@ github.com/disiqueira/gotree/v3 v3.0.2 h1:ik5iuLQQoufZBNPY518dXhiO5056hyNBIK9lWh
|
||||||
github.com/disiqueira/gotree/v3 v3.0.2/go.mod h1:ZuyjE4+mUQZlbpkI24AmruZKhg3VHEgPLDY8Qk+uUu8=
|
github.com/disiqueira/gotree/v3 v3.0.2/go.mod h1:ZuyjE4+mUQZlbpkI24AmruZKhg3VHEgPLDY8Qk+uUu8=
|
||||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||||
github.com/docker/cli v27.0.3+incompatible h1:usGs0/BoBW8MWxGeEtqPMkzOY56jZ6kYlSN5BLDioCQ=
|
github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE=
|
||||||
github.com/docker/cli v27.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v27.1.0+incompatible h1:rEHVQc4GZ0MIQKifQPHSFGV/dVgaZafgRf8fCPtDYBs=
|
github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
|
||||||
github.com/docker/docker v27.1.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
|
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
|
||||||
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||||
|
@ -161,8 +161,8 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
|
||||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
github.com/fsouza/go-dockerclient v1.11.0 h1:4ZAk6W7rPAtPXm7198EFqA5S68rwnNQORxlOA5OurCA=
|
github.com/fsouza/go-dockerclient v1.11.1 h1:i5Vk9riDxW2uP9pVS5FYkpquMTFT5lsx2pt7oErRTjI=
|
||||||
github.com/fsouza/go-dockerclient v1.11.0/go.mod h1:0I3TQCRseuPTzqlY4Y3ajfsg2VAdMQoazrkxJTiJg8s=
|
github.com/fsouza/go-dockerclient v1.11.1/go.mod h1:UfjOOaspAq+RGh7GX1aZ0HeWWGHQWWsh+H5BgEWB3Pk=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
|
@ -398,8 +398,8 @@ github.com/opencontainers/runtime-tools v0.9.1-0.20230914150019-408c51e934dc h1:
|
||||||
github.com/opencontainers/runtime-tools v0.9.1-0.20230914150019-408c51e934dc/go.mod h1:8tx1helyqhUC65McMm3x7HmOex8lO2/v9zPuxmKHurs=
|
github.com/opencontainers/runtime-tools v0.9.1-0.20230914150019-408c51e934dc/go.mod h1:8tx1helyqhUC65McMm3x7HmOex8lO2/v9zPuxmKHurs=
|
||||||
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
|
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
|
||||||
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
||||||
github.com/openshift/imagebuilder v1.2.11 h1:4EmEMyiLr7jlskS1h6V6smdcrQSGLRdcIeaXeV3F8EM=
|
github.com/openshift/imagebuilder v1.2.14 h1:l4gUw0KIsjZrX7otfS4WoKxzGBrxYldU3pF4+5W/ud8=
|
||||||
github.com/openshift/imagebuilder v1.2.11/go.mod h1:KkkXOyRjJlZEXWQtHNBNzVHqh4vf/0xX5cDIQ2gr+5I=
|
github.com/openshift/imagebuilder v1.2.14/go.mod h1:KkkXOyRjJlZEXWQtHNBNzVHqh4vf/0xX5cDIQ2gr+5I=
|
||||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||||
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f h1:/UDgs8FGMqwnHagNDPGOlts35QkhAZ8by3DR7nMih7M=
|
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f h1:/UDgs8FGMqwnHagNDPGOlts35QkhAZ8by3DR7nMih7M=
|
||||||
|
@ -426,8 +426,8 @@ github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZ
|
||||||
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
|
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
|
||||||
github.com/prometheus/common v0.51.1 h1:eIjN50Bwglz6a/c3hAgSMcofL3nD+nFQkV6Dd4DsQCw=
|
github.com/prometheus/common v0.51.1 h1:eIjN50Bwglz6a/c3hAgSMcofL3nD+nFQkV6Dd4DsQCw=
|
||||||
github.com/prometheus/common v0.51.1/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q=
|
github.com/prometheus/common v0.51.1/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q=
|
||||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
|
|
|
@ -97,6 +97,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||||
CacheTo string `schema:"cacheto"`
|
CacheTo string `schema:"cacheto"`
|
||||||
CacheTTL string `schema:"cachettl"`
|
CacheTTL string `schema:"cachettl"`
|
||||||
CgroupParent string `schema:"cgroupparent"`
|
CgroupParent string `schema:"cgroupparent"`
|
||||||
|
CompatVolumes bool `schema:"compatvolumes"`
|
||||||
Compression uint64 `schema:"compression"`
|
Compression uint64 `schema:"compression"`
|
||||||
ConfigureNetwork string `schema:"networkmode"`
|
ConfigureNetwork string `schema:"networkmode"`
|
||||||
CPPFlags string `schema:"cppflags"`
|
CPPFlags string `schema:"cppflags"`
|
||||||
|
@ -702,6 +703,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
|
||||||
Secrets: secrets,
|
Secrets: secrets,
|
||||||
Volumes: query.Volumes,
|
Volumes: query.Volumes,
|
||||||
},
|
},
|
||||||
|
CompatVolumes: types.NewOptionalBool(query.CompatVolumes),
|
||||||
Compression: compression,
|
Compression: compression,
|
||||||
ConfigureNetwork: parseNetworkConfigurationPolicy(query.ConfigureNetwork),
|
ConfigureNetwork: parseNetworkConfigurationPolicy(query.ConfigureNetwork),
|
||||||
ContextDirectory: contextDirectory,
|
ContextDirectory: contextDirectory,
|
||||||
|
|
|
@ -540,6 +540,13 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
||||||
// description: |
|
// description: |
|
||||||
// Suppress verbose build output
|
// Suppress verbose build output
|
||||||
// - in: query
|
// - in: query
|
||||||
|
// name: compatvolumes
|
||||||
|
// type: boolean
|
||||||
|
// default: false
|
||||||
|
// description: |
|
||||||
|
// Contents of base images to be modified on ADD or COPY only
|
||||||
|
// (As of version 1.37)
|
||||||
|
// - in: query
|
||||||
// name: nocache
|
// name: nocache
|
||||||
// type: boolean
|
// type: boolean
|
||||||
// default: false
|
// default: false
|
||||||
|
@ -1494,6 +1501,13 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
||||||
// description: |
|
// description: |
|
||||||
// Suppress verbose build output
|
// Suppress verbose build output
|
||||||
// - in: query
|
// - in: query
|
||||||
|
// name: compatvolumes
|
||||||
|
// type: boolean
|
||||||
|
// default: false
|
||||||
|
// description: |
|
||||||
|
// Contents of base images to be modified on ADD or COPY only
|
||||||
|
// (As of version 1.37)
|
||||||
|
// - in: query
|
||||||
// name: nocache
|
// name: nocache
|
||||||
// type: boolean
|
// type: boolean
|
||||||
// default: false
|
// default: false
|
||||||
|
|
|
@ -281,6 +281,12 @@ func Build(ctx context.Context, containerFiles []string, options types.BuildOpti
|
||||||
if mem := options.CommonBuildOpts.Memory; mem > 0 {
|
if mem := options.CommonBuildOpts.Memory; mem > 0 {
|
||||||
params.Set("memory", strconv.Itoa(int(mem)))
|
params.Set("memory", strconv.Itoa(int(mem)))
|
||||||
}
|
}
|
||||||
|
switch options.CompatVolumes {
|
||||||
|
case imageTypes.OptionalBoolTrue:
|
||||||
|
params.Set("compatvolumes", "1")
|
||||||
|
case imageTypes.OptionalBoolFalse:
|
||||||
|
params.Set("compatvolumes", "0")
|
||||||
|
}
|
||||||
if options.NoCache {
|
if options.NoCache {
|
||||||
params.Set("nocache", "1")
|
params.Set("nocache", "1")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
From 09b115ea501320bde7cf979f280f42dc803aa70b Mon Sep 17 00:00:00 2001
|
From 6f7a27f4787ec91ecf7bd7c4de048b23c3cdb74f Mon Sep 17 00:00:00 2001
|
||||||
From: Ed Santiago <santiago@redhat.com>
|
From: Ed Santiago <santiago@redhat.com>
|
||||||
Date: Thu, 6 Oct 2022 17:32:59 -0600
|
Date: Thu, 6 Oct 2022 17:32:59 -0600
|
||||||
Subject: [PATCH] tweaks for running buildah tests under podman
|
Subject: [PATCH] tweaks for running buildah tests under podman
|
||||||
|
@ -9,13 +9,13 @@ Signed-off-by: Ed Santiago <santiago@redhat.com>
|
||||||
1 file changed, 115 insertions(+), 4 deletions(-)
|
1 file changed, 115 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
diff --git a/tests/helpers.bash b/tests/helpers.bash
|
diff --git a/tests/helpers.bash b/tests/helpers.bash
|
||||||
index f4245c8bc..8df18c0cc 100644
|
index b47939284..ce6dde76e 100644
|
||||||
--- a/tests/helpers.bash
|
--- a/tests/helpers.bash
|
||||||
+++ b/tests/helpers.bash
|
+++ b/tests/helpers.bash
|
||||||
@@ -71,6 +71,38 @@ EOF
|
@@ -79,6 +79,38 @@ EOF
|
||||||
BUILDAH_REGISTRY_OPTS="--registries-conf ${TEST_SOURCES}/registries.conf --registries-conf-dir ${TEST_SCRATCH_DIR}/registries.d --short-name-alias-conf ${TEST_SCRATCH_DIR}/cache/shortnames.conf"
|
BUILDAH_REGISTRY_OPTS="${regconfopt} ${regconfdir} --short-name-alias-conf ${TEST_SCRATCH_DIR}/cache/shortnames.conf"
|
||||||
COPY_REGISTRY_OPTS="--registries-conf ${TEST_SOURCES}/registries.conf --registries-conf-dir ${TEST_SCRATCH_DIR}/registries.d --short-name-alias-conf ${TEST_SCRATCH_DIR}/cache/shortnames.conf"
|
COPY_REGISTRY_OPTS="${BUILDAH_REGISTRY_OPTS}"
|
||||||
PODMAN_REGISTRY_OPTS="--registries-conf ${TEST_SOURCES}/registries.conf"
|
PODMAN_REGISTRY_OPTS="${regconfopt}"
|
||||||
+
|
+
|
||||||
+ PODMAN_SERVER_PID=
|
+ PODMAN_SERVER_PID=
|
||||||
+ PODMAN_NATIVE="${PODMAN_BINARY} ${ROOTDIR_OPTS} ${PODMAN_REGISTRY_OPTS}"
|
+ PODMAN_NATIVE="${PODMAN_BINARY} ${ROOTDIR_OPTS} ${PODMAN_REGISTRY_OPTS}"
|
||||||
|
@ -51,7 +51,7 @@ index f4245c8bc..8df18c0cc 100644
|
||||||
}
|
}
|
||||||
|
|
||||||
function starthttpd() {
|
function starthttpd() {
|
||||||
@@ -114,6 +146,32 @@ function teardown_tests() {
|
@@ -122,6 +154,32 @@ function teardown_tests() {
|
||||||
stop_git_daemon
|
stop_git_daemon
|
||||||
stop_registry
|
stop_registry
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ index f4245c8bc..8df18c0cc 100644
|
||||||
# Workaround for #1991 - buildah + overlayfs leaks mount points.
|
# Workaround for #1991 - buildah + overlayfs leaks mount points.
|
||||||
# Many tests leave behind /var/tmp/.../root/overlay and sub-mounts;
|
# Many tests leave behind /var/tmp/.../root/overlay and sub-mounts;
|
||||||
# let's find those and clean them up, otherwise 'rm -rf' fails.
|
# let's find those and clean them up, otherwise 'rm -rf' fails.
|
||||||
@@ -203,7 +261,12 @@ function copy() {
|
@@ -211,7 +269,12 @@ function copy() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function podman() {
|
function podman() {
|
||||||
|
@ -98,7 +98,7 @@ index f4245c8bc..8df18c0cc 100644
|
||||||
}
|
}
|
||||||
|
|
||||||
# There are various scenarios where we would like to execute `tests` as rootless user, however certain commands like `buildah mount`
|
# There are various scenarios where we would like to execute `tests` as rootless user, however certain commands like `buildah mount`
|
||||||
@@ -267,8 +330,36 @@ function run_buildah() {
|
@@ -275,8 +338,36 @@ function run_buildah() {
|
||||||
--retry) retry=3; shift;; # retry network flakes
|
--retry) retry=3; shift;; # retry network flakes
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ index f4245c8bc..8df18c0cc 100644
|
||||||
|
|
||||||
# If session is rootless and `buildah mount` is invoked, perform unshare,
|
# If session is rootless and `buildah mount` is invoked, perform unshare,
|
||||||
# since normal user cannot mount a filesystem unless they're in a user namespace along with its own mount namespace.
|
# since normal user cannot mount a filesystem unless they're in a user namespace along with its own mount namespace.
|
||||||
@@ -282,8 +373,8 @@ function run_buildah() {
|
@@ -290,8 +381,8 @@ function run_buildah() {
|
||||||
retry=$(( retry - 1 ))
|
retry=$(( retry - 1 ))
|
||||||
|
|
||||||
# stdout is only emitted upon error; this echo is to help a debugger
|
# stdout is only emitted upon error; this echo is to help a debugger
|
||||||
|
@ -147,7 +147,7 @@ index f4245c8bc..8df18c0cc 100644
|
||||||
# without "quotes", multiple lines are glommed together into one
|
# without "quotes", multiple lines are glommed together into one
|
||||||
if [ -n "$output" ]; then
|
if [ -n "$output" ]; then
|
||||||
echo "$output"
|
echo "$output"
|
||||||
@@ -644,6 +735,26 @@ function skip_if_no_unshare() {
|
@@ -652,6 +743,26 @@ function skip_if_no_unshare() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,5 +175,4 @@ index f4245c8bc..8df18c0cc 100644
|
||||||
daemondir=${TEST_SCRATCH_DIR}/git-daemon
|
daemondir=${TEST_SCRATCH_DIR}/git-daemon
|
||||||
mkdir -p ${daemondir}/repo
|
mkdir -p ${daemondir}/repo
|
||||||
--
|
--
|
||||||
2.44.0
|
2.45.2
|
||||||
|
|
||||||
|
|
116
vendor/github.com/containerd/containerd/errdefs/errdefs_deprecated.go
generated
vendored
Normal file
116
vendor/github.com/containerd/containerd/errdefs/errdefs_deprecated.go
generated
vendored
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Package errdefs defines the common errors used throughout containerd
|
||||||
|
// packages.
|
||||||
|
//
|
||||||
|
// Use with fmt.Errorf to add context to an error.
|
||||||
|
//
|
||||||
|
// To detect an error class, use the IsXXX functions to tell whether an error
|
||||||
|
// is of a certain type.
|
||||||
|
//
|
||||||
|
// The functions ToGRPC and FromGRPC can be used to map server-side and
|
||||||
|
// client-side errors to the correct types.
|
||||||
|
package errdefs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/containerd/errdefs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Definitions of common error types used throughout containerd. All containerd
|
||||||
|
// errors returned by most packages will map into one of these errors classes.
|
||||||
|
// Packages should return errors of these types when they want to instruct a
|
||||||
|
// client to take a particular action.
|
||||||
|
//
|
||||||
|
// For the most part, we just try to provide local grpc errors. Most conditions
|
||||||
|
// map very well to those defined by grpc.
|
||||||
|
var (
|
||||||
|
ErrUnknown = errdefs.ErrUnknown
|
||||||
|
ErrInvalidArgument = errdefs.ErrInvalidArgument
|
||||||
|
ErrNotFound = errdefs.ErrNotFound
|
||||||
|
ErrAlreadyExists = errdefs.ErrAlreadyExists
|
||||||
|
ErrFailedPrecondition = errdefs.ErrFailedPrecondition
|
||||||
|
ErrUnavailable = errdefs.ErrUnavailable
|
||||||
|
ErrNotImplemented = errdefs.ErrNotImplemented
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsInvalidArgument returns true if the error is due to an invalid argument
|
||||||
|
func IsInvalidArgument(err error) bool {
|
||||||
|
return errdefs.IsInvalidArgument(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNotFound returns true if the error is due to a missing object
|
||||||
|
func IsNotFound(err error) bool {
|
||||||
|
return errdefs.IsNotFound(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAlreadyExists returns true if the error is due to an already existing
|
||||||
|
// metadata item
|
||||||
|
func IsAlreadyExists(err error) bool {
|
||||||
|
return errdefs.IsAlreadyExists(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsFailedPrecondition returns true if an operation could not proceed to the
|
||||||
|
// lack of a particular condition
|
||||||
|
func IsFailedPrecondition(err error) bool {
|
||||||
|
return errdefs.IsFailedPrecondition(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsUnavailable returns true if the error is due to a resource being unavailable
|
||||||
|
func IsUnavailable(err error) bool {
|
||||||
|
return errdefs.IsUnavailable(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNotImplemented returns true if the error is due to not being implemented
|
||||||
|
func IsNotImplemented(err error) bool {
|
||||||
|
return errdefs.IsNotImplemented(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCanceled returns true if the error is due to `context.Canceled`.
|
||||||
|
func IsCanceled(err error) bool {
|
||||||
|
return errdefs.IsCanceled(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDeadlineExceeded returns true if the error is due to
|
||||||
|
// `context.DeadlineExceeded`.
|
||||||
|
func IsDeadlineExceeded(err error) bool {
|
||||||
|
return errdefs.IsDeadlineExceeded(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToGRPC will attempt to map the backend containerd error into a grpc error,
|
||||||
|
// using the original error message as a description.
|
||||||
|
//
|
||||||
|
// Further information may be extracted from certain errors depending on their
|
||||||
|
// type.
|
||||||
|
//
|
||||||
|
// If the error is unmapped, the original error will be returned to be handled
|
||||||
|
// by the regular grpc error handling stack.
|
||||||
|
func ToGRPC(err error) error {
|
||||||
|
return errdefs.ToGRPC(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToGRPCf maps the error to grpc error codes, assembling the formatting string
|
||||||
|
// and combining it with the target error string.
|
||||||
|
//
|
||||||
|
// This is equivalent to errdefs.ToGRPC(fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), err))
|
||||||
|
func ToGRPCf(err error, format string, args ...interface{}) error {
|
||||||
|
return errdefs.ToGRPCf(err, format, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromGRPC returns the underlying error from a grpc service based on the grpc error code
|
||||||
|
func FromGRPC(err error) error {
|
||||||
|
return errdefs.FromGRPC(err)
|
||||||
|
}
|
|
@ -817,6 +817,8 @@ func (c *CNIConfig) GCNetworkList(ctx context.Context, list *NetworkConfigList,
|
||||||
}
|
}
|
||||||
if args != nil {
|
if args != nil {
|
||||||
inject["cni.dev/valid-attachments"] = args.ValidAttachments
|
inject["cni.dev/valid-attachments"] = args.ValidAttachments
|
||||||
|
// #1101: spec used incorrect variable name
|
||||||
|
inject["cni.dev/attachments"] = args.ValidAttachments
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, plugin := range list.Plugins {
|
for _, plugin := range list.Plugins {
|
||||||
|
|
|
@ -32,7 +32,7 @@ env:
|
||||||
DEBIAN_NAME: "debian-13"
|
DEBIAN_NAME: "debian-13"
|
||||||
|
|
||||||
# Image identifiers
|
# Image identifiers
|
||||||
IMAGE_SUFFIX: "c20240620t153000z-f40f39d13"
|
IMAGE_SUFFIX: "c20240708t152000z-f40f39d13"
|
||||||
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
|
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}"
|
||||||
DEBIAN_CACHE_IMAGE_NAME: "debian-${IMAGE_SUFFIX}"
|
DEBIAN_CACHE_IMAGE_NAME: "debian-${IMAGE_SUFFIX}"
|
||||||
|
|
|
@ -2,6 +2,78 @@
|
||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## vv1.37.0 (2024-07-26)
|
||||||
|
|
||||||
|
Bump c/storage, c/image, c/common for v1.37.0
|
||||||
|
"build with basename resolving user arg" tests: correct ARG use
|
||||||
|
bud-multiple-platform-no-run test: correct ARG use
|
||||||
|
imagebuildah: always have default values for $TARGET... args ready
|
||||||
|
bump github.com/openshift/imagebuilder to v1.2.14
|
||||||
|
fix(deps): update module github.com/docker/docker to v27.1.1+incompatible
|
||||||
|
fix(deps): update module github.com/cyphar/filepath-securejoin to v0.3.1
|
||||||
|
fix(deps): update module github.com/docker/docker to v27.1.0+incompatible
|
||||||
|
CI: use local registry, part 2 of 2
|
||||||
|
CI: use local registry, part 1 of 2
|
||||||
|
fix(deps): update module github.com/fsouza/go-dockerclient to v1.11.1
|
||||||
|
Revert "fix(deps): update github.com/containers/image/v5 to v5.31.1"
|
||||||
|
Replace libimage.LookupReferenceFunc with the manifests version
|
||||||
|
conformance tests: enable testing CompatVolumes
|
||||||
|
conformance tests: add a test that tries to chown a volume
|
||||||
|
imagebuildah: make traditional volume handling not the default
|
||||||
|
StageExecutor.prepare(): mark base image volumes for preservation
|
||||||
|
fix(deps): update module github.com/containers/image/v5 to v5.31.1
|
||||||
|
Vendor in latest containers/(common, storage, image)
|
||||||
|
fix(deps): update module golang.org/x/term to v0.22.0
|
||||||
|
fix(deps): update module golang.org/x/sys to v0.22.0
|
||||||
|
fix(deps): update golang.org/x/exp digest to 7f521ea
|
||||||
|
fix(deps): update github.com/containers/luksy digest to a8846e2
|
||||||
|
imagebuildah.StageExecutor.Copy(): reject new flags for now
|
||||||
|
bump github.com/openshift/imagebuilder to v1.2.11
|
||||||
|
Rework parsing of --pull flags
|
||||||
|
fix(deps): update module github.com/containers/image/v5 to v5.31.1
|
||||||
|
imagebuildah.StageExecutor.prepare(): log the --platform flag
|
||||||
|
CI VMs: bump
|
||||||
|
buildah copy: preserve owner info with --from= a container or image
|
||||||
|
conformance tests: enable testing CompatSetParent
|
||||||
|
containerImageRef.NewImageSource(): move the FROM comment to first
|
||||||
|
commit: set "parent" for docker format only when requested
|
||||||
|
Update godoc for Builder.EnsureContainerPathAs
|
||||||
|
fix(deps): update module github.com/spf13/cobra to v1.8.1
|
||||||
|
fix(deps): update module github.com/containernetworking/cni to v1.2.0
|
||||||
|
fix(deps): update module github.com/opencontainers/runc to v1.1.13
|
||||||
|
Change default for podman build to --pull missing
|
||||||
|
fix(deps): update module github.com/containers/common to v0.59.1
|
||||||
|
Clarify definition of --pull options
|
||||||
|
buildah: fix a nil pointer reference on FreeBSD
|
||||||
|
Use /var/tmp for $TMPDIR for vfs conformance jobs
|
||||||
|
Cirrus: run `df` during job setup
|
||||||
|
conformance: use quay.io/libpod/centos:7 instead of centos:8
|
||||||
|
Stop setting "parent" in docker format
|
||||||
|
conformance: check if workdir trims path separator suffixes
|
||||||
|
push integration test: pass password to docker login via stdin
|
||||||
|
Re-enable the "copy with chown" conformance test
|
||||||
|
healthcheck: Add support for `--start-interval`
|
||||||
|
fix(deps): update module github.com/docker/docker to v26.1.4+incompatible
|
||||||
|
fix(deps): update module github.com/containerd/containerd to v1.7.18
|
||||||
|
tests: set _CONTAINERS_USERNS_CONFIGURED=done for libnetwork
|
||||||
|
Cross-build on Fedora
|
||||||
|
Drop copyStringSlice() and copyStringStringMap()
|
||||||
|
fix(deps): update module golang.org/x/crypto to v0.24.0
|
||||||
|
fix(deps): update module github.com/openshift/imagebuilder to v1.2.10
|
||||||
|
Provide an uptime_netbsd.go
|
||||||
|
Spell unix as "!windows"
|
||||||
|
Add netbsd to lists-of-OSes
|
||||||
|
fix(deps): update golang.org/x/exp digest to fd00a4e
|
||||||
|
[skip-ci] Packit: enable c10s downstream sync
|
||||||
|
CI VMs: bump, to debian with cgroups v2
|
||||||
|
Document when BlobDirectory is overridden
|
||||||
|
fix secret mounts for env vars when using chroot isolation
|
||||||
|
Change to take a types.ImageReference arg
|
||||||
|
imagebuildah: Support custom image reference lookup for cache push/pull
|
||||||
|
fix(deps): update module github.com/onsi/ginkgo/v2 to v2.19.0
|
||||||
|
Bump to v1.37.0-dev
|
||||||
|
CI: Clarify Debian use for conformance tests
|
||||||
|
|
||||||
## v1.36.0 (2024-05-23)
|
## v1.36.0 (2024-05-23)
|
||||||
|
|
||||||
build: be more selective about specifying the default OS
|
build: be more selective about specifying the default OS
|
||||||
|
|
|
@ -1,3 +1,74 @@
|
||||||
|
- Changelog for vv1.37.0 (2024-07-26)
|
||||||
|
* Bump c/storage, c/image, c/common for v1.37.0
|
||||||
|
* "build with basename resolving user arg" tests: correct ARG use
|
||||||
|
* bud-multiple-platform-no-run test: correct ARG use
|
||||||
|
* imagebuildah: always have default values for $TARGET... args ready
|
||||||
|
* bump github.com/openshift/imagebuilder to v1.2.14
|
||||||
|
* fix(deps): update module github.com/docker/docker to v27.1.1+incompatible
|
||||||
|
* fix(deps): update module github.com/cyphar/filepath-securejoin to v0.3.1
|
||||||
|
* fix(deps): update module github.com/docker/docker to v27.1.0+incompatible
|
||||||
|
* CI: use local registry, part 2 of 2
|
||||||
|
* CI: use local registry, part 1 of 2
|
||||||
|
* fix(deps): update module github.com/fsouza/go-dockerclient to v1.11.1
|
||||||
|
* Revert "fix(deps): update github.com/containers/image/v5 to v5.31.1"
|
||||||
|
* Replace libimage.LookupReferenceFunc with the manifests version
|
||||||
|
* conformance tests: enable testing CompatVolumes
|
||||||
|
* conformance tests: add a test that tries to chown a volume
|
||||||
|
* imagebuildah: make traditional volume handling not the default
|
||||||
|
* StageExecutor.prepare(): mark base image volumes for preservation
|
||||||
|
* fix(deps): update module github.com/containers/image/v5 to v5.31.1
|
||||||
|
* Vendor in latest containers/(common, storage, image)
|
||||||
|
* fix(deps): update module golang.org/x/term to v0.22.0
|
||||||
|
* fix(deps): update module golang.org/x/sys to v0.22.0
|
||||||
|
* fix(deps): update golang.org/x/exp digest to 7f521ea
|
||||||
|
* fix(deps): update github.com/containers/luksy digest to a8846e2
|
||||||
|
* imagebuildah.StageExecutor.Copy(): reject new flags for now
|
||||||
|
* bump github.com/openshift/imagebuilder to v1.2.11
|
||||||
|
* Rework parsing of --pull flags
|
||||||
|
* fix(deps): update module github.com/containers/image/v5 to v5.31.1
|
||||||
|
* imagebuildah.StageExecutor.prepare(): log the --platform flag
|
||||||
|
* CI VMs: bump
|
||||||
|
* buildah copy: preserve owner info with --from= a container or image
|
||||||
|
* conformance tests: enable testing CompatSetParent
|
||||||
|
* containerImageRef.NewImageSource(): move the FROM comment to first
|
||||||
|
* commit: set "parent" for docker format only when requested
|
||||||
|
* Update godoc for Builder.EnsureContainerPathAs
|
||||||
|
* fix(deps): update module github.com/spf13/cobra to v1.8.1
|
||||||
|
* fix(deps): update module github.com/containernetworking/cni to v1.2.0
|
||||||
|
* fix(deps): update module github.com/opencontainers/runc to v1.1.13
|
||||||
|
* Change default for podman build to --pull missing
|
||||||
|
* fix(deps): update module github.com/containers/common to v0.59.1
|
||||||
|
* Clarify definition of --pull options
|
||||||
|
* buildah: fix a nil pointer reference on FreeBSD
|
||||||
|
* Use /var/tmp for $TMPDIR for vfs conformance jobs
|
||||||
|
* Cirrus: run `df` during job setup
|
||||||
|
* conformance: use quay.io/libpod/centos:7 instead of centos:8
|
||||||
|
* Stop setting "parent" in docker format
|
||||||
|
* conformance: check if workdir trims path separator suffixes
|
||||||
|
* push integration test: pass password to docker login via stdin
|
||||||
|
* Re-enable the "copy with chown" conformance test
|
||||||
|
* healthcheck: Add support for `--start-interval`
|
||||||
|
* fix(deps): update module github.com/docker/docker to v26.1.4+incompatible
|
||||||
|
* fix(deps): update module github.com/containerd/containerd to v1.7.18
|
||||||
|
* tests: set _CONTAINERS_USERNS_CONFIGURED=done for libnetwork
|
||||||
|
* Cross-build on Fedora
|
||||||
|
* Drop copyStringSlice() and copyStringStringMap()
|
||||||
|
* fix(deps): update module golang.org/x/crypto to v0.24.0
|
||||||
|
* fix(deps): update module github.com/openshift/imagebuilder to v1.2.10
|
||||||
|
* Provide an uptime_netbsd.go
|
||||||
|
* Spell unix as "!windows"
|
||||||
|
* Add netbsd to lists-of-OSes
|
||||||
|
* fix(deps): update golang.org/x/exp digest to fd00a4e
|
||||||
|
* [skip-ci] Packit: enable c10s downstream sync
|
||||||
|
* CI VMs: bump, to debian with cgroups v2
|
||||||
|
* Document when BlobDirectory is overridden
|
||||||
|
* fix secret mounts for env vars when using chroot isolation
|
||||||
|
* Change to take a types.ImageReference arg
|
||||||
|
* imagebuildah: Support custom image reference lookup for cache push/pull
|
||||||
|
* fix(deps): update module github.com/onsi/ginkgo/v2 to v2.19.0
|
||||||
|
* Bump to v1.37.0-dev
|
||||||
|
* CI: Clarify Debian use for conformance tests
|
||||||
|
|
||||||
- Changelog for v1.36.0 (2024-05-23)
|
- Changelog for v1.36.0 (2024-05-23)
|
||||||
* build: be more selective about specifying the default OS
|
* build: be more selective about specifying the default OS
|
||||||
* Bump to c/common v0.59.0
|
* Bump to c/common v0.59.0
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/common/libimage"
|
"github.com/containers/common/libimage/manifests"
|
||||||
nettypes "github.com/containers/common/libnetwork/types"
|
nettypes "github.com/containers/common/libnetwork/types"
|
||||||
"github.com/containers/image/v5/docker/reference"
|
"github.com/containers/image/v5/docker/reference"
|
||||||
"github.com/containers/image/v5/types"
|
"github.com/containers/image/v5/types"
|
||||||
|
@ -349,25 +349,29 @@ type BuildOptions struct {
|
||||||
CDIConfigDir string
|
CDIConfigDir string
|
||||||
// CachePullSourceLookupReferenceFunc is an optional LookupReferenceFunc
|
// CachePullSourceLookupReferenceFunc is an optional LookupReferenceFunc
|
||||||
// used to look up source references for cache pulls.
|
// used to look up source references for cache pulls.
|
||||||
CachePullSourceLookupReferenceFunc libimage.LookupReferenceFunc
|
CachePullSourceLookupReferenceFunc manifests.LookupReferenceFunc
|
||||||
// CachePullDestinationLookupReferenceFunc is an optional generator
|
// CachePullDestinationLookupReferenceFunc is an optional generator
|
||||||
// function which provides a LookupReferenceFunc used to look up
|
// function which provides a LookupReferenceFunc used to look up
|
||||||
// destination references for cache pulls.
|
// destination references for cache pulls.
|
||||||
//
|
//
|
||||||
// BlobDirectory will be ignored for cache pulls if this option is set.
|
// BlobDirectory will be ignored for cache pulls if this option is set.
|
||||||
CachePullDestinationLookupReferenceFunc func(srcRef types.ImageReference) libimage.LookupReferenceFunc
|
CachePullDestinationLookupReferenceFunc func(srcRef types.ImageReference) manifests.LookupReferenceFunc
|
||||||
// CachePushSourceLookupReferenceFunc is an optional generator function
|
// CachePushSourceLookupReferenceFunc is an optional generator function
|
||||||
// which provides a LookupReferenceFunc used to look up source
|
// which provides a LookupReferenceFunc used to look up source
|
||||||
// references for cache pushes.
|
// references for cache pushes.
|
||||||
//
|
//
|
||||||
// BlobDirectory will be ignored for cache pushes if this option is set.
|
// BlobDirectory will be ignored for cache pushes if this option is set.
|
||||||
CachePushSourceLookupReferenceFunc func(dest types.ImageReference) libimage.LookupReferenceFunc
|
CachePushSourceLookupReferenceFunc func(dest types.ImageReference) manifests.LookupReferenceFunc
|
||||||
// CachePushDestinationLookupReferenceFunc is an optional
|
// CachePushDestinationLookupReferenceFunc is an optional
|
||||||
// LookupReferenceFunc used to look up destination references for cache
|
// LookupReferenceFunc used to look up destination references for cache
|
||||||
// pushes
|
// pushes
|
||||||
CachePushDestinationLookupReferenceFunc libimage.LookupReferenceFunc
|
CachePushDestinationLookupReferenceFunc manifests.LookupReferenceFunc
|
||||||
// CompatSetParent causes the "parent" field to be set in the image's
|
// CompatSetParent causes the "parent" field to be set in the image's
|
||||||
// configuration when committing in Docker format. Newer
|
// configuration when committing in Docker format. Newer
|
||||||
// BuildKit-based docker build doesn't set this field.
|
// BuildKit-based docker build doesn't set this field.
|
||||||
CompatSetParent types.OptionalBool
|
CompatSetParent types.OptionalBool
|
||||||
|
// CompatVolumes causes the contents of locations marked as volumes in
|
||||||
|
// base images or by a VOLUME instruction to be preserved during RUN
|
||||||
|
// instructions. Newer BuildKit-based docker build doesn't bother.
|
||||||
|
CompatVolumes types.OptionalBool
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ const (
|
||||||
// identify working containers.
|
// identify working containers.
|
||||||
Package = "buildah"
|
Package = "buildah"
|
||||||
// Version for the Package. Also used by .packit.sh for Packit builds.
|
// Version for the Package. Also used by .packit.sh for Packit builds.
|
||||||
Version = "1.37.0-dev"
|
Version = "1.37.0"
|
||||||
|
|
||||||
// DefaultRuntime if containers.conf fails.
|
// DefaultRuntime if containers.conf fails.
|
||||||
DefaultRuntime = "runc"
|
DefaultRuntime = "runc"
|
||||||
|
|
|
@ -38,6 +38,7 @@ import (
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/openshift/imagebuilder"
|
"github.com/openshift/imagebuilder"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
"golang.org/x/sync/semaphore"
|
"golang.org/x/sync/semaphore"
|
||||||
)
|
)
|
||||||
|
@ -204,6 +205,9 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B
|
||||||
if options.SystemContext == nil {
|
if options.SystemContext == nil {
|
||||||
options.SystemContext = &types.SystemContext{}
|
options.SystemContext = &types.SystemContext{}
|
||||||
}
|
}
|
||||||
|
if options.AdditionalBuildContexts == nil {
|
||||||
|
options.AdditionalBuildContexts = make(map[string]*define.AdditionalBuildContext)
|
||||||
|
}
|
||||||
|
|
||||||
if len(options.Platforms) == 0 {
|
if len(options.Platforms) == 0 {
|
||||||
options.Platforms = append(options.Platforms, struct{ OS, Arch, Variant string }{
|
options.Platforms = append(options.Platforms, struct{ OS, Arch, Variant string }{
|
||||||
|
@ -213,9 +217,6 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.AllPlatforms {
|
if options.AllPlatforms {
|
||||||
if options.AdditionalBuildContexts == nil {
|
|
||||||
options.AdditionalBuildContexts = make(map[string]*define.AdditionalBuildContext)
|
|
||||||
}
|
|
||||||
options.Platforms, err = platformsForBaseImages(ctx, logger, paths, files, options.From, options.Args, options.AdditionalBuildContexts, options.SystemContext)
|
options.Platforms, err = platformsForBaseImages(ctx, logger, paths, files, options.From, options.Args, options.AdditionalBuildContexts, options.SystemContext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
|
@ -251,11 +252,7 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B
|
||||||
logPrefix = "[" + platforms.Format(platformSpec) + "] "
|
logPrefix = "[" + platforms.Format(platformSpec) + "] "
|
||||||
}
|
}
|
||||||
// Deep copy args to prevent concurrent read/writes over Args.
|
// Deep copy args to prevent concurrent read/writes over Args.
|
||||||
argsCopy := make(map[string]string)
|
platformOptions.Args = maps.Clone(options.Args)
|
||||||
for key, value := range options.Args {
|
|
||||||
argsCopy[key] = value
|
|
||||||
}
|
|
||||||
platformOptions.Args = argsCopy
|
|
||||||
builds.Go(func() error {
|
builds.Go(func() error {
|
||||||
loggerPerPlatform := logger
|
loggerPerPlatform := logger
|
||||||
if platformOptions.LogFile != "" && platformOptions.LogSplitByPlatform {
|
if platformOptions.LogFile != "" && platformOptions.LogSplitByPlatform {
|
||||||
|
@ -395,36 +392,38 @@ func buildDockerfilesOnce(ctx context.Context, store storage.Store, logger *logr
|
||||||
// --platform was explicitly selected for this build
|
// --platform was explicitly selected for this build
|
||||||
// so set correct TARGETPLATFORM in args if it is not
|
// so set correct TARGETPLATFORM in args if it is not
|
||||||
// already selected by the user.
|
// already selected by the user.
|
||||||
|
builtinArgDefaults := make(map[string]string)
|
||||||
if options.SystemContext.OSChoice != "" && options.SystemContext.ArchitectureChoice != "" {
|
if options.SystemContext.OSChoice != "" && options.SystemContext.ArchitectureChoice != "" {
|
||||||
// os component from --platform string populates TARGETOS
|
// os component from --platform string populates TARGETOS
|
||||||
// buildkit parity: give priority to user's `--build-arg`
|
// buildkit parity: give priority to user's `--build-arg`
|
||||||
if _, ok := options.Args["TARGETOS"]; !ok {
|
builtinArgDefaults["TARGETOS"] = options.SystemContext.OSChoice
|
||||||
options.Args["TARGETOS"] = options.SystemContext.OSChoice
|
|
||||||
}
|
|
||||||
// arch component from --platform string populates TARGETARCH
|
// arch component from --platform string populates TARGETARCH
|
||||||
// buildkit parity: give priority to user's `--build-arg`
|
// buildkit parity: give priority to user's `--build-arg`
|
||||||
if _, ok := options.Args["TARGETARCH"]; !ok {
|
builtinArgDefaults["TARGETARCH"] = options.SystemContext.ArchitectureChoice
|
||||||
options.Args["TARGETARCH"] = options.SystemContext.ArchitectureChoice
|
|
||||||
}
|
|
||||||
// variant component from --platform string populates TARGETVARIANT
|
// variant component from --platform string populates TARGETVARIANT
|
||||||
// buildkit parity: give priority to user's `--build-arg`
|
// buildkit parity: give priority to user's `--build-arg`
|
||||||
if _, ok := options.Args["TARGETVARIANT"]; !ok {
|
builtinArgDefaults["TARGETVARIANT"] = options.SystemContext.VariantChoice
|
||||||
if options.SystemContext.VariantChoice != "" {
|
|
||||||
options.Args["TARGETVARIANT"] = options.SystemContext.VariantChoice
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// buildkit parity: give priority to user's `--build-arg`
|
// buildkit parity: give priority to user's `--build-arg`
|
||||||
if _, ok := options.Args["TARGETPLATFORM"]; !ok {
|
// buildkit parity: TARGETPLATFORM should be always created
|
||||||
// buildkit parity: TARGETPLATFORM should be always created
|
// from SystemContext and not `TARGETOS` and `TARGETARCH` because
|
||||||
// from SystemContext and not `TARGETOS` and `TARGETARCH` because
|
// users can always override values of `TARGETOS` and `TARGETARCH`
|
||||||
// users can always override values of `TARGETOS` and `TARGETARCH`
|
// but `TARGETPLATFORM` should be set independent of those values.
|
||||||
// but `TARGETPLATFORM` should be set independent of those values.
|
builtinArgDefaults["TARGETPLATFORM"] = builtinArgDefaults["TARGETOS"] + "/" + builtinArgDefaults["TARGETARCH"]
|
||||||
options.Args["TARGETPLATFORM"] = options.SystemContext.OSChoice + "/" + options.SystemContext.ArchitectureChoice
|
if options.SystemContext.VariantChoice != "" {
|
||||||
if options.SystemContext.VariantChoice != "" {
|
builtinArgDefaults["TARGETPLATFORM"] += "/" + options.SystemContext.VariantChoice
|
||||||
options.Args["TARGETPLATFORM"] = options.Args["TARGETPLATFORM"] + "/" + options.SystemContext.VariantChoice
|
}
|
||||||
}
|
} else {
|
||||||
|
// fill them in using values for the default platform
|
||||||
|
defaultPlatform := platforms.DefaultSpec()
|
||||||
|
builtinArgDefaults["TARGETOS"] = defaultPlatform.OS
|
||||||
|
builtinArgDefaults["TARGETVARIANT"] = defaultPlatform.Variant
|
||||||
|
builtinArgDefaults["TARGETARCH"] = defaultPlatform.Architecture
|
||||||
|
builtinArgDefaults["TARGETPLATFORM"] = defaultPlatform.OS + "/" + defaultPlatform.Architecture
|
||||||
|
if defaultPlatform.Variant != "" {
|
||||||
|
builtinArgDefaults["TARGETPLATFORM"] += "/" + defaultPlatform.Variant
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
delete(options.Args, "TARGETPLATFORM")
|
||||||
|
|
||||||
for i, d := range dockerfilecontents[1:] {
|
for i, d := range dockerfilecontents[1:] {
|
||||||
additionalNode, err := imagebuilder.ParseDockerfile(bytes.NewReader(d))
|
additionalNode, err := imagebuilder.ParseDockerfile(bytes.NewReader(d))
|
||||||
|
@ -440,6 +439,9 @@ func buildDockerfilesOnce(ctx context.Context, store storage.Store, logger *logr
|
||||||
return "", nil, fmt.Errorf("creating build executor: %w", err)
|
return "", nil, fmt.Errorf("creating build executor: %w", err)
|
||||||
}
|
}
|
||||||
b := imagebuilder.NewBuilder(options.Args)
|
b := imagebuilder.NewBuilder(options.Args)
|
||||||
|
for k, v := range builtinArgDefaults {
|
||||||
|
b.BuiltinArgDefaults[k] = v
|
||||||
|
}
|
||||||
defaultContainerConfig, err := config.Default()
|
defaultContainerConfig, err := config.Default()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, fmt.Errorf("failed to get container config: %w", err)
|
return "", nil, fmt.Errorf("failed to get container config: %w", err)
|
||||||
|
|
|
@ -161,6 +161,7 @@ type Executor struct {
|
||||||
sbomScanOptions []define.SBOMScanOptions
|
sbomScanOptions []define.SBOMScanOptions
|
||||||
cdiConfigDir string
|
cdiConfigDir string
|
||||||
compatSetParent types.OptionalBool
|
compatSetParent types.OptionalBool
|
||||||
|
compatVolumes types.OptionalBool
|
||||||
}
|
}
|
||||||
|
|
||||||
type imageTypeAndHistoryAndDiffIDs struct {
|
type imageTypeAndHistoryAndDiffIDs struct {
|
||||||
|
@ -318,6 +319,7 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o
|
||||||
sbomScanOptions: options.SBOMScanOptions,
|
sbomScanOptions: options.SBOMScanOptions,
|
||||||
cdiConfigDir: options.CDIConfigDir,
|
cdiConfigDir: options.CDIConfigDir,
|
||||||
compatSetParent: options.CompatSetParent,
|
compatSetParent: options.CompatSetParent,
|
||||||
|
compatVolumes: options.CompatVolumes,
|
||||||
}
|
}
|
||||||
if exec.err == nil {
|
if exec.err == nil {
|
||||||
exec.err = os.Stderr
|
exec.err = os.Stderr
|
||||||
|
@ -771,18 +773,19 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
|
||||||
base = child.Next.Value
|
base = child.Next.Value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
builtinArgs := argsMapToSlice(stage.Builder.BuiltinArgDefaults)
|
||||||
headingArgs := argsMapToSlice(stage.Builder.HeadingArgs)
|
headingArgs := argsMapToSlice(stage.Builder.HeadingArgs)
|
||||||
userArgs := argsMapToSlice(stage.Builder.Args)
|
userArgs := argsMapToSlice(stage.Builder.Args)
|
||||||
// append heading args so if --build-arg key=value is not
|
// append heading args so if --build-arg key=value is not
|
||||||
// specified but default value is set in Containerfile
|
// specified but default value is set in Containerfile
|
||||||
// via `ARG key=value` so default value can be used.
|
// via `ARG key=value` so default value can be used.
|
||||||
userArgs = append(headingArgs, userArgs...)
|
userArgs = append(builtinArgs, append(userArgs, headingArgs...)...)
|
||||||
baseWithArg, err := imagebuilder.ProcessWord(base, userArgs)
|
baseWithArg, err := imagebuilder.ProcessWord(base, userArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, fmt.Errorf("while replacing arg variables with values for format %q: %w", base, err)
|
return "", nil, fmt.Errorf("while replacing arg variables with values for format %q: %w", base, err)
|
||||||
}
|
}
|
||||||
b.baseMap[baseWithArg] = struct{}{}
|
b.baseMap[baseWithArg] = struct{}{}
|
||||||
logrus.Debugf("base for stage %d: %q", stageIndex, base)
|
logrus.Debugf("base for stage %d: %q resolves to %q", stageIndex, base, baseWithArg)
|
||||||
// Check if selected base is not an additional
|
// Check if selected base is not an additional
|
||||||
// build context and if base is a valid stage
|
// build context and if base is a valid stage
|
||||||
// add it to current stage's dependency tree.
|
// add it to current stage's dependency tree.
|
||||||
|
@ -809,16 +812,18 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
|
||||||
// if following ADD or COPY needs any other
|
// if following ADD or COPY needs any other
|
||||||
// stage.
|
// stage.
|
||||||
stageName := rootfs
|
stageName := rootfs
|
||||||
|
builtinArgs := argsMapToSlice(stage.Builder.BuiltinArgDefaults)
|
||||||
headingArgs := argsMapToSlice(stage.Builder.HeadingArgs)
|
headingArgs := argsMapToSlice(stage.Builder.HeadingArgs)
|
||||||
userArgs := argsMapToSlice(stage.Builder.Args)
|
userArgs := argsMapToSlice(stage.Builder.Args)
|
||||||
// append heading args so if --build-arg key=value is not
|
// append heading args so if --build-arg key=value is not
|
||||||
// specified but default value is set in Containerfile
|
// specified but default value is set in Containerfile
|
||||||
// via `ARG key=value` so default value can be used.
|
// via `ARG key=value` so default value can be used.
|
||||||
userArgs = append(headingArgs, userArgs...)
|
userArgs = append(builtinArgs, append(userArgs, headingArgs...)...)
|
||||||
baseWithArg, err := imagebuilder.ProcessWord(stageName, userArgs)
|
baseWithArg, err := imagebuilder.ProcessWord(stageName, userArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, fmt.Errorf("while replacing arg variables with values for format %q: %w", stageName, err)
|
return "", nil, fmt.Errorf("while replacing arg variables with values for format %q: %w", stageName, err)
|
||||||
}
|
}
|
||||||
|
logrus.Debugf("stage %d name: %q resolves to %q", stageIndex, stageName, baseWithArg)
|
||||||
stageName = baseWithArg
|
stageName = baseWithArg
|
||||||
// If --from=<index> convert index to name
|
// If --from=<index> convert index to name
|
||||||
if index, err := strconv.Atoi(stageName); err == nil {
|
if index, err := strconv.Atoi(stageName); err == nil {
|
||||||
|
|
|
@ -44,6 +44,7 @@ import (
|
||||||
"github.com/openshift/imagebuilder/dockerfile/command"
|
"github.com/openshift/imagebuilder/dockerfile/command"
|
||||||
"github.com/openshift/imagebuilder/dockerfile/parser"
|
"github.com/openshift/imagebuilder/dockerfile/parser"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StageExecutor bundles up what we need to know when executing one stage of a
|
// StageExecutor bundles up what we need to know when executing one stage of a
|
||||||
|
@ -80,42 +81,22 @@ type StageExecutor struct {
|
||||||
// Preserve informs the stage executor that from this point on, it needs to
|
// Preserve informs the stage executor that from this point on, it needs to
|
||||||
// ensure that only COPY and ADD instructions can modify the contents of this
|
// ensure that only COPY and ADD instructions can modify the contents of this
|
||||||
// directory or anything below it.
|
// directory or anything below it.
|
||||||
// The StageExecutor handles this by caching the contents of directories which
|
// When CompatVolumes is enabled, the StageExecutor handles this by caching the
|
||||||
// have been marked this way before executing a RUN instruction, invalidating
|
// contents of directories which have been marked this way before executing a
|
||||||
// that cache when an ADD or COPY instruction sets any location under the
|
// RUN instruction, invalidating that cache when an ADD or COPY instruction
|
||||||
// directory as the destination, and using the cache to reset the contents of
|
// sets any location under the directory as the destination, and using the
|
||||||
// the directory tree after processing each RUN instruction.
|
// cache to reset the contents of the directory tree after processing each RUN
|
||||||
|
// instruction.
|
||||||
// It would be simpler if we could just mark the directory as a read-only bind
|
// It would be simpler if we could just mark the directory as a read-only bind
|
||||||
// mount of itself during Run(), but the directory is expected to be remain
|
// mount of itself during Run(), but the directory is expected to be remain
|
||||||
// writeable while the RUN instruction is being handled, even if any changes
|
// writeable while the RUN instruction is being handled, even if any changes
|
||||||
// made within the directory are ultimately discarded.
|
// made within the directory are ultimately discarded.
|
||||||
func (s *StageExecutor) Preserve(path string) error {
|
func (s *StageExecutor) Preserve(path string) error {
|
||||||
logrus.Debugf("PRESERVE %q", path)
|
logrus.Debugf("PRESERVE %q in %q", path, s.builder.ContainerID)
|
||||||
if s.volumes.Covers(path) {
|
|
||||||
// This path is already a subdirectory of a volume path that
|
|
||||||
// we're already preserving, so there's nothing new to be done
|
|
||||||
// except ensure that it exists.
|
|
||||||
createdDirPerms := os.FileMode(0755)
|
|
||||||
if err := copier.Mkdir(s.mountPoint, filepath.Join(s.mountPoint, path), copier.MkdirOptions{ChmodNew: &createdDirPerms}); err != nil {
|
|
||||||
return fmt.Errorf("ensuring volume path exists: %w", err)
|
|
||||||
}
|
|
||||||
if err := s.volumeCacheInvalidate(path); err != nil {
|
|
||||||
return fmt.Errorf("ensuring volume path %q is preserved: %w", filepath.Join(s.mountPoint, path), err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// Figure out where the cache for this volume would be stored.
|
|
||||||
s.preserved++
|
|
||||||
cacheDir, err := s.executor.store.ContainerDirectory(s.builder.ContainerID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to locate temporary directory for container")
|
|
||||||
}
|
|
||||||
cacheFile := filepath.Join(cacheDir, fmt.Sprintf("volume%d.tar", s.preserved))
|
|
||||||
// Save info about the top level of the location that we'll be archiving.
|
|
||||||
var archivedPath string
|
|
||||||
|
|
||||||
// Try and resolve the symlink (if one exists)
|
// Try and resolve the symlink (if one exists)
|
||||||
// Set archivedPath and path based on whether a symlink is found or not
|
// Set archivedPath and path based on whether a symlink is found or not
|
||||||
|
var archivedPath string
|
||||||
if evaluated, err := copier.Eval(s.mountPoint, filepath.Join(s.mountPoint, path), copier.EvalOptions{}); err == nil {
|
if evaluated, err := copier.Eval(s.mountPoint, filepath.Join(s.mountPoint, path), copier.EvalOptions{}); err == nil {
|
||||||
symLink, err := filepath.Rel(s.mountPoint, evaluated)
|
symLink, err := filepath.Rel(s.mountPoint, evaluated)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -130,9 +111,55 @@ func (s *StageExecutor) Preserve(path string) error {
|
||||||
return fmt.Errorf("evaluating path %q: %w", path, err)
|
return fmt.Errorf("evaluating path %q: %w", path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const createdDirPerms = os.FileMode(0o755)
|
||||||
|
if s.executor.compatVolumes != types.OptionalBoolTrue {
|
||||||
|
logrus.Debugf("ensuring volume path %q exists", path)
|
||||||
|
createdDirPerms := createdDirPerms
|
||||||
|
if err := copier.Mkdir(s.mountPoint, archivedPath, copier.MkdirOptions{ChmodNew: &createdDirPerms}); err != nil {
|
||||||
|
return fmt.Errorf("ensuring volume path exists: %w", err)
|
||||||
|
}
|
||||||
|
logrus.Debugf("not doing volume save-and-restore of %q in %q", path, s.builder.ContainerID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.volumes.Covers(path) {
|
||||||
|
// This path is a subdirectory of a volume path that we're
|
||||||
|
// already preserving, so there's nothing new to be done except
|
||||||
|
// ensure that it exists.
|
||||||
|
st, err := os.Stat(archivedPath)
|
||||||
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
|
// We do have to create it. That means it's not in any
|
||||||
|
// cached copy of the path that covers it, so we have
|
||||||
|
// to invalidate such cached copy.
|
||||||
|
logrus.Debugf("have to create volume %q", path)
|
||||||
|
createdDirPerms := createdDirPerms
|
||||||
|
if err := copier.Mkdir(s.mountPoint, filepath.Join(s.mountPoint, path), copier.MkdirOptions{ChmodNew: &createdDirPerms}); err != nil {
|
||||||
|
return fmt.Errorf("ensuring volume path exists: %w", err)
|
||||||
|
}
|
||||||
|
if err := s.volumeCacheInvalidate(path); err != nil {
|
||||||
|
return fmt.Errorf("ensuring volume path %q is preserved: %w", filepath.Join(s.mountPoint, path), err)
|
||||||
|
}
|
||||||
|
if st, err = os.Stat(archivedPath); err != nil {
|
||||||
|
return fmt.Errorf("checking on just-created volume path: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.volumeCacheInfo[path] = st
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Figure out where the cache for this volume would be stored.
|
||||||
|
s.preserved++
|
||||||
|
cacheDir, err := s.executor.store.ContainerDirectory(s.builder.ContainerID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to locate temporary directory for container")
|
||||||
|
}
|
||||||
|
cacheFile := filepath.Join(cacheDir, fmt.Sprintf("volume%d.tar", s.preserved))
|
||||||
|
|
||||||
|
// Save info about the top level of the location that we'll be archiving.
|
||||||
st, err := os.Stat(archivedPath)
|
st, err := os.Stat(archivedPath)
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
createdDirPerms := os.FileMode(0755)
|
logrus.Debugf("have to create volume %q", path)
|
||||||
|
createdDirPerms := os.FileMode(0o755)
|
||||||
if err = copier.Mkdir(s.mountPoint, archivedPath, copier.MkdirOptions{ChmodNew: &createdDirPerms}); err != nil {
|
if err = copier.Mkdir(s.mountPoint, archivedPath, copier.MkdirOptions{ChmodNew: &createdDirPerms}); err != nil {
|
||||||
return fmt.Errorf("ensuring volume path exists: %w", err)
|
return fmt.Errorf("ensuring volume path exists: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -145,11 +172,13 @@ func (s *StageExecutor) Preserve(path string) error {
|
||||||
s.volumeCacheInfo[path] = st
|
s.volumeCacheInfo[path] = st
|
||||||
if !s.volumes.Add(path) {
|
if !s.volumes.Add(path) {
|
||||||
// This path is not a subdirectory of a volume path that we're
|
// This path is not a subdirectory of a volume path that we're
|
||||||
// already preserving, so adding it to the list should work.
|
// already preserving, so adding it to the list should have
|
||||||
|
// worked.
|
||||||
return fmt.Errorf("adding %q to the volume cache", path)
|
return fmt.Errorf("adding %q to the volume cache", path)
|
||||||
}
|
}
|
||||||
s.volumeCache[path] = cacheFile
|
s.volumeCache[path] = cacheFile
|
||||||
// Now prune cache files for volumes that are now supplanted by this one.
|
|
||||||
|
// Now prune cache files for volumes that are newly supplanted by this one.
|
||||||
removed := []string{}
|
removed := []string{}
|
||||||
for cachedPath := range s.volumeCache {
|
for cachedPath := range s.volumeCache {
|
||||||
// Walk our list of cached volumes, and check that they're
|
// Walk our list of cached volumes, and check that they're
|
||||||
|
@ -168,6 +197,7 @@ func (s *StageExecutor) Preserve(path string) error {
|
||||||
removed = append(removed, cachedPath)
|
removed = append(removed, cachedPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actually remove the caches that we decided to remove.
|
// Actually remove the caches that we decided to remove.
|
||||||
for _, cachedPath := range removed {
|
for _, cachedPath := range removed {
|
||||||
archivedPath := filepath.Join(s.mountPoint, cachedPath)
|
archivedPath := filepath.Join(s.mountPoint, cachedPath)
|
||||||
|
@ -274,7 +304,7 @@ func (s *StageExecutor) volumeCacheRestoreVFS() (err error) {
|
||||||
if err := copier.Remove(s.mountPoint, archivedPath, copier.RemoveOptions{All: true}); err != nil {
|
if err := copier.Remove(s.mountPoint, archivedPath, copier.RemoveOptions{All: true}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
createdDirPerms := os.FileMode(0755)
|
createdDirPerms := os.FileMode(0o755)
|
||||||
if err := copier.Mkdir(s.mountPoint, archivedPath, copier.MkdirOptions{ChmodNew: &createdDirPerms}); err != nil {
|
if err := copier.Mkdir(s.mountPoint, archivedPath, copier.MkdirOptions{ChmodNew: &createdDirPerms}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -772,32 +802,33 @@ func (s *StageExecutor) Run(run imagebuilder.Run, config docker.Config) error {
|
||||||
}
|
}
|
||||||
namespaceOptions := append([]define.NamespaceOption{}, s.executor.namespaceOptions...)
|
namespaceOptions := append([]define.NamespaceOption{}, s.executor.namespaceOptions...)
|
||||||
options := buildah.RunOptions{
|
options := buildah.RunOptions{
|
||||||
Args: s.executor.runtimeArgs,
|
Args: s.executor.runtimeArgs,
|
||||||
Cmd: config.Cmd,
|
Cmd: config.Cmd,
|
||||||
ContextDir: s.executor.contextDir,
|
ContextDir: s.executor.contextDir,
|
||||||
ConfigureNetwork: s.executor.configureNetwork,
|
ConfigureNetwork: s.executor.configureNetwork,
|
||||||
Entrypoint: config.Entrypoint,
|
Entrypoint: config.Entrypoint,
|
||||||
Env: config.Env,
|
Env: config.Env,
|
||||||
Hostname: config.Hostname,
|
Hostname: config.Hostname,
|
||||||
Logger: s.executor.logger,
|
Logger: s.executor.logger,
|
||||||
Mounts: s.executor.transientMounts,
|
Mounts: slices.Clone(s.executor.transientMounts),
|
||||||
NamespaceOptions: namespaceOptions,
|
NamespaceOptions: namespaceOptions,
|
||||||
NoHostname: s.executor.noHostname,
|
NoHostname: s.executor.noHostname,
|
||||||
NoHosts: s.executor.noHosts,
|
NoHosts: s.executor.noHosts,
|
||||||
NoPivot: os.Getenv("BUILDAH_NOPIVOT") != "",
|
NoPivot: os.Getenv("BUILDAH_NOPIVOT") != "",
|
||||||
Quiet: s.executor.quiet,
|
Quiet: s.executor.quiet,
|
||||||
RunMounts: run.Mounts,
|
CompatBuiltinVolumes: types.OptionalBoolFalse,
|
||||||
Runtime: s.executor.runtime,
|
RunMounts: run.Mounts,
|
||||||
Secrets: s.executor.secrets,
|
Runtime: s.executor.runtime,
|
||||||
SSHSources: s.executor.sshsources,
|
Secrets: s.executor.secrets,
|
||||||
StageMountPoints: stageMountPoints,
|
SSHSources: s.executor.sshsources,
|
||||||
Stderr: s.executor.err,
|
StageMountPoints: stageMountPoints,
|
||||||
Stdin: stdin,
|
Stderr: s.executor.err,
|
||||||
Stdout: s.executor.out,
|
Stdin: stdin,
|
||||||
SystemContext: s.executor.systemContext,
|
Stdout: s.executor.out,
|
||||||
Terminal: buildah.WithoutTerminal,
|
SystemContext: s.executor.systemContext,
|
||||||
User: config.User,
|
Terminal: buildah.WithoutTerminal,
|
||||||
WorkingDir: config.WorkingDir,
|
User: config.User,
|
||||||
|
WorkingDir: config.WorkingDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Honor `RUN --network=<>`.
|
// Honor `RUN --network=<>`.
|
||||||
|
@ -824,20 +855,40 @@ func (s *StageExecutor) Run(run imagebuilder.Run, config docker.Config) error {
|
||||||
args = append([]string{"/bin/sh", "-c"}, args...)
|
args = append([]string{"/bin/sh", "-c"}, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mounts, err := s.volumeCacheSave()
|
|
||||||
if err != nil {
|
if s.executor.compatVolumes == types.OptionalBoolTrue {
|
||||||
return err
|
// Only bother with saving/restoring the contents of volumes if
|
||||||
|
// we've been specifically asked to.
|
||||||
|
mounts, err := s.volumeCacheSave()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
options.Mounts = append(options.Mounts, mounts...)
|
||||||
}
|
}
|
||||||
options.Mounts = append(options.Mounts, mounts...)
|
|
||||||
|
// The list of built-in volumes isn't passed in via RunOptions, so make
|
||||||
|
// sure the builder's list of built-in volumes includes anything that
|
||||||
|
// the configuration thinks is a built-in volume.
|
||||||
|
s.builder.ClearVolumes()
|
||||||
|
for v := range config.Volumes {
|
||||||
|
s.builder.AddVolume(v)
|
||||||
|
}
|
||||||
|
|
||||||
if len(heredocMounts) > 0 {
|
if len(heredocMounts) > 0 {
|
||||||
options.Mounts = append(options.Mounts, heredocMounts...)
|
options.Mounts = append(options.Mounts, heredocMounts...)
|
||||||
}
|
}
|
||||||
err = s.builder.Run(args, options)
|
err = s.builder.Run(args, options)
|
||||||
if err2 := s.volumeCacheRestore(); err2 != nil {
|
|
||||||
if err == nil {
|
if s.executor.compatVolumes == types.OptionalBoolTrue {
|
||||||
return err2
|
// Only bother with saving/restoring the contents of volumes if
|
||||||
|
// we've been specifically asked to.
|
||||||
|
if err2 := s.volumeCacheRestore(); err2 != nil {
|
||||||
|
if err == nil {
|
||||||
|
return err2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1027,6 +1078,14 @@ func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBCo
|
||||||
// Make this our "current" working container.
|
// Make this our "current" working container.
|
||||||
s.mountPoint = mountPoint
|
s.mountPoint = mountPoint
|
||||||
s.builder = builder
|
s.builder = builder
|
||||||
|
// Now that the rootfs is mounted, set up handling of volumes from the base image.
|
||||||
|
s.volumeCache = make(map[string]string)
|
||||||
|
s.volumeCacheInfo = make(map[string]os.FileInfo)
|
||||||
|
for _, v := range builder.Volumes() {
|
||||||
|
if err := s.Preserve(v); err != nil {
|
||||||
|
return nil, fmt.Errorf("marking base image volume %q for preservation: %w", v, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
logrus.Debugln("Container ID:", builder.ContainerID)
|
logrus.Debugln("Container ID:", builder.ContainerID)
|
||||||
return builder, nil
|
return builder, nil
|
||||||
|
|
|
@ -361,6 +361,7 @@ func GenBuildOptions(c *cobra.Command, inputArgs []string, iopts BuildOptions) (
|
||||||
CDIConfigDir: iopts.CDIConfigDir,
|
CDIConfigDir: iopts.CDIConfigDir,
|
||||||
CNIConfigDir: iopts.CNIConfigDir,
|
CNIConfigDir: iopts.CNIConfigDir,
|
||||||
CNIPluginPath: iopts.CNIPlugInPath,
|
CNIPluginPath: iopts.CNIPlugInPath,
|
||||||
|
CompatVolumes: types.NewOptionalBool(iopts.CompatVolumes),
|
||||||
ConfidentialWorkload: confidentialWorkloadOptions,
|
ConfidentialWorkload: confidentialWorkloadOptions,
|
||||||
CPPFlags: iopts.CPPFlags,
|
CPPFlags: iopts.CPPFlags,
|
||||||
CommonBuildOpts: commonOpts,
|
CommonBuildOpts: commonOpts,
|
||||||
|
|
|
@ -119,6 +119,7 @@ type BudResults struct {
|
||||||
OSVersion string
|
OSVersion string
|
||||||
CWOptions string
|
CWOptions string
|
||||||
SBOMOptions []string
|
SBOMOptions []string
|
||||||
|
CompatVolumes bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromAndBugResults represents the results for common flags
|
// FromAndBugResults represents the results for common flags
|
||||||
|
@ -228,6 +229,7 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
|
||||||
fs.StringVar(&flags.CacheTTL, "cache-ttl", "", "only consider cache images under specified duration.")
|
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.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.BoolVar(&flags.Compress, "compress", false, "this is a legacy option, which has no effect on the image")
|
||||||
|
fs.BoolVar(&flags.CompatVolumes, "compat-volumes", false, "preserve the contents of VOLUMEs during RUN instructions")
|
||||||
fs.StringArrayVar(&flags.CPPFlags, "cpp-flag", []string{}, "set additional flag to pass to C preprocessor (cpp)")
|
fs.StringArrayVar(&flags.CPPFlags, "cpp-flag", []string{}, "set additional flag to pass to C preprocessor (cpp)")
|
||||||
fs.StringVar(&flags.Creds, "creds", "", "use `[username[:password]]` for accessing the registry")
|
fs.StringVar(&flags.Creds, "creds", "", "use `[username[:password]]` for accessing the registry")
|
||||||
fs.StringVarP(&flags.CWOptions, "cw", "", "", "confidential workload `options`")
|
fs.StringVarP(&flags.CWOptions, "cw", "", "", "confidential workload `options`")
|
||||||
|
|
|
@ -170,6 +170,12 @@ type RunOptions struct {
|
||||||
// CDIConfigDir is the location of CDI configuration files, if the files in
|
// CDIConfigDir is the location of CDI configuration files, if the files in
|
||||||
// the default configuration locations shouldn't be used.
|
// the default configuration locations shouldn't be used.
|
||||||
CDIConfigDir string
|
CDIConfigDir string
|
||||||
|
// CompatBuiltinVolumes causes the contents of locations marked as
|
||||||
|
// volumes in the container's configuration to be set up as bind mounts to
|
||||||
|
// directories which are not in the container's rootfs, hiding changes
|
||||||
|
// made to contents of those changes when the container is subsequently
|
||||||
|
// committed.
|
||||||
|
CompatBuiltinVolumes types.OptionalBool
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunMountArtifacts are the artifacts created when using a run mount.
|
// RunMountArtifacts are the artifacts created when using a run mount.
|
||||||
|
|
|
@ -39,6 +39,7 @@ import (
|
||||||
netUtil "github.com/containers/common/libnetwork/util"
|
netUtil "github.com/containers/common/libnetwork/util"
|
||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
"github.com/containers/common/pkg/subscriptions"
|
"github.com/containers/common/pkg/subscriptions"
|
||||||
|
"github.com/containers/image/v5/types"
|
||||||
imageTypes "github.com/containers/image/v5/types"
|
imageTypes "github.com/containers/image/v5/types"
|
||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
"github.com/containers/storage/pkg/fileutils"
|
"github.com/containers/storage/pkg/fileutils"
|
||||||
|
@ -1304,7 +1305,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this succeeds, the caller must call cleanupMounts().
|
// If this succeeds, the caller must call cleanupMounts().
|
||||||
func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath string, optionMounts []specs.Mount, bindFiles map[string]string, builtinVolumes, volumeMounts []string, runFileMounts []string, runMountInfo runMountInfo) (*runMountArtifacts, error) {
|
func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath string, optionMounts []specs.Mount, bindFiles map[string]string, builtinVolumes []string, compatBuiltinVolumes types.OptionalBool, volumeMounts []string, runFileMounts []string, runMountInfo runMountInfo) (*runMountArtifacts, error) {
|
||||||
// Start building a new list of mounts.
|
// Start building a new list of mounts.
|
||||||
var mounts []specs.Mount
|
var mounts []specs.Mount
|
||||||
haveMount := func(destination string) bool {
|
haveMount := func(destination string) bool {
|
||||||
|
@ -1374,7 +1375,7 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st
|
||||||
}()
|
}()
|
||||||
// Add temporary copies of the contents of volume locations at the
|
// Add temporary copies of the contents of volume locations at the
|
||||||
// volume locations, unless we already have something there.
|
// volume locations, unless we already have something there.
|
||||||
builtins, err := runSetupBuiltinVolumes(b.MountLabel, mountPoint, cdir, builtinVolumes, int(rootUID), int(rootGID))
|
builtins, err := runSetupBuiltinVolumes(b.MountLabel, mountPoint, cdir, builtinVolumes, compatBuiltinVolumes, int(rootUID), int(rootGID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -1411,17 +1412,31 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st
|
||||||
return mountArtifacts, nil
|
return mountArtifacts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runSetupBuiltinVolumes(mountLabel, mountPoint, containerDir string, builtinVolumes []string, rootUID, rootGID int) ([]specs.Mount, error) {
|
func runSetupBuiltinVolumes(mountLabel, mountPoint, containerDir string, builtinVolumes []string, compatBuiltinVolumes types.OptionalBool, rootUID, rootGID int) ([]specs.Mount, error) {
|
||||||
var mounts []specs.Mount
|
var mounts []specs.Mount
|
||||||
hostOwner := idtools.IDPair{UID: rootUID, GID: rootGID}
|
hostOwner := idtools.IDPair{UID: rootUID, GID: rootGID}
|
||||||
// Add temporary copies of the contents of volume locations at the
|
// Add temporary copies of the contents of volume locations at the
|
||||||
// volume locations, unless we already have something there.
|
// volume locations, unless we already have something there.
|
||||||
for _, volume := range builtinVolumes {
|
for _, volume := range builtinVolumes {
|
||||||
volumePath := filepath.Join(containerDir, "buildah-volumes", digest.Canonical.FromString(volume).Hex())
|
// Make sure the volume exists in the rootfs.
|
||||||
initializeVolume := false
|
createDirPerms := os.FileMode(0o755)
|
||||||
|
err := copier.Mkdir(mountPoint, filepath.Join(mountPoint, volume), copier.MkdirOptions{
|
||||||
|
ChownNew: &hostOwner,
|
||||||
|
ChmodNew: &createDirPerms,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("ensuring volume path %q: %w", filepath.Join(mountPoint, volume), err)
|
||||||
|
}
|
||||||
|
// If we're not being asked to bind mount anonymous volumes
|
||||||
|
// onto the volume paths, we're done here.
|
||||||
|
if compatBuiltinVolumes != types.OptionalBoolTrue {
|
||||||
|
continue
|
||||||
|
}
|
||||||
// If we need to, create the directory that we'll use to hold
|
// If we need to, create the directory that we'll use to hold
|
||||||
// the volume contents. If we do need to create it, then we'll
|
// the volume contents. If we do need to create it, then we'll
|
||||||
// need to populate it, too, so make a note of that.
|
// need to populate it, too, so make a note of that.
|
||||||
|
volumePath := filepath.Join(containerDir, "buildah-volumes", digest.Canonical.FromString(volume).Hex())
|
||||||
|
initializeVolume := false
|
||||||
if err := fileutils.Exists(volumePath); err != nil {
|
if err := fileutils.Exists(volumePath); err != nil {
|
||||||
if !errors.Is(err, fs.ErrNotExist) {
|
if !errors.Is(err, fs.ErrNotExist) {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1435,15 +1450,7 @@ func runSetupBuiltinVolumes(mountLabel, mountPoint, containerDir string, builtin
|
||||||
}
|
}
|
||||||
initializeVolume = true
|
initializeVolume = true
|
||||||
}
|
}
|
||||||
// Make sure the volume exists in the rootfs and read its attributes.
|
// Read the attributes of the volume's location in the rootfs.
|
||||||
createDirPerms := os.FileMode(0755)
|
|
||||||
err := copier.Mkdir(mountPoint, filepath.Join(mountPoint, volume), copier.MkdirOptions{
|
|
||||||
ChownNew: &hostOwner,
|
|
||||||
ChmodNew: &createDirPerms,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("ensuring volume path %q: %w", filepath.Join(mountPoint, volume), err)
|
|
||||||
}
|
|
||||||
srcPath, err := copier.Eval(mountPoint, filepath.Join(mountPoint, volume), copier.EvalOptions{})
|
srcPath, err := copier.Eval(mountPoint, filepath.Join(mountPoint, volume), copier.EvalOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("evaluating path %q: %w", srcPath, err)
|
return nil, fmt.Errorf("evaluating path %q: %w", srcPath, err)
|
||||||
|
|
|
@ -259,7 +259,7 @@ func (b *Builder) Run(command []string, options RunOptions) error {
|
||||||
SystemContext: options.SystemContext,
|
SystemContext: options.SystemContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
runArtifacts, err := b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, volumes, b.CommonBuildOpts.Volumes, options.RunMounts, runMountInfo)
|
runArtifacts, err := b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, volumes, options.CompatBuiltinVolumes, b.CommonBuildOpts.Volumes, options.RunMounts, runMountInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("resolving mountpoints for container %q: %w", b.ContainerID, err)
|
return fmt.Errorf("resolving mountpoints for container %q: %w", b.ContainerID, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -475,7 +475,7 @@ rootless=%d
|
||||||
SystemContext: options.SystemContext,
|
SystemContext: options.SystemContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
runArtifacts, err := b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, volumes, b.CommonBuildOpts.Volumes, options.RunMounts, runMountInfo)
|
runArtifacts, err := b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, volumes, options.CompatBuiltinVolumes, b.CommonBuildOpts.Volumes, options.RunMounts, runMountInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("resolving mountpoints for container %q: %w", b.ContainerID, err)
|
return fmt.Errorf("resolving mountpoints for container %q: %w", b.ContainerID, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ func (r *Runtime) layerTree(ctx context.Context, images []*Image) (*layerTree, e
|
||||||
// mistake. Users may not be able to recover, so we're now
|
// mistake. Users may not be able to recover, so we're now
|
||||||
// throwing a warning to guide them to resolve the issue and
|
// throwing a warning to guide them to resolve the issue and
|
||||||
// turn the errors non-fatal.
|
// turn the errors non-fatal.
|
||||||
logrus.Warnf("Top layer %s of image %s not found in layer tree. The storage may be corrupted, consider running `podman system reset`.", topLayer, img.ID())
|
logrus.Warnf("Top layer %s of image %s not found in layer tree. The storage may be corrupted, consider running `podman system check`.", topLayer, img.ID())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
node.images = append(node.images, img)
|
node.images = append(node.images, img)
|
||||||
|
@ -234,7 +234,7 @@ func (t *layerTree) children(ctx context.Context, parent *Image, all bool) ([]*I
|
||||||
// mistake. Users may not be able to recover, so we're now
|
// mistake. Users may not be able to recover, so we're now
|
||||||
// throwing a warning to guide them to resolve the issue and
|
// throwing a warning to guide them to resolve the issue and
|
||||||
// turn the errors non-fatal.
|
// turn the errors non-fatal.
|
||||||
logrus.Warnf("Layer %s not found in layer tree. The storage may be corrupted, consider running `podman system reset`.", parent.TopLayer())
|
logrus.Warnf("Layer %s not found in layer tree. The storage may be corrupted, consider running `podman system check`.", parent.TopLayer())
|
||||||
return children, nil
|
return children, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ func (t *layerTree) parent(ctx context.Context, child *Image) (*Image, error) {
|
||||||
// mistake. Users may not be able to recover, so we're now
|
// mistake. Users may not be able to recover, so we're now
|
||||||
// throwing a warning to guide them to resolve the issue and
|
// throwing a warning to guide them to resolve the issue and
|
||||||
// turn the errors non-fatal.
|
// turn the errors non-fatal.
|
||||||
logrus.Warnf("Layer %s not found in layer tree. The storage may be corrupted, consider running `podman system reset`.", child.TopLayer())
|
logrus.Warnf("Layer %s not found in layer tree. The storage may be corrupted, consider running `podman system check`.", child.TopLayer())
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package version
|
package version
|
||||||
|
|
||||||
// Version is the version of the build.
|
// Version is the version of the build.
|
||||||
const Version = "0.60.0-dev"
|
const Version = "0.60.0"
|
||||||
|
|
|
@ -73,7 +73,7 @@ type bpCompressionStepData struct {
|
||||||
operation bpcOperation // What we are actually doing
|
operation bpcOperation // What we are actually doing
|
||||||
uploadedOperation types.LayerCompression // Operation to use for updating the blob metadata (matching the end state, not necessarily what we do)
|
uploadedOperation types.LayerCompression // Operation to use for updating the blob metadata (matching the end state, not necessarily what we do)
|
||||||
uploadedAlgorithm *compressiontypes.Algorithm // An algorithm parameter for the compressionOperation edits.
|
uploadedAlgorithm *compressiontypes.Algorithm // An algorithm parameter for the compressionOperation edits.
|
||||||
uploadedAnnotations map[string]string // Annotations that should be set on the uploaded blob. WARNING: This is only set after the srcStream.reader is fully consumed.
|
uploadedAnnotations map[string]string // Compression-related annotations that should be set on the uploaded blob. WARNING: This is only set after the srcStream.reader is fully consumed.
|
||||||
srcCompressorName string // Compressor name to record in the blob info cache for the source blob.
|
srcCompressorName string // Compressor name to record in the blob info cache for the source blob.
|
||||||
uploadedCompressorName string // Compressor name to record in the blob info cache for the uploaded blob.
|
uploadedCompressorName string // Compressor name to record in the blob info cache for the uploaded blob.
|
||||||
closers []io.Closer // Objects to close after the upload is done, if any.
|
closers []io.Closer // Objects to close after the upload is done, if any.
|
||||||
|
@ -323,7 +323,11 @@ func (d *bpCompressionStepData) recordValidatedDigestData(c *copier, uploadedInf
|
||||||
return fmt.Errorf("Internal error: Unexpected d.operation value %#v", d.operation)
|
return fmt.Errorf("Internal error: Unexpected d.operation value %#v", d.operation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if d.uploadedCompressorName != "" && d.uploadedCompressorName != internalblobinfocache.UnknownCompression {
|
if d.srcCompressorName == "" || d.uploadedCompressorName == "" {
|
||||||
|
return fmt.Errorf("internal error: missing compressor names (src: %q, uploaded: %q)",
|
||||||
|
d.srcCompressorName, d.uploadedCompressorName)
|
||||||
|
}
|
||||||
|
if d.uploadedCompressorName != internalblobinfocache.UnknownCompression {
|
||||||
if d.uploadedCompressorName != compressiontypes.ZstdChunkedAlgorithmName {
|
if d.uploadedCompressorName != compressiontypes.ZstdChunkedAlgorithmName {
|
||||||
// HACK: Don’t record zstd:chunked algorithms.
|
// HACK: Don’t record zstd:chunked algorithms.
|
||||||
// There is already a similar hack in internal/imagedestination/impl/helpers.CandidateMatchesTryReusingBlobOptions,
|
// There is already a similar hack in internal/imagedestination/impl/helpers.CandidateMatchesTryReusingBlobOptions,
|
||||||
|
@ -337,7 +341,7 @@ func (d *bpCompressionStepData) recordValidatedDigestData(c *copier, uploadedInf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if srcInfo.Digest != "" && srcInfo.Digest != uploadedInfo.Digest &&
|
if srcInfo.Digest != "" && srcInfo.Digest != uploadedInfo.Digest &&
|
||||||
d.srcCompressorName != "" && d.srcCompressorName != internalblobinfocache.UnknownCompression {
|
d.srcCompressorName != internalblobinfocache.UnknownCompression {
|
||||||
if d.srcCompressorName != compressiontypes.ZstdChunkedAlgorithmName {
|
if d.srcCompressorName != compressiontypes.ZstdChunkedAlgorithmName {
|
||||||
// HACK: Don’t record zstd:chunked algorithms, see above.
|
// HACK: Don’t record zstd:chunked algorithms, see above.
|
||||||
c.blobInfoCache.RecordDigestCompressorName(srcInfo.Digest, d.srcCompressorName)
|
c.blobInfoCache.RecordDigestCompressorName(srcInfo.Digest, d.srcCompressorName)
|
||||||
|
|
|
@ -361,8 +361,6 @@ func (d *dockerImageDestination) TryReusingBlobWithOptions(ctx context.Context,
|
||||||
logrus.Debugf("Error parsing BlobInfoCache location reference: %s", err)
|
logrus.Debugf("Error parsing BlobInfoCache location reference: %s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if !candidate.UnknownLocation {
|
|
||||||
if candidate.CompressionAlgorithm != nil {
|
if candidate.CompressionAlgorithm != nil {
|
||||||
logrus.Debugf("Trying to reuse blob with cached digest %s compressed with %s in destination repo %s", candidate.Digest.String(), candidate.CompressionAlgorithm.Name(), candidateRepo.Name())
|
logrus.Debugf("Trying to reuse blob with cached digest %s compressed with %s in destination repo %s", candidate.Digest.String(), candidate.CompressionAlgorithm.Name(), candidateRepo.Name())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -27,7 +27,7 @@ type cache struct {
|
||||||
uncompressedDigests map[digest.Digest]digest.Digest
|
uncompressedDigests map[digest.Digest]digest.Digest
|
||||||
digestsByUncompressed map[digest.Digest]*set.Set[digest.Digest] // stores a set of digests for each uncompressed digest
|
digestsByUncompressed map[digest.Digest]*set.Set[digest.Digest] // stores a set of digests for each uncompressed digest
|
||||||
knownLocations map[locationKey]map[types.BICLocationReference]time.Time // stores last known existence time for each location reference
|
knownLocations map[locationKey]map[types.BICLocationReference]time.Time // stores last known existence time for each location reference
|
||||||
compressors map[digest.Digest]string // stores a compressor name, or blobinfocache.Unknown (not blobinfocache.UnknownCompression), for each digest
|
compressors map[digest.Digest]string // stores a compressor name, or blobinfocache.Uncompressed (not blobinfocache.UnknownCompression), for each digest
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a BlobInfoCache implementation which is in-memory only.
|
// New returns a BlobInfoCache implementation which is in-memory only.
|
||||||
|
|
|
@ -11,7 +11,7 @@ const (
|
||||||
VersionPatch = 0
|
VersionPatch = 0
|
||||||
|
|
||||||
// VersionDev indicates development branch. Releases will be empty string.
|
// VersionDev indicates development branch. Releases will be empty string.
|
||||||
VersionDev = "-dev"
|
VersionDev = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
// Version is the specification version that the package types support.
|
// Version is the specification version that the package types support.
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.55.0-dev
|
1.55.0
|
||||||
|
|
|
@ -401,7 +401,7 @@ type ExportImagesOptions struct {
|
||||||
//
|
//
|
||||||
// See https://goo.gl/N9XlDn for more details.
|
// See https://goo.gl/N9XlDn for more details.
|
||||||
func (c *Client) ExportImages(opts ExportImagesOptions) error {
|
func (c *Client) ExportImages(opts ExportImagesOptions) error {
|
||||||
if opts.Names == nil || len(opts.Names) == 0 {
|
if len(opts.Names) == 0 {
|
||||||
return ErrMustSpecifyNames
|
return ErrMustSpecifyNames
|
||||||
}
|
}
|
||||||
// API < 1.25 allows multiple name values
|
// API < 1.25 allows multiple name values
|
||||||
|
|
|
@ -14,8 +14,13 @@ before_install:
|
||||||
- yes | sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
|
- yes | sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
|
||||||
- sudo apt-get update -q -y
|
- sudo apt-get update -q -y
|
||||||
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
||||||
|
- sudo systemctl enable --now docker.service && sudo systemctl enable --now docker.socket
|
||||||
- docker pull busybox
|
- docker pull busybox
|
||||||
- docker pull centos:7
|
- docker pull centos:7
|
||||||
|
- docker pull alpine
|
||||||
|
- docker pull registry.fedoraproject.org/fedora-minimal
|
||||||
|
- docker pull registry.fedoraproject.org/fedora-minimal:41-x86_64
|
||||||
|
- docker pull registry.fedoraproject.org/fedora-minimal:41-aarch64
|
||||||
- chmod -R go-w ./dockerclient/testdata
|
- chmod -R go-w ./dockerclient/testdata
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
|
|
@ -103,7 +103,11 @@ Example of usage from OpenShift's experimental `dockerbuild` [command with mount
|
||||||
|
|
||||||
```
|
```
|
||||||
docker rmi busybox; docker pull busybox
|
docker rmi busybox; docker pull busybox
|
||||||
|
docker rmi alpine; docker pull alpine
|
||||||
docker rmi centos:7; docker pull centos:7
|
docker rmi centos:7; docker pull centos:7
|
||||||
|
docker rmi registry.fedoraproject.org/fedora-minimal; docker pull registry.fedoraproject.org/fedora-minimal
|
||||||
|
docker rmi registry.fedoraproject.org/fedora-minimal:41-x86_64; docker pull registry.fedoraproject.org/fedora-minimal:41-x86_64
|
||||||
|
docker rmi registry.fedoraproject.org/fedora-minimal:41-aarch64; docker pull registry.fedoraproject.org/fedora-minimal:41-aarch64
|
||||||
chmod -R go-w ./dockerclient/testdata
|
chmod -R go-w ./dockerclient/testdata
|
||||||
go test ./dockerclient -tags conformance -timeout 30m
|
go test ./dockerclient -tags conformance -timeout 30m
|
||||||
```
|
```
|
||||||
|
|
|
@ -288,29 +288,38 @@ type Stage struct {
|
||||||
|
|
||||||
func NewStages(node *parser.Node, b *Builder) (Stages, error) {
|
func NewStages(node *parser.Node, b *Builder) (Stages, error) {
|
||||||
var stages Stages
|
var stages Stages
|
||||||
var allDeclaredArgs []string
|
var headingArgs []string
|
||||||
for _, root := range SplitBy(node, command.Arg) {
|
|
||||||
argNode := root.Children[0]
|
|
||||||
if argNode.Value == command.Arg {
|
|
||||||
// extract declared variable
|
|
||||||
s := strings.SplitN(argNode.Original, " ", 2)
|
|
||||||
if len(s) == 2 && (strings.ToLower(s[0]) == command.Arg) {
|
|
||||||
allDeclaredArgs = append(allDeclaredArgs, s[1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := b.extractHeadingArgsFromNode(node); err != nil {
|
if err := b.extractHeadingArgsFromNode(node); err != nil {
|
||||||
return stages, err
|
return stages, err
|
||||||
}
|
}
|
||||||
|
for k := range b.HeadingArgs {
|
||||||
|
headingArgs = append(headingArgs, k)
|
||||||
|
}
|
||||||
for i, root := range SplitBy(node, command.From) {
|
for i, root := range SplitBy(node, command.From) {
|
||||||
name, _ := extractNameFromNode(root.Children[0])
|
name, _ := extractNameFromNode(root.Children[0])
|
||||||
if len(name) == 0 {
|
if len(name) == 0 {
|
||||||
name = strconv.Itoa(i)
|
name = strconv.Itoa(i)
|
||||||
}
|
}
|
||||||
|
filteredUserArgs := make(map[string]string)
|
||||||
|
for k, v := range b.UserArgs {
|
||||||
|
for _, a := range b.GlobalAllowedArgs {
|
||||||
|
if a == k {
|
||||||
|
filteredUserArgs[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
userArgs := envMapAsSlice(filteredUserArgs)
|
||||||
|
userArgs = mergeEnv(envMapAsSlice(b.BuiltinArgDefaults), userArgs)
|
||||||
|
userArgs = mergeEnv(envMapAsSlice(builtinArgDefaults), userArgs)
|
||||||
|
userArgs = mergeEnv(envMapAsSlice(b.HeadingArgs), userArgs)
|
||||||
|
processedName, err := ProcessWord(name, userArgs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
stages = append(stages, Stage{
|
stages = append(stages, Stage{
|
||||||
Position: i,
|
Position: i,
|
||||||
Name: name,
|
Name: processedName,
|
||||||
Builder: b.builderForStage(allDeclaredArgs),
|
Builder: b.builderForStage(headingArgs),
|
||||||
Node: root,
|
Node: root,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -375,32 +384,41 @@ func extractNameFromNode(node *parser.Node) (string, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) builderForStage(globalArgsList []string) *Builder {
|
func (b *Builder) builderForStage(globalArgsList []string) *Builder {
|
||||||
stageBuilder := newBuilderWithGlobalAllowedArgs(b.UserArgs, globalArgsList)
|
stageBuilder := newBuilderWithGlobalAllowedArgs(b.UserArgs, b.HeadingArgs, b.BuiltinArgDefaults, globalArgsList)
|
||||||
for k, v := range b.HeadingArgs {
|
|
||||||
stageBuilder.HeadingArgs[k] = v
|
|
||||||
}
|
|
||||||
return stageBuilder
|
return stageBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
type Builder struct {
|
type Builder struct {
|
||||||
RunConfig docker.Config
|
RunConfig docker.Config
|
||||||
|
|
||||||
Env []string
|
Env []string
|
||||||
Args map[string]string
|
|
||||||
HeadingArgs map[string]string
|
|
||||||
UserArgs map[string]string
|
|
||||||
CmdSet bool
|
|
||||||
Author string
|
|
||||||
// Certain instructions like `FROM` will need to use
|
|
||||||
// `ARG` decalred before or not in this stage hence
|
|
||||||
// while processing instruction like `FROM ${SOME_ARG}`
|
|
||||||
// we will make sure to verify if they are declared any
|
|
||||||
// where in containerfile or not.
|
|
||||||
GlobalAllowedArgs []string
|
|
||||||
|
|
||||||
|
// Args contains values originally given to NewBuilder() or set due to
|
||||||
|
// ARG instructions in a stage, either with a default value provided,
|
||||||
|
// or with a default inherited from an ARG instruction in the header
|
||||||
|
Args map[string]string
|
||||||
|
// HeadingArgs contains the values for ARG instructions in the
|
||||||
|
// Dockerfile which occurred before the first FROM instruction, either
|
||||||
|
// with a default value provided as part of the ARG instruction, or
|
||||||
|
// expecting a value to be supplied in UserArgs via NewBuilder().
|
||||||
|
HeadingArgs map[string]string
|
||||||
|
// UserArgs includes a copy of the values that were passed to
|
||||||
|
// NewBuilder(), unmodified.
|
||||||
|
UserArgs map[string]string
|
||||||
|
|
||||||
|
CmdSet bool
|
||||||
|
Author string
|
||||||
|
|
||||||
|
// GlobalAllowedArgs are args which should be resolvable in a FROM
|
||||||
|
// instruction, either built-in and always available, or introduced by
|
||||||
|
// an ARG instruction in the header.
|
||||||
|
GlobalAllowedArgs []string
|
||||||
|
// AllowedArgs are args which should be resolvable in this stage,
|
||||||
|
// having been introduced by a previous ARG instruction in this stage.
|
||||||
AllowedArgs map[string]bool
|
AllowedArgs map[string]bool
|
||||||
Volumes VolumeSet
|
|
||||||
Excludes []string
|
Volumes VolumeSet
|
||||||
|
Excludes []string
|
||||||
|
|
||||||
PendingVolumes VolumeSet
|
PendingVolumes VolumeSet
|
||||||
PendingRuns []Run
|
PendingRuns []Run
|
||||||
|
@ -410,13 +428,18 @@ type Builder struct {
|
||||||
// Raw platform string specified with `FROM --platform` of the stage
|
// Raw platform string specified with `FROM --platform` of the stage
|
||||||
// It's up to the implementation or client to parse and use this field
|
// It's up to the implementation or client to parse and use this field
|
||||||
Platform string
|
Platform string
|
||||||
|
|
||||||
|
// Overrides for TARGET... and BUILD... values. TARGET... values are
|
||||||
|
// typically only necessary if the builder's target platform is not the
|
||||||
|
// same as the build platform.
|
||||||
|
BuiltinArgDefaults map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBuilder(args map[string]string) *Builder {
|
func NewBuilder(args map[string]string) *Builder {
|
||||||
return newBuilderWithGlobalAllowedArgs(args, []string{})
|
return newBuilderWithGlobalAllowedArgs(args, nil, nil, []string{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBuilderWithGlobalAllowedArgs(args map[string]string, globalallowedargs []string) *Builder {
|
func newBuilderWithGlobalAllowedArgs(args, headingArgs, userBuiltinArgDefaults map[string]string, globalAllowedArgs []string) *Builder {
|
||||||
allowed := make(map[string]bool)
|
allowed := make(map[string]bool)
|
||||||
for k, v := range builtinAllowedBuildArgs {
|
for k, v := range builtinAllowedBuildArgs {
|
||||||
allowed[k] = v
|
allowed[k] = v
|
||||||
|
@ -427,12 +450,28 @@ func newBuilderWithGlobalAllowedArgs(args map[string]string, globalallowedargs [
|
||||||
userArgs[k] = v
|
userArgs[k] = v
|
||||||
initialArgs[k] = v
|
initialArgs[k] = v
|
||||||
}
|
}
|
||||||
|
var copiedGlobalAllowedArgs []string
|
||||||
|
if len(globalAllowedArgs) > 0 {
|
||||||
|
copiedGlobalAllowedArgs = append([]string{}, globalAllowedArgs...)
|
||||||
|
}
|
||||||
|
copiedHeadingArgs := make(map[string]string)
|
||||||
|
for k, v := range headingArgs {
|
||||||
|
copiedHeadingArgs[k] = v
|
||||||
|
}
|
||||||
|
copiedBuiltinArgDefaults := make(map[string]string)
|
||||||
|
for k, v := range builtinArgDefaults {
|
||||||
|
copiedBuiltinArgDefaults[k] = v
|
||||||
|
}
|
||||||
|
for k, v := range userBuiltinArgDefaults {
|
||||||
|
copiedBuiltinArgDefaults[k] = v
|
||||||
|
}
|
||||||
return &Builder{
|
return &Builder{
|
||||||
Args: initialArgs,
|
Args: initialArgs,
|
||||||
UserArgs: userArgs,
|
UserArgs: userArgs,
|
||||||
HeadingArgs: make(map[string]string),
|
HeadingArgs: copiedHeadingArgs,
|
||||||
AllowedArgs: allowed,
|
AllowedArgs: allowed,
|
||||||
GlobalAllowedArgs: globalallowedargs,
|
GlobalAllowedArgs: copiedGlobalAllowedArgs,
|
||||||
|
BuiltinArgDefaults: copiedBuiltinArgDefaults,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
|
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
docker "github.com/fsouza/go-dockerclient"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
"github.com/containers/storage/pkg/regexp"
|
"github.com/containers/storage/pkg/regexp"
|
||||||
"github.com/openshift/imagebuilder/signal"
|
"github.com/openshift/imagebuilder/signal"
|
||||||
|
@ -35,7 +36,7 @@ var (
|
||||||
var localspec = platforms.DefaultSpec()
|
var localspec = platforms.DefaultSpec()
|
||||||
|
|
||||||
// https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
|
// https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
|
||||||
var builtinBuildArgs = map[string]string{
|
var builtinArgDefaults = map[string]string{
|
||||||
"TARGETPLATFORM": localspec.OS + "/" + localspec.Architecture,
|
"TARGETPLATFORM": localspec.OS + "/" + localspec.Architecture,
|
||||||
"TARGETOS": localspec.OS,
|
"TARGETOS": localspec.OS,
|
||||||
"TARGETARCH": localspec.Architecture,
|
"TARGETARCH": localspec.Architecture,
|
||||||
|
@ -48,8 +49,8 @@ var builtinBuildArgs = map[string]string{
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if localspec.Variant != "" {
|
if localspec.Variant != "" {
|
||||||
builtinBuildArgs["TARGETPLATFORM"] = builtinBuildArgs["TARGETPLATFORM"] + "/" + localspec.Variant
|
builtinArgDefaults["TARGETPLATFORM"] = builtinArgDefaults["TARGETPLATFORM"] + "/" + localspec.Variant
|
||||||
builtinBuildArgs["BUILDPLATFORM"] = builtinBuildArgs["BUILDPLATFORM"] + "/" + localspec.Variant
|
builtinArgDefaults["BUILDPLATFORM"] = builtinArgDefaults["BUILDPLATFORM"] + "/" + localspec.Variant
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,13 +84,12 @@ func env(b *Builder, args []string, attributes map[string]bool, flagArgs []strin
|
||||||
fmt.Printf("Str1:%v\n", flStr1)
|
fmt.Printf("Str1:%v\n", flStr1)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for j := 0; j < len(args); j++ {
|
for j := 0; j+1 < len(args); j += 2 {
|
||||||
// name ==> args[j]
|
// name ==> args[j]
|
||||||
// value ==> args[j+1]
|
// value ==> args[j+1]
|
||||||
newVar := []string{args[j] + "=" + args[j+1]}
|
newVar := []string{args[j] + "=" + args[j+1]}
|
||||||
b.RunConfig.Env = mergeEnv(b.RunConfig.Env, newVar)
|
b.RunConfig.Env = mergeEnv(b.RunConfig.Env, newVar)
|
||||||
b.Env = mergeEnv(b.Env, newVar)
|
b.Env = mergeEnv(b.Env, newVar)
|
||||||
j++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -254,7 +254,13 @@ func dispatchCopy(b *Builder, args []string, attributes map[string]bool, flagArg
|
||||||
var link bool
|
var link bool
|
||||||
var parents bool
|
var parents bool
|
||||||
var excludes []string
|
var excludes []string
|
||||||
userArgs := mergeEnv(envMapAsSlice(b.Args), b.Env)
|
filteredUserArgs := make(map[string]string)
|
||||||
|
for k, v := range b.Args {
|
||||||
|
if _, ok := b.AllowedArgs[k]; ok {
|
||||||
|
filteredUserArgs[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
userArgs := mergeEnv(envMapAsSlice(filteredUserArgs), b.Env)
|
||||||
for _, a := range flagArgs {
|
for _, a := range flagArgs {
|
||||||
arg, err := ProcessWord(a, userArgs)
|
arg, err := ProcessWord(a, userArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -323,17 +329,12 @@ func from(b *Builder, args []string, attributes map[string]bool, flagArgs []stri
|
||||||
case len(args) == 3 && len(args[0]) > 0 && strings.EqualFold(args[1], "as") && len(args[2]) > 0:
|
case len(args) == 3 && len(args[0]) > 0 && strings.EqualFold(args[1], "as") && len(args[2]) > 0:
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("FROM requires either one argument, or three: FROM <source> [as <name>]")
|
return fmt.Errorf("FROM requires either one argument, or three: FROM <source> [AS <name>]")
|
||||||
}
|
}
|
||||||
|
|
||||||
name := args[0]
|
name := args[0]
|
||||||
|
|
||||||
// Support ARG before from
|
// Support ARG before FROM
|
||||||
argStrs := []string{}
|
|
||||||
for n, v := range b.HeadingArgs {
|
|
||||||
argStrs = append(argStrs, n+"="+v)
|
|
||||||
}
|
|
||||||
defaultArgs := envMapAsSlice(builtinBuildArgs)
|
|
||||||
filteredUserArgs := make(map[string]string)
|
filteredUserArgs := make(map[string]string)
|
||||||
for k, v := range b.UserArgs {
|
for k, v := range b.UserArgs {
|
||||||
for _, a := range b.GlobalAllowedArgs {
|
for _, a := range b.GlobalAllowedArgs {
|
||||||
|
@ -343,10 +344,11 @@ func from(b *Builder, args []string, attributes map[string]bool, flagArgs []stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
userArgs := mergeEnv(envMapAsSlice(filteredUserArgs), b.Env)
|
userArgs := mergeEnv(envMapAsSlice(filteredUserArgs), b.Env)
|
||||||
userArgs = mergeEnv(defaultArgs, userArgs)
|
userArgs = mergeEnv(envMapAsSlice(b.BuiltinArgDefaults), userArgs)
|
||||||
nameArgs := mergeEnv(argStrs, userArgs)
|
userArgs = mergeEnv(envMapAsSlice(builtinArgDefaults), userArgs)
|
||||||
|
userArgs = mergeEnv(envMapAsSlice(b.HeadingArgs), userArgs)
|
||||||
var err error
|
var err error
|
||||||
if name, err = ProcessWord(name, nameArgs); err != nil {
|
if name, err = ProcessWord(name, userArgs); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +359,7 @@ func from(b *Builder, args []string, attributes map[string]bool, flagArgs []stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, a := range flagArgs {
|
for _, a := range flagArgs {
|
||||||
arg, err := ProcessWord(a, nameArgs)
|
arg, err := ProcessWord(a, userArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -727,70 +729,64 @@ func healthcheck(b *Builder, args []string, attributes map[string]bool, flagArgs
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var targetArgs = []string{"TARGETOS", "TARGETARCH", "TARGETVARIANT"}
|
|
||||||
|
|
||||||
// ARG name[=value]
|
// ARG name[=value]
|
||||||
//
|
//
|
||||||
// Adds the variable foo to the trusted list of variables that can be passed
|
// Adds the variable foo to the trusted list of variables that can be passed
|
||||||
// to builder using the --build-arg flag for expansion/subsitution or passing to 'run'.
|
// to builder using the --build-arg flag for expansion/subsitution or passing to 'run'.
|
||||||
// Dockerfile author may optionally set a default value of this variable.
|
// Dockerfile author may optionally set a default value of this variable.
|
||||||
func arg(b *Builder, args []string, attributes map[string]bool, flagArgs []string, original string, heredocs []buildkitparser.Heredoc) error {
|
func arg(b *Builder, args []string, attributes map[string]bool, flagArgs []string, original string, heredocs []buildkitparser.Heredoc) error {
|
||||||
var (
|
|
||||||
name string
|
|
||||||
value string
|
|
||||||
hasDefault bool
|
|
||||||
)
|
|
||||||
|
|
||||||
for _, argument := range args {
|
for _, argument := range args {
|
||||||
|
var (
|
||||||
|
name string
|
||||||
|
defaultValue string
|
||||||
|
haveDefault bool
|
||||||
|
)
|
||||||
arg := argument
|
arg := argument
|
||||||
// 'arg' can just be a name or name-value pair. Note that this is different
|
// 'arg' can just be a name or name-value pair. Note that this is different
|
||||||
// from 'env' that handles the split of name and value at the parser level.
|
// from 'env' that handles the split of name and value at the parser level.
|
||||||
// The reason for doing it differently for 'arg' is that we support just
|
// The reason for doing it differently for 'arg' is that we support just
|
||||||
// defining an arg and not assign it a value (while 'env' always expects a
|
// defining an arg without assigning it a value (while 'env' always expects a
|
||||||
// name-value pair). If possible, it will be good to harmonize the two.
|
// name-value pair). If possible, it will be good to harmonize the two.
|
||||||
if strings.Contains(arg, "=") {
|
name, defaultValue, haveDefault = strings.Cut(arg, "=")
|
||||||
parts := strings.SplitN(arg, "=", 2)
|
|
||||||
name = parts[0]
|
|
||||||
value = parts[1]
|
|
||||||
hasDefault = true
|
|
||||||
if name == "TARGETPLATFORM" {
|
|
||||||
p, err := platforms.Parse(value)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error parsing TARGETPLATFORM argument")
|
|
||||||
}
|
|
||||||
for _, val := range targetArgs {
|
|
||||||
b.AllowedArgs[val] = true
|
|
||||||
}
|
|
||||||
b.Args["TARGETPLATFORM"] = p.OS + "/" + p.Architecture
|
|
||||||
b.Args["TARGETOS"] = p.OS
|
|
||||||
b.Args["TARGETARCH"] = p.Architecture
|
|
||||||
b.Args["TARGETVARIANT"] = p.Variant
|
|
||||||
if p.Variant != "" {
|
|
||||||
b.Args["TARGETPLATFORM"] = b.Args["TARGETPLATFORM"] + "/" + p.Variant
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if val, ok := builtinBuildArgs[arg]; ok {
|
|
||||||
name = arg
|
|
||||||
value = val
|
|
||||||
hasDefault = true
|
|
||||||
} else {
|
|
||||||
name = arg
|
|
||||||
hasDefault = false
|
|
||||||
}
|
|
||||||
// add the arg to allowed list of build-time args from this step on.
|
// add the arg to allowed list of build-time args from this step on.
|
||||||
b.AllowedArgs[name] = true
|
b.AllowedArgs[name] = true
|
||||||
|
|
||||||
// If there is still no default value, a value can be assigned from the heading args
|
// If the stage introduces one of the predefined args, add the
|
||||||
if val, ok := b.HeadingArgs[name]; ok && !hasDefault {
|
// predefined value to the list of values known in this stage
|
||||||
b.Args[name] = val
|
if value, defined := builtinArgDefaults[name]; defined {
|
||||||
|
if haveDefault && (name == "TARGETPLATFORM" || name == "BUILDPLATFORM") {
|
||||||
|
return fmt.Errorf("attempted to redefine %q: %w", name, errdefs.ErrInvalidArgument)
|
||||||
|
}
|
||||||
|
if b.BuiltinArgDefaults == nil {
|
||||||
|
b.BuiltinArgDefaults = make(map[string]string)
|
||||||
|
}
|
||||||
|
// N.B.: we're only consulting b.BuiltinArgDefaults for
|
||||||
|
// values that correspond to keys in
|
||||||
|
// builtinArgDefaults, which keeps the caller from
|
||||||
|
// using it to sneak in arbitrary ARG values
|
||||||
|
if _, setByUser := b.UserArgs[name]; !setByUser && defined {
|
||||||
|
if builderValue, builderDefined := b.BuiltinArgDefaults[name]; builderDefined {
|
||||||
|
b.Args[name] = builderValue
|
||||||
|
} else {
|
||||||
|
b.Args[name] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a default value associated with this arg then add it to the
|
// If there is still no default value, check for a default value from the heading args
|
||||||
// b.buildArgs, later default values for the same arg override earlier ones.
|
if !haveDefault {
|
||||||
// The args passed to builder (UserArgs) override the default value of 'arg'
|
defaultValue, haveDefault = b.HeadingArgs[name]
|
||||||
// Don't add them here as they were already set in NewBuilder.
|
}
|
||||||
if _, ok := b.UserArgs[name]; !ok && hasDefault {
|
|
||||||
b.Args[name] = value
|
// If there is a default value provided for this arg, and the user didn't supply
|
||||||
|
// a value, then set the default value in b.Args. Later defaults given for the
|
||||||
|
// same arg override earlier ones. The args passed to the builder (UserArgs) override
|
||||||
|
// any default values of 'arg', so don't set them here as they were already set
|
||||||
|
// in NewBuilder().
|
||||||
|
if _, setByUser := b.UserArgs[name]; !setByUser && haveDefault {
|
||||||
|
b.Args[name] = defaultValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
%global golang_version 1.19
|
%global golang_version 1.19
|
||||||
%{!?version: %global version 1.2.11}
|
%{!?version: %global version 1.2.14}
|
||||||
%{!?release: %global release 1}
|
%{!?release: %global release 1}
|
||||||
%global package_name imagebuilder
|
%global package_name imagebuilder
|
||||||
%global product_name Container Image Builder
|
%global product_name Container Image Builder
|
||||||
|
|
|
@ -9,6 +9,7 @@ package imagebuilder
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"text/scanner"
|
"text/scanner"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
@ -103,9 +104,14 @@ func (w *wordsStruct) getWords() []string {
|
||||||
return w.words
|
return w.words
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sw *shellWord) processStopOn(stopChar rune) (string, []string, error) {
|
||||||
|
_, result, words, err := sw.processStopOnAny([]rune{stopChar})
|
||||||
|
return result, words, err
|
||||||
|
}
|
||||||
|
|
||||||
// Process the word, starting at 'pos', and stop when we get to the
|
// Process the word, starting at 'pos', and stop when we get to the
|
||||||
// end of the word or the 'stopChar' character
|
// end of the word or the 'stopChar' character
|
||||||
func (sw *shellWord) processStopOn(stopChar rune) (string, []string, error) {
|
func (sw *shellWord) processStopOnAny(stopChars []rune) (rune, string, []string, error) {
|
||||||
var result string
|
var result string
|
||||||
var words wordsStruct
|
var words wordsStruct
|
||||||
|
|
||||||
|
@ -115,18 +121,26 @@ func (sw *shellWord) processStopOn(stopChar rune) (string, []string, error) {
|
||||||
'$': sw.processDollar,
|
'$': sw.processDollar,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sliceContains := func(slice []rune, value rune) bool {
|
||||||
|
for _, r := range slice {
|
||||||
|
if r == value {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
for sw.scanner.Peek() != scanner.EOF {
|
for sw.scanner.Peek() != scanner.EOF {
|
||||||
ch := sw.scanner.Peek()
|
ch := sw.scanner.Peek()
|
||||||
|
|
||||||
if stopChar != scanner.EOF && ch == stopChar {
|
if sliceContains(stopChars, ch) {
|
||||||
sw.scanner.Next()
|
sw.scanner.Next() // skip over ch
|
||||||
return result, words.getWords(), nil
|
return ch, result, words.getWords(), nil
|
||||||
}
|
}
|
||||||
if fn, ok := charFuncMapping[ch]; ok {
|
if fn, ok := charFuncMapping[ch]; ok {
|
||||||
// Call special processing func for certain chars
|
// Call special processing func for certain chars
|
||||||
tmp, err := fn()
|
tmp, err := fn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", []string{}, err
|
return ch, "", []string{}, err
|
||||||
}
|
}
|
||||||
result += tmp
|
result += tmp
|
||||||
|
|
||||||
|
@ -157,11 +171,11 @@ func (sw *shellWord) processStopOn(stopChar rune) (string, []string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if stopChar != scanner.EOF {
|
if !sliceContains(stopChars, scanner.EOF) {
|
||||||
return "", []string{}, fmt.Errorf("unexpected end of statement while looking for matching %s", string(stopChar))
|
return scanner.EOF, "", []string{}, fmt.Errorf("unexpected end of statement while looking for matching %s", string(stopChars))
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, words.getWords(), nil
|
return scanner.EOF, result, words.getWords(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sw *shellWord) processSingleQuote() (string, error) {
|
func (sw *shellWord) processSingleQuote() (string, error) {
|
||||||
|
@ -281,7 +295,117 @@ func (sw *shellWord) processDollar() (string, error) {
|
||||||
return "", fmt.Errorf("Unsupported modifier (%c) in substitution: %s", modifier, sw.word)
|
return "", fmt.Errorf("Unsupported modifier (%c) in substitution: %s", modifier, sw.word)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("Missing ':' in substitution: %s", sw.word)
|
if ch == '#' || ch == '%' { // strip a prefix or suffix
|
||||||
|
sw.scanner.Next() // skip over # or %
|
||||||
|
greedy := false
|
||||||
|
if sw.scanner.Peek() == ch {
|
||||||
|
sw.scanner.Next() // skip over second # or %
|
||||||
|
greedy = true
|
||||||
|
}
|
||||||
|
word, _, err := sw.processStopOn('}')
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
value := sw.getEnv(name)
|
||||||
|
switch ch {
|
||||||
|
case '#': // strip a prefix
|
||||||
|
if word == "" {
|
||||||
|
return "", fmt.Errorf("%s#: no prefix to remove", name)
|
||||||
|
}
|
||||||
|
if greedy {
|
||||||
|
for i := len(value) - 1; i >= 0; i-- {
|
||||||
|
if matches, err := path.Match(word, value[:i]); err == nil && matches {
|
||||||
|
return value[i:], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := 0; i < len(value)-1; i++ {
|
||||||
|
if matches, err := path.Match(word, value[:i]); err == nil && matches {
|
||||||
|
return value[i:], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value, nil
|
||||||
|
case '%': // strip a suffix
|
||||||
|
if word == "" {
|
||||||
|
return "", fmt.Errorf("%s%%: no suffix to remove", name)
|
||||||
|
}
|
||||||
|
if greedy {
|
||||||
|
for i := 0; i < len(value)-1; i++ {
|
||||||
|
if matches, err := path.Match(word, value[i:]); err == nil && matches {
|
||||||
|
return value[:i], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := len(value) - 1; i >= 0; i-- {
|
||||||
|
if matches, err := path.Match(word, value[i:]); err == nil && matches {
|
||||||
|
return value[:i], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ch == '/' { // perform substitution
|
||||||
|
sw.scanner.Next() // skip over /
|
||||||
|
all, begin, end := false, false, false
|
||||||
|
switch sw.scanner.Peek() {
|
||||||
|
case ch:
|
||||||
|
sw.scanner.Next() // skip over second /
|
||||||
|
all = true // replace all instances
|
||||||
|
case '#':
|
||||||
|
sw.scanner.Next() // skip over #
|
||||||
|
begin = true // replace only an prefix instance
|
||||||
|
case '%':
|
||||||
|
sw.scanner.Next() // skip over %
|
||||||
|
end = true // replace only a fuffix instance
|
||||||
|
}
|
||||||
|
// the '/', and the replacement pattern that follows
|
||||||
|
// it, can be omitted if the replacement pattern is "",
|
||||||
|
// so the pattern-to-replace can end at either a '/' or
|
||||||
|
// a '}'
|
||||||
|
ch, pattern, _, err := sw.processStopOnAny([]rune{'/', '}'})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if pattern == "" { // pattern to replace needs to not be empty
|
||||||
|
return "", fmt.Errorf("%s/: no pattern to replace", name)
|
||||||
|
}
|
||||||
|
var replacement string
|
||||||
|
if ch == '/' { // patter to replace it with was specified
|
||||||
|
replacement, _, err = sw.processStopOn('}')
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value := sw.getEnv(name)
|
||||||
|
i := 0
|
||||||
|
for {
|
||||||
|
if i >= len(value) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for j := len(value); j > i; j-- {
|
||||||
|
if begin && i != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if end && j != len(value) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
matches, err := path.Match(pattern, value[i:j])
|
||||||
|
if err == nil && matches {
|
||||||
|
value = value[:i] + replacement + value[j:]
|
||||||
|
if !all {
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
i += (len(replacement) - 1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("Missing ':' or '#' or '%%' or '/' in substitution: %s", sw.word)
|
||||||
}
|
}
|
||||||
// $xxx case
|
// $xxx case
|
||||||
name := sw.processName()
|
name := sw.processName()
|
||||||
|
|
|
@ -109,6 +109,7 @@ github.com/chzyer/readline
|
||||||
github.com/containerd/cgroups/v3/cgroup1/stats
|
github.com/containerd/cgroups/v3/cgroup1/stats
|
||||||
# github.com/containerd/containerd v1.7.18
|
# github.com/containerd/containerd v1.7.18
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
|
github.com/containerd/containerd/errdefs
|
||||||
github.com/containerd/containerd/pkg/userns
|
github.com/containerd/containerd/pkg/userns
|
||||||
github.com/containerd/containerd/platforms
|
github.com/containerd/containerd/platforms
|
||||||
# github.com/containerd/errdefs v0.1.0
|
# github.com/containerd/errdefs v0.1.0
|
||||||
|
@ -124,7 +125,7 @@ github.com/containerd/stargz-snapshotter/estargz/errorutil
|
||||||
# github.com/containerd/typeurl/v2 v2.1.1
|
# github.com/containerd/typeurl/v2 v2.1.1
|
||||||
## explicit; go 1.13
|
## explicit; go 1.13
|
||||||
github.com/containerd/typeurl/v2
|
github.com/containerd/typeurl/v2
|
||||||
# github.com/containernetworking/cni v1.2.2
|
# github.com/containernetworking/cni v1.2.3
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
github.com/containernetworking/cni/libcni
|
github.com/containernetworking/cni/libcni
|
||||||
github.com/containernetworking/cni/pkg/invoke
|
github.com/containernetworking/cni/pkg/invoke
|
||||||
|
@ -139,7 +140,7 @@ github.com/containernetworking/cni/pkg/version
|
||||||
# github.com/containernetworking/plugins v1.5.1
|
# github.com/containernetworking/plugins v1.5.1
|
||||||
## explicit; go 1.20
|
## explicit; go 1.20
|
||||||
github.com/containernetworking/plugins/pkg/ns
|
github.com/containernetworking/plugins/pkg/ns
|
||||||
# github.com/containers/buildah v1.36.1-0.20240715114330-4a82e0a3f382
|
# github.com/containers/buildah v1.37.0
|
||||||
## explicit; go 1.21.0
|
## explicit; go 1.21.0
|
||||||
github.com/containers/buildah
|
github.com/containers/buildah
|
||||||
github.com/containers/buildah/bind
|
github.com/containers/buildah/bind
|
||||||
|
@ -169,7 +170,7 @@ github.com/containers/buildah/pkg/sshagent
|
||||||
github.com/containers/buildah/pkg/util
|
github.com/containers/buildah/pkg/util
|
||||||
github.com/containers/buildah/pkg/volumes
|
github.com/containers/buildah/pkg/volumes
|
||||||
github.com/containers/buildah/util
|
github.com/containers/buildah/util
|
||||||
# github.com/containers/common v0.59.1-0.20240717135212-fdbae3a180cb
|
# github.com/containers/common v0.60.0
|
||||||
## explicit; go 1.21.0
|
## explicit; go 1.21.0
|
||||||
github.com/containers/common/internal
|
github.com/containers/common/internal
|
||||||
github.com/containers/common/internal/attributedstring
|
github.com/containers/common/internal/attributedstring
|
||||||
|
@ -242,7 +243,7 @@ github.com/containers/conmon/runner/config
|
||||||
# github.com/containers/gvisor-tap-vsock v0.7.4
|
# github.com/containers/gvisor-tap-vsock v0.7.4
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
github.com/containers/gvisor-tap-vsock/pkg/types
|
github.com/containers/gvisor-tap-vsock/pkg/types
|
||||||
# github.com/containers/image/v5 v5.31.1-0.20240711123249-1dbd8fbbe516
|
# github.com/containers/image/v5 v5.32.0
|
||||||
## explicit; go 1.21.0
|
## explicit; go 1.21.0
|
||||||
github.com/containers/image/v5/copy
|
github.com/containers/image/v5/copy
|
||||||
github.com/containers/image/v5/directory
|
github.com/containers/image/v5/directory
|
||||||
|
@ -353,7 +354,7 @@ github.com/containers/psgo/internal/dev
|
||||||
github.com/containers/psgo/internal/host
|
github.com/containers/psgo/internal/host
|
||||||
github.com/containers/psgo/internal/proc
|
github.com/containers/psgo/internal/proc
|
||||||
github.com/containers/psgo/internal/process
|
github.com/containers/psgo/internal/process
|
||||||
# github.com/containers/storage v1.54.1-0.20240724150347-86a0c425388b
|
# github.com/containers/storage v1.55.0
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
github.com/containers/storage
|
github.com/containers/storage
|
||||||
github.com/containers/storage/drivers
|
github.com/containers/storage/drivers
|
||||||
|
@ -467,7 +468,7 @@ github.com/distribution/reference
|
||||||
github.com/docker/distribution/registry/api/errcode
|
github.com/docker/distribution/registry/api/errcode
|
||||||
github.com/docker/distribution/registry/api/v2
|
github.com/docker/distribution/registry/api/v2
|
||||||
github.com/docker/distribution/registry/client/auth/challenge
|
github.com/docker/distribution/registry/client/auth/challenge
|
||||||
# github.com/docker/docker v27.1.0+incompatible
|
# github.com/docker/docker v27.1.1+incompatible
|
||||||
## explicit
|
## explicit
|
||||||
github.com/docker/docker/api
|
github.com/docker/docker/api
|
||||||
github.com/docker/docker/api/types
|
github.com/docker/docker/api/types
|
||||||
|
@ -526,7 +527,7 @@ github.com/felixge/httpsnoop
|
||||||
# github.com/fsnotify/fsnotify v1.7.0
|
# github.com/fsnotify/fsnotify v1.7.0
|
||||||
## explicit; go 1.17
|
## explicit; go 1.17
|
||||||
github.com/fsnotify/fsnotify
|
github.com/fsnotify/fsnotify
|
||||||
# github.com/fsouza/go-dockerclient v1.11.0
|
# github.com/fsouza/go-dockerclient v1.11.1
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
github.com/fsouza/go-dockerclient
|
github.com/fsouza/go-dockerclient
|
||||||
# github.com/gabriel-vasile/mimetype v1.4.3
|
# github.com/gabriel-vasile/mimetype v1.4.3
|
||||||
|
@ -907,7 +908,7 @@ github.com/opencontainers/runtime-tools/validate/capabilities
|
||||||
github.com/opencontainers/selinux/go-selinux
|
github.com/opencontainers/selinux/go-selinux
|
||||||
github.com/opencontainers/selinux/go-selinux/label
|
github.com/opencontainers/selinux/go-selinux/label
|
||||||
github.com/opencontainers/selinux/pkg/pwalkdir
|
github.com/opencontainers/selinux/pkg/pwalkdir
|
||||||
# github.com/openshift/imagebuilder v1.2.11
|
# github.com/openshift/imagebuilder v1.2.14
|
||||||
## explicit; go 1.19
|
## explicit; go 1.19
|
||||||
github.com/openshift/imagebuilder
|
github.com/openshift/imagebuilder
|
||||||
github.com/openshift/imagebuilder/dockerfile/command
|
github.com/openshift/imagebuilder/dockerfile/command
|
||||||
|
|
Loading…
Reference in New Issue