Merge pull request #5253 from rhatdan/buildah
Update to the latest version of buildah
This commit is contained in:
		
						commit
						c8436cd870
					
				| 
						 | 
				
			
			@ -84,7 +84,10 @@ func init() {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	flag.DefValue = "true"
 | 
			
		||||
	fromAndBugFlags := buildahcli.GetFromAndBudFlags(&fromAndBudValues, &userNSValues, &namespaceValues)
 | 
			
		||||
	fromAndBugFlags, err := buildahcli.GetFromAndBudFlags(&fromAndBudValues, &userNSValues, &namespaceValues)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logrus.Errorf("failed to setup podman build flags: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	flags.AddFlagSet(&budFlags)
 | 
			
		||||
	flags.AddFlagSet(&fromAndBugFlags)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										22
									
								
								go.mod
								
								
								
								
							| 
						 | 
				
			
			@ -4,19 +4,16 @@ go 1.12
 | 
			
		|||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/BurntSushi/toml v0.3.1
 | 
			
		||||
	github.com/blang/semver v3.5.1+incompatible // indirect
 | 
			
		||||
	github.com/buger/goterm v0.0.0-20181115115552-c206103e1f37
 | 
			
		||||
	github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b
 | 
			
		||||
	github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect
 | 
			
		||||
	github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784
 | 
			
		||||
	github.com/containernetworking/plugins v0.8.5
 | 
			
		||||
	github.com/containers/buildah v1.13.1
 | 
			
		||||
	github.com/containers/buildah v1.14.1-0.20200219125159-7cd6f7d04842
 | 
			
		||||
	github.com/containers/conmon v2.0.10+incompatible
 | 
			
		||||
	github.com/containers/image/v5 v5.2.1
 | 
			
		||||
	github.com/containers/psgo v1.4.0
 | 
			
		||||
	github.com/containers/storage v1.16.0
 | 
			
		||||
	github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
 | 
			
		||||
	github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
 | 
			
		||||
	github.com/cri-o/ocicni v0.1.1-0.20190920040751-deac903fd99b
 | 
			
		||||
	github.com/cyphar/filepath-securejoin v0.2.2
 | 
			
		||||
	github.com/davecgh/go-spew v1.1.1
 | 
			
		||||
| 
						 | 
				
			
			@ -25,27 +22,19 @@ require (
 | 
			
		|||
	github.com/docker/docker-credential-helpers v0.6.3
 | 
			
		||||
	github.com/docker/go-connections v0.4.0
 | 
			
		||||
	github.com/docker/go-units v0.4.0
 | 
			
		||||
	github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect
 | 
			
		||||
	github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 // indirect
 | 
			
		||||
	github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect
 | 
			
		||||
	github.com/elazarl/goproxy/ext v0.0.0-20190911111923-ecfe977594f1 // indirect
 | 
			
		||||
	github.com/etcd-io/bbolt v1.3.3
 | 
			
		||||
	github.com/fatih/camelcase v1.0.0 // indirect
 | 
			
		||||
	github.com/fsnotify/fsnotify v1.4.7
 | 
			
		||||
	github.com/ghodss/yaml v1.0.0
 | 
			
		||||
	github.com/go-ini/ini v1.51.1 // indirect
 | 
			
		||||
	github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e
 | 
			
		||||
	github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
 | 
			
		||||
	github.com/google/uuid v1.1.1
 | 
			
		||||
	github.com/gorilla/handlers v1.4.2 // indirect
 | 
			
		||||
	github.com/gorilla/mux v1.7.4
 | 
			
		||||
	github.com/gorilla/schema v1.1.0
 | 
			
		||||
	github.com/hashicorp/go-multierror v1.0.0
 | 
			
		||||
	github.com/hpcloud/tail v1.0.0
 | 
			
		||||
	github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07 // indirect
 | 
			
		||||
	github.com/json-iterator/go v1.1.9
 | 
			
		||||
	github.com/mrtazz/checkmake v0.0.0-20191009095831-03dd76b964dd // indirect
 | 
			
		||||
	github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618
 | 
			
		||||
	github.com/olekukonko/tablewriter v0.0.4 // indirect
 | 
			
		||||
	github.com/onsi/ginkgo v1.12.0
 | 
			
		||||
	github.com/onsi/gomega v1.9.0
 | 
			
		||||
	github.com/opencontainers/go-digest v1.0.0-rc1
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +45,6 @@ require (
 | 
			
		|||
	github.com/opencontainers/selinux v1.3.1
 | 
			
		||||
	github.com/opentracing/opentracing-go v1.1.0
 | 
			
		||||
	github.com/pkg/errors v0.9.1
 | 
			
		||||
	github.com/pkg/profile v1.4.0 // indirect
 | 
			
		||||
	github.com/pmezard/go-difflib v1.0.0
 | 
			
		||||
	github.com/rootless-containers/rootlesskit v0.8.0
 | 
			
		||||
	github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f
 | 
			
		||||
| 
						 | 
				
			
			@ -66,20 +54,14 @@ require (
 | 
			
		|||
	github.com/stretchr/testify v1.5.0
 | 
			
		||||
	github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
 | 
			
		||||
	github.com/uber/jaeger-client-go v2.22.1+incompatible
 | 
			
		||||
	github.com/uber/jaeger-lib v0.0.0-20190122222657-d036253de8f5 // indirect
 | 
			
		||||
	github.com/varlink/go v0.0.0-20190502142041-0f1d566d194b
 | 
			
		||||
	github.com/vishvananda/netlink v1.1.0
 | 
			
		||||
	go.uber.org/atomic v1.4.0 // indirect
 | 
			
		||||
	golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708
 | 
			
		||||
	golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect
 | 
			
		||||
	golang.org/x/sync v0.0.0-20190423024810-112230192c58
 | 
			
		||||
	golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2
 | 
			
		||||
	google.golang.org/appengine v1.6.1 // indirect
 | 
			
		||||
	google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601 // indirect
 | 
			
		||||
	gopkg.in/yaml.v2 v2.2.8
 | 
			
		||||
	gotest.tools/v3 v3.0.2 // indirect
 | 
			
		||||
	k8s.io/api v0.17.3
 | 
			
		||||
	k8s.io/apimachinery v0.17.3
 | 
			
		||||
	k8s.io/client-go v0.0.0-20190620085101-78d2af792bab
 | 
			
		||||
	k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a // indirect
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										17
									
								
								go.sum
								
								
								
								
							| 
						 | 
				
			
			@ -67,8 +67,12 @@ 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/containers/buildah v1.13.1 h1:EdhllQxXmOZ56mGFf68AkrpIj9XtEkkGq0WaPWFuGM0=
 | 
			
		||||
github.com/containers/buildah v1.13.1/go.mod h1:U0LcOzSqoYdyQC5L2hMeLbtCDuCCLxmZV1eb+SWY4GA=
 | 
			
		||||
github.com/containers/buildah v1.14.1-0.20200219125159-7cd6f7d04842 h1:OM/a/RYfWe721ZjDJf4RyGhyvEGJIdmx9tYZl1bq5jY=
 | 
			
		||||
github.com/containers/buildah v1.14.1-0.20200219125159-7cd6f7d04842/go.mod h1:dmPZHakxkaCVu5oefZaLVAZXNGva9PqVSMVK3hkarvA=
 | 
			
		||||
github.com/containers/common v0.0.7 h1:eKYZLKfJ2d/RNDgecLDFv45cHb4imYzIcrQHx1Y029M=
 | 
			
		||||
github.com/containers/common v0.0.7/go.mod h1:lhWV3MLhO1+KGE2x6v9+K38MxpjXGso+edmpkFnCOqI=
 | 
			
		||||
github.com/containers/common v0.3.0 h1:9ysL/OfPcMls1Ac3jzFA4XZJVSD/JG7Dst3uQSwQtwA=
 | 
			
		||||
github.com/containers/common v0.3.0/go.mod h1:AiPCv0ZcBOVshnup/X6MuaqkySZQZ3iBWfInjJFIl40=
 | 
			
		||||
github.com/containers/conmon v2.0.10+incompatible h1:EiwL41r5vx8SxG+dyUmbJ3baV9GUWjijPOdCkzM6gWU=
 | 
			
		||||
github.com/containers/conmon v2.0.10+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
 | 
			
		||||
github.com/containers/image/v5 v5.1.0/go.mod h1:BKlMD34WxRo1ruGHHEOrPQP0Qci7SWoPwU6fS7arsCU=
 | 
			
		||||
| 
						 | 
				
			
			@ -76,6 +80,7 @@ github.com/containers/image/v5 v5.2.0 h1:DowY5OII5x9Pb6Pt76vnHU79BgG4/jdwhZjeAj2
 | 
			
		|||
github.com/containers/image/v5 v5.2.0/go.mod h1:IAub4gDGvXoxaIAdNy4e3FbVTDPVNMv9F0UfVVFbYCU=
 | 
			
		||||
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/libpod v1.8.0/go.mod h1:53h7AOg4tQSX1rqKfR78/6Us/whERRzCQ20z0GiR44U=
 | 
			
		||||
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/ocicrypt v0.0.0-20190930154801-b87a4a69c741 h1:8tQkOcednLJtUcZgK7sPglscXtxvMOnFOa6wd09VWLM=
 | 
			
		||||
| 
						 | 
				
			
			@ -153,6 +158,8 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
 | 
			
		|||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 | 
			
		||||
github.com/fsouza/go-dockerclient v1.6.0 h1:f7j+AX94143JL1H3TiqSMkM4EcLDI0De1qD4GGn3Hig=
 | 
			
		||||
github.com/fsouza/go-dockerclient v1.6.0/go.mod h1:YWwtNPuL4XTX1SKJQk86cWPmmqwx+4np9qfPbb+znGc=
 | 
			
		||||
github.com/fsouza/go-dockerclient v1.6.1 h1:qBvbtwBTpOYktncvxjFMHxJHuGG19lb2fvAFqfXeh7w=
 | 
			
		||||
github.com/fsouza/go-dockerclient v1.6.1/go.mod h1:g2pGMa82+SdtAicFSpxGJc1Anx//HHssXyWLwMRxaqg=
 | 
			
		||||
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU=
 | 
			
		||||
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
 | 
			
		||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 | 
			
		||||
| 
						 | 
				
			
			@ -199,6 +206,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
 | 
			
		|||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
 | 
			
		||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
			
		||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
 | 
			
		||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
 | 
			
		||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
 | 
			
		||||
| 
						 | 
				
			
			@ -241,6 +249,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
 | 
			
		|||
github.com/insomniacslk/dhcp v0.0.0-20190712084813-dc1a53400564/go.mod h1:CfMdguCK66I5DAUJgGKyNz8aB6vO5dZzkm9Xep6WGvw=
 | 
			
		||||
github.com/ishidawataru/sctp v0.0.0-20180918013207-6e2cb1366111 h1:NAAiV9ass6VReWFjuxqrMIq12WKlSULI6Gs3PxQghLA=
 | 
			
		||||
github.com/ishidawataru/sctp v0.0.0-20180918013207-6e2cb1366111/go.mod h1:DM4VvS+hD/kDi1U1QsX2fnZowwBhqD0Dk3bRPKF/Oc8=
 | 
			
		||||
github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07 h1:rw3IAne6CDuVFlZbPOkA7bhxlqawFh7RJJ+CejfMaxE=
 | 
			
		||||
github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
 | 
			
		||||
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
 | 
			
		||||
github.com/jamescun/tuntap v0.0.0-20190712092105-cb1fb277045c/go.mod h1:zzwpsgcYhzzIP5WyF8g9ivCv38cY9uAV9Gu0m3lThhE=
 | 
			
		||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 | 
			
		||||
| 
						 | 
				
			
			@ -303,6 +313,7 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN
 | 
			
		|||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
			
		||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
 | 
			
		||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
			
		||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE=
 | 
			
		||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
 | 
			
		||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
 | 
			
		||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
 | 
			
		||||
| 
						 | 
				
			
			@ -397,6 +408,8 @@ github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa
 | 
			
		|||
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
 | 
			
		||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
 | 
			
		||||
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
 | 
			
		||||
github.com/rhatdan/buildah v0.0.0-20200218224501-fc6baddc9762 h1:HO8tASQj1anmipujM8qxt3XEmJGQfjc8xW6ksRkZpic=
 | 
			
		||||
github.com/rhatdan/buildah v0.0.0-20200218224501-fc6baddc9762/go.mod h1:dmPZHakxkaCVu5oefZaLVAZXNGva9PqVSMVK3hkarvA=
 | 
			
		||||
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
 | 
			
		||||
github.com/rootless-containers/rootlesskit v0.7.2 h1:gcWQ9/GN98ne1AqnoeOgQ8e6qpKd3BuB4ug+2h95Fr0=
 | 
			
		||||
github.com/rootless-containers/rootlesskit v0.7.2/go.mod h1:r9YL5mKRIdnwcYk4G8E5CSc9MDeFtgYmhfE4CSvDGYA=
 | 
			
		||||
| 
						 | 
				
			
			@ -479,6 +492,7 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b/go.mod h1:N2
 | 
			
		|||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
 | 
			
		||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
 | 
			
		||||
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
 | 
			
		||||
github.com/xeipuuv/gojsonschema v0.0.0-20190816131739-be0936907f66 h1:F6RPtD6im1kY4bmLByRlOLOZwsPP7mw7cxR1v2CotL0=
 | 
			
		||||
github.com/xeipuuv/gojsonschema v0.0.0-20190816131739-be0936907f66/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
 | 
			
		||||
github.com/xeipuuv/gojsonschema v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg=
 | 
			
		||||
github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
 | 
			
		||||
| 
						 | 
				
			
			@ -569,6 +583,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		|||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 | 
			
		||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 | 
			
		||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 | 
			
		||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wktg7Jn/a/fNmr33HSj8g=
 | 
			
		||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 h1:xQwXv67TxFo9nC1GJFyab5eq/5B590r6RlnL/G8Sz7w=
 | 
			
		||||
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
| 
						 | 
				
			
			@ -589,6 +604,8 @@ golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgw
 | 
			
		|||
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
 | 
			
		||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
 | 
			
		||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,24 +5,33 @@ env:
 | 
			
		|||
    ####
 | 
			
		||||
    #### Global variables used for all tasks
 | 
			
		||||
    ####
 | 
			
		||||
    # Name of the ultimate destination branch for this CI run, PR or post-merge.
 | 
			
		||||
    DEST_BRANCH: "master"
 | 
			
		||||
    GOPATH: "/var/tmp/go"
 | 
			
		||||
    GOSRC: "${GOPATH}/src/github.com/containers/buildah"
 | 
			
		||||
    # Overrides default location (/tmp/cirrus) for repo clone
 | 
			
		||||
    CIRRUS_WORKING_DIR: "/var/tmp/go/src/github.com/containers/buildah"
 | 
			
		||||
    CIRRUS_WORKING_DIR: "${GOSRC}"
 | 
			
		||||
    # Shell used to execute all script commands
 | 
			
		||||
    CIRRUS_SHELL: "/bin/bash"
 | 
			
		||||
    # Automation script path relative to $CIRRUS_WORKING_DIR)
 | 
			
		||||
    SCRIPT_BASE: "./contrib/cirrus"
 | 
			
		||||
    # No need to go crazy, but grab enough to cover most PRs
 | 
			
		||||
    CIRRUS_CLONE_DEPTH: 50
 | 
			
		||||
    # Unless set by in_podman.sh, default to operating outside of a podman container
 | 
			
		||||
    IN_PODMAN: 'false'
 | 
			
		||||
    # Not cross-compiling by default
 | 
			
		||||
    CROSS_TARGET: ""
 | 
			
		||||
 | 
			
		||||
    ####
 | 
			
		||||
    #### Cache-image names to test with
 | 
			
		||||
    ####
 | 
			
		||||
    # GCE project where images live
 | 
			
		||||
    IMAGE_PROJECT: "libpod-218412"
 | 
			
		||||
    # TODO: Setting up from base-images is very inefficient, use libpod's cache-images instead?
 | 
			
		||||
    FEDORA_CACHE_IMAGE_NAME: "fedora-cloud-base-30-1-2-1565360543"
 | 
			
		||||
    PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-cloud-base-29-1-2-1565360543"
 | 
			
		||||
    UBUNTU_CACHE_IMAGE_NAME: "ubuntu-1904-disco-v20190724"          # Latest
 | 
			
		||||
    PRIOR_UBUNTU_CACHE_IMAGE_NAME: "ubuntu-1804-bionic-v20190722a"  # LTS
 | 
			
		||||
    UBUNTU_CACHE_IMAGE_NAME: "ubuntu-1904-disco-v20190724"
 | 
			
		||||
    PRIOR_UBUNTU_CACHE_IMAGE_NAME: "ubuntu-1804-bionic-v20190722a"
 | 
			
		||||
 | 
			
		||||
    ####
 | 
			
		||||
    #### Command variables to help avoid duplication
 | 
			
		||||
| 
						 | 
				
			
			@ -30,10 +39,6 @@ env:
 | 
			
		|||
    # Command to prefix every output line with a timestamp
 | 
			
		||||
    # (can't do inline awk script, Cirrus-CI or YAML mangles quoting)
 | 
			
		||||
    _TIMESTAMP: 'awk -f ${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/timestamp.awk'
 | 
			
		||||
    _DFCMD: 'df -lhTx tmpfs'
 | 
			
		||||
    _RAUDITCMD: 'cat /var/log/audit/audit.log'
 | 
			
		||||
    _UAUDITCMD: 'cat /var/log/kern.log'
 | 
			
		||||
    _JOURNALCMD: 'journalctl -b'
 | 
			
		||||
 | 
			
		||||
gcp_credentials: ENCRYPTED[ae0bf7370f0b6e446bc61d0865a2c55d3e166b3fab9466eb0393e38e1c66a31ca4c71ddc7e0139d47d075c36dd6d3fd7]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -50,61 +55,11 @@ gce_instance:
 | 
			
		|||
    image_name: "${FEDORA_CACHE_IMAGE_NAME}"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
testing_task:
 | 
			
		||||
    gce_instance:  # Only need to specify differences from defaults (above)
 | 
			
		||||
        matrix:  # Duplicate this task for each matrix product.
 | 
			
		||||
            image_name: "${FEDORA_CACHE_IMAGE_NAME}"
 | 
			
		||||
            image_name: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}"
 | 
			
		||||
            image_name: "${UBUNTU_CACHE_IMAGE_NAME}"
 | 
			
		||||
            image_name: "${PRIOR_UBUNTU_CACHE_IMAGE_NAME}"
 | 
			
		||||
 | 
			
		||||
    # Separate scripts for separate outputs, makes debugging easier.
 | 
			
		||||
    setup_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
 | 
			
		||||
    build_and_test_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/build_and_test.sh |& ${_TIMESTAMP}'
 | 
			
		||||
 | 
			
		||||
    # Log collection when job was successful
 | 
			
		||||
    df_script: '${_DFCMD} || true'
 | 
			
		||||
    rh_audit_log_script: '${_RAUDITCMD} || true'
 | 
			
		||||
    ubuntu_audit_log_script: '${_UAUDITCMD} || true'
 | 
			
		||||
    journal_log_script: '${_JOURNALCMD} || true'
 | 
			
		||||
 | 
			
		||||
    on_failure:  # Script names must be different from above
 | 
			
		||||
        failure_df_script: '${_DFCMD} || true'
 | 
			
		||||
        failure_rh_audit_log_script: '${_RAUDITCMD} || true'
 | 
			
		||||
        failure_ubuntu_audit_log_script: '${_UAUDITCMD} || true'
 | 
			
		||||
        failure_journal_log_script: '${_JOURNALCMD} || true'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# This task runs `make vendor` followed by ./hack/tree_status.sh to check
 | 
			
		||||
# whether the git tree is clean.  The reasoning for that is to make sure
 | 
			
		||||
# that the vendor.conf, the code and the vendored packages in ./vendor are
 | 
			
		||||
# in sync at all times.
 | 
			
		||||
vendor_task:
 | 
			
		||||
 | 
			
		||||
    only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*'
 | 
			
		||||
 | 
			
		||||
    env:
 | 
			
		||||
        CIRRUS_WORKING_DIR: "/var/tmp/go/src/github.com/containers/buildah"
 | 
			
		||||
        GOPATH: "/go"
 | 
			
		||||
        GOSRC: "/go/src/github.com/containers/buildah"
 | 
			
		||||
 | 
			
		||||
    # Runs within Cirrus's "community cluster"
 | 
			
		||||
    container:
 | 
			
		||||
        image: docker.io/library/golang:1.13
 | 
			
		||||
        cpu: 1
 | 
			
		||||
        memory: 1
 | 
			
		||||
 | 
			
		||||
    timeout_in: 30m
 | 
			
		||||
 | 
			
		||||
    vendor_script:
 | 
			
		||||
        - 'cd ${CIRRUS_WORKING_DIR} && make vendor'
 | 
			
		||||
        - 'cd ${CIRRUS_WORKING_DIR} && ./hack/tree_status.sh'
 | 
			
		||||
 | 
			
		||||
# Update metadata on VM images referenced by this repository state
 | 
			
		||||
meta_task:
 | 
			
		||||
'cirrus-ci/only_prs/meta_task':
 | 
			
		||||
 | 
			
		||||
    depends_on:
 | 
			
		||||
        - "vendor"
 | 
			
		||||
    # see bors.toml
 | 
			
		||||
    skip: $CIRRUS_BRANCH =~ ".*\.tmp"
 | 
			
		||||
 | 
			
		||||
    container:
 | 
			
		||||
        image: "quay.io/libpod/imgts:latest"  # see contrib/imgts
 | 
			
		||||
| 
						 | 
				
			
			@ -126,3 +81,174 @@ meta_task:
 | 
			
		|||
        CIRRUS_CLONE_DEPTH: 1  # source not used
 | 
			
		||||
 | 
			
		||||
    script: '/usr/local/bin/entrypoint.sh |& ${_TIMESTAMP}'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
'cirrus-ci/only_prs/gate_task':
 | 
			
		||||
 | 
			
		||||
    # see bors.toml
 | 
			
		||||
    skip: $CIRRUS_BRANCH =~ ".*\.tmp"
 | 
			
		||||
 | 
			
		||||
    timeout_in: 30m
 | 
			
		||||
 | 
			
		||||
    setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
 | 
			
		||||
    build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}'
 | 
			
		||||
    validate_test_script: '${SCRIPT_BASE}/test.sh validate |& ${_TIMESTAMP}'
 | 
			
		||||
 | 
			
		||||
    binary_artifacts:
 | 
			
		||||
        path: ./bin/*
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
'cirrus-ci/only_prs/unit_task':
 | 
			
		||||
 | 
			
		||||
    # see bors.toml
 | 
			
		||||
    skip: $CIRRUS_BRANCH =~ ".*\.tmp"
 | 
			
		||||
 | 
			
		||||
    # not supported by bors-ng
 | 
			
		||||
    # allow_failures: $CI == $CI
 | 
			
		||||
 | 
			
		||||
    timeout_in: 30m
 | 
			
		||||
 | 
			
		||||
    setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
 | 
			
		||||
    build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}'
 | 
			
		||||
    # FIXME: These tests mostly/always fail
 | 
			
		||||
    unit_test_script: '${SCRIPT_BASE}/test.sh unit |& ${_TIMESTAMP} || true'
 | 
			
		||||
 | 
			
		||||
    binary_artifacts:
 | 
			
		||||
        path: ./bin/*
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# This task runs `make vendor` followed by ./hack/tree_status.sh to check
 | 
			
		||||
# whether the git tree is clean.  The reasoning for that is to make sure
 | 
			
		||||
# that the vendor.conf, the code and the vendored packages in ./vendor are
 | 
			
		||||
# in sync at all times.
 | 
			
		||||
'cirrus-ci/only_prs/vendor_task':
 | 
			
		||||
 | 
			
		||||
    # see bors.toml
 | 
			
		||||
    skip: $CIRRUS_BRANCH =~ ".*\.tmp"
 | 
			
		||||
 | 
			
		||||
    env:
 | 
			
		||||
        CIRRUS_WORKING_DIR: "/var/tmp/go/src/github.com/containers/buildah"
 | 
			
		||||
        GOPATH: "/var/tmp/go"
 | 
			
		||||
        GOSRC: "/var/tmp/go/src/github.com/containers/buildah"
 | 
			
		||||
 | 
			
		||||
    # Runs within Cirrus's "community cluster"
 | 
			
		||||
    container:
 | 
			
		||||
        image: docker.io/library/golang:1.13
 | 
			
		||||
        cpu: 1
 | 
			
		||||
        memory: 1
 | 
			
		||||
 | 
			
		||||
    timeout_in: 5m
 | 
			
		||||
 | 
			
		||||
    vendor_script:
 | 
			
		||||
        - 'make vendor'
 | 
			
		||||
        - './hack/tree_status.sh'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
'cirrus-ci/only_prs/cross_task':
 | 
			
		||||
 | 
			
		||||
    # see bors.toml
 | 
			
		||||
    skip: $CIRRUS_BRANCH =~ ".*\.tmp"
 | 
			
		||||
 | 
			
		||||
    depends_on:
 | 
			
		||||
        - 'cirrus-ci/only_prs/gate'
 | 
			
		||||
        - 'cirrus-ci/only_prs/vendor'
 | 
			
		||||
 | 
			
		||||
    container:
 | 
			
		||||
        image: registry.fedoraproject.org/fedora:30
 | 
			
		||||
 | 
			
		||||
    env:
 | 
			
		||||
        matrix:
 | 
			
		||||
            CROSS_TARGET: darwin
 | 
			
		||||
 | 
			
		||||
    setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
 | 
			
		||||
    build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}'
 | 
			
		||||
 | 
			
		||||
    binary_artifacts:
 | 
			
		||||
        path: ./bin/*
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
'cirrus-ci/required/testing_task':
 | 
			
		||||
 | 
			
		||||
    # see bors.toml
 | 
			
		||||
    skip: $CIRRUS_BRANCH =~ ".*\.tmp"
 | 
			
		||||
 | 
			
		||||
    depends_on:
 | 
			
		||||
        - 'cirrus-ci/only_prs/gate'
 | 
			
		||||
        - 'cirrus-ci/only_prs/vendor'
 | 
			
		||||
 | 
			
		||||
    gce_instance:  # Only need to specify differences from defaults (above)
 | 
			
		||||
        matrix:  # Duplicate this task for each matrix product.
 | 
			
		||||
            image_name: "${FEDORA_CACHE_IMAGE_NAME}"
 | 
			
		||||
            # TODO: Re-enable once prior image is F30 and above is F31
 | 
			
		||||
            # image_name: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}"
 | 
			
		||||
            image_name: "${UBUNTU_CACHE_IMAGE_NAME}"
 | 
			
		||||
            image_name: "${PRIOR_UBUNTU_CACHE_IMAGE_NAME}"
 | 
			
		||||
 | 
			
		||||
    # Separate scripts for separate outputs, makes debugging easier.
 | 
			
		||||
    setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
 | 
			
		||||
    build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}'
 | 
			
		||||
    integration_test_script: '${SCRIPT_BASE}/test.sh integration |& ${_TIMESTAMP}'
 | 
			
		||||
 | 
			
		||||
    binary_artifacts:
 | 
			
		||||
        path: ./bin/*
 | 
			
		||||
 | 
			
		||||
    always: &standardlogs
 | 
			
		||||
        audit_log_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh audit'
 | 
			
		||||
        df_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh df'
 | 
			
		||||
        journal_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh journal'
 | 
			
		||||
        podman_system_info_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh podman'
 | 
			
		||||
        buildah_version_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh buildah_version'
 | 
			
		||||
        buildah_info_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh buildah_info'
 | 
			
		||||
        package_versions_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh packages'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
'cirrus-ci/required/in_podman_task':
 | 
			
		||||
 | 
			
		||||
    # see bors.toml
 | 
			
		||||
    skip: $CIRRUS_BRANCH =~ ".*\.tmp"
 | 
			
		||||
 | 
			
		||||
    depends_on:
 | 
			
		||||
        - 'cirrus-ci/only_prs/gate'
 | 
			
		||||
        - 'cirrus-ci/only_prs/vendor'
 | 
			
		||||
 | 
			
		||||
    env:
 | 
			
		||||
        # This is key, it causes the scripts to re-execute themselves inside a container.
 | 
			
		||||
        IN_PODMAN: 'true'
 | 
			
		||||
        BUILDAH_ISOLATION: 'chroot'
 | 
			
		||||
        STORAGE_DRIVER: 'vfs'
 | 
			
		||||
        STORAGE_OPTIONS: ''
 | 
			
		||||
 | 
			
		||||
    # Separate scripts for separate outputs, makes debugging easier.
 | 
			
		||||
    setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
 | 
			
		||||
    build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}'
 | 
			
		||||
    integration_test_script: '${SCRIPT_BASE}/test.sh integration |& ${_TIMESTAMP}'
 | 
			
		||||
 | 
			
		||||
    binary_artifacts:
 | 
			
		||||
        path: ./bin/*
 | 
			
		||||
 | 
			
		||||
    always:
 | 
			
		||||
        <<: *standardlogs
 | 
			
		||||
 | 
			
		||||
# TODO: Bors-ng has trouble interpreting multiple status-checks as being required
 | 
			
		||||
#       when their names contain wild-cards (like `testing%`).  Until that issue
 | 
			
		||||
#       can be fixed, use a single "test" to represent pass/fail status of all
 | 
			
		||||
#       required checks.
 | 
			
		||||
'cirrus-ci/success_task':
 | 
			
		||||
 | 
			
		||||
    # see bors.toml
 | 
			
		||||
    skip: $CIRRUS_BRANCH =~ ".*\.tmp"
 | 
			
		||||
 | 
			
		||||
    depends_on:
 | 
			
		||||
        - "cirrus-ci/required/testing"
 | 
			
		||||
        - "cirrus-ci/required/in_podman"
 | 
			
		||||
 | 
			
		||||
    env:
 | 
			
		||||
        CIRRUS_WORKING_DIR: /tmp
 | 
			
		||||
        CIRRUS_CLONE_DEPTH: 1  # no code is being used by this task
 | 
			
		||||
 | 
			
		||||
    container:
 | 
			
		||||
        image: "registry.fedoraproject.org/fedora-minimal:latest"
 | 
			
		||||
        cpu: 1
 | 
			
		||||
        memory: 1
 | 
			
		||||
 | 
			
		||||
    script: /bin/true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,42 +0,0 @@
 | 
			
		|||
#!/bin/bash
 | 
			
		||||
set -xeuo pipefail
 | 
			
		||||
export GOPATH=/go
 | 
			
		||||
export PATH=$HOME/gopath/bin:$PATH:$GOPATH/bin
 | 
			
		||||
export GOSRC=$GOPATH/src/github.com/containers/buildah
 | 
			
		||||
 | 
			
		||||
cp -fv /etc/yum.repos.d{.host/*.repo,}
 | 
			
		||||
 | 
			
		||||
dnf install -y \
 | 
			
		||||
  bats \
 | 
			
		||||
  btrfs-progs-devel \
 | 
			
		||||
  bzip2 \
 | 
			
		||||
  device-mapper-devel \
 | 
			
		||||
  findutils \
 | 
			
		||||
  git \
 | 
			
		||||
  glib2-devel \
 | 
			
		||||
  glibc-static \
 | 
			
		||||
  gnupg \
 | 
			
		||||
  golang \
 | 
			
		||||
  gpgme-devel \
 | 
			
		||||
  libassuan-devel \
 | 
			
		||||
  libseccomp-devel \
 | 
			
		||||
  libselinux-devel \
 | 
			
		||||
  libselinux-static \
 | 
			
		||||
  libseccomp-static \
 | 
			
		||||
  libselinux-utils \
 | 
			
		||||
  make \
 | 
			
		||||
  openssl \
 | 
			
		||||
  skopeo-containers \
 | 
			
		||||
  which
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Install gomega
 | 
			
		||||
go get github.com/onsi/gomega/...
 | 
			
		||||
 | 
			
		||||
# PAPR adds a merge commit, for testing, which fails the
 | 
			
		||||
# short-commit-subject validation test, so tell git-validate.sh to only check
 | 
			
		||||
# up to, but not including, the merge commit.
 | 
			
		||||
export GITVALIDATE_TIP=$(cd $GOSRC; git log -2 --pretty='%H' | tail -n 1)
 | 
			
		||||
make -C $GOSRC install.tools runc all validate test-unit test-integration static
 | 
			
		||||
env BUILDAH_ISOLATION=chroot make -C $GOSRC test-integration
 | 
			
		||||
env BUILDAH_ISOLATION=rootless make -C $GOSRC test-integration
 | 
			
		||||
| 
						 | 
				
			
			@ -1,87 +0,0 @@
 | 
			
		|||
branches:
 | 
			
		||||
  - master
 | 
			
		||||
  - auto
 | 
			
		||||
  - try
 | 
			
		||||
 | 
			
		||||
host:
 | 
			
		||||
  # 29 is the highest level of atomic
 | 
			
		||||
  distro: fedora/29/atomic
 | 
			
		||||
 | 
			
		||||
required: true
 | 
			
		||||
 | 
			
		||||
tests:
 | 
			
		||||
  #  Let's create a self signed certificate and get it in the right places
 | 
			
		||||
  - hostname
 | 
			
		||||
  - ip a
 | 
			
		||||
  - ping -c 3 localhost
 | 
			
		||||
  - cat /etc/hostname
 | 
			
		||||
  - mkdir -p /home/travis/auth
 | 
			
		||||
  - openssl req -newkey rsa:4096 -nodes -sha256 -keyout /home/travis/auth/domain.key -x509 -days 2 -out /home/travis/auth/domain.crt -subj "/C=US/ST=Foo/L=Bar/O=Red Hat, Inc./CN=localhost"
 | 
			
		||||
  - cp /home/travis/auth/domain.crt /home/travis/auth/domain.cert
 | 
			
		||||
  - sudo mkdir -p /etc/docker/certs.d/docker.io/
 | 
			
		||||
  - sudo cp /home/travis/auth/domain.crt /etc/docker/certs.d/docker.io/ca.crt
 | 
			
		||||
  - sudo mkdir -p /etc/docker/certs.d/localhost:5000/
 | 
			
		||||
  - sudo cp /home/travis/auth/domain.crt /etc/docker/certs.d/localhost:5000/ca.crt
 | 
			
		||||
  - sudo cp /home/travis/auth/domain.crt /etc/docker/certs.d/localhost:5000/domain.crt
 | 
			
		||||
  # Create the credentials file, then start up the Docker registry
 | 
			
		||||
  - podman run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > /home/travis/auth/htpasswd
 | 
			
		||||
  - podman run -d -p 5000:5000 --name registry -v /home/travis/auth:/home/travis/auth:Z -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/home/travis/auth/htpasswd -e REGISTRY_HTTP_TLS_CERTIFICATE=/home/travis/auth/domain.crt -e REGISTRY_HTTP_TLS_KEY=/home/travis/auth/domain.key registry:2
 | 
			
		||||
 | 
			
		||||
# Test Podman setup
 | 
			
		||||
  - podman version
 | 
			
		||||
  - podman info
 | 
			
		||||
  - podman ps --all
 | 
			
		||||
  - podman images
 | 
			
		||||
  - ls -alF /home/travis/auth
 | 
			
		||||
  - podman pull alpine
 | 
			
		||||
  - podman login localhost:5000 --username testuser --password testpassword
 | 
			
		||||
  - podman tag alpine localhost:5000/my-alpine
 | 
			
		||||
  - podman push --creds=testuser:testpassword localhost:5000/my-alpine
 | 
			
		||||
  - podman ps --all
 | 
			
		||||
  - podman images
 | 
			
		||||
  - podman rmi docker.io/alpine
 | 
			
		||||
  - podman rmi localhost:5000/my-alpine
 | 
			
		||||
  - podman pull --creds=testuser:testpassword localhost:5000/my-alpine
 | 
			
		||||
  - podman ps --all
 | 
			
		||||
  - podman images
 | 
			
		||||
  - podman rmi localhost:5000/my-alpine
 | 
			
		||||
 | 
			
		||||
  # mount yum repos to inherit injected mirrors from PAPR
 | 
			
		||||
  - podman run --net=host --security-opt label=disable --cap-add all --security-opt seccomp=unconfined -v /etc/yum.repos.d:/etc/yum.repos.d.host:ro
 | 
			
		||||
    -v $PWD:/go/src/github.com/containers/buildah
 | 
			
		||||
    --workdir /go/src/github.com/containers/buildah
 | 
			
		||||
    registry.fedoraproject.org/fedora:30 bash -c sh ./.papr.sh
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
container:
 | 
			
		||||
    image: registry.fedoraproject.org/fedora:30
 | 
			
		||||
 | 
			
		||||
packages:
 | 
			
		||||
    - btrfs-progs-devel
 | 
			
		||||
    - bzip2
 | 
			
		||||
    - device-mapper-devel
 | 
			
		||||
    - findutils
 | 
			
		||||
    - git
 | 
			
		||||
    - glib2-devel
 | 
			
		||||
    - gnupg
 | 
			
		||||
    - golang
 | 
			
		||||
    - libassuan-devel
 | 
			
		||||
    - make
 | 
			
		||||
    - skopeo-containers
 | 
			
		||||
 | 
			
		||||
required: false
 | 
			
		||||
pulls: true
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
    GOPATH: /go
 | 
			
		||||
    GOSRC: /go/src/github.com/containers
 | 
			
		||||
 | 
			
		||||
tests:
 | 
			
		||||
    - mkdir -p $GOSRC && ln -s /var/tmp/checkout $GOSRC/buildah
 | 
			
		||||
    - cd $GOSRC/buildah && make darwin
 | 
			
		||||
 | 
			
		||||
artifacts:
 | 
			
		||||
    - test-suite.log
 | 
			
		||||
 | 
			
		||||
context: "darwin CI"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,95 +0,0 @@
 | 
			
		|||
language: go
 | 
			
		||||
dist: xenial
 | 
			
		||||
sudo: required
 | 
			
		||||
go:
 | 
			
		||||
    - 1.13.x
 | 
			
		||||
    - tip
 | 
			
		||||
go_import_path: github.com/containers/buildah
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
    global:
 | 
			
		||||
        - TRAVIS_ENV="-e TRAVIS=$TRAVIS
 | 
			
		||||
                      -e CI=$CI
 | 
			
		||||
                      -e TRAVIS_COMMIT=$TRAVIS_COMMIT
 | 
			
		||||
                      -e TRAVIS_COMMIT_RANGE=$TRAVIS_COMMIT_RANGE
 | 
			
		||||
                      -e TRAVIS_REPO_SLUG=$TRAVIS_REPO_SLUG
 | 
			
		||||
                      -e TRAVIS_PULL_REQUEST=$TRAVIS_PULL_REQUEST
 | 
			
		||||
                      -e TRAVIS_PULL_REQUEST_SHA=$TRAVIS_PULL_REQUEST_SHA
 | 
			
		||||
                      -e TRAVIS_PULL_REQUEST_SLUG=$TRAVIS_PULL_REQUEST_SLUG
 | 
			
		||||
                      -e TRAVIS_BRANCH=$TRAVIS_BRANCH
 | 
			
		||||
                      -e TRAVIS_JOB_ID=$TRAVIS_JOB_ID
 | 
			
		||||
                      -e TRAVIS_BUILD_DIR=$TRAVIS_BUILD_DIR"
 | 
			
		||||
    matrix:
 | 
			
		||||
        - BUILDAH_ISOLATION=oci
 | 
			
		||||
          DISTRO="ubuntu"
 | 
			
		||||
        - BUILDAH_ISOLATION=chroot
 | 
			
		||||
          DISTRO="ubuntu"
 | 
			
		||||
        - BUILDAH_ISOLATION=rootless
 | 
			
		||||
          DISTRO="ubuntu"
 | 
			
		||||
matrix:
 | 
			
		||||
  # If the latest unstable development version of go fails, that's OK.
 | 
			
		||||
  allow_failures:
 | 
			
		||||
    - go: tip
 | 
			
		||||
    - env: TEST_GROUP=conformance
 | 
			
		||||
 | 
			
		||||
  # Don't hold on the tip tests to finish.  Mark tests green if the
 | 
			
		||||
  # stable versions pass.
 | 
			
		||||
  fast_finish: true
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
    - docker
 | 
			
		||||
before_install:
 | 
			
		||||
    - sudo apt-get -qq install software-properties-common
 | 
			
		||||
    - sudo add-apt-repository -y ppa:duggan/bats
 | 
			
		||||
    - sudo apt-get update
 | 
			
		||||
    - sudo apt-get -qq install bats btrfs-tools git libapparmor-dev libc-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libselinux1-dev linux-libc-dev realpath e2fslibs-dev libfuse-dev codespell
 | 
			
		||||
    - sudo apt-get -qq update
 | 
			
		||||
    - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
 | 
			
		||||
    - mkdir /home/travis/auth
 | 
			
		||||
    - sudo mkdir -p /var/lib/containers/storage/overlay
 | 
			
		||||
install:
 | 
			
		||||
    #  Let's create a self signed certificate and get it in the right places
 | 
			
		||||
    - hostname
 | 
			
		||||
    - ip a
 | 
			
		||||
    - ping -c 3 localhost
 | 
			
		||||
    - cat /etc/hostname
 | 
			
		||||
    - openssl req -newkey rsa:4096 -nodes -sha256 -keyout /home/travis/auth/domain.key -x509 -days 2 -out /home/travis/auth/domain.crt -subj "/C=US/ST=Foo/L=Bar/O=Red Hat, Inc./CN=localhost"
 | 
			
		||||
    - cp /home/travis/auth/domain.crt /home/travis/auth/domain.cert
 | 
			
		||||
    - sudo mkdir -p /etc/docker/certs.d/docker.io/
 | 
			
		||||
    - sudo cp /home/travis/auth/domain.crt /etc/docker/certs.d/docker.io/ca.crt
 | 
			
		||||
    - sudo mkdir -p /etc/docker/certs.d/localhost:5000/
 | 
			
		||||
    - sudo cp /home/travis/auth/domain.crt /etc/docker/certs.d/localhost:5000/ca.crt
 | 
			
		||||
    - sudo cp /home/travis/auth/domain.crt /etc/docker/certs.d/localhost:5000/domain.crt
 | 
			
		||||
    # Create the credentials file, then start up the Docker registry
 | 
			
		||||
    - docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > /home/travis/auth/htpasswd
 | 
			
		||||
    - docker run -d -p 5000:5000 --name registry -v /home/travis/auth:/home/travis/auth:Z -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/home/travis/auth/htpasswd -e REGISTRY_HTTP_TLS_CERTIFICATE=/home/travis/auth/domain.crt -e REGISTRY_HTTP_TLS_KEY=/home/travis/auth/domain.key registry:2
 | 
			
		||||
script:
 | 
			
		||||
    # Fail fast
 | 
			
		||||
    - set -e
 | 
			
		||||
    # Let's do some docker stuff just for verification purposes
 | 
			
		||||
# Commented out the following in order to get travis runs
 | 
			
		||||
# under the 50 minute requirement.  Do not remove as we may
 | 
			
		||||
# want to use this in cirrius testing when we move there.
 | 
			
		||||
#    - docker ps --all
 | 
			
		||||
#    - docker images
 | 
			
		||||
#    - ls -alF /home/travis/auth
 | 
			
		||||
#    - docker pull docker.io/alpine
 | 
			
		||||
#    - echo testpassword | docker login localhost:5000 --username testuser --password-stdin
 | 
			
		||||
#    - docker tag alpine localhost:5000/my-alpine
 | 
			
		||||
#    - docker push localhost:5000/my-alpine
 | 
			
		||||
#    - docker ps --all
 | 
			
		||||
#    - docker images
 | 
			
		||||
#    - docker rmi docker.io/alpine
 | 
			
		||||
#    - docker rmi localhost:5000/my-alpine
 | 
			
		||||
#    - docker pull localhost:5000/my-alpine
 | 
			
		||||
#    - docker ps --all
 | 
			
		||||
#    - docker images
 | 
			
		||||
#    - docker rmi localhost:5000/my-alpine
 | 
			
		||||
# End Speed up comment
 | 
			
		||||
    # Setting up  Docker Registry is complete, let's do Buildah testing!
 | 
			
		||||
    - make install.tools -j4
 | 
			
		||||
    - make install.libseccomp.sudo all runc validate lint SECURITYTAGS="apparmor seccomp"
 | 
			
		||||
    - go test -c -tags "apparmor seccomp `./btrfs_tag.sh` `./libdm_tag.sh` `./selinux_tag.sh`" ./cmd/buildah
 | 
			
		||||
    - tmp=`mktemp -d`; mkdir $tmp/root $tmp/runroot; sudo PATH="$PATH" ./buildah.test -test.v --root $tmp/root --runroot $tmp/runroot --storage-driver vfs --signature-policy `pwd`/tests/policy.json --registries-conf `pwd`/tests/registries.conf
 | 
			
		||||
    - cd tests; sudo PATH="$PATH" ./test_runner.sh
 | 
			
		||||
    - cd ..
 | 
			
		||||
| 
						 | 
				
			
			@ -2,8 +2,41 @@
 | 
			
		|||
 | 
			
		||||
# Changelog
 | 
			
		||||
 | 
			
		||||
## v1.14.0 (2020-02-05)
 | 
			
		||||
    bump github.com/mtrmac/gpgme
 | 
			
		||||
    Update containers/common to v0.1.4
 | 
			
		||||
    manifest push: add --format option
 | 
			
		||||
    Bump github.com/onsi/gomega from 1.8.1 to 1.9.0
 | 
			
		||||
    vendor github.com/containers/image/v5@v5.2.0
 | 
			
		||||
    info test: deal with random key order
 | 
			
		||||
    Bump back to v1.14.0-dev
 | 
			
		||||
 | 
			
		||||
## v1.13.2 (2020-01-29)
 | 
			
		||||
    sign.bats: set GPG_TTY=/dev/null
 | 
			
		||||
    Fix parse_unsupported.go
 | 
			
		||||
    getDateAndDigestAndSize(): use manifest.Digest
 | 
			
		||||
    Bump github.com/opencontainers/selinux from 1.3.0 to 1.3.1
 | 
			
		||||
    Bump github.com/containers/common from 0.1.0 to 0.1.2
 | 
			
		||||
    Touch up os/arch doc
 | 
			
		||||
    chroot: handle slightly broken seccomp defaults
 | 
			
		||||
    buildahimage: specify fuse-overlayfs mount options
 | 
			
		||||
    Bump github.com/mattn/go-shellwords from 1.0.7 to 1.0.9
 | 
			
		||||
    copy.bats: make sure we detect failures due to missing source
 | 
			
		||||
    parse: don't complain about not being able to rename something to itself
 | 
			
		||||
    Makefile: use a $(GO_TEST) macro, fix a typo
 | 
			
		||||
    manifests: unit test fix
 | 
			
		||||
    Fix build for 32bit platforms
 | 
			
		||||
    Allow users to set OS and architecture on bud
 | 
			
		||||
    Fix COPY in containerfile with envvar
 | 
			
		||||
    Bump c/storage to v1.15.7
 | 
			
		||||
    add --sign-by to bud/commit/push, --remove-signatures for pull/push
 | 
			
		||||
    Remove cut/paste error in CHANGELOG.md
 | 
			
		||||
    Update vendor of containers/common to v0.1.0
 | 
			
		||||
    update install instructions for Debian, Raspbian and Ubuntu
 | 
			
		||||
    Add support for containers.conf
 | 
			
		||||
    Bump back to v1.14.0-dev
 | 
			
		||||
 | 
			
		||||
## v1.13.1 (2020-01-14)
 | 
			
		||||
Changelog for v1.13.1 (2020-01-14)
 | 
			
		||||
    Bump github.com/containers/common from 0.0.5 to 0.0.7
 | 
			
		||||
    Bump github.com/onsi/ginkgo from 1.10.3 to 1.11.0
 | 
			
		||||
    Bump github.com/pkg/errors from 0.8.1 to 0.9.0
 | 
			
		||||
| 
						 | 
				
			
			@ -25,23 +58,6 @@ Changelog for v1.13.1 (2020-01-14)
 | 
			
		|||
    discard outputs coming from onbuild command on buildah-from --quiet
 | 
			
		||||
    make --format columnizing consistent with buildah images
 | 
			
		||||
    Bump to v1.14.0-dev
 | 
			
		||||
    Bump to v1.13.0
 | 
			
		||||
    Bump to c/storage v1.15.5
 | 
			
		||||
    Update container/storage to v1.15.4
 | 
			
		||||
    Fix option handling for volumes in build
 | 
			
		||||
    Rework overlay pkg for use with libpod
 | 
			
		||||
    Fix buildahimage builds for buildah
 | 
			
		||||
    Add support for FIPS-Mode backends
 | 
			
		||||
    Set the TMPDIR for pulling/pushing image to $TMPDIR
 | 
			
		||||
    WIP: safer test for pull --all-tags
 | 
			
		||||
    BATS major cleanup: blobcache.bats: refactor
 | 
			
		||||
    BATS major cleanup: part 4: manual stuff
 | 
			
		||||
    BATS major cleanup, step 3: yet more run_buildah
 | 
			
		||||
    BATS major cleanup, part 2: use more run_buildah
 | 
			
		||||
    BATS major cleanup, part 1: log-level
 | 
			
		||||
    Bump github.com/containers/image/v5 from 5.0.0 to 5.1.0
 | 
			
		||||
    Bump github.com/containers/common from 0.0.3 to 0.0.5
 | 
			
		||||
    Bump to v1.13.0-dev
 | 
			
		||||
 | 
			
		||||
## v1.13.0 (2019-12-27)
 | 
			
		||||
    Bump to c/storage v1.15.5
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
## The Buildah Project Community Code of Conduct
 | 
			
		||||
 | 
			
		||||
The Buildah Project follows the [Containers Community Code of Conduct](https://github.com/containers/common/blob/master/CODE-OF-CONDUCT.md).
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +10,7 @@ that we follow.
 | 
			
		|||
* [Reporting Issues](#reporting-issues)
 | 
			
		||||
* [Submitting Pull Requests](#submitting-pull-requests)
 | 
			
		||||
* [Sign your PRs](#sign-your-prs)
 | 
			
		||||
* [Merge bot interaction](#merge-bot-interaction)
 | 
			
		||||
* [Communications](#communications)
 | 
			
		||||
* [Becoming a Maintainer](#becoming-a-maintainer)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -116,6 +117,57 @@ Use your real name (sorry, no pseudonyms or anonymous contributions.)
 | 
			
		|||
If you set your `user.name` and `user.email` git configs, you can sign your
 | 
			
		||||
commit automatically with `git commit -s`.
 | 
			
		||||
 | 
			
		||||
## Merge bot interaction
 | 
			
		||||
 | 
			
		||||
Maintainers should never merge anything directly into upstream
 | 
			
		||||
branches.  Instead, interact with the [bors-ng bot](https://bors.tech/)
 | 
			
		||||
through PR comments as summarized below. This ensures all upstream
 | 
			
		||||
branches contain commits in a predictable order, and that every commit
 | 
			
		||||
has passed automated testing at some point in the past. A
 | 
			
		||||
[Maintainer portal](https://app.bors.tech/repositories/22803)
 | 
			
		||||
is available, showing all PRs awaiting review and approval.
 | 
			
		||||
 | 
			
		||||
### Common [bors-ng comment commands](https://bors.tech/documentation/):
 | 
			
		||||
 | 
			
		||||
(must be on a single comment-line, without any other extraneous text)
 | 
			
		||||
 | 
			
		||||
* `bors r+` - Check the current number of Github Code-review Approvals.
 | 
			
		||||
  If the PR has that many approvals or more, the bot will add the PR into
 | 
			
		||||
  the queue for testing and possible merging.  Both the success criteria
 | 
			
		||||
  and minimum approval number are set in the configuration file (see below).
 | 
			
		||||
* `bors retry` - Re-run whatever request was previously issued to the bot.  Useful
 | 
			
		||||
  when there was a testing flake upon attempted merge.
 | 
			
		||||
* `bors try` - Optional / simulate the actions of `bors r+` (see above) having
 | 
			
		||||
  met the minimum number of required approvals.  The result will be reported
 | 
			
		||||
  back as a comment in the PR, by the bors bot.
 | 
			
		||||
* `bors ping` - Confirm bot is functioning, it will post a comment in the PR if so.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Interaction/Monitoring
 | 
			
		||||
 | 
			
		||||
Bors-ng relies on the regular branch-testing occurring when it updates the
 | 
			
		||||
special branches ('trying' or 'staging').  Therefore you may use the full
 | 
			
		||||
capabilities available within the CI system.  ***Note:*** A single bors-ng
 | 
			
		||||
run may include multiple PRs at once.
 | 
			
		||||
 | 
			
		||||
The easiest way to access a running 'bors try' or 'bors r+' run, is by clicking the
 | 
			
		||||
yellow-circle "status" icon that shows up in an affected PR, for example:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
This will cause a pop-up window to appear with the relevant test-statuses and 'details'
 | 
			
		||||
links available.  Since bors-ng will wait for success, as long as one test is still
 | 
			
		||||
running, it's possible to manually re-run any failed tests (e.g. due to flakes).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Configuration of bors-ng:
 | 
			
		||||
 | 
			
		||||
* The `bors.toml` file in the repository root.  This controls
 | 
			
		||||
  runtime options for timeouts, blocking labels, and required status names.
 | 
			
		||||
* The [settings page](https://app.bors.tech/repositories/22803/settings).
 | 
			
		||||
  This contains mostly security-related and branch-control options.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Communications
 | 
			
		||||
 | 
			
		||||
For general questions or discussions, please use the
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,8 +18,10 @@ GOVERSION := $(findstring $(GO110),$(shell go version))
 | 
			
		|||
# test for go module support
 | 
			
		||||
ifeq ($(shell go help mod >/dev/null 2>&1 && echo true), true)
 | 
			
		||||
export GO_BUILD=GO111MODULE=on $(GO) build -mod=vendor
 | 
			
		||||
export GO_TEST=GO111MODULE=on $(GO) test -mod=vendor
 | 
			
		||||
else
 | 
			
		||||
export GO_BUILD=$(GO) build
 | 
			
		||||
export GO_TEST=$(GO) test
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
GIT_COMMIT ?= $(if $(shell git rev-parse --short HEAD),$(shell git rev-parse --short HEAD),$(error "git failed"))
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +37,8 @@ EXTRALDFLAGS :=
 | 
			
		|||
LDFLAGS := -ldflags '-X main.GitCommit=$(GIT_COMMIT) -X main.buildInfo=$(SOURCE_DATE_EPOCH) -X main.cniVersion=$(CNI_COMMIT)' $(EXTRALDFLAGS)
 | 
			
		||||
SOURCES=*.go imagebuildah/*.go bind/*.go chroot/*.go cmd/buildah/*.go docker/*.go pkg/blobcache/*.go pkg/cli/*.go pkg/parse/*.go util/*.go
 | 
			
		||||
 | 
			
		||||
LINTFLAGS ?=
 | 
			
		||||
 | 
			
		||||
all: buildah imgtype docs
 | 
			
		||||
 | 
			
		||||
.PHONY: static
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +101,7 @@ install.libseccomp.sudo: gopath
 | 
			
		|||
install.cni.sudo: gopath
 | 
			
		||||
	rm -rf ../../containernetworking/plugins
 | 
			
		||||
	git clone https://github.com/containernetworking/plugins ../../containernetworking/plugins
 | 
			
		||||
	cd ../../containernetworking/plugins && ./build.sh && mkdir -p /opt/cni/bin && sudo install -v -m755 bin/* /opt/cni/bin/
 | 
			
		||||
	cd ../../containernetworking/plugins && ./build_linux.sh && sudo install -D -v -m755 -t /opt/cni/bin/ bin/*
 | 
			
		||||
 | 
			
		||||
.PHONY: install
 | 
			
		||||
install:
 | 
			
		||||
| 
						 | 
				
			
			@ -128,10 +132,10 @@ tests/testreport/testreport: tests/testreport/testreport.go
 | 
			
		|||
 | 
			
		||||
.PHONY: test-unit
 | 
			
		||||
test-unit: tests/testreport/testreport
 | 
			
		||||
	$(GO) test -v -tags "$(STOAGETAGS) $(SECURITYTAGS)" -race $(shell $(GO) list ./... | grep -v vendor | grep -v tests | grep -v cmd)
 | 
			
		||||
	$(GO_TEST) -v -tags "$(STORAGETAGS) $(SECURITYTAGS)" -race $(shell $(GO) list ./... | grep -v vendor | grep -v tests | grep -v cmd)
 | 
			
		||||
	tmp=$(shell mktemp -d) ; \
 | 
			
		||||
	mkdir -p $$tmp/root $$tmp/runroot; \
 | 
			
		||||
	$(GO) test -v -tags "$(STORAGETAGS) $(SECURITYTAGS)" ./cmd/buildah -args -root $$tmp/root -runroot $$tmp/runroot -storage-driver vfs -signature-policy $(shell pwd)/tests/policy.json -registries-conf $(shell pwd)/tests/registries.conf
 | 
			
		||||
	$(GO_TEST) -v -tags "$(STORAGETAGS) $(SECURITYTAGS)" ./cmd/buildah -args -root $$tmp/root -runroot $$tmp/runroot -storage-driver vfs -signature-policy $(shell pwd)/tests/policy.json -registries-conf $(shell pwd)/tests/registries.conf
 | 
			
		||||
 | 
			
		||||
vendor-in-container:
 | 
			
		||||
	podman run --privileged --rm --env HOME=/root -v `pwd`:/src -w /src docker.io/library/golang:1.13 make vendor
 | 
			
		||||
| 
						 | 
				
			
			@ -145,4 +149,4 @@ vendor:
 | 
			
		|||
 | 
			
		||||
.PHONY: lint
 | 
			
		||||
lint: install.tools
 | 
			
		||||
	./tests/tools/build/golangci-lint run
 | 
			
		||||
	./tests/tools/build/golangci-lint run $(LINTFLAGS)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,9 @@
 | 
			
		|||
# [Buildah](https://www.youtube.com/embed/YVk5NgSiUw8) - a tool that facilitates building [Open Container Initiative (OCI)](https://www.opencontainers.org/) container images
 | 
			
		||||
 | 
			
		||||
[](https://goreportcard.com/report/github.com/containers/buildah)
 | 
			
		||||
[](https://travis-ci.org/containers/buildah)
 | 
			
		||||
 | 
			
		||||
[](https://app.bors.tech/repositories/22803)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
The Buildah package provides a command line tool that can be used to
 | 
			
		||||
* create a working container, either from scratch or using an image as a starting point
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
# Bors-ng is a service which provides a merge and review bot for github PRs.
 | 
			
		||||
# When approved for merging (`bors r+`) or test merging (`bors try`), all
 | 
			
		||||
# pending PRs at the time will be merged together in one of two special
 | 
			
		||||
# branches. Either 'staging' or 'trying'.  In the case of `staging` branch,
 | 
			
		||||
# when all status tests pass (see below) the serialized set of merges will become
 | 
			
		||||
# the new destination branch HEAD (i.e. master).  This guarantees there is never
 | 
			
		||||
# any conflicts with PR merge order on the destination branch(es).
 | 
			
		||||
#
 | 
			
		||||
# Note: The branches 'staging.tmp' and 'trying.tmp' must always be ignored
 | 
			
		||||
# by _all_ CI systems.  They are by bors temporarily, and may go away at
 | 
			
		||||
# unpredictable times.
 | 
			
		||||
#
 | 
			
		||||
# Format Ref: https://bors.tech/documentation/#configuration-borstoml
 | 
			
		||||
#
 | 
			
		||||
# status
 | 
			
		||||
# ------------------
 | 
			
		||||
# Selects which tests are required for merging, matching against values
 | 
			
		||||
# from BOTH the older github 'status API' (ref: https://developer.github.com/v3/repos/statuses
 | 
			
		||||
# /#list-statuses-for-a-specific-ref) AND newer 'checks API'. Ref: https://developer.github.com/v3/checks
 | 
			
		||||
# /runs/#list-check-runs-in-a-check-suite both return JSON:
 | 
			
		||||
#
 | 
			
		||||
# Status API:  Matches against '[].context' values
 | 
			
		||||
# Checks API:  Matches against 'check_runs[].name' values
 | 
			
		||||
#
 | 
			
		||||
# Note: The wild-card character '%' is available.
 | 
			
		||||
status = [
 | 
			
		||||
    "cirrus-ci/success",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
# Same as 'status' (above) but statuses that must pass on every PR
 | 
			
		||||
pr_status = [
 | 
			
		||||
    "cirrus-ci/success",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
# Cirrus-CI Max Timeout is 60 * 60 * 2
 | 
			
		||||
timeout_sec = 7200
 | 
			
		||||
 | 
			
		||||
# List of strings: PR Labels that must NOT be present
 | 
			
		||||
block_labels = []
 | 
			
		||||
 | 
			
		||||
# The number of required GitHub code reviews set 'Approve'
 | 
			
		||||
# before 'bors r+' will allow merging.  Does not require
 | 
			
		||||
# the reviewer being in the 'Reviewers' list for the PR.
 | 
			
		||||
required_approvals = 0
 | 
			
		||||
| 
						 | 
				
			
			@ -8,10 +8,10 @@ import (
 | 
			
		|||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/containers/buildah/docker"
 | 
			
		||||
	"github.com/containers/buildah/util"
 | 
			
		||||
	"github.com/containers/image/v5/types"
 | 
			
		||||
	"github.com/containers/storage"
 | 
			
		||||
	"github.com/containers/storage/pkg/ioutils"
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ const (
 | 
			
		|||
	Package = "buildah"
 | 
			
		||||
	// Version for the Package.  Bump version in contrib/rpm/buildah.spec
 | 
			
		||||
	// too.
 | 
			
		||||
	Version = "1.13.1"
 | 
			
		||||
	Version = "1.15.0-dev"
 | 
			
		||||
	// The value we use to identify what type of information, currently a
 | 
			
		||||
	// serialized Builder structure, we are using as per-container state.
 | 
			
		||||
	// This should only be changed when we make incompatible changes to
 | 
			
		||||
| 
						 | 
				
			
			@ -180,13 +180,8 @@ type Builder struct {
 | 
			
		|||
	CNIConfigDir string
 | 
			
		||||
	// ID mapping options to use when running processes in the container with non-host user namespaces.
 | 
			
		||||
	IDMappingOptions IDMappingOptions
 | 
			
		||||
	// AddCapabilities is a list of capabilities to add to the default set when running
 | 
			
		||||
	// commands in the container.
 | 
			
		||||
	AddCapabilities []string
 | 
			
		||||
	// DropCapabilities is a list of capabilities to remove from the default set,
 | 
			
		||||
	// after processing the AddCapabilities set, when running commands in the container.
 | 
			
		||||
	// If a capability appears in both lists, it will be dropped.
 | 
			
		||||
	DropCapabilities []string
 | 
			
		||||
	// Capabilities is a list of capabilities to use when running commands in the container.
 | 
			
		||||
	Capabilities []string
 | 
			
		||||
	// PrependedEmptyLayers are history entries that we'll add to a
 | 
			
		||||
	// committed image, after any history items that we inherit from a base
 | 
			
		||||
	// image, but before the history item for the layer that we're
 | 
			
		||||
| 
						 | 
				
			
			@ -229,13 +224,11 @@ type BuilderInfo struct {
 | 
			
		|||
	DefaultMountsFilePath string
 | 
			
		||||
	Isolation             string
 | 
			
		||||
	NamespaceOptions      NamespaceOptions
 | 
			
		||||
	Capabilities          []string
 | 
			
		||||
	ConfigureNetwork      string
 | 
			
		||||
	CNIPluginPath         string
 | 
			
		||||
	CNIConfigDir          string
 | 
			
		||||
	IDMappingOptions      IDMappingOptions
 | 
			
		||||
	DefaultCapabilities   []string
 | 
			
		||||
	AddCapabilities       []string
 | 
			
		||||
	DropCapabilities      []string
 | 
			
		||||
	History               []v1.History
 | 
			
		||||
	Devices               []configs.Device
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -255,6 +248,7 @@ func GetBuildInfo(b *Builder) BuilderInfo {
 | 
			
		|||
		EmptyLayer: false,
 | 
			
		||||
	})
 | 
			
		||||
	history = append(history, copyHistory(b.AppendedEmptyLayers)...)
 | 
			
		||||
	sort.Strings(b.Capabilities)
 | 
			
		||||
	return BuilderInfo{
 | 
			
		||||
		Type:                  b.Type,
 | 
			
		||||
		FromImage:             b.FromImage,
 | 
			
		||||
| 
						 | 
				
			
			@ -278,9 +272,7 @@ func GetBuildInfo(b *Builder) BuilderInfo {
 | 
			
		|||
		CNIPluginPath:         b.CNIPluginPath,
 | 
			
		||||
		CNIConfigDir:          b.CNIConfigDir,
 | 
			
		||||
		IDMappingOptions:      b.IDMappingOptions,
 | 
			
		||||
		DefaultCapabilities:   append([]string{}, util.DefaultCapabilities...),
 | 
			
		||||
		AddCapabilities:       append([]string{}, b.AddCapabilities...),
 | 
			
		||||
		DropCapabilities:      append([]string{}, b.DropCapabilities...),
 | 
			
		||||
		Capabilities:          b.Capabilities,
 | 
			
		||||
		History:               history,
 | 
			
		||||
		Devices:               b.Devices,
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -406,19 +398,16 @@ type BuilderOptions struct {
 | 
			
		|||
	CNIConfigDir string
 | 
			
		||||
	// ID mapping options to use if we're setting up our own user namespace.
 | 
			
		||||
	IDMappingOptions *IDMappingOptions
 | 
			
		||||
	// AddCapabilities is a list of capabilities to add to the default set when
 | 
			
		||||
	// Capabilities is a list of capabilities to use when
 | 
			
		||||
	// running commands in the container.
 | 
			
		||||
	AddCapabilities []string
 | 
			
		||||
	// DropCapabilities is a list of capabilities to remove from the default set,
 | 
			
		||||
	// after processing the AddCapabilities set, when running commands in the
 | 
			
		||||
	// container.  If a capability appears in both lists, it will be dropped.
 | 
			
		||||
	DropCapabilities []string
 | 
			
		||||
 | 
			
		||||
	Capabilities    []string
 | 
			
		||||
	CommonBuildOpts *CommonBuildOptions
 | 
			
		||||
	// Format for the container image
 | 
			
		||||
	Format string
 | 
			
		||||
	// Devices are the additional devices to add to the containers
 | 
			
		||||
	Devices []configs.Device
 | 
			
		||||
	//DefaultEnv for containers
 | 
			
		||||
	DefaultEnv []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ImportOptions are used to initialize a Builder from an existing container
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,37 @@
 | 
			
		|||
- Changelog for v1.14.0 (2020-02-05)
 | 
			
		||||
  * bump github.com/mtrmac/gpgme
 | 
			
		||||
  * Update containers/common to v0.1.4
 | 
			
		||||
  * manifest push: add --format option
 | 
			
		||||
  * Bump github.com/onsi/gomega from 1.8.1 to 1.9.0
 | 
			
		||||
  * vendor github.com/containers/image/v5@v5.2.0
 | 
			
		||||
  * info test: deal with random key order
 | 
			
		||||
  * Bump back to v1.14.0-dev
 | 
			
		||||
 | 
			
		||||
- Changelog for v1.13.2 (2020-01-29)
 | 
			
		||||
  * sign.bats: set GPG_TTY=/dev/null
 | 
			
		||||
  * Fix parse_unsupported.go
 | 
			
		||||
  * getDateAndDigestAndSize(): use manifest.Digest
 | 
			
		||||
  * Bump github.com/opencontainers/selinux from 1.3.0 to 1.3.1
 | 
			
		||||
  * Bump github.com/containers/common from 0.1.0 to 0.1.2
 | 
			
		||||
  * Touch up os/arch doc
 | 
			
		||||
  * chroot: handle slightly broken seccomp defaults
 | 
			
		||||
  * buildahimage: specify fuse-overlayfs mount options
 | 
			
		||||
  * Bump github.com/mattn/go-shellwords from 1.0.7 to 1.0.9
 | 
			
		||||
  * copy.bats: make sure we detect failures due to missing source
 | 
			
		||||
  * parse: don't complain about not being able to rename something to itself
 | 
			
		||||
  * Makefile: use a $(GO_TEST) macro, fix a typo
 | 
			
		||||
  * manifests: unit test fix
 | 
			
		||||
  * Fix build for 32bit platforms
 | 
			
		||||
  * Allow users to set OS and architecture on bud
 | 
			
		||||
  * Fix COPY in containerfile with envvar
 | 
			
		||||
  * Bump c/storage to v1.15.7
 | 
			
		||||
  * add --sign-by to bud/commit/push, --remove-signatures for pull/push
 | 
			
		||||
  * Remove cut/paste error in CHANGELOG.md
 | 
			
		||||
  * Update vendor of containers/common to v0.1.0
 | 
			
		||||
  * update install instructions for Debian, Raspbian and Ubuntu
 | 
			
		||||
  * Add support for containers.conf
 | 
			
		||||
  * Bump back to v1.14.0-dev
 | 
			
		||||
 | 
			
		||||
- Changelog for v1.13.1 (2020-01-14)
 | 
			
		||||
  * Bump github.com/containers/common from 0.0.5 to 0.0.7
 | 
			
		||||
  * Bump github.com/onsi/ginkgo from 1.10.3 to 1.11.0
 | 
			
		||||
| 
						 | 
				
			
			@ -20,23 +54,6 @@
 | 
			
		|||
  * discard outputs coming from onbuild command on buildah-from --quiet
 | 
			
		||||
  * make --format columnizing consistent with buildah images
 | 
			
		||||
  * Bump to v1.14.0-dev
 | 
			
		||||
  * Bump to v1.13.0
 | 
			
		||||
  * Bump to c/storage v1.15.5
 | 
			
		||||
  * Update container/storage to v1.15.4
 | 
			
		||||
  * Fix option handling for volumes in build
 | 
			
		||||
  * Rework overlay pkg for use with libpod
 | 
			
		||||
  * Fix buildahimage builds for buildah
 | 
			
		||||
  * Add support for FIPS-Mode backends
 | 
			
		||||
  * Set the TMPDIR for pulling/pushing image to $TMPDIR
 | 
			
		||||
  * WIP: safer test for pull --all-tags
 | 
			
		||||
  * BATS major cleanup: blobcache.bats: refactor
 | 
			
		||||
  * BATS major cleanup: part 4: manual stuff
 | 
			
		||||
  * BATS major cleanup, step 3: yet more run_buildah
 | 
			
		||||
  * BATS major cleanup, part 2: use more run_buildah
 | 
			
		||||
  * BATS major cleanup, part 1: log-level
 | 
			
		||||
  * Bump github.com/containers/image/v5 from 5.0.0 to 5.1.0
 | 
			
		||||
  * Bump github.com/containers/common from 0.0.3 to 0.0.5
 | 
			
		||||
  * Bump to v1.13.0-dev
 | 
			
		||||
 | 
			
		||||
- Changelog for v1.13.0 (2019-12-27)
 | 
			
		||||
  * Bump to c/storage v1.15.5
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
package chroot
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/opencontainers/runtime-spec/specs-go"
 | 
			
		||||
	specs "github.com/opencontainers/runtime-spec/specs-go"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	libseccomp "github.com/seccomp/libseccomp-golang"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
| 
						 | 
				
			
			@ -118,15 +118,32 @@ func setSeccomp(spec *specs.Spec) error {
 | 
			
		|||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			var conditions []libseccomp.ScmpCondition
 | 
			
		||||
			opsAreAllEquality := true
 | 
			
		||||
			for _, arg := range rule.Args {
 | 
			
		||||
				condition, err := libseccomp.MakeCondition(arg.Index, mapOp(arg.Op), arg.Value, arg.ValueTwo)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return errors.Wrapf(err, "error building a seccomp condition %d:%v:%d:%d", arg.Index, arg.Op, arg.Value, arg.ValueTwo)
 | 
			
		||||
				}
 | 
			
		||||
				if arg.Op != specs.OpEqualTo {
 | 
			
		||||
					opsAreAllEquality = false
 | 
			
		||||
				}
 | 
			
		||||
				conditions = append(conditions, condition)
 | 
			
		||||
			}
 | 
			
		||||
			if err = filter.AddRuleConditional(scnum, mapAction(rule.Action), conditions); err != nil {
 | 
			
		||||
				return errors.Wrapf(err, "error adding a conditional rule (%q:%q) to seccomp filter", scnames[scnum], rule.Action)
 | 
			
		||||
				// Okay, if the rules specify multiple equality
 | 
			
		||||
				// checks, assume someone thought that they
 | 
			
		||||
				// were OR'd, when in fact they're ordinarily
 | 
			
		||||
				// supposed to be AND'd.  Break them up into
 | 
			
		||||
				// different rules to get that OR effect.
 | 
			
		||||
				if len(rule.Args) > 1 && opsAreAllEquality && err.Error() == "two checks on same syscall argument" {
 | 
			
		||||
					for i := range conditions {
 | 
			
		||||
						if err = filter.AddRuleConditional(scnum, mapAction(rule.Action), conditions[i:i+1]); err != nil {
 | 
			
		||||
							return errors.Wrapf(err, "error adding a conditional rule (%q:%q[%d]) to seccomp filter", scnames[scnum], rule.Action, i)
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					return errors.Wrapf(err, "error adding a conditional rule (%q:%q) to seccomp filter", scnames[scnum], rule.Action)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,6 +81,8 @@ type CommitOptions struct {
 | 
			
		|||
	// OmitTimestamp forces epoch 0 as created timestamp to allow for
 | 
			
		||||
	// deterministic, content-addressable builds.
 | 
			
		||||
	OmitTimestamp bool
 | 
			
		||||
	// SignBy is the fingerprint of a GPG key to use for signing the image.
 | 
			
		||||
	SignBy string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PushOptions can be used to alter how an image is copied somewhere.
 | 
			
		||||
| 
						 | 
				
			
			@ -115,6 +117,11 @@ type PushOptions struct {
 | 
			
		|||
	// the user will be displayed, this is best used for logging.
 | 
			
		||||
	// The default is false.
 | 
			
		||||
	Quiet bool
 | 
			
		||||
	// SignBy is the fingerprint of a GPG key to use for signing the image.
 | 
			
		||||
	SignBy string
 | 
			
		||||
	// RemoveSignatures causes any existing signatures for the image to be
 | 
			
		||||
	// discarded for the pushed copy.
 | 
			
		||||
	RemoveSignatures bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
| 
						 | 
				
			
			@ -293,8 +300,16 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
 | 
			
		|||
	case archive.Gzip:
 | 
			
		||||
		systemContext.DirForceCompress = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if systemContext.ArchitectureChoice != b.Architecture() {
 | 
			
		||||
		systemContext.ArchitectureChoice = b.Architecture()
 | 
			
		||||
	}
 | 
			
		||||
	if systemContext.OSChoice != b.OS() {
 | 
			
		||||
		systemContext.OSChoice = b.OS()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var manifestBytes []byte
 | 
			
		||||
	if manifestBytes, err = cp.Image(ctx, policyContext, maybeCachedDest, maybeCachedSrc, getCopyOptions(b.store, options.ReportWriter, nil, systemContext, "")); err != nil {
 | 
			
		||||
	if manifestBytes, err = cp.Image(ctx, policyContext, maybeCachedDest, maybeCachedSrc, getCopyOptions(b.store, options.ReportWriter, nil, systemContext, "", false, options.SignBy)); err != nil {
 | 
			
		||||
		return imgID, nil, "", errors.Wrapf(err, "error copying layers and metadata for container %q", b.ContainerID)
 | 
			
		||||
	}
 | 
			
		||||
	// If we've got more names to attach, and we know how to do that for
 | 
			
		||||
| 
						 | 
				
			
			@ -426,7 +441,7 @@ func Push(ctx context.Context, image string, dest types.ImageReference, options
 | 
			
		|||
		systemContext.DirForceCompress = true
 | 
			
		||||
	}
 | 
			
		||||
	var manifestBytes []byte
 | 
			
		||||
	if manifestBytes, err = cp.Image(ctx, policyContext, dest, maybeCachedSrc, getCopyOptions(options.Store, options.ReportWriter, nil, systemContext, options.ManifestType)); err != nil {
 | 
			
		||||
	if manifestBytes, err = cp.Image(ctx, policyContext, dest, maybeCachedSrc, getCopyOptions(options.Store, options.ReportWriter, nil, systemContext, options.ManifestType, options.RemoveSignatures, options.SignBy)); err != nil {
 | 
			
		||||
		return nil, "", errors.Wrapf(err, "error copying layers and metadata from %q to %q", transports.ImageName(maybeCachedSrc), transports.ImageName(dest))
 | 
			
		||||
	}
 | 
			
		||||
	if options.ReportWriter != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,7 @@ const (
 | 
			
		|||
	DOCKER = "docker"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func getCopyOptions(store storage.Store, reportWriter io.Writer, sourceSystemContext *types.SystemContext, destinationSystemContext *types.SystemContext, manifestType string) *cp.Options {
 | 
			
		||||
func getCopyOptions(store storage.Store, reportWriter io.Writer, sourceSystemContext *types.SystemContext, destinationSystemContext *types.SystemContext, manifestType string, removeSignatures bool, addSigner string) *cp.Options {
 | 
			
		||||
	sourceCtx := getSystemContext(store, nil, "")
 | 
			
		||||
	if sourceSystemContext != nil {
 | 
			
		||||
		*sourceCtx = *sourceSystemContext
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +33,8 @@ func getCopyOptions(store storage.Store, reportWriter io.Writer, sourceSystemCon
 | 
			
		|||
		SourceCtx:             sourceCtx,
 | 
			
		||||
		DestinationCtx:        destinationCtx,
 | 
			
		||||
		ForceManifestMIMEType: manifestType,
 | 
			
		||||
		RemoveSignatures:      removeSignatures,
 | 
			
		||||
		SignBy:                addSigner,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,46 +3,37 @@ module github.com/containers/buildah
 | 
			
		|||
go 1.12
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/blang/semver v3.5.0+incompatible // indirect
 | 
			
		||||
	github.com/containernetworking/cni v0.7.1
 | 
			
		||||
	github.com/containers/common v0.0.7
 | 
			
		||||
	github.com/containers/image/v5 v5.1.0
 | 
			
		||||
	github.com/containers/storage v1.15.5
 | 
			
		||||
	github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784
 | 
			
		||||
	github.com/containers/common v0.3.0
 | 
			
		||||
	github.com/containers/image/v5 v5.2.1
 | 
			
		||||
	github.com/containers/storage v1.15.8
 | 
			
		||||
	github.com/cyphar/filepath-securejoin v0.2.2
 | 
			
		||||
	github.com/docker/distribution v2.7.1+incompatible
 | 
			
		||||
	github.com/docker/go-metrics v0.0.1 // indirect
 | 
			
		||||
	github.com/docker/go-units v0.4.0
 | 
			
		||||
	github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316
 | 
			
		||||
	github.com/etcd-io/bbolt v1.3.3
 | 
			
		||||
	github.com/fsouza/go-dockerclient v1.6.0
 | 
			
		||||
	github.com/fsouza/go-dockerclient v1.6.1
 | 
			
		||||
	github.com/ghodss/yaml v1.0.0
 | 
			
		||||
	github.com/hashicorp/go-multierror v1.0.0
 | 
			
		||||
	github.com/ishidawataru/sctp v0.0.0-20180918013207-6e2cb1366111 // indirect
 | 
			
		||||
	github.com/mattn/go-shellwords v1.0.6
 | 
			
		||||
	github.com/morikuni/aec v1.0.0 // indirect
 | 
			
		||||
	github.com/onsi/ginkgo v1.11.0
 | 
			
		||||
	github.com/onsi/gomega v1.8.1
 | 
			
		||||
	github.com/mattn/go-shellwords v1.0.10
 | 
			
		||||
	github.com/onsi/ginkgo v1.12.0
 | 
			
		||||
	github.com/onsi/gomega v1.9.0
 | 
			
		||||
	github.com/opencontainers/go-digest v1.0.0-rc1
 | 
			
		||||
	github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6
 | 
			
		||||
	github.com/opencontainers/runc v1.0.0-rc9
 | 
			
		||||
	github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7
 | 
			
		||||
	github.com/opencontainers/runtime-tools v0.9.0
 | 
			
		||||
	github.com/opencontainers/selinux v1.3.0
 | 
			
		||||
	github.com/opencontainers/selinux v1.3.1
 | 
			
		||||
	github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316
 | 
			
		||||
	github.com/openshift/imagebuilder v1.1.1
 | 
			
		||||
	github.com/pkg/errors v0.9.0
 | 
			
		||||
	github.com/seccomp/containers-golang v0.0.0-20180629143253-cdfdaa7543f4
 | 
			
		||||
	github.com/pkg/errors v0.9.1
 | 
			
		||||
	github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f
 | 
			
		||||
	github.com/seccomp/libseccomp-golang v0.9.1
 | 
			
		||||
	github.com/sirupsen/logrus v1.4.2
 | 
			
		||||
	github.com/spf13/cobra v0.0.5
 | 
			
		||||
	github.com/spf13/pflag v1.0.5
 | 
			
		||||
	github.com/stretchr/testify v1.4.0
 | 
			
		||||
	github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
 | 
			
		||||
	github.com/vishvananda/netlink v1.0.0 // indirect
 | 
			
		||||
	github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f // indirect
 | 
			
		||||
	github.com/xeipuuv/gojsonschema v1.1.0 // indirect
 | 
			
		||||
	golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708
 | 
			
		||||
	golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2
 | 
			
		||||
	golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
 | 
			
		||||
	k8s.io/client-go v0.0.0-20181219152756-3dd551c0f083 // indirect
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,16 @@
 | 
			
		|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 | 
			
		||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 | 
			
		||||
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg=
 | 
			
		||||
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0=
 | 
			
		||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
 | 
			
		||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
 | 
			
		||||
github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
 | 
			
		||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 | 
			
		||||
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/DataDog/zstd v1.4.0 h1:vhoV+DUHnRZdKW1i5UMjAk2G4JY8wN4ayRfYDNdEhwo=
 | 
			
		||||
github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
 | 
			
		||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
 | 
			
		||||
github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
 | 
			
		||||
github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
 | 
			
		||||
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
 | 
			
		||||
| 
						 | 
				
			
			@ -27,8 +30,11 @@ github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdko
 | 
			
		|||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
 | 
			
		||||
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
 | 
			
		||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
 | 
			
		||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
 | 
			
		||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
 | 
			
		||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 | 
			
		||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 | 
			
		||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
 | 
			
		||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
 | 
			
		||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 | 
			
		||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +43,13 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
 | 
			
		|||
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 | 
			
		||||
github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
 | 
			
		||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 | 
			
		||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
 | 
			
		||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 | 
			
		||||
github.com/buger/goterm v0.0.0-20181115115552-c206103e1f37/go.mod h1:u9UyCz2eTrSGy6fbupqJ54eY5c4IC8gREQ1053dK12U=
 | 
			
		||||
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
 | 
			
		||||
github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b/go.mod h1:TrMrLQfeENAPYPRsJuq3jsqdlRh3lvi6trTZJG8+tho=
 | 
			
		||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 | 
			
		||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
 | 
			
		||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s=
 | 
			
		||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
 | 
			
		||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
 | 
			
		||||
| 
						 | 
				
			
			@ -56,22 +68,49 @@ 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/containernetworking/cni v0.7.1 h1:fE3r16wpSEyaqY4Z4oFrLMmIGfBYIKpPrHK31EJ9FzE=
 | 
			
		||||
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
 | 
			
		||||
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/plugins v0.8.5/go.mod h1:UZ2539umj8djuRQmBxuazHeJbYrLV8BSBejkk+she6o=
 | 
			
		||||
github.com/containers/buildah v1.13.1/go.mod h1:U0LcOzSqoYdyQC5L2hMeLbtCDuCCLxmZV1eb+SWY4GA=
 | 
			
		||||
github.com/containers/common v0.0.3 h1:C2Zshb0w720FqPa42MCRuiGfbW0kwbURRwvK1EWIC5I=
 | 
			
		||||
github.com/containers/common v0.0.3/go.mod h1:CaOgMRiwi2JJHISMZ6VPPZhQYFUDRv3YYVss2RqUCMg=
 | 
			
		||||
github.com/containers/common v0.0.5 h1:Hi4+eyUZx8hXB4reLNPbdT6XT8MGMAzdlbg8V+WifkQ=
 | 
			
		||||
github.com/containers/common v0.0.5/go.mod h1:lhWV3MLhO1+KGE2x6v9+K38MxpjXGso+edmpkFnCOqI=
 | 
			
		||||
github.com/containers/common v0.0.7 h1:eKYZLKfJ2d/RNDgecLDFv45cHb4imYzIcrQHx1Y029M=
 | 
			
		||||
github.com/containers/common v0.0.7/go.mod h1:lhWV3MLhO1+KGE2x6v9+K38MxpjXGso+edmpkFnCOqI=
 | 
			
		||||
github.com/containers/common v0.0.8-0.20200106141003-a79791495fd1 h1:udiDqxQSdunVXNjBW4icHrnFLNOiTpvH6GRG+ywA4f4=
 | 
			
		||||
github.com/containers/common v0.0.8-0.20200106141003-a79791495fd1/go.mod h1:lhWV3MLhO1+KGE2x6v9+K38MxpjXGso+edmpkFnCOqI=
 | 
			
		||||
github.com/containers/common v0.0.8-0.20200108114752-d87ce6ce296b h1:G+DKyzrku0fC5Qa3paArNBERTwRleTg45ypY0qjo7YM=
 | 
			
		||||
github.com/containers/common v0.0.8-0.20200108114752-d87ce6ce296b/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
 | 
			
		||||
github.com/containers/common v0.1.0 h1:RsAxx1yeepYhXXEasNpspi/nPC8KKP1AzzOgEuvfWXk=
 | 
			
		||||
github.com/containers/common v0.1.0/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
 | 
			
		||||
github.com/containers/common v0.1.2 h1:EYAgJsQgH3akh6kdlN4c2t09bqRgyzpxyWmlFTf1Igc=
 | 
			
		||||
github.com/containers/common v0.1.2/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
 | 
			
		||||
github.com/containers/common v0.1.4 h1:6tizbvX9BJTnJ0S3pe65Vcu8gJagbm6oFBCmwUIiOE4=
 | 
			
		||||
github.com/containers/common v0.1.4/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
 | 
			
		||||
github.com/containers/common v0.2.0 h1:umTbAiX39/0oNxHn10ia0RyXrZCs/CnjJQlRiTdiXb8=
 | 
			
		||||
github.com/containers/common v0.2.0/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
 | 
			
		||||
github.com/containers/common v0.2.1 h1:sEMQm9S+Z7zaQNaSJYbJ5DeR539rk8qscH11RMYw9Fk=
 | 
			
		||||
github.com/containers/common v0.2.1/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
 | 
			
		||||
github.com/containers/common v0.3.0 h1:9ysL/OfPcMls1Ac3jzFA4XZJVSD/JG7Dst3uQSwQtwA=
 | 
			
		||||
github.com/containers/common v0.3.0/go.mod h1:AiPCv0ZcBOVshnup/X6MuaqkySZQZ3iBWfInjJFIl40=
 | 
			
		||||
github.com/containers/conmon v2.0.10+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
 | 
			
		||||
github.com/containers/image/v4 v4.0.1 h1:idNGHChj0Pyv3vLrxul2oSVMZLeFqpoq3CjLeVgapSQ=
 | 
			
		||||
github.com/containers/image/v4 v4.0.1/go.mod h1:0ASJH1YgJiX/eqFZObqepgsvIA4XjCgpyfwn9pDGafA=
 | 
			
		||||
github.com/containers/image/v5 v5.0.0 h1:arnXgbt1ucsC/ndtSpiQY87rA0UjhF+/xQnPzqdBDn4=
 | 
			
		||||
github.com/containers/image/v5 v5.0.0/go.mod h1:MgiLzCfIeo8lrHi+4Lb8HP+rh513sm0Mlk6RrhjFOLY=
 | 
			
		||||
github.com/containers/image/v5 v5.1.0 h1:5FjAvPJniamuNNIQHkh4PnsL+n+xzs6Aonzaz5dqTEo=
 | 
			
		||||
github.com/containers/image/v5 v5.1.0/go.mod h1:BKlMD34WxRo1ruGHHEOrPQP0Qci7SWoPwU6fS7arsCU=
 | 
			
		||||
github.com/containers/image/v5 v5.2.0 h1:DowY5OII5x9Pb6Pt76vnHU79BgG4/jdwhZjeAj2R+t8=
 | 
			
		||||
github.com/containers/image/v5 v5.2.0/go.mod h1:IAub4gDGvXoxaIAdNy4e3FbVTDPVNMv9F0UfVVFbYCU=
 | 
			
		||||
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/libpod v1.8.0/go.mod h1:53h7AOg4tQSX1rqKfR78/6Us/whERRzCQ20z0GiR44U=
 | 
			
		||||
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/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/psgo v1.4.0/go.mod h1:ENXXLQ5E1At4K0EUsGogXBJi/C28gwqkONWeLPI9fJ8=
 | 
			
		||||
github.com/containers/storage v1.13.2/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
 | 
			
		||||
github.com/containers/storage v1.13.4 h1:j0bBaJDKbUHtAW1MXPFnwXJtqcH+foWeuXK1YaBV5GA=
 | 
			
		||||
github.com/containers/storage v1.13.4/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
 | 
			
		||||
| 
						 | 
				
			
			@ -93,20 +132,33 @@ github.com/containers/storage v1.15.4 h1:eiUtV9MOTnPHibO18nDRI+aDhKudY7WmAiJdyVM
 | 
			
		|||
github.com/containers/storage v1.15.4/go.mod h1:v0lq/3f+cXH3Y/HiDaFYRR0zilwDve7I4W7U5xQxvF8=
 | 
			
		||||
github.com/containers/storage v1.15.5 h1:dBZx9yRFHod9c8FVaXlVtRqr2cmlAhpl+9rt87cE7J4=
 | 
			
		||||
github.com/containers/storage v1.15.5/go.mod h1:v0lq/3f+cXH3Y/HiDaFYRR0zilwDve7I4W7U5xQxvF8=
 | 
			
		||||
github.com/containers/storage v1.15.7 h1:ecPmv2y/qpxeSTHZ147jQLO6to8wDn8yUPtDCZlz0H4=
 | 
			
		||||
github.com/containers/storage v1.15.7/go.mod h1:gLZIp+/hP8nFn9tLS0uJlnk4h1tSoDu3oS2eFiaIqkE=
 | 
			
		||||
github.com/containers/storage v1.15.8 h1:ef7OfUMTpyq0PIVAhV7qfufEI92gAldk25nItrip+6Q=
 | 
			
		||||
github.com/containers/storage v1.15.8/go.mod h1:zhvjIIl/fR6wt/lgqQAC+xanHQ+8gUQ0GBVeXYN81qI=
 | 
			
		||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
 | 
			
		||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
 | 
			
		||||
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
 | 
			
		||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
 | 
			
		||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 | 
			
		||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 | 
			
		||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=
 | 
			
		||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 | 
			
		||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 | 
			
		||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
 | 
			
		||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 | 
			
		||||
github.com/cri-o/ocicni v0.1.1-0.20190920040751-deac903fd99b/go.mod h1:ZOuIEOp/3MB1eCBWANnNxM3zUA3NWh76wSRCsnKAg2c=
 | 
			
		||||
github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=
 | 
			
		||||
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
 | 
			
		||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
 | 
			
		||||
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
 | 
			
		||||
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
 | 
			
		||||
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
 | 
			
		||||
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
			
		||||
github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 | 
			
		||||
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/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 | 
			
		||||
| 
						 | 
				
			
			@ -118,6 +170,8 @@ github.com/docker/docker v1.4.2-0.20190927142053-ada3c14355ce h1:H3csZuxZESJeeEi
 | 
			
		|||
github.com/docker/docker v1.4.2-0.20190927142053-ada3c14355ce/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/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 | 
			
		||||
github.com/docker/docker v1.4.2-0.20191219165747-a9416c67da9f h1:Sm8iD2lifO31DwXfkGzq8VgA7rwxPjRsYmeo0K/dF9Y=
 | 
			
		||||
github.com/docker/docker v1.4.2-0.20191219165747-a9416c67da9f/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 | 
			
		||||
github.com/docker/docker-credential-helpers v0.6.0/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
 | 
			
		||||
github.com/docker/docker-credential-helpers v0.6.1 h1:Dq4iIfcM7cNtddhLVWe9h4QDjsi4OER3Z8voPu/I52g=
 | 
			
		||||
github.com/docker/docker-credential-helpers v0.6.1/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
 | 
			
		||||
| 
						 | 
				
			
			@ -135,12 +189,18 @@ github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316/go.mod h
 | 
			
		|||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
 | 
			
		||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
 | 
			
		||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
 | 
			
		||||
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
 | 
			
		||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
 | 
			
		||||
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
 | 
			
		||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
 | 
			
		||||
github.com/elazarl/goproxy/ext v0.0.0-20190911111923-ecfe977594f1/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
 | 
			
		||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 | 
			
		||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 | 
			
		||||
github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM=
 | 
			
		||||
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
 | 
			
		||||
github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 | 
			
		||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 | 
			
		||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
 | 
			
		||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
 | 
			
		||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 | 
			
		||||
github.com/fsouza/go-dockerclient v1.4.4 h1:Sd5nD4wdAgiPxvrbYUzT2ZZNmPk3z+GGnZ+frvw8z04=
 | 
			
		||||
| 
						 | 
				
			
			@ -149,12 +209,15 @@ github.com/fsouza/go-dockerclient v1.5.0 h1:7OtayOe5HnoG+KWMHgyyPymwaodnB2IDYuVf
 | 
			
		|||
github.com/fsouza/go-dockerclient v1.5.0/go.mod h1:AqZZK/zFO3phxYxlTsAaeAMSdQ9mgHuhy+bjN034Qds=
 | 
			
		||||
github.com/fsouza/go-dockerclient v1.6.0 h1:f7j+AX94143JL1H3TiqSMkM4EcLDI0De1qD4GGn3Hig=
 | 
			
		||||
github.com/fsouza/go-dockerclient v1.6.0/go.mod h1:YWwtNPuL4XTX1SKJQk86cWPmmqwx+4np9qfPbb+znGc=
 | 
			
		||||
github.com/fsouza/go-dockerclient v1.6.1 h1:qBvbtwBTpOYktncvxjFMHxJHuGG19lb2fvAFqfXeh7w=
 | 
			
		||||
github.com/fsouza/go-dockerclient v1.6.1/go.mod h1:g2pGMa82+SdtAicFSpxGJc1Anx//HHssXyWLwMRxaqg=
 | 
			
		||||
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU=
 | 
			
		||||
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
 | 
			
		||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 | 
			
		||||
github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 | 
			
		||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
 | 
			
		||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 | 
			
		||||
github.com/go-ini/ini v1.51.1/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
 | 
			
		||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 | 
			
		||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 | 
			
		||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
 | 
			
		||||
| 
						 | 
				
			
			@ -171,9 +234,12 @@ github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dp
 | 
			
		|||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
 | 
			
		||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
 | 
			
		||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 | 
			
		||||
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
 | 
			
		||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8=
 | 
			
		||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
 | 
			
		||||
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
 | 
			
		||||
github.com/gogo/protobuf v0.0.0-20170815085658-fcdc5011193f/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 | 
			
		||||
github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 | 
			
		||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 | 
			
		||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
 | 
			
		||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
 | 
			
		||||
| 
						 | 
				
			
			@ -189,21 +255,30 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a
 | 
			
		|||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 | 
			
		||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
 | 
			
		||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 | 
			
		||||
github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 | 
			
		||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 | 
			
		||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
 | 
			
		||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
			
		||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
 | 
			
		||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
 | 
			
		||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
 | 
			
		||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 | 
			
		||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
 | 
			
		||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 | 
			
		||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 | 
			
		||||
github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
 | 
			
		||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
 | 
			
		||||
github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
 | 
			
		||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
 | 
			
		||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
 | 
			
		||||
github.com/gorilla/mux v0.0.0-20170217192616-94e7d24fd285/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 | 
			
		||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
 | 
			
		||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 | 
			
		||||
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
 | 
			
		||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
 | 
			
		||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
 | 
			
		||||
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=
 | 
			
		||||
| 
						 | 
				
			
			@ -225,13 +300,21 @@ github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
 | 
			
		|||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
 | 
			
		||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
 | 
			
		||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 | 
			
		||||
github.com/insomniacslk/dhcp v0.0.0-20190712084813-dc1a53400564/go.mod h1:CfMdguCK66I5DAUJgGKyNz8aB6vO5dZzkm9Xep6WGvw=
 | 
			
		||||
github.com/ishidawataru/sctp v0.0.0-20180918013207-6e2cb1366111 h1:NAAiV9ass6VReWFjuxqrMIq12WKlSULI6Gs3PxQghLA=
 | 
			
		||||
github.com/ishidawataru/sctp v0.0.0-20180918013207-6e2cb1366111/go.mod h1:DM4VvS+hD/kDi1U1QsX2fnZowwBhqD0Dk3bRPKF/Oc8=
 | 
			
		||||
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
 | 
			
		||||
github.com/jamescun/tuntap v0.0.0-20190712092105-cb1fb277045c/go.mod h1:zzwpsgcYhzzIP5WyF8g9ivCv38cY9uAV9Gu0m3lThhE=
 | 
			
		||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 | 
			
		||||
github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 | 
			
		||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 | 
			
		||||
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
 | 
			
		||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
			
		||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
			
		||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
			
		||||
github.com/juju/errors v0.0.0-20180806074554-22422dad46e1/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
 | 
			
		||||
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
 | 
			
		||||
github.com/juju/testing v0.0.0-20190613124551-e81189438503/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
 | 
			
		||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 | 
			
		||||
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=
 | 
			
		||||
| 
						 | 
				
			
			@ -248,6 +331,10 @@ github.com/klauspost/compress v1.9.3 h1:hkFELABwacUEgBfiguNeQydKv3M9pawBq8o24Ypw
 | 
			
		|||
github.com/klauspost/compress v1.9.3/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 | 
			
		||||
github.com/klauspost/compress v1.9.4 h1:xhvAeUPQ2drNUhKtrGdTGNvV9nNafHMUkRyLkzxJoB4=
 | 
			
		||||
github.com/klauspost/compress v1.9.4/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 | 
			
		||||
github.com/klauspost/compress v1.9.7 h1:hYW1gP94JUmAhBtJ+LNz5My+gBobDxPR1iVuKug26aA=
 | 
			
		||||
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 | 
			
		||||
github.com/klauspost/compress v1.9.8 h1:VMAMUUOh+gaxKTMk+zqbjsSjsIcUcL/LF4o63i82QyA=
 | 
			
		||||
github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 | 
			
		||||
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
 | 
			
		||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 | 
			
		||||
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
 | 
			
		||||
| 
						 | 
				
			
			@ -270,16 +357,25 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
 | 
			
		|||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
 | 
			
		||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
 | 
			
		||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 | 
			
		||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 | 
			
		||||
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
 | 
			
		||||
github.com/mattn/go-shellwords v1.0.5 h1:JhhFTIOslh5ZsPrpa3Wdg8bF0WI3b44EMblmU9wIsXc=
 | 
			
		||||
github.com/mattn/go-shellwords v1.0.5/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
 | 
			
		||||
github.com/mattn/go-shellwords v1.0.6 h1:9Jok5pILi5S1MnDirGVTufYGtksUs/V2BWUP3ZkeUUI=
 | 
			
		||||
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
 | 
			
		||||
github.com/mattn/go-shellwords v1.0.7 h1:KqhVjVZomx2puPACkj9vrGFqnp42Htvo9SEAWePHKOs=
 | 
			
		||||
github.com/mattn/go-shellwords v1.0.7/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
 | 
			
		||||
github.com/mattn/go-shellwords v1.0.9 h1:eaB5JspOwiKKcHdqcjbfe5lA9cNn/4NRRtddXJCimqk=
 | 
			
		||||
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/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/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 | 
			
		||||
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/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 | 
			
		||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 | 
			
		||||
github.com/moby/vpnkit v0.3.1-0.20190720080441-7dd3dcce7d3d/go.mod h1:KyjUrL9cb6ZSNNAUwZfqRjhwwgJ3BJN+kXh0t43WTUQ=
 | 
			
		||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
			
		||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 | 
			
		||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
			
		||||
| 
						 | 
				
			
			@ -290,11 +386,19 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
 | 
			
		|||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
 | 
			
		||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
 | 
			
		||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
 | 
			
		||||
github.com/mrtazz/checkmake v0.0.0-20191009095831-03dd76b964dd/go.mod h1:YBPKCT1PrhoFU743gPdtJNp+LmM0QlGMWME1J+FJtQI=
 | 
			
		||||
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
 | 
			
		||||
github.com/mtrmac/gpgme v0.0.0-20170102180018-b2432428689c h1:xa+eQWKuJ9MbB9FBL/eoNvDFvveAkz2LQoz8PzX7Q/4=
 | 
			
		||||
github.com/mtrmac/gpgme v0.0.0-20170102180018-b2432428689c/go.mod h1:GhAqVMEWnTcW2dxoD/SO3n2enrgWl3y6Dnx4m59GvcA=
 | 
			
		||||
github.com/mtrmac/gpgme v0.1.1 h1:a5ISnvahzTzBH0m/klhehN68N+9+/jLwhpPFtH3oPAQ=
 | 
			
		||||
github.com/mtrmac/gpgme v0.1.1/go.mod h1:GYYHnGSuS7HK3zVS2n3y73y0okK/BeKzwnn5jgiVFNI=
 | 
			
		||||
github.com/mtrmac/gpgme v0.1.2 h1:dNOmvYmsrakgW7LcgiprD0yfRuQQe8/C8F6Z+zogO3s=
 | 
			
		||||
github.com/mtrmac/gpgme v0.1.2/go.mod h1:GYYHnGSuS7HK3zVS2n3y73y0okK/BeKzwnn5jgiVFNI=
 | 
			
		||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 | 
			
		||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 | 
			
		||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
 | 
			
		||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
 | 
			
		||||
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 | 
			
		||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 | 
			
		||||
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
 | 
			
		||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 | 
			
		||||
| 
						 | 
				
			
			@ -308,7 +412,11 @@ github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY=
 | 
			
		|||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 | 
			
		||||
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
 | 
			
		||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 | 
			
		||||
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
 | 
			
		||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
 | 
			
		||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
 | 
			
		||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
 | 
			
		||||
github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 | 
			
		||||
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
 | 
			
		||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 | 
			
		||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
 | 
			
		||||
| 
						 | 
				
			
			@ -317,6 +425,8 @@ github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
 | 
			
		|||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 | 
			
		||||
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
 | 
			
		||||
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
 | 
			
		||||
github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
 | 
			
		||||
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 v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
 | 
			
		||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
 | 
			
		||||
| 
						 | 
				
			
			@ -325,6 +435,7 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM
 | 
			
		|||
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 h1:yN8BPXVwMBAm3Cuvh1L5XE8XpvYRMdsVLd82ILprhUU=
 | 
			
		||||
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
 | 
			
		||||
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
 | 
			
		||||
github.com/opencontainers/runc v0.0.0-20190425234816-dae70e8efea4/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
 | 
			
		||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
 | 
			
		||||
github.com/opencontainers/runc v1.0.0-rc8 h1:dDCFes8Hj1r/i5qnypONo5jdOme/8HWZC/aNDyhECt0=
 | 
			
		||||
github.com/opencontainers/runc v1.0.0-rc8/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
 | 
			
		||||
| 
						 | 
				
			
			@ -342,6 +453,8 @@ github.com/opencontainers/selinux v1.2.2 h1:Kx9J6eDG5/24A6DtUquGSpJQ+m2MUTahn4Ft
 | 
			
		|||
github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
 | 
			
		||||
github.com/opencontainers/selinux v1.3.0 h1:xsI95WzPZu5exzA6JzkLSfdr/DilzOhCJOqGe5TgR0g=
 | 
			
		||||
github.com/opencontainers/selinux v1.3.0/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
 | 
			
		||||
github.com/opencontainers/selinux v1.3.1 h1:dn2Rc3wTEvTB6iVqoFrKKeMb0uZ38ZheeyMu2h5C1TI=
 | 
			
		||||
github.com/opencontainers/selinux v1.3.1/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/go.mod h1:dv+J0b/HWai0QnMVb37/H0v36klkLBi2TNpPeWDxX10=
 | 
			
		||||
github.com/openshift/api v3.9.1-0.20190810003144-27fb16909b15+incompatible h1:s55wx8JIG/CKnewev892HifTBrtKzMdvgB3rm4rxC2s=
 | 
			
		||||
| 
						 | 
				
			
			@ -350,14 +463,20 @@ github.com/openshift/imagebuilder v1.1.0 h1:oT704SkwMEzmIMU/+Uv1Wmvt+p10q3v2WuYM
 | 
			
		|||
github.com/openshift/imagebuilder v1.1.0/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
 | 
			
		||||
github.com/openshift/imagebuilder v1.1.1 h1:KAUR31p8UBJdfVO42azWgb+LeMAed2zaKQ19e0C0X2I=
 | 
			
		||||
github.com/openshift/imagebuilder v1.1.1/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
 | 
			
		||||
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/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
 | 
			
		||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 | 
			
		||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 | 
			
		||||
github.com/pkg/errors v0.0.0-20190227000051-27936f6d90f9/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
			
		||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
			
		||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 | 
			
		||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
			
		||||
github.com/pkg/errors v0.9.0 h1:J8lpUdobwIeCI7OiSxHqEwJUKvJwicL5+3v1oe2Yb4k=
 | 
			
		||||
github.com/pkg/errors v0.9.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
			
		||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 | 
			
		||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
			
		||||
github.com/pkg/profile v1.4.0/go.mod h1:NWz/XGvpEW1FyYQ7fCx4dqYBLlfTcE+A9FLAkNKqjFE=
 | 
			
		||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
			
		||||
| 
						 | 
				
			
			@ -382,8 +501,15 @@ github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa
 | 
			
		|||
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
 | 
			
		||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
 | 
			
		||||
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
 | 
			
		||||
github.com/rhatdan/common v0.0.3-0.20200203010855-77d72c3e2feb h1:pABQ1OA6mO8XrdHran0oaTEvSb2aZpM+bI8+NfcjALQ=
 | 
			
		||||
github.com/rhatdan/common v0.0.3-0.20200203010855-77d72c3e2feb/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
 | 
			
		||||
github.com/rhatdan/common v0.0.3-0.20200208104512-837f7aa36449 h1:3uEI2WT7ZUWIKbbyKjm7etLgSSMOmdiJ4cqksVnuV9A=
 | 
			
		||||
github.com/rhatdan/common v0.0.3-0.20200208104512-837f7aa36449/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
 | 
			
		||||
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
 | 
			
		||||
github.com/rootless-containers/rootlesskit v0.7.2/go.mod h1:r9YL5mKRIdnwcYk4G8E5CSc9MDeFtgYmhfE4CSvDGYA=
 | 
			
		||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
 | 
			
		||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 | 
			
		||||
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
 | 
			
		||||
github.com/saschagrunert/storage v1.12.3-0.20191015073819-a34ddea087da h1:5aEGhStFh+0r/t0kT0utSi5C6MIMHBgMHkeIu1JUvfA=
 | 
			
		||||
github.com/saschagrunert/storage v1.12.3-0.20191015073819-a34ddea087da/go.mod h1:imKnA8Ozb99yPWt64WPrtNOR0v0HKQZFH4oLV45N22k=
 | 
			
		||||
github.com/saschagrunert/storage v1.12.3-0.20191018073047-1d43d5290f84 h1:iBs6FOO2GpFpdaa3WC4XhqHI6S2LE7RTlgn8LodsXVo=
 | 
			
		||||
| 
						 | 
				
			
			@ -410,19 +536,25 @@ github.com/saschagrunert/storage v1.12.3-0.20191204101521-aca03d333c53 h1:CBWb8W
 | 
			
		|||
github.com/saschagrunert/storage v1.12.3-0.20191204101521-aca03d333c53/go.mod h1:/Lild6FqQu2HwAVjVC9d5EAls3Mqwoxx67XpnR4UgEY=
 | 
			
		||||
github.com/seccomp/containers-golang v0.0.0-20180629143253-cdfdaa7543f4 h1:rOG9oHVIndNR14f3HRyBy9UPQYmIPniWqTU1TDdHhq4=
 | 
			
		||||
github.com/seccomp/containers-golang v0.0.0-20180629143253-cdfdaa7543f4/go.mod h1:f/98/SnvAzhAEFQJ3u836FePXvcbE8BS0YGMQNn4mhA=
 | 
			
		||||
github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f h1:OtU/w6sBKmXYaw2KEODxjcYi3oPSyyslhgGFgIJVGAI=
 | 
			
		||||
github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f/go.mod h1:f/98/SnvAzhAEFQJ3u836FePXvcbE8BS0YGMQNn4mhA=
 | 
			
		||||
github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo=
 | 
			
		||||
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
 | 
			
		||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 | 
			
		||||
github.com/sirupsen/logrus v0.0.0-20190403091019-9b3cdde74fbe/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 | 
			
		||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
 | 
			
		||||
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.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
 | 
			
		||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 | 
			
		||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 | 
			
		||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 | 
			
		||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 | 
			
		||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
 | 
			
		||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
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 v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 | 
			
		||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
 | 
			
		||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 | 
			
		||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 | 
			
		||||
| 
						 | 
				
			
			@ -443,21 +575,33 @@ github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0
 | 
			
		|||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
 | 
			
		||||
github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs=
 | 
			
		||||
github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
 | 
			
		||||
github.com/theckman/go-flock v0.7.1/go.mod h1:kjuth3y9VJ2aNlkNEO99G/8lp9fMIKaGyBmh84IBheM=
 | 
			
		||||
github.com/u-root/u-root v5.0.0+incompatible/go.mod h1:RYkpo8pTHrNjW08opNd/U6p/RJE7K0D8fXO0d47+3YY=
 | 
			
		||||
github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
 | 
			
		||||
github.com/uber/jaeger-lib v0.0.0-20190122222657-d036253de8f5/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
 | 
			
		||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
 | 
			
		||||
github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8=
 | 
			
		||||
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
 | 
			
		||||
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 | 
			
		||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 | 
			
		||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 | 
			
		||||
github.com/varlink/go v0.0.0-20190502142041-0f1d566d194b/go.mod h1:YHaw8N660ESgMgLOZfLQqT1htFItynAUxMesFBho52s=
 | 
			
		||||
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/vbauerster/mpb v3.4.0+incompatible h1:mfiiYw87ARaeRW6x5gWwYRUawxaW1tLAD8IceomUCNw=
 | 
			
		||||
github.com/vbauerster/mpb v3.4.0+incompatible/go.mod h1:zAHG26FUhVKETRu+MWqYXcI70POlC6N8up9p1dID7SU=
 | 
			
		||||
github.com/vbauerster/mpb/v4 v4.11.1 h1:ZOYQSVHgmeanXsbyC44aDg76tBGCS/54Rk8VkL8dJGA=
 | 
			
		||||
github.com/vbauerster/mpb/v4 v4.11.1/go.mod h1:vMLa1J/ZKC83G2lB/52XpqT+ZZtFG4aZOdKhmpRL1uM=
 | 
			
		||||
github.com/vbauerster/mpb/v4 v4.11.2 h1:ynkUoKzi65DZ1UsQPx7sgi/KN6G9f7br+Us2nKm35AM=
 | 
			
		||||
github.com/vbauerster/mpb/v4 v4.11.2/go.mod h1:jIuIRCltGJUnm6DCyPVkwjlLUk4nHTH+m4eD14CdFF0=
 | 
			
		||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
 | 
			
		||||
github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM=
 | 
			
		||||
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
 | 
			
		||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
 | 
			
		||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
 | 
			
		||||
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f h1:nBX3nTcmxEtHSERBJaIo1Qa26VwRaopnZmfDQUXsF4I=
 | 
			
		||||
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
 | 
			
		||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
 | 
			
		||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
 | 
			
		||||
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=
 | 
			
		||||
| 
						 | 
				
			
			@ -473,10 +617,14 @@ go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
 | 
			
		|||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 | 
			
		||||
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
 | 
			
		||||
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=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/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 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
			
		||||
| 
						 | 
				
			
			@ -496,11 +644,15 @@ golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73r
 | 
			
		|||
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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
			
		||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
			
		||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
			
		||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
			
		||||
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
			
		||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
			
		||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 | 
			
		||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 | 
			
		||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 | 
			
		||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU=
 | 
			
		||||
| 
						 | 
				
			
			@ -509,6 +661,8 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL
 | 
			
		|||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
 | 
			
		||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 | 
			
		||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
 | 
			
		||||
| 
						 | 
				
			
			@ -527,14 +681,18 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w
 | 
			
		|||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190425145619-16072639606e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542 h1:6ZQFf1D2YYDDI7eSwW8adlkkavTB9sw5I24FVtEvNUQ=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0=
 | 
			
		||||
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=
 | 
			
		||||
| 
						 | 
				
			
			@ -543,13 +701,17 @@ golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7w
 | 
			
		|||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo=
 | 
			
		||||
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-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.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 | 
			
		||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 | 
			
		||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 | 
			
		||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 | 
			
		||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 h1:xQwXv67TxFo9nC1GJFyab5eq/5B590r6RlnL/G8Sz7w=
 | 
			
		||||
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
			
		||||
| 
						 | 
				
			
			@ -563,26 +725,34 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
 | 
			
		|||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 | 
			
		||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 | 
			
		||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 | 
			
		||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 | 
			
		||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 | 
			
		||||
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
 | 
			
		||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
 | 
			
		||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
 | 
			
		||||
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.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 | 
			
		||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb h1:i1Ppqkc3WQXikh8bXiwHqAN5Rv3/qDCcRk0/Otx73BY=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601 h1:9VBRTdmgQxbs6HE0sUnMrSWNePppAJU07NYvX5dIB04=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
 | 
			
		||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 | 
			
		||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
 | 
			
		||||
google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw=
 | 
			
		||||
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
 | 
			
		||||
google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s=
 | 
			
		||||
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
 | 
			
		||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
 | 
			
		||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 | 
			
		||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 | 
			
		||||
| 
						 | 
				
			
			@ -591,10 +761,12 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
 | 
			
		|||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 | 
			
		||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 | 
			
		||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
 | 
			
		||||
gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o=
 | 
			
		||||
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 | 
			
		||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 | 
			
		||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 | 
			
		||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
 | 
			
		||||
gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4=
 | 
			
		||||
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
 | 
			
		||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 | 
			
		||||
| 
						 | 
				
			
			@ -604,33 +776,47 @@ 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.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
 | 
			
		||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
			
		||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
 | 
			
		||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
			
		||||
gotest.tools v0.0.0-20190624233834-05ebafbffc79/go.mod h1:R//lfYlUuTOTfblYI3lGoAAAebUdzjvbmQsuB7Ykd90=
 | 
			
		||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
 | 
			
		||||
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-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 | 
			
		||||
k8s.io/api v0.0.0-20190620084959-7cf5895f2711/go.mod h1:TBhBqb1AWbBQbW3XRusr7n7E4v2+5ZY8r8sAMnyFC5A=
 | 
			
		||||
k8s.io/api v0.0.0-20190813020757-36bff7324fb7 h1:4uJOjRn9kWq4AqJRE8+qzmAy+lJd9rh8TY455dNef4U=
 | 
			
		||||
k8s.io/api v0.0.0-20190813020757-36bff7324fb7/go.mod h1:3Iy+myeAORNCLgjd/Xu9ebwN7Vh59Bw0vh9jhoX+V58=
 | 
			
		||||
k8s.io/api v0.17.0 h1:H9d/lw+VkZKEVIUc8F3wgiQ+FUXTTr21M87jXLU7yqM=
 | 
			
		||||
k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
 | 
			
		||||
k8s.io/api v0.17.2 h1:NF1UFXcKN7/OOv1uxdRz3qfra8AHsPav5M93hlV9+Dc=
 | 
			
		||||
k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4=
 | 
			
		||||
k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719/go.mod h1:I4A+glKBHiTgiEjQiCCQfCAIcIMFGt291SmsvcrFzJA=
 | 
			
		||||
k8s.io/apimachinery v0.0.0-20190809020650-423f5d784010 h1:pyoq062NftC1y/OcnbSvgolyZDJ8y4fmUPWMkdA6gfU=
 | 
			
		||||
k8s.io/apimachinery v0.0.0-20190809020650-423f5d784010/go.mod h1:Waf/xTS2FGRrgXCkO5FP3XxTOWh0qLf2QhL1qFZZ/R8=
 | 
			
		||||
k8s.io/apimachinery v0.17.0 h1:xRBnuie9rXcPxUkDizUsGvPf1cnlZCFu210op7J7LJo=
 | 
			
		||||
k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
 | 
			
		||||
k8s.io/apimachinery v0.17.2 h1:hwDQQFbdRlpnnsR64Asdi55GyCaIP/3WQpMmbNBeWr4=
 | 
			
		||||
k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
 | 
			
		||||
k8s.io/client-go v0.0.0-20170217214107-bcde30fb7eae/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
 | 
			
		||||
k8s.io/client-go v0.0.0-20181219152756-3dd551c0f083 h1:+Qf/nITucAbm09aIdxvoA+7X0BwaXmQGVoR8k7Ynk9o=
 | 
			
		||||
k8s.io/client-go v0.0.0-20181219152756-3dd551c0f083/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
 | 
			
		||||
k8s.io/client-go v0.0.0-20190620085101-78d2af792bab h1:E8Fecph0qbNsAbijJJQryKu4Oi9QTp5cVpjTE+nqg6g=
 | 
			
		||||
k8s.io/client-go v0.0.0-20190620085101-78d2af792bab/go.mod h1:E95RaSlHr79aHaX0aGSwcPNfygDiPKOVXdmivCIZT0k=
 | 
			
		||||
k8s.io/code-generator v0.17.0/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
 | 
			
		||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
 | 
			
		||||
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
 | 
			
		||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
 | 
			
		||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
 | 
			
		||||
k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68=
 | 
			
		||||
k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
 | 
			
		||||
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
 | 
			
		||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
 | 
			
		||||
k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
 | 
			
		||||
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4=
 | 
			
		||||
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
 | 
			
		||||
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
 | 
			
		||||
k8s.io/utils v0.0.0-20190221042446-c2654d5206da/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0=
 | 
			
		||||
k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
 | 
			
		||||
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
 | 
			
		||||
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
 | 
			
		||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,11 +13,11 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/containers/buildah"
 | 
			
		||||
	"github.com/containers/common/pkg/config"
 | 
			
		||||
	"github.com/containers/image/v5/docker/reference"
 | 
			
		||||
	"github.com/containers/image/v5/types"
 | 
			
		||||
	"github.com/containers/storage"
 | 
			
		||||
	"github.com/containers/storage/pkg/archive"
 | 
			
		||||
	"github.com/opencontainers/runc/libcontainer/configs"
 | 
			
		||||
	specs "github.com/opencontainers/runtime-spec/specs-go"
 | 
			
		||||
	"github.com/openshift/imagebuilder"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +66,7 @@ type BuildOptions struct {
 | 
			
		|||
	// RuntimeArgs adds global arguments for the runtime.
 | 
			
		||||
	RuntimeArgs []string
 | 
			
		||||
	// TransientMounts is a list of mounts that won't be kept in the image.
 | 
			
		||||
	TransientMounts []Mount
 | 
			
		||||
	TransientMounts []string
 | 
			
		||||
	// Compression specifies the type of compression which is applied to
 | 
			
		||||
	// layer blobs.  The default is to not use compression, but
 | 
			
		||||
	// archive.Gzip is recommended.
 | 
			
		||||
| 
						 | 
				
			
			@ -156,10 +156,16 @@ type BuildOptions struct {
 | 
			
		|||
	ForceRmIntermediateCtrs bool
 | 
			
		||||
	// BlobDirectory is a directory which we'll use for caching layer blobs.
 | 
			
		||||
	BlobDirectory string
 | 
			
		||||
	// Target the targeted FROM in the Dockerfile to build
 | 
			
		||||
	// Target the targeted FROM in the Dockerfile to build.
 | 
			
		||||
	Target string
 | 
			
		||||
	// Devices are the additional devices to add to the containers
 | 
			
		||||
	Devices []configs.Device
 | 
			
		||||
	// Devices are the additional devices to add to the containers.
 | 
			
		||||
	Devices []string
 | 
			
		||||
	// SignBy is the fingerprint of a GPG key to use for signing images.
 | 
			
		||||
	SignBy string
 | 
			
		||||
	// Architecture specifies the target architecture of the image to be built.
 | 
			
		||||
	Architecture string
 | 
			
		||||
	// OS is the specifies the operating system of the image to be built.
 | 
			
		||||
	OS string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BuildDockerfiles parses a set of one or more Dockerfiles (which may be
 | 
			
		||||
| 
						 | 
				
			
			@ -250,6 +256,11 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOpt
 | 
			
		|||
		return "", nil, errors.Wrapf(err, "error creating build executor")
 | 
			
		||||
	}
 | 
			
		||||
	b := imagebuilder.NewBuilder(options.Args)
 | 
			
		||||
	defaultContainerConfig, err := config.Default()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", nil, errors.Wrapf(err, "failed to get container config")
 | 
			
		||||
	}
 | 
			
		||||
	b.Env = append(defaultContainerConfig.GetDefaultEnv(), b.Env...)
 | 
			
		||||
	stages, err := imagebuilder.NewStages(mainNode, b)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", nil, errors.Wrap(err, "error reading multiple stages")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,9 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/containers/buildah"
 | 
			
		||||
	"github.com/containers/buildah/pkg/parse"
 | 
			
		||||
	"github.com/containers/buildah/util"
 | 
			
		||||
	"github.com/containers/common/pkg/config"
 | 
			
		||||
	"github.com/containers/image/v5/docker/reference"
 | 
			
		||||
	is "github.com/containers/image/v5/storage"
 | 
			
		||||
	"github.com/containers/image/v5/transports"
 | 
			
		||||
| 
						 | 
				
			
			@ -91,17 +93,44 @@ type Executor struct {
 | 
			
		|||
	excludes                       []string
 | 
			
		||||
	unusedArgs                     map[string]struct{}
 | 
			
		||||
	buildArgs                      map[string]string
 | 
			
		||||
	addCapabilities                []string
 | 
			
		||||
	dropCapabilities               []string
 | 
			
		||||
	capabilities                   []string
 | 
			
		||||
	devices                        []configs.Device
 | 
			
		||||
	signBy                         string
 | 
			
		||||
	architecture                   string
 | 
			
		||||
	os                             string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewExecutor creates a new instance of the imagebuilder.Executor interface.
 | 
			
		||||
func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Node) (*Executor, error) {
 | 
			
		||||
	defaultContainerConfig, err := config.Default()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(err, "failed to get container config")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	excludes, err := imagebuilder.ParseDockerignore(options.ContextDirectory)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	capabilities := defaultContainerConfig.Capabilities("", options.AddCapabilities, options.DropCapabilities)
 | 
			
		||||
 | 
			
		||||
	devices := []configs.Device{}
 | 
			
		||||
	for _, device := range append(defaultContainerConfig.Containers.AdditionalDevices, options.Devices...) {
 | 
			
		||||
		dev, err := parse.DeviceFromPath(device)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		devices = append(dev, devices...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	transientMounts := []Mount{}
 | 
			
		||||
	for _, volume := range append(defaultContainerConfig.Containers.AdditionalVolumes, options.TransientMounts...) {
 | 
			
		||||
		mount, err := parse.Volume(volume)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		transientMounts = append([]Mount{Mount(mount)}, transientMounts...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	exec := Executor{
 | 
			
		||||
		store:                          store,
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +142,7 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod
 | 
			
		|||
		quiet:                          options.Quiet,
 | 
			
		||||
		runtime:                        options.Runtime,
 | 
			
		||||
		runtimeArgs:                    options.RuntimeArgs,
 | 
			
		||||
		transientMounts:                options.TransientMounts,
 | 
			
		||||
		transientMounts:                transientMounts,
 | 
			
		||||
		compression:                    options.Compression,
 | 
			
		||||
		output:                         options.Output,
 | 
			
		||||
		outputFormat:                   options.OutputFormat,
 | 
			
		||||
| 
						 | 
				
			
			@ -148,9 +177,11 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod
 | 
			
		|||
		blobDirectory:                  options.BlobDirectory,
 | 
			
		||||
		unusedArgs:                     make(map[string]struct{}),
 | 
			
		||||
		buildArgs:                      options.Args,
 | 
			
		||||
		addCapabilities:                options.AddCapabilities,
 | 
			
		||||
		dropCapabilities:               options.DropCapabilities,
 | 
			
		||||
		devices:                        options.Devices,
 | 
			
		||||
		capabilities:                   capabilities,
 | 
			
		||||
		devices:                        devices,
 | 
			
		||||
		signBy:                         options.SignBy,
 | 
			
		||||
		architecture:                   options.Architecture,
 | 
			
		||||
		os:                             options.OS,
 | 
			
		||||
	}
 | 
			
		||||
	if exec.err == nil {
 | 
			
		||||
		exec.err = os.Stderr
 | 
			
		||||
| 
						 | 
				
			
			@ -527,7 +558,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
 | 
			
		|||
	if err := cleanup(); err != nil {
 | 
			
		||||
		return "", nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logrus.Debugf("printing final image id %q", imageID)
 | 
			
		||||
	if b.iidfile != "" {
 | 
			
		||||
		if err = ioutil.WriteFile(b.iidfile, []byte(imageID), 0644); err != nil {
 | 
			
		||||
			return imageID, ref, errors.Wrapf(err, "failed to write image ID to file %q", b.iidfile)
 | 
			
		||||
| 
						 | 
				
			
			@ -537,7 +568,6 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
 | 
			
		|||
			return imageID, ref, errors.Wrapf(err, "failed to write image ID to stdout")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return imageID, ref, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -253,7 +253,7 @@ func (s *StageExecutor) volumeCacheRestore() error {
 | 
			
		|||
// don't care about the details of where in the filesystem the content actually
 | 
			
		||||
// goes, because we're not actually going to add it here, so this is less
 | 
			
		||||
// involved than Copy().
 | 
			
		||||
func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []string) (string, error) {
 | 
			
		||||
func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []string, envValues []string) (string, error) {
 | 
			
		||||
	// No instruction: done.
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		return "", nil
 | 
			
		||||
| 
						 | 
				
			
			@ -298,10 +298,11 @@ func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []st
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	varValues := append(argValues, envValues...)
 | 
			
		||||
	for _, src := range srcs {
 | 
			
		||||
		// If src has an argument within it, resolve it to its
 | 
			
		||||
		// value.  Otherwise just return the value found.
 | 
			
		||||
		name, err := imagebuilder.ProcessWord(src, argValues)
 | 
			
		||||
		name, err := imagebuilder.ProcessWord(src, varValues)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", errors.Wrapf(err, "unable to resolve source %q", src)
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -315,8 +316,12 @@ func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []st
 | 
			
		|||
		} else {
 | 
			
		||||
			// Source is not a URL, so it's a location relative to
 | 
			
		||||
			// the all-content-comes-from-below-this-directory
 | 
			
		||||
			// directory.
 | 
			
		||||
			// directory.  Also raise an error if the src escapes
 | 
			
		||||
			// the context directory.
 | 
			
		||||
			contextSrc, err := securejoin.SecureJoin(contextDir, src)
 | 
			
		||||
			if err == nil && strings.HasPrefix(src, "../") {
 | 
			
		||||
				err = errors.New("escaping context directory error")
 | 
			
		||||
			}
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return "", errors.Wrapf(err, "forbidden path for %q, it is outside of the build context %q", src, contextDir)
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -345,7 +350,7 @@ func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []st
 | 
			
		|||
 | 
			
		||||
	// If destination.Value has an argument within it, resolve it to its
 | 
			
		||||
	// value.  Otherwise just return the value found.
 | 
			
		||||
	destValue, destErr := imagebuilder.ProcessWord(destination.Value, argValues)
 | 
			
		||||
	destValue, destErr := imagebuilder.ProcessWord(destination.Value, varValues)
 | 
			
		||||
	if destErr != nil {
 | 
			
		||||
		return "", errors.Wrapf(destErr, "unable to resolve destination %q", destination.Value)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -434,8 +439,12 @@ func (s *StageExecutor) Copy(excludes []string, copies ...imagebuilder.Copy) err
 | 
			
		|||
				// Treat the source, which is not a URL, as a
 | 
			
		||||
				// location relative to the
 | 
			
		||||
				// all-content-comes-from-below-this-directory
 | 
			
		||||
				// directory.
 | 
			
		||||
				// directory.  Also raise an error if the src
 | 
			
		||||
				// escapes the context directory.
 | 
			
		||||
				srcSecure, err := securejoin.SecureJoin(contextDir, src)
 | 
			
		||||
				if err == nil && strings.HasPrefix(src, "../") {
 | 
			
		||||
					err = errors.New("escaping context directory error")
 | 
			
		||||
				}
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return errors.Wrapf(err, "forbidden path for %q, it is outside of the build context %q", src, contextDir)
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -452,6 +461,11 @@ func (s *StageExecutor) Copy(excludes []string, copies ...imagebuilder.Copy) err
 | 
			
		|||
							Excludes:         copyExcludes,
 | 
			
		||||
							IDMappingOptions: idMappingOptions,
 | 
			
		||||
						}
 | 
			
		||||
						// If we've a tar file, it will create a directory using the name of the tar
 | 
			
		||||
						// file if we don't blank it out.
 | 
			
		||||
						if strings.HasSuffix(srcName, ".tar") || strings.HasSuffix(srcName, ".gz") {
 | 
			
		||||
							srcName = ""
 | 
			
		||||
						}
 | 
			
		||||
						if err := s.builder.Add(filepath.Join(copy.Dest, srcName), copy.Download, options, srcSecure); err != nil {
 | 
			
		||||
							return err
 | 
			
		||||
						}
 | 
			
		||||
| 
						 | 
				
			
			@ -605,8 +619,7 @@ func (s *StageExecutor) prepare(ctx context.Context, stage imagebuilder.Stage, f
 | 
			
		|||
		CommonBuildOpts:       s.executor.commonBuildOptions,
 | 
			
		||||
		DefaultMountsFilePath: s.executor.defaultMountsFilePath,
 | 
			
		||||
		Format:                s.executor.outputFormat,
 | 
			
		||||
		AddCapabilities:       s.executor.addCapabilities,
 | 
			
		||||
		DropCapabilities:      s.executor.dropCapabilities,
 | 
			
		||||
		Capabilities:          s.executor.capabilities,
 | 
			
		||||
		Devices:               s.executor.devices,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -771,8 +784,12 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
	logImageID := func(imgID string) {
 | 
			
		||||
		if len(imgID) > 11 {
 | 
			
		||||
			imgID = imgID[0:11]
 | 
			
		||||
		}
 | 
			
		||||
		if s.executor.iidfile == "" {
 | 
			
		||||
			fmt.Fprintf(s.executor.out, "%s\n", imgID)
 | 
			
		||||
 | 
			
		||||
			fmt.Fprintf(s.executor.out, "--> %s\n", imgID)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -869,7 +886,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
 | 
			
		|||
				return "", nil, errors.Wrapf(err, "error building at STEP \"%s\"", step.Message)
 | 
			
		||||
			}
 | 
			
		||||
			// In case we added content, retrieve its digest.
 | 
			
		||||
			addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments())
 | 
			
		||||
			addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments(), ib.Config().Env)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return "", nil, err
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -918,7 +935,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
 | 
			
		|||
		// cached images so far, look for one that matches what we
 | 
			
		||||
		// expect to produce for this instruction.
 | 
			
		||||
		if checkForLayers && !(s.executor.squash && lastInstruction && lastStage) {
 | 
			
		||||
			addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments())
 | 
			
		||||
			addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments(), ib.Config().Env)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return "", nil, err
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -976,7 +993,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
 | 
			
		|||
				return "", nil, errors.Wrapf(err, "error building at STEP \"%s\"", step.Message)
 | 
			
		||||
			}
 | 
			
		||||
			// In case we added content, retrieve its digest.
 | 
			
		||||
			addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments())
 | 
			
		||||
			addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments(), ib.Config().Env)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return "", nil, err
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -1013,7 +1030,6 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return imgID, ref, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1132,6 +1148,8 @@ func (s *StageExecutor) commit(ctx context.Context, ib *imagebuilder.Builder, cr
 | 
			
		|||
	}
 | 
			
		||||
	s.builder.SetHostname(config.Hostname)
 | 
			
		||||
	s.builder.SetDomainname(config.Domainname)
 | 
			
		||||
	s.builder.SetArchitecture(s.executor.architecture)
 | 
			
		||||
	s.builder.SetOS(s.executor.os)
 | 
			
		||||
	s.builder.SetUser(config.User)
 | 
			
		||||
	s.builder.ClearPorts()
 | 
			
		||||
	for p := range config.ExposedPorts {
 | 
			
		||||
| 
						 | 
				
			
			@ -1204,6 +1222,7 @@ func (s *StageExecutor) commit(ctx context.Context, ib *imagebuilder.Builder, cr
 | 
			
		|||
		Squash:                s.executor.squash,
 | 
			
		||||
		EmptyLayer:            emptyLayer,
 | 
			
		||||
		BlobDirectory:         s.executor.blobDirectory,
 | 
			
		||||
		SignBy:                s.executor.signBy,
 | 
			
		||||
	}
 | 
			
		||||
	imgID, _, manifestDigest, err := s.builder.Commit(ctx, imageRef, options)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,6 @@ import (
 | 
			
		|||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/containers/buildah/util"
 | 
			
		||||
	"github.com/containers/common/pkg/cgroups"
 | 
			
		||||
	"github.com/containers/common/pkg/unshare"
 | 
			
		||||
	"github.com/containers/storage"
 | 
			
		||||
	"github.com/containers/storage/pkg/system"
 | 
			
		||||
| 
						 | 
				
			
			@ -48,7 +47,7 @@ func hostInfo() map[string]interface{} {
 | 
			
		|||
	info["cpus"] = runtime.NumCPU()
 | 
			
		||||
	info["rootless"] = unshare.IsRootless()
 | 
			
		||||
 | 
			
		||||
	unified, err := cgroups.IsCgroup2UnifiedMode()
 | 
			
		||||
	unified, err := util.IsCgroup2UnifiedMode()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logrus.Error(err, "err reading cgroups mode")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,12 +4,87 @@
 | 
			
		|||
 | 
			
		||||
## Installing packaged versions of buildah
 | 
			
		||||
 | 
			
		||||
#### [Amazon Linux 2](https://aws.amazon.com/amazon-linux-2/)
 | 
			
		||||
 | 
			
		||||
The [Kubic project](https://build.opensuse.org/project/show/devel:kubic:libcontainers:stable)
 | 
			
		||||
provides updated packages for CentOS 7 which can be used unmodified on Amazon Linux 2.
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
cd /etc/yum.repos.d/
 | 
			
		||||
sudo wget https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_7/devel:kubic:libcontainers:stable.repo
 | 
			
		||||
sudo yum -y install buildah
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### [Arch Linux](https://www.archlinux.org)
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo pacman -S buildah
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### [CentOS](https://www.centos.org)
 | 
			
		||||
 | 
			
		||||
Buildah is available in the default Extras repos for CentOS 7 and in
 | 
			
		||||
the AppStream repo for CentOS 8 and Stream, however the available version often
 | 
			
		||||
lags the upstream release.
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo yum -y install buildah
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The [Kubic project](https://build.opensuse.org/project/show/devel:kubic:libcontainers:stable)
 | 
			
		||||
provides updated packages for CentOS 7, 8 and Stream.
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# CentOS 7
 | 
			
		||||
cd /etc/yum.repos.d/
 | 
			
		||||
sudo wget https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_7/devel:kubic:libcontainers:stable.repo
 | 
			
		||||
sudo yum -y install buildah
 | 
			
		||||
 | 
			
		||||
# CentOS 8
 | 
			
		||||
sudo dnf -y module disable container-tools
 | 
			
		||||
sudo dnf -y install 'dnf-command(copr)'
 | 
			
		||||
sudo dnf -y copr enable rhcontainerbot/container-selinux
 | 
			
		||||
cd /etc/yum.repos.d
 | 
			
		||||
sudo wget https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_8/devel:kubic:libcontainers:stable.repo
 | 
			
		||||
sudo dnf -y install buildah
 | 
			
		||||
 | 
			
		||||
# CentOS Stream
 | 
			
		||||
sudo dnf -y module disable container-tools
 | 
			
		||||
sudo dnf -y install 'dnf-command(copr)'
 | 
			
		||||
sudo dnf -y copr enable rhcontainerbot/container-selinux
 | 
			
		||||
cd /etc/yum.repos.d
 | 
			
		||||
sudo wget https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_8_Stream/devel:kubic:libcontainers:stable.repo
 | 
			
		||||
sudo dnf -y install buildah
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### [Debian](https://debian.org)
 | 
			
		||||
 | 
			
		||||
The buildah package is [being worked on](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=928083)
 | 
			
		||||
for inclusion in the default Debian repos.
 | 
			
		||||
 | 
			
		||||
Alternatively, the [Kubic project](https://build.opensuse.org/project/show/devel:kubic:libcontainers:stable)
 | 
			
		||||
provides packages for Debian 10, testing and unstable.
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# Debian Unstable/Sid
 | 
			
		||||
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Unstable/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
 | 
			
		||||
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_Unstable/Release.key -O Release.key
 | 
			
		||||
 | 
			
		||||
# Debian Testing
 | 
			
		||||
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Testing/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
 | 
			
		||||
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_Testing/Release.key -O Release.key
 | 
			
		||||
 | 
			
		||||
# Debian 10
 | 
			
		||||
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
 | 
			
		||||
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_10/Release.key -O Release.key
 | 
			
		||||
 | 
			
		||||
sudo apt-key add - < Release.key
 | 
			
		||||
sudo apt-get update -qq
 | 
			
		||||
sudo apt-get -qq -y install buildah
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### [Fedora](https://www.fedoraproject.org), [CentOS](https://www.centos.org)
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +101,7 @@ Not Available.  Must be installed via package layering.
 | 
			
		|||
 | 
			
		||||
rpm-ostree install buildah
 | 
			
		||||
 | 
			
		||||
Note: `[podman](https://podman.io) build` is available by default.
 | 
			
		||||
Note: [`podman`](https://podman.io) build is available by default.
 | 
			
		||||
 | 
			
		||||
### [Gentoo](https://www.gentoo.org)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +128,19 @@ sudo subscription-manager repos --enable=rhel-7-server-extras-rpms
 | 
			
		|||
sudo yum -y install buildah
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### [Raspbian](https://raspbian.org)
 | 
			
		||||
 | 
			
		||||
The Kubic project provides packages for Raspbian 10.
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# Raspbian 10
 | 
			
		||||
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Raspbian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
 | 
			
		||||
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Raspbian_10/Release.key -O Release.key
 | 
			
		||||
sudo apt-key add - < Release.key
 | 
			
		||||
sudo apt-get update -qq
 | 
			
		||||
sudo apt-get -qq -y install buildah
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### [RHEL8 Beta](https://www.redhat.com/en/blog/powering-its-future-while-preserving-present-introducing-red-hat-enterprise-linux-8-beta?intcmp=701f2000001Cz6OAAS)
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
| 
						 | 
				
			
			@ -62,10 +150,13 @@ sudo yum module install -y buildah
 | 
			
		|||
 | 
			
		||||
### [Ubuntu](https://www.ubuntu.com)
 | 
			
		||||
 | 
			
		||||
The Kubic project provides packages for Ubuntu 18.04, 19.04 and 19.10 (it should also work with direct derivatives like Pop!\_OS).
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo apt-get update -qq
 | 
			
		||||
sudo apt-get install -qq -y software-properties-common
 | 
			
		||||
sudo add-apt-repository -y ppa:projectatomic/ppa
 | 
			
		||||
. /etc/os-release
 | 
			
		||||
sudo sh -c "echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/x${ID^}_${VERSION_ID}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list"
 | 
			
		||||
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/x${ID^}_${VERSION_ID}/Release.key -O Release.key
 | 
			
		||||
sudo apt-key add - < Release.key
 | 
			
		||||
sudo apt-get update -qq
 | 
			
		||||
sudo apt-get -qq -y install buildah
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			@ -107,9 +198,9 @@ named `containernetworking-cni`).  If not, they will need to be installed,
 | 
			
		|||
for example using:
 | 
			
		||||
```
 | 
			
		||||
  git clone https://github.com/containernetworking/plugins
 | 
			
		||||
  ( cd ./plugins; ./build.sh )
 | 
			
		||||
  mkdir -p /opt/cni/bin
 | 
			
		||||
  install -v ./plugins/bin/* /opt/cni/bin
 | 
			
		||||
  ( cd ./plugins; ./build_linux.sh )
 | 
			
		||||
  sudo mkdir -p /opt/cni/bin
 | 
			
		||||
  sudo install -v ./plugins/bin/* /opt/cni/bin
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The CNI library needs to be configured so that it will know which plugins to
 | 
			
		||||
| 
						 | 
				
			
			@ -233,13 +324,13 @@ The build steps for Buildah on SUSE / openSUSE are the same as for Fedora, above
 | 
			
		|||
In Ubuntu zesty and xenial, you can use these commands:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
  apt-get -y install software-properties-common
 | 
			
		||||
  add-apt-repository -y ppa:alexlarsson/flatpak
 | 
			
		||||
  add-apt-repository -y ppa:gophers/archive
 | 
			
		||||
  apt-add-repository -y ppa:projectatomic/ppa
 | 
			
		||||
  apt-get -y -qq update
 | 
			
		||||
  apt-get -y install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man
 | 
			
		||||
  apt-get -y install golang-1.12
 | 
			
		||||
  sudo apt-get -y install software-properties-common
 | 
			
		||||
  sudo add-apt-repository -y ppa:alexlarsson/flatpak
 | 
			
		||||
  sudo add-apt-repository -y ppa:gophers/archive
 | 
			
		||||
  sudo apt-add-repository -y ppa:projectatomic/ppa
 | 
			
		||||
  sudo apt-get -y -qq update
 | 
			
		||||
  sudo apt-get -y install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man
 | 
			
		||||
  sudo apt-get -y install golang-1.12
 | 
			
		||||
```
 | 
			
		||||
Then to install Buildah on Ubuntu follow the steps in this example:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -249,7 +340,7 @@ Then to install Buildah on Ubuntu follow the steps in this example:
 | 
			
		|||
  export GOPATH=`pwd`
 | 
			
		||||
  git clone https://github.com/containers/buildah ./src/github.com/containers/buildah
 | 
			
		||||
  cd ./src/github.com/containers/buildah
 | 
			
		||||
  PATH=/usr/lib/go-1.10/bin:$PATH make runc all SECURITYTAGS="apparmor seccomp"
 | 
			
		||||
  PATH=/usr/lib/go-1.12/bin:$PATH make runc all SECURITYTAGS="apparmor seccomp"
 | 
			
		||||
  sudo make install install.runc
 | 
			
		||||
  buildah --help
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			@ -260,11 +351,11 @@ To install the required dependencies, you can use those commands, tested under D
 | 
			
		|||
 | 
			
		||||
```
 | 
			
		||||
gpg --recv-keys 0x018BA5AD9DF57A4448F0E6CF8BECF1637AD8C79D
 | 
			
		||||
gpg --export 0x018BA5AD9DF57A4448F0E6CF8BECF1637AD8C79D >> /usr/share/keyrings/projectatomic-ppa.gpg
 | 
			
		||||
echo 'deb [signed-by=/usr/share/keyrings/projectatomic-ppa.gpg] http://ppa.launchpad.net/projectatomic/ppa/ubuntu zesty main' > /etc/apt/sources.list.d/projectatomic-ppa.list
 | 
			
		||||
apt update
 | 
			
		||||
apt -y install -t stretch-backports golang
 | 
			
		||||
apt -y install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man
 | 
			
		||||
sudo gpg --export 0x018BA5AD9DF57A4448F0E6CF8BECF1637AD8C79D >> /usr/share/keyrings/projectatomic-ppa.gpg
 | 
			
		||||
sudo echo 'deb [signed-by=/usr/share/keyrings/projectatomic-ppa.gpg] http://ppa.launchpad.net/projectatomic/ppa/ubuntu zesty main' > /etc/apt/sources.list.d/projectatomic-ppa.list
 | 
			
		||||
sudo apt update
 | 
			
		||||
sudo apt -y install -t stretch-backports golang
 | 
			
		||||
sudo apt -y install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The build steps on Debian are otherwise the same as Ubuntu, above.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -398,14 +398,13 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
 | 
			
		|||
			UIDMap:         uidmap,
 | 
			
		||||
			GIDMap:         gidmap,
 | 
			
		||||
		},
 | 
			
		||||
		AddCapabilities:  copyStringSlice(options.AddCapabilities),
 | 
			
		||||
		DropCapabilities: copyStringSlice(options.DropCapabilities),
 | 
			
		||||
		CommonBuildOpts:  options.CommonBuildOpts,
 | 
			
		||||
		TopLayer:         topLayer,
 | 
			
		||||
		Args:             options.Args,
 | 
			
		||||
		Format:           options.Format,
 | 
			
		||||
		TempVolumes:      map[string]bool{},
 | 
			
		||||
		Devices:          options.Devices,
 | 
			
		||||
		Capabilities:    copyStringSlice(options.Capabilities),
 | 
			
		||||
		CommonBuildOpts: options.CommonBuildOpts,
 | 
			
		||||
		TopLayer:        topLayer,
 | 
			
		||||
		Args:            options.Args,
 | 
			
		||||
		Format:          options.Format,
 | 
			
		||||
		TempVolumes:     map[string]bool{},
 | 
			
		||||
		Devices:         options.Devices,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if options.Mount {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,9 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/containers/buildah"
 | 
			
		||||
	"github.com/containers/buildah/pkg/parse"
 | 
			
		||||
	"github.com/containers/buildah/util"
 | 
			
		||||
	"github.com/containers/common/pkg/config"
 | 
			
		||||
	"github.com/opencontainers/runtime-spec/specs-go"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"github.com/spf13/pflag"
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +47,7 @@ type NameSpaceResults struct {
 | 
			
		|||
// BudResults represents the results for Bud flags
 | 
			
		||||
type BudResults struct {
 | 
			
		||||
	Annotation          []string
 | 
			
		||||
	Arch                string
 | 
			
		||||
	Authfile            string
 | 
			
		||||
	BuildArg            []string
 | 
			
		||||
	CacheFrom           string
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +63,7 @@ type BudResults struct {
 | 
			
		|||
	Logfile             string
 | 
			
		||||
	Loglevel            int
 | 
			
		||||
	NoCache             bool
 | 
			
		||||
	OS                  string
 | 
			
		||||
	Platform            string
 | 
			
		||||
	Pull                bool
 | 
			
		||||
	PullAlways          bool
 | 
			
		||||
| 
						 | 
				
			
			@ -69,6 +73,7 @@ type BudResults struct {
 | 
			
		|||
	Runtime             string
 | 
			
		||||
	RuntimeFlags        []string
 | 
			
		||||
	SignaturePolicy     string
 | 
			
		||||
	SignBy              string
 | 
			
		||||
	Squash              bool
 | 
			
		||||
	Tag                 []string
 | 
			
		||||
	Target              string
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +148,7 @@ func GetLayerFlags(flags *LayerResults) pflag.FlagSet {
 | 
			
		|||
// GetBudFlags returns common bud flags
 | 
			
		||||
func GetBudFlags(flags *BudResults) pflag.FlagSet {
 | 
			
		||||
	fs := pflag.FlagSet{}
 | 
			
		||||
	fs.StringVar(&flags.Arch, "arch", runtime.GOARCH, "set the ARCH of the image to the provided value instead of the architecture of the host")
 | 
			
		||||
	fs.StringArrayVar(&flags.Annotation, "annotation", []string{}, "Set metadata for an image (default [])")
 | 
			
		||||
	fs.StringVar(&flags.Authfile, "authfile", GetDefaultAuthFile(), "path of the authentication file.")
 | 
			
		||||
	fs.StringArrayVar(&flags.BuildArg, "build-arg", []string{}, "`argument=value` to supply to the builder")
 | 
			
		||||
| 
						 | 
				
			
			@ -159,7 +165,8 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
 | 
			
		|||
	fs.BoolVar(&flags.NoCache, "no-cache", false, "Do not use existing cached images for the container build. Build from the start with a new set of cached layers.")
 | 
			
		||||
	fs.StringVar(&flags.Logfile, "logfile", "", "log to `file` instead of stdout/stderr")
 | 
			
		||||
	fs.IntVar(&flags.Loglevel, "loglevel", 0, "adjust logging level (range from -2 to 3)")
 | 
			
		||||
	fs.StringVar(&flags.Platform, "platform", "", "CLI compatibility: no action or effect")
 | 
			
		||||
	fs.StringVar(&flags.OS, "os", runtime.GOOS, "set the OS to the provided value instead of the current operating system of the host")
 | 
			
		||||
	fs.StringVar(&flags.Platform, "platform", parse.DefaultPlatform(), "set the OS/ARCH to the provided value instead of the current operating system and architecture of the host (for example `linux/arm`)")
 | 
			
		||||
	fs.BoolVar(&flags.Pull, "pull", true, "pull the image from the registry if newer or not present in store, if false, only pull the image if not present")
 | 
			
		||||
	fs.BoolVar(&flags.PullAlways, "pull-always", false, "pull the image even if the named image is present in store")
 | 
			
		||||
	fs.BoolVar(&flags.PullNever, "pull-never", false, "do not pull the image, use the image present in store if available")
 | 
			
		||||
| 
						 | 
				
			
			@ -167,16 +174,22 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
 | 
			
		|||
	fs.BoolVar(&flags.Rm, "rm", true, "Remove intermediate containers after a successful build")
 | 
			
		||||
	// "runtime" definition moved to avoid name collision in podman build.  Defined in cmd/buildah/bud.go.
 | 
			
		||||
	fs.StringSliceVar(&flags.RuntimeFlags, "runtime-flag", []string{}, "add global flags for the container runtime")
 | 
			
		||||
	fs.StringVar(&flags.SignBy, "sign-by", "", "sign the image using a GPG key with the specified `FINGERPRINT`")
 | 
			
		||||
	fs.StringVar(&flags.SignaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
 | 
			
		||||
	fs.BoolVar(&flags.Squash, "squash", false, "Squash newly built layers into a single new layer.")
 | 
			
		||||
	fs.BoolVar(&flags.Squash, "squash", false, "squash newly built layers into a single new layer")
 | 
			
		||||
	fs.StringArrayVarP(&flags.Tag, "tag", "t", []string{}, "tagged `name` to apply to the built image")
 | 
			
		||||
	fs.StringVar(&flags.Target, "target", "", "set the target build stage to build")
 | 
			
		||||
	fs.BoolVar(&flags.TLSVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry")
 | 
			
		||||
	return fs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults, namespaceResults *NameSpaceResults) pflag.FlagSet {
 | 
			
		||||
func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults, namespaceResults *NameSpaceResults) (pflag.FlagSet, error) {
 | 
			
		||||
	fs := pflag.FlagSet{}
 | 
			
		||||
	defaultContainerConfig, err := config.Default()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fs, errors.Wrapf(err, "failed to get container config")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fs.StringSliceVar(&flags.AddHost, "add-host", []string{}, "add a custom host-to-IP mapping (`host:ip`) (default [])")
 | 
			
		||||
	fs.StringVar(&flags.BlobCache, "blob-cache", "", "assume image blobs in the specified directory will be available for pushing")
 | 
			
		||||
	if err := fs.MarkHidden("blob-cache"); err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -190,10 +203,10 @@ func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults,
 | 
			
		|||
	fs.Uint64VarP(&flags.CPUShares, "cpu-shares", "c", 0, "CPU shares (relative weight)")
 | 
			
		||||
	fs.StringVar(&flags.CPUSetCPUs, "cpuset-cpus", "", "CPUs in which to allow execution (0-3, 0,1)")
 | 
			
		||||
	fs.StringVar(&flags.CPUSetMems, "cpuset-mems", "", "memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.")
 | 
			
		||||
	fs.StringArrayVar(&flags.Devices, "device", []string{}, "Additional devices to be used within containers (default [])")
 | 
			
		||||
	fs.StringSliceVar(&flags.DNSSearch, "dns-search", []string{}, "Set custom DNS search domains")
 | 
			
		||||
	fs.StringSliceVar(&flags.DNSServers, "dns", []string{}, "Set custom DNS servers or disable it completely by setting it to 'none', which prevents the automatic creation of `/etc/resolv.conf`.")
 | 
			
		||||
	fs.StringSliceVar(&flags.DNSOptions, "dns-option", []string{}, "Set custom DNS options")
 | 
			
		||||
	fs.StringArrayVar(&flags.Devices, "device", defaultContainerConfig.Containers.AdditionalDevices, "Additional devices to be used within containers (default [])")
 | 
			
		||||
	fs.StringSliceVar(&flags.DNSSearch, "dns-search", defaultContainerConfig.Containers.DNSSearches, "Set custom DNS search domains")
 | 
			
		||||
	fs.StringSliceVar(&flags.DNSServers, "dns", defaultContainerConfig.Containers.DNSServers, "Set custom DNS servers or disable it completely by setting it to 'none', which prevents the automatic creation of `/etc/resolv.conf`.")
 | 
			
		||||
	fs.StringSliceVar(&flags.DNSOptions, "dns-option", defaultContainerConfig.Containers.DNSOptions, "Set custom DNS options")
 | 
			
		||||
	fs.BoolVar(&flags.HTTPProxy, "http-proxy", true, "pass through HTTP Proxy environment variables")
 | 
			
		||||
	fs.StringVar(&flags.Isolation, "isolation", DefaultIsolation(), "`type` of process isolation to use. Use BUILDAH_ISOLATION environment variable to override.")
 | 
			
		||||
	fs.StringVarP(&flags.Memory, "memory", "m", "", "memory limit (format: <number>[<unit>], where unit = b, k, m or g)")
 | 
			
		||||
| 
						 | 
				
			
			@ -207,9 +220,9 @@ func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults,
 | 
			
		|||
		panic(fmt.Sprintf("error marking override-arch as hidden: %v", err))
 | 
			
		||||
	}
 | 
			
		||||
	fs.StringArrayVar(&flags.SecurityOpt, "security-opt", []string{}, "security options (default [])")
 | 
			
		||||
	fs.StringVar(&flags.ShmSize, "shm-size", "65536k", "size of '/dev/shm'. The format is `<number><unit>`.")
 | 
			
		||||
	fs.StringSliceVar(&flags.Ulimit, "ulimit", []string{}, "ulimit options (default [])")
 | 
			
		||||
	fs.StringArrayVarP(&flags.Volumes, "volume", "v", []string{}, "bind mount a volume into the container (default [])")
 | 
			
		||||
	fs.StringVar(&flags.ShmSize, "shm-size", defaultContainerConfig.Containers.ShmSize, "size of '/dev/shm'. The format is `<number><unit>`.")
 | 
			
		||||
	fs.StringSliceVar(&flags.Ulimit, "ulimit", defaultContainerConfig.Containers.DefaultUlimits, "ulimit options")
 | 
			
		||||
	fs.StringArrayVarP(&flags.Volumes, "volume", "v", defaultContainerConfig.Containers.AdditionalVolumes, "bind mount a volume into the container")
 | 
			
		||||
 | 
			
		||||
	// Add in the usernamespace and namespaceflags
 | 
			
		||||
	usernsFlags := GetUserNSFlags(usernsResults)
 | 
			
		||||
| 
						 | 
				
			
			@ -217,7 +230,7 @@ func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults,
 | 
			
		|||
	fs.AddFlagSet(&usernsFlags)
 | 
			
		||||
	fs.AddFlagSet(&namespaceFlags)
 | 
			
		||||
 | 
			
		||||
	return fs
 | 
			
		||||
	return fs, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UseLayers returns true if BUILDAH_LAYERS is set to "1" or "true"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@ import (
 | 
			
		|||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode"
 | 
			
		||||
| 
						 | 
				
			
			@ -51,8 +52,6 @@ func CommonBuildOptions(c *cobra.Command) (*buildah.CommonBuildOptions, error) {
 | 
			
		|||
		err         error
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	defaultLimits := getDefaultProcessLimits()
 | 
			
		||||
 | 
			
		||||
	memVal, _ := c.Flags().GetString("memory")
 | 
			
		||||
	if memVal != "" {
 | 
			
		||||
		memoryLimit, err = units.RAMInBytes(memVal)
 | 
			
		||||
| 
						 | 
				
			
			@ -79,24 +78,33 @@ func CommonBuildOptions(c *cobra.Command) (*buildah.CommonBuildOptions, error) {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	noDNS = false
 | 
			
		||||
	dnsServers, _ := c.Flags().GetStringSlice("dns")
 | 
			
		||||
	for _, server := range dnsServers {
 | 
			
		||||
		if strings.ToLower(server) == "none" {
 | 
			
		||||
			noDNS = true
 | 
			
		||||
	dnsServers := []string{}
 | 
			
		||||
	if c.Flag("dns").Changed {
 | 
			
		||||
		dnsServers, _ = c.Flags().GetStringSlice("dns")
 | 
			
		||||
		for _, server := range dnsServers {
 | 
			
		||||
			if strings.ToLower(server) == "none" {
 | 
			
		||||
				noDNS = true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if noDNS && len(dnsServers) > 1 {
 | 
			
		||||
			return nil, errors.Errorf("invalid --dns, --dns=none may not be used with any other --dns options")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if noDNS && len(dnsServers) > 1 {
 | 
			
		||||
		return nil, errors.Errorf("invalid --dns, --dns=none may not be used with any other --dns options")
 | 
			
		||||
 | 
			
		||||
	dnsSearch := []string{}
 | 
			
		||||
	if c.Flag("dns-search").Changed {
 | 
			
		||||
		dnsSearch, _ = c.Flags().GetStringSlice("dns-search")
 | 
			
		||||
		if noDNS && len(dnsSearch) > 0 {
 | 
			
		||||
			return nil, errors.Errorf("invalid --dns-search, --dns-search may not be used with --dns=none")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dnsSearch, _ := c.Flags().GetStringSlice("dns-search")
 | 
			
		||||
	if noDNS && len(dnsSearch) > 0 {
 | 
			
		||||
		return nil, errors.Errorf("invalid --dns-search, --dns-search may not be used with --dns=none")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dnsOptions, _ := c.Flags().GetStringSlice("dns-option")
 | 
			
		||||
	if noDNS && len(dnsOptions) > 0 {
 | 
			
		||||
		return nil, errors.Errorf("invalid --dns-option, --dns-option may not be used with --dns=none")
 | 
			
		||||
	dnsOptions := []string{}
 | 
			
		||||
	if c.Flag("dns-search").Changed {
 | 
			
		||||
		dnsOptions, _ = c.Flags().GetStringSlice("dns-option")
 | 
			
		||||
		if noDNS && len(dnsOptions) > 0 {
 | 
			
		||||
			return nil, errors.Errorf("invalid --dns-option, --dns-option may not be used with --dns=none")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, err := units.FromHumanSize(c.Flag("shm-size").Value.String()); err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +118,12 @@ func CommonBuildOptions(c *cobra.Command) (*buildah.CommonBuildOptions, error) {
 | 
			
		|||
	cpuQuota, _ := c.Flags().GetInt64("cpu-quota")
 | 
			
		||||
	cpuShares, _ := c.Flags().GetUint64("cpu-shares")
 | 
			
		||||
	httpProxy, _ := c.Flags().GetBool("http-proxy")
 | 
			
		||||
	ulimit, _ := c.Flags().GetStringSlice("ulimit")
 | 
			
		||||
 | 
			
		||||
	ulimit := []string{}
 | 
			
		||||
	if c.Flag("ulimit").Changed {
 | 
			
		||||
		ulimit, _ = c.Flags().GetStringSlice("ulimit")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	commonOpts := &buildah.CommonBuildOptions{
 | 
			
		||||
		AddHost:      addHost,
 | 
			
		||||
		CgroupParent: c.Flag("cgroup-parent").Value.String(),
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +139,7 @@ func CommonBuildOptions(c *cobra.Command) (*buildah.CommonBuildOptions, error) {
 | 
			
		|||
		Memory:       memoryLimit,
 | 
			
		||||
		MemorySwap:   memorySwap,
 | 
			
		||||
		ShmSize:      c.Flag("shm-size").Value.String(),
 | 
			
		||||
		Ulimit:       append(defaultLimits, ulimit...),
 | 
			
		||||
		Ulimit:       ulimit,
 | 
			
		||||
		Volumes:      volumes,
 | 
			
		||||
	}
 | 
			
		||||
	securityOpts, _ := c.Flags().GetStringArray("security-opt")
 | 
			
		||||
| 
						 | 
				
			
			@ -600,6 +613,46 @@ func getAuthFile(authfile string) string {
 | 
			
		|||
	return os.Getenv("REGISTRY_AUTH_FILE")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PlatformFromOptions parses the operating system (os) and architecture (arch)
 | 
			
		||||
// from the provided command line options.
 | 
			
		||||
func PlatformFromOptions(c *cobra.Command) (os, arch string, err error) {
 | 
			
		||||
	os = runtime.GOOS
 | 
			
		||||
	arch = runtime.GOARCH
 | 
			
		||||
 | 
			
		||||
	if selectedOS, err := c.Flags().GetString("os"); err == nil && selectedOS != runtime.GOOS {
 | 
			
		||||
		os = selectedOS
 | 
			
		||||
	}
 | 
			
		||||
	if selectedArch, err := c.Flags().GetString("arch"); err == nil && selectedArch != runtime.GOARCH {
 | 
			
		||||
		arch = selectedArch
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if pf, err := c.Flags().GetString("platform"); err == nil && pf != DefaultPlatform() {
 | 
			
		||||
		selectedOS, selectedArch, err := parsePlatform(pf)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", "", errors.Wrap(err, "unable to parse platform")
 | 
			
		||||
		}
 | 
			
		||||
		arch = selectedArch
 | 
			
		||||
		os = selectedOS
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return os, arch, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const platformSep = "/"
 | 
			
		||||
 | 
			
		||||
// DefaultPlatform returns the standard platform for the current system
 | 
			
		||||
func DefaultPlatform() string {
 | 
			
		||||
	return runtime.GOOS + platformSep + runtime.GOARCH
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parsePlatform(platform string) (os, arch string, err error) {
 | 
			
		||||
	split := strings.Split(platform, platformSep)
 | 
			
		||||
	if len(split) != 2 {
 | 
			
		||||
		return "", "", errors.Errorf("invalid platform syntax for %q (use OS/ARCH)", platform)
 | 
			
		||||
	}
 | 
			
		||||
	return split[0], split[1], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseCreds(creds string) (string, string) {
 | 
			
		||||
	if creds == "" {
 | 
			
		||||
		return "", ""
 | 
			
		||||
| 
						 | 
				
			
			@ -858,8 +911,7 @@ func defaultIsolation() (buildah.Isolation, error) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// IsolationOption parses the --isolation flag.
 | 
			
		||||
func IsolationOption(c *cobra.Command) (buildah.Isolation, error) {
 | 
			
		||||
	isolation, _ := c.Flags().GetString("isolation")
 | 
			
		||||
func IsolationOption(isolation string) (buildah.Isolation, error) {
 | 
			
		||||
	if isolation != "" {
 | 
			
		||||
		switch strings.ToLower(isolation) {
 | 
			
		||||
		case "oci":
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
package parse
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -11,29 +10,16 @@ import (
 | 
			
		|||
	"github.com/opencontainers/runc/libcontainer/configs"
 | 
			
		||||
	"github.com/opencontainers/runc/libcontainer/devices"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"golang.org/x/sys/unix"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func getDefaultProcessLimits() []string {
 | 
			
		||||
	rlim := unix.Rlimit{Cur: 1048576, Max: 1048576}
 | 
			
		||||
	defaultLimits := []string{}
 | 
			
		||||
	if err := unix.Setrlimit(unix.RLIMIT_NOFILE, &rlim); err == nil {
 | 
			
		||||
		defaultLimits = append(defaultLimits, fmt.Sprintf("nofile=%d:%d", rlim.Cur, rlim.Max))
 | 
			
		||||
	}
 | 
			
		||||
	if err := unix.Setrlimit(unix.RLIMIT_NPROC, &rlim); err == nil {
 | 
			
		||||
		defaultLimits = append(defaultLimits, fmt.Sprintf("nproc=%d:%d", rlim.Cur, rlim.Max))
 | 
			
		||||
	}
 | 
			
		||||
	return defaultLimits
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DeviceFromPath(device string) ([]configs.Device, error) {
 | 
			
		||||
	var devs []configs.Device
 | 
			
		||||
	src, dst, permissions, err := Device(device)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if unshare.IsRootless() {
 | 
			
		||||
		return nil, errors.Errorf("Renaming device %s to %s is not a supported in rootless containers", src, dst)
 | 
			
		||||
	if unshare.IsRootless() && src != dst {
 | 
			
		||||
		return nil, errors.Errorf("Renaming device %s to %s is not supported in rootless containers", src, dst)
 | 
			
		||||
	}
 | 
			
		||||
	srcInfo, err := os.Stat(src)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,6 @@ func getDefaultProcessLimits() []string {
 | 
			
		|||
	return []string{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DeviceFromPath(device string) (configs.Device, error) {
 | 
			
		||||
	return configs.Device{}, fmt.Errorf("devices not supported")
 | 
			
		||||
func DeviceFromPath(device string) ([]configs.Device, error) {
 | 
			
		||||
	return []configs.Device{}, fmt.Errorf("devices not supported")
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,9 @@ type PullOptions struct {
 | 
			
		|||
	// AllTags is a boolean value that determines if all tagged images
 | 
			
		||||
	// will be downloaded from the repository. The default is false.
 | 
			
		||||
	AllTags bool
 | 
			
		||||
	// RemoveSignatures causes any existing signatures for the image to be
 | 
			
		||||
	// discarded when pulling it.
 | 
			
		||||
	RemoveSignatures bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func localImageNameForReference(ctx context.Context, store storage.Store, srcRef types.ImageReference) (string, error) {
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +66,7 @@ func localImageNameForReference(ctx context.Context, store storage.Store, srcRef
 | 
			
		|||
		if err != nil {
 | 
			
		||||
			return "", errors.Wrapf(err, "error opening tarfile %q as a source image", file)
 | 
			
		||||
		}
 | 
			
		||||
		defer tarSource.Close()
 | 
			
		||||
		manifest, err := tarSource.LoadTarManifest()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", errors.Errorf("error retrieving manifest.json from tarfile %q: %v", file, err)
 | 
			
		||||
| 
						 | 
				
			
			@ -260,7 +264,7 @@ func pullImage(ctx context.Context, store storage.Store, srcRef types.ImageRefer
 | 
			
		|||
	}()
 | 
			
		||||
 | 
			
		||||
	logrus.Debugf("copying %q to %q", transports.ImageName(srcRef), destName)
 | 
			
		||||
	if _, err := cp.Image(ctx, policyContext, maybeCachedDestRef, srcRef, getCopyOptions(store, options.ReportWriter, sc, nil, "")); err != nil {
 | 
			
		||||
	if _, err := cp.Image(ctx, policyContext, maybeCachedDestRef, srcRef, getCopyOptions(store, options.ReportWriter, sc, nil, "", options.RemoveSignatures, "")); err != nil {
 | 
			
		||||
		logrus.Debugf("error copying src image [%q] to dest image [%q] err: %v", transports.ImageName(srcRef), destName, err)
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,8 @@ import (
 | 
			
		|||
	"github.com/containers/buildah/pkg/overlay"
 | 
			
		||||
	"github.com/containers/buildah/pkg/secrets"
 | 
			
		||||
	"github.com/containers/buildah/util"
 | 
			
		||||
	"github.com/containers/common/pkg/capabilities"
 | 
			
		||||
	"github.com/containers/common/pkg/config"
 | 
			
		||||
	"github.com/containers/common/pkg/unshare"
 | 
			
		||||
	"github.com/containers/storage/pkg/idtools"
 | 
			
		||||
	"github.com/containers/storage/pkg/ioutils"
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +91,11 @@ func (b *Builder) Run(command []string, options RunOptions) error {
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b.configureEnvironment(g, options)
 | 
			
		||||
	defaultContainerConfig, err := config.Default()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errors.Wrapf(err, "failed to get container config")
 | 
			
		||||
	}
 | 
			
		||||
	b.configureEnvironment(g, options, defaultContainerConfig.Containers.Env)
 | 
			
		||||
 | 
			
		||||
	if b.CommonBuildOpts == nil {
 | 
			
		||||
		return errors.Errorf("Invalid format on container you must recreate the container")
 | 
			
		||||
| 
						 | 
				
			
			@ -291,8 +297,12 @@ func addCommonOptsToSpec(commonOpts *CommonBuildOptions, g *generate.Generator)
 | 
			
		|||
		g.SetLinuxCgroupsPath(commonOpts.CgroupParent)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defaultContainerConfig, err := config.Default()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errors.Wrapf(err, "failed to get container config")
 | 
			
		||||
	}
 | 
			
		||||
	// Other process resource limits
 | 
			
		||||
	if err := addRlimits(commonOpts.Ulimit, g); err != nil {
 | 
			
		||||
	if err := addRlimits(commonOpts.Ulimit, g, defaultContainerConfig.Containers.DefaultUlimits); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -506,6 +516,11 @@ func (b *Builder) addNetworkConfig(rdir, hostPath string, chownOpts *idtools.IDP
 | 
			
		|||
	nameservers := resolvconf.GetNameservers(contents, types.IP)
 | 
			
		||||
	options := resolvconf.GetOptions(contents)
 | 
			
		||||
 | 
			
		||||
	defaultContainerConfig, err := config.Default()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", errors.Wrapf(err, "failed to get container config")
 | 
			
		||||
	}
 | 
			
		||||
	dnsSearch = append(defaultContainerConfig.Containers.DNSSearches, dnsSearch...)
 | 
			
		||||
	if len(dnsSearch) > 0 {
 | 
			
		||||
		search = dnsSearch
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -519,6 +534,7 @@ func (b *Builder) addNetworkConfig(rdir, hostPath string, chownOpts *idtools.IDP
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dnsServers = append(defaultContainerConfig.Containers.DNSServers, dnsServers...)
 | 
			
		||||
	if len(dnsServers) != 0 {
 | 
			
		||||
		dns, err := getDNSIP(dnsServers)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -530,6 +546,7 @@ func (b *Builder) addNetworkConfig(rdir, hostPath string, chownOpts *idtools.IDP
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dnsOptions = append(defaultContainerConfig.Containers.DNSOptions, dnsOptions...)
 | 
			
		||||
	if len(dnsOptions) != 0 {
 | 
			
		||||
		options = dnsOptions
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1599,12 +1616,13 @@ func runSetupBoundFiles(bundlePath string, bindFiles map[string]string) (mounts
 | 
			
		|||
	return mounts
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func addRlimits(ulimit []string, g *generate.Generator) error {
 | 
			
		||||
func addRlimits(ulimit []string, g *generate.Generator, defaultUlimits []string) error {
 | 
			
		||||
	var (
 | 
			
		||||
		ul  *units.Ulimit
 | 
			
		||||
		err error
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	ulimit = append(defaultUlimits, ulimit...)
 | 
			
		||||
	for _, u := range ulimit {
 | 
			
		||||
		if ul, err = units.ParseUlimit(u); err != nil {
 | 
			
		||||
			return errors.Wrapf(err, "ulimit option %q requires name=SOFT:HARD, failed to be parsed", u)
 | 
			
		||||
| 
						 | 
				
			
			@ -1799,21 +1817,27 @@ func setupCapDrop(g *generate.Generator, caps ...string) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func setupCapabilities(g *generate.Generator, firstAdds, firstDrops, secondAdds, secondDrops []string) error {
 | 
			
		||||
func setupCapabilities(g *generate.Generator, defaultCapabilities, adds, drops []string) error {
 | 
			
		||||
	g.ClearProcessCapabilities()
 | 
			
		||||
	if err := setupCapAdd(g, util.DefaultCapabilities...); err != nil {
 | 
			
		||||
	if err := setupCapAdd(g, defaultCapabilities...); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if err := setupCapAdd(g, firstAdds...); err != nil {
 | 
			
		||||
	for _, c := range adds {
 | 
			
		||||
		if strings.ToLower(c) == "all" {
 | 
			
		||||
			adds = capabilities.AllCapabilities()
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for _, c := range drops {
 | 
			
		||||
		if strings.ToLower(c) == "all" {
 | 
			
		||||
			g.ClearProcessCapabilities()
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if err := setupCapAdd(g, adds...); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if err := setupCapDrop(g, firstDrops...); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if err := setupCapAdd(g, secondAdds...); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return setupCapDrop(g, secondDrops...)
 | 
			
		||||
	return setupCapDrop(g, drops...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Search for a command that isn't given as an absolute path using the $PATH
 | 
			
		||||
| 
						 | 
				
			
			@ -1880,7 +1904,7 @@ func (b *Builder) configureUIDGID(g *generate.Generator, mountPoint string, opti
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	if err := setupCapabilities(g, b.AddCapabilities, b.DropCapabilities, options.AddCapabilities, options.DropCapabilities); err != nil {
 | 
			
		||||
	if err := setupCapabilities(g, b.Capabilities, options.AddCapabilities, options.DropCapabilities); err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	g.SetProcessUID(user.UID)
 | 
			
		||||
| 
						 | 
				
			
			@ -1899,8 +1923,9 @@ func (b *Builder) configureUIDGID(g *generate.Generator, mountPoint string, opti
 | 
			
		|||
	return homeDir, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Builder) configureEnvironment(g *generate.Generator, options RunOptions) {
 | 
			
		||||
func (b *Builder) configureEnvironment(g *generate.Generator, options RunOptions, defaultEnv []string) {
 | 
			
		||||
	g.ClearProcessEnv()
 | 
			
		||||
 | 
			
		||||
	if b.CommonBuildOpts.HTTPProxy {
 | 
			
		||||
		for _, envSpec := range []string{
 | 
			
		||||
			"http_proxy",
 | 
			
		||||
| 
						 | 
				
			
			@ -1919,7 +1944,7 @@ func (b *Builder) configureEnvironment(g *generate.Generator, options RunOptions
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, envSpec := range append(b.Env(), options.Env...) {
 | 
			
		||||
	for _, envSpec := range append(append(defaultEnv, b.Env()...), options.Env...) {
 | 
			
		||||
		env := strings.SplitN(envSpec, "=", 2)
 | 
			
		||||
		if len(env) > 1 {
 | 
			
		||||
			g.AddProcessEnv(env[0], env[1])
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,9 +7,9 @@ import (
 | 
			
		|||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"github.com/containers/common/pkg/cgroups"
 | 
			
		||||
	"github.com/containers/image/v5/docker/reference"
 | 
			
		||||
	"github.com/containers/image/v5/pkg/sysregistriesv2"
 | 
			
		||||
	"github.com/containers/image/v5/signature"
 | 
			
		||||
| 
						 | 
				
			
			@ -252,7 +252,7 @@ func Runtime() string {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Need to switch default until runc supports cgroups v2
 | 
			
		||||
	if unified, _ := cgroups.IsCgroup2UnifiedMode(); unified {
 | 
			
		||||
	if unified, _ := IsCgroup2UnifiedMode(); unified {
 | 
			
		||||
		return "crun"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -395,3 +395,9 @@ func TruncateString(str string, to int) string {
 | 
			
		|||
	}
 | 
			
		||||
	return newStr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	isUnifiedOnce sync.Once
 | 
			
		||||
	isUnified     bool
 | 
			
		||||
	isUnifiedErr  error
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
package util
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/unix"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
 | 
			
		||||
func IsCgroup2UnifiedMode() (bool, error) {
 | 
			
		||||
	isUnifiedOnce.Do(func() {
 | 
			
		||||
		var st syscall.Statfs_t
 | 
			
		||||
		if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil {
 | 
			
		||||
			isUnified, isUnifiedErr = false, err
 | 
			
		||||
		} else {
 | 
			
		||||
			isUnified, isUnifiedErr = st.Type == unix.CGROUP2_SUPER_MAGIC, nil
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	return isUnified, isUnifiedErr
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
// +build !linux
 | 
			
		||||
 | 
			
		||||
package util
 | 
			
		||||
 | 
			
		||||
// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
 | 
			
		||||
func IsCgroup2UnifiedMode() (bool, error) {
 | 
			
		||||
	return false, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										137
									
								
								vendor/github.com/containers/common/pkg/capabilities/capabilities.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										137
									
								
								vendor/github.com/containers/common/pkg/capabilities/capabilities.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							| 
						 | 
				
			
			@ -0,0 +1,137 @@
 | 
			
		|||
package capabilities
 | 
			
		||||
 | 
			
		||||
// Copyright 2013-2018 Docker, Inc.
 | 
			
		||||
 | 
			
		||||
// NOTE: this package has been copied from github.com/docker/docker but been
 | 
			
		||||
//       changed significantly to fit the needs of libpod.
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"github.com/syndtr/gocapability/capability"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// Used internally and populated during init().
 | 
			
		||||
	capabilityList []string
 | 
			
		||||
 | 
			
		||||
	// ErrUnknownCapability is thrown when an unknown capability is processed.
 | 
			
		||||
	ErrUnknownCapability = errors.New("unknown capability")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// All is a special value used to add/drop all known capababilities.
 | 
			
		||||
// Useful on the CLI for `--cap-add=all` etc.
 | 
			
		||||
const All = "ALL"
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	last := capability.CAP_LAST_CAP
 | 
			
		||||
	// hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
 | 
			
		||||
	if last == capability.Cap(63) {
 | 
			
		||||
		last = capability.CAP_BLOCK_SUSPEND
 | 
			
		||||
	}
 | 
			
		||||
	for _, cap := range capability.List() {
 | 
			
		||||
		if cap > last {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		capabilityList = append(capabilityList, "CAP_"+strings.ToUpper(cap.String()))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stringInSlice determines if a string is in a string slice, returns bool
 | 
			
		||||
func stringInSlice(s string, sl []string) bool {
 | 
			
		||||
	for _, i := range sl {
 | 
			
		||||
		if i == s {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
// AllCapabilities returns all known capabilities.
 | 
			
		||||
func AllCapabilities() []string {
 | 
			
		||||
	return capabilityList
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// normalizeCapabilities normalizes caps by adding a "CAP_" prefix (if not yet
 | 
			
		||||
// present).
 | 
			
		||||
func normalizeCapabilities(caps []string) ([]string, error) {
 | 
			
		||||
	normalized := make([]string, len(caps))
 | 
			
		||||
	for i, c := range caps {
 | 
			
		||||
		c = strings.ToUpper(c)
 | 
			
		||||
		if c == All {
 | 
			
		||||
			normalized = append(normalized, c)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if !strings.HasPrefix(c, "CAP_") {
 | 
			
		||||
			c = "CAP_" + c
 | 
			
		||||
		}
 | 
			
		||||
		if !stringInSlice(c, capabilityList) {
 | 
			
		||||
			return nil, errors.Wrapf(ErrUnknownCapability, "%q", c)
 | 
			
		||||
		}
 | 
			
		||||
		normalized[i] = c
 | 
			
		||||
	}
 | 
			
		||||
	return normalized, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ValidateCapabilities validates if caps only contains valid capabilities.
 | 
			
		||||
func ValidateCapabilities(caps []string) error {
 | 
			
		||||
	for _, c := range caps {
 | 
			
		||||
		if !stringInSlice(c, capabilityList) {
 | 
			
		||||
			return errors.Wrapf(ErrUnknownCapability, "%q", c)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MergeCapabilities computes a set of capabilities by adding capapbitilities
 | 
			
		||||
// to or dropping them from base.
 | 
			
		||||
//
 | 
			
		||||
// Note that "ALL" will cause all known capabilities to be added/dropped but
 | 
			
		||||
// the ones specified to be dropped/added.
 | 
			
		||||
func MergeCapabilities(base, adds, drops []string) ([]string, error) {
 | 
			
		||||
	if len(adds) == 0 && len(drops) == 0 {
 | 
			
		||||
		// Nothing to tweak; we're done
 | 
			
		||||
		return base, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	capDrop, err := normalizeCapabilities(drops)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	capAdd, err := normalizeCapabilities(adds)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Make sure that capDrop and capAdd are distinct sets.
 | 
			
		||||
	for _, drop := range capDrop {
 | 
			
		||||
		if stringInSlice(drop, capAdd) {
 | 
			
		||||
			return nil, errors.Errorf("capability %q cannot be dropped and added", drop)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var caps []string
 | 
			
		||||
 | 
			
		||||
	switch {
 | 
			
		||||
	case stringInSlice(All, capAdd):
 | 
			
		||||
		// Add all capabilities except ones on capDrop
 | 
			
		||||
		for _, c := range capabilityList {
 | 
			
		||||
			if !stringInSlice(c, capDrop) {
 | 
			
		||||
				caps = append(caps, c)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	case stringInSlice(All, capDrop):
 | 
			
		||||
		// "Drop" all capabilities; use what's in capAdd instead
 | 
			
		||||
		caps = capAdd
 | 
			
		||||
	default:
 | 
			
		||||
		// First drop some capabilities
 | 
			
		||||
		for _, c := range base {
 | 
			
		||||
			if !stringInSlice(c, capDrop) {
 | 
			
		||||
				caps = append(caps, c)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// Then add the list of capabilities from capAdd
 | 
			
		||||
		caps = append(caps, capAdd...)
 | 
			
		||||
	}
 | 
			
		||||
	return caps, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,149 +0,0 @@
 | 
			
		|||
package cgroups
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	spec "github.com/opencontainers/runtime-spec/specs-go"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type blkioHandler struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getBlkioHandler() *blkioHandler {
 | 
			
		||||
	return &blkioHandler{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Apply set the specified constraints
 | 
			
		||||
func (c *blkioHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error {
 | 
			
		||||
	if res.BlockIO == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Errorf("blkio apply function not implemented yet")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create the cgroup
 | 
			
		||||
func (c *blkioHandler) Create(ctr *CgroupControl) (bool, error) {
 | 
			
		||||
	if ctr.cgroup2 {
 | 
			
		||||
		return false, nil
 | 
			
		||||
	}
 | 
			
		||||
	return ctr.createCgroupDirectory(Blkio)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Destroy the cgroup
 | 
			
		||||
func (c *blkioHandler) Destroy(ctr *CgroupControl) error {
 | 
			
		||||
	return rmDirRecursively(ctr.getCgroupv1Path(Blkio))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stat fills a metrics structure with usage stats for the controller
 | 
			
		||||
func (c *blkioHandler) Stat(ctr *CgroupControl, m *Metrics) error {
 | 
			
		||||
	var ioServiceBytesRecursive []BlkIOEntry
 | 
			
		||||
 | 
			
		||||
	if ctr.cgroup2 {
 | 
			
		||||
		// more details on the io.stat file format:X https://facebookmicrosites.github.io/cgroup2/docs/io-controller.html
 | 
			
		||||
		values, err := readCgroup2MapFile(ctr, "io.stat")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		for k, v := range values {
 | 
			
		||||
			d := strings.Split(k, ":")
 | 
			
		||||
			if len(d) != 2 {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			minor, err := strconv.ParseUint(d[0], 10, 0)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			major, err := strconv.ParseUint(d[1], 10, 0)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for _, item := range v {
 | 
			
		||||
				d := strings.Split(item, "=")
 | 
			
		||||
				if len(d) != 2 {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				op := d[0]
 | 
			
		||||
 | 
			
		||||
				// Accommodate the cgroup v1 naming
 | 
			
		||||
				switch op {
 | 
			
		||||
				case "rbytes":
 | 
			
		||||
					op = "read"
 | 
			
		||||
				case "wbytes":
 | 
			
		||||
					op = "write"
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				value, err := strconv.ParseUint(d[1], 10, 0)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				entry := BlkIOEntry{
 | 
			
		||||
					Op:    op,
 | 
			
		||||
					Major: major,
 | 
			
		||||
					Minor: minor,
 | 
			
		||||
					Value: value,
 | 
			
		||||
				}
 | 
			
		||||
				ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		BlkioRoot := ctr.getCgroupv1Path(Blkio)
 | 
			
		||||
 | 
			
		||||
		p := filepath.Join(BlkioRoot, "blkio.throttle.io_service_bytes_recursive")
 | 
			
		||||
		f, err := os.Open(p)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if os.IsNotExist(err) {
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
			return errors.Wrapf(err, "open %s", p)
 | 
			
		||||
		}
 | 
			
		||||
		defer f.Close()
 | 
			
		||||
 | 
			
		||||
		scanner := bufio.NewScanner(f)
 | 
			
		||||
		for scanner.Scan() {
 | 
			
		||||
			line := scanner.Text()
 | 
			
		||||
			parts := strings.Fields(line)
 | 
			
		||||
			if len(parts) < 3 {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			d := strings.Split(parts[0], ":")
 | 
			
		||||
			if len(d) != 2 {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			minor, err := strconv.ParseUint(d[0], 10, 0)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			major, err := strconv.ParseUint(d[1], 10, 0)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			op := parts[1]
 | 
			
		||||
 | 
			
		||||
			value, err := strconv.ParseUint(parts[2], 10, 0)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			entry := BlkIOEntry{
 | 
			
		||||
				Op:    op,
 | 
			
		||||
				Major: major,
 | 
			
		||||
				Minor: minor,
 | 
			
		||||
				Value: value,
 | 
			
		||||
			}
 | 
			
		||||
			ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry)
 | 
			
		||||
		}
 | 
			
		||||
		if err := scanner.Err(); err != nil {
 | 
			
		||||
			return errors.Wrapf(err, "parse %s", p)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	m.Blkio = BlkioMetrics{IoServiceBytesRecursive: ioServiceBytesRecursive}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,564 +0,0 @@
 | 
			
		|||
package cgroups
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"math"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/containers/common/pkg/unshare"
 | 
			
		||||
	systemdDbus "github.com/coreos/go-systemd/dbus"
 | 
			
		||||
	"github.com/godbus/dbus"
 | 
			
		||||
	spec "github.com/opencontainers/runtime-spec/specs-go"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// ErrCgroupDeleted means the cgroup was deleted
 | 
			
		||||
	ErrCgroupDeleted = errors.New("cgroup deleted")
 | 
			
		||||
	// ErrCgroupV1Rootless means the cgroup v1 were attempted to be used in rootless environmen
 | 
			
		||||
	ErrCgroupV1Rootless = errors.New("no support for CGroups V1 in rootless environments")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CgroupControl controls a cgroup hierarchy
 | 
			
		||||
type CgroupControl struct {
 | 
			
		||||
	cgroup2 bool
 | 
			
		||||
	path    string
 | 
			
		||||
	systemd bool
 | 
			
		||||
	// List of additional cgroup subsystems joined that
 | 
			
		||||
	// do not have a custom handler.
 | 
			
		||||
	additionalControllers []controller
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CPUUsage keeps stats for the CPU usage (unit: nanoseconds)
 | 
			
		||||
type CPUUsage struct {
 | 
			
		||||
	Kernel uint64
 | 
			
		||||
	Total  uint64
 | 
			
		||||
	PerCPU []uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MemoryUsage keeps stats for the memory usage
 | 
			
		||||
type MemoryUsage struct {
 | 
			
		||||
	Usage uint64
 | 
			
		||||
	Limit uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CPUMetrics keeps stats for the CPU usage
 | 
			
		||||
type CPUMetrics struct {
 | 
			
		||||
	Usage CPUUsage
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BlkIOEntry describes an entry in the blkio stats
 | 
			
		||||
type BlkIOEntry struct {
 | 
			
		||||
	Op    string
 | 
			
		||||
	Major uint64
 | 
			
		||||
	Minor uint64
 | 
			
		||||
	Value uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BlkioMetrics keeps usage stats for the blkio cgroup controller
 | 
			
		||||
type BlkioMetrics struct {
 | 
			
		||||
	IoServiceBytesRecursive []BlkIOEntry
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MemoryMetrics keeps usage stats for the memory cgroup controller
 | 
			
		||||
type MemoryMetrics struct {
 | 
			
		||||
	Usage MemoryUsage
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PidsMetrics keeps usage stats for the pids cgroup controller
 | 
			
		||||
type PidsMetrics struct {
 | 
			
		||||
	Current uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Metrics keeps usage stats for the cgroup controllers
 | 
			
		||||
type Metrics struct {
 | 
			
		||||
	CPU    CPUMetrics
 | 
			
		||||
	Blkio  BlkioMetrics
 | 
			
		||||
	Memory MemoryMetrics
 | 
			
		||||
	Pids   PidsMetrics
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type controller struct {
 | 
			
		||||
	name    string
 | 
			
		||||
	symlink bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type controllerHandler interface {
 | 
			
		||||
	Create(*CgroupControl) (bool, error)
 | 
			
		||||
	Apply(*CgroupControl, *spec.LinuxResources) error
 | 
			
		||||
	Destroy(*CgroupControl) error
 | 
			
		||||
	Stat(*CgroupControl, *Metrics) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	cgroupRoot         = "/sys/fs/cgroup"
 | 
			
		||||
	_cgroup2SuperMagic = 0x63677270
 | 
			
		||||
	// CPU is the cpu controller
 | 
			
		||||
	CPU = "cpu"
 | 
			
		||||
	// CPUAcct is the cpuacct controller
 | 
			
		||||
	CPUAcct = "cpuacct"
 | 
			
		||||
	// CPUset is the cpuset controller
 | 
			
		||||
	CPUset = "cpuset"
 | 
			
		||||
	// Memory is the memory controller
 | 
			
		||||
	Memory = "memory"
 | 
			
		||||
	// Pids is the pids controller
 | 
			
		||||
	Pids = "pids"
 | 
			
		||||
	// Blkio is the blkio controller
 | 
			
		||||
	Blkio = "blkio"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var handlers map[string]controllerHandler
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	handlers = make(map[string]controllerHandler)
 | 
			
		||||
	handlers[CPU] = getCPUHandler()
 | 
			
		||||
	handlers[CPUset] = getCpusetHandler()
 | 
			
		||||
	handlers[Memory] = getMemoryHandler()
 | 
			
		||||
	handlers[Pids] = getPidsHandler()
 | 
			
		||||
	handlers[Blkio] = getBlkioHandler()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getAvailableControllers get the available controllers
 | 
			
		||||
func getAvailableControllers(exclude map[string]controllerHandler, cgroup2 bool) ([]controller, error) {
 | 
			
		||||
	if cgroup2 {
 | 
			
		||||
		return nil, fmt.Errorf("getAvailableControllers not implemented yet for cgroup v2")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	infos, err := ioutil.ReadDir(cgroupRoot)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(err, "read directory %s", cgroupRoot)
 | 
			
		||||
	}
 | 
			
		||||
	var controllers []controller
 | 
			
		||||
	for _, i := range infos {
 | 
			
		||||
		name := i.Name()
 | 
			
		||||
		if _, found := exclude[name]; found {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		c := controller{
 | 
			
		||||
			name:    name,
 | 
			
		||||
			symlink: !i.IsDir(),
 | 
			
		||||
		}
 | 
			
		||||
		controllers = append(controllers, c)
 | 
			
		||||
	}
 | 
			
		||||
	return controllers, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getCgroupv1Path is a helper function to get the cgroup v1 path
 | 
			
		||||
func (c *CgroupControl) getCgroupv1Path(name string) string {
 | 
			
		||||
	return filepath.Join(cgroupRoot, name, c.path)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// createCgroupv2Path creates the cgroupv2 path and enables all the available controllers
 | 
			
		||||
func createCgroupv2Path(path string) (Err error) {
 | 
			
		||||
	content, err := ioutil.ReadFile("/sys/fs/cgroup/cgroup.controllers")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errors.Wrapf(err, "read /sys/fs/cgroup/cgroup.controllers")
 | 
			
		||||
	}
 | 
			
		||||
	if !strings.HasPrefix(path, "/sys/fs/cgroup/") {
 | 
			
		||||
		return fmt.Errorf("invalid cgroup path %s", path)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	res := ""
 | 
			
		||||
	for i, c := range strings.Split(strings.TrimSpace(string(content)), " ") {
 | 
			
		||||
		if i == 0 {
 | 
			
		||||
			res = fmt.Sprintf("+%s", c)
 | 
			
		||||
		} else {
 | 
			
		||||
			res = res + fmt.Sprintf(" +%s", c)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	resByte := []byte(res)
 | 
			
		||||
 | 
			
		||||
	current := "/sys/fs"
 | 
			
		||||
	elements := strings.Split(path, "/")
 | 
			
		||||
	for i, e := range elements[3:] {
 | 
			
		||||
		current = filepath.Join(current, e)
 | 
			
		||||
		if i > 0 {
 | 
			
		||||
			if err := os.Mkdir(current, 0755); err != nil {
 | 
			
		||||
				if !os.IsExist(err) {
 | 
			
		||||
					return errors.Wrapf(err, "mkdir %s", path)
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				// If the directory was created, be sure it is not left around on errors.
 | 
			
		||||
				defer func() {
 | 
			
		||||
					if Err != nil {
 | 
			
		||||
						os.Remove(current)
 | 
			
		||||
					}
 | 
			
		||||
				}()
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// We enable the controllers for all the path components except the last one.  It is not allowed to add
 | 
			
		||||
		// PIDs if there are already enabled controllers.
 | 
			
		||||
		if i < len(elements[3:])-1 {
 | 
			
		||||
			if err := ioutil.WriteFile(filepath.Join(current, "cgroup.subtree_control"), resByte, 0755); err != nil {
 | 
			
		||||
				return errors.Wrapf(err, "write %s", filepath.Join(current, "cgroup.subtree_control"))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// initialize initializes the specified hierarchy
 | 
			
		||||
func (c *CgroupControl) initialize() (err error) {
 | 
			
		||||
	createdSoFar := map[string]controllerHandler{}
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			for name, ctr := range createdSoFar {
 | 
			
		||||
				if err := ctr.Destroy(c); err != nil {
 | 
			
		||||
					logrus.Warningf("error cleaning up controller %s for %s", name, c.path)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	if c.cgroup2 {
 | 
			
		||||
		if err := createCgroupv2Path(filepath.Join(cgroupRoot, c.path)); err != nil {
 | 
			
		||||
			return errors.Wrapf(err, "error creating cgroup path %s", c.path)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for name, handler := range handlers {
 | 
			
		||||
		created, err := handler.Create(c)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if created {
 | 
			
		||||
			createdSoFar[name] = handler
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !c.cgroup2 {
 | 
			
		||||
		// We won't need to do this for cgroup v2
 | 
			
		||||
		for _, ctr := range c.additionalControllers {
 | 
			
		||||
			if ctr.symlink {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			path := c.getCgroupv1Path(ctr.name)
 | 
			
		||||
			if err := os.MkdirAll(path, 0755); err != nil {
 | 
			
		||||
				return errors.Wrapf(err, "error creating cgroup path %s for %s", path, ctr.name)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *CgroupControl) createCgroupDirectory(controller string) (bool, error) {
 | 
			
		||||
	cPath := c.getCgroupv1Path(controller)
 | 
			
		||||
	_, err := os.Stat(cPath)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		return false, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !os.IsNotExist(err) {
 | 
			
		||||
		return false, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := os.MkdirAll(cPath, 0755); err != nil {
 | 
			
		||||
		return false, errors.Wrapf(err, "error creating cgroup for %s", controller)
 | 
			
		||||
	}
 | 
			
		||||
	return true, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func readFileAsUint64(path string) (uint64, error) {
 | 
			
		||||
	data, err := ioutil.ReadFile(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, errors.Wrapf(err, "open %s", path)
 | 
			
		||||
	}
 | 
			
		||||
	v := cleanString(string(data))
 | 
			
		||||
	if v == "max" {
 | 
			
		||||
		return math.MaxUint64, nil
 | 
			
		||||
	}
 | 
			
		||||
	ret, err := strconv.ParseUint(v, 10, 0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return ret, errors.Wrapf(err, "parse %s from %s", v, path)
 | 
			
		||||
	}
 | 
			
		||||
	return ret, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New creates a new cgroup control
 | 
			
		||||
func New(path string, resources *spec.LinuxResources) (*CgroupControl, error) {
 | 
			
		||||
	cgroup2, err := IsCgroup2UnifiedMode()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	control := &CgroupControl{
 | 
			
		||||
		cgroup2: cgroup2,
 | 
			
		||||
		path:    path,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !cgroup2 {
 | 
			
		||||
		controllers, err := getAvailableControllers(handlers, false)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		control.additionalControllers = controllers
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := control.initialize(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return control, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSystemd creates a new cgroup control
 | 
			
		||||
func NewSystemd(path string) (*CgroupControl, error) {
 | 
			
		||||
	cgroup2, err := IsCgroup2UnifiedMode()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	control := &CgroupControl{
 | 
			
		||||
		cgroup2: cgroup2,
 | 
			
		||||
		path:    path,
 | 
			
		||||
		systemd: true,
 | 
			
		||||
	}
 | 
			
		||||
	return control, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Load loads an existing cgroup control
 | 
			
		||||
func Load(path string) (*CgroupControl, error) {
 | 
			
		||||
	cgroup2, err := IsCgroup2UnifiedMode()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	control := &CgroupControl{
 | 
			
		||||
		cgroup2: cgroup2,
 | 
			
		||||
		path:    path,
 | 
			
		||||
		systemd: false,
 | 
			
		||||
	}
 | 
			
		||||
	if !cgroup2 {
 | 
			
		||||
		controllers, err := getAvailableControllers(handlers, false)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		control.additionalControllers = controllers
 | 
			
		||||
	}
 | 
			
		||||
	if !cgroup2 {
 | 
			
		||||
		for name := range handlers {
 | 
			
		||||
			p := control.getCgroupv1Path(name)
 | 
			
		||||
			if _, err := os.Stat(p); err != nil {
 | 
			
		||||
				if os.IsNotExist(err) {
 | 
			
		||||
					if unshare.IsRootless() {
 | 
			
		||||
						return nil, ErrCgroupV1Rootless
 | 
			
		||||
					}
 | 
			
		||||
					// compatible with the error code
 | 
			
		||||
					// used by containerd/cgroups
 | 
			
		||||
					return nil, ErrCgroupDeleted
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return control, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CreateSystemdUnit creates the systemd cgroup
 | 
			
		||||
func (c *CgroupControl) CreateSystemdUnit(path string) error {
 | 
			
		||||
	if !c.systemd {
 | 
			
		||||
		return fmt.Errorf("the cgroup controller is not using systemd")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	conn, err := systemdDbus.New()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer conn.Close()
 | 
			
		||||
 | 
			
		||||
	return systemdCreate(path, conn)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetUserConnection returns an user connection to D-BUS
 | 
			
		||||
func GetUserConnection(uid int) (*systemdDbus.Conn, error) {
 | 
			
		||||
	return systemdDbus.NewConnection(func() (*dbus.Conn, error) {
 | 
			
		||||
		return dbusAuthConnection(uid, dbus.SessionBusPrivate)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CreateSystemdUserUnit creates the systemd cgroup for the specified user
 | 
			
		||||
func (c *CgroupControl) CreateSystemdUserUnit(path string, uid int) error {
 | 
			
		||||
	if !c.systemd {
 | 
			
		||||
		return fmt.Errorf("the cgroup controller is not using systemd")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	conn, err := GetUserConnection(uid)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer conn.Close()
 | 
			
		||||
 | 
			
		||||
	return systemdCreate(path, conn)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dbusAuthConnection(uid int, createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) {
 | 
			
		||||
	conn, err := createBus()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(uid))}
 | 
			
		||||
 | 
			
		||||
	err = conn.Auth(methods)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		conn.Close()
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := conn.Hello(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return conn, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Delete cleans a cgroup
 | 
			
		||||
func (c *CgroupControl) Delete() error {
 | 
			
		||||
	return c.DeleteByPath(c.path)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// rmDirRecursively delete recursively a cgroup directory.
 | 
			
		||||
// It differs from os.RemoveAll as it doesn't attempt to unlink files.
 | 
			
		||||
// On cgroupfs we are allowed only to rmdir empty directories.
 | 
			
		||||
func rmDirRecursively(path string) error {
 | 
			
		||||
	if err := os.Remove(path); err == nil || os.IsNotExist(err) {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	entries, err := ioutil.ReadDir(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errors.Wrapf(err, "read %s", path)
 | 
			
		||||
	}
 | 
			
		||||
	for _, i := range entries {
 | 
			
		||||
		if i.IsDir() {
 | 
			
		||||
			if err := rmDirRecursively(filepath.Join(path, i.Name())); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if err := os.Remove(path); err != nil {
 | 
			
		||||
		if !os.IsNotExist(err) {
 | 
			
		||||
			return errors.Wrapf(err, "remove %s", path)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteByPathConn deletes the specified cgroup path using the specified
 | 
			
		||||
// dbus connection if needed.
 | 
			
		||||
func (c *CgroupControl) DeleteByPathConn(path string, conn *systemdDbus.Conn) error {
 | 
			
		||||
	if c.systemd {
 | 
			
		||||
		return systemdDestroyConn(path, conn)
 | 
			
		||||
	}
 | 
			
		||||
	if c.cgroup2 {
 | 
			
		||||
		return rmDirRecursively(filepath.Join(cgroupRoot, c.path))
 | 
			
		||||
	}
 | 
			
		||||
	var lastError error
 | 
			
		||||
	for _, h := range handlers {
 | 
			
		||||
		if err := h.Destroy(c); err != nil {
 | 
			
		||||
			lastError = err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, ctr := range c.additionalControllers {
 | 
			
		||||
		if ctr.symlink {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		p := c.getCgroupv1Path(ctr.name)
 | 
			
		||||
		if err := rmDirRecursively(p); err != nil {
 | 
			
		||||
			lastError = errors.Wrapf(err, "remove %s", p)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return lastError
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteByPath deletes the specified cgroup path
 | 
			
		||||
func (c *CgroupControl) DeleteByPath(path string) error {
 | 
			
		||||
	if c.systemd {
 | 
			
		||||
		conn, err := systemdDbus.New()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		defer conn.Close()
 | 
			
		||||
		return c.DeleteByPathConn(path, conn)
 | 
			
		||||
	}
 | 
			
		||||
	return c.DeleteByPathConn(path, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update updates the cgroups
 | 
			
		||||
func (c *CgroupControl) Update(resources *spec.LinuxResources) error {
 | 
			
		||||
	for _, h := range handlers {
 | 
			
		||||
		if err := h.Apply(c, resources); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddPid moves the specified pid to the cgroup
 | 
			
		||||
func (c *CgroupControl) AddPid(pid int) error {
 | 
			
		||||
	pidString := []byte(fmt.Sprintf("%d\n", pid))
 | 
			
		||||
 | 
			
		||||
	if c.cgroup2 {
 | 
			
		||||
		p := filepath.Join(cgroupRoot, c.path, "cgroup.procs")
 | 
			
		||||
		if err := ioutil.WriteFile(p, pidString, 0644); err != nil {
 | 
			
		||||
			return errors.Wrapf(err, "write %s", p)
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var names []string
 | 
			
		||||
	for n := range handlers {
 | 
			
		||||
		names = append(names, n)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, c := range c.additionalControllers {
 | 
			
		||||
		if !c.symlink {
 | 
			
		||||
			names = append(names, c.name)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, n := range names {
 | 
			
		||||
		p := filepath.Join(c.getCgroupv1Path(n), "tasks")
 | 
			
		||||
		if err := ioutil.WriteFile(p, pidString, 0644); err != nil {
 | 
			
		||||
			return errors.Wrapf(err, "write %s", p)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stat returns usage statistics for the cgroup
 | 
			
		||||
func (c *CgroupControl) Stat() (*Metrics, error) {
 | 
			
		||||
	m := Metrics{}
 | 
			
		||||
	for _, h := range handlers {
 | 
			
		||||
		if err := h.Stat(c, &m); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return &m, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func readCgroup2MapFile(ctr *CgroupControl, name string) (map[string][]string, error) {
 | 
			
		||||
	ret := map[string][]string{}
 | 
			
		||||
	p := filepath.Join(cgroupRoot, ctr.path, name)
 | 
			
		||||
	f, err := os.Open(p)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if os.IsNotExist(err) {
 | 
			
		||||
			return ret, nil
 | 
			
		||||
		}
 | 
			
		||||
		return nil, errors.Wrapf(err, "open file %s", p)
 | 
			
		||||
	}
 | 
			
		||||
	defer f.Close()
 | 
			
		||||
	scanner := bufio.NewScanner(f)
 | 
			
		||||
	for scanner.Scan() {
 | 
			
		||||
		line := scanner.Text()
 | 
			
		||||
		parts := strings.Fields(line)
 | 
			
		||||
		if len(parts) < 2 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		ret[parts[0]] = parts[1:]
 | 
			
		||||
	}
 | 
			
		||||
	if err := scanner.Err(); err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(err, "parsing file %s", p)
 | 
			
		||||
	}
 | 
			
		||||
	return ret, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,89 +0,0 @@
 | 
			
		|||
// +build linux
 | 
			
		||||
 | 
			
		||||
package cgroups
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	isUnifiedOnce sync.Once
 | 
			
		||||
	isUnified     bool
 | 
			
		||||
	isUnifiedErr  error
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
 | 
			
		||||
func IsCgroup2UnifiedMode() (bool, error) {
 | 
			
		||||
	isUnifiedOnce.Do(func() {
 | 
			
		||||
		var st syscall.Statfs_t
 | 
			
		||||
		if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil {
 | 
			
		||||
			isUnified, isUnifiedErr = false, err
 | 
			
		||||
		} else {
 | 
			
		||||
			isUnified, isUnifiedErr = st.Type == _cgroup2SuperMagic, nil
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	return isUnified, isUnifiedErr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UserOwnsCurrentSystemdCgroup checks whether the current EUID owns the
 | 
			
		||||
// current cgroup.
 | 
			
		||||
func UserOwnsCurrentSystemdCgroup() (bool, error) {
 | 
			
		||||
	uid := os.Geteuid()
 | 
			
		||||
 | 
			
		||||
	cgroup2, err := IsCgroup2UnifiedMode()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	f, err := os.Open("/proc/self/cgroup")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false, errors.Wrapf(err, "open file /proc/self/cgroup")
 | 
			
		||||
	}
 | 
			
		||||
	defer f.Close()
 | 
			
		||||
 | 
			
		||||
	scanner := bufio.NewScanner(f)
 | 
			
		||||
	for scanner.Scan() {
 | 
			
		||||
		line := scanner.Text()
 | 
			
		||||
		parts := strings.SplitN(line, ":", 3)
 | 
			
		||||
 | 
			
		||||
		if len(parts) < 3 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var cgroupPath string
 | 
			
		||||
 | 
			
		||||
		if cgroup2 {
 | 
			
		||||
			cgroupPath = filepath.Join(cgroupRoot, parts[2])
 | 
			
		||||
		} else {
 | 
			
		||||
			if parts[1] != "name=systemd" {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			cgroupPath = filepath.Join(cgroupRoot, "systemd", parts[2])
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		st, err := os.Stat(cgroupPath)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return false, err
 | 
			
		||||
		}
 | 
			
		||||
		s := st.Sys()
 | 
			
		||||
		if s == nil {
 | 
			
		||||
			return false, fmt.Errorf("error stat cgroup path %s", cgroupPath)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if int(s.(*syscall.Stat_t).Uid) != uid {
 | 
			
		||||
			return false, nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if err := scanner.Err(); err != nil {
 | 
			
		||||
		return false, errors.Wrapf(err, "parsing file /proc/self/cgroup")
 | 
			
		||||
	}
 | 
			
		||||
	return true, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +0,0 @@
 | 
			
		|||
// +build !linux
 | 
			
		||||
 | 
			
		||||
package cgroups
 | 
			
		||||
 | 
			
		||||
// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
 | 
			
		||||
func IsCgroup2UnifiedMode() (bool, error) {
 | 
			
		||||
	return false, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UserOwnsCurrentSystemdCgroup checks whether the current EUID owns the
 | 
			
		||||
// current cgroup.
 | 
			
		||||
func UserOwnsCurrentSystemdCgroup() (bool, error) {
 | 
			
		||||
	return false, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,123 +0,0 @@
 | 
			
		|||
package cgroups
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	spec "github.com/opencontainers/runtime-spec/specs-go"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type cpuHandler struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getCPUHandler() *cpuHandler {
 | 
			
		||||
	return &cpuHandler{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cleanString(s string) string {
 | 
			
		||||
	return strings.Trim(s, "\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func readAcct(ctr *CgroupControl, name string) (uint64, error) {
 | 
			
		||||
	p := filepath.Join(ctr.getCgroupv1Path(CPUAcct), name)
 | 
			
		||||
	return readFileAsUint64(p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func readAcctList(ctr *CgroupControl, name string) ([]uint64, error) {
 | 
			
		||||
	var r []uint64
 | 
			
		||||
 | 
			
		||||
	p := filepath.Join(ctr.getCgroupv1Path(CPUAcct), name)
 | 
			
		||||
	data, err := ioutil.ReadFile(p)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(err, "reading %s", p)
 | 
			
		||||
	}
 | 
			
		||||
	for _, s := range strings.Split(string(data), " ") {
 | 
			
		||||
		s = cleanString(s)
 | 
			
		||||
		if s == "" {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		v, err := strconv.ParseUint(s, 10, 0)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, errors.Wrapf(err, "parsing %s", s)
 | 
			
		||||
		}
 | 
			
		||||
		r = append(r, v)
 | 
			
		||||
	}
 | 
			
		||||
	return r, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Apply set the specified constraints
 | 
			
		||||
func (c *cpuHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error {
 | 
			
		||||
	if res.CPU == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Errorf("cpu apply not implemented yet")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create the cgroup
 | 
			
		||||
func (c *cpuHandler) Create(ctr *CgroupControl) (bool, error) {
 | 
			
		||||
	if ctr.cgroup2 {
 | 
			
		||||
		return false, nil
 | 
			
		||||
	}
 | 
			
		||||
	return ctr.createCgroupDirectory(CPU)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Destroy the cgroup
 | 
			
		||||
func (c *cpuHandler) Destroy(ctr *CgroupControl) error {
 | 
			
		||||
	return rmDirRecursively(ctr.getCgroupv1Path(CPU))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stat fills a metrics structure with usage stats for the controller
 | 
			
		||||
func (c *cpuHandler) Stat(ctr *CgroupControl, m *Metrics) error {
 | 
			
		||||
	var err error
 | 
			
		||||
	usage := CPUUsage{}
 | 
			
		||||
	if ctr.cgroup2 {
 | 
			
		||||
		values, err := readCgroup2MapFile(ctr, "cpu.stat")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if val, found := values["usage_usec"]; found {
 | 
			
		||||
			usage.Total, err = strconv.ParseUint(cleanString(val[0]), 10, 0)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			usage.Kernel *= 1000
 | 
			
		||||
		}
 | 
			
		||||
		if val, found := values["system_usec"]; found {
 | 
			
		||||
			usage.Kernel, err = strconv.ParseUint(cleanString(val[0]), 10, 0)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			usage.Total *= 1000
 | 
			
		||||
		}
 | 
			
		||||
		// FIXME: How to read usage.PerCPU?
 | 
			
		||||
	} else {
 | 
			
		||||
		usage.Total, err = readAcct(ctr, "cpuacct.usage")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if !os.IsNotExist(errors.Cause(err)) {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			usage.Total = 0
 | 
			
		||||
		}
 | 
			
		||||
		usage.Kernel, err = readAcct(ctr, "cpuacct.usage_sys")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if !os.IsNotExist(errors.Cause(err)) {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			usage.Kernel = 0
 | 
			
		||||
		}
 | 
			
		||||
		usage.PerCPU, err = readAcctList(ctr, "cpuacct.usage_percpu")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if !os.IsNotExist(errors.Cause(err)) {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			usage.PerCPU = nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	m.CPU = CPUMetrics{Usage: usage}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,85 +0,0 @@
 | 
			
		|||
package cgroups
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	spec "github.com/opencontainers/runtime-spec/specs-go"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type cpusetHandler struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cpusetCopyFileFromParent(dir, file string, cgroupv2 bool) ([]byte, error) {
 | 
			
		||||
	if dir == cgroupRoot {
 | 
			
		||||
		return nil, fmt.Errorf("could not find parent to initialize cpuset %s", file)
 | 
			
		||||
	}
 | 
			
		||||
	path := filepath.Join(dir, file)
 | 
			
		||||
	parentPath := path
 | 
			
		||||
	if cgroupv2 {
 | 
			
		||||
		parentPath = fmt.Sprintf("%s.effective", parentPath)
 | 
			
		||||
	}
 | 
			
		||||
	data, err := ioutil.ReadFile(parentPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(err, "open %s", path)
 | 
			
		||||
	}
 | 
			
		||||
	if len(strings.Trim(string(data), "\n")) != 0 {
 | 
			
		||||
		return data, nil
 | 
			
		||||
	}
 | 
			
		||||
	data, err = cpusetCopyFileFromParent(filepath.Dir(dir), file, cgroupv2)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := ioutil.WriteFile(path, data, 0644); err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(err, "write %s", path)
 | 
			
		||||
	}
 | 
			
		||||
	return data, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cpusetCopyFromParent(path string, cgroupv2 bool) error {
 | 
			
		||||
	for _, file := range []string{"cpuset.cpus", "cpuset.mems"} {
 | 
			
		||||
		if _, err := cpusetCopyFileFromParent(path, file, cgroupv2); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getCpusetHandler() *cpusetHandler {
 | 
			
		||||
	return &cpusetHandler{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Apply set the specified constraints
 | 
			
		||||
func (c *cpusetHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error {
 | 
			
		||||
	if res.CPU == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Errorf("cpuset apply not implemented yet")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create the cgroup
 | 
			
		||||
func (c *cpusetHandler) Create(ctr *CgroupControl) (bool, error) {
 | 
			
		||||
	if ctr.cgroup2 {
 | 
			
		||||
		path := filepath.Join(cgroupRoot, ctr.path)
 | 
			
		||||
		return true, cpusetCopyFromParent(path, true)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	created, err := ctr.createCgroupDirectory(CPUset)
 | 
			
		||||
	if !created || err != nil {
 | 
			
		||||
		return created, err
 | 
			
		||||
	}
 | 
			
		||||
	return true, cpusetCopyFromParent(ctr.getCgroupv1Path(CPUset), false)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Destroy the cgroup
 | 
			
		||||
func (c *cpusetHandler) Destroy(ctr *CgroupControl) error {
 | 
			
		||||
	return rmDirRecursively(ctr.getCgroupv1Path(CPUset))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stat fills a metrics structure with usage stats for the controller
 | 
			
		||||
func (c *cpusetHandler) Stat(ctr *CgroupControl, m *Metrics) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,66 +0,0 @@
 | 
			
		|||
package cgroups
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
 | 
			
		||||
	spec "github.com/opencontainers/runtime-spec/specs-go"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type memHandler struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getMemoryHandler() *memHandler {
 | 
			
		||||
	return &memHandler{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Apply set the specified constraints
 | 
			
		||||
func (c *memHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error {
 | 
			
		||||
	if res.Memory == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Errorf("memory apply not implemented yet")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create the cgroup
 | 
			
		||||
func (c *memHandler) Create(ctr *CgroupControl) (bool, error) {
 | 
			
		||||
	if ctr.cgroup2 {
 | 
			
		||||
		return false, nil
 | 
			
		||||
	}
 | 
			
		||||
	return ctr.createCgroupDirectory(Memory)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Destroy the cgroup
 | 
			
		||||
func (c *memHandler) Destroy(ctr *CgroupControl) error {
 | 
			
		||||
	return rmDirRecursively(ctr.getCgroupv1Path(Memory))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stat fills a metrics structure with usage stats for the controller
 | 
			
		||||
func (c *memHandler) Stat(ctr *CgroupControl, m *Metrics) error {
 | 
			
		||||
	var err error
 | 
			
		||||
	usage := MemoryUsage{}
 | 
			
		||||
 | 
			
		||||
	var memoryRoot string
 | 
			
		||||
	filenames := map[string]string{}
 | 
			
		||||
 | 
			
		||||
	if ctr.cgroup2 {
 | 
			
		||||
		memoryRoot = filepath.Join(cgroupRoot, ctr.path)
 | 
			
		||||
		filenames["usage"] = "memory.current"
 | 
			
		||||
		filenames["limit"] = "memory.max"
 | 
			
		||||
	} else {
 | 
			
		||||
		memoryRoot = ctr.getCgroupv1Path(Memory)
 | 
			
		||||
		filenames["usage"] = "memory.usage_in_bytes"
 | 
			
		||||
		filenames["limit"] = "memory.limit_in_bytes"
 | 
			
		||||
	}
 | 
			
		||||
	usage.Usage, err = readFileAsUint64(filepath.Join(memoryRoot, filenames["usage"]))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	usage.Limit, err = readFileAsUint64(filepath.Join(memoryRoot, filenames["limit"]))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.Memory = MemoryMetrics{Usage: usage}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,62 +0,0 @@
 | 
			
		|||
package cgroups
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
 | 
			
		||||
	spec "github.com/opencontainers/runtime-spec/specs-go"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type pidHandler struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getPidsHandler() *pidHandler {
 | 
			
		||||
	return &pidHandler{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Apply set the specified constraints
 | 
			
		||||
func (c *pidHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error {
 | 
			
		||||
	if res.Pids == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	var PIDRoot string
 | 
			
		||||
 | 
			
		||||
	if ctr.cgroup2 {
 | 
			
		||||
		PIDRoot = filepath.Join(cgroupRoot, ctr.path)
 | 
			
		||||
	} else {
 | 
			
		||||
		PIDRoot = ctr.getCgroupv1Path(Pids)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p := filepath.Join(PIDRoot, "pids.max")
 | 
			
		||||
	return ioutil.WriteFile(p, []byte(fmt.Sprintf("%d\n", res.Pids.Limit)), 0644)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create the cgroup
 | 
			
		||||
func (c *pidHandler) Create(ctr *CgroupControl) (bool, error) {
 | 
			
		||||
	return ctr.createCgroupDirectory(Pids)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Destroy the cgroup
 | 
			
		||||
func (c *pidHandler) Destroy(ctr *CgroupControl) error {
 | 
			
		||||
	return rmDirRecursively(ctr.getCgroupv1Path(Pids))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stat fills a metrics structure with usage stats for the controller
 | 
			
		||||
func (c *pidHandler) Stat(ctr *CgroupControl, m *Metrics) error {
 | 
			
		||||
	var PIDRoot string
 | 
			
		||||
 | 
			
		||||
	if ctr.cgroup2 {
 | 
			
		||||
		PIDRoot = filepath.Join(cgroupRoot, ctr.path)
 | 
			
		||||
	} else {
 | 
			
		||||
		PIDRoot = ctr.getCgroupv1Path(Pids)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	current, err := readFileAsUint64(filepath.Join(PIDRoot, "pids.current"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.Pids = PidsMetrics{Current: current}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,79 +0,0 @@
 | 
			
		|||
package cgroups
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	systemdDbus "github.com/coreos/go-systemd/dbus"
 | 
			
		||||
	"github.com/godbus/dbus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func systemdCreate(path string, c *systemdDbus.Conn) error {
 | 
			
		||||
	slice, name := filepath.Split(path)
 | 
			
		||||
	slice = strings.TrimSuffix(slice, "/")
 | 
			
		||||
 | 
			
		||||
	var lastError error
 | 
			
		||||
	for i := 0; i < 2; i++ {
 | 
			
		||||
		properties := []systemdDbus.Property{
 | 
			
		||||
			systemdDbus.PropDescription(fmt.Sprintf("cgroup %s", name)),
 | 
			
		||||
			systemdDbus.PropWants(slice),
 | 
			
		||||
		}
 | 
			
		||||
		pMap := map[string]bool{
 | 
			
		||||
			"DefaultDependencies": false,
 | 
			
		||||
			"MemoryAccounting":    true,
 | 
			
		||||
			"CPUAccounting":       true,
 | 
			
		||||
			"BlockIOAccounting":   true,
 | 
			
		||||
		}
 | 
			
		||||
		if i == 0 {
 | 
			
		||||
			pMap["Delegate"] = true
 | 
			
		||||
		}
 | 
			
		||||
		for k, v := range pMap {
 | 
			
		||||
			p := systemdDbus.Property{
 | 
			
		||||
				Name:  k,
 | 
			
		||||
				Value: dbus.MakeVariant(v),
 | 
			
		||||
			}
 | 
			
		||||
			properties = append(properties, p)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ch := make(chan string)
 | 
			
		||||
		_, err := c.StartTransientUnit(name, "replace", properties, ch)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			lastError = err
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		<-ch
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return lastError
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
   systemdDestroyConn is copied from containerd/cgroups/systemd.go file, that
 | 
			
		||||
   has the following license:
 | 
			
		||||
 | 
			
		||||
   Copyright The containerd Authors.
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
func systemdDestroyConn(path string, c *systemdDbus.Conn) error {
 | 
			
		||||
	name := filepath.Base(path)
 | 
			
		||||
 | 
			
		||||
	ch := make(chan string)
 | 
			
		||||
	_, err := c.StopUnit(name, "replace", ch)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	<-ch
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,881 @@
 | 
			
		|||
package config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"github.com/BurntSushi/toml"
 | 
			
		||||
	"github.com/containers/common/pkg/capabilities"
 | 
			
		||||
	"github.com/containers/common/pkg/unshare"
 | 
			
		||||
	"github.com/containers/storage"
 | 
			
		||||
	units "github.com/docker/go-units"
 | 
			
		||||
	selinux "github.com/opencontainers/selinux/go-selinux"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// DefaultContainersConfig holds the default containers config path
 | 
			
		||||
	DefaultContainersConfig = "/usr/share/containers/containers.conf"
 | 
			
		||||
	// OverrideContainersConfig holds the default config paths overridden by the root user
 | 
			
		||||
	OverrideContainersConfig = "/etc/containers/containers.conf"
 | 
			
		||||
	// UserOverrideContainersConfig holds the containers config path overridden by the rootless user
 | 
			
		||||
	UserOverrideContainersConfig = ".config/containers/containers.conf"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// RuntimeStateStore is a constant indicating which state store implementation
 | 
			
		||||
// should be used by libpod
 | 
			
		||||
type RuntimeStateStore int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// InvalidStateStore is an invalid state store
 | 
			
		||||
	InvalidStateStore RuntimeStateStore = iota
 | 
			
		||||
	// InMemoryStateStore is an in-memory state that will not persist data
 | 
			
		||||
	// on containers and pods between libpod instances or after system
 | 
			
		||||
	// reboot
 | 
			
		||||
	InMemoryStateStore RuntimeStateStore = iota
 | 
			
		||||
	// SQLiteStateStore is a state backed by a SQLite database
 | 
			
		||||
	// It is presently disabled
 | 
			
		||||
	SQLiteStateStore RuntimeStateStore = iota
 | 
			
		||||
	// BoltDBStateStore is a state backed by a BoltDB database
 | 
			
		||||
	BoltDBStateStore RuntimeStateStore = iota
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Config contains configuration options for container tools
 | 
			
		||||
type Config struct {
 | 
			
		||||
	// Containers specify settings that configure how containers will run ont the system
 | 
			
		||||
	Containers ContainersConfig `toml:"containers"`
 | 
			
		||||
	// Libpod specifies how the container engine based on Libpod will run
 | 
			
		||||
	Libpod LibpodConfig `toml:"libpod"`
 | 
			
		||||
	// Network section defines the configuration of CNI Plugins
 | 
			
		||||
	Network NetworkConfig `toml:"network"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ContainersConfig represents the "containers" TOML config table
 | 
			
		||||
// containers global options for containers tools
 | 
			
		||||
type ContainersConfig struct {
 | 
			
		||||
 | 
			
		||||
	// Devices to add to all containers
 | 
			
		||||
	AdditionalDevices []string `toml:"additional_devices"`
 | 
			
		||||
 | 
			
		||||
	// Volumes to add to all containers
 | 
			
		||||
	AdditionalVolumes []string `toml:"additional_volumes"`
 | 
			
		||||
 | 
			
		||||
	// ApparmorProfile is the apparmor profile name which is used as the
 | 
			
		||||
	// default for the runtime.
 | 
			
		||||
	ApparmorProfile string `toml:"apparmor_profile"`
 | 
			
		||||
 | 
			
		||||
	// Annotation to add to all containers
 | 
			
		||||
	AdditionalAnnotations []string `toml:"additional_annotations"`
 | 
			
		||||
 | 
			
		||||
	// CGroupManager is the CGroup Manager to use Valid values are "cgroupfs"
 | 
			
		||||
	// and "systemd".
 | 
			
		||||
	CgroupManager string `toml:"cgroup_manager"`
 | 
			
		||||
 | 
			
		||||
	// Default way to create a cgroup namespace for the container
 | 
			
		||||
	CgroupNS string `toml:"cgroupns"`
 | 
			
		||||
 | 
			
		||||
	// Capabilities to add to all containers.
 | 
			
		||||
	DefaultCapabilities []string `toml:"default_capabilities"`
 | 
			
		||||
 | 
			
		||||
	// Sysctls to add to all containers.
 | 
			
		||||
	DefaultSysctls []string `toml:"default_sysctls"`
 | 
			
		||||
 | 
			
		||||
	// DefaultUlimits specifies the default ulimits to apply to containers
 | 
			
		||||
	DefaultUlimits []string `toml:"default_ulimits"`
 | 
			
		||||
 | 
			
		||||
	// DefaultMountsFile is the path to the default mounts file for testing
 | 
			
		||||
	DefaultMountsFile string `toml:"-"`
 | 
			
		||||
 | 
			
		||||
	// DNSServers set default DNS servers.
 | 
			
		||||
	DNSServers []string `toml:"dns_servers"`
 | 
			
		||||
 | 
			
		||||
	// DNSOptions set default DNS options.
 | 
			
		||||
	DNSOptions []string `toml:"dns_options"`
 | 
			
		||||
 | 
			
		||||
	// DNSSearches set default DNS search domains.
 | 
			
		||||
	DNSSearches []string `toml:"dns_searches"`
 | 
			
		||||
 | 
			
		||||
	// EnableLabeling tells the container engines whether to use MAC
 | 
			
		||||
	// Labeling to separate containers (SELinux)
 | 
			
		||||
	EnableLabeling bool `toml:"label"`
 | 
			
		||||
 | 
			
		||||
	// Env is the environment variable list for container process.
 | 
			
		||||
	Env []string `toml:"env"`
 | 
			
		||||
 | 
			
		||||
	// EnvHost Pass all host environment variables into the container.
 | 
			
		||||
	EnvHost bool `toml:"env_host"`
 | 
			
		||||
 | 
			
		||||
	// HTTPProxy is the proxy environment variable list to apply to container process
 | 
			
		||||
	HTTPProxy bool `toml:"http_proxy"`
 | 
			
		||||
 | 
			
		||||
	// Init tells container runtimes whether to run init inside the
 | 
			
		||||
	// container that forwards signals and reaps processes.
 | 
			
		||||
	Init bool `toml:"init"`
 | 
			
		||||
 | 
			
		||||
	// InitPath is the path for init to run if the Init bool is enabled
 | 
			
		||||
	InitPath string `toml:"init_path"`
 | 
			
		||||
 | 
			
		||||
	// IPCNS way to to create a ipc namespace for the container
 | 
			
		||||
	IPCNS string `toml:"ipcns"`
 | 
			
		||||
 | 
			
		||||
	// LogDriver  for the container.  For example: k8s-file and journald
 | 
			
		||||
	LogDriver string `toml:"log_driver"`
 | 
			
		||||
 | 
			
		||||
	// LogSizeMax is the maximum number of bytes after which the log file
 | 
			
		||||
	// will be truncated. It can be expressed as a human-friendly string
 | 
			
		||||
	// that is parsed to bytes.
 | 
			
		||||
	// Negative values indicate that the log file won't be truncated.
 | 
			
		||||
	LogSizeMax int64 `toml:"log_size_max"`
 | 
			
		||||
 | 
			
		||||
	// NetNS indicates how to create a network namespace for the container
 | 
			
		||||
	NetNS string `toml:"netns"`
 | 
			
		||||
 | 
			
		||||
	// NoHosts tells container engine whether to create its own /etc/hosts
 | 
			
		||||
	NoHosts bool `toml:"no_hosts"`
 | 
			
		||||
 | 
			
		||||
	// PidsLimit is the number of processes each container is restricted to
 | 
			
		||||
	// by the cgroup process number controller.
 | 
			
		||||
	PidsLimit int64 `toml:"pids_limit"`
 | 
			
		||||
 | 
			
		||||
	// PidNS indicates how to create a pid namespace for the container
 | 
			
		||||
	PidNS string `toml:"pidns"`
 | 
			
		||||
 | 
			
		||||
	// SeccompProfile is the seccomp.json profile path which is used as the
 | 
			
		||||
	// default for the runtime.
 | 
			
		||||
	SeccompProfile string `toml:"seccomp_profile"`
 | 
			
		||||
 | 
			
		||||
	// ShmSize holds the size of /dev/shm.
 | 
			
		||||
	ShmSize string `toml:"shm_size"`
 | 
			
		||||
 | 
			
		||||
	// SignaturePolicyPath is the path to a signature policy to use for
 | 
			
		||||
	// validating images. If left empty, the containers/image default signature
 | 
			
		||||
	// policy will be used.
 | 
			
		||||
	SignaturePolicyPath string `toml:"_"`
 | 
			
		||||
 | 
			
		||||
	// UTSNS indicates how to create a UTS namespace for the container
 | 
			
		||||
	UTSNS string `toml:"utsns"`
 | 
			
		||||
 | 
			
		||||
	// UserNS indicates how to create a User namespace for the container
 | 
			
		||||
	UserNS string `toml:"userns"`
 | 
			
		||||
 | 
			
		||||
	// UserNSSize how many UIDs to allocate for automatically created UserNS
 | 
			
		||||
	UserNSSize int `toml:"userns_size"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LibpodConfig contains configuration options used to set up a libpod runtime
 | 
			
		||||
type LibpodConfig struct {
 | 
			
		||||
	// NOTE: when changing this struct, make sure to update (*Config).Merge().
 | 
			
		||||
 | 
			
		||||
	// ConmonEnvVars are environment variables to pass to the Conmon binary
 | 
			
		||||
	// when it is launched.
 | 
			
		||||
	ConmonEnvVars []string `toml:"conmon_env_vars"`
 | 
			
		||||
 | 
			
		||||
	// ConmonPath is the path to the Conmon binary used for managing containers.
 | 
			
		||||
	// The first path pointing to a valid file will be used.
 | 
			
		||||
	ConmonPath []string `toml:"conmon_path"`
 | 
			
		||||
 | 
			
		||||
	//DetachKeys is the sequence of keys used to detach a container.
 | 
			
		||||
	DetachKeys string `toml:"detach_keys"`
 | 
			
		||||
 | 
			
		||||
	// EnablePortReservation determines whether libpod will reserve ports on the
 | 
			
		||||
	// host when they are forwarded to containers. When enabled, when ports are
 | 
			
		||||
	// forwarded to containers, they are held open by conmon as long as the
 | 
			
		||||
	// container is running, ensuring that they cannot be reused by other
 | 
			
		||||
	// programs on the host. However, this can cause significant memory usage if
 | 
			
		||||
	// a container has many ports forwarded to it. Disabling this can save
 | 
			
		||||
	// memory.
 | 
			
		||||
	EnablePortReservation bool `toml:"enable_port_reservation"`
 | 
			
		||||
 | 
			
		||||
	// EventsLogFilePath is where the events log is stored.
 | 
			
		||||
	EventsLogFilePath string `toml:"events_logfile_path"`
 | 
			
		||||
 | 
			
		||||
	// EventsLogger determines where events should be logged.
 | 
			
		||||
	EventsLogger string `toml:"events_logger"`
 | 
			
		||||
 | 
			
		||||
	// configuration files. When the same filename is present in in
 | 
			
		||||
	// multiple directories, the file in the directory listed last in
 | 
			
		||||
	// this slice takes precedence.
 | 
			
		||||
	HooksDir []string `toml:"hooks_dir"`
 | 
			
		||||
 | 
			
		||||
	// ImageDefaultTransport is the default transport method used to fetch
 | 
			
		||||
	// images.
 | 
			
		||||
	ImageDefaultTransport string `toml:"image_default_transport"`
 | 
			
		||||
 | 
			
		||||
	// InfraCommand is the command run to start up a pod infra container.
 | 
			
		||||
	InfraCommand string `toml:"infra_command"`
 | 
			
		||||
 | 
			
		||||
	// InfraImage is the image a pod infra container will use to manage
 | 
			
		||||
	// namespaces.
 | 
			
		||||
	InfraImage string `toml:"infra_image"`
 | 
			
		||||
 | 
			
		||||
	// InitPath is the path to the container-init binary.
 | 
			
		||||
	InitPath string `toml:"init_path"`
 | 
			
		||||
 | 
			
		||||
	// LockType is the type of locking to use.
 | 
			
		||||
	LockType string `toml:"lock_type,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// Namespace is the libpod namespace to use. Namespaces are used to create
 | 
			
		||||
	// scopes to separate containers and pods in the state. When namespace is
 | 
			
		||||
	// set, libpod will only view containers and pods in the same namespace. All
 | 
			
		||||
	// containers and pods created will default to the namespace set here. A
 | 
			
		||||
	// namespace of "", the empty string, is equivalent to no namespace, and all
 | 
			
		||||
	// containers and pods will be visible. The default namespace is "".
 | 
			
		||||
	Namespace string `toml:"namespace,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// NetworkCmdPath is the path to the slirp4netns binary.
 | 
			
		||||
	NetworkCmdPath string `toml:"network_cmd_path"`
 | 
			
		||||
 | 
			
		||||
	// NoPivotRoot sets whether to set no-pivot-root in the OCI runtime.
 | 
			
		||||
	NoPivotRoot bool `toml:"no_pivot_root"`
 | 
			
		||||
 | 
			
		||||
	// NumLocks is the number of locks to make available for containers and
 | 
			
		||||
	// pods.
 | 
			
		||||
	NumLocks uint32 `toml:"num_locks,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// OCIRuntime is the OCI runtime to use.
 | 
			
		||||
	OCIRuntime string `toml:"runtime"`
 | 
			
		||||
 | 
			
		||||
	// OCIRuntimes are the set of configured OCI runtimes (default is runc).
 | 
			
		||||
	OCIRuntimes map[string][]string `toml:"runtimes"`
 | 
			
		||||
 | 
			
		||||
	// RuntimeSupportsJSON is the list of the OCI runtimes that support
 | 
			
		||||
	// --format=json.
 | 
			
		||||
	RuntimeSupportsJSON []string `toml:"runtime_supports_json"`
 | 
			
		||||
 | 
			
		||||
	// RuntimeSupportsNoCgroups is a list of OCI runtimes that support
 | 
			
		||||
	// running containers without CGroups.
 | 
			
		||||
	RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroups"`
 | 
			
		||||
 | 
			
		||||
	// 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 a parsed libpod
 | 
			
		||||
	// configuration file. If not, the corresponding option might be
 | 
			
		||||
	// overwritten by values from the database. This behavior guarantees
 | 
			
		||||
	// backwards compat with older version of libpod and Podman.
 | 
			
		||||
	SetOptions
 | 
			
		||||
 | 
			
		||||
	// SDNotify tells container engine to allow containers to notify the host systemd of
 | 
			
		||||
	// readiness using the SD_NOTIFY mechanism.
 | 
			
		||||
	SDNotify bool
 | 
			
		||||
 | 
			
		||||
	// StateType is the type of the backing state store. Avoid using multiple
 | 
			
		||||
	// values for this with the same containers/storage configuration on the
 | 
			
		||||
	// same system. Different state types do not interact, and each will see a
 | 
			
		||||
	// separate set of containers, which may cause conflicts in
 | 
			
		||||
	// containers/storage. As such this is not exposed via the config file.
 | 
			
		||||
	StateType RuntimeStateStore `toml:"-"`
 | 
			
		||||
 | 
			
		||||
	// StaticDir is the path to a persistent directory to store container
 | 
			
		||||
	// files.
 | 
			
		||||
	StaticDir string `toml:"static_dir"`
 | 
			
		||||
 | 
			
		||||
	// StorageConfig is the configuration used by containers/storage Not
 | 
			
		||||
	// included in the on-disk config, use the dedicated containers/storage
 | 
			
		||||
	// configuration file instead.
 | 
			
		||||
	StorageConfig storage.StoreOptions `toml:"-"`
 | 
			
		||||
 | 
			
		||||
	// TmpDir is the path to a temporary directory to store per-boot container
 | 
			
		||||
	// files. Must be stored in a tmpfs.
 | 
			
		||||
	TmpDir string `toml:"tmp_dir"`
 | 
			
		||||
 | 
			
		||||
	// VolumePath is the default location that named volumes will be created
 | 
			
		||||
	// under. This convention is followed by the default volume driver, but
 | 
			
		||||
	// may not be by other drivers.
 | 
			
		||||
	VolumePath string `toml:"volume_path"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetOptions contains a subset of options in a Config. It's used to indicate if
 | 
			
		||||
// a given option has either been set by the user or by a parsed libpod
 | 
			
		||||
// configuration file. If not, the corresponding option might be overwritten by
 | 
			
		||||
// values from the database. This behavior guarantees backwards compat with
 | 
			
		||||
// older version of libpod and Podman.
 | 
			
		||||
type SetOptions struct {
 | 
			
		||||
	// StorageConfigRunRootSet indicates if the RunRoot has been explicitly set
 | 
			
		||||
	// by the config or by the user. It's required to guarantee backwards
 | 
			
		||||
	// compatibility with older versions of libpod for which we must query the
 | 
			
		||||
	// database configuration. Not included in the on-disk config.
 | 
			
		||||
	StorageConfigRunRootSet bool `toml:"-"`
 | 
			
		||||
 | 
			
		||||
	// StorageConfigGraphRootSet indicates if the RunRoot has been explicitly
 | 
			
		||||
	// set by the config or by the user. It's required to guarantee backwards
 | 
			
		||||
	// compatibility with older versions of libpod for which we must query the
 | 
			
		||||
	// database configuration. Not included in the on-disk config.
 | 
			
		||||
	StorageConfigGraphRootSet bool `toml:"-"`
 | 
			
		||||
 | 
			
		||||
	// StorageConfigGraphDriverNameSet indicates if the GraphDriverName has been
 | 
			
		||||
	// explicitly set by the config or by the user. It's required to guarantee
 | 
			
		||||
	// backwards compatibility with older versions of libpod for which we must
 | 
			
		||||
	// query the database configuration. Not included in the on-disk config.
 | 
			
		||||
	StorageConfigGraphDriverNameSet bool `toml:"-"`
 | 
			
		||||
 | 
			
		||||
	// StaticDirSet indicates if the StaticDir has been explicitly set by the
 | 
			
		||||
	// config or by the user. It's required to guarantee backwards compatibility
 | 
			
		||||
	// with older versions of libpod for which we must query the database
 | 
			
		||||
	// configuration. Not included in the on-disk config.
 | 
			
		||||
	StaticDirSet bool `toml:"-"`
 | 
			
		||||
 | 
			
		||||
	// VolumePathSet indicates if the VolumePath has been explicitly set by the
 | 
			
		||||
	// config or by the user. It's required to guarantee backwards compatibility
 | 
			
		||||
	// with older versions of libpod for which we must query the database
 | 
			
		||||
	// configuration. Not included in the on-disk config.
 | 
			
		||||
	VolumePathSet bool `toml:"-"`
 | 
			
		||||
 | 
			
		||||
	// TmpDirSet indicates if the TmpDir has been explicitly set by the config
 | 
			
		||||
	// or by the user. It's required to guarantee backwards compatibility with
 | 
			
		||||
	// older versions of libpod for which we must query the database
 | 
			
		||||
	// configuration. Not included in the on-disk config.
 | 
			
		||||
	TmpDirSet bool `toml:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NetworkConfig represents the "network" TOML config table
 | 
			
		||||
type NetworkConfig struct {
 | 
			
		||||
	// CNIPluginDirs is where CNI plugin binaries are stored.
 | 
			
		||||
	CNIPluginDirs []string `toml:"cni_plugin_dirs"`
 | 
			
		||||
 | 
			
		||||
	// DefaultNetwork is the network name of the default CNI network
 | 
			
		||||
	// to attach pods to.
 | 
			
		||||
	DefaultNetwork string `toml:"default_network,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// NetworkConfigDir is where CNI network configuration files are stored.
 | 
			
		||||
	NetworkConfigDir string `toml:"network_config_dir"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewConfig creates a new Config. It starts with an empty config and, if
 | 
			
		||||
// specified, merges the config at `userConfigPath` path.  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).
 | 
			
		||||
// 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
 | 
			
		||||
// might change in the future.
 | 
			
		||||
func NewConfig(userConfigPath string) (*Config, error) {
 | 
			
		||||
 | 
			
		||||
	// Generate the default config for the system
 | 
			
		||||
	config, err := DefaultConfig()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If the caller specified a config path to use, then we read this
 | 
			
		||||
	// rather then using the system defaults.
 | 
			
		||||
	if userConfigPath != "" {
 | 
			
		||||
		var err error
 | 
			
		||||
		// readConfigFromFile reads in container config in the specified
 | 
			
		||||
		// file and then merge changes with the current default.
 | 
			
		||||
		config, err = readConfigFromFile(userConfigPath, config)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, errors.Wrapf(err, "error reading user config %q", userConfigPath)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Now, gather the system configs and merge them as needed.
 | 
			
		||||
	configs, err := systemConfigs()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errors.Wrapf(err, "error finding config on system")
 | 
			
		||||
	}
 | 
			
		||||
	for _, path := range configs {
 | 
			
		||||
		// Merge changes in later configs with the previous configs.
 | 
			
		||||
		// Each config file that specified fields, will override the
 | 
			
		||||
		// previous fields.
 | 
			
		||||
		config, err := readConfigFromFile(path, config)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, errors.Wrapf(err, "error reading system config %q", path)
 | 
			
		||||
		}
 | 
			
		||||
		logrus.Debugf("Merged system config %q: %v", path, config)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	config.checkCgroupsAndAdjustConfig()
 | 
			
		||||
	config.addCAPPrefix()
 | 
			
		||||
 | 
			
		||||
	if err := config.Validate(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return config, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// readConfigFromFile reads the specified config file at `path` and attempts to
 | 
			
		||||
// unmarshal its content into a Config. The config param specifies the previous
 | 
			
		||||
// default config. If the path, only specifies a few fields in the Toml file
 | 
			
		||||
// the defaults from the config parameter will be used for all other fields.
 | 
			
		||||
func readConfigFromFile(path string, config *Config) (*Config, error) {
 | 
			
		||||
	logrus.Debugf("Reading configuration file %q", path)
 | 
			
		||||
	_, err := toml.DecodeFile(path, config)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("unable to decode configuration %v: %v", path, err)
 | 
			
		||||
	}
 | 
			
		||||
	if config.Libpod.VolumePath != "" {
 | 
			
		||||
		config.Libpod.VolumePathSet = true
 | 
			
		||||
	}
 | 
			
		||||
	if config.Libpod.StaticDir != "" {
 | 
			
		||||
		config.Libpod.StaticDirSet = true
 | 
			
		||||
	}
 | 
			
		||||
	if config.Libpod.TmpDir != "" {
 | 
			
		||||
		config.Libpod.TmpDirSet = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return config, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns the list of configuration files, if they exist in order of hierarchy.
 | 
			
		||||
// The files are read in order and each new file can/will override previous
 | 
			
		||||
// file settings.
 | 
			
		||||
func systemConfigs() ([]string, error) {
 | 
			
		||||
	configs := []string{}
 | 
			
		||||
	path := os.Getenv("CONTAINERS_CONF")
 | 
			
		||||
	if path != "" {
 | 
			
		||||
		if _, err := os.Stat(path); err != nil {
 | 
			
		||||
			return nil, errors.Wrap(err, "failed to stat of %s from CONTAINERS_CONF environment variable")
 | 
			
		||||
		}
 | 
			
		||||
		return append(configs, path), nil
 | 
			
		||||
	}
 | 
			
		||||
	if _, err := os.Stat(DefaultContainersConfig); err == nil {
 | 
			
		||||
		configs = append(configs, DefaultContainersConfig)
 | 
			
		||||
	}
 | 
			
		||||
	if _, err := os.Stat(OverrideContainersConfig); err == nil {
 | 
			
		||||
		configs = append(configs, OverrideContainersConfig)
 | 
			
		||||
	}
 | 
			
		||||
	if unshare.IsRootless() {
 | 
			
		||||
		path, err := rootlessConfigPath()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		if _, err := os.Stat(path); err == nil {
 | 
			
		||||
			configs = append(configs, path)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return configs, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkCgroupsAndAdjustConfig checks if we're running rootless with the systemd
 | 
			
		||||
// cgroup manager. In case the user session isn't available, we're switching the
 | 
			
		||||
// cgroup manager to cgroupfs.  Note, this only applies to rootless.
 | 
			
		||||
func (c *Config) checkCgroupsAndAdjustConfig() {
 | 
			
		||||
	if !unshare.IsRootless() || c.Containers.CgroupManager != SystemdCgroupsManager {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	session := os.Getenv("DBUS_SESSION_BUS_ADDRESS")
 | 
			
		||||
	hasSession := session != ""
 | 
			
		||||
	if hasSession && strings.HasPrefix(session, "unix:path=") {
 | 
			
		||||
		_, err := os.Stat(strings.TrimPrefix(session, "unix:path="))
 | 
			
		||||
		hasSession = err == nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !hasSession {
 | 
			
		||||
		logrus.Warningf("The cgroups 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("Alternatively, you can enable lingering with: `loginctl enable-linger %d` (possibly as root)", unshare.GetRootlessUID())
 | 
			
		||||
		logrus.Warningf("Falling back to --cgroup-manager=cgroupfs")
 | 
			
		||||
		c.Containers.CgroupManager = CgroupfsCgroupsManager
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Config) addCAPPrefix() {
 | 
			
		||||
	toCAPPrefixed := func(cap string) string {
 | 
			
		||||
		if !strings.HasPrefix(strings.ToLower(cap), "cap_") {
 | 
			
		||||
			return "CAP_" + strings.ToUpper(cap)
 | 
			
		||||
		}
 | 
			
		||||
		return cap
 | 
			
		||||
	}
 | 
			
		||||
	for i, cap := range c.Containers.DefaultCapabilities {
 | 
			
		||||
		c.Containers.DefaultCapabilities[i] = toCAPPrefixed(cap)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate is the main entry point for library configuration validation.
 | 
			
		||||
func (c *Config) Validate() error {
 | 
			
		||||
 | 
			
		||||
	if err := c.Containers.Validate(); err != nil {
 | 
			
		||||
		return errors.Wrapf(err, "containers config")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !c.Containers.EnableLabeling {
 | 
			
		||||
		selinux.SetDisabled()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate is the main entry point for Libpod configuration validation
 | 
			
		||||
// It returns an `error` on validation failure, otherwise
 | 
			
		||||
// `nil`.
 | 
			
		||||
func (c *LibpodConfig) Validate() error {
 | 
			
		||||
	// Relative paths can cause nasty bugs, because core paths we use could
 | 
			
		||||
	// shift between runs (or even parts of the program - the OCI runtime
 | 
			
		||||
	// uses a different working directory than we do, for example.
 | 
			
		||||
	if !filepath.IsAbs(c.StaticDir) {
 | 
			
		||||
		return fmt.Errorf("static directory must be an absolute path - instead got %q", c.StaticDir)
 | 
			
		||||
	}
 | 
			
		||||
	if !filepath.IsAbs(c.TmpDir) {
 | 
			
		||||
		return fmt.Errorf("temporary directory must be an absolute path - instead got %q", c.TmpDir)
 | 
			
		||||
	}
 | 
			
		||||
	if !filepath.IsAbs(c.VolumePath) {
 | 
			
		||||
		return fmt.Errorf("volume path must be an absolute path - instead got %q", c.VolumePath)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate is the main entry point for containers configuration validation
 | 
			
		||||
// It returns an `error` on validation failure, otherwise
 | 
			
		||||
// `nil`.
 | 
			
		||||
func (c *ContainersConfig) Validate() error {
 | 
			
		||||
	for _, u := range c.DefaultUlimits {
 | 
			
		||||
		ul, err := units.ParseUlimit(u)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return fmt.Errorf("unrecognized ulimit %s: %v", u, err)
 | 
			
		||||
		}
 | 
			
		||||
		_, err = ul.GetRlimit()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, d := range c.AdditionalDevices {
 | 
			
		||||
		_, _, _, err := Device(d)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.LogSizeMax >= 0 && c.LogSizeMax < OCIBufSize {
 | 
			
		||||
		return fmt.Errorf("log size max should be negative or >= %d", OCIBufSize)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, err := units.FromHumanSize(c.ShmSize); err != nil {
 | 
			
		||||
		return fmt.Errorf("invalid --shm-size %s, %q", c.ShmSize, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate is the main entry point for network configuration validation.
 | 
			
		||||
// The parameter `onExecution` specifies if the validation should include
 | 
			
		||||
// execution checks. It returns an `error` on validation failure, otherwise
 | 
			
		||||
// `nil`.
 | 
			
		||||
func (c *NetworkConfig) Validate() error {
 | 
			
		||||
 | 
			
		||||
	if c.NetworkConfigDir != cniConfigDir {
 | 
			
		||||
		err := isDirectory(c.NetworkConfigDir)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return errors.Wrapf(err, "invalid network_config_dir: %s", c.NetworkConfigDir)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if stringsEq(c.CNIPluginDirs, cniBinDir) {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, pluginDir := range c.CNIPluginDirs {
 | 
			
		||||
		if err := isDirectory(pluginDir); err == nil {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return errors.Errorf("invalid cni_plugin_dirs: %s", strings.Join(c.CNIPluginDirs, ","))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DBConfig is a set of Libpod runtime configuration settings that are saved in
 | 
			
		||||
// a State when it is first created, and can subsequently be retrieved.
 | 
			
		||||
type DBConfig struct {
 | 
			
		||||
	LibpodRoot  string
 | 
			
		||||
	LibpodTmp   string
 | 
			
		||||
	StorageRoot string
 | 
			
		||||
	StorageTmp  string
 | 
			
		||||
	GraphDriver string
 | 
			
		||||
	VolumePath  string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MergeDBConfig merges the configuration from the database.
 | 
			
		||||
func (c *Config) MergeDBConfig(dbConfig *DBConfig) error {
 | 
			
		||||
 | 
			
		||||
	if !c.Libpod.StorageConfigRunRootSet && dbConfig.StorageTmp != "" {
 | 
			
		||||
		if c.Libpod.StorageConfig.RunRoot != dbConfig.StorageTmp &&
 | 
			
		||||
			c.Libpod.StorageConfig.RunRoot != "" {
 | 
			
		||||
			logrus.Debugf("Overriding run root %q with %q from database",
 | 
			
		||||
				c.Libpod.StorageConfig.RunRoot, dbConfig.StorageTmp)
 | 
			
		||||
		}
 | 
			
		||||
		c.Libpod.StorageConfig.RunRoot = dbConfig.StorageTmp
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !c.Libpod.StorageConfigGraphRootSet && dbConfig.StorageRoot != "" {
 | 
			
		||||
		if c.Libpod.StorageConfig.GraphRoot != dbConfig.StorageRoot &&
 | 
			
		||||
			c.Libpod.StorageConfig.GraphRoot != "" {
 | 
			
		||||
			logrus.Debugf("Overriding graph root %q with %q from database",
 | 
			
		||||
				c.Libpod.StorageConfig.GraphRoot, dbConfig.StorageRoot)
 | 
			
		||||
		}
 | 
			
		||||
		c.Libpod.StorageConfig.GraphRoot = dbConfig.StorageRoot
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !c.Libpod.StorageConfigGraphDriverNameSet && dbConfig.GraphDriver != "" {
 | 
			
		||||
		if c.Libpod.StorageConfig.GraphDriverName != dbConfig.GraphDriver &&
 | 
			
		||||
			c.Libpod.StorageConfig.GraphDriverName != "" {
 | 
			
		||||
			logrus.Errorf("User-selected graph driver %q overwritten by graph driver %q from database - delete libpod local files to resolve",
 | 
			
		||||
				c.Libpod.StorageConfig.GraphDriverName, dbConfig.GraphDriver)
 | 
			
		||||
		}
 | 
			
		||||
		c.Libpod.StorageConfig.GraphDriverName = dbConfig.GraphDriver
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !c.Libpod.StaticDirSet && dbConfig.LibpodRoot != "" {
 | 
			
		||||
		if c.Libpod.StaticDir != dbConfig.LibpodRoot && c.Libpod.StaticDir != "" {
 | 
			
		||||
			logrus.Debugf("Overriding static dir %q with %q from database", c.Libpod.StaticDir, dbConfig.LibpodRoot)
 | 
			
		||||
		}
 | 
			
		||||
		c.Libpod.StaticDir = dbConfig.LibpodRoot
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !c.Libpod.TmpDirSet && dbConfig.LibpodTmp != "" {
 | 
			
		||||
		if c.Libpod.TmpDir != dbConfig.LibpodTmp && c.Libpod.TmpDir != "" {
 | 
			
		||||
			logrus.Debugf("Overriding tmp dir %q with %q from database", c.Libpod.TmpDir, dbConfig.LibpodTmp)
 | 
			
		||||
		}
 | 
			
		||||
		c.Libpod.TmpDir = dbConfig.LibpodTmp
 | 
			
		||||
		c.Libpod.EventsLogFilePath = filepath.Join(dbConfig.LibpodTmp, "events", "events.log")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !c.Libpod.VolumePathSet && dbConfig.VolumePath != "" {
 | 
			
		||||
		if c.Libpod.VolumePath != dbConfig.VolumePath && c.Libpod.VolumePath != "" {
 | 
			
		||||
			logrus.Debugf("Overriding volume path %q with %q from database", c.Libpod.VolumePath, dbConfig.VolumePath)
 | 
			
		||||
		}
 | 
			
		||||
		c.Libpod.VolumePath = dbConfig.VolumePath
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FindConmon iterates over (*Config).ConmonPath and returns the path
 | 
			
		||||
// to first (version) matching conmon binary. If non is found, we try
 | 
			
		||||
// to do a path lookup of "conmon".
 | 
			
		||||
func (c *Config) FindConmon() (string, error) {
 | 
			
		||||
	foundOutdatedConmon := false
 | 
			
		||||
	for _, path := range c.Libpod.ConmonPath {
 | 
			
		||||
		stat, err := os.Stat(path)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if stat.IsDir() {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if err := probeConmon(path); err != nil {
 | 
			
		||||
			logrus.Warnf("Conmon at %s invalid: %v", path, err)
 | 
			
		||||
			foundOutdatedConmon = true
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		logrus.Debugf("Using conmon: %q", path)
 | 
			
		||||
		return path, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Search the $PATH as last fallback
 | 
			
		||||
	if path, err := exec.LookPath("conmon"); err == nil {
 | 
			
		||||
		if err := probeConmon(path); err != nil {
 | 
			
		||||
			logrus.Warnf("Conmon at %s is invalid: %v", path, err)
 | 
			
		||||
			foundOutdatedConmon = true
 | 
			
		||||
		} else {
 | 
			
		||||
			logrus.Debugf("Using conmon from $PATH: %q", path)
 | 
			
		||||
			return path, nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if foundOutdatedConmon {
 | 
			
		||||
		return "", errors.Wrapf(ErrConmonOutdated,
 | 
			
		||||
			"please update to v%d.%d.%d or later",
 | 
			
		||||
			_conmonMinMajorVersion, _conmonMinMinorVersion, _conmonMinPatchVersion)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return "", errors.Wrapf(ErrInvalidArg,
 | 
			
		||||
		"could not find a working conmon binary (configured options: %v)",
 | 
			
		||||
		c.Libpod.ConmonPath)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetDefaultEnv returns the environment variables for the container.
 | 
			
		||||
// It will checn the HTTPProxy and HostEnv booleans and add the appropriate
 | 
			
		||||
// environment variables to the container.
 | 
			
		||||
func (c *Config) GetDefaultEnv() []string {
 | 
			
		||||
	var env []string
 | 
			
		||||
	if c.Containers.EnvHost {
 | 
			
		||||
		env = append(env, os.Environ()...)
 | 
			
		||||
	} else if c.Containers.HTTPProxy {
 | 
			
		||||
		proxy := []string{"http_proxy", "https_proxy", "ftp_proxy", "no_proxy", "HTTP_PROXY", "HTTPS_PROXY", "FTP_PROXY", "NO_PROXY"}
 | 
			
		||||
		for _, p := range proxy {
 | 
			
		||||
			if val, ok := os.LookupEnv(p); ok {
 | 
			
		||||
				env = append(env, fmt.Sprintf("%s=%s", p, val))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return append(env, c.Containers.Env...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Capabilities returns the capabilities parses the Add and Drop capability
 | 
			
		||||
// list from the default capabiltiies for the container
 | 
			
		||||
func (c *Config) Capabilities(user string, addCapabilities, dropCapabilities []string) []string {
 | 
			
		||||
 | 
			
		||||
	userNotRoot := func(user string) bool {
 | 
			
		||||
		if user == "" || user == "root" || user == "0" {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var caps []string
 | 
			
		||||
	defaultCapabilities := c.Containers.DefaultCapabilities
 | 
			
		||||
	if userNotRoot(user) {
 | 
			
		||||
		defaultCapabilities = []string{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mapCap := make(map[string]bool, len(defaultCapabilities))
 | 
			
		||||
	for _, c := range addCapabilities {
 | 
			
		||||
		if strings.ToLower(c) == "all" {
 | 
			
		||||
			defaultCapabilities = capabilities.AllCapabilities()
 | 
			
		||||
			addCapabilities = nil
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, c := range append(defaultCapabilities, addCapabilities...) {
 | 
			
		||||
		mapCap[c] = true
 | 
			
		||||
	}
 | 
			
		||||
	for _, c := range dropCapabilities {
 | 
			
		||||
		if "all" == strings.ToLower(c) {
 | 
			
		||||
			return caps
 | 
			
		||||
		}
 | 
			
		||||
		mapCap[c] = false
 | 
			
		||||
	}
 | 
			
		||||
	for cap, add := range mapCap {
 | 
			
		||||
		if add {
 | 
			
		||||
			caps = append(caps, cap)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return caps
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Device parses device mapping string to a src, dest & permissions string
 | 
			
		||||
// Valid values for device looklike:
 | 
			
		||||
//    '/dev/sdc"
 | 
			
		||||
//    '/dev/sdc:/dev/xvdc"
 | 
			
		||||
//    '/dev/sdc:/dev/xvdc:rwm"
 | 
			
		||||
//    '/dev/sdc:rm"
 | 
			
		||||
func Device(device string) (string, string, string, error) {
 | 
			
		||||
	src := ""
 | 
			
		||||
	dst := ""
 | 
			
		||||
	permissions := "rwm"
 | 
			
		||||
	split := strings.Split(device, ":")
 | 
			
		||||
	switch len(split) {
 | 
			
		||||
	case 3:
 | 
			
		||||
		if !IsValidDeviceMode(split[2]) {
 | 
			
		||||
			return "", "", "", fmt.Errorf("invalid device mode: %s", split[2])
 | 
			
		||||
		}
 | 
			
		||||
		permissions = split[2]
 | 
			
		||||
		fallthrough
 | 
			
		||||
	case 2:
 | 
			
		||||
		if IsValidDeviceMode(split[1]) {
 | 
			
		||||
			permissions = split[1]
 | 
			
		||||
		} else {
 | 
			
		||||
			if len(split[1]) == 0 || split[1][0] != '/' {
 | 
			
		||||
				return "", "", "", fmt.Errorf("invalid device mode: %s", split[1])
 | 
			
		||||
			}
 | 
			
		||||
			dst = split[1]
 | 
			
		||||
		}
 | 
			
		||||
		fallthrough
 | 
			
		||||
	case 1:
 | 
			
		||||
		if !strings.HasPrefix(split[0], "/dev/") {
 | 
			
		||||
			return "", "", "", fmt.Errorf("invalid device mode: %s", split[0])
 | 
			
		||||
		}
 | 
			
		||||
		src = split[0]
 | 
			
		||||
	default:
 | 
			
		||||
		return "", "", "", fmt.Errorf("invalid device specification: %s", device)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if dst == "" {
 | 
			
		||||
		dst = src
 | 
			
		||||
	}
 | 
			
		||||
	return src, dst, permissions, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsValidDeviceMode checks if the mode for device is valid or not.
 | 
			
		||||
// IsValid mode is a composition of r (read), w (write), and m (mknod).
 | 
			
		||||
func IsValidDeviceMode(mode string) bool {
 | 
			
		||||
	var legalDeviceMode = map[rune]bool{
 | 
			
		||||
		'r': true,
 | 
			
		||||
		'w': true,
 | 
			
		||||
		'm': true,
 | 
			
		||||
	}
 | 
			
		||||
	if mode == "" {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	for _, c := range mode {
 | 
			
		||||
		if !legalDeviceMode[c] {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		legalDeviceMode[c] = false
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// isDirectory tests whether the given path exists and is a directory. It
 | 
			
		||||
// follows symlinks.
 | 
			
		||||
func isDirectory(path string) error {
 | 
			
		||||
	info, err := os.Stat(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !info.Mode().IsDir() {
 | 
			
		||||
		// Return a PathError to be consistent with os.Stat().
 | 
			
		||||
		return &os.PathError{
 | 
			
		||||
			Op:   "stat",
 | 
			
		||||
			Path: path,
 | 
			
		||||
			Err:  syscall.ENOTDIR,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func rootlessConfigPath() (string, error) {
 | 
			
		||||
	home, err := unshare.HomeDir()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return filepath.Join(home, UserOverrideContainersConfig), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func stringsEq(a, b []string) bool {
 | 
			
		||||
 | 
			
		||||
	if len(a) != len(b) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i := range a {
 | 
			
		||||
		if a[i] != b[i] {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	configOnce sync.Once
 | 
			
		||||
	config     *Config
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Default returns the default container config.
 | 
			
		||||
// Configuration files will be read in the following files:
 | 
			
		||||
// * /usr/share/containers/containers.conf
 | 
			
		||||
// * /etc/containers/containers.conf
 | 
			
		||||
// * $HOME/.config/containers/containers.conf # When run in rootless mode
 | 
			
		||||
// Fields in latter files override defaults set in previous files and the
 | 
			
		||||
// default config.
 | 
			
		||||
// None of these files are required, and not all fields need to be specified
 | 
			
		||||
// in each file, only the fields you want to override.
 | 
			
		||||
// The system defaults container config files can be overwritten using the
 | 
			
		||||
// CONTAINERS_CONF environment variable.  This is usually done for testing.
 | 
			
		||||
func Default() (*Config, error) {
 | 
			
		||||
	var err error
 | 
			
		||||
	configOnce.Do(func() {
 | 
			
		||||
		config, err = NewConfig("")
 | 
			
		||||
	})
 | 
			
		||||
	return config, err
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
package config
 | 
			
		||||
 | 
			
		||||
import selinux "github.com/opencontainers/selinux/go-selinux"
 | 
			
		||||
 | 
			
		||||
func selinuxEnabled() bool {
 | 
			
		||||
	return selinux.GetEnabled()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
// +build !windows
 | 
			
		||||
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
// Defaults for linux/unix if none are specified
 | 
			
		||||
const (
 | 
			
		||||
	cniConfigDir = "/etc/cni/net.d/"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var cniBinDir = []string{
 | 
			
		||||
	"/usr/libexec/cni",
 | 
			
		||||
	"/usr/lib/cni",
 | 
			
		||||
	"/usr/local/lib/cni",
 | 
			
		||||
	"/opt/cni/bin",
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/github.com/containers/common/pkg/config/config_unsupported.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										7
									
								
								vendor/github.com/containers/common/pkg/config/config_unsupported.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
// +build !linux
 | 
			
		||||
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
func selinuxEnabled() bool {
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
// +build windows
 | 
			
		||||
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
// Defaults for linux/unix if none are specified
 | 
			
		||||
const (
 | 
			
		||||
	cniConfigDir = "C:\\cni\\etc\\net.d\\"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var cniBinDir = []string{"C:\\cni\\bin\\"}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,372 @@
 | 
			
		|||
# The containers configuration file specifies all of the available configuration
 | 
			
		||||
# command-line options/flags for container runtime tools like Podman & Buildah,
 | 
			
		||||
# but in a TOML format that can be easily modified and versioned.
 | 
			
		||||
 | 
			
		||||
# Please refer to containers.conf(5) for details of all configuration options.
 | 
			
		||||
# Not all container tools implement all of the options.
 | 
			
		||||
# All of the options have hard coded defaults and these options will override
 | 
			
		||||
# the built in defaults. Users can then override these options via the command
 | 
			
		||||
# line. Container engines will read containers.conf files in up to three
 | 
			
		||||
# locations in the following order:
 | 
			
		||||
#  1. /usr/share/containers/containers.conf
 | 
			
		||||
#  2. /etc/containers/containers.conf
 | 
			
		||||
#  3. $HOME/.config/containers/containers.conf (Rootless containers ONLY)
 | 
			
		||||
#  Items specified in the latter containers.conf, if they exist, override the
 | 
			
		||||
# previous containers.conf settings, or the default settings.
 | 
			
		||||
 | 
			
		||||
[containers]
 | 
			
		||||
 | 
			
		||||
# List of additional devices. Specified as
 | 
			
		||||
# "<device-on-host>:<device-on-container>:<permissions>", for example:
 | 
			
		||||
# "/dev/sdc:/dev/xvdc:rwm".
 | 
			
		||||
# If it is empty or commented out, only the default devices will be used
 | 
			
		||||
#
 | 
			
		||||
# additional_devices = []
 | 
			
		||||
 | 
			
		||||
# List of additional volumes. Specified as
 | 
			
		||||
# "<directory-on-host>:<directory-in-container>:<options>", for example:
 | 
			
		||||
# "/db:/var/lib/db:ro".
 | 
			
		||||
# If it is empty or commented out, no volumes will be added
 | 
			
		||||
#
 | 
			
		||||
# additional_volumes = []
 | 
			
		||||
 | 
			
		||||
# Used to change the name of the default AppArmor profile of container engines.
 | 
			
		||||
#
 | 
			
		||||
# apparmor_profile = "container-default"
 | 
			
		||||
 | 
			
		||||
# List of additional annotation. Specified as
 | 
			
		||||
# "key=value"
 | 
			
		||||
# If it is empty or commented out, no annotations will be added
 | 
			
		||||
#
 | 
			
		||||
# additional_annotations = []
 | 
			
		||||
 | 
			
		||||
# Default way to to create a cgroup namespace for the container
 | 
			
		||||
# Options are:
 | 
			
		||||
# `private` Create private Cgroup Namespace for the container.
 | 
			
		||||
# `host`    Share host Cgroup Namespace with the container.
 | 
			
		||||
#
 | 
			
		||||
# cgroupns = "private"
 | 
			
		||||
 | 
			
		||||
# Cgroup management implementation used for the runtime.
 | 
			
		||||
# Valid options “systemd” or “cgroupfs”
 | 
			
		||||
#
 | 
			
		||||
# cgroup_manager = "systemd"
 | 
			
		||||
 | 
			
		||||
# List of default capabilities for containers. If it is empty or commented out,
 | 
			
		||||
# the default capabilities defined in the container engine will be added.
 | 
			
		||||
#
 | 
			
		||||
# default_capabilities = [
 | 
			
		||||
#    "AUDIT_WRITE",
 | 
			
		||||
#    "CHOWN",
 | 
			
		||||
#    "DAC_OVERRIDE",
 | 
			
		||||
#    "FOWNER",
 | 
			
		||||
#    "FSETID",
 | 
			
		||||
#    "KILL",
 | 
			
		||||
#    "MKNOD",
 | 
			
		||||
#    "NET_BIND_SERVICE",
 | 
			
		||||
#    "NET_RAW",
 | 
			
		||||
#    "SETGID",
 | 
			
		||||
#    "SETPCAP",
 | 
			
		||||
#    "SETUID",
 | 
			
		||||
#    "SYS_CHROOT",
 | 
			
		||||
# ]
 | 
			
		||||
 | 
			
		||||
# A list of sysctls to be set in containers by default,
 | 
			
		||||
# specified as "name=value",
 | 
			
		||||
# for example:"net.ipv4.ping_group_range = 0 1000".
 | 
			
		||||
#
 | 
			
		||||
# default_sysctls = [
 | 
			
		||||
#  "net.ipv4.ping_group_range=0 1000",
 | 
			
		||||
# ]
 | 
			
		||||
 | 
			
		||||
# A list of ulimits to be set in containers by default, specified as
 | 
			
		||||
# "<ulimit name>=<soft limit>:<hard limit>", for example:
 | 
			
		||||
# "nofile=1024:2048"
 | 
			
		||||
# See setrlimit(2) for a list of resource names.
 | 
			
		||||
# Any limit not specified here will be inherited from the process launching the
 | 
			
		||||
# container engine.
 | 
			
		||||
# Ulimits has limits for non privileged container engines.
 | 
			
		||||
#
 | 
			
		||||
# default_ulimits = [
 | 
			
		||||
#  “nofile”=”1280:2560”,
 | 
			
		||||
# ]
 | 
			
		||||
 | 
			
		||||
# List of default DNS options to be added to /etc/resolv.conf inside of the container.
 | 
			
		||||
#
 | 
			
		||||
# dns_options = []
 | 
			
		||||
 | 
			
		||||
# List of default DNS search domains to be added to /etc/resolv.conf inside of the container.
 | 
			
		||||
#
 | 
			
		||||
# dns_searches = []
 | 
			
		||||
 | 
			
		||||
# Set default DNS servers.
 | 
			
		||||
# This option can be used to override the DNS configuration passed to the
 | 
			
		||||
# container. The special value “none” can be specified to disable creation of
 | 
			
		||||
# /etc/resolv.conf in the container.
 | 
			
		||||
# The /etc/resolv.conf file in the image will be used without changes.
 | 
			
		||||
#
 | 
			
		||||
# dns_servers = []
 | 
			
		||||
 | 
			
		||||
# Environment variable list for the conmon process; used for passing necessary
 | 
			
		||||
# environment variables to conmon or the runtime.
 | 
			
		||||
#
 | 
			
		||||
# env = [
 | 
			
		||||
#    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
 | 
			
		||||
# ]
 | 
			
		||||
 | 
			
		||||
# Pass all host environment variables into the container.
 | 
			
		||||
#
 | 
			
		||||
# env_host = false
 | 
			
		||||
 | 
			
		||||
# Path to OCI hooks directories for automatically executed hooks.
 | 
			
		||||
#
 | 
			
		||||
# hooks_dir = [
 | 
			
		||||
# “/usr/share/containers/oci/hooks.d”,
 | 
			
		||||
# ]
 | 
			
		||||
 | 
			
		||||
# Default proxy environment variables passed into the container.
 | 
			
		||||
# The environment variables passed in include:
 | 
			
		||||
# http_proxy, https_proxy, ftp_proxy, no_proxy, and the upper case versions of
 | 
			
		||||
# these. This option is needed when host system uses a proxy but container
 | 
			
		||||
# should not use proxy. Proxy environment variables specified for the container
 | 
			
		||||
# in any other way will override the values passed from the host.
 | 
			
		||||
#
 | 
			
		||||
# http_proxy = true
 | 
			
		||||
 | 
			
		||||
# Run an init inside the container that forwards signals and reaps processes.
 | 
			
		||||
#
 | 
			
		||||
# init = false
 | 
			
		||||
 | 
			
		||||
#  Container init binary, if init=true, this is the init binary to be used for containers.
 | 
			
		||||
#
 | 
			
		||||
# init_path = "/usr/libexec/podman/catatonit"
 | 
			
		||||
 | 
			
		||||
# Default way to to create an IPC namespace (POSIX SysV IPC) for the container
 | 
			
		||||
# Options are:
 | 
			
		||||
# `private` Create private IPC Namespace for the container.
 | 
			
		||||
# `host`    Share host IPC Namespace with the container.
 | 
			
		||||
#
 | 
			
		||||
# ipcns = "private"
 | 
			
		||||
 | 
			
		||||
# container engines use container separation using MAC(SELinux) labeling.
 | 
			
		||||
# Flag is ignored on label disabled systems.
 | 
			
		||||
#
 | 
			
		||||
# label = true
 | 
			
		||||
 | 
			
		||||
# Logging driver for the container. Available options: k8s-file and journald.
 | 
			
		||||
#
 | 
			
		||||
# log_driver = "k8s-file"
 | 
			
		||||
 | 
			
		||||
# Maximum size allowed for the container log file. Negative numbers indicate
 | 
			
		||||
# that no size limit is imposed. If positive, it must be >= 8192 to match or
 | 
			
		||||
# exceed conmon's read buffer. The file is truncated and re-opened so the
 | 
			
		||||
# limit is never exceeded.
 | 
			
		||||
#
 | 
			
		||||
# log_size_max = -1
 | 
			
		||||
 | 
			
		||||
# Default way to to create a Network namespace for the container
 | 
			
		||||
# Options are:
 | 
			
		||||
# `private` Create private Network Namespace for the container.
 | 
			
		||||
# `host`    Share host Network Namespace with the container.
 | 
			
		||||
# `none`    Containers do not use the network
 | 
			
		||||
#
 | 
			
		||||
# netns = "private"
 | 
			
		||||
 | 
			
		||||
# Create /etc/hosts for the container.  By default, container engines manage
 | 
			
		||||
# /etc/hosts, automatically adding  the container's  own  IP  address.
 | 
			
		||||
#
 | 
			
		||||
# no_hosts = false
 | 
			
		||||
 | 
			
		||||
# Maximum number of processes allowed in a container.
 | 
			
		||||
#
 | 
			
		||||
# pids_limit = 2048
 | 
			
		||||
 | 
			
		||||
# Default way to to create a PID namespace for the container
 | 
			
		||||
# Options are:
 | 
			
		||||
# `private` Create private PID Namespace for the container.
 | 
			
		||||
# `host`    Share host PID Namespace with the container.
 | 
			
		||||
#
 | 
			
		||||
# pidns = "private"
 | 
			
		||||
 | 
			
		||||
# Path to the seccomp.json profile which is used as the default seccomp profile
 | 
			
		||||
# for the runtime.
 | 
			
		||||
#
 | 
			
		||||
# seccomp_profile = "/usr/share/containers/seccomp.json"
 | 
			
		||||
 | 
			
		||||
# Size of /dev/shm. Specified as <number><unit>.
 | 
			
		||||
# Unit is optional, values:
 | 
			
		||||
# b (bytes), k (kilobytes), m (megabytes), or g (gigabytes).
 | 
			
		||||
# If the unit is omitted, the system uses bytes.
 | 
			
		||||
#
 | 
			
		||||
# shm_size = "65536k"
 | 
			
		||||
 | 
			
		||||
# Default way to to create a UTS namespace for the container
 | 
			
		||||
# Options are:
 | 
			
		||||
# `private`        Create private UTS Namespace for the container.
 | 
			
		||||
# `host`    Share host UTS Namespace with the container.
 | 
			
		||||
#
 | 
			
		||||
# utsns = "private"
 | 
			
		||||
 | 
			
		||||
# Default way to to create a User namespace for the container
 | 
			
		||||
# Options are:
 | 
			
		||||
# `auto`        Create unique User Namespace for the container.
 | 
			
		||||
# `host`    Share host User Namespace with the container.
 | 
			
		||||
#
 | 
			
		||||
# userns = "host"
 | 
			
		||||
 | 
			
		||||
# Number of UIDs to allocate for the automatic container creation.
 | 
			
		||||
# UIDs are allocated from the “container” UIDs listed in
 | 
			
		||||
# /etc/subuid & /etc/subgid
 | 
			
		||||
#
 | 
			
		||||
# userns_size=65536
 | 
			
		||||
 | 
			
		||||
# The network table contains settings pertaining to the management of
 | 
			
		||||
# CNI plugins.
 | 
			
		||||
 | 
			
		||||
[network]
 | 
			
		||||
 | 
			
		||||
# Path to directory where CNI plugin binaries are located.
 | 
			
		||||
#
 | 
			
		||||
# cni_plugin_dirs = ["/usr/libexec/cni"]
 | 
			
		||||
 | 
			
		||||
# Path to the directory where CNI configuration files are located.
 | 
			
		||||
#
 | 
			
		||||
# network_config_dir = "/etc/cni/net.d/"
 | 
			
		||||
 | 
			
		||||
[libpod]
 | 
			
		||||
 | 
			
		||||
# Environment variables to pass into conmon
 | 
			
		||||
#
 | 
			
		||||
# conmon_env_vars = [
 | 
			
		||||
#        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 | 
			
		||||
# ]
 | 
			
		||||
 | 
			
		||||
# Paths to look for the conmon container manager binary
 | 
			
		||||
#
 | 
			
		||||
# conmon_path = [
 | 
			
		||||
#        "/usr/libexec/podman/conmon",
 | 
			
		||||
#        "/usr/local/libexec/podman/conmon",
 | 
			
		||||
#        "/usr/local/lib/podman/conmon",
 | 
			
		||||
#        "/usr/bin/conmon",
 | 
			
		||||
#        "/usr/sbin/conmon",
 | 
			
		||||
#        "/usr/local/bin/conmon",
 | 
			
		||||
#        "/usr/local/sbin/conmon"
 | 
			
		||||
# ]
 | 
			
		||||
 | 
			
		||||
# Specify the keys sequence used to detach a container.
 | 
			
		||||
# Format is a single character [a-Z] or a comma separated sequence of
 | 
			
		||||
# `ctrl-<value>`, where `<value>` is one of:
 | 
			
		||||
# `a-z`, `@`, `^`, `[`, `\`, `]`, `^` or `_`
 | 
			
		||||
#
 | 
			
		||||
# detach_keys = "ctrl-p,ctrl-q"
 | 
			
		||||
 | 
			
		||||
# Determines whether libpod will reserve ports on the host when they are
 | 
			
		||||
# forwarded to containers. When enabled, when ports are forwarded to containers,
 | 
			
		||||
# ports are held open by as long as the container is running, ensuring that
 | 
			
		||||
# they cannot be reused by other programs on the host. However, this can cause
 | 
			
		||||
# significant memory usage if a container has many ports forwarded to it.
 | 
			
		||||
# Disabling this can save memory.
 | 
			
		||||
#
 | 
			
		||||
# enable_port_reservation = true
 | 
			
		||||
 | 
			
		||||
# Selects which logging mechanism to use for container engine events.
 | 
			
		||||
# Valid values are `journald`, `file` and `none`.
 | 
			
		||||
#
 | 
			
		||||
# events_logger = "journald"
 | 
			
		||||
 | 
			
		||||
# Default transport method for pulling and pushing for images
 | 
			
		||||
#
 | 
			
		||||
# image_default_transport = "docker://"
 | 
			
		||||
 | 
			
		||||
# Default command to run the infra container
 | 
			
		||||
#
 | 
			
		||||
# infra_command = "/pause"
 | 
			
		||||
 | 
			
		||||
# Infra (pause) container image name for pod infra containers.  When running a
 | 
			
		||||
# pod, we start a `pause` process in a container to hold open the namespaces
 | 
			
		||||
# associated with the  pod.  This container does nothing other then sleep,
 | 
			
		||||
# reserving the pods resources for the lifetime of the pod.
 | 
			
		||||
#
 | 
			
		||||
# infra_image = "k8s.gcr.io/pause:3.1"
 | 
			
		||||
 | 
			
		||||
# 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
 | 
			
		||||
# "file" is useful only on platforms where cgo is not available for using the
 | 
			
		||||
# faster "shm" lock type.  You may need to run "podman system renumber" after
 | 
			
		||||
# you change the lock type.
 | 
			
		||||
#
 | 
			
		||||
# lock_type** = "shm"
 | 
			
		||||
 | 
			
		||||
# Default libpod namespace
 | 
			
		||||
# If libpod is joined to a namespace, it will see only containers and pods
 | 
			
		||||
# that were created in the same namespace, and will create new containers and
 | 
			
		||||
# pods in that namespace.
 | 
			
		||||
# The default namespace is "", which corresponds to no namespace. When no
 | 
			
		||||
# namespace is set, all containers and pods are visible.
 | 
			
		||||
#
 | 
			
		||||
# namespace = ""
 | 
			
		||||
 | 
			
		||||
# Whether to use chroot instead of pivot_root in the runtime
 | 
			
		||||
#
 | 
			
		||||
# no_pivot_root = false
 | 
			
		||||
 | 
			
		||||
# Number of locks available for containers and pods.
 | 
			
		||||
# If this is changed, a lock renumber must be performed (e.g. with the
 | 
			
		||||
# 'podman system renumber' command).
 | 
			
		||||
#
 | 
			
		||||
# num_locks = 2048
 | 
			
		||||
 | 
			
		||||
# Directory for persistent libpod files (database, etc)
 | 
			
		||||
# By default, this will be configured relative to where the containers/storage
 | 
			
		||||
# stores containers
 | 
			
		||||
# Uncomment to change location from this default
 | 
			
		||||
#
 | 
			
		||||
# static_dir = "/var/lib/containers/storage/libpod"
 | 
			
		||||
 | 
			
		||||
# Directory for temporary files. Must be tmpfs (wiped after reboot)
 | 
			
		||||
#
 | 
			
		||||
# tmp_dir = "/var/run/libpod"
 | 
			
		||||
 | 
			
		||||
# Directory for libpod named volumes.
 | 
			
		||||
# By default, this will be configured relative to where containers/storage
 | 
			
		||||
# stores containers.
 | 
			
		||||
# Uncomment to change location from this default.
 | 
			
		||||
#
 | 
			
		||||
# volume_path = "/var/lib/containers/storage/volumes"
 | 
			
		||||
 | 
			
		||||
# Default OCI runtime
 | 
			
		||||
#
 | 
			
		||||
# runtime = "runc"
 | 
			
		||||
 | 
			
		||||
# List of the OCI runtimes that support --format=json.  When json is supported
 | 
			
		||||
# libpod will use it for reporting nicer errors.
 | 
			
		||||
#
 | 
			
		||||
# runtime_supports_json = ["crun", "runc"]
 | 
			
		||||
 | 
			
		||||
# Paths to look for a valid OCI runtime (runc, runv, etc)
 | 
			
		||||
[libpod.runtimes]
 | 
			
		||||
# runc = [
 | 
			
		||||
#        "/usr/bin/runc",
 | 
			
		||||
#        "/usr/sbin/runc",
 | 
			
		||||
#        "/usr/local/bin/runc",
 | 
			
		||||
#        "/usr/local/sbin/runc",
 | 
			
		||||
#        "/sbin/runc",
 | 
			
		||||
#        "/bin/runc",
 | 
			
		||||
#        "/usr/lib/cri-o-runc/sbin/runc",
 | 
			
		||||
# ]
 | 
			
		||||
 | 
			
		||||
# crun = [
 | 
			
		||||
#            "/usr/bin/crun",
 | 
			
		||||
#            "/usr/sbin/crun",
 | 
			
		||||
#            "/usr/local/bin/crun",
 | 
			
		||||
#            "/usr/local/sbin/crun",
 | 
			
		||||
#            "/sbin/crun",
 | 
			
		||||
#            "/bin/crun",
 | 
			
		||||
#            "/run/current-system/sw/bin/crun",
 | 
			
		||||
# ]
 | 
			
		||||
 | 
			
		||||
# The [libpod.runtimes] table MUST be the last entry in this file.
 | 
			
		||||
# (Unless another table is added)
 | 
			
		||||
# TOML does not provide a way to end a table other than a further table being
 | 
			
		||||
# defined, so every key hereafter will be part of [runtimes] and not the main
 | 
			
		||||
# config.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,344 @@
 | 
			
		|||
package config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"github.com/containers/common/pkg/unshare"
 | 
			
		||||
	"github.com/containers/storage"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// _conmonMinMajorVersion is the major version required for conmon.
 | 
			
		||||
	_conmonMinMajorVersion = 2
 | 
			
		||||
 | 
			
		||||
	// _conmonMinMinorVersion is the minor version required for conmon.
 | 
			
		||||
	_conmonMinMinorVersion = 0
 | 
			
		||||
 | 
			
		||||
	// _conmonMinPatchVersion is the sub-minor version required for conmon.
 | 
			
		||||
	_conmonMinPatchVersion = 1
 | 
			
		||||
 | 
			
		||||
	// _conmonVersionFormatErr is used when the expected versio-format of conmon
 | 
			
		||||
	// has changed.
 | 
			
		||||
	_conmonVersionFormatErr = "conmon version changed format"
 | 
			
		||||
 | 
			
		||||
	// _defaultGraphRoot points to the default path of the graph root.
 | 
			
		||||
	_defaultGraphRoot = "/var/lib/containers/storage"
 | 
			
		||||
 | 
			
		||||
	// _defaultTransport is a prefix that we apply to an image name to check
 | 
			
		||||
	// docker hub first for the image.
 | 
			
		||||
	_defaultTransport = "docker://"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// DefaultInitPath is the default path to the container-init binary
 | 
			
		||||
	DefaultInitPath = "/usr/libexec/podman/catatonit"
 | 
			
		||||
	// DefaultInfraImage to use for infra container
 | 
			
		||||
	DefaultInfraImage = "k8s.gcr.io/pause:3.1"
 | 
			
		||||
	// DefaultInfraCommand to be run in an infra container
 | 
			
		||||
	DefaultInfraCommand = "/pause"
 | 
			
		||||
	// DefaultRootlessSHMLockPath is the default path for rootless SHM locks
 | 
			
		||||
	DefaultRootlessSHMLockPath = "/libpod_rootless_lock"
 | 
			
		||||
	// DefaultDetachKeys is the default keys sequence for detaching a
 | 
			
		||||
	// container
 | 
			
		||||
	DefaultDetachKeys = "ctrl-p,ctrl-q"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// ErrConmonOutdated indicates the version of conmon found (whether via the configuration or $PATH)
 | 
			
		||||
	// is out of date for the current podman version
 | 
			
		||||
	ErrConmonOutdated = errors.New("outdated conmon version")
 | 
			
		||||
	// ErrInvalidArg indicates that an invalid argument was passed
 | 
			
		||||
	ErrInvalidArg = errors.New("invalid argument")
 | 
			
		||||
	// DefaultHooksDirs defines the default hooks directory
 | 
			
		||||
	DefaultHooksDirs = []string{"/usr/share/containers/oci/hooks.d"}
 | 
			
		||||
	// DefaultCapabilities for the default_capabilities option in the containers.conf file
 | 
			
		||||
	DefaultCapabilities = []string{
 | 
			
		||||
		"CAP_AUDIT_WRITE",
 | 
			
		||||
		"CAP_CHOWN",
 | 
			
		||||
		"CAP_DAC_OVERRIDE",
 | 
			
		||||
		"CAP_FOWNER",
 | 
			
		||||
		"CAP_FSETID",
 | 
			
		||||
		"CAP_KILL",
 | 
			
		||||
		"CAP_MKNOD",
 | 
			
		||||
		"CAP_NET_BIND_SERVICE",
 | 
			
		||||
		"CAP_NET_RAW",
 | 
			
		||||
		"CAP_SETGID",
 | 
			
		||||
		"CAP_SETPCAP",
 | 
			
		||||
		"CAP_SETUID",
 | 
			
		||||
		"CAP_SYS_CHROOT",
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// EtcDir is the sysconfdir where podman should look for system config files.
 | 
			
		||||
	// It can be overridden at build time.
 | 
			
		||||
	_etcDir = "/etc"
 | 
			
		||||
	// InstallPrefix is the prefix where podman will be installed.
 | 
			
		||||
	// It can be overridden at build time.
 | 
			
		||||
	_installPrefix = "/usr"
 | 
			
		||||
	// CgroupfsCgroupsManager represents cgroupfs native cgroup manager
 | 
			
		||||
	CgroupfsCgroupsManager = "cgroupfs"
 | 
			
		||||
	// DefaultApparmorProfile  specifies the default apparmor profile for the container.
 | 
			
		||||
	DefaultApparmorProfile = "container-default"
 | 
			
		||||
	// SystemdCgroupsManager represents systemd native cgroup manager
 | 
			
		||||
	SystemdCgroupsManager = "systemd"
 | 
			
		||||
	// DefaultLogDriver is the default type of log files
 | 
			
		||||
	DefaultLogDriver = "k8s-file"
 | 
			
		||||
	// DefaultLogSizeMax is the default value for the maximum log size
 | 
			
		||||
	// allowed for a container. Negative values mean that no limit is imposed.
 | 
			
		||||
	DefaultLogSizeMax = -1
 | 
			
		||||
	// DefaultPidsLimit is the default value for maximum number of processes
 | 
			
		||||
	// allowed inside a container
 | 
			
		||||
	DefaultPidsLimit = 2048
 | 
			
		||||
	// DefaultRootlessSignaturePolicyPath is the default value for the
 | 
			
		||||
	// rootless policy.json file.
 | 
			
		||||
	DefaultRootlessSignaturePolicyPath = ".config/containers/policy.json"
 | 
			
		||||
	// DefaultShmSize default value
 | 
			
		||||
	DefaultShmSize = "65536k"
 | 
			
		||||
	// DefaultUserNSSize default value
 | 
			
		||||
	DefaultUserNSSize = 65536
 | 
			
		||||
	// OCIBufSize limits maximum LogSizeMax
 | 
			
		||||
	OCIBufSize = 8192
 | 
			
		||||
	// SeccompOverridePath if this exists it overrides the default seccomp path.
 | 
			
		||||
	SeccompOverridePath = _etcDir + "/containers/seccomp.json"
 | 
			
		||||
	// SeccompDefaultPath defines the default seccomp path.
 | 
			
		||||
	SeccompDefaultPath = _installPrefix + "/share/containers/seccomp.json"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DefaultConfig defines the default values from containers.conf
 | 
			
		||||
func DefaultConfig() (*Config, error) {
 | 
			
		||||
 | 
			
		||||
	defaultLibpodConfig, err := defaultConfigFromMemory()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var signaturePolicyPath string
 | 
			
		||||
	netns := "bridge"
 | 
			
		||||
	if unshare.IsRootless() {
 | 
			
		||||
		home, err := unshare.HomeDir()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		sigPath := filepath.Join(home, DefaultRootlessSignaturePolicyPath)
 | 
			
		||||
		if _, err := os.Stat(sigPath); err == nil {
 | 
			
		||||
			signaturePolicyPath = sigPath
 | 
			
		||||
		}
 | 
			
		||||
		netns = "slirp4netns"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &Config{
 | 
			
		||||
		Containers: ContainersConfig{
 | 
			
		||||
			AdditionalDevices:     []string{},
 | 
			
		||||
			AdditionalVolumes:     []string{},
 | 
			
		||||
			AdditionalAnnotations: []string{},
 | 
			
		||||
			ApparmorProfile:       DefaultApparmorProfile,
 | 
			
		||||
			CgroupManager:         SystemdCgroupsManager,
 | 
			
		||||
			CgroupNS:              "private",
 | 
			
		||||
			DefaultCapabilities:   DefaultCapabilities,
 | 
			
		||||
			DefaultSysctls:        []string{},
 | 
			
		||||
			DefaultUlimits:        getDefaultProcessLimits(),
 | 
			
		||||
			DNSServers:            []string{},
 | 
			
		||||
			DNSOptions:            []string{},
 | 
			
		||||
			DNSSearches:           []string{},
 | 
			
		||||
			EnableLabeling:        selinuxEnabled(),
 | 
			
		||||
			Env: []string{
 | 
			
		||||
				"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
 | 
			
		||||
			},
 | 
			
		||||
			EnvHost:             false,
 | 
			
		||||
			HTTPProxy:           false,
 | 
			
		||||
			Init:                false,
 | 
			
		||||
			InitPath:            "",
 | 
			
		||||
			IPCNS:               "private",
 | 
			
		||||
			LogDriver:           DefaultLogDriver,
 | 
			
		||||
			LogSizeMax:          DefaultLogSizeMax,
 | 
			
		||||
			NetNS:               netns,
 | 
			
		||||
			NoHosts:             false,
 | 
			
		||||
			PidsLimit:           DefaultPidsLimit,
 | 
			
		||||
			PidNS:               "private",
 | 
			
		||||
			SeccompProfile:      SeccompDefaultPath,
 | 
			
		||||
			ShmSize:             DefaultShmSize,
 | 
			
		||||
			SignaturePolicyPath: signaturePolicyPath,
 | 
			
		||||
			UTSNS:               "private",
 | 
			
		||||
			UserNS:              "private",
 | 
			
		||||
			UserNSSize:          DefaultUserNSSize,
 | 
			
		||||
		},
 | 
			
		||||
		Network: NetworkConfig{
 | 
			
		||||
			DefaultNetwork:   "podman",
 | 
			
		||||
			NetworkConfigDir: cniConfigDir,
 | 
			
		||||
			CNIPluginDirs:    cniBinDir,
 | 
			
		||||
		},
 | 
			
		||||
		Libpod: *defaultLibpodConfig,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// defaultConfigFromMemory returns a default libpod configuration. Note that the
 | 
			
		||||
// config is different for root and rootless. It also parses the storage.conf.
 | 
			
		||||
func defaultConfigFromMemory() (*LibpodConfig, error) {
 | 
			
		||||
	c := new(LibpodConfig)
 | 
			
		||||
	tmp, err := defaultTmpDir()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	c.TmpDir = tmp
 | 
			
		||||
 | 
			
		||||
	c.EventsLogFilePath = filepath.Join(c.TmpDir, "events", "events.log")
 | 
			
		||||
 | 
			
		||||
	storeOpts, err := storage.DefaultStoreOptions(unshare.IsRootless(), unshare.GetRootlessUID())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if storeOpts.GraphRoot == "" {
 | 
			
		||||
		logrus.Warnf("Storage configuration is unset - using hardcoded default graph root %q", _defaultGraphRoot)
 | 
			
		||||
		storeOpts.GraphRoot = _defaultGraphRoot
 | 
			
		||||
	}
 | 
			
		||||
	c.StaticDir = filepath.Join(storeOpts.GraphRoot, "libpod")
 | 
			
		||||
	c.VolumePath = filepath.Join(storeOpts.GraphRoot, "volumes")
 | 
			
		||||
	c.StorageConfig = storeOpts
 | 
			
		||||
 | 
			
		||||
	c.HooksDir = DefaultHooksDirs
 | 
			
		||||
	c.ImageDefaultTransport = _defaultTransport
 | 
			
		||||
	c.StateType = BoltDBStateStore
 | 
			
		||||
 | 
			
		||||
	c.OCIRuntime = "runc"
 | 
			
		||||
	// If we're running on cgroups v2, default to using crun.
 | 
			
		||||
	if onCgroupsv2, _ := isCgroup2UnifiedMode(); onCgroupsv2 {
 | 
			
		||||
		c.OCIRuntime = "crun"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.OCIRuntimes = map[string][]string{
 | 
			
		||||
		"runc": {
 | 
			
		||||
			"/usr/bin/runc",
 | 
			
		||||
			"/usr/sbin/runc",
 | 
			
		||||
			"/usr/local/bin/runc",
 | 
			
		||||
			"/usr/local/sbin/runc",
 | 
			
		||||
			"/sbin/runc",
 | 
			
		||||
			"/bin/runc",
 | 
			
		||||
			"/usr/lib/cri-o-runc/sbin/runc",
 | 
			
		||||
			"/run/current-system/sw/bin/runc",
 | 
			
		||||
		},
 | 
			
		||||
		"crun": {
 | 
			
		||||
			"/usr/bin/crun",
 | 
			
		||||
			"/usr/sbin/crun",
 | 
			
		||||
			"/usr/local/bin/crun",
 | 
			
		||||
			"/usr/local/sbin/crun",
 | 
			
		||||
			"/sbin/crun",
 | 
			
		||||
			"/bin/crun",
 | 
			
		||||
			"/run/current-system/sw/bin/crun",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	c.ConmonEnvVars = []string{
 | 
			
		||||
		"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
 | 
			
		||||
	}
 | 
			
		||||
	c.ConmonPath = []string{
 | 
			
		||||
		"/usr/libexec/podman/conmon",
 | 
			
		||||
		"/usr/local/libexec/podman/conmon",
 | 
			
		||||
		"/usr/local/lib/podman/conmon",
 | 
			
		||||
		"/usr/bin/conmon",
 | 
			
		||||
		"/usr/sbin/conmon",
 | 
			
		||||
		"/usr/local/bin/conmon",
 | 
			
		||||
		"/usr/local/sbin/conmon",
 | 
			
		||||
		"/run/current-system/sw/bin/conmon",
 | 
			
		||||
	}
 | 
			
		||||
	c.RuntimeSupportsJSON = []string{
 | 
			
		||||
		"crun",
 | 
			
		||||
		"runc",
 | 
			
		||||
	}
 | 
			
		||||
	c.RuntimeSupportsNoCgroups = []string{"crun"}
 | 
			
		||||
	c.InitPath = DefaultInitPath
 | 
			
		||||
	c.NoPivotRoot = false
 | 
			
		||||
 | 
			
		||||
	c.InfraCommand = DefaultInfraCommand
 | 
			
		||||
	c.InfraImage = DefaultInfraImage
 | 
			
		||||
	c.EnablePortReservation = true
 | 
			
		||||
	c.NumLocks = 2048
 | 
			
		||||
	c.EventsLogger = "journald"
 | 
			
		||||
	c.DetachKeys = DefaultDetachKeys
 | 
			
		||||
	c.SDNotify = false
 | 
			
		||||
	// TODO - ideally we should expose a `type LockType string` along with
 | 
			
		||||
	// constants.
 | 
			
		||||
	c.LockType = "shm"
 | 
			
		||||
 | 
			
		||||
	return c, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func defaultTmpDir() (string, error) {
 | 
			
		||||
	if !unshare.IsRootless() {
 | 
			
		||||
		return "/var/run/libpod", nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	runtimeDir, err := getRuntimeDir()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	libpodRuntimeDir := filepath.Join(runtimeDir, "libpod")
 | 
			
		||||
 | 
			
		||||
	if err := os.Mkdir(libpodRuntimeDir, 0700|os.ModeSticky); err != nil {
 | 
			
		||||
		if !os.IsExist(err) {
 | 
			
		||||
			return "", errors.Wrapf(err, "cannot mkdir %s", libpodRuntimeDir)
 | 
			
		||||
		} else if err := os.Chmod(libpodRuntimeDir, 0700|os.ModeSticky); err != nil {
 | 
			
		||||
			// The directory already exist, just set the sticky bit
 | 
			
		||||
			return "", errors.Wrapf(err, "could not set sticky bit on %s", libpodRuntimeDir)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return filepath.Join(libpodRuntimeDir, "tmp"), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// probeConmon calls conmon --version and verifies it is a new enough version for
 | 
			
		||||
// the runtime expectations the container engine currently has.
 | 
			
		||||
func probeConmon(conmonBinary string) error {
 | 
			
		||||
	cmd := exec.Command(conmonBinary, "--version")
 | 
			
		||||
	var out bytes.Buffer
 | 
			
		||||
	cmd.Stdout = &out
 | 
			
		||||
	err := cmd.Run()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	r := regexp.MustCompile(`^conmon version (?P<Major>\d+).(?P<Minor>\d+).(?P<Patch>\d+)`)
 | 
			
		||||
 | 
			
		||||
	matches := r.FindStringSubmatch(out.String())
 | 
			
		||||
	if len(matches) != 4 {
 | 
			
		||||
		return errors.Wrap(err, _conmonVersionFormatErr)
 | 
			
		||||
	}
 | 
			
		||||
	major, err := strconv.Atoi(matches[1])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errors.Wrap(err, _conmonVersionFormatErr)
 | 
			
		||||
	}
 | 
			
		||||
	if major < _conmonMinMajorVersion {
 | 
			
		||||
		return ErrConmonOutdated
 | 
			
		||||
	}
 | 
			
		||||
	if major > _conmonMinMajorVersion {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	minor, err := strconv.Atoi(matches[2])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errors.Wrap(err, _conmonVersionFormatErr)
 | 
			
		||||
	}
 | 
			
		||||
	if minor < _conmonMinMinorVersion {
 | 
			
		||||
		return ErrConmonOutdated
 | 
			
		||||
	}
 | 
			
		||||
	if minor > _conmonMinMinorVersion {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	patch, err := strconv.Atoi(matches[3])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errors.Wrap(err, _conmonVersionFormatErr)
 | 
			
		||||
	}
 | 
			
		||||
	if patch < _conmonMinPatchVersion {
 | 
			
		||||
		return ErrConmonOutdated
 | 
			
		||||
	}
 | 
			
		||||
	if patch > _conmonMinPatchVersion {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
package config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"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 = st.Type == unix.CGROUP2_SUPER_MAGIC, nil
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	oldMaxSize = uint64(1048576)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// getDefaultProcessLimits returns the nproc for the current process in ulimits format
 | 
			
		||||
// Note that nfile sometimes cannot be set to unlimited, and the limit is hardcoded
 | 
			
		||||
// to (oldMaxSize) 1048576 (2^20), see: http://stackoverflow.com/a/1213069/1811501
 | 
			
		||||
// In rootless containers this will fail, and the process will just use its current limits
 | 
			
		||||
func getDefaultProcessLimits() []string {
 | 
			
		||||
	rlim := unix.Rlimit{Cur: oldMaxSize, Max: oldMaxSize}
 | 
			
		||||
	oldrlim := rlim
 | 
			
		||||
	// Attempt to set file limit and process limit to pid_max in OS
 | 
			
		||||
	dat, err := ioutil.ReadFile("/proc/sys/kernel/pid_max")
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		val := strings.TrimSuffix(string(dat), "\n")
 | 
			
		||||
		max, err := strconv.ParseUint(val, 10, 64)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			rlim = unix.Rlimit{Cur: uint64(max), Max: uint64(max)}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	defaultLimits := []string{}
 | 
			
		||||
	if err := unix.Setrlimit(unix.RLIMIT_NPROC, &rlim); err == nil {
 | 
			
		||||
		defaultLimits = append(defaultLimits, fmt.Sprintf("nproc=%d:%d", rlim.Cur, rlim.Max))
 | 
			
		||||
	} else {
 | 
			
		||||
		if err := unix.Setrlimit(unix.RLIMIT_NPROC, &oldrlim); err == nil {
 | 
			
		||||
			defaultLimits = append(defaultLimits, fmt.Sprintf("nproc=%d:%d", oldrlim.Cur, oldrlim.Max))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return defaultLimits
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								vendor/github.com/containers/common/pkg/config/default_unsupported.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										13
									
								
								vendor/github.com/containers/common/pkg/config/default_unsupported.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
// +build !linux
 | 
			
		||||
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
// isCgroup2UnifiedMode returns whether we are running in cgroup2 mode.
 | 
			
		||||
func isCgroup2UnifiedMode() (isUnified bool, isUnifiedErr error) {
 | 
			
		||||
	return false, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getDefaultProcessLimits returns the nofile and nproc for the current process in ulimits format
 | 
			
		||||
func getDefaultProcessLimits() []string {
 | 
			
		||||
	return []string{}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,69 @@
 | 
			
		|||
// +build linux darwin
 | 
			
		||||
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"github.com/containers/common/pkg/unshare"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	rootlessRuntimeDirOnce sync.Once
 | 
			
		||||
	rootlessRuntimeDir     string
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// getRuntimeDir returns the runtime directory
 | 
			
		||||
func getRuntimeDir() (string, error) {
 | 
			
		||||
	var rootlessRuntimeDirError error
 | 
			
		||||
 | 
			
		||||
	rootlessRuntimeDirOnce.Do(func() {
 | 
			
		||||
		runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
 | 
			
		||||
		uid := fmt.Sprintf("%d", unshare.GetRootlessUID())
 | 
			
		||||
		if runtimeDir == "" {
 | 
			
		||||
			tmpDir := filepath.Join("/run", "user", uid)
 | 
			
		||||
			if err := os.MkdirAll(tmpDir, 0700); err != nil {
 | 
			
		||||
				logrus.Debugf("unable to make temp dir %s", tmpDir)
 | 
			
		||||
			}
 | 
			
		||||
			st, err := os.Stat(tmpDir)
 | 
			
		||||
			if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
 | 
			
		||||
				runtimeDir = tmpDir
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if runtimeDir == "" {
 | 
			
		||||
			tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("run-%s", uid))
 | 
			
		||||
			if err := os.MkdirAll(tmpDir, 0700); err != nil {
 | 
			
		||||
				logrus.Debugf("unable to make temp dir %s", tmpDir)
 | 
			
		||||
			}
 | 
			
		||||
			st, err := os.Stat(tmpDir)
 | 
			
		||||
			if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
 | 
			
		||||
				runtimeDir = tmpDir
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if runtimeDir == "" {
 | 
			
		||||
			home := os.Getenv("HOME")
 | 
			
		||||
			if home == "" {
 | 
			
		||||
				rootlessRuntimeDirError = fmt.Errorf("neither XDG_RUNTIME_DIR nor HOME was set non-empty")
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			resolvedHome, err := filepath.EvalSymlinks(home)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				rootlessRuntimeDirError = errors.Wrapf(err, "cannot resolve %s", home)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			runtimeDir = filepath.Join(resolvedHome, "rundir")
 | 
			
		||||
		}
 | 
			
		||||
		rootlessRuntimeDir = runtimeDir
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	if rootlessRuntimeDirError != nil {
 | 
			
		||||
		return "", rootlessRuntimeDirError
 | 
			
		||||
	}
 | 
			
		||||
	return rootlessRuntimeDir, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
// +build windows
 | 
			
		||||
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// getRuntimeDir returns the runtime directory
 | 
			
		||||
func getRuntimeDir() (string, error) {
 | 
			
		||||
	return "", errors.New("this function is not implemented for windows")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								vendor/github.com/containers/common/pkg/unshare/getenv_linux_cgo.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										22
									
								
								vendor/github.com/containers/common/pkg/unshare/getenv_linux_cgo.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
// +build linux,cgo
 | 
			
		||||
 | 
			
		||||
package unshare
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
#cgo remoteclient CFLAGS: -Wall -Werror
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
*/
 | 
			
		||||
import "C"
 | 
			
		||||
 | 
			
		||||
func getenv(name string) string {
 | 
			
		||||
	cName := C.CString(name)
 | 
			
		||||
	defer C.free(unsafe.Pointer(cName))
 | 
			
		||||
 | 
			
		||||
	value := C.GoString(C.getenv(cName))
 | 
			
		||||
 | 
			
		||||
	return value
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								vendor/github.com/containers/common/pkg/unshare/getenv_linux_nocgo.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										11
									
								
								vendor/github.com/containers/common/pkg/unshare/getenv_linux_nocgo.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
// +build linux,!cgo
 | 
			
		||||
 | 
			
		||||
package unshare
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func getenv(name string) string {
 | 
			
		||||
	return os.Getenv(name)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -50,6 +50,31 @@ func Command(args ...string) *Cmd {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getRootlessUID() int {
 | 
			
		||||
	uidEnv := getenv("_CONTAINERS_ROOTLESS_UID")
 | 
			
		||||
	if uidEnv != "" {
 | 
			
		||||
		u, _ := strconv.Atoi(uidEnv)
 | 
			
		||||
		return u
 | 
			
		||||
	}
 | 
			
		||||
	return os.Geteuid()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getRootlessGID() int {
 | 
			
		||||
	gidEnv := getenv("_CONTAINERS_ROOTLESS_GID")
 | 
			
		||||
	if gidEnv != "" {
 | 
			
		||||
		u, _ := strconv.Atoi(gidEnv)
 | 
			
		||||
		return u
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* If the _CONTAINERS_ROOTLESS_UID is set, assume the gid==uid.  */
 | 
			
		||||
	uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID")
 | 
			
		||||
	if uidEnv != "" {
 | 
			
		||||
		u, _ := strconv.Atoi(uidEnv)
 | 
			
		||||
		return u
 | 
			
		||||
	}
 | 
			
		||||
	return os.Getegid()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Cmd) Start() error {
 | 
			
		||||
	runtime.LockOSThread()
 | 
			
		||||
	defer runtime.UnlockOSThread()
 | 
			
		||||
| 
						 | 
				
			
			@ -61,10 +86,10 @@ func (c *Cmd) Start() error {
 | 
			
		|||
	c.Env = append(c.Env, fmt.Sprintf("_Containers-unshare=%d", c.UnshareFlags))
 | 
			
		||||
 | 
			
		||||
	// Please the libpod "rootless" package to find the expected env variables.
 | 
			
		||||
	if os.Geteuid() != 0 {
 | 
			
		||||
	if IsRootless() {
 | 
			
		||||
		c.Env = append(c.Env, "_CONTAINERS_USERNS_CONFIGURED=done")
 | 
			
		||||
		c.Env = append(c.Env, fmt.Sprintf("_CONTAINERS_ROOTLESS_UID=%d", os.Geteuid()))
 | 
			
		||||
		c.Env = append(c.Env, fmt.Sprintf("_CONTAINERS_ROOTLESS_GID=%d", os.Getegid()))
 | 
			
		||||
		c.Env = append(c.Env, fmt.Sprintf("_CONTAINERS_ROOTLESS_UID=%d", getRootlessUID()))
 | 
			
		||||
		c.Env = append(c.Env, fmt.Sprintf("_CONTAINERS_ROOTLESS_GID=%d", getRootlessGID()))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Create the pipe for reading the child's PID.
 | 
			
		||||
| 
						 | 
				
			
			@ -318,14 +343,14 @@ const (
 | 
			
		|||
// IsRootless tells us if we are running in rootless mode
 | 
			
		||||
func IsRootless() bool {
 | 
			
		||||
	isRootlessOnce.Do(func() {
 | 
			
		||||
		isRootless = os.Geteuid() != 0 || os.Getenv(UsernsEnvName) != ""
 | 
			
		||||
		isRootless = getRootlessUID() != 0 || getenv(UsernsEnvName) != ""
 | 
			
		||||
	})
 | 
			
		||||
	return isRootless
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetRootlessUID returns the UID of the user in the parent userNS
 | 
			
		||||
func GetRootlessUID() int {
 | 
			
		||||
	uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID")
 | 
			
		||||
	uidEnv := getenv("_CONTAINERS_ROOTLESS_UID")
 | 
			
		||||
	if uidEnv != "" {
 | 
			
		||||
		u, _ := strconv.Atoi(uidEnv)
 | 
			
		||||
		return u
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,5 +25,6 @@ linters:
 | 
			
		|||
    - gochecknoglobals
 | 
			
		||||
    - gocognit
 | 
			
		||||
    - goconst
 | 
			
		||||
    - gomnd
 | 
			
		||||
    - lll
 | 
			
		||||
    - wsl
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ language: go
 | 
			
		|||
go:
 | 
			
		||||
  - 1.12.x
 | 
			
		||||
  - 1.13.x
 | 
			
		||||
  - 1.14rc1
 | 
			
		||||
os:
 | 
			
		||||
  - linux
 | 
			
		||||
  - osx
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
Copyright (c) 2013-2019, go-dockerclient authors
 | 
			
		||||
Copyright (c) 2013-2020, go-dockerclient authors
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
 | 
			
		||||
[](https://travis-ci.com/fsouza/go-dockerclient)
 | 
			
		||||
[](https://ci.appveyor.com/project/fsouza/go-dockerclient)
 | 
			
		||||
[](https://godoc.org/github.com/fsouza/go-dockerclient)
 | 
			
		||||
[](https://pkg.go.dev/github.com/docker/docker/api/types?tab=doc#AuthConfig)
 | 
			
		||||
 | 
			
		||||
This package presents a client for the Docker remote API. It also provides
 | 
			
		||||
support for the extensions in the [Swarm API](https://docs.docker.com/swarm/swarm-api/).
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,8 +7,9 @@ environment:
 | 
			
		|||
  GOPROXY: https://proxy.golang.org
 | 
			
		||||
  GO111MODULE: on
 | 
			
		||||
  matrix:
 | 
			
		||||
    - GOVERSION: "1.12.13"
 | 
			
		||||
    - GOVERSION: "1.13.4"
 | 
			
		||||
    - GOVERSION: "1.12.14"
 | 
			
		||||
    - GOVERSION: "1.13.5"
 | 
			
		||||
    - GOVERSION: "1.14rc1"
 | 
			
		||||
install:
 | 
			
		||||
  - choco install make
 | 
			
		||||
  - set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ type AuthConfiguration struct {
 | 
			
		|||
	ServerAddress string `json:"serveraddress,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// IdentityToken can be supplied with the identitytoken response of the AuthCheck call
 | 
			
		||||
	// see https://godoc.org/github.com/docker/docker/api/types#AuthConfig
 | 
			
		||||
	// see https://pkg.go.dev/github.com/docker/docker/api/types?tab=doc#AuthConfig
 | 
			
		||||
	// It can be used in place of password not in conjunction with it
 | 
			
		||||
	IdentityToken string `json:"identitytoken,omitempty"`
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -170,9 +170,14 @@ func authConfigs(confs map[string]dockerConfig) (*AuthConfigurations, error) {
 | 
			
		|||
		if conf.Auth == "" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// support both padded and unpadded encoding
 | 
			
		||||
		data, err := base64.StdEncoding.DecodeString(conf.Auth)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
			data, err = base64.StdEncoding.WithPadding(base64.NoPadding).DecodeString(conf.Auth)
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, errors.New("error decoding plaintext credentials")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		userpass := strings.SplitN(string(data), ":", 2)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -788,6 +788,7 @@ type HostConfig struct {
 | 
			
		|||
	CPUPeriod            int64                  `json:"CpuPeriod,omitempty" yaml:"CpuPeriod,omitempty" toml:"CpuPeriod,omitempty"`
 | 
			
		||||
	CPURealtimePeriod    int64                  `json:"CpuRealtimePeriod,omitempty" yaml:"CpuRealtimePeriod,omitempty" toml:"CpuRealtimePeriod,omitempty"`
 | 
			
		||||
	CPURealtimeRuntime   int64                  `json:"CpuRealtimeRuntime,omitempty" yaml:"CpuRealtimeRuntime,omitempty" toml:"CpuRealtimeRuntime,omitempty"`
 | 
			
		||||
	NanoCPUs             int64                  `json:"NanoCpus,omitempty" yaml:"NanoCpus,omitempty" toml:"NanoCpus,omitempty"`
 | 
			
		||||
	BlkioWeight          int64                  `json:"BlkioWeight,omitempty" yaml:"BlkioWeight,omitempty" toml:"BlkioWeight,omitempty"`
 | 
			
		||||
	BlkioWeightDevice    []BlockWeight          `json:"BlkioWeightDevice,omitempty" yaml:"BlkioWeightDevice,omitempty" toml:"BlkioWeightDevice,omitempty"`
 | 
			
		||||
	BlkioDeviceReadBps   []BlockLimit           `json:"BlkioDeviceReadBps,omitempty" yaml:"BlkioDeviceReadBps,omitempty" toml:"BlkioDeviceReadBps,omitempty"`
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,7 @@ require (
 | 
			
		|||
	github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23
 | 
			
		||||
	github.com/docker/go-connections v0.4.0 // indirect
 | 
			
		||||
	github.com/docker/go-units v0.4.0
 | 
			
		||||
	github.com/google/go-cmp v0.3.1
 | 
			
		||||
	github.com/google/go-cmp v0.4.0
 | 
			
		||||
	github.com/gorilla/mux v1.7.3
 | 
			
		||||
	github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect
 | 
			
		||||
	github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,8 +41,8 @@ github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg
 | 
			
		|||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 | 
			
		||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 | 
			
		||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
 | 
			
		||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
 | 
			
		||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
			
		||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
 | 
			
		||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 | 
			
		||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 | 
			
		||||
| 
						 | 
				
			
			@ -119,6 +119,8 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
 | 
			
		|||
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-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -147,6 +147,7 @@ func (c *Client) InspectService(id string) (*swarm.Service, error) {
 | 
			
		|||
// See https://goo.gl/DwvNMd for more details.
 | 
			
		||||
type ListServicesOptions struct {
 | 
			
		||||
	Filters map[string][]string
 | 
			
		||||
	Status  bool
 | 
			
		||||
	Context context.Context
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -106,7 +106,6 @@ func copyTLSConfig(cfg *tls.Config) *tls.Config {
 | 
			
		|||
		InsecureSkipVerify:       cfg.InsecureSkipVerify, //nolint:gosec
 | 
			
		||||
		MaxVersion:               cfg.MaxVersion,
 | 
			
		||||
		MinVersion:               cfg.MinVersion,
 | 
			
		||||
		NameToCertificate:        cfg.NameToCertificate,
 | 
			
		||||
		NextProtos:               cfg.NextProtos,
 | 
			
		||||
		PreferServerCipherSuites: cfg.PreferServerCipherSuites,
 | 
			
		||||
		Rand:                     cfg.Rand,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
language: go
 | 
			
		||||
go:
 | 
			
		||||
 - 1.6
 | 
			
		||||
 - 1.7
 | 
			
		||||
 - 1.8
 | 
			
		||||
 - 1.9
 | 
			
		||||
 - "1.10"
 | 
			
		||||
 - 1.9.x
 | 
			
		||||
 - 1.10.x
 | 
			
		||||
 - 1.11.x
 | 
			
		||||
 - 1.12.x
 | 
			
		||||
 - 1.13.x
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
 - go test -v -race ./...
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
This source code includes following third party code
 | 
			
		||||
 | 
			
		||||
- ipsock_linux.go : licensed by the Go authors, see GO_LICENSE file for the license which applies to the code
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
module github.com/ishidawataru/sctp
 | 
			
		||||
 | 
			
		||||
go 1.12
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +1,7 @@
 | 
			
		|||
// Copyright 2009 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the GO_LICENSE file.
 | 
			
		||||
 | 
			
		||||
package sctp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,18 @@
 | 
			
		|||
// Copyright 2019 Wataru Ishida. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
// implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package sctp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -678,3 +693,37 @@ func (c *SCTPSndRcvInfoWrappedConn) SetReadDeadline(t time.Time) error {
 | 
			
		|||
func (c *SCTPSndRcvInfoWrappedConn) SetWriteDeadline(t time.Time) error {
 | 
			
		||||
	return c.conn.SetWriteDeadline(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPSndRcvInfoWrappedConn) SetWriteBuffer(bytes int) error {
 | 
			
		||||
	return c.conn.SetWriteBuffer(bytes)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPSndRcvInfoWrappedConn) GetWriteBuffer() (int, error) {
 | 
			
		||||
	return c.conn.GetWriteBuffer()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPSndRcvInfoWrappedConn) SetReadBuffer(bytes int) error {
 | 
			
		||||
	return c.conn.SetReadBuffer(bytes)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPSndRcvInfoWrappedConn) GetReadBuffer() (int, error) {
 | 
			
		||||
	return c.conn.GetReadBuffer()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SocketConfig contains options for the SCTP socket.
 | 
			
		||||
type SocketConfig struct {
 | 
			
		||||
	// If Control is not nil it is called after the socket is created but before
 | 
			
		||||
	// it is bound or connected.
 | 
			
		||||
	Control func(network, address string, c syscall.RawConn) error
 | 
			
		||||
 | 
			
		||||
	// InitMsg is the options to send in the initial SCTP message
 | 
			
		||||
	InitMsg InitMsg
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cfg *SocketConfig) Listen(net string, laddr *SCTPAddr) (*SCTPListener, error) {
 | 
			
		||||
	return listenSCTPExtConfig(net, laddr, cfg.InitMsg, cfg.Control)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cfg *SocketConfig) Dial(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) {
 | 
			
		||||
	return dialSCTPExtConfig(net, laddr, raddr, cfg.InitMsg, cfg.Control)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,18 @@
 | 
			
		|||
// +build linux,!386
 | 
			
		||||
// Copyright 2019 Wataru Ishida. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
// implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package sctp
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +54,23 @@ func getsockopt(fd int, optname, optval, optlen uintptr) (uintptr, uintptr, erro
 | 
			
		|||
	return r0, r1, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type rawConn struct {
 | 
			
		||||
	sockfd int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r rawConn) Control(f func(fd uintptr)) error {
 | 
			
		||||
	f(uintptr(r.sockfd))
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r rawConn) Read(f func(fd uintptr) (done bool)) error {
 | 
			
		||||
	panic("not implemented")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r rawConn) Write(f func(fd uintptr) (done bool)) error {
 | 
			
		||||
	panic("not implemented")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPConn) SCTPWrite(b []byte, info *SndRcvInfo) (int, error) {
 | 
			
		||||
	var cbuf []byte
 | 
			
		||||
	if info != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +145,22 @@ func (c *SCTPConn) Close() error {
 | 
			
		|||
	return syscall.EBADF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPConn) SetWriteBuffer(bytes int) error {
 | 
			
		||||
	return syscall.SetsockoptInt(c.fd(), syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPConn) GetWriteBuffer() (int, error) {
 | 
			
		||||
	return syscall.GetsockoptInt(c.fd(), syscall.SOL_SOCKET, syscall.SO_SNDBUF)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPConn) SetReadBuffer(bytes int) error {
 | 
			
		||||
	return syscall.SetsockoptInt(c.fd(), syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPConn) GetReadBuffer() (int, error) {
 | 
			
		||||
	return syscall.GetsockoptInt(c.fd(), syscall.SOL_SOCKET, syscall.SO_RCVBUF)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ListenSCTP - start listener on specified address/port
 | 
			
		||||
func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
 | 
			
		||||
	return ListenSCTPExt(net, laddr, InitMsg{NumOstreams: SCTP_MAX_STREAM})
 | 
			
		||||
| 
						 | 
				
			
			@ -121,6 +168,11 @@ func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
 | 
			
		|||
 | 
			
		||||
// ListenSCTPExt - start listener on specified address/port with given SCTP options
 | 
			
		||||
func ListenSCTPExt(network string, laddr *SCTPAddr, options InitMsg) (*SCTPListener, error) {
 | 
			
		||||
	return listenSCTPExtConfig(network, laddr, options, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// listenSCTPExtConfig - start listener on specified address/port with given SCTP options and socket configuration
 | 
			
		||||
func listenSCTPExtConfig(network string, laddr *SCTPAddr, options InitMsg, control func(network, address string, c syscall.RawConn) error) (*SCTPListener, error) {
 | 
			
		||||
	af, ipv6only := favoriteAddrFamily(network, laddr, nil, "listen")
 | 
			
		||||
	sock, err := syscall.Socket(
 | 
			
		||||
		af,
 | 
			
		||||
| 
						 | 
				
			
			@ -140,6 +192,12 @@ func ListenSCTPExt(network string, laddr *SCTPAddr, options InitMsg) (*SCTPListe
 | 
			
		|||
	if err = setDefaultSockopts(sock, af, ipv6only); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if control != nil {
 | 
			
		||||
		rc := rawConn{sockfd: sock}
 | 
			
		||||
		if err = control(network, laddr.String(), rc); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	err = setInitOpts(sock, options)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
| 
						 | 
				
			
			@ -191,6 +249,11 @@ func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) {
 | 
			
		|||
 | 
			
		||||
// DialSCTPExt - same as DialSCTP but with given SCTP options
 | 
			
		||||
func DialSCTPExt(network string, laddr, raddr *SCTPAddr, options InitMsg) (*SCTPConn, error) {
 | 
			
		||||
	return dialSCTPExtConfig(network, laddr, raddr, options, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// dialSCTPExtConfig - same as DialSCTP but with given SCTP options and socket configuration
 | 
			
		||||
func dialSCTPExtConfig(network string, laddr, raddr *SCTPAddr, options InitMsg, control func(network, address string, c syscall.RawConn) error) (*SCTPConn, error) {
 | 
			
		||||
	af, ipv6only := favoriteAddrFamily(network, laddr, raddr, "dial")
 | 
			
		||||
	sock, err := syscall.Socket(
 | 
			
		||||
		af,
 | 
			
		||||
| 
						 | 
				
			
			@ -210,6 +273,12 @@ func DialSCTPExt(network string, laddr, raddr *SCTPAddr, options InitMsg) (*SCTP
 | 
			
		|||
	if err = setDefaultSockopts(sock, af, ipv6only); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if control != nil {
 | 
			
		||||
		rc := rawConn{sockfd: sock}
 | 
			
		||||
		if err = control(network, laddr.String(), rc); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	err = setInitOpts(sock, options)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,18 @@
 | 
			
		|||
// +build !linux linux,386
 | 
			
		||||
// Copyright 2019 Wataru Ishida. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
// implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package sctp
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -6,6 +20,7 @@ import (
 | 
			
		|||
	"errors"
 | 
			
		||||
	"net"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var ErrUnsupported = errors.New("SCTP is unsupported on " + runtime.GOOS + "/" + runtime.GOARCH)
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +45,22 @@ func (c *SCTPConn) Close() error {
 | 
			
		|||
	return ErrUnsupported
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPConn) SetWriteBuffer(bytes int) error {
 | 
			
		||||
	return ErrUnsupported
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPConn) GetWriteBuffer() (int, error) {
 | 
			
		||||
	return 0, ErrUnsupported
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPConn) SetReadBuffer(bytes int) error {
 | 
			
		||||
	return ErrUnsupported
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SCTPConn) GetReadBuffer() (int, error) {
 | 
			
		||||
	return 0, ErrUnsupported
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
 | 
			
		||||
	return nil, ErrUnsupported
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -38,6 +69,10 @@ func ListenSCTPExt(net string, laddr *SCTPAddr, options InitMsg) (*SCTPListener,
 | 
			
		|||
	return nil, ErrUnsupported
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func listenSCTPExtConfig(network string, laddr *SCTPAddr, options InitMsg, control func(network, address string, c syscall.RawConn) error) (*SCTPListener, error) {
 | 
			
		||||
	return nil, ErrUnsupported
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ln *SCTPListener) Accept() (net.Conn, error) {
 | 
			
		||||
	return nil, ErrUnsupported
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -57,3 +92,7 @@ func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) {
 | 
			
		|||
func DialSCTPExt(network string, laddr, raddr *SCTPAddr, options InitMsg) (*SCTPConn, error) {
 | 
			
		||||
	return nil, ErrUnsupported
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dialSCTPExtConfig(network string, laddr, raddr *SCTPAddr, options InitMsg, control func(network, address string, c syscall.RawConn) error) (*SCTPConn, error) {
 | 
			
		||||
	return nil, ErrUnsupported
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,22 +4,19 @@
 | 
			
		|||
 | 
			
		||||
// Package xerrors implements functions to manipulate errors.
 | 
			
		||||
//
 | 
			
		||||
// This package supports transitioning to the Go 2 proposal for error values:
 | 
			
		||||
// This package is based on the Go 2 proposal for error values:
 | 
			
		||||
//   https://golang.org/design/29934-error-values
 | 
			
		||||
//
 | 
			
		||||
// Most of the functions and types in this package will be incorporated into the
 | 
			
		||||
// standard library's errors package in Go 1.13; the behavior of this package's
 | 
			
		||||
// Errorf function will be incorporated into the standard library's fmt.Errorf.
 | 
			
		||||
// Use this package to get equivalent behavior in all supported Go versions. For
 | 
			
		||||
// example, create errors using
 | 
			
		||||
// These functions were incorporated into the standard library's errors package
 | 
			
		||||
// in Go 1.13:
 | 
			
		||||
// - Is
 | 
			
		||||
// - As
 | 
			
		||||
// - Unwrap
 | 
			
		||||
//
 | 
			
		||||
//    xerrors.New("write failed")
 | 
			
		||||
// Also, Errorf's %w verb was incorporated into fmt.Errorf.
 | 
			
		||||
//
 | 
			
		||||
// or
 | 
			
		||||
// Use this package to get equivalent behavior in all supported Go versions.
 | 
			
		||||
//
 | 
			
		||||
//    xerrors.Errorf("while reading: %v", err)
 | 
			
		||||
//
 | 
			
		||||
// If you want your error type to participate in the new formatting
 | 
			
		||||
// implementation for %v and %+v, provide it with a Format method that calls
 | 
			
		||||
// xerrors.FormatError, as shown in the example for FormatError.
 | 
			
		||||
// No other features of this package were included in Go 1.13, and at present
 | 
			
		||||
// there are no plans to include any of them.
 | 
			
		||||
package xerrors // import "golang.org/x/xerrors"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,10 +7,14 @@ package xerrors
 | 
			
		|||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/xerrors/internal"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const percentBangString = "%!"
 | 
			
		||||
 | 
			
		||||
// Errorf formats according to a format specifier and returns the string as a
 | 
			
		||||
// value that satisfies error.
 | 
			
		||||
//
 | 
			
		||||
| 
						 | 
				
			
			@ -18,29 +22,71 @@ import (
 | 
			
		|||
// formatted with additional detail enabled. If the last argument is an error
 | 
			
		||||
// the returned error's Format method will return it if the format string ends
 | 
			
		||||
// with ": %s", ": %v", or ": %w". If the last argument is an error and the
 | 
			
		||||
// format string ends with ": %w", the returned error implements Wrapper
 | 
			
		||||
// with an Unwrap method returning it.
 | 
			
		||||
// format string ends with ": %w", the returned error implements an Unwrap
 | 
			
		||||
// method returning it.
 | 
			
		||||
//
 | 
			
		||||
// If the format specifier includes a %w verb with an error operand in a
 | 
			
		||||
// position other than at the end, the returned error will still implement an
 | 
			
		||||
// Unwrap method returning the operand, but the error's Format method will not
 | 
			
		||||
// return the wrapped error.
 | 
			
		||||
//
 | 
			
		||||
// It is invalid to include more than one %w verb or to supply it with an
 | 
			
		||||
// operand that does not implement the error interface. The %w verb is otherwise
 | 
			
		||||
// a synonym for %v.
 | 
			
		||||
func Errorf(format string, a ...interface{}) error {
 | 
			
		||||
	err, wrap := lastError(format, a)
 | 
			
		||||
	format = formatPlusW(format)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)}
 | 
			
		||||
	// Support a ": %[wsv]" suffix, which works well with xerrors.Formatter.
 | 
			
		||||
	wrap := strings.HasSuffix(format, ": %w")
 | 
			
		||||
	idx, format2, ok := parsePercentW(format)
 | 
			
		||||
	percentWElsewhere := !wrap && idx >= 0
 | 
			
		||||
	if !percentWElsewhere && (wrap || strings.HasSuffix(format, ": %s") || strings.HasSuffix(format, ": %v")) {
 | 
			
		||||
		err := errorAt(a, len(a)-1)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)}
 | 
			
		||||
		}
 | 
			
		||||
		// TODO: this is not entirely correct. The error value could be
 | 
			
		||||
		// printed elsewhere in format if it mixes numbered with unnumbered
 | 
			
		||||
		// substitutions. With relatively small changes to doPrintf we can
 | 
			
		||||
		// have it optionally ignore extra arguments and pass the argument
 | 
			
		||||
		// list in its entirety.
 | 
			
		||||
		msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...)
 | 
			
		||||
		frame := Frame{}
 | 
			
		||||
		if internal.EnableTrace {
 | 
			
		||||
			frame = Caller(1)
 | 
			
		||||
		}
 | 
			
		||||
		if wrap {
 | 
			
		||||
			return &wrapError{msg, err, frame}
 | 
			
		||||
		}
 | 
			
		||||
		return &noWrapError{msg, err, frame}
 | 
			
		||||
	}
 | 
			
		||||
	// Support %w anywhere.
 | 
			
		||||
	// TODO: don't repeat the wrapped error's message when %w occurs in the middle.
 | 
			
		||||
	msg := fmt.Sprintf(format2, a...)
 | 
			
		||||
	if idx < 0 {
 | 
			
		||||
		return &noWrapError{msg, nil, Caller(1)}
 | 
			
		||||
	}
 | 
			
		||||
	err := errorAt(a, idx)
 | 
			
		||||
	if !ok || err == nil {
 | 
			
		||||
		// Too many %ws or argument of %w is not an error. Approximate the Go
 | 
			
		||||
		// 1.13 fmt.Errorf message.
 | 
			
		||||
		return &noWrapError{fmt.Sprintf("%sw(%s)", percentBangString, msg), nil, Caller(1)}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// TODO: this is not entirely correct. The error value could be
 | 
			
		||||
	// printed elsewhere in format if it mixes numbered with unnumbered
 | 
			
		||||
	// substitutions. With relatively small changes to doPrintf we can
 | 
			
		||||
	// have it optionally ignore extra arguments and pass the argument
 | 
			
		||||
	// list in its entirety.
 | 
			
		||||
	msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...)
 | 
			
		||||
	frame := Frame{}
 | 
			
		||||
	if internal.EnableTrace {
 | 
			
		||||
		frame = Caller(1)
 | 
			
		||||
	}
 | 
			
		||||
	if wrap {
 | 
			
		||||
		return &wrapError{msg, err, frame}
 | 
			
		||||
	return &wrapError{msg, err, frame}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func errorAt(args []interface{}, i int) error {
 | 
			
		||||
	if i < 0 || i >= len(args) {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return &noWrapError{msg, err, frame}
 | 
			
		||||
	err, ok := args[i].(error)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// formatPlusW is used to avoid the vet check that will barf at %w.
 | 
			
		||||
| 
						 | 
				
			
			@ -48,24 +94,56 @@ func formatPlusW(s string) string {
 | 
			
		|||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func lastError(format string, a []interface{}) (err error, wrap bool) {
 | 
			
		||||
	wrap = strings.HasSuffix(format, ": %w")
 | 
			
		||||
	if !wrap &&
 | 
			
		||||
		!strings.HasSuffix(format, ": %s") &&
 | 
			
		||||
		!strings.HasSuffix(format, ": %v") {
 | 
			
		||||
		return nil, false
 | 
			
		||||
// Return the index of the only %w in format, or -1 if none.
 | 
			
		||||
// Also return a rewritten format string with %w replaced by %v, and
 | 
			
		||||
// false if there is more than one %w.
 | 
			
		||||
// TODO: handle "%[N]w".
 | 
			
		||||
func parsePercentW(format string) (idx int, newFormat string, ok bool) {
 | 
			
		||||
	// Loosely copied from golang.org/x/tools/go/analysis/passes/printf/printf.go.
 | 
			
		||||
	idx = -1
 | 
			
		||||
	ok = true
 | 
			
		||||
	n := 0
 | 
			
		||||
	sz := 0
 | 
			
		||||
	var isW bool
 | 
			
		||||
	for i := 0; i < len(format); i += sz {
 | 
			
		||||
		if format[i] != '%' {
 | 
			
		||||
			sz = 1
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// "%%" is not a format directive.
 | 
			
		||||
		if i+1 < len(format) && format[i+1] == '%' {
 | 
			
		||||
			sz = 2
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		sz, isW = parsePrintfVerb(format[i:])
 | 
			
		||||
		if isW {
 | 
			
		||||
			if idx >= 0 {
 | 
			
		||||
				ok = false
 | 
			
		||||
			} else {
 | 
			
		||||
				idx = n
 | 
			
		||||
			}
 | 
			
		||||
			// "Replace" the last character, the 'w', with a 'v'.
 | 
			
		||||
			p := i + sz - 1
 | 
			
		||||
			format = format[:p] + "v" + format[p+1:]
 | 
			
		||||
		}
 | 
			
		||||
		n++
 | 
			
		||||
	}
 | 
			
		||||
	return idx, format, ok
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	if len(a) == 0 {
 | 
			
		||||
		return nil, false
 | 
			
		||||
// Parse the printf verb starting with a % at s[0].
 | 
			
		||||
// Return how many bytes it occupies and whether the verb is 'w'.
 | 
			
		||||
func parsePrintfVerb(s string) (int, bool) {
 | 
			
		||||
	// Assume only that the directive is a sequence of non-letters followed by a single letter.
 | 
			
		||||
	sz := 0
 | 
			
		||||
	var r rune
 | 
			
		||||
	for i := 1; i < len(s); i += sz {
 | 
			
		||||
		r, sz = utf8.DecodeRuneInString(s[i:])
 | 
			
		||||
		if unicode.IsLetter(r) {
 | 
			
		||||
			return i + sz, r == 'w'
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err, ok := a[len(a)-1].(error)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err, wrap
 | 
			
		||||
	return len(s), false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type noWrapError struct {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,7 +62,7 @@ github.com/containernetworking/plugins/pkg/ns
 | 
			
		|||
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/allocator
 | 
			
		||||
# github.com/containers/buildah v1.13.1
 | 
			
		||||
# github.com/containers/buildah v1.14.1-0.20200219125159-7cd6f7d04842
 | 
			
		||||
github.com/containers/buildah
 | 
			
		||||
github.com/containers/buildah/bind
 | 
			
		||||
github.com/containers/buildah/chroot
 | 
			
		||||
| 
						 | 
				
			
			@ -77,8 +77,9 @@ github.com/containers/buildah/pkg/parse
 | 
			
		|||
github.com/containers/buildah/pkg/secrets
 | 
			
		||||
github.com/containers/buildah/pkg/umask
 | 
			
		||||
github.com/containers/buildah/util
 | 
			
		||||
# github.com/containers/common v0.0.7
 | 
			
		||||
github.com/containers/common/pkg/cgroups
 | 
			
		||||
# github.com/containers/common v0.3.0
 | 
			
		||||
github.com/containers/common/pkg/capabilities
 | 
			
		||||
github.com/containers/common/pkg/config
 | 
			
		||||
github.com/containers/common/pkg/unshare
 | 
			
		||||
# github.com/containers/conmon v2.0.10+incompatible
 | 
			
		||||
github.com/containers/conmon/runner/config
 | 
			
		||||
| 
						 | 
				
			
			@ -264,7 +265,7 @@ github.com/docker/spdystream/spdy
 | 
			
		|||
github.com/etcd-io/bbolt
 | 
			
		||||
# github.com/fsnotify/fsnotify v1.4.7
 | 
			
		||||
github.com/fsnotify/fsnotify
 | 
			
		||||
# github.com/fsouza/go-dockerclient v1.6.0
 | 
			
		||||
# github.com/fsouza/go-dockerclient v1.6.1
 | 
			
		||||
github.com/fsouza/go-dockerclient
 | 
			
		||||
# github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa
 | 
			
		||||
github.com/fullsailor/pkcs7
 | 
			
		||||
| 
						 | 
				
			
			@ -309,7 +310,7 @@ github.com/hpcloud/tail/winfile
 | 
			
		|||
github.com/imdario/mergo
 | 
			
		||||
# github.com/inconshreveable/mousetrap v1.0.0
 | 
			
		||||
github.com/inconshreveable/mousetrap
 | 
			
		||||
# github.com/ishidawataru/sctp v0.0.0-20180918013207-6e2cb1366111
 | 
			
		||||
# github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07
 | 
			
		||||
github.com/ishidawataru/sctp
 | 
			
		||||
# github.com/json-iterator/go v1.1.9
 | 
			
		||||
github.com/json-iterator/go
 | 
			
		||||
| 
						 | 
				
			
			@ -597,7 +598,7 @@ golang.org/x/text/unicode/bidi
 | 
			
		|||
golang.org/x/text/unicode/norm
 | 
			
		||||
# golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0
 | 
			
		||||
golang.org/x/time/rate
 | 
			
		||||
# golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
 | 
			
		||||
# golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
 | 
			
		||||
golang.org/x/xerrors
 | 
			
		||||
golang.org/x/xerrors/internal
 | 
			
		||||
# google.golang.org/appengine v1.6.1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue