Bump github.com/containers/common from 0.6.1 to 0.8.0

Bumps [github.com/containers/common](https://github.com/containers/common) from 0.6.1 to 0.8.0.
- [Release notes](https://github.com/containers/common/releases)
- [Commits](https://github.com/containers/common/compare/v0.6.1...v0.8.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
dependabot-preview[bot]
2020-04-02 08:37:42 +00:00
committed by Daniel J Walsh
parent ccb9e579c4
commit eb86bfc344
62 changed files with 2186 additions and 248 deletions

6
go.mod
View File

@ -9,12 +9,12 @@ require (
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect
github.com/containernetworking/cni v0.7.2-0.20200304161608-4fae32b84921 github.com/containernetworking/cni v0.7.2-0.20200304161608-4fae32b84921
github.com/containernetworking/plugins v0.8.5 github.com/containernetworking/plugins v0.8.5
github.com/containers/buildah v1.14.5 github.com/containers/buildah v1.14.6-0.20200402210551-e9a6703edee2
github.com/containers/common v0.6.1 github.com/containers/common v0.8.0
github.com/containers/conmon v2.0.14+incompatible github.com/containers/conmon v2.0.14+incompatible
github.com/containers/image/v5 v5.3.1 github.com/containers/image/v5 v5.3.1
github.com/containers/psgo v1.4.0 github.com/containers/psgo v1.4.0
github.com/containers/storage v1.16.6 github.com/containers/storage v1.18.1
github.com/coreos/go-systemd/v22 v22.0.0 github.com/coreos/go-systemd/v22 v22.0.0
github.com/cri-o/ocicni v0.1.1-0.20190920040751-deac903fd99b github.com/cri-o/ocicni v0.1.1-0.20190920040751-deac903fd99b
github.com/cyphar/filepath-securejoin v0.2.2 github.com/cyphar/filepath-securejoin v0.2.2

12
go.sum
View File

@ -64,8 +64,15 @@ github.com/containernetworking/plugins v0.8.5 h1:pCvEMrFf7yzJI8+/D/7jkvE96KD52b7
github.com/containernetworking/plugins v0.8.5/go.mod h1:UZ2539umj8djuRQmBxuazHeJbYrLV8BSBejkk+she6o= github.com/containernetworking/plugins v0.8.5/go.mod h1:UZ2539umj8djuRQmBxuazHeJbYrLV8BSBejkk+she6o=
github.com/containers/buildah v1.14.5 h1:0Q+UgkIG4gAgAEZCu+0Syu/fSKsM1EsrctwV8G299jo= github.com/containers/buildah v1.14.5 h1:0Q+UgkIG4gAgAEZCu+0Syu/fSKsM1EsrctwV8G299jo=
github.com/containers/buildah v1.14.5/go.mod h1:2rfICEnpTtrMhWF6FZLnAL1Bh7SNmjhiKrjuIo0ZuN8= github.com/containers/buildah v1.14.5/go.mod h1:2rfICEnpTtrMhWF6FZLnAL1Bh7SNmjhiKrjuIo0ZuN8=
github.com/containers/buildah v1.14.6-0.20200402210551-e9a6703edee2 h1:9WchHVTk/FuAHHMuClpAZqk8dxOsPi6i6Yw5ocLbZxk=
github.com/containers/buildah v1.14.6-0.20200402210551-e9a6703edee2/go.mod h1:auylD7PH2uPpE+a/FmgZmP/uC30pIbR3cNYMPSNHxXg=
github.com/containers/common v0.6.1 h1:z9VeVXYeOnNV99uNLp7zoE5KO1n0hqz1mdm5a6AiIrA= github.com/containers/common v0.6.1 h1:z9VeVXYeOnNV99uNLp7zoE5KO1n0hqz1mdm5a6AiIrA=
github.com/containers/common v0.6.1/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys= github.com/containers/common v0.6.1/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys=
github.com/containers/common v0.7.0/go.mod h1:UmhIdvSkhTR0hWR01AnuZGNufm80+A0s8isb05eTmz0=
github.com/containers/common v0.8.0 h1:C+wjkcmR4gooeKCXZpyjsHSFARm5AZRegflGz0x0MMw=
github.com/containers/common v0.8.0/go.mod h1:QJTx9+SvhHKP6e+p7Nxqc8oNnS5rSf0KVhxudIbDslU=
github.com/containers/common v1.0.0 h1:sZB48LzGP4bP1CmrkQIFUzdUVBysqRv3kWVk4+qbaVA=
github.com/containers/common v1.0.0/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys=
github.com/containers/conmon v2.0.14+incompatible h1:knU1O1QxXy5YxtjMQVKEyCajROaehizK9FHaICl+P5Y= github.com/containers/conmon v2.0.14+incompatible h1:knU1O1QxXy5YxtjMQVKEyCajROaehizK9FHaICl+P5Y=
github.com/containers/conmon v2.0.14+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I= github.com/containers/conmon v2.0.14+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.2.1/go.mod h1:TfhmLwH+v1/HBVPIWH7diLs8XwcOkP3c7t7JFgqaUEc= github.com/containers/image/v5 v5.2.1/go.mod h1:TfhmLwH+v1/HBVPIWH7diLs8XwcOkP3c7t7JFgqaUEc=
@ -82,6 +89,9 @@ github.com/containers/storage v1.16.0/go.mod h1:nqN09JSi1/RSI1UAUwDYXPRiGSlq5FPb
github.com/containers/storage v1.16.5/go.mod h1:SdysZeLKJOvfHYysUWg9OZUC3gdZWi5b2b7NC18VpPE= github.com/containers/storage v1.16.5/go.mod h1:SdysZeLKJOvfHYysUWg9OZUC3gdZWi5b2b7NC18VpPE=
github.com/containers/storage v1.16.6 h1:G/thPW/LVRwJpQvve1V4DQXVZpxzSltC2fzc3yTEdi8= github.com/containers/storage v1.16.6 h1:G/thPW/LVRwJpQvve1V4DQXVZpxzSltC2fzc3yTEdi8=
github.com/containers/storage v1.16.6/go.mod h1:Fws4I+U+C4DmJxDbBs1z9SKk50DzN4LtA+g1b+FmkTY= github.com/containers/storage v1.16.6/go.mod h1:Fws4I+U+C4DmJxDbBs1z9SKk50DzN4LtA+g1b+FmkTY=
github.com/containers/storage v1.18.0/go.mod h1:gbFeFybWhlVCk3buJ0sovNKs8MzWEBTrk8/sbJw8irQ=
github.com/containers/storage v1.18.1 h1:W134oYa8ALd78yo6DKiDp6n7EWXrc+fCnYmJi6o49vo=
github.com/containers/storage v1.18.1/go.mod h1:6NtCgnUeYsRlyZyrZ5qKkXYC560GRgvA7YrKRSAYSlo=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-iptables v0.4.5 h1:DpHb9vJrZQEFMcVLFKAAGMUVX0XoRC0ptCthinRYm38= github.com/coreos/go-iptables v0.4.5 h1:DpHb9vJrZQEFMcVLFKAAGMUVX0XoRC0ptCthinRYm38=
@ -345,6 +355,8 @@ github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316 h1:enQG2QUGwug4fR1yM
github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316/go.mod h1:dv+J0b/HWai0QnMVb37/H0v36klkLBi2TNpPeWDxX10= github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316/go.mod h1:dv+J0b/HWai0QnMVb37/H0v36klkLBi2TNpPeWDxX10=
github.com/openshift/imagebuilder v1.1.3 h1:8TiphsD2wboU7tygtGZ5ZBfCP9FH2ZtvEAli67V2PJ4= github.com/openshift/imagebuilder v1.1.3 h1:8TiphsD2wboU7tygtGZ5ZBfCP9FH2ZtvEAli67V2PJ4=
github.com/openshift/imagebuilder v1.1.3/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo= github.com/openshift/imagebuilder v1.1.3/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
github.com/openshift/imagebuilder v1.1.4 h1:LUg8aTjyXMtlDx6IbtvaqofFGZ6aYqe+VIeATE735LM=
github.com/openshift/imagebuilder v1.1.4/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 h1:TnbXhKzrTOyuvWrjI8W6pcoI9XPbLHFXCdN2dtUw7Rw= github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 h1:TnbXhKzrTOyuvWrjI8W6pcoI9XPbLHFXCdN2dtUw7Rw=

View File

@ -4,3 +4,4 @@ docs/buildah*.1
/build/ /build/
tests/tools/build tests/tools/build
Dockerfile* Dockerfile*
*.swp

View File

@ -2,6 +2,20 @@
# Changelog # Changelog
## v1.14.6 (2020-04-02)
bud.bats - cleanup, refactoring
vendor in latest containers/storage 1.18.0 and containers/common v0.7.0
Bump github.com/spf13/cobra from 0.0.6 to 0.0.7
Bump github.com/containers/storage from 1.16.5 to 1.17.0
Bump github.com/containers/image/v5 from 5.2.1 to 5.3.1
Fix Amazon install step
Bump back to v1.15.0-dev
Fix bud-build-arg-cache test
Make image history work correctly with new args handling
Don't add args to the RUN environment from the Builder
Update github.com/openshift/imagebuilder to v1.1.4
Add .swp files to .gitignore
## v1.14.5 (2020-03-26) ## v1.14.5 (2020-03-26)
revert #2246 FIPS mode change revert #2246 FIPS mode change
Bump back to v1.15.0-dev Bump back to v1.15.0-dev

View File

@ -27,7 +27,7 @@ const (
Package = "buildah" Package = "buildah"
// Version for the Package. Bump version in contrib/rpm/buildah.spec // Version for the Package. Bump version in contrib/rpm/buildah.spec
// too. // too.
Version = "1.14.5" Version = "1.15.0-dev"
// The value we use to identify what type of information, currently a // The value we use to identify what type of information, currently a
// serialized Builder structure, we are using as per-container state. // serialized Builder structure, we are using as per-container state.
// This should only be changed when we make incompatible changes to // This should only be changed when we make incompatible changes to

View File

@ -1,3 +1,17 @@
- Changelog for v1.14.6 (2020-04-02)
* bud.bats - cleanup, refactoring
* vendor in latest containers/storage 1.18.0 and containers/common v0.7.0
* Bump github.com/spf13/cobra from 0.0.6 to 0.0.7
* Bump github.com/containers/storage from 1.16.5 to 1.17.0
* Bump github.com/containers/image/v5 from 5.2.1 to 5.3.1
* Fix Amazon install step
* Bump back to v1.15.0-dev
* Fix bud-build-arg-cache test
* Make image history work correctly with new args handling
* Don't add args to the RUN environment from the Builder
* Update github.com/openshift/imagebuilder to v1.1.4
* Add .swp files to .gitignore
- Changelog for v1.14.5 (2020-03-26) - Changelog for v1.14.5 (2020-03-26)
* revert #2246 FIPS mode change * revert #2246 FIPS mode change
* Bump back to v1.15.0-dev * Bump back to v1.15.0-dev

View File

@ -20,10 +20,10 @@ import (
"github.com/containers/buildah/bind" "github.com/containers/buildah/bind"
"github.com/containers/buildah/util" "github.com/containers/buildah/util"
"github.com/containers/common/pkg/unshare"
"github.com/containers/storage/pkg/ioutils" "github.com/containers/storage/pkg/ioutils"
"github.com/containers/storage/pkg/mount" "github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/reexec" "github.com/containers/storage/pkg/reexec"
"github.com/containers/storage/pkg/unshare"
"github.com/opencontainers/runc/libcontainer/apparmor" "github.com/opencontainers/runc/libcontainer/apparmor"
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors" "github.com/pkg/errors"

View File

@ -10,12 +10,12 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/containers/common/pkg/unshare"
cp "github.com/containers/image/v5/copy" cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/docker" "github.com/containers/image/v5/docker"
"github.com/containers/image/v5/signature" "github.com/containers/image/v5/signature"
"github.com/containers/image/v5/types" "github.com/containers/image/v5/types"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/containers/storage/pkg/unshare"
"github.com/docker/distribution/registry/api/errcode" "github.com/docker/distribution/registry/api/errcode"
errcodev2 "github.com/docker/distribution/registry/api/v2" errcodev2 "github.com/docker/distribution/registry/api/v2"
multierror "github.com/hashicorp/go-multierror" multierror "github.com/hashicorp/go-multierror"

View File

@ -4,9 +4,9 @@ go 1.12
require ( require (
github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784
github.com/containers/common v0.6.1 github.com/containers/common v0.7.0
github.com/containers/image/v5 v5.2.1 github.com/containers/image/v5 v5.3.1
github.com/containers/storage v1.16.5 github.com/containers/storage v1.18.0
github.com/cyphar/filepath-securejoin v0.2.2 github.com/cyphar/filepath-securejoin v0.2.2
github.com/docker/distribution v2.7.1+incompatible github.com/docker/distribution v2.7.1+incompatible
github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-metrics v0.0.1 // indirect
@ -27,15 +27,15 @@ require (
github.com/opencontainers/runtime-tools v0.9.0 github.com/opencontainers/runtime-tools v0.9.0
github.com/opencontainers/selinux v1.4.0 github.com/opencontainers/selinux v1.4.0
github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316 github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316
github.com/openshift/imagebuilder v1.1.3 github.com/openshift/imagebuilder v1.1.4
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f
github.com/seccomp/libseccomp-golang v0.9.1 github.com/seccomp/libseccomp-golang v0.9.1
github.com/sirupsen/logrus v1.4.2 github.com/sirupsen/logrus v1.5.0
github.com/spf13/cobra v0.0.6 github.com/spf13/cobra v0.0.7
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.5.1 github.com/stretchr/testify v1.5.1
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975
golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2 golang.org/x/sys v0.0.0-20200217220822-9197077df867
) )

View File

@ -5,7 +5,6 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
github.com/Microsoft/hcsshim v0.8.7-0.20191101173118-65519b62243c/go.mod h1:7xhjOwRV2+0HXGmM0jxaEu+ZiXJFoVZOTfL/dmqbrD8= github.com/Microsoft/hcsshim v0.8.7-0.20191101173118-65519b62243c/go.mod h1:7xhjOwRV2+0HXGmM0jxaEu+ZiXJFoVZOTfL/dmqbrD8=
@ -47,20 +46,17 @@ github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDG
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 h1:rqUVLD8I859xRgUx/WMC3v7QAFqbLKZbs+0kqYboRJc= github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 h1:rqUVLD8I859xRgUx/WMC3v7QAFqbLKZbs+0kqYboRJc=
github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
github.com/containers/common v0.5.0 h1:ZAef7h3oO46PcbTyfooZf8XLHrYad+GkhSu3EhH6P24= github.com/containers/common v0.7.0 h1:wlcHuOa8CcsreCMd0BlvKUubIVzkLy8EMLtJ0JO+Y6I=
github.com/containers/common v0.5.0/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys= github.com/containers/common v0.7.0/go.mod h1:UmhIdvSkhTR0hWR01AnuZGNufm80+A0s8isb05eTmz0=
github.com/containers/common v0.6.1 h1:z9VeVXYeOnNV99uNLp7zoE5KO1n0hqz1mdm5a6AiIrA= github.com/containers/image/v5 v5.3.1 h1:AL0pR0d1ho3kLUAuBr+wnFlXuD3ChzKVljk0M8JBJHQ=
github.com/containers/common v0.6.1/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys= github.com/containers/image/v5 v5.3.1/go.mod h1:JnCfhbTIL9IxPPZm1JoQwiE0S9KET46M4OZySJsLylk=
github.com/containers/image/v5 v5.2.1 h1:rQR6QSUneWBoW1bTFpP9EJJTevQFv27YsKYQVJIzg+s=
github.com/containers/image/v5 v5.2.1/go.mod h1:TfhmLwH+v1/HBVPIWH7diLs8XwcOkP3c7t7JFgqaUEc=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v0.0.0-20190930154801-b87a4a69c741 h1:8tQkOcednLJtUcZgK7sPglscXtxvMOnFOa6wd09VWLM= github.com/containers/ocicrypt v0.0.0-20190930154801-b87a4a69c741 h1:8tQkOcednLJtUcZgK7sPglscXtxvMOnFOa6wd09VWLM=
github.com/containers/ocicrypt v0.0.0-20190930154801-b87a4a69c741/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= github.com/containers/ocicrypt v0.0.0-20190930154801-b87a4a69c741/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
github.com/containers/storage v1.15.8/go.mod h1:zhvjIIl/fR6wt/lgqQAC+xanHQ+8gUQ0GBVeXYN81qI= github.com/containers/storage v1.16.6/go.mod h1:Fws4I+U+C4DmJxDbBs1z9SKk50DzN4LtA+g1b+FmkTY=
github.com/containers/storage v1.16.0/go.mod h1:nqN09JSi1/RSI1UAUwDYXPRiGSlq5FPbNkN/xb0TfG0= github.com/containers/storage v1.18.0 h1:l0vqAJwhMvfg2VM8Kwcc92bMyBrsQIul+Rs88pd7c+A=
github.com/containers/storage v1.16.5 h1:eHeWEhUEWX3VMIG1Vn1rEjfRoLHUQev3cwtA5zd89wk= github.com/containers/storage v1.18.0/go.mod h1:gbFeFybWhlVCk3buJ0sovNKs8MzWEBTrk8/sbJw8irQ=
github.com/containers/storage v1.16.5/go.mod h1:SdysZeLKJOvfHYysUWg9OZUC3gdZWi5b2b7NC18VpPE=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@ -79,7 +75,6 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8
github.com/docker/distribution v0.0.0-20170817175659-5f6282db7d65/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v0.0.0-20170817175659-5f6282db7d65/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.0.0-20171019062838-86f080cff091/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v0.0.0-20180522102801-da99009bbb11/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v0.0.0-20180522102801-da99009bbb11/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23 h1:oqgGT9O61YAYvI41EBsLePOr+LE6roB0xY4gpkZuFSE= github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23 h1:oqgGT9O61YAYvI41EBsLePOr+LE6roB0xY4gpkZuFSE=
github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
@ -185,14 +180,10 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.10.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8= github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/pgzip v1.2.3 h1:Ce2to9wvs/cuJ2b86/CKQoTYr9VHfpanYosZ0UBJqdw=
github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.3/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/klauspost/pgzip v1.2.2 h1:8d4I0LDiieuGngsqlqOih9ker/NS0LX4V0i+EhiFWg0=
github.com/klauspost/pgzip v1.2.2/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@ -206,8 +197,6 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-shellwords v1.0.9/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw= github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw=
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
@ -255,16 +244,12 @@ github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7/go.m
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/runtime-tools v0.9.0 h1:FYgwVsKRI/H9hU32MJ/4MLOzXWodKK5zsQavY8NPMkU= github.com/opencontainers/runtime-tools v0.9.0 h1:FYgwVsKRI/H9hU32MJ/4MLOzXWodKK5zsQavY8NPMkU=
github.com/opencontainers/runtime-tools v0.9.0/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opencontainers/runtime-tools v0.9.0/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/selinux v1.3.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/opencontainers/selinux v1.3.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/opencontainers/selinux v1.4.0 h1:cpiX/2wWIju/6My60T6/z9CxNG7c8xTQyEmA9fChpUo= github.com/opencontainers/selinux v1.4.0 h1:cpiX/2wWIju/6My60T6/z9CxNG7c8xTQyEmA9fChpUo=
github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316 h1:enQG2QUGwug4fR1yM6hL0Fjzx6Km/exZY6RbSPwMu3o= github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316 h1:enQG2QUGwug4fR1yM6hL0Fjzx6Km/exZY6RbSPwMu3o=
github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316/go.mod h1:dv+J0b/HWai0QnMVb37/H0v36klkLBi2TNpPeWDxX10= github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316/go.mod h1:dv+J0b/HWai0QnMVb37/H0v36klkLBi2TNpPeWDxX10=
github.com/openshift/imagebuilder v1.1.2 h1:vCO8hZQR/4uzo+j0PceBH5aKFcvCDM43UzUGOYQN+Go= github.com/openshift/imagebuilder v1.1.4 h1:LUg8aTjyXMtlDx6IbtvaqofFGZ6aYqe+VIeATE735LM=
github.com/openshift/imagebuilder v1.1.2/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo= github.com/openshift/imagebuilder v1.1.4/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
github.com/openshift/imagebuilder v1.1.3 h1:8TiphsD2wboU7tygtGZ5ZBfCP9FH2ZtvEAli67V2PJ4=
github.com/openshift/imagebuilder v1.1.3/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 h1:TnbXhKzrTOyuvWrjI8W6pcoI9XPbLHFXCdN2dtUw7Rw= github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 h1:TnbXhKzrTOyuvWrjI8W6pcoI9XPbLHFXCdN2dtUw7Rw=
github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc= github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@ -308,14 +293,15 @@ github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvW
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs= github.com/spf13/cobra v0.0.7 h1:FfTH+vuMXOas8jmfb5/M7dzEYx7LpcLb7a0LPe34uOU=
github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
@ -338,14 +324,14 @@ github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmD
github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8= github.com/ulikunitz/xz v0.5.7 h1:YvTNdFzX6+W5m9msiYg/zpkSURPPtOlzbqYjrFn7Yt4=
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE= github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE=
github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g= github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g=
github.com/vbauerster/mpb/v4 v4.11.2 h1:ynkUoKzi65DZ1UsQPx7sgi/KN6G9f7br+Us2nKm35AM= github.com/vbauerster/mpb/v4 v4.12.2 h1:TsBs1nWRYF0m8cUH13pxNhOUqY6yKcOr2PeSYxp2L3I=
github.com/vbauerster/mpb/v4 v4.11.2/go.mod h1:jIuIRCltGJUnm6DCyPVkwjlLUk4nHTH+m4eD14CdFF0= github.com/vbauerster/mpb/v4 v4.12.2/go.mod h1:LVRGvMch8T4HQO3eg2pFPsACH9kO/O6fT/7vhGje3QE=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b h1:6cLsL+2FW6dRAdl5iMtHgRogVCff0QpRi9653YmdcJA= github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b h1:6cLsL+2FW6dRAdl5iMtHgRogVCff0QpRi9653YmdcJA=
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@ -357,7 +343,8 @@ github.com/xeipuuv/gojsonschema v0.0.0-20190816131739-be0936907f66/go.mod h1:anY
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg=
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@ -367,7 +354,7 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -418,11 +405,12 @@ golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2 h1:/J2nHFg1MTqaRLFO7M+J78ASNsJoz3r0cvHBPQ77fsE=
golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867 h1:JoRuNIf+rpHl+VhScRQQvzbHed86tKkqwPMV34T8myw=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=

View File

@ -93,7 +93,6 @@ type Executor struct {
blobDirectory string blobDirectory string
excludes []string excludes []string
unusedArgs map[string]struct{} unusedArgs map[string]struct{}
buildArgs map[string]string
capabilities []string capabilities []string
devices []configs.Device devices []configs.Device
signBy string signBy string
@ -179,7 +178,6 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod
rootfsMap: make(map[string]bool), rootfsMap: make(map[string]bool),
blobDirectory: options.BlobDirectory, blobDirectory: options.BlobDirectory,
unusedArgs: make(map[string]struct{}), unusedArgs: make(map[string]struct{}),
buildArgs: copyStringStringMap(options.Args),
capabilities: capabilities, capabilities: capabilities,
devices: devices, devices: devices,
signBy: options.SignBy, signBy: options.SignBy,
@ -232,25 +230,26 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod
// startStage creates a new stage executor that will be referenced whenever a // startStage creates a new stage executor that will be referenced whenever a
// COPY or ADD statement uses a --from=NAME flag. // COPY or ADD statement uses a --from=NAME flag.
func (b *Executor) startStage(name string, index, stages int, from, output string) *StageExecutor { func (b *Executor) startStage(stage *imagebuilder.Stage, stages int, from, output string) *StageExecutor {
if b.stages == nil { if b.stages == nil {
b.stages = make(map[string]*StageExecutor) b.stages = make(map[string]*StageExecutor)
} }
stage := &StageExecutor{ stageExec := &StageExecutor{
executor: b, executor: b,
index: index, index: stage.Position,
stages: stages, stages: stages,
name: name, name: stage.Name,
volumeCache: make(map[string]string), volumeCache: make(map[string]string),
volumeCacheInfo: make(map[string]os.FileInfo), volumeCacheInfo: make(map[string]os.FileInfo),
output: output, output: output,
stage: stage,
} }
b.stages[name] = stage b.stages[stage.Name] = stageExec
b.stages[from] = stage b.stages[from] = stageExec
if idx := strconv.Itoa(index); idx != name { if idx := strconv.Itoa(stage.Position); idx != stage.Name {
b.stages[idx] = stage b.stages[idx] = stageExec
} }
return stage return stageExec
} }
// resolveNameToImageRef creates a types.ImageReference for the output name in local storage // resolveNameToImageRef creates a types.ImageReference for the output name in local storage
@ -291,81 +290,6 @@ func (b *Executor) getImageHistory(ctx context.Context, imageID string) ([]v1.Hi
return oci.History, nil return oci.History, nil
} }
// getCreatedBy returns the command the image at node will be created by. If
// the passed-in CompositeDigester is not nil, it is assumed to have the digest
// information for the content if the node is ADD or COPY.
func (b *Executor) getCreatedBy(node *parser.Node, addedContentDigest string) string {
if node == nil {
return "/bin/sh"
}
switch strings.ToUpper(node.Value) {
case "RUN":
buildArgs := b.getBuildArgs()
if buildArgs != "" {
return "|" + strconv.Itoa(len(strings.Split(buildArgs, " "))) + " " + buildArgs + " /bin/sh -c " + node.Original[4:]
}
return "/bin/sh -c " + node.Original[4:]
case "ADD", "COPY":
destination := node
for destination.Next != nil {
destination = destination.Next
}
return "/bin/sh -c #(nop) " + strings.ToUpper(node.Value) + " " + addedContentDigest + " in " + destination.Value + " "
default:
return "/bin/sh -c #(nop) " + node.Original
}
}
// historyMatches returns true if a candidate history matches the history of our
// base image (if we have one), plus the current instruction.
// Used to verify whether a cache of the intermediate image exists and whether
// to run the build again.
func (b *Executor) historyMatches(baseHistory []v1.History, child *parser.Node, history []v1.History, addedContentDigest string) bool {
if len(baseHistory) >= len(history) {
return false
}
if len(history)-len(baseHistory) != 1 {
return false
}
for i := range baseHistory {
if baseHistory[i].CreatedBy != history[i].CreatedBy {
return false
}
if baseHistory[i].Comment != history[i].Comment {
return false
}
if baseHistory[i].Author != history[i].Author {
return false
}
if baseHistory[i].EmptyLayer != history[i].EmptyLayer {
return false
}
if baseHistory[i].Created != nil && history[i].Created == nil {
return false
}
if baseHistory[i].Created == nil && history[i].Created != nil {
return false
}
if baseHistory[i].Created != nil && history[i].Created != nil && *baseHistory[i].Created != *history[i].Created {
return false
}
}
return history[len(baseHistory)].CreatedBy == b.getCreatedBy(child, addedContentDigest)
}
// getBuildArgs returns a string of the build-args specified during the build process
// it excludes any build-args that were not used in the build process
func (b *Executor) getBuildArgs() string {
var buildArgs []string
for k, v := range b.buildArgs {
if _, ok := b.unusedArgs[k]; !ok {
buildArgs = append(buildArgs, k+"="+v)
}
}
sort.Strings(buildArgs)
return strings.Join(buildArgs, " ")
}
// Build takes care of the details of running Prepare/Execute/Commit/Delete // Build takes care of the details of running Prepare/Execute/Commit/Delete
// over each of the one or more parsed Dockerfiles and stages. // over each of the one or more parsed Dockerfiles and stages.
func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (imageID string, ref reference.Canonical, err error) { func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (imageID string, ref reference.Canonical, err error) {
@ -494,7 +418,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
output = b.output output = b.output
} }
stageExecutor := b.startStage(stage.Name, stage.Position, len(stages), base, output) stageExecutor := b.startStage(&stage, len(stages), base, output)
// If this a single-layer build, or if it's a multi-layered // If this a single-layer build, or if it's a multi-layered
// build and b.forceRmIntermediateCtrs is set, make sure we // build and b.forceRmIntermediateCtrs is set, make sure we
@ -505,7 +429,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
} }
// Build this stage. // Build this stage.
if imageID, ref, err = stageExecutor.Execute(ctx, stage, base); err != nil { if imageID, ref, err = stageExecutor.Execute(ctx, base); err != nil {
lastErr = err lastErr = err
} }
if lastErr != nil { if lastErr != nil {

View File

@ -6,6 +6,7 @@ import (
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"sort"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -56,6 +57,7 @@ type StageExecutor struct {
copyFrom string // Used to keep track of the --from flag from COPY and ADD copyFrom string // Used to keep track of the --from flag from COPY and ADD
output string output string
containerIDs []string containerIDs []string
stage *imagebuilder.Stage
} }
// 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
@ -579,7 +581,8 @@ func (s *StageExecutor) UnrecognizedInstruction(step *imagebuilder.Step) error {
// prepare creates a working container based on the specified image, or if one // prepare creates a working container based on the specified image, or if one
// isn't specified, the first argument passed to the first FROM instruction we // isn't specified, the first argument passed to the first FROM instruction we
// can find in the stage's parsed tree. // can find in the stage's parsed tree.
func (s *StageExecutor) prepare(ctx context.Context, stage imagebuilder.Stage, from string, initializeIBConfig, rebase bool) (builder *buildah.Builder, err error) { func (s *StageExecutor) prepare(ctx context.Context, from string, initializeIBConfig, rebase bool) (builder *buildah.Builder, err error) {
stage := s.stage
ib := stage.Builder ib := stage.Builder
node := stage.Node node := stage.Node
@ -732,11 +735,11 @@ func (*StageExecutor) stepRequiresLayer(step *imagebuilder.Step) bool {
// storage. If it isn't found, it pulls down a copy. Then, if we don't have a // storage. If it isn't found, it pulls down a copy. Then, if we don't have a
// working container root filesystem based on the image, it creates one. Then // working container root filesystem based on the image, it creates one. Then
// it returns that root filesystem's location. // it returns that root filesystem's location.
func (s *StageExecutor) getImageRootfs(ctx context.Context, stage imagebuilder.Stage, image string) (mountPoint string, err error) { func (s *StageExecutor) getImageRootfs(ctx context.Context, image string) (mountPoint string, err error) {
if builder, ok := s.executor.containerMap[image]; ok { if builder, ok := s.executor.containerMap[image]; ok {
return builder.MountPoint, nil return builder.MountPoint, nil
} }
builder, err := s.prepare(ctx, stage, image, false, false) builder, err := s.prepare(ctx, image, false, false)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -745,7 +748,8 @@ func (s *StageExecutor) getImageRootfs(ctx context.Context, stage imagebuilder.S
} }
// Execute runs each of the steps in the stage's parsed tree, in turn. // Execute runs each of the steps in the stage's parsed tree, in turn.
func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, base string) (imgID string, ref reference.Canonical, err error) { func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, ref reference.Canonical, err error) {
stage := s.stage
ib := stage.Builder ib := stage.Builder
checkForLayers := s.executor.layers && s.executor.useCache checkForLayers := s.executor.layers && s.executor.useCache
moreStages := s.index < s.stages-1 moreStages := s.index < s.stages-1
@ -765,7 +769,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
// Create the (first) working container for this stage. Reinitializing // Create the (first) working container for this stage. Reinitializing
// the imagebuilder configuration may alter the list of steps we have, // the imagebuilder configuration may alter the list of steps we have,
// so take a snapshot of them *after* that. // so take a snapshot of them *after* that.
if _, err := s.prepare(ctx, stage, base, true, true); err != nil { if _, err := s.prepare(ctx, base, true, true); err != nil {
return "", nil, err return "", nil, err
} }
children := stage.Node.Children children := stage.Node.Children
@ -809,14 +813,14 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
// squash the contents of the base image. Whichever is // squash the contents of the base image. Whichever is
// the case, we need to commit() to create a new image. // the case, we need to commit() to create a new image.
logCommit(s.output, -1) logCommit(s.output, -1)
if imgID, ref, err = s.commit(ctx, ib, s.executor.getCreatedBy(nil, ""), false, s.output); err != nil { if imgID, ref, err = s.commit(ctx, s.getCreatedBy(nil, ""), false, s.output); err != nil {
return "", nil, errors.Wrapf(err, "error committing base container") return "", nil, errors.Wrapf(err, "error committing base container")
} }
} else if len(s.executor.labels) > 0 || len(s.executor.annotations) > 0 { } else if len(s.executor.labels) > 0 || len(s.executor.annotations) > 0 {
// The image would be modified by the labels passed // The image would be modified by the labels passed
// via the command line, so we need to commit. // via the command line, so we need to commit.
logCommit(s.output, -1) logCommit(s.output, -1)
if imgID, ref, err = s.commit(ctx, ib, s.executor.getCreatedBy(stage.Node, ""), true, s.output); err != nil { if imgID, ref, err = s.commit(ctx, s.getCreatedBy(stage.Node, ""), true, s.output); err != nil {
return "", nil, err return "", nil, err
} }
} else { } else {
@ -866,7 +870,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
} }
otherStage, ok := s.executor.stages[arr[1]] otherStage, ok := s.executor.stages[arr[1]]
if !ok { if !ok {
if mountPoint, err = s.getImageRootfs(ctx, stage, arr[1]); err != nil { if mountPoint, err = s.getImageRootfs(ctx, arr[1]); err != nil {
return "", nil, errors.Errorf("%s --from=%s: no stage or image found with that name", command, arr[1]) return "", nil, errors.Errorf("%s --from=%s: no stage or image found with that name", command, arr[1])
} }
} else { } else {
@ -905,7 +909,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
// instruction in the history that we'll write // instruction in the history that we'll write
// for the image when we eventually commit it. // for the image when we eventually commit it.
now := time.Now() now := time.Now()
s.builder.AddPrependedEmptyLayer(&now, s.executor.getCreatedBy(node, addedContentDigest), "", "") s.builder.AddPrependedEmptyLayer(&now, s.getCreatedBy(node, addedContentDigest), "", "")
continue continue
} else { } else {
// This is the last instruction for this stage, // This is the last instruction for this stage,
@ -914,7 +918,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
// if it's used as the basis for a later stage. // if it's used as the basis for a later stage.
if lastStage || imageIsUsedLater { if lastStage || imageIsUsedLater {
logCommit(s.output, i) logCommit(s.output, i)
imgID, ref, err = s.commit(ctx, ib, s.executor.getCreatedBy(node, addedContentDigest), false, s.output) imgID, ref, err = s.commit(ctx, s.getCreatedBy(node, addedContentDigest), false, s.output)
if err != nil { if err != nil {
return "", nil, errors.Wrapf(err, "error committing container for step %+v", *step) return "", nil, errors.Wrapf(err, "error committing container for step %+v", *step)
} }
@ -1008,7 +1012,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
} }
// Create a new image, maybe with a new layer. // Create a new image, maybe with a new layer.
logCommit(s.output, i) logCommit(s.output, i)
imgID, ref, err = s.commit(ctx, ib, s.executor.getCreatedBy(node, addedContentDigest), !s.stepRequiresLayer(step), commitName) imgID, ref, err = s.commit(ctx, s.getCreatedBy(node, addedContentDigest), !s.stepRequiresLayer(step), commitName)
if err != nil { if err != nil {
return "", nil, errors.Wrapf(err, "error committing container for step %+v", *step) return "", nil, errors.Wrapf(err, "error committing container for step %+v", *step)
} }
@ -1034,7 +1038,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
// creating a new working container with the // creating a new working container with the
// just-committed or updated cached image as its new // just-committed or updated cached image as its new
// base image. // base image.
if _, err := s.prepare(ctx, stage, imgID, false, true); err != nil { if _, err := s.prepare(ctx, imgID, false, true); err != nil {
return "", nil, errors.Wrap(err, "error preparing container for next step") return "", nil, errors.Wrap(err, "error preparing container for next step")
} }
} }
@ -1042,6 +1046,76 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
return imgID, ref, nil return imgID, ref, nil
} }
// historyMatches returns true if a candidate history matches the history of our
// base image (if we have one), plus the current instruction.
// Used to verify whether a cache of the intermediate image exists and whether
// to run the build again.
func (s *StageExecutor) historyMatches(baseHistory []v1.History, child *parser.Node, history []v1.History, addedContentDigest string) bool {
if len(baseHistory) >= len(history) {
return false
}
if len(history)-len(baseHistory) != 1 {
return false
}
for i := range baseHistory {
if baseHistory[i].CreatedBy != history[i].CreatedBy {
return false
}
if baseHistory[i].Comment != history[i].Comment {
return false
}
if baseHistory[i].Author != history[i].Author {
return false
}
if baseHistory[i].EmptyLayer != history[i].EmptyLayer {
return false
}
if baseHistory[i].Created != nil && history[i].Created == nil {
return false
}
if baseHistory[i].Created == nil && history[i].Created != nil {
return false
}
if baseHistory[i].Created != nil && history[i].Created != nil && *baseHistory[i].Created != *history[i].Created {
return false
}
}
return history[len(baseHistory)].CreatedBy == s.getCreatedBy(child, addedContentDigest)
}
// getCreatedBy returns the command the image at node will be created by. If
// the passed-in CompositeDigester is not nil, it is assumed to have the digest
// information for the content if the node is ADD or COPY.
func (s *StageExecutor) getCreatedBy(node *parser.Node, addedContentDigest string) string {
if node == nil {
return "/bin/sh"
}
switch strings.ToUpper(node.Value) {
case "RUN":
buildArgs := s.getBuildArgs()
if buildArgs != "" {
return "|" + strconv.Itoa(len(strings.Split(buildArgs, " "))) + " " + buildArgs + " /bin/sh -c " + node.Original[4:]
}
return "/bin/sh -c " + node.Original[4:]
case "ADD", "COPY":
destination := node
for destination.Next != nil {
destination = destination.Next
}
return "/bin/sh -c #(nop) " + strings.ToUpper(node.Value) + " " + addedContentDigest + " in " + destination.Value + " "
default:
return "/bin/sh -c #(nop) " + node.Original
}
}
// getBuildArgs returns a string of the build-args specified during the build process
// it excludes any build-args that were not used in the build process
func (s *StageExecutor) getBuildArgs() string {
buildArgs := s.stage.Builder.Arguments()
sort.Strings(buildArgs)
return strings.Join(buildArgs, " ")
}
// tagExistingImage adds names to an image already in the store // tagExistingImage adds names to an image already in the store
func (s *StageExecutor) tagExistingImage(ctx context.Context, cacheID, output string) (string, reference.Canonical, error) { func (s *StageExecutor) tagExistingImage(ctx context.Context, cacheID, output string) (string, reference.Canonical, error) {
// If we don't need to attach a name to the image, just return the cache ID. // If we don't need to attach a name to the image, just return the cache ID.
@ -1128,7 +1202,7 @@ func (s *StageExecutor) intermediateImageExists(ctx context.Context, currNode *p
return "", errors.Wrapf(err, "error getting history of %q", image.ID) return "", errors.Wrapf(err, "error getting history of %q", image.ID)
} }
// children + currNode is the point of the Dockerfile we are currently at. // children + currNode is the point of the Dockerfile we are currently at.
if s.executor.historyMatches(baseHistory, currNode, history, addedContentDigest) { if s.historyMatches(baseHistory, currNode, history, addedContentDigest) {
return image.ID, nil return image.ID, nil
} }
} }
@ -1138,7 +1212,8 @@ func (s *StageExecutor) intermediateImageExists(ctx context.Context, currNode *p
// commit writes the container's contents to an image, using a passed-in tag as // commit writes the container's contents to an image, using a passed-in tag as
// the name if there is one, generating a unique ID-based one otherwise. // the name if there is one, generating a unique ID-based one otherwise.
func (s *StageExecutor) commit(ctx context.Context, ib *imagebuilder.Builder, createdBy string, emptyLayer bool, output string) (string, reference.Canonical, error) { func (s *StageExecutor) commit(ctx context.Context, createdBy string, emptyLayer bool, output string) (string, reference.Canonical, error) {
ib := s.stage.Builder
var imageRef types.ImageReference var imageRef types.ImageReference
if output != "" { if output != "" {
imageRef2, err := s.executor.resolveNameToImageRef(output) imageRef2, err := s.executor.resolveNameToImageRef(output)

View File

@ -166,11 +166,3 @@ func convertMounts(mounts []Mount) []specs.Mount {
} }
return specmounts return specmounts
} }
func copyStringStringMap(m map[string]string) map[string]string {
n := map[string]string{}
for k, v := range m {
n[k] = v
}
return n
}

View File

@ -12,9 +12,9 @@ import (
"time" "time"
"github.com/containers/buildah/util" "github.com/containers/buildah/util"
"github.com/containers/common/pkg/unshare"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/containers/storage/pkg/system" "github.com/containers/storage/pkg/system"
"github.com/containers/storage/pkg/unshare"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )

View File

@ -12,7 +12,7 @@ provides updated packages for CentOS 7 which can be used unmodified on Amazon Li
```bash ```bash
cd /etc/yum.repos.d/ cd /etc/yum.repos.d/
sudo wget https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_7/devel:kubic:libcontainers:stable.repo sudo wget https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_7/devel:kubic:libcontainers:stable.repo
sudo yum -y yum-plugin-copr sudo yum -y install yum-plugin-copr
sudo yum -y copr enable lsm5/container-selinux sudo yum -y copr enable lsm5/container-selinux
sudo yum -y install buildah sudo yum -y install buildah
``` ```

View File

@ -8,9 +8,9 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/containers/common/pkg/unshare"
"github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/system" "github.com/containers/storage/pkg/system"
"github.com/containers/storage/pkg/unshare"
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"

View File

@ -6,7 +6,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/containers/common/pkg/unshare" "github.com/containers/storage/pkg/unshare"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/devices" "github.com/opencontainers/runc/libcontainer/devices"
"github.com/pkg/errors" "github.com/pkg/errors"

View File

@ -28,11 +28,11 @@ import (
"github.com/containers/buildah/util" "github.com/containers/buildah/util"
"github.com/containers/common/pkg/capabilities" "github.com/containers/common/pkg/capabilities"
"github.com/containers/common/pkg/config" "github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/unshare"
"github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/ioutils" "github.com/containers/storage/pkg/ioutils"
"github.com/containers/storage/pkg/reexec" "github.com/containers/storage/pkg/reexec"
"github.com/containers/storage/pkg/stringid" "github.com/containers/storage/pkg/stringid"
"github.com/containers/storage/pkg/unshare"
"github.com/docker/go-units" "github.com/docker/go-units"
"github.com/docker/libnetwork/resolvconf" "github.com/docker/libnetwork/resolvconf"
"github.com/docker/libnetwork/types" "github.com/docker/libnetwork/types"
@ -1972,10 +1972,6 @@ func (b *Builder) configureEnvironment(g *generate.Generator, options RunOptions
g.AddProcessEnv(env[0], env[1]) g.AddProcessEnv(env[0], env[1])
} }
} }
for src, dest := range b.Args {
g.AddProcessEnv(src, dest)
}
} }
func setupRootlessSpecChanges(spec *specs.Spec, bundleDir string, shmSize string) error { func setupRootlessSpecChanges(spec *specs.Spec, bundleDir string, shmSize string) error {

View File

@ -0,0 +1,21 @@
package apparmor
import (
"errors"
)
const (
// ProfilePrefix is used for version-independent presence checks.
ProfilePrefix = "apparmor_profile"
// Profile default name
Profile = "container-default"
)
var (
// ErrApparmorUnsupported indicates that AppArmor support is not supported.
ErrApparmorUnsupported = errors.New("AppArmor is not supported")
// ErrApparmorRootless indicates that AppArmor support is not supported in rootless mode.
ErrApparmorRootless = errors.New("AppArmor is not supported in rootless mode")
)

View File

@ -0,0 +1,289 @@
// +build linux,apparmor
package apparmor
import (
"bufio"
"bytes"
"fmt"
"io"
"os"
"os/exec"
"path"
"strconv"
"strings"
"text/template"
"github.com/containers/storage/pkg/unshare"
runcaa "github.com/opencontainers/runc/libcontainer/apparmor"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// profileDirectory is the file store for apparmor profiles and macros.
var profileDirectory = "/etc/apparmor.d"
// IsEnabled returns true if AppArmor is enabled on the host.
func IsEnabled() bool {
if unshare.IsRootless() {
return false
}
return runcaa.IsEnabled()
}
// profileData holds information about the given profile for generation.
type profileData struct {
// Name is profile name.
Name string
// Imports defines the apparmor functions to import, before defining the profile.
Imports []string
// InnerImports defines the apparmor functions to import in the profile.
InnerImports []string
// Version is the {major, minor, patch} version of apparmor_parser as a single number.
Version int
}
// generateDefault creates an apparmor profile from ProfileData.
func (p *profileData) generateDefault(out io.Writer) error {
compiled, err := template.New("apparmor_profile").Parse(defaultProfileTemplate)
if err != nil {
return err
}
if macroExists("tunables/global") {
p.Imports = append(p.Imports, "#include <tunables/global>")
} else {
p.Imports = append(p.Imports, "@{PROC}=/proc/")
}
if macroExists("abstractions/base") {
p.InnerImports = append(p.InnerImports, "#include <abstractions/base>")
}
ver, err := getAAParserVersion()
if err != nil {
return err
}
p.Version = ver
return compiled.Execute(out, p)
}
// macrosExists checks if the passed macro exists.
func macroExists(m string) bool {
_, err := os.Stat(path.Join(profileDirectory, m))
return err == nil
}
// InstallDefault generates a default profile and loads it into the kernel
// using 'apparmor_parser'.
func InstallDefault(name string) error {
if unshare.IsRootless() {
return ErrApparmorRootless
}
p := profileData{
Name: name,
}
cmd := exec.Command("apparmor_parser", "-Kr")
pipe, err := cmd.StdinPipe()
if err != nil {
return err
}
if err := cmd.Start(); err != nil {
if pipeErr := pipe.Close(); pipeErr != nil {
logrus.Errorf("unable to close apparmor pipe: %q", pipeErr)
}
return err
}
if err := p.generateDefault(pipe); err != nil {
if pipeErr := pipe.Close(); pipeErr != nil {
logrus.Errorf("unable to close apparmor pipe: %q", pipeErr)
}
if cmdErr := cmd.Wait(); cmdErr != nil {
logrus.Errorf("unable to wait for apparmor command: %q", cmdErr)
}
return err
}
if pipeErr := pipe.Close(); pipeErr != nil {
logrus.Errorf("unable to close apparmor pipe: %q", pipeErr)
}
return cmd.Wait()
}
// DefaultContent returns the default profile content as byte slice. The
// profile is named as the provided `name`. The function errors if the profile
// generation fails.
func DefaultContent(name string) ([]byte, error) {
p := profileData{Name: name}
var bytes bytes.Buffer
if err := p.generateDefault(&bytes); err != nil {
return nil, err
}
return bytes.Bytes(), nil
}
// IsLoaded checks if a profile with the given name has been loaded into the
// kernel.
func IsLoaded(name string) (bool, error) {
if name != "" && unshare.IsRootless() {
return false, errors.Wrapf(ErrApparmorRootless, "cannot load AppArmor profile %q", name)
}
file, err := os.Open("/sys/kernel/security/apparmor/profiles")
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
defer file.Close()
r := bufio.NewReader(file)
for {
p, err := r.ReadString('\n')
if err == io.EOF {
break
}
if err != nil {
return false, err
}
if strings.HasPrefix(p, name+" ") {
return true, nil
}
}
return false, nil
}
// execAAParser runs `apparmor_parser` with the passed arguments.
func execAAParser(dir string, args ...string) (string, error) {
c := exec.Command("apparmor_parser", args...)
c.Dir = dir
output, err := c.CombinedOutput()
if err != nil {
return "", fmt.Errorf("running `%s %s` failed with output: %s\nerror: %v", c.Path, strings.Join(c.Args, " "), output, err)
}
return string(output), nil
}
// getAAParserVersion returns the major and minor version of apparmor_parser.
func getAAParserVersion() (int, error) {
output, err := execAAParser("", "--version")
if err != nil {
return -1, err
}
return parseAAParserVersion(output)
}
// parseAAParserVersion parses the given `apparmor_parser --version` output and
// returns the major and minor version number as an integer.
func parseAAParserVersion(output string) (int, error) {
// output is in the form of the following:
// AppArmor parser version 2.9.1
// Copyright (C) 1999-2008 Novell Inc.
// Copyright 2009-2012 Canonical Ltd.
lines := strings.SplitN(output, "\n", 2)
words := strings.Split(lines[0], " ")
version := words[len(words)-1]
// split by major minor version
v := strings.Split(version, ".")
if len(v) == 0 || len(v) > 3 {
return -1, fmt.Errorf("parsing version failed for output: `%s`", output)
}
// Default the versions to 0.
var majorVersion, minorVersion, patchLevel int
majorVersion, err := strconv.Atoi(v[0])
if err != nil {
return -1, err
}
if len(v) > 1 {
minorVersion, err = strconv.Atoi(v[1])
if err != nil {
return -1, err
}
}
if len(v) > 2 {
patchLevel, err = strconv.Atoi(v[2])
if err != nil {
return -1, err
}
}
// major*10^5 + minor*10^3 + patch*10^0
numericVersion := majorVersion*1e5 + minorVersion*1e3 + patchLevel
return numericVersion, nil
}
// CheckProfileAndLoadDefault checks if the specified profile is loaded and
// loads the DefaultLibpodProfile if the specified on is prefixed by
// DefaultLipodProfilePrefix. This allows to always load and apply the latest
// default AppArmor profile. Note that AppArmor requires root. If it's a
// default profile, return DefaultLipodProfilePrefix, otherwise the specified
// one.
func CheckProfileAndLoadDefault(name string) (string, error) {
if name == "unconfined" {
return name, nil
}
// AppArmor is not supported in rootless mode as it requires root
// privileges. Return an error in case a specific profile is specified.
if unshare.IsRootless() {
if name != "" {
return "", errors.Wrapf(ErrApparmorRootless, "cannot load AppArmor profile %q", name)
} else {
logrus.Debug("skipping loading default AppArmor profile (rootless mode)")
return "", nil
}
}
// Check if AppArmor is disabled and error out if a profile is to be set.
if !runcaa.IsEnabled() {
if name == "" {
return "", nil
} else {
return "", fmt.Errorf("profile %q specified but AppArmor is disabled on the host", name)
}
}
// If the specified name is not empty or is not a default libpod one,
// ignore it and return the name.
if name != "" && !strings.HasPrefix(name, ProfilePrefix) {
isLoaded, err := IsLoaded(name)
if err != nil {
return "", err
}
if !isLoaded {
return "", fmt.Errorf("AppArmor profile %q specified but not loaded", name)
}
return name, nil
}
name = Profile
// To avoid expensive redundant loads on each invocation, check
// if it's loaded before installing it.
isLoaded, err := IsLoaded(name)
if err != nil {
return "", err
}
if !isLoaded {
err = InstallDefault(name)
if err != nil {
return "", err
}
logrus.Infof("successfully loaded AppAmor profile %q", name)
} else {
logrus.Infof("AppAmor profile %q is already loaded", name)
}
return name, nil
}

View File

@ -0,0 +1,49 @@
// +build linux,apparmor
package apparmor
const defaultProfileTemplate = `
{{range $value := .Imports}}
{{$value}}
{{end}}
profile {{.Name}} flags=(attach_disconnected,mediate_deleted) {
{{range $value := .InnerImports}}
{{$value}}
{{end}}
network,
capability,
file,
umount,
{{if ge .Version 208096}}
# Allow signals from privileged profiles and from within the same profile
signal (receive) peer=unconfined,
signal (send,receive) peer={{.Name}},
{{end}}
deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir)
# deny write to files not in /proc/<number>/** or /proc/sys/**
deny @{PROC}/{[^1-9],[^1-9][^0-9],[^1-9s][^0-9y][^0-9s],[^1-9][^0-9][^0-9][^0-9]*}/** w,
deny @{PROC}/sys/[^k]** w, # deny /proc/sys except /proc/sys/k* (effectively /proc/sys/kernel)
deny @{PROC}/sys/kernel/{?,??,[^s][^h][^m]**} w, # deny everything except shm* in /proc/sys/kernel/
deny @{PROC}/sysrq-trigger rwklx,
deny @{PROC}/kcore rwklx,
deny mount,
deny /sys/[^f]*/** wklx,
deny /sys/f[^s]*/** wklx,
deny /sys/fs/[^c]*/** wklx,
deny /sys/fs/c[^g]*/** wklx,
deny /sys/fs/cg[^r]*/** wklx,
deny /sys/firmware/** rwklx,
deny /sys/kernel/security/** rwklx,
{{if ge .Version 208095}}
# suppress ptrace denials when using using 'ps' inside a container
ptrace (trace,read) peer={{.Name}},
{{end}}
}
`

View File

@ -0,0 +1,31 @@
// +build !linux !apparmor
package apparmor
// IsEnabled dummy.
func IsEnabled() bool {
return false
}
// InstallDefault dummy.
func InstallDefault(name string) error {
return ErrApparmorUnsupported
}
// IsLoaded dummy.
func IsLoaded(name string) (bool, error) {
return false, ErrApparmorUnsupported
}
// CheckProfileAndLoadDefault dummy.
func CheckProfileAndLoadDefault(name string) (string, error) {
if name == "" {
return "", nil
}
return "", ErrApparmorUnsupported
}
// DefaultContent dummy.
func DefaultContent(name string) ([]byte, error) {
return nil, nil
}

View File

@ -99,6 +99,10 @@ func MergeCapabilities(base, adds, drops []string) ([]string, error) {
return base, nil return base, nil
} }
base, err := normalizeCapabilities(base)
if err != nil {
return nil, err
}
capDrop, err := normalizeCapabilities(drops) capDrop, err := normalizeCapabilities(drops)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -0,0 +1,27 @@
package cgroupv2
import (
"sync"
"syscall"
"golang.org/x/sys/unix"
)
var (
isCgroupV2Once sync.Once
isCgroupV2 bool
isCgroupV2Err error
)
// Enabled returns whether we are running in cgroup 2 cgroup2 mode.
func Enabled() (bool, error) {
isCgroupV2Once.Do(func() {
var st syscall.Statfs_t
if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil {
isCgroupV2, isCgroupV2Err = false, err
} else {
isCgroupV2, isCgroupV2Err = st.Type == unix.CGROUP2_SUPER_MAGIC, nil
}
})
return isCgroupV2, isCgroupV2Err
}

View File

@ -0,0 +1,8 @@
// +build !linux
package cgroupv2
// Enabled returns whether we are running in cgroup 2 cgroup2 mode.
func Enabled() (bool, error) {
return false, nil
}

View File

@ -11,7 +11,7 @@ import (
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
"github.com/containers/common/pkg/capabilities" "github.com/containers/common/pkg/capabilities"
"github.com/containers/common/pkg/unshare" "github.com/containers/storage/pkg/unshare"
units "github.com/docker/go-units" units "github.com/docker/go-units"
selinux "github.com/opencontainers/selinux/go-selinux" selinux "github.com/opencontainers/selinux/go-selinux"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -173,7 +173,7 @@ type ContainersConfig struct {
// EngineConfig contains configuration options used to set up a engine runtime // EngineConfig contains configuration options used to set up a engine runtime
type EngineConfig struct { type EngineConfig struct {
// CgroupCheck indicates the configuration has been rewritten after an // CgroupCheck indicates the configuration has been rewritten after an
// upgrade to Fedora 31 to change the default OCI runtime for cgroupsv2. // upgrade to Fedora 31 to change the default OCI runtime for cgroupv2v2.
CgroupCheck bool `toml:"cgroup_check,omitempty"` CgroupCheck bool `toml:"cgroup_check,omitempty"`
// CGroupManager is the CGroup Manager to use Valid values are "cgroupfs" // CGroupManager is the CGroup Manager to use Valid values are "cgroupfs"
@ -269,7 +269,7 @@ type EngineConfig struct {
// RuntimeSupportsNoCgroups is a list of OCI runtimes that support // RuntimeSupportsNoCgroups is a list of OCI runtimes that support
// running containers without CGroups. // running containers without CGroups.
RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroups"` RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroupv2"`
// SetOptions contains a subset of config options. It's used to indicate if // SetOptions contains a subset of config options. It's used to indicate if
// a given option has either been set by the user or by the parsed // a given option has either been set by the user or by the parsed
@ -373,7 +373,7 @@ type NetworkConfig struct {
// running as root or rootless, we then merge the system configuration followed // running as root or rootless, we then merge the system configuration followed
// by merging the default config (hard-coded default in memory). // by merging the default config (hard-coded default in memory).
// Note that the OCI runtime is hard-set to `crun` if we're running on a system // Note that the OCI runtime is hard-set to `crun` if we're running on a system
// with cgroupsv2. Other OCI runtimes are not yet supporting cgroupsv2. This // with cgroupv2v2. Other OCI runtimes are not yet supporting cgroupv2v2. This
// might change in the future. // might change in the future.
func NewConfig(userConfigPath string) (*Config, error) { func NewConfig(userConfigPath string) (*Config, error) {
@ -494,7 +494,7 @@ func (c *Config) CheckCgroupsAndAdjustConfig() {
} }
if !hasSession { if !hasSession {
logrus.Warningf("The cgroups manager is set to systemd but there is no systemd user session available") logrus.Warningf("The cgroupv2 manager is set to systemd but there is no systemd user session available")
logrus.Warningf("For using systemd, you may need to login using an user session") logrus.Warningf("For using systemd, you may need to login using an user session")
logrus.Warningf("Alternatively, you can enable lingering with: `loginctl enable-linger %d` (possibly as root)", unshare.GetRootlessUID()) logrus.Warningf("Alternatively, you can enable lingering with: `loginctl enable-linger %d` (possibly as root)", unshare.GetRootlessUID())
logrus.Warningf("Falling back to --cgroup-manager=cgroupfs") logrus.Warningf("Falling back to --cgroup-manager=cgroupfs")
@ -806,9 +806,35 @@ func IsValidDeviceMode(mode string) bool {
return true return true
} }
// resolveHomeDir converts a path referencing the home directory via "~"
// to an absolute path
func resolveHomeDir(path string) (string, error) {
// check if the path references the home dir to avoid work
// don't use strings.HasPrefix(path, "~") as this doesn't match "~" alone
// use strings.HasPrefix(...) to not match "something/~/something"
if !(path == "~" || strings.HasPrefix(path, "~/")) {
// path does not reference home dir -> Nothing to do
return path, nil
}
// only get HomeDir when necessary
home, err := unshare.HomeDir()
if err != nil {
return "", err
}
// replace the first "~" (start of path) with the HomeDir to resolve "~"
return strings.Replace(path, "~", home, 1), nil
}
// isDirectory tests whether the given path exists and is a directory. It // isDirectory tests whether the given path exists and is a directory. It
// follows symlinks. // follows symlinks.
func isDirectory(path string) error { func isDirectory(path string) error {
path, err := resolveHomeDir(path)
if err != nil {
return err
}
info, err := os.Stat(path) info, err := os.Stat(path)
if err != nil { if err != nil {
return err return err

View File

@ -288,7 +288,7 @@
# associated with the pod. This container does nothing other then sleep, # associated with the pod. This container does nothing other then sleep,
# reserving the pods resources for the lifetime of the pod. # reserving the pods resources for the lifetime of the pod.
# #
# infra_image = "k8s.gcr.io/pause:3.1" # infra_image = "k8s.gcr.io/pause:3.2"
# Specify the locking mechanism to use; valid values are "shm" and "file". # Specify the locking mechanism to use; valid values are "shm" and "file".
# Change the default only if you are sure of what you are doing, in general # Change the default only if you are sure of what you are doing, in general
@ -345,9 +345,9 @@
# List of the OCI runtimes that support --format=json. When json is supported # List of the OCI runtimes that support --format=json. When json is supported
# engine will use it for reporting nicer errors. # engine will use it for reporting nicer errors.
# #
# runtime_supports_json = ["crun", "runc"] # runtime_supports_json = ["crun", "runc", "kata"]
# Paths to look for a valid OCI runtime (runc, runv, etc) # Paths to look for a valid OCI runtime (runc, runv, kata, etc)
[engine.runtimes] [engine.runtimes]
# runc = [ # runc = [
# "/usr/bin/runc", # "/usr/bin/runc",
@ -369,6 +369,15 @@
# "/run/current-system/sw/bin/crun", # "/run/current-system/sw/bin/crun",
# ] # ]
# kata = [
# "/usr/bin/kata-runtime",
# "/usr/sbin/kata-runtime",
# "/usr/local/bin/kata-runtime",
# "/usr/local/sbin/kata-runtime",
# "/sbin/kata-runtime",
# "/bin/kata-runtime",
# ]
# Number of seconds to wait for container to exit before sending kill signal. # Number of seconds to wait for container to exit before sending kill signal.
#stop_timeout = 10 #stop_timeout = 10

View File

@ -2,14 +2,19 @@ package config
import ( import (
"bytes" "bytes"
"fmt"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strconv" "strconv"
"github.com/containers/common/pkg/unshare" "github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/cgroupv2"
"github.com/containers/common/pkg/sysinfo"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/containers/storage/pkg/unshare"
"github.com/opencontainers/selinux/go-selinux"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -40,7 +45,7 @@ var (
// DefaultInitPath is the default path to the container-init binary // DefaultInitPath is the default path to the container-init binary
DefaultInitPath = "/usr/libexec/podman/catatonit" DefaultInitPath = "/usr/libexec/podman/catatonit"
// DefaultInfraImage to use for infra container // DefaultInfraImage to use for infra container
DefaultInfraImage = "k8s.gcr.io/pause:3.1" DefaultInfraImage = "k8s.gcr.io/pause:3.2"
// DefaultInfraCommand to be run in an infra container // DefaultInfraCommand to be run in an infra container
DefaultInfraCommand = "/pause" DefaultInfraCommand = "/pause"
// DefaultRootlessSHMLockPath is the default path for rootless SHM locks // DefaultRootlessSHMLockPath is the default path for rootless SHM locks
@ -87,7 +92,7 @@ const (
// CgroupfsCgroupsManager represents cgroupfs native cgroup manager // CgroupfsCgroupsManager represents cgroupfs native cgroup manager
CgroupfsCgroupsManager = "cgroupfs" CgroupfsCgroupsManager = "cgroupfs"
// DefaultApparmorProfile specifies the default apparmor profile for the container. // DefaultApparmorProfile specifies the default apparmor profile for the container.
DefaultApparmorProfile = "container-default" DefaultApparmorProfile = apparmor.Profile
// SystemdCgroupsManager represents systemd native cgroup manager // SystemdCgroupsManager represents systemd native cgroup manager
SystemdCgroupsManager = "systemd" SystemdCgroupsManager = "systemd"
// DefaultLogDriver is the default type of log files // DefaultLogDriver is the default type of log files
@ -207,11 +212,11 @@ func defaultConfigFromMemory() (*EngineConfig, error) {
c.StateType = BoltDBStateStore c.StateType = BoltDBStateStore
c.OCIRuntime = "runc" c.OCIRuntime = "runc"
// If we're running on cgroups v2, default to using crun. // If we're running on cgroupv2 v2, default to using crun.
if onCgroupsv2, _ := isCgroup2UnifiedMode(); onCgroupsv2 { if cgroup2, _ := cgroupv2.Enabled(); cgroup2 {
c.OCIRuntime = "crun" c.OCIRuntime = "crun"
} }
c.CgroupManager = SystemdCgroupsManager c.CgroupManager = defaultCgroupManager()
c.StopTimeout = uint(10) c.StopTimeout = uint(10)
c.OCIRuntimes = map[string][]string{ c.OCIRuntimes = map[string][]string{
@ -234,6 +239,14 @@ func defaultConfigFromMemory() (*EngineConfig, error) {
"/bin/crun", "/bin/crun",
"/run/current-system/sw/bin/crun", "/run/current-system/sw/bin/crun",
}, },
"kata": {
"/usr/bin/kata-runtime",
"/usr/sbin/kata-runtime",
"/usr/local/bin/kata-runtime",
"/usr/local/sbin/kata-runtime",
"/sbin/kata-runtime",
"/bin/kata-runtime",
},
} }
c.ConmonEnvVars = []string{ c.ConmonEnvVars = []string{
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
@ -261,7 +274,7 @@ func defaultConfigFromMemory() (*EngineConfig, error) {
c.InfraImage = DefaultInfraImage c.InfraImage = DefaultInfraImage
c.EnablePortReservation = true c.EnablePortReservation = true
c.NumLocks = 2048 c.NumLocks = 2048
c.EventsLogger = "journald" c.EventsLogger = defaultEventsLogger()
c.DetachKeys = DefaultDetachKeys c.DetachKeys = DefaultDetachKeys
c.SDNotify = false c.SDNotify = false
// TODO - ideally we should expose a `type LockType string` along with // TODO - ideally we should expose a `type LockType string` along with
@ -344,3 +357,112 @@ func probeConmon(conmonBinary string) error {
return nil return nil
} }
// NetNS returns the default network namespace
func (c *Config) NetNS() string {
if c.Containers.NetNS == "private" && unshare.IsRootless() {
return "slirp4netns"
}
return c.Containers.NetNS
}
// SecurityOptions returns the default security options
func (c *Config) SecurityOptions() []string {
securityOpts := []string{}
if c.Containers.SeccompProfile != "" && c.Containers.SeccompProfile != SeccompDefaultPath {
securityOpts = append(securityOpts, fmt.Sprintf("seccomp=%s", c.Containers.SeccompProfile))
}
if apparmor.IsEnabled() && c.Containers.ApparmorProfile != "" {
securityOpts = append(securityOpts, fmt.Sprintf("apparmor=%s", c.Containers.ApparmorProfile))
}
if selinux.GetEnabled() && !c.Containers.EnableLabeling {
securityOpts = append(securityOpts, fmt.Sprintf("label=%s", selinux.DisableSecOpt()[0]))
}
return securityOpts
}
// Sysctls returns the default sysctls
func (c *Config) Sysctls() []string {
return c.Containers.DefaultSysctls
}
// Volumes returns the default additional volumes for containersvolumes
func (c *Config) Volumes() []string {
return c.Containers.Volumes
}
// Devices returns the default additional devices for containers
func (c *Config) Devices() []string {
return c.Containers.Devices
}
// DNSServers returns the default DNS servers to add to resolv.conf in containers
func (c *Config) DNSServers() []string {
return c.Containers.DNSServers
}
// DNSSerches returns the default DNS searches to add to resolv.conf in containers
func (c *Config) DNSSearches() []string {
return c.Containers.DNSSearches
}
// DNSOptions returns the default DNS options to add to resolv.conf in containers
func (c *Config) DNSOptions() []string {
return c.Containers.DNSOptions
}
// Env returns the default additional environment variables to add to containers
func (c *Config) Env() []string {
return c.Containers.Env
}
// InitPath returns the default init path to add to containers
func (c *Config) InitPath() string {
return c.Containers.InitPath
}
// IPCNS returns the default IPC Namespace configuration to run containers with
func (c *Config) IPCNS() string {
return c.Containers.IPCNS
}
// PIDNS returns the default PID Namespace configuration to run containers with
func (c *Config) PidNS() string {
return c.Containers.PidNS
}
// CgroupNS returns the default Cgroup Namespace configuration to run containers with
func (c *Config) CgroupNS() string {
return c.Containers.CgroupNS
}
// UTSNS returns the default UTS Namespace configuration to run containers with
func (c *Config) UTSNS() string {
return c.Containers.UTSNS
}
// ShmSize returns the default size for temporary file systems to use in containers
func (c *Config) ShmSize() string {
return c.Containers.ShmSize
}
// Ulimits returns the default ulimits to use in containers
func (c *Config) Ulimits() []string {
return c.Containers.DefaultUlimits
}
// PidsLimit returns the default maximum number of pids to use in containers
func (c *Config) PidsLimit() int64 {
if unshare.IsRootless() {
cgroup2, _ := cgroupv2.Enabled()
if cgroup2 {
return c.Containers.PidsLimit
}
}
return sysinfo.GetDefaultPidsLimit()
}
// DetachKeys returns the default detach keys to detach from a container
func (c *Config) DetachKeys() string {
return c.Engine.DetachKeys
}

View File

@ -5,24 +5,10 @@ import (
"io/ioutil" "io/ioutil"
"strconv" "strconv"
"strings" "strings"
"syscall"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
// isCgroup2UnifiedMode returns whether we are running in cgroup2 mode.
func isCgroup2UnifiedMode() (isUnified bool, isUnifiedErr error) {
cgroupRoot := "/sys/fs/cgroup"
var st syscall.Statfs_t
if err := syscall.Statfs(cgroupRoot, &st); err != nil {
isUnified, isUnifiedErr = false, err
} else {
isUnified, isUnifiedErr = int64(st.Type) == int64(unix.CGROUP2_SUPER_MAGIC), nil
}
return
}
const ( const (
oldMaxSize = uint64(1048576) oldMaxSize = uint64(1048576)
) )

View File

@ -9,7 +9,8 @@ import (
"path/filepath" "path/filepath"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
"github.com/containers/common/pkg/unshare" "github.com/containers/common/pkg/cgroupv2"
"github.com/containers/storage/pkg/unshare"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -69,7 +70,7 @@ type ConfigFromLibpod struct {
// RuntimeSupportsNoCgroups is a list of OCI runtimes that support // RuntimeSupportsNoCgroups is a list of OCI runtimes that support
// running containers without CGroups. // running containers without CGroups.
RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroups,omitempty"` RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroupv2,omitempty"`
// RuntimePath is the path to OCI runtime binary for launching containers. // RuntimePath is the path to OCI runtime binary for launching containers.
// The first path pointing to a valid file will be used This is used only // The first path pointing to a valid file will be used This is used only
@ -175,7 +176,7 @@ type ConfigFromLibpod struct {
SDNotify bool `toml:",omitempty"` SDNotify bool `toml:",omitempty"`
// CgroupCheck indicates the configuration has been rewritten after an // CgroupCheck indicates the configuration has been rewritten after an
// upgrade to Fedora 31 to change the default OCI runtime for cgroupsv2. // upgrade to Fedora 31 to change the default OCI runtime for cgroupv2v2.
CgroupCheck bool `toml:"cgroup_check,omitempty"` CgroupCheck bool `toml:"cgroup_check,omitempty"`
} }
@ -183,7 +184,7 @@ type ConfigFromLibpod struct {
// Depending if we're running as root or rootless, we then merge the system configuration followed // Depending if we're running as root or rootless, we then merge the system configuration followed
// by merging the default config (hard-coded default in memory). // by merging the default config (hard-coded default in memory).
// Note that the OCI runtime is hard-set to `crun` if we're running on a system // Note that the OCI runtime is hard-set to `crun` if we're running on a system
// with cgroupsv2. Other OCI runtimes are not yet supporting cgroupsv2. This // with cgroupv2v2. Other OCI runtimes are not yet supporting cgroupv2v2. This
// might change in the future. // might change in the future.
func newLibpodConfig(c *Config) error { func newLibpodConfig(c *Config) error {
// Start with the default config and interatively merge // Start with the default config and interatively merge
@ -205,13 +206,13 @@ func newLibpodConfig(c *Config) error {
// Since runc does not currently support cgroupV2 // Since runc does not currently support cgroupV2
// Change to default crun on first running of libpod.conf // Change to default crun on first running of libpod.conf
// TODO Once runc has support for cgroups, this function should be removed. // TODO Once runc has support for cgroupv2, this function should be removed.
if !config.CgroupCheck && unshare.IsRootless() { if !config.CgroupCheck && unshare.IsRootless() {
cgroupsV2, err := isCgroup2UnifiedMode() cgroup2, err := cgroupv2.Enabled()
if err != nil { if err != nil {
return err return err
} }
if cgroupsV2 { if cgroup2 {
path, err := exec.LookPath("crun") path, err := exec.LookPath("crun")
if err != nil { if err != nil {
// Can't find crun path so do nothing // Can't find crun path so do nothing

View File

@ -0,0 +1,11 @@
// +build !systemd
package config
func defaultCgroupManager() string {
return "cgroupfs"
}
func defaultEventsLogger() string {
return "file"
}

View File

@ -0,0 +1,10 @@
// +build systemd
package config
func defaultCgroupManager() string {
return SystemdCgroupsManager
}
func defaultEventsLogger() string {
return "journald"
}

View File

@ -9,7 +9,7 @@ import (
"sync" "sync"
"syscall" "syscall"
"github.com/containers/common/pkg/unshare" "github.com/containers/storage/pkg/unshare"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )

View File

@ -0,0 +1 @@
SysInfo stores information about which features a kernel supports.

View File

@ -0,0 +1,12 @@
// +build !linux,!windows
package sysinfo
import (
"runtime"
)
// NumCPU returns the number of CPUs
func NumCPU() int {
return runtime.NumCPU()
}

View File

@ -0,0 +1,44 @@
// +build linux
package sysinfo
import (
"runtime"
"unsafe"
"golang.org/x/sys/unix"
)
// numCPU queries the system for the count of threads available
// for use to this process.
//
// Issues two syscalls.
// Returns 0 on errors. Use |runtime.NumCPU| in that case.
func numCPU() int {
// Gets the affinity mask for a process: The very one invoking this function.
pid, _, _ := unix.RawSyscall(unix.SYS_GETPID, 0, 0, 0)
var mask [1024 / 64]uintptr
_, _, err := unix.RawSyscall(unix.SYS_SCHED_GETAFFINITY, pid, uintptr(len(mask)*8), uintptr(unsafe.Pointer(&mask[0])))
if err != 0 {
return 0
}
// For every available thread a bit is set in the mask.
ncpu := 0
for _, e := range mask {
if e == 0 {
continue
}
ncpu += int(popcnt(uint64(e)))
}
return ncpu
}
// NumCPU returns the number of CPUs which are currently online
func NumCPU() int {
if ncpu := numCPU(); ncpu > 0 {
return ncpu
}
return runtime.NumCPU()
}

View File

@ -0,0 +1,37 @@
// +build windows
package sysinfo
import (
"runtime"
"unsafe"
"golang.org/x/sys/windows"
)
var (
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
getCurrentProcess = kernel32.NewProc("GetCurrentProcess")
getProcessAffinityMask = kernel32.NewProc("GetProcessAffinityMask")
)
func numCPU() int {
// Gets the affinity mask for a process
var mask, sysmask uintptr
currentProcess, _, _ := getCurrentProcess.Call()
ret, _, _ := getProcessAffinityMask.Call(currentProcess, uintptr(unsafe.Pointer(&mask)), uintptr(unsafe.Pointer(&sysmask)))
if ret == 0 {
return 0
}
// For every available thread a bit is set in the mask.
ncpu := int(popcnt(uint64(mask)))
return ncpu
}
// NumCPU returns the number of CPUs which are currently online
func NumCPU() int {
if ncpu := numCPU(); ncpu > 0 {
return ncpu
}
return runtime.NumCPU()
}

View File

@ -0,0 +1,153 @@
package sysinfo
import "github.com/docker/docker/pkg/parsers"
// SysInfo stores information about which features a kernel supports.
// TODO Windows: Factor out platform specific capabilities.
type SysInfo struct {
// Whether the kernel supports AppArmor or not
AppArmor bool
// Whether the kernel supports Seccomp or not
Seccomp bool
cgroupMemInfo
cgroupCPUInfo
cgroupBlkioInfo
cgroupCpusetInfo
cgroupPids
// Whether IPv4 forwarding is supported or not, if this was disabled, networking will not work
IPv4ForwardingDisabled bool
// Whether bridge-nf-call-iptables is supported or not
BridgeNFCallIPTablesDisabled bool
// Whether bridge-nf-call-ip6tables is supported or not
BridgeNFCallIP6TablesDisabled bool
// Whether the cgroup has the mountpoint of "devices" or not
CgroupDevicesEnabled bool
}
type cgroupMemInfo struct {
// Whether memory limit is supported or not
MemoryLimit bool
// Whether swap limit is supported or not
SwapLimit bool
// Whether soft limit is supported or not
MemoryReservation bool
// Whether OOM killer disable is supported or not
OomKillDisable bool
// Whether memory swappiness is supported or not
MemorySwappiness bool
// Whether kernel memory limit is supported or not
KernelMemory bool
}
type cgroupCPUInfo struct {
// Whether CPU shares is supported or not
CPUShares bool
// Whether CPU CFS(Completely Fair Scheduler) period is supported or not
CPUCfsPeriod bool
// Whether CPU CFS(Completely Fair Scheduler) quota is supported or not
CPUCfsQuota bool
// Whether CPU real-time period is supported or not
CPURealtimePeriod bool
// Whether CPU real-time runtime is supported or not
CPURealtimeRuntime bool
}
type cgroupBlkioInfo struct {
// Whether Block IO weight is supported or not
BlkioWeight bool
// Whether Block IO weight_device is supported or not
BlkioWeightDevice bool
// Whether Block IO read limit in bytes per second is supported or not
BlkioReadBpsDevice bool
// Whether Block IO write limit in bytes per second is supported or not
BlkioWriteBpsDevice bool
// Whether Block IO read limit in IO per second is supported or not
BlkioReadIOpsDevice bool
// Whether Block IO write limit in IO per second is supported or not
BlkioWriteIOpsDevice bool
}
type cgroupCpusetInfo struct {
// Whether Cpuset is supported or not
Cpuset bool
// Available Cpuset's cpus
Cpus string
// Available Cpuset's memory nodes
Mems string
}
type cgroupPids struct {
// Whether Pids Limit is supported or not
PidsLimit bool
}
// IsCpusetCpusAvailable returns `true` if the provided string set is contained
// in cgroup's cpuset.cpus set, `false` otherwise.
// If error is not nil a parsing error occurred.
func (c cgroupCpusetInfo) IsCpusetCpusAvailable(provided string) (bool, error) {
return isCpusetListAvailable(provided, c.Cpus)
}
// IsCpusetMemsAvailable returns `true` if the provided string set is contained
// in cgroup's cpuset.mems set, `false` otherwise.
// If error is not nil a parsing error occurred.
func (c cgroupCpusetInfo) IsCpusetMemsAvailable(provided string) (bool, error) {
return isCpusetListAvailable(provided, c.Mems)
}
func isCpusetListAvailable(provided, available string) (bool, error) {
parsedProvided, err := parsers.ParseUintList(provided)
if err != nil {
return false, err
}
parsedAvailable, err := parsers.ParseUintList(available)
if err != nil {
return false, err
}
for k := range parsedProvided {
if !parsedAvailable[k] {
return false, nil
}
}
return true, nil
}
// Returns bit count of 1, used by NumCPU
func popcnt(x uint64) (n byte) {
x -= (x >> 1) & 0x5555555555555555
x = (x>>2)&0x3333333333333333 + x&0x3333333333333333
x += x >> 4
x &= 0x0f0f0f0f0f0f0f0f
x *= 0x0101010101010101
return byte(x >> 56)
}
// GetDefaultPidsLimit returns the default pids limit to run containers with
func GetDefaultPidsLimit() int64 {
sysInfo := New(true)
if !sysInfo.PidsLimit {
return 0
}
return 4096
}

View File

@ -0,0 +1,261 @@
package sysinfo
import (
"fmt"
"io/ioutil"
"os"
"path"
"strings"
"github.com/containers/common/pkg/cgroupv2"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
func findCgroupMountpoints() (map[string]string, error) {
cgMounts, err := cgroups.GetCgroupMounts(false)
if err != nil {
return nil, fmt.Errorf("failed to parse cgroup information: %v", err)
}
mps := make(map[string]string)
for _, m := range cgMounts {
for _, ss := range m.Subsystems {
mps[ss] = m.Mountpoint
}
}
return mps, nil
}
// New returns a new SysInfo, using the filesystem to detect which features
// the kernel supports. If `quiet` is `false` warnings are printed in logs
// whenever an error occurs or misconfigurations are present.
func New(quiet bool) *SysInfo {
sysInfo := &SysInfo{}
cgMounts, err := findCgroupMountpoints()
if err != nil {
logrus.Warnf("Failed to parse cgroup information: %v", err)
} else {
sysInfo.cgroupMemInfo = checkCgroupMem(cgMounts, quiet)
sysInfo.cgroupCPUInfo = checkCgroupCPU(cgMounts, quiet)
sysInfo.cgroupBlkioInfo = checkCgroupBlkioInfo(cgMounts, quiet)
sysInfo.cgroupCpusetInfo = checkCgroupCpusetInfo(cgMounts, quiet)
sysInfo.cgroupPids = checkCgroupPids(quiet)
}
_, ok := cgMounts["devices"]
sysInfo.CgroupDevicesEnabled = ok
sysInfo.IPv4ForwardingDisabled = !readProcBool("/proc/sys/net/ipv4/ip_forward")
sysInfo.BridgeNFCallIPTablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-iptables")
sysInfo.BridgeNFCallIP6TablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-ip6tables")
// Check if AppArmor is supported.
if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) {
sysInfo.AppArmor = true
}
// Check if Seccomp is supported, via CONFIG_SECCOMP.
if err := unix.Prctl(unix.PR_GET_SECCOMP, 0, 0, 0, 0); err != unix.EINVAL {
// Make sure the kernel has CONFIG_SECCOMP_FILTER.
if err := unix.Prctl(unix.PR_SET_SECCOMP, unix.SECCOMP_MODE_FILTER, 0, 0, 0); err != unix.EINVAL {
sysInfo.Seccomp = true
}
}
return sysInfo
}
// checkCgroupMem reads the memory information from the memory cgroup mount point.
func checkCgroupMem(cgMounts map[string]string, quiet bool) cgroupMemInfo {
mountPoint, ok := cgMounts["memory"]
if !ok {
if !quiet {
logrus.Warn("Your kernel does not support cgroup memory limit")
}
return cgroupMemInfo{}
}
swapLimit := cgroupEnabled(mountPoint, "memory.memsw.limit_in_bytes")
if !quiet && !swapLimit {
logrus.Warn("Your kernel does not support swap memory limit")
}
memoryReservation := cgroupEnabled(mountPoint, "memory.soft_limit_in_bytes")
if !quiet && !memoryReservation {
logrus.Warn("Your kernel does not support memory reservation")
}
oomKillDisable := cgroupEnabled(mountPoint, "memory.oom_control")
if !quiet && !oomKillDisable {
logrus.Warn("Your kernel does not support oom control")
}
memorySwappiness := cgroupEnabled(mountPoint, "memory.swappiness")
if !quiet && !memorySwappiness {
logrus.Warn("Your kernel does not support memory swappiness")
}
kernelMemory := cgroupEnabled(mountPoint, "memory.kmem.limit_in_bytes")
if !quiet && !kernelMemory {
logrus.Warn("Your kernel does not support kernel memory limit")
}
return cgroupMemInfo{
MemoryLimit: true,
SwapLimit: swapLimit,
MemoryReservation: memoryReservation,
OomKillDisable: oomKillDisable,
MemorySwappiness: memorySwappiness,
KernelMemory: kernelMemory,
}
}
// checkCgroupCPU reads the cpu information from the cpu cgroup mount point.
func checkCgroupCPU(cgMounts map[string]string, quiet bool) cgroupCPUInfo {
mountPoint, ok := cgMounts["cpu"]
if !ok {
if !quiet {
logrus.Warn("Unable to find cpu cgroup in mounts")
}
return cgroupCPUInfo{}
}
cpuShares := cgroupEnabled(mountPoint, "cpu.shares")
if !quiet && !cpuShares {
logrus.Warn("Your kernel does not support cgroup cpu shares")
}
cpuCfsPeriod := cgroupEnabled(mountPoint, "cpu.cfs_period_us")
if !quiet && !cpuCfsPeriod {
logrus.Warn("Your kernel does not support cgroup cfs period")
}
cpuCfsQuota := cgroupEnabled(mountPoint, "cpu.cfs_quota_us")
if !quiet && !cpuCfsQuota {
logrus.Warn("Your kernel does not support cgroup cfs quotas")
}
cpuRealtimePeriod := cgroupEnabled(mountPoint, "cpu.rt_period_us")
if !quiet && !cpuRealtimePeriod {
logrus.Warn("Your kernel does not support cgroup rt period")
}
cpuRealtimeRuntime := cgroupEnabled(mountPoint, "cpu.rt_runtime_us")
if !quiet && !cpuRealtimeRuntime {
logrus.Warn("Your kernel does not support cgroup rt runtime")
}
return cgroupCPUInfo{
CPUShares: cpuShares,
CPUCfsPeriod: cpuCfsPeriod,
CPUCfsQuota: cpuCfsQuota,
CPURealtimePeriod: cpuRealtimePeriod,
CPURealtimeRuntime: cpuRealtimeRuntime,
}
}
// checkCgroupBlkioInfo reads the blkio information from the blkio cgroup mount point.
func checkCgroupBlkioInfo(cgMounts map[string]string, quiet bool) cgroupBlkioInfo {
mountPoint, ok := cgMounts["blkio"]
if !ok {
if !quiet {
logrus.Warn("Unable to find blkio cgroup in mounts")
}
return cgroupBlkioInfo{}
}
weight := cgroupEnabled(mountPoint, "blkio.weight")
if !quiet && !weight {
logrus.Warn("Your kernel does not support cgroup blkio weight")
}
weightDevice := cgroupEnabled(mountPoint, "blkio.weight_device")
if !quiet && !weightDevice {
logrus.Warn("Your kernel does not support cgroup blkio weight_device")
}
readBpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.read_bps_device")
if !quiet && !readBpsDevice {
logrus.Warn("Your kernel does not support cgroup blkio throttle.read_bps_device")
}
writeBpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.write_bps_device")
if !quiet && !writeBpsDevice {
logrus.Warn("Your kernel does not support cgroup blkio throttle.write_bps_device")
}
readIOpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.read_iops_device")
if !quiet && !readIOpsDevice {
logrus.Warn("Your kernel does not support cgroup blkio throttle.read_iops_device")
}
writeIOpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.write_iops_device")
if !quiet && !writeIOpsDevice {
logrus.Warn("Your kernel does not support cgroup blkio throttle.write_iops_device")
}
return cgroupBlkioInfo{
BlkioWeight: weight,
BlkioWeightDevice: weightDevice,
BlkioReadBpsDevice: readBpsDevice,
BlkioWriteBpsDevice: writeBpsDevice,
BlkioReadIOpsDevice: readIOpsDevice,
BlkioWriteIOpsDevice: writeIOpsDevice,
}
}
// checkCgroupCpusetInfo reads the cpuset information from the cpuset cgroup mount point.
func checkCgroupCpusetInfo(cgMounts map[string]string, quiet bool) cgroupCpusetInfo {
mountPoint, ok := cgMounts["cpuset"]
if !ok {
if !quiet {
logrus.Warn("Unable to find cpuset cgroup in mounts")
}
return cgroupCpusetInfo{}
}
cpus, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.cpus"))
if err != nil {
return cgroupCpusetInfo{}
}
mems, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.mems"))
if err != nil {
return cgroupCpusetInfo{}
}
return cgroupCpusetInfo{
Cpuset: true,
Cpus: strings.TrimSpace(string(cpus)),
Mems: strings.TrimSpace(string(mems)),
}
}
// checkCgroupPids reads the pids information from the pids cgroup mount point.
func checkCgroupPids(quiet bool) cgroupPids {
cgroup2, err := cgroupv2.Enabled()
if err != nil {
logrus.Errorf("Failed to check cgroups version: %v", err)
}
if !cgroup2 {
_, err := cgroups.FindCgroupMountpoint("", "pids")
if err != nil {
if !quiet {
logrus.Warn(err)
}
return cgroupPids{}
}
}
return cgroupPids{
PidsLimit: true,
}
}
func cgroupEnabled(mountPoint, name string) bool {
_, err := os.Stat(path.Join(mountPoint, name))
return err == nil
}
func readProcBool(path string) bool {
val, err := ioutil.ReadFile(path)
if err != nil {
return false
}
return strings.TrimSpace(string(val)) == "1"
}

View File

@ -0,0 +1,122 @@
// +build solaris,cgo
package sysinfo
import (
"bytes"
"os/exec"
"strconv"
"strings"
)
/*
#cgo LDFLAGS: -llgrp
#cgo CFLAGS: -Wall -Werror
#include <unistd.h>
#include <stdlib.h>
#include <sys/lgrp_user.h>
int getLgrpCount() {
lgrp_cookie_t lgrpcookie = LGRP_COOKIE_NONE;
uint_t nlgrps;
if ((lgrpcookie = lgrp_init(LGRP_VIEW_OS)) == LGRP_COOKIE_NONE) {
return -1;
}
nlgrps = lgrp_nlgrps(lgrpcookie);
return nlgrps;
}
*/
import "C"
// IsCPUSharesAvailable returns whether CPUShares setting is supported.
// We need FSS to be set as default scheduling class to support CPU Shares
func IsCPUSharesAvailable() bool {
cmd := exec.Command("/usr/sbin/dispadmin", "-d")
outBuf := new(bytes.Buffer)
errBuf := new(bytes.Buffer)
cmd.Stderr = errBuf
cmd.Stdout = outBuf
if err := cmd.Run(); err != nil {
return false
}
return (strings.Contains(outBuf.String(), "FSS"))
}
// New returns a new SysInfo, using the filesystem to detect which features
// the kernel supports.
//NOTE Solaris: If we change the below capabilities be sure
// to update verifyPlatformContainerSettings() in daemon_solaris.go
func New(quiet bool) *SysInfo {
sysInfo := &SysInfo{}
sysInfo.cgroupMemInfo = setCgroupMem(quiet)
sysInfo.cgroupCPUInfo = setCgroupCPU(quiet)
sysInfo.cgroupBlkioInfo = setCgroupBlkioInfo(quiet)
sysInfo.cgroupCpusetInfo = setCgroupCPUsetInfo(quiet)
sysInfo.IPv4ForwardingDisabled = false
sysInfo.AppArmor = false
return sysInfo
}
// setCgroupMem reads the memory information for Solaris.
func setCgroupMem(quiet bool) cgroupMemInfo {
return cgroupMemInfo{
MemoryLimit: true,
SwapLimit: true,
MemoryReservation: false,
OomKillDisable: false,
MemorySwappiness: false,
KernelMemory: false,
}
}
// setCgroupCPU reads the cpu information for Solaris.
func setCgroupCPU(quiet bool) cgroupCPUInfo {
return cgroupCPUInfo{
CPUShares: true,
CPUCfsPeriod: false,
CPUCfsQuota: true,
CPURealtimePeriod: false,
CPURealtimeRuntime: false,
}
}
// blkio switches are not supported in Solaris.
func setCgroupBlkioInfo(quiet bool) cgroupBlkioInfo {
return cgroupBlkioInfo{
BlkioWeight: false,
BlkioWeightDevice: false,
}
}
// setCgroupCPUsetInfo reads the cpuset information for Solaris.
func setCgroupCPUsetInfo(quiet bool) cgroupCpusetInfo {
return cgroupCpusetInfo{
Cpuset: true,
Cpus: getCPUCount(),
Mems: getLgrpCount(),
}
}
func getCPUCount() string {
ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN)
if ncpus <= 0 {
return ""
}
return strconv.FormatInt(int64(ncpus), 16)
}
func getLgrpCount() string {
nlgrps := C.getLgrpCount()
if nlgrps <= 0 {
return ""
}
return strconv.FormatInt(int64(nlgrps), 16)
}

View File

@ -0,0 +1,9 @@
// +build !linux,!solaris,!windows
package sysinfo
// New returns an empty SysInfo for non linux nor solaris for now.
func New(quiet bool) *SysInfo {
sysInfo := &SysInfo{}
return sysInfo
}

View File

@ -0,0 +1,9 @@
// +build windows
package sysinfo
// New returns an empty SysInfo for windows for now.
func New(quiet bool) *SysInfo {
sysInfo := &SysInfo{}
return sysInfo
}

View File

@ -1 +1 @@
1.16.6 1.18.1

View File

@ -5,12 +5,14 @@ require (
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
github.com/Microsoft/hcsshim v0.8.7 github.com/Microsoft/hcsshim v0.8.7
github.com/docker/go-units v0.4.0 github.com/docker/go-units v0.4.0
github.com/hashicorp/go-multierror v1.0.0
github.com/klauspost/compress v1.10.3 github.com/klauspost/compress v1.10.3
github.com/klauspost/pgzip v1.2.3 github.com/klauspost/pgzip v1.2.3
github.com/mattn/go-shellwords v1.0.10 github.com/mattn/go-shellwords v1.0.10
github.com/mistifyio/go-zfs v2.1.1+incompatible github.com/mistifyio/go-zfs v2.1.1+incompatible
github.com/opencontainers/go-digest v1.0.0-rc1 github.com/opencontainers/go-digest v1.0.0-rc1
github.com/opencontainers/runc v1.0.0-rc9 github.com/opencontainers/runc v1.0.0-rc9
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700
github.com/opencontainers/selinux v1.4.0 github.com/opencontainers/selinux v1.4.0
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7 github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7
@ -20,7 +22,7 @@ require (
github.com/tchap/go-patricia v2.3.0+incompatible github.com/tchap/go-patricia v2.3.0+incompatible
github.com/vbatts/tar-split v0.11.1 github.com/vbatts/tar-split v0.11.1
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 golang.org/x/net v0.0.0-20190628185345-da137c7871d7
golang.org/x/sys v0.0.0-20191115151921-52ab43148777 golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2
gotest.tools v2.2.0+incompatible gotest.tools v2.2.0+incompatible
) )

View File

@ -1,6 +1,7 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg= github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg=
@ -16,12 +17,19 @@ github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/containers/common v0.5.0 h1:ZAef7h3oO46PcbTyfooZf8XLHrYad+GkhSu3EhH6P24=
github.com/containers/common v0.5.0/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys=
github.com/containers/common v0.6.1 h1:z9VeVXYeOnNV99uNLp7zoE5KO1n0hqz1mdm5a6AiIrA=
github.com/containers/common v0.6.1/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys=
github.com/containers/storage v1.16.0/go.mod h1:nqN09JSi1/RSI1UAUwDYXPRiGSlq5FPbNkN/xb0TfG0=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/docker v0.0.0-20171019062838-86f080cff091/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
@ -32,15 +40,22 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.10.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.10.2 h1:Znfn6hXZAHaLPNnlqUYRrBSReFHYybslgv4PTiyz6P0= github.com/klauspost/compress v1.10.2 h1:Znfn6hXZAHaLPNnlqUYRrBSReFHYybslgv4PTiyz6P0=
github.com/klauspost/compress v1.10.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8= github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM= github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/klauspost/pgzip v1.2.2 h1:8d4I0LDiieuGngsqlqOih9ker/NS0LX4V0i+EhiFWg0= github.com/klauspost/pgzip v1.2.2 h1:8d4I0LDiieuGngsqlqOih9ker/NS0LX4V0i+EhiFWg0=
@ -53,14 +68,23 @@ github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvO
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJdNZo6oqSENd4eW8= github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJdNZo6oqSENd4eW8=
github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc9 h1:/k06BMULKF5hidyoZymkoDCzdJzltZpz/UU4LguQVtc= github.com/opencontainers/runc v1.0.0-rc9 h1:/k06BMULKF5hidyoZymkoDCzdJzltZpz/UU4LguQVtc=
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700 h1:eNUVfm/RFLIi1G7flU5/ZRTHvd4kcVuzfRnL6OFlzCI=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7 h1:Dliu5QO+4JYWu/yMshaMU7G3JN2POGpwjJN7gjy10Go=
github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/selinux v1.3.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/opencontainers/selinux v1.3.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/opencontainers/selinux v1.4.0 h1:cpiX/2wWIju/6My60T6/z9CxNG7c8xTQyEmA9fChpUo= github.com/opencontainers/selinux v1.4.0 h1:cpiX/2wWIju/6My60T6/z9CxNG7c8xTQyEmA9fChpUo=
github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
@ -77,10 +101,12 @@ github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q= github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
@ -103,6 +129,7 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@ -115,6 +142,7 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -123,6 +151,9 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777 h1:wejkGHRTr38uaKRqECZlsCsJ1/TGxIyFbH32x5zUdu4= golang.org/x/sys v0.0.0-20191115151921-52ab43148777 h1:wejkGHRTr38uaKRqECZlsCsJ1/TGxIyFbH32x5zUdu4=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2 h1:/J2nHFg1MTqaRLFO7M+J78ASNsJoz3r0cvHBPQ77fsE=
golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -130,6 +161,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@ -138,8 +170,12 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -281,6 +281,8 @@ func copyLayer(l *Layer) *Layer {
Flags: copyStringInterfaceMap(l.Flags), Flags: copyStringInterfaceMap(l.Flags),
UIDMap: copyIDMap(l.UIDMap), UIDMap: copyIDMap(l.UIDMap),
GIDMap: copyIDMap(l.GIDMap), GIDMap: copyIDMap(l.GIDMap),
UIDs: copyUint32Slice(l.UIDs),
GIDs: copyUint32Slice(l.GIDs),
} }
} }

View File

@ -134,6 +134,18 @@ type OptionsConfig struct {
// should be used to set up default GID mappings. // should be used to set up default GID mappings.
RemapGroup string `toml:"remap-group"` RemapGroup string `toml:"remap-group"`
// RootAutoUsernsUser is the name of one or more entries in /etc/subuid and
// /etc/subgid which should be used to set up automatically a userns.
RootAutoUsernsUser string `toml:"root-auto-userns-user"`
// AutoUsernsMinSize is the minimum size for a user namespace that is
// created automatically.
AutoUsernsMinSize uint32 `toml:"auto-userns-min-size"`
// AutoUsernsMaxSize is the maximum size for a user namespace that is
// created automatically.
AutoUsernsMaxSize uint32 `toml:"auto-userns-max-size"`
// Aufs container options to be handed to aufs drivers // Aufs container options to be handed to aufs drivers
Aufs struct{ AufsOptionsConfig } `toml:"aufs"` Aufs struct{ AufsOptionsConfig } `toml:"aufs"`

View File

@ -1,3 +1,5 @@
#ifndef UNSHARE_NO_CODE_AT_ALL
#define _GNU_SOURCE #define _GNU_SOURCE
#include <sys/types.h> #include <sys/types.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -285,3 +287,5 @@ void _containers_unshare(void)
} }
return; return;
} }
#endif // !UNSHARE_NO_CODE_AT_ALL

View File

@ -31,9 +31,9 @@ type Cmd struct {
*exec.Cmd *exec.Cmd
UnshareFlags int UnshareFlags int
UseNewuidmap bool UseNewuidmap bool
UidMappings []specs.LinuxIDMapping UidMappings []specs.LinuxIDMapping // nolint: golint
UseNewgidmap bool UseNewgidmap bool
GidMappings []specs.LinuxIDMapping GidMappings []specs.LinuxIDMapping // nolint: golint
GidMappingsEnableSetgroups bool GidMappingsEnableSetgroups bool
Setsid bool Setsid bool
Setpgrp bool Setpgrp bool
@ -367,7 +367,7 @@ type Runnable interface {
Run() error Run() error
} }
func bailOnError(err error, format string, a ...interface{}) { func bailOnError(err error, format string, a ...interface{}) { // nolint: golint,goprintffuncname
if err != nil { if err != nil {
if format != "" { if format != "" {
logrus.Errorf("%s: %v", fmt.Sprintf(format, a...), err) logrus.Errorf("%s: %v", fmt.Sprintf(format, a...), err)

View File

@ -0,0 +1,10 @@
// +build !linux,cgo
package unshare
// Go refuses to compile a subpackage with CGO_ENABLED=1 if there is a *.c file but no 'import "C"'.
// OTOH if we did have an 'import "C"', the Linux-only code would fail to compile.
// So, satisfy the Go compiler by using import "C" but #ifdef-ing out all of the code.
// #cgo CPPFLAGS: -DUNSHARE_NO_CODE_AT_ALL
import "C"

View File

@ -43,8 +43,22 @@ additionalimagestores = [
# lowest host-level IDs first, to the lowest not-yet-mapped in-container ID, # lowest host-level IDs first, to the lowest not-yet-mapped in-container ID,
# until all of the entries have been used for maps. # until all of the entries have been used for maps.
# #
# remap-user = "storage" # remap-user = "containers"
# remap-group = "storage" # remap-group = "containers"
# Root-auto-userns-user is a user name which can be used to look up one or more UID/GID
# ranges in the /etc/subuid and /etc/subgid file. These ranges will be partioned
# to containers configured to create automatically a user namespace. Containers
# configured to automatically create a user namespace can still overlap with containers
# having an explicit mapping set.
# This setting is ignored when running as rootless.
# root-auto-userns-user = "storage"
#
# Auto-userns-min-size is the minimum size for a user namespace created automatically.
# auto-userns-min-size=1024
#
# Auto-userns-max-size is the minimum size for a user namespace created automatically.
# auto-userns-max-size=65536
[storage.options.overlay] [storage.options.overlay]
# ignore_chown_errors can be set to allow a non privileged user running with # ignore_chown_errors can be set to allow a non privileged user running with

View File

@ -26,6 +26,7 @@ import (
"github.com/containers/storage/pkg/parsers" "github.com/containers/storage/pkg/parsers"
"github.com/containers/storage/pkg/stringid" "github.com/containers/storage/pkg/stringid"
"github.com/containers/storage/pkg/stringutils" "github.com/containers/storage/pkg/stringutils"
"github.com/hashicorp/go-multierror"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
"github.com/opencontainers/selinux/go-selinux/label" "github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -152,6 +153,13 @@ type StoreOptions struct {
// for use inside of a user namespace where UID mapping is being used. // for use inside of a user namespace where UID mapping is being used.
UIDMap []idtools.IDMap `json:"uidmap,omitempty"` UIDMap []idtools.IDMap `json:"uidmap,omitempty"`
GIDMap []idtools.IDMap `json:"gidmap,omitempty"` GIDMap []idtools.IDMap `json:"gidmap,omitempty"`
// RootAutoNsUser is the user used to pick a subrange when automatically setting
// a user namespace for the root user.
RootAutoNsUser string `json:"root_auto_ns_user,omitempty"`
// AutoNsMinSize is the minimum size for an automatic user namespace.
AutoNsMinSize uint32 `json:"auto_userns_min_size,omitempty"`
// AutoNsMaxSize is the maximum size for an automatic user namespace.
AutoNsMaxSize uint32 `json:"auto_userns_max_size,omitempty"`
} }
// Store wraps up the various types of file-based stores that we use into a // Store wraps up the various types of file-based stores that we use into a
@ -469,6 +477,27 @@ type Store interface {
GetDigestLock(digest.Digest) (Locker, error) GetDigestLock(digest.Digest) (Locker, error)
} }
// AutoUserNsOptions defines how to automatically create a user namespace.
type AutoUserNsOptions struct {
// Size defines the size for the user namespace. If it is set to a
// value bigger than 0, the user namespace will have exactly this size.
// If it is not set, some heuristics will be used to find its size.
Size uint32
// InitialSize defines the minimum size for the user namespace.
// The created user namespace will have at least this size.
InitialSize uint32
// PasswdFile to use if the container uses a volume.
PasswdFile string
// GroupFile to use if the container uses a volume.
GroupFile string
// AdditionalUIDMappings specified additional UID mappings to include in
// the generated user namespace.
AdditionalUIDMappings []idtools.IDMap
// AdditionalGIDMappings specified additional GID mappings to include in
// the generated user namespace.
AdditionalGIDMappings []idtools.IDMap
}
// IDMappingOptions are used for specifying how ID mapping should be set up for // IDMappingOptions are used for specifying how ID mapping should be set up for
// a layer or container. // a layer or container.
type IDMappingOptions struct { type IDMappingOptions struct {
@ -485,6 +514,8 @@ type IDMappingOptions struct {
HostGIDMapping bool HostGIDMapping bool
UIDMap []idtools.IDMap UIDMap []idtools.IDMap
GIDMap []idtools.IDMap GIDMap []idtools.IDMap
AutoUserNs bool
AutoUserNsOpts AutoUserNsOptions
} }
// LayerOptions is used for passing options to a Store's CreateLayer() and PutLayer() methods. // LayerOptions is used for passing options to a Store's CreateLayer() and PutLayer() methods.
@ -525,11 +556,17 @@ type store struct {
lastLoaded time.Time lastLoaded time.Time
runRoot string runRoot string
graphLock Locker graphLock Locker
usernsLock Locker
graphRoot string graphRoot string
graphDriverName string graphDriverName string
graphOptions []string graphOptions []string
uidMap []idtools.IDMap uidMap []idtools.IDMap
gidMap []idtools.IDMap gidMap []idtools.IDMap
autoUsernsUser string
autoUIDMap []idtools.IDMap // Set by getAvailableMappings()
autoGIDMap []idtools.IDMap // Set by getAvailableMappings()
autoNsMinSize uint32
autoNsMaxSize uint32
graphDriver drivers.Driver graphDriver drivers.Driver
layerStore LayerStore layerStore LayerStore
roLayerStores []ROLayerStore roLayerStores []ROLayerStore
@ -608,6 +645,20 @@ func GetStore(options StoreOptions) (Store, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
usernsLock, err := GetLockfile(filepath.Join(options.GraphRoot, "userns.lock"))
if err != nil {
return nil, err
}
autoNsMinSize := options.AutoNsMinSize
autoNsMaxSize := options.AutoNsMaxSize
if autoNsMinSize == 0 {
autoNsMinSize = AutoUserNsMinSize
}
if autoNsMaxSize == 0 {
autoNsMaxSize = AutoUserNsMaxSize
}
s := &store{ s := &store{
runRoot: options.RunRoot, runRoot: options.RunRoot,
graphLock: graphLock, graphLock: graphLock,
@ -616,6 +667,12 @@ func GetStore(options StoreOptions) (Store, error) {
graphOptions: options.GraphDriverOptions, graphOptions: options.GraphDriverOptions,
uidMap: copyIDMap(options.UIDMap), uidMap: copyIDMap(options.UIDMap),
gidMap: copyIDMap(options.GIDMap), gidMap: copyIDMap(options.GIDMap),
autoUsernsUser: options.RootAutoNsUser,
autoNsMinSize: autoNsMinSize,
autoNsMaxSize: autoNsMaxSize,
autoUIDMap: nil,
autoGIDMap: nil,
usernsLock: usernsLock,
} }
if err := s.load(); err != nil { if err := s.load(); err != nil {
return nil, err return nil, err
@ -626,6 +683,18 @@ func GetStore(options StoreOptions) (Store, error) {
return s, nil return s, nil
} }
func copyUint32Slice(slice []uint32) []uint32 {
m := []uint32{}
if slice != nil {
m = make([]uint32, len(slice))
copy(m, slice)
}
if len(m) > 0 {
return m[:]
}
return nil
}
func copyIDMap(idmap []idtools.IDMap) []idtools.IDMap { func copyIDMap(idmap []idtools.IDMap) []idtools.IDMap {
m := []idtools.IDMap{} m := []idtools.IDMap{}
if idmap != nil { if idmap != nil {
@ -1151,21 +1220,32 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
var imageTopLayer *Layer var imageTopLayer *Layer
imageID := "" imageID := ""
uidMap := options.UIDMap
gidMap := options.GIDMap
idMappingsOptions := options.IDMappingOptions if options.AutoUserNs || options.UIDMap != nil || options.GIDMap != nil {
// Prevent multiple instances to retrieve the same range when AutoUserNs
// are used.
// It doesn't prevent containers that specify an explicit mapping to overlap
// with AutoUserNs.
s.usernsLock.Lock()
defer s.usernsLock.Unlock()
}
var imageHomeStore ROImageStore
var istore ImageStore
var istores []ROImageStore
var lstores []ROLayerStore
var cimage *Image
if image != "" { if image != "" {
var imageHomeStore ROImageStore var err error
lstores, err := s.ROLayerStores() lstores, err = s.ROLayerStores()
if err != nil { if err != nil {
return nil, err return nil, err
} }
istore, err := s.ImageStore() istore, err = s.ImageStore()
if err != nil { if err != nil {
return nil, err return nil, err
} }
istores, err := s.ROImageStores() istores, err = s.ROImageStores()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1176,7 +1256,6 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
return nil, err return nil, err
} }
} }
var cimage *Image
for _, s := range append([]ROImageStore{istore}, istores...) { for _, s := range append([]ROImageStore{istore}, istores...) {
store := s store := s
if store == istore { if store == istore {
@ -1200,7 +1279,21 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
return nil, errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id) return nil, errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
} }
imageID = cimage.ID imageID = cimage.ID
}
if options.AutoUserNs {
var err error
options.UIDMap, options.GIDMap, err = s.getAutoUserNS(id, &options.AutoUserNsOpts, cimage)
if err != nil {
return nil, err
}
}
uidMap := options.UIDMap
gidMap := options.GIDMap
idMappingsOptions := options.IDMappingOptions
if image != "" {
if cimage.TopLayer != "" { if cimage.TopLayer != "" {
createMappedLayer := imageHomeStore == istore createMappedLayer := imageHomeStore == istore
ilayer, err := s.imageTopLayerForMapping(cimage, imageHomeStore, createMappedLayer, rlstore, lstores, idMappingsOptions) ilayer, err := s.imageTopLayerForMapping(cimage, imageHomeStore, createMappedLayer, rlstore, lstores, idMappingsOptions)
@ -2356,14 +2449,15 @@ func (s *store) DeleteContainer(id string) error {
close(errChan) close(errChan)
}() }()
var errors []error
for { for {
select { select {
case err, ok := <-errChan: case err, ok := <-errChan:
if !ok { if !ok {
return nil return multierror.Append(nil, errors...).ErrorOrNil()
} }
if err != nil { if err != nil {
return err errors = append(errors, err)
} }
} }
} }
@ -3305,6 +3399,16 @@ func copyStringInterfaceMap(m map[string]interface{}) map[string]interface{} {
// defaultConfigFile path to the system wide storage.conf file // defaultConfigFile path to the system wide storage.conf file
const defaultConfigFile = "/etc/containers/storage.conf" const defaultConfigFile = "/etc/containers/storage.conf"
// AutoUserNsMinSize is the minimum size for automatically created user namespaces
const AutoUserNsMinSize = 1024
// AutoUserNsMaxSize is the maximum size for automatically created user namespaces
const AutoUserNsMaxSize = 65536
// RootAutoUserNsUser is the default user used for root containers when automatically
// creating a user namespace.
const RootAutoUserNsUser = "containers"
// DefaultConfigFile returns the path to the storage config file used // DefaultConfigFile returns the path to the storage config file used
func DefaultConfigFile(rootless bool) (string, error) { func DefaultConfigFile(rootless bool) (string, error) {
if rootless { if rootless {
@ -3406,6 +3510,13 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) {
} else { } else {
storeOptions.GIDMap = append(storeOptions.GIDMap, gidmap...) storeOptions.GIDMap = append(storeOptions.GIDMap, gidmap...)
} }
storeOptions.RootAutoNsUser = config.Storage.Options.RootAutoUsernsUser
if config.Storage.Options.AutoUsernsMinSize > 0 {
storeOptions.AutoNsMinSize = config.Storage.Options.AutoUsernsMinSize
}
if config.Storage.Options.AutoUsernsMaxSize > 0 {
storeOptions.AutoNsMaxSize = config.Storage.Options.AutoUsernsMaxSize
}
storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, cfg.GetGraphDriverOptions(storeOptions.GraphDriverName, config.Storage.Options)...) storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, cfg.GetGraphDriverOptions(storeOptions.GraphDriverName, config.Storage.Options)...)

457
vendor/github.com/containers/storage/userns.go generated vendored Normal file
View File

@ -0,0 +1,457 @@
package storage
import (
"os"
"os/user"
"path/filepath"
"strconv"
drivers "github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/unshare"
libcontainerUser "github.com/opencontainers/runc/libcontainer/user"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
// getAdditionalSubIDs looks up the additional IDs configured for
// the specified user.
// The argument USERNAME is ignored for rootless users, as it is not
// possible to use an arbitrary entry in /etc/sub*id.
// Differently, if the username is not specified for root users, a
// default name is used.
func getAdditionalSubIDs(username string) ([]idtools.IDMap, []idtools.IDMap, error) {
var uids, gids []idtools.IDMap
if unshare.IsRootless() {
username = os.Getenv("USER")
if username == "" {
var id string
if os.Geteuid() == 0 {
id = strconv.Itoa(unshare.GetRootlessUID())
} else {
id = strconv.Itoa(os.Geteuid())
}
userID, err := user.LookupId(id)
if err == nil {
username = userID.Username
}
}
} else if username == "" {
username = RootAutoUserNsUser
}
mappings, err := idtools.NewIDMappings(username, username)
if err != nil {
logrus.Errorf("cannot find mappings for user %q: %v", username, err)
} else {
uids = mappings.UIDs()
gids = mappings.GIDs()
}
return uids, gids, nil
}
// getAvailableMappings returns the list of ranges that are usable by the current user.
// When running as root, it looks up the additional IDs assigned to the specified user.
// When running as rootless, the mappings assigned to the unprivileged user are converted
// to the IDs inside of the initial rootless user namespace.
func (s *store) getAvailableMappings() ([]idtools.IDMap, []idtools.IDMap, error) {
if s.autoUIDMap == nil {
uids, gids, err := getAdditionalSubIDs(s.autoUsernsUser)
if err != nil {
return nil, nil, err
}
// Store the result so we don't need to look it up again next time
s.autoUIDMap, s.autoGIDMap = uids, gids
}
uids := s.autoUIDMap
gids := s.autoGIDMap
if !unshare.IsRootless() {
// No mapping to inner namespace needed
return copyIDMap(uids), copyIDMap(gids), nil
}
// We are already inside of the rootless user namespace.
// We need to remap the configured mappings to what is available
// inside of the rootless userns.
totaluid := 0
totalgid := 0
for _, u := range uids {
totaluid += u.Size
}
for _, g := range gids {
totalgid += g.Size
}
u := []idtools.IDMap{{ContainerID: 0, HostID: 1, Size: totaluid}}
g := []idtools.IDMap{{ContainerID: 0, HostID: 1, Size: totalgid}}
return u, g, nil
}
// parseMountedFiles returns the maximum UID and GID found in the /etc/passwd and
// /etc/group files.
func parseMountedFiles(containerMount, passwdFile, groupFile string) uint32 {
if passwdFile == "" {
passwdFile = filepath.Join(containerMount, "etc/passwd")
}
if groupFile == "" {
groupFile = filepath.Join(groupFile, "etc/group")
}
size := 0
users, err := libcontainerUser.ParsePasswdFile(passwdFile)
if err == nil {
for _, u := range users {
// Skip the "nobody" user otherwise we end up with 65536
// ids with most images
if u.Name == "nobody" {
continue
}
if u.Uid > size {
size = u.Uid
}
if u.Gid > size {
size = u.Uid
}
}
}
groups, err := libcontainerUser.ParseGroupFile(groupFile)
if err == nil {
for _, g := range groups {
if g.Name == "nobody" {
continue
}
if g.Gid > size {
size = g.Gid
}
}
}
return uint32(size)
}
// getMaxSizeFromImage returns the maximum ID used by the specified image.
// The layer stores must be already locked.
func (s *store) getMaxSizeFromImage(id string, image *Image, passwdFile, groupFile string) (uint32, error) {
lstore, err := s.LayerStore()
if err != nil {
return 0, err
}
lstores, err := s.ROLayerStores()
if err != nil {
return 0, err
}
size := uint32(0)
var topLayer *Layer
layerName := image.TopLayer
outer:
for {
for _, ls := range append([]ROLayerStore{lstore}, lstores...) {
layer, err := ls.Get(layerName)
if err != nil {
continue
}
if image.TopLayer == layerName {
topLayer = layer
}
for _, uid := range layer.UIDs {
if uid >= size {
size = uid + 1
}
}
for _, gid := range layer.GIDs {
if gid >= size {
size = gid + 1
}
}
layerName = layer.Parent
if layerName == "" {
break outer
}
continue outer
}
return 0, errors.Errorf("cannot find layer %q", layerName)
}
rlstore, err := s.LayerStore()
if err != nil {
return 0, err
}
layerOptions := &LayerOptions{
IDMappingOptions: IDMappingOptions{
HostUIDMapping: true,
HostGIDMapping: true,
UIDMap: nil,
GIDMap: nil,
},
}
// We need to create a temporary layer so we can mount it and lookup the
// maximum IDs used.
clayer, err := rlstore.Create(id, topLayer, nil, "", nil, layerOptions, false)
if err != nil {
return 0, err
}
defer rlstore.Delete(clayer.ID)
mountOptions := drivers.MountOpts{
MountLabel: "",
UidMaps: nil,
GidMaps: nil,
Options: nil,
}
mountpoint, err := rlstore.Mount(clayer.ID, mountOptions)
if err != nil {
return 0, err
}
defer rlstore.Unmount(clayer.ID, true)
userFilesSize := parseMountedFiles(mountpoint, passwdFile, groupFile)
if userFilesSize > size {
size = userFilesSize
}
return size, nil
}
// subtractHostIDs return the subtraction of the range USED from AVAIL. The range is specified
// by [HostID, HostID+Size).
// ContainerID is ignored.
func subtractHostIDs(avail idtools.IDMap, used idtools.IDMap) []idtools.IDMap {
switch {
case used.HostID <= avail.HostID && used.HostID+used.Size >= avail.HostID+avail.Size:
return nil
case used.HostID <= avail.HostID && used.HostID+used.Size > avail.HostID && used.HostID+used.Size < avail.HostID+avail.Size:
newContainerID := used.HostID + used.Size
newHostID := used.HostID + used.Size
r := idtools.IDMap{
ContainerID: newContainerID,
HostID: newHostID,
Size: avail.Size + avail.HostID - newHostID,
}
return []idtools.IDMap{r}
case used.HostID > avail.HostID && used.HostID < avail.HostID+avail.Size && used.HostID+used.Size >= avail.HostID+avail.Size:
r := idtools.IDMap{
ContainerID: avail.ContainerID,
HostID: avail.HostID,
Size: used.HostID - avail.HostID,
}
return []idtools.IDMap{r}
case used.HostID > avail.HostID && used.HostID < avail.HostID+avail.Size && used.HostID+used.Size < avail.HostID+avail.Size:
r1 := idtools.IDMap{
ContainerID: avail.ContainerID,
HostID: avail.HostID,
Size: used.HostID - avail.HostID,
}
r2 := idtools.IDMap{
ContainerID: used.ContainerID + used.Size,
HostID: used.HostID + used.Size,
Size: avail.HostID + avail.Size - used.HostID - used.Size,
}
return []idtools.IDMap{r1, r2}
default:
r := idtools.IDMap{
ContainerID: 0,
HostID: avail.HostID,
Size: avail.Size,
}
return []idtools.IDMap{r}
}
}
// subtractContainerIDs return the subtraction of the range USED from AVAIL. The range is specified
// by [ContainerID, ContainerID+Size).
// HostID is ignored.
func subtractContainerIDs(avail idtools.IDMap, used idtools.IDMap) []idtools.IDMap {
switch {
case used.ContainerID <= avail.ContainerID && used.ContainerID+used.Size >= avail.ContainerID+avail.Size:
return nil
case used.ContainerID <= avail.ContainerID && used.ContainerID+used.Size > avail.ContainerID && used.ContainerID+used.Size < avail.ContainerID+avail.Size:
newContainerID := used.ContainerID + used.Size
newHostID := used.HostID + used.Size
r := idtools.IDMap{
ContainerID: newContainerID,
HostID: newHostID,
Size: avail.Size + avail.ContainerID - newContainerID,
}
return []idtools.IDMap{r}
case used.ContainerID > avail.ContainerID && used.ContainerID < avail.ContainerID+avail.Size && used.ContainerID+used.Size >= avail.ContainerID+avail.Size:
r := idtools.IDMap{
ContainerID: avail.ContainerID,
HostID: avail.HostID,
Size: used.ContainerID - avail.ContainerID,
}
return []idtools.IDMap{r}
case used.ContainerID > avail.ContainerID && used.ContainerID < avail.ContainerID+avail.Size && used.ContainerID+used.Size < avail.ContainerID+avail.Size:
r1 := idtools.IDMap{
ContainerID: avail.ContainerID,
HostID: avail.HostID,
Size: used.ContainerID - avail.ContainerID,
}
r2 := idtools.IDMap{
ContainerID: used.ContainerID + used.Size,
HostID: used.HostID + used.Size,
Size: avail.ContainerID + avail.Size - used.ContainerID - used.Size,
}
return []idtools.IDMap{r1, r2}
default:
r := idtools.IDMap{
ContainerID: avail.ContainerID,
HostID: avail.HostID,
Size: avail.Size,
}
return []idtools.IDMap{r}
}
}
// subtractAll subtracts all usedIDs from the available IDs.
func subtractAll(availableIDs, usedIDs []idtools.IDMap, host bool) []idtools.IDMap {
for _, u := range usedIDs {
for i := 0; i < len(availableIDs); {
var prev []idtools.IDMap
if i > 0 {
prev = availableIDs[:i-1]
}
next := availableIDs[i+1:]
cur := availableIDs[i]
var newRanges []idtools.IDMap
if host {
newRanges = subtractHostIDs(cur, u)
} else {
newRanges = subtractContainerIDs(cur, u)
}
availableIDs = append(append(prev, newRanges...), next...)
i += len(newRanges)
}
}
return availableIDs
}
// findAvailableIDRange returns the list of IDs that are not used by existing containers.
// This function is used to lookup both UIDs and GIDs.
func findAvailableIDRange(size uint32, availableIDs, usedIDs []idtools.IDMap) ([]idtools.IDMap, error) {
var avail []idtools.IDMap
// ContainerID will be adjusted later.
for _, i := range availableIDs {
n := idtools.IDMap{
ContainerID: 0,
HostID: i.HostID,
Size: i.Size,
}
avail = append(avail, n)
}
avail = subtractAll(avail, usedIDs, true)
currentID := 0
remaining := size
// We know the size for each intervals, let's adjust the ContainerID for each
// of them.
for i := 0; i < len(avail); i++ {
avail[i].ContainerID = currentID
if uint32(avail[i].Size) >= remaining {
avail[i].Size = int(remaining)
return avail[:i+1], nil
}
remaining -= uint32(avail[i].Size)
}
return nil, errors.New("could not find enough available IDs")
}
// findAvailableRange returns both the list of UIDs and GIDs ranges that are not
// currently used by other containers.
// It is a wrapper for findAvailableIDRange.
func findAvailableRange(sizeUID, sizeGID uint32, availableUIDs, availableGIDs, usedUIDs, usedGIDs []idtools.IDMap) ([]idtools.IDMap, []idtools.IDMap, error) {
UIDMap, err := findAvailableIDRange(sizeUID, availableUIDs, usedUIDs)
if err != nil {
return nil, nil, err
}
GIDMap, err := findAvailableIDRange(sizeGID, availableGIDs, usedGIDs)
if err != nil {
return nil, nil, err
}
return UIDMap, GIDMap, nil
}
// getAutoUserNS creates an automatic user namespace
func (s *store) getAutoUserNS(id string, options *AutoUserNsOptions, image *Image) ([]idtools.IDMap, []idtools.IDMap, error) {
requestedSize := uint32(0)
initialSize := uint32(1)
if options.Size > 0 {
requestedSize = options.Size
}
if options.InitialSize > 0 {
initialSize = options.InitialSize
}
availableUIDs, availableGIDs, err := s.getAvailableMappings()
if err != nil {
return nil, nil, errors.Wrapf(err, "cannot read mappings")
}
// Look every container that is using a user namespace and store
// the intervals that are already used.
containers, err := s.Containers()
if err != nil {
return nil, nil, err
}
var usedUIDs, usedGIDs []idtools.IDMap
for _, c := range containers {
usedUIDs = append(usedUIDs, c.UIDMap...)
usedGIDs = append(usedGIDs, c.GIDMap...)
}
size := requestedSize
// If there is no requestedSize, lookup the maximum used IDs in the layers
// metadata. Make sure the size is at least s.autoNsMinSize and it is not
// bigger than s.autoNsMaxSize.
// This is a best effort heuristic.
if requestedSize == 0 {
size = initialSize
if s.autoNsMinSize > size {
size = s.autoNsMinSize
}
if image != nil {
sizeFromImage, err := s.getMaxSizeFromImage(id, image, options.PasswdFile, options.GroupFile)
if err != nil {
return nil, nil, err
}
if sizeFromImage > size {
size = sizeFromImage
}
}
if s.autoNsMaxSize > 0 && size > s.autoNsMaxSize {
return nil, nil, errors.Errorf("the container needs a user namespace with size %q that is bigger than the maximum value allowed with userns=auto %q", size, s.autoNsMaxSize)
}
}
// Make sure the specified additional IDs are not used as part of the automatic
// mapping
usedUIDs = append(usedUIDs, options.AdditionalUIDMappings...)
usedGIDs = append(usedGIDs, options.AdditionalGIDMappings...)
availableUIDs, availableGIDs, err = findAvailableRange(size, size, availableUIDs, availableGIDs, usedUIDs, usedGIDs)
if err != nil {
return nil, nil, err
}
// We need to make sure the specified container IDs are also dropped from the automatic
// namespaces we have found.
if len(options.AdditionalUIDMappings) > 0 {
availableUIDs = subtractAll(availableUIDs, options.AdditionalUIDMappings, false)
}
if len(options.AdditionalGIDMappings) > 0 {
availableGIDs = subtractAll(availableGIDs, options.AdditionalGIDMappings, false)
}
return append(availableUIDs, options.AdditionalUIDMappings...), append(availableGIDs, options.AdditionalGIDMappings...), nil
}

View File

@ -209,12 +209,8 @@ func NewStages(node *parser.Node, b *Builder) (Stages, error) {
stages = append(stages, Stage{ stages = append(stages, Stage{
Position: i, Position: i,
Name: name, Name: name,
Builder: &Builder{ Builder: b.builderForStage(),
Args: b.Args, Node: root,
AllowedArgs: b.AllowedArgs,
Env: b.Env,
},
Node: root,
}) })
} }
return stages, nil return stages, nil
@ -235,17 +231,30 @@ func (b *Builder) extractHeadingArgsFromNode(node *parser.Node) error {
} }
} }
// Set children equal to everything except the leading ARG nodes
node.Children = children
// Use a separate builder to evaluate the heading args
tempBuilder := NewBuilder(b.UserArgs)
// Evaluate all the heading arg commands
for _, c := range args { for _, c := range args {
step := b.Step() step := tempBuilder.Step()
if err := step.Resolve(c); err != nil { if err := step.Resolve(c); err != nil {
return err return err
} }
if err := b.Run(step, NoopExecutor, false); err != nil { if err := tempBuilder.Run(step, NoopExecutor, false); err != nil {
return err return err
} }
} }
node.Children = children // Add all of the defined heading args to the original builder's HeadingArgs map
for k, v := range tempBuilder.Args {
if _, ok := tempBuilder.AllowedArgs[k]; ok {
b.HeadingArgs[k] = v
}
}
return nil return nil
} }
@ -264,13 +273,23 @@ func extractNameFromNode(node *parser.Node) (string, bool) {
return n.Next.Value, true return n.Next.Value, true
} }
func (b *Builder) builderForStage() *Builder {
stageBuilder := NewBuilder(b.UserArgs)
for k, v := range b.HeadingArgs {
stageBuilder.HeadingArgs[k] = v
}
return stageBuilder
}
type Builder struct { type Builder struct {
RunConfig docker.Config RunConfig docker.Config
Env []string Env []string
Args map[string]string Args map[string]string
CmdSet bool HeadingArgs map[string]string
Author string UserArgs map[string]string
CmdSet bool
Author string
AllowedArgs map[string]bool AllowedArgs map[string]bool
Volumes VolumeSet Volumes VolumeSet
@ -288,12 +307,16 @@ func NewBuilder(args map[string]string) *Builder {
for k, v := range builtinAllowedBuildArgs { for k, v := range builtinAllowedBuildArgs {
allowed[k] = v allowed[k] = v
} }
provided := make(map[string]string) userArgs := make(map[string]string)
initialArgs := make(map[string]string)
for k, v := range args { for k, v := range args {
provided[k] = v userArgs[k] = v
initialArgs[k] = v
} }
return &Builder{ return &Builder{
Args: provided, Args: initialArgs,
UserArgs: userArgs,
HeadingArgs: make(map[string]string),
AllowedArgs: allowed, AllowedArgs: allowed,
} }
} }

View File

@ -216,7 +216,7 @@ func from(b *Builder, args []string, attributes map[string]bool, flagArgs []stri
// Support ARG before from // Support ARG before from
argStrs := []string{} argStrs := []string{}
for n, v := range b.Args { for n, v := range b.HeadingArgs {
argStrs = append(argStrs, n+"="+v) argStrs = append(argStrs, n+"="+v)
} }
var err error var err error
@ -598,10 +598,16 @@ func arg(b *Builder, args []string, attributes map[string]bool, flagArgs []strin
// 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 val, ok := b.HeadingArgs[name]; ok && !hasDefault {
b.Args[name] = val
}
// If there is a default value associated with this arg then add it to the // If there is a default value associated with this arg then add it to the
// b.buildArgs if one is not already passed to the builder. The args passed // b.buildArgs, later default values for the same arg override earlier ones.
// to builder override the default value of 'arg'. // The args passed to builder (UserArgs) override the default value of 'arg'
if _, ok := b.Args[name]; !ok && hasDefault { // Don't add them here as they were already set in NewBuilder.
if _, ok := b.UserArgs[name]; !ok && hasDefault {
b.Args[name] = value b.Args[name] = value
} }

13
vendor/modules.txt vendored
View File

@ -64,7 +64,7 @@ github.com/containernetworking/plugins/pkg/ns
github.com/containernetworking/plugins/pkg/utils/hwaddr github.com/containernetworking/plugins/pkg/utils/hwaddr
github.com/containernetworking/plugins/plugins/ipam/host-local/backend github.com/containernetworking/plugins/plugins/ipam/host-local/backend
github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator
# github.com/containers/buildah v1.14.5 # github.com/containers/buildah v1.14.6-0.20200402210551-e9a6703edee2
github.com/containers/buildah github.com/containers/buildah
github.com/containers/buildah/bind github.com/containers/buildah/bind
github.com/containers/buildah/chroot github.com/containers/buildah/chroot
@ -82,10 +82,12 @@ github.com/containers/buildah/pkg/secrets
github.com/containers/buildah/pkg/supplemented github.com/containers/buildah/pkg/supplemented
github.com/containers/buildah/pkg/umask github.com/containers/buildah/pkg/umask
github.com/containers/buildah/util github.com/containers/buildah/util
# github.com/containers/common v0.6.1 # github.com/containers/common v0.8.0
github.com/containers/common/pkg/apparmor
github.com/containers/common/pkg/capabilities github.com/containers/common/pkg/capabilities
github.com/containers/common/pkg/cgroupv2
github.com/containers/common/pkg/config github.com/containers/common/pkg/config
github.com/containers/common/pkg/unshare github.com/containers/common/pkg/sysinfo
# github.com/containers/conmon v2.0.14+incompatible # github.com/containers/conmon v2.0.14+incompatible
github.com/containers/conmon/runner/config github.com/containers/conmon/runner/config
# github.com/containers/image/v5 v5.3.1 # github.com/containers/image/v5 v5.3.1
@ -148,7 +150,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.16.6 # github.com/containers/storage v1.18.1
github.com/containers/storage github.com/containers/storage
github.com/containers/storage/drivers github.com/containers/storage/drivers
github.com/containers/storage/drivers/aufs github.com/containers/storage/drivers/aufs
@ -188,6 +190,7 @@ github.com/containers/storage/pkg/stringutils
github.com/containers/storage/pkg/system github.com/containers/storage/pkg/system
github.com/containers/storage/pkg/tarlog github.com/containers/storage/pkg/tarlog
github.com/containers/storage/pkg/truncindex github.com/containers/storage/pkg/truncindex
github.com/containers/storage/pkg/unshare
# github.com/coreos/go-iptables v0.4.5 # github.com/coreos/go-iptables v0.4.5
github.com/coreos/go-iptables/iptables github.com/coreos/go-iptables/iptables
# github.com/coreos/go-systemd/v22 v22.0.0 # github.com/coreos/go-systemd/v22 v22.0.0
@ -414,7 +417,7 @@ github.com/opencontainers/selinux/go-selinux/label
github.com/opencontainers/selinux/pkg/pwalk github.com/opencontainers/selinux/pkg/pwalk
# github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316 # github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316
github.com/openshift/api/config/v1 github.com/openshift/api/config/v1
# github.com/openshift/imagebuilder v1.1.3 # github.com/openshift/imagebuilder v1.1.4
github.com/openshift/imagebuilder github.com/openshift/imagebuilder
github.com/openshift/imagebuilder/dockerfile/command github.com/openshift/imagebuilder/dockerfile/command
github.com/openshift/imagebuilder/dockerfile/parser github.com/openshift/imagebuilder/dockerfile/parser