Vendor in buildah 1.9.2
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
parent
680a383874
commit
141c7a5165
25
go.mod
25
go.mod
|
|
@ -6,18 +6,16 @@ require (
|
|||
cloud.google.com/go v0.40.0 // indirect
|
||||
github.com/Azure/go-autorest v12.1.0+incompatible // indirect
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/DataDog/zstd v1.4.0 // indirect
|
||||
github.com/Microsoft/hcsshim v0.8.6 // indirect
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||
github.com/VividCortex/ewma v1.1.1 // indirect
|
||||
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/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect
|
||||
github.com/containernetworking/cni v0.7.1
|
||||
github.com/containernetworking/plugins v0.8.1
|
||||
github.com/containers/buildah v1.9.0
|
||||
github.com/containers/buildah v1.9.2
|
||||
github.com/containers/conmon v0.3.0 // indirect
|
||||
github.com/containers/image v2.0.1+incompatible
|
||||
github.com/containers/psgo v1.3.1
|
||||
github.com/containers/storage v1.12.13
|
||||
|
|
@ -35,8 +33,6 @@ require (
|
|||
github.com/docker/go-connections v0.4.0
|
||||
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 // indirect
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/docker/libnetwork v0.8.0-dev.2.0.20180608203834-19279f049241 // indirect
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
|
||||
github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect
|
||||
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect
|
||||
github.com/emicklei/go-restful v2.9.6+incompatible // indirect
|
||||
|
|
@ -54,36 +50,30 @@ require (
|
|||
github.com/googleapis/gax-go/v2 v2.0.5 // indirect
|
||||
github.com/googleapis/gnostic v0.3.0 // indirect
|
||||
github.com/gophercloud/gophercloud v0.2.0 // indirect
|
||||
github.com/gorilla/context v1.1.1 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.2 // indirect
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
github.com/hpcloud/tail v1.0.0
|
||||
github.com/imdario/mergo v0.3.7 // indirect
|
||||
github.com/ishidawataru/sctp v0.0.0-20180213033435-07191f837fed // indirect
|
||||
github.com/json-iterator/go v1.1.6
|
||||
github.com/kisielk/errcheck v1.2.0 // indirect
|
||||
github.com/klauspost/compress v1.7.1 // indirect
|
||||
github.com/klauspost/cpuid v1.2.1 // indirect
|
||||
github.com/klauspost/pgzip v1.2.1 // indirect
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||
github.com/magiconair/properties v1.8.1 // indirect
|
||||
github.com/mailru/easyjson v0.0.0-20190620125010-da37f6c1e481 // indirect
|
||||
github.com/mattn/go-isatty v0.0.8 // indirect
|
||||
github.com/mattn/go-shellwords v1.0.5 // indirect
|
||||
github.com/mistifyio/go-zfs v2.1.1+incompatible // indirect
|
||||
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618
|
||||
github.com/mtrmac/gpgme v0.0.0-20170102180018-b2432428689c // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20190414153302-2ae31c8b6b30 // indirect
|
||||
github.com/onsi/ginkgo v1.8.0
|
||||
github.com/onsi/gomega v1.5.0
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/opencontainers/runc v1.0.0-rc6
|
||||
github.com/opencontainers/runtime-spec v0.0.0-20181111125026-1722abf79c2f
|
||||
github.com/opencontainers/runc v1.0.0-rc8
|
||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7
|
||||
github.com/opencontainers/runtime-tools v0.9.0
|
||||
github.com/opencontainers/selinux v1.2.2
|
||||
github.com/openshift/imagebuilder v1.1.0 // indirect
|
||||
github.com/opentracing/opentracing-go v1.1.0
|
||||
github.com/ostreedev/ostree-go v0.0.0-20181213164143-d0388bd827cf // indirect
|
||||
github.com/pelletier/go-toml v1.4.0 // indirect
|
||||
|
|
@ -111,10 +101,7 @@ require (
|
|||
github.com/vbatts/tar-split v0.11.1 // indirect
|
||||
github.com/vbauerster/mpb v3.4.0+incompatible // indirect
|
||||
github.com/vishvananda/netlink v1.0.0
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.1.0 // indirect
|
||||
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f // indirect
|
||||
go.etcd.io/bbolt v1.3.3 // indirect
|
||||
go.opencensus.io v0.22.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4
|
||||
|
|
@ -128,8 +115,6 @@ require (
|
|||
google.golang.org/appengine v1.6.1 // indirect
|
||||
google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601 // indirect
|
||||
google.golang.org/grpc v1.21.1 // indirect
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce // indirect
|
||||
gopkg.in/yaml.v2 v2.2.2
|
||||
|
|
|
|||
18
go.sum
18
go.sum
|
|
@ -6,6 +6,7 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7O
|
|||
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/Azure/go-autorest v12.1.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/BurntSushi/toml v0.2.0/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
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=
|
||||
|
|
@ -68,6 +69,10 @@ github.com/containernetworking/plugins v0.8.1 h1:dJbykiiSIS3Xvo8d+A6rSXcUEFGfvCj
|
|||
github.com/containernetworking/plugins v0.8.1/go.mod h1:dagHaAhNjXjT9QYOklkKJDGaQPTg4pf//FrUcJeb7FU=
|
||||
github.com/containers/buildah v1.9.0 h1:ktVRCGNoVfW8PlTuCKUeh+zGdqn1Nik80DSWvGX+v4Y=
|
||||
github.com/containers/buildah v1.9.0/go.mod h1:1CsiLJvyU+h+wOjnqJJOWuJCVcMxZOr5HN/gHGdzJxY=
|
||||
github.com/containers/buildah v1.9.2 h1:dg87r1W1poWVQE0lTmP3BzaqgEI5IRudZ3jKjNIZ3xQ=
|
||||
github.com/containers/buildah v1.9.2/go.mod h1:UFq7EQtnDEEZv42AE7ZbmQMN+mSWSg1JIMwjYW1bn48=
|
||||
github.com/containers/conmon v0.3.0 h1:NDkYcQAu1BDZSVLh6xrY9jh/WmiDaUloKzRM16237XM=
|
||||
github.com/containers/conmon v0.3.0/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
|
||||
github.com/containers/image v2.0.0+incompatible h1:FTr6Br7jlIKNCKMjSOMbAxKp2keQ0//jzJaYNTVhauk=
|
||||
github.com/containers/image v2.0.0+incompatible/go.mod h1:8Vtij257IWSanUQKe1tAeNOm2sRVkSqQTVQ1IlwI3+M=
|
||||
github.com/containers/image v2.0.1+incompatible h1:w39mlElA/aSFZ6moFa5N+A4MWu9c8hgdMiMMYnH94Hs=
|
||||
|
|
@ -150,6 +155,8 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
|
|||
github.com/docker/libnetwork v0.0.0-20181207044626-1a06131fb8a0/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8=
|
||||
github.com/docker/libnetwork v0.8.0-dev.2.0.20180608203834-19279f049241 h1:+ebE/hCU02srkeIg8Vp/vlUp182JapYWtXzV+bCeR2I=
|
||||
github.com/docker/libnetwork v0.8.0-dev.2.0.20180608203834-19279f049241/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8=
|
||||
github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316 h1:moehPjPiGUaWdwgOl92xRyFHJyaqXDHcCyW9M6nmCK4=
|
||||
github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8=
|
||||
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=
|
||||
|
|
@ -313,6 +320,7 @@ 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-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
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/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
|
|
@ -321,6 +329,7 @@ github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJd
|
|||
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/moby v0.0.0-20171005181806-f8806b18b4b9/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
|
||||
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=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
|
|
@ -358,8 +367,12 @@ github.com/opencontainers/runc v0.0.0-20190425234816-dae70e8efea4/go.mod h1:qT5X
|
|||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v1.0.0-rc6 h1:7AoN22rYxxkmsJS48wFaziH/n0OvrZVqL/TglgHKbKQ=
|
||||
github.com/opencontainers/runc v1.0.0-rc6/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=
|
||||
github.com/opencontainers/runtime-spec v0.0.0-20181111125026-1722abf79c2f h1:yBRNGmKl04BYFrAx8cUYDknbFNVk9yIF/3gH1/4lu0I=
|
||||
github.com/opencontainers/runtime-spec v0.0.0-20181111125026-1722abf79c2f/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7 h1:Dliu5QO+4JYWu/yMshaMU7G3JN2POGpwjJN7gjy10Go=
|
||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-tools v0.8.0 h1:YapwQol12sO/sioRsGNmxDSDAmbbDGRPPlCFxctIeQU=
|
||||
github.com/opencontainers/runtime-tools v0.8.0/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
||||
github.com/opencontainers/runtime-tools v0.9.0 h1:FYgwVsKRI/H9hU32MJ/4MLOzXWodKK5zsQavY8NPMkU=
|
||||
|
|
@ -374,6 +387,7 @@ github.com/opentracing/opentracing-go v0.0.0-20190218023034-25a84ff92183 h1:kwFC
|
|||
github.com/opentracing/opentracing-go v0.0.0-20190218023034-25a84ff92183/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/ostreedev/ostree-go v0.0.0-20181112201119-9ab99253d365/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
|
||||
github.com/ostreedev/ostree-go v0.0.0-20181213164143-d0388bd827cf h1:tap+MXBMnRjexGsKGhIk4hV2QWASgxEvx8NMTtoSi8U=
|
||||
github.com/ostreedev/ostree-go v0.0.0-20181213164143-d0388bd827cf/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
|
|
@ -390,6 +404,7 @@ github.com/pkg/profile v1.3.0/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6J
|
|||
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=
|
||||
github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
|
||||
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7 h1:gGBSHPOU7g8YjTbhwn+lvFm2VDEhhA+PwDIlstkgSxE=
|
||||
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
|
|
@ -479,6 +494,7 @@ github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8=
|
|||
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/varlink/go v0.0.0-20190502142041-0f1d566d194b h1:hdDRrn9OP/roL8a/e/5Zu85ldrcdndu9IeBj2OEvQm0=
|
||||
github.com/varlink/go v0.0.0-20190502142041-0f1d566d194b/go.mod h1:YHaw8N660ESgMgLOZfLQqT1htFItynAUxMesFBho52s=
|
||||
github.com/vbatts/tar-split v0.10.2/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g=
|
||||
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.3.4+incompatible h1:DDIhnwmgTQIDZo+SWlEr5d6mJBxkOLBwCXPzunhEfJ4=
|
||||
|
|
@ -489,6 +505,8 @@ github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCO
|
|||
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4=
|
||||
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/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/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
|
|
|
|||
|
|
@ -185,11 +185,11 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
|
|||
// If network namespace was requested, add it now
|
||||
if c.config.CreateNetNS {
|
||||
if c.config.PostConfigureNetNS {
|
||||
if err := g.AddOrReplaceLinuxNamespace(spec.NetworkNamespace, ""); err != nil {
|
||||
if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), ""); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if err := g.AddOrReplaceLinuxNamespace(spec.NetworkNamespace, c.state.NetNS.Path()); err != nil {
|
||||
if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), c.state.NetNS.Path()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
@ -310,7 +310,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
|
|||
}
|
||||
}
|
||||
if c.config.PIDNsCtr != "" {
|
||||
if err := c.addNamespaceContainer(&g, PIDNS, c.config.PIDNsCtr, string(spec.PIDNamespace)); err != nil {
|
||||
if err := c.addNamespaceContainer(&g, PIDNS, c.config.PIDNsCtr, spec.PIDNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
@ -340,7 +340,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
|
|||
g.AddAnnotation("org.opencontainers.image.stopSignal", fmt.Sprintf("%d", c.config.StopSignal))
|
||||
|
||||
for _, i := range c.config.Spec.Linux.Namespaces {
|
||||
if string(i.Type) == spec.UTSNamespace {
|
||||
if i.Type == spec.UTSNamespace {
|
||||
hostname := c.Hostname()
|
||||
g.SetHostname(hostname)
|
||||
g.AddProcessEnv("HOSTNAME", hostname)
|
||||
|
|
@ -496,7 +496,7 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
|
|||
}
|
||||
|
||||
// Add an existing container's namespace to the spec
|
||||
func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr string, specNS string) error {
|
||||
func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr string, specNS spec.LinuxNamespaceType) error {
|
||||
nsCtr, err := c.runtime.state.Container(ctr)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error retrieving dependency %s of container %s from state", ctr, c.ID())
|
||||
|
|
@ -508,7 +508,7 @@ func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr
|
|||
return err
|
||||
}
|
||||
|
||||
if err := g.AddOrReplaceLinuxNamespace(specNS, nsPath); err != nil {
|
||||
if err := g.AddOrReplaceLinuxNamespace(string(specNS), nsPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -787,7 +787,7 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
|
|||
|
||||
// We want to have the same network namespace as before.
|
||||
if c.config.CreateNetNS {
|
||||
if err := g.AddOrReplaceLinuxNamespace(spec.NetworkNamespace, c.state.NetNS.Path()); err != nil {
|
||||
if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), c.state.NetNS.Path()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -552,7 +552,7 @@ func addPidNS(config *CreateConfig, g *generate.Generator) error {
|
|||
|
||||
func addUserNS(config *CreateConfig, g *generate.Generator) error {
|
||||
if IsNS(string(config.UsernsMode)) {
|
||||
if err := g.AddOrReplaceLinuxNamespace(spec.UserNamespace, NS(string(config.UsernsMode))); err != nil {
|
||||
if err := g.AddOrReplaceLinuxNamespace(string(spec.UserNamespace), NS(string(config.UsernsMode))); err != nil {
|
||||
return err
|
||||
}
|
||||
// runc complains if no mapping is specified, even if we join another ns. So provide a dummy mapping
|
||||
|
|
@ -561,7 +561,7 @@ func addUserNS(config *CreateConfig, g *generate.Generator) error {
|
|||
}
|
||||
|
||||
if (len(config.IDMappings.UIDMap) > 0 || len(config.IDMappings.GIDMap) > 0) && !config.UsernsMode.IsHost() {
|
||||
if err := g.AddOrReplaceLinuxNamespace(spec.UserNamespace, ""); err != nil {
|
||||
if err := g.AddOrReplaceLinuxNamespace(string(spec.UserNamespace), ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -572,7 +572,7 @@ func addNetNS(config *CreateConfig, g *generate.Generator) error {
|
|||
netMode := config.NetMode
|
||||
if netMode.IsHost() {
|
||||
logrus.Debug("Using host netmode")
|
||||
return g.RemoveLinuxNamespace(spec.NetworkNamespace)
|
||||
return g.RemoveLinuxNamespace(string(spec.NetworkNamespace))
|
||||
} else if netMode.IsNone() {
|
||||
logrus.Debug("Using none netmode")
|
||||
return nil
|
||||
|
|
@ -584,7 +584,7 @@ func addNetNS(config *CreateConfig, g *generate.Generator) error {
|
|||
return nil
|
||||
} else if IsNS(string(netMode)) {
|
||||
logrus.Debug("Using ns netmode")
|
||||
return g.AddOrReplaceLinuxNamespace(spec.NetworkNamespace, NS(string(netMode)))
|
||||
return g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), NS(string(netMode)))
|
||||
} else if IsPod(string(netMode)) {
|
||||
logrus.Debug("Using pod netmode, unless pod is not sharing")
|
||||
return nil
|
||||
|
|
@ -604,7 +604,7 @@ func addUTSNS(config *CreateConfig, g *generate.Generator) error {
|
|||
return g.AddOrReplaceLinuxNamespace(string(spec.UTSNamespace), NS(string(utsMode)))
|
||||
}
|
||||
if utsMode.IsHost() {
|
||||
return g.RemoveLinuxNamespace(spec.UTSNamespace)
|
||||
return g.RemoveLinuxNamespace(string(spec.UTSNamespace))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -615,7 +615,7 @@ func addIpcNS(config *CreateConfig, g *generate.Generator) error {
|
|||
return g.AddOrReplaceLinuxNamespace(string(spec.IPCNamespace), NS(string(ipcMode)))
|
||||
}
|
||||
if ipcMode.IsHost() {
|
||||
return g.RemoveLinuxNamespace(spec.IPCNamespace)
|
||||
return g.RemoveLinuxNamespace(string(spec.IPCNamespace))
|
||||
}
|
||||
if ipcMode.IsContainer() {
|
||||
logrus.Debug("Using container ipcmode")
|
||||
|
|
@ -630,10 +630,10 @@ func addCgroupNS(config *CreateConfig, g *generate.Generator) error {
|
|||
return g.AddOrReplaceLinuxNamespace(string(spec.CgroupNamespace), NS(string(cgroupMode)))
|
||||
}
|
||||
if cgroupMode.IsHost() {
|
||||
return g.RemoveLinuxNamespace(spec.CgroupNamespace)
|
||||
return g.RemoveLinuxNamespace(string(spec.CgroupNamespace))
|
||||
}
|
||||
if cgroupMode.IsPrivate() {
|
||||
return g.AddOrReplaceLinuxNamespace(spec.CgroupNamespace, "")
|
||||
return g.AddOrReplaceLinuxNamespace(string(spec.CgroupNamespace), "")
|
||||
}
|
||||
if cgroupMode.IsContainer() {
|
||||
logrus.Debug("Using container cgroup mode")
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildI
|
|||
}
|
||||
|
||||
hostNetwork := buildah.NamespaceOption{
|
||||
Name: specs.NetworkNamespace,
|
||||
Name: string(specs.NetworkNamespace),
|
||||
Host: true,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
---
|
||||
|
||||
# Main collection of env. vars to set for all tasks and scripts.
|
||||
env:
|
||||
####
|
||||
#### Global variables used for all tasks
|
||||
####
|
||||
# Overrides default location (/tmp/cirrus) for repo clone
|
||||
CIRRUS_WORKING_DIR: "/var/tmp/go/src/github.com/containers/buildah"
|
||||
# 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
|
||||
|
||||
####
|
||||
#### Cache-image names to test with
|
||||
####
|
||||
# GCE project where images live
|
||||
IMAGE_PROJECT: "libpod-218412"
|
||||
FEDORA_CACHE_IMAGE_NAME: "fedora-cloud-base-30-1-2-1559164849"
|
||||
PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-cloud-base-29-1-2-1559164849"
|
||||
UBUNTU_CACHE_IMAGE_NAME: "ubuntu-1904-disco-v20190514" # Latest
|
||||
PRIOR_UBUNTU_CACHE_IMAGE_NAME: "ubuntu-1804-bionic-v20190530" # LTS
|
||||
|
||||
####
|
||||
#### Command variables to help avoid duplication
|
||||
####
|
||||
# Command to prefix every output line with a timestamp
|
||||
# (can't do inline awk script, Cirrus-CI or YAML mangles quoting)
|
||||
_TIMESTAMP: 'awk --file ${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]
|
||||
|
||||
# Default timeout for each task
|
||||
timeout_in: 120m
|
||||
|
||||
# Default VM to use unless set or modified by task
|
||||
gce_instance:
|
||||
image_project: "${IMAGE_PROJECT}"
|
||||
zone: "us-central1-c" # Required by Cirrus for the time being
|
||||
cpu: 2
|
||||
memory: "4Gb"
|
||||
disk: 200 # Gigabytes, do not set less than 200 per obscure GCE docs re: I/O performance
|
||||
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'
|
||||
|
||||
|
||||
# Update metadata on VM images referenced by this repository state
|
||||
meta_task:
|
||||
|
||||
container:
|
||||
image: "quay.io/libpod/imgts:latest" # see contrib/imgts
|
||||
cpu: 1
|
||||
memory: 1
|
||||
|
||||
env:
|
||||
# Space-separated list of images used by this repository state
|
||||
IMGNAMES: |-
|
||||
${FEDORA_CACHE_IMAGE_NAME}
|
||||
${PRIOR_FEDORA_CACHE_IMAGE_NAME}
|
||||
${UBUNTU_CACHE_IMAGE_NAME}
|
||||
${PRIOR_UBUNTU_CACHE_IMAGE_NAME}
|
||||
BUILDID: "${CIRRUS_BUILD_ID}"
|
||||
REPOREF: "${CIRRUS_CHANGE_IN_REPO}"
|
||||
GCPJSON: ENCRYPTED[d3614d6f5cc0e66be89d4252b3365fd84f14eee0259d4eb47e25fc0bc2842c7937f5ee8c882b7e547b4c5ec4b6733b14]
|
||||
GCPNAME: ENCRYPTED[8509e6a681b859479ce6aa275bd3c4ac82de5beec6df6057925afc4cd85b7ef2e879066ae8baaa2d453b82958e434578]
|
||||
GCPPROJECT: ENCRYPTED[cc09b62d0ec6746a3df685e663ad25d9d5af95ef5fd843c96f3d0ec9d7f065dc63216b9c685c9f43a776a1d403991494]
|
||||
CIRRUS_CLONE_DEPTH: 1 # source not used
|
||||
|
||||
script: '/usr/local/bin/entrypoint.sh |& ${_TIMESTAMP}'
|
||||
|
|
@ -2,3 +2,4 @@ docs/buildah*.1
|
|||
/buildah
|
||||
/imgtype
|
||||
/build/
|
||||
tests/tools/build
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
run:
|
||||
build-tags:
|
||||
- apparmor
|
||||
- ostree
|
||||
- seccomp
|
||||
- selinux
|
||||
concurrency: 6
|
||||
deadline: 5m
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- bodyclose
|
||||
- deadcode
|
||||
- depguard
|
||||
- dupl
|
||||
- errcheck
|
||||
- gofmt
|
||||
- goimports
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- misspell
|
||||
- nakedret
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- stylecheck
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- varcheck
|
||||
# - gochecknoglobals
|
||||
# - gochecknoinits
|
||||
# - goconst
|
||||
# - gocritic
|
||||
# - gocyclo
|
||||
# - golint
|
||||
# - gosec
|
||||
# - interfacer
|
||||
# - lll
|
||||
# - maligned
|
||||
# - prealloc
|
||||
# - scopelint
|
||||
|
|
@ -45,11 +45,20 @@ 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
|
||||
- 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
|
||||
- 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
|
||||
- >
|
||||
OSTREE_VERSION=v2019.2;
|
||||
git clone https://github.com/ostreedev/ostree &&
|
||||
pushd ostree &&
|
||||
git checkout $OSTREE_VERSION &&
|
||||
./autogen.sh --prefix=/usr &&
|
||||
sudo make -j4 install &&
|
||||
popd &&
|
||||
sudo rm -rf ostree
|
||||
install:
|
||||
# Let's create a self signed certificate and get it in the right places
|
||||
- hostname
|
||||
|
|
@ -85,8 +94,9 @@ script:
|
|||
- docker ps --all
|
||||
- docker images
|
||||
- docker rmi localhost:5000/my-alpine
|
||||
# Setting up Docker Registry is complete, let's do Buildah testing!
|
||||
- make install.tools install.libseccomp.sudo all runc validate SECURITYTAGS="apparmor seccomp"
|
||||
# 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` `./ostree_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
|
||||
|
|
|
|||
|
|
@ -118,11 +118,18 @@ commit automatically with `git commit -s`.
|
|||
|
||||
## Communications
|
||||
|
||||
For general questions, or discussions, please use the
|
||||
For general questions or discussions, please use the
|
||||
IRC group on `irc.freenode.net` called `buildah`
|
||||
that has been setup.
|
||||
|
||||
For discussions around issues/bugs and features, you can use the github
|
||||
### For discussions around issues/bugs and features:
|
||||
|
||||
#### Buildah Mailing List
|
||||
|
||||
You can join the Buildah mailing list by sending an email to `buildah-join@lists.buildah.io` with the word `subscribe` in the subject. You can also go to this [page](https://lists.podman.io/admin/lists/buildah.lists.buildah.io/), then scroll down to the bottom of the page and enter your email and optionally name, then click on the "Subscribe" buton.
|
||||
|
||||
#### GitHub
|
||||
You can also use the github
|
||||
[issues](https://github.com/containers/buildah/issues)
|
||||
and
|
||||
[PRs](https://github.com/containers/buildah/pulls)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
export GO111MODULE=off
|
||||
|
||||
SELINUXTAG := $(shell ./selinux_tag.sh)
|
||||
STORAGETAGS := $(shell ./btrfs_tag.sh) $(shell ./btrfs_installed_tag.sh) $(shell ./libdm_tag.sh) $(shell ./ostree_tag.sh)
|
||||
SECURITYTAGS ?= seccomp $(SELINUXTAG)
|
||||
|
|
@ -13,10 +15,10 @@ GO110 := 1.10
|
|||
GOVERSION := $(findstring $(GO110),$(shell go version))
|
||||
GIT_COMMIT ?= $(if $(shell git rev-parse --short HEAD),$(shell git rev-parse --short HEAD),$(error "git failed"))
|
||||
BUILD_INFO := $(if $(shell date +%s),$(shell date +%s),$(error "date failed"))
|
||||
CNI_COMMIT := $(if $(shell sed -e '\,github.com/containernetworking/cni, !d' -e 's,.* ,,g' vendor.conf),$(shell sed -e '\,github.com/containernetworking/cni, !d' -e 's,.* ,,g' vendor.conf),$(error "sed failed"))
|
||||
STATIC_STORAGETAGS = "containers_image_ostree_stub containers_image_openpgp exclude_graphdriver_devicemapper $(STORAGE_TAGS)"
|
||||
|
||||
RUNC_COMMIT := 2c632d1a2de0192c3f18a2542ccb6f30a8719b1f
|
||||
CNI_COMMIT := $(shell sed -n 's;\tgithub.com/containernetworking/cni \([^ \n]*\).*$\;\1;p' go.mod)
|
||||
RUNC_COMMIT := $(shell sed -n 's;\tgithub.com/opencontainers/runc \([^ \n]*\).*$\;\1;p' go.mod)
|
||||
LIBSECCOMP_COMMIT := release-2.3
|
||||
|
||||
EXTRALDFLAGS :=
|
||||
|
|
@ -47,7 +49,7 @@ clean:
|
|||
$(MAKE) -C docs clean
|
||||
|
||||
.PHONY: docs
|
||||
docs: ## build the docs on the host
|
||||
docs: install.tools ## build the docs on the host
|
||||
$(MAKE) -C docs
|
||||
|
||||
# For vendoring to work right, the checkout directory must be such that our top
|
||||
|
|
@ -62,7 +64,7 @@ deps: gopath
|
|||
env GOPATH=$(shell cd ../../../.. ; pwd) vndr
|
||||
|
||||
.PHONY: validate
|
||||
validate:
|
||||
validate: install.tools
|
||||
# Run gofmt on version 1.11 and higher
|
||||
ifneq ($(GO110),$(GOVERSION))
|
||||
@./tests/validate/gofmt.sh
|
||||
|
|
@ -70,15 +72,10 @@ endif
|
|||
@./tests/validate/whitespace.sh
|
||||
@./tests/validate/govet.sh
|
||||
@./tests/validate/git-validation.sh
|
||||
@./tests/validate/gometalinter.sh . cmd/buildah
|
||||
|
||||
.PHONY: install.tools
|
||||
install.tools:
|
||||
$(GO) get -u $(BUILDFLAGS) github.com/cpuguy83/go-md2man
|
||||
$(GO) get -u $(BUILDFLAGS) github.com/vbatts/git-validation
|
||||
$(GO) get -u $(BUILDFLAGS) github.com/onsi/ginkgo/ginkgo
|
||||
$(GO) get -u $(BUILDFLAGS) gopkg.in/alecthomas/gometalinter.v1
|
||||
$(GOPATH)/bin/gometalinter.v1 -i
|
||||
make -C tests/tools
|
||||
|
||||
.PHONY: runc
|
||||
runc: gopath
|
||||
|
|
@ -119,8 +116,8 @@ install.runc:
|
|||
install -m 755 ../../opencontainers/runc/runc $(DESTDIR)/$(BINDIR)/
|
||||
|
||||
.PHONY: test-integration
|
||||
test-integration:
|
||||
ginkgo -v tests/e2e/.
|
||||
test-integration: install.tools
|
||||
./tests/tools/ginkgo $(BUILDFLAGS) -v tests/e2e/.
|
||||
cd tests; ./test_runner.sh
|
||||
|
||||
tests/testreport/testreport: tests/testreport/testreport.go
|
||||
|
|
@ -133,11 +130,13 @@ test-unit: tests/testreport/testreport
|
|||
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
|
||||
|
||||
.PHONY: .install.vndr
|
||||
.install.vndr:
|
||||
$(GO) get -u github.com/LK4D4/vndr
|
||||
|
||||
.PHONY: vendor
|
||||
vendor: vendor.conf .install.vndr
|
||||
$(GOPATH)/bin/vndr \
|
||||
-whitelist "github.com/onsi/gomega"
|
||||
vendor:
|
||||
export GO111MODULE=on \
|
||||
$(GO) mod tidy && \
|
||||
$(GO) mod vendor && \
|
||||
$(GO) mod verify
|
||||
|
||||
.PHONY: lint
|
||||
lint: install.tools
|
||||
./tests/tools/build/golangci-lint run
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ func addHelper(excludes *fileutils.PatternMatcher, extract bool, dest string, de
|
|||
return errors.Wrapf(err, "error creating directory %q", dest)
|
||||
}
|
||||
logrus.Debugf("copying %q to %q", esrc+string(os.PathSeparator)+"*", dest+string(os.PathSeparator)+"*")
|
||||
if excludes == nil {
|
||||
if excludes == nil || !excludes.Exclusions() {
|
||||
if err = copyWithTar(esrc, dest); err != nil {
|
||||
return errors.Wrapf(err, "error copying %q to %q", esrc, dest)
|
||||
}
|
||||
|
|
@ -310,7 +310,7 @@ func addHelper(excludes *fileutils.PatternMatcher, extract bool, dest string, de
|
|||
return addHelperDirectory(esrc, path, filepath.Join(dest, fpath), info, hostOwner, times)
|
||||
}
|
||||
if info.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||
return addHelperSymlink(path, filepath.Join(dest, fpath), info, hostOwner, times)
|
||||
return addHelperSymlink(path, filepath.Join(dest, fpath), hostOwner, times)
|
||||
}
|
||||
if !info.Mode().IsRegular() {
|
||||
return errors.Errorf("error copying %q to %q: source is not a regular file; file mode is %s", path, dest, info.Mode())
|
||||
|
|
@ -368,7 +368,7 @@ func addHelperDirectory(esrc, path, dest string, info os.FileInfo, hostOwner idt
|
|||
return nil
|
||||
}
|
||||
|
||||
func addHelperSymlink(src, dest string, info os.FileInfo, hostOwner idtools.IDPair, times []syscall.Timespec) error {
|
||||
func addHelperSymlink(src, dest string, hostOwner idtools.IDPair, times []syscall.Timespec) error {
|
||||
linkContents, err := os.Readlink(src)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error reading contents of symbolic link at %q", src)
|
||||
|
|
|
|||
|
|
@ -25,15 +25,3 @@ func stripNoBindOption(spec *specs.Spec) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func dedupeStringSlice(slice []string) []string {
|
||||
done := make([]string, 0, len(slice))
|
||||
m := make(map[string]struct{})
|
||||
for _, s := range slice {
|
||||
if _, present := m[s]; !present {
|
||||
m[s] = struct{}{}
|
||||
done = append(done, s)
|
||||
}
|
||||
}
|
||||
return done
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import (
|
|||
"github.com/containers/image/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/ioutils"
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
|
@ -26,7 +26,7 @@ const (
|
|||
Package = "buildah"
|
||||
// Version for the Package. Bump version in contrib/rpm/buildah.spec
|
||||
// too.
|
||||
Version = "1.9.0"
|
||||
Version = "1.9.2"
|
||||
// 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
|
||||
|
|
@ -119,6 +119,9 @@ type Builder struct {
|
|||
// FromImageID is the ID of the source image which was used to create
|
||||
// the container, if one was used. It should not be modified.
|
||||
FromImageID string `json:"image-id"`
|
||||
// FromImageDigest is the digest of the source image which was used to
|
||||
// create the container, if one was used. It should not be modified.
|
||||
FromImageDigest string `json:"image-digest"`
|
||||
// Config is the source image's configuration. It should not be
|
||||
// modified.
|
||||
Config []byte `json:"config,omitempty"`
|
||||
|
|
@ -200,6 +203,7 @@ type BuilderInfo struct {
|
|||
Type string
|
||||
FromImage string
|
||||
FromImageID string
|
||||
FromImageDigest string
|
||||
Config string
|
||||
Manifest string
|
||||
Container string
|
||||
|
|
@ -243,6 +247,7 @@ func GetBuildInfo(b *Builder) BuilderInfo {
|
|||
Type: b.Type,
|
||||
FromImage: b.FromImage,
|
||||
FromImageID: b.FromImageID,
|
||||
FromImageDigest: b.FromImageDigest,
|
||||
Config: string(b.Config),
|
||||
Manifest: string(b.Manifest),
|
||||
Container: b.Container,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,86 @@
|
|||
- Changelog for v1.9.2 (2019-07-19)
|
||||
* from/import: record the base image's digest, if it has one
|
||||
* Fix CNI version retrieval to not require network connection
|
||||
* Add misspell linter and apply fixes
|
||||
* Add goimports linter and apply fixes
|
||||
* Add stylecheck linter and apply fixes
|
||||
* Add unconvert linter and apply fixes
|
||||
* image: make sure we don't try to use zstd compression
|
||||
* run.bats: skip the "z" flag when testing --mount
|
||||
* Update to runc v1.0.0-rc8
|
||||
* Update to match updated runtime-tools API
|
||||
* bump github.com/opencontainers/runtime-tools to v0.9.0
|
||||
* Build e2e tests using the proper build tags
|
||||
* Add unparam linter and apply fixes
|
||||
* Run: correct a typo in the --cap-add help text
|
||||
* unshare: add a --mount flag
|
||||
* fix push check image name is not empty
|
||||
* Bump to v1.9.2-dev
|
||||
|
||||
- Changelog for v1.9.1 (2019-07-12)
|
||||
* add: fix slow copy with no excludes
|
||||
* Add errcheck linter and fix missing error check
|
||||
* Improve tests/tools/Makefile parallelism and abstraction
|
||||
* Fix response body not closed resource leak
|
||||
* Switch to golangci-lint
|
||||
* Add gomod instructions and mailing list links
|
||||
* On Masked path, check if /dev/null already mounted before mounting
|
||||
* Update to containers/storage v1.12.13
|
||||
* Refactor code in package imagebuildah
|
||||
* Add rootless podman with NFS issue in documentation
|
||||
* Add --mount for buildah run
|
||||
* import method ValidateVolumeOpts from libpod
|
||||
* Fix typo
|
||||
* Makefile: set GO111MODULE=off
|
||||
* rootless: add the built-in slirp DNS server
|
||||
* Update docker/libnetwork to get rid of outdated sctp package
|
||||
* Update buildah-login.md
|
||||
* migrate to go modules
|
||||
* install.md: mention go modules
|
||||
* tests/tools: go module for test binaries
|
||||
* fix --volume splits comma delimited option
|
||||
* Add bud test for RUN with a priv'd command
|
||||
* vendor logrus v1.4.2
|
||||
* pkg/cli: panic when flags can't be hidden
|
||||
* pkg/unshare: check all errors
|
||||
* pull: check error during report write
|
||||
* run_linux.go: ignore unchecked errors
|
||||
* conformance test: catch copy error
|
||||
* chroot/run_test.go: export funcs to actually be executed
|
||||
* tests/imgtype: ignore error when shutting down the store
|
||||
* testreport: check json error
|
||||
* bind/util.go: remove unused func
|
||||
* rm chroot/util.go
|
||||
* imagebuildah: remove unused `dedupeStringSlice`
|
||||
* StageExecutor: EnsureContainerPath: catch error from SecureJoin()
|
||||
* imagebuildah/build.go: return <expr> instead of branching
|
||||
* rmi: avoid redundant branching
|
||||
* conformance tests: nilness: allocate map
|
||||
* imagebuildah/build.go: avoid redundant `filepath.Join()`
|
||||
* imagebuildah/build.go: avoid redundant `os.Stat()`
|
||||
* imagebuildah: omit comparison to bool
|
||||
* fix "ineffectual assignment" lint errors
|
||||
* docker: ignore "repeats json tag" lint error
|
||||
* pkg/unshare: use `...` instead of iterating a slice
|
||||
* conformance: bud test: use raw strings for regexes
|
||||
* conformance suite: remove unused func/var
|
||||
* buildah test suite: remove unused vars/funcs
|
||||
* testreport: fix golangci-lint errors
|
||||
* util: remove redundant `return` statement
|
||||
* chroot: only log clean-up errors
|
||||
* images_test: ignore golangci-lint error
|
||||
* blobcache: log error when draining the pipe
|
||||
* imagebuildah: check errors in deferred calls
|
||||
* chroot: fix error handling in deferred funcs
|
||||
* cmd: check all errors
|
||||
* chroot/run_test.go: check errors
|
||||
* chroot/run.go: check errors in deferred calls
|
||||
* imagebuildah.Executor: remove unused onbuild field
|
||||
* docker/types.go: remove unused struct fields
|
||||
* util: use strings.ContainsRune instead of index check
|
||||
* Cirrus: Initial implementation
|
||||
* Bump to v1.9.1-dev
|
||||
|
||||
- Changelog for v1.9.0 (2019-06-15)
|
||||
* buildah-run: fix-out-of-range panic (2)
|
||||
* Bump back to v1.9.0-dev
|
||||
|
|
|
|||
|
|
@ -507,7 +507,9 @@ func runUsingChroot(spec *specs.Spec, bundlePath string, ctty *os.File, stdin io
|
|||
return 1, err
|
||||
}
|
||||
defer func() {
|
||||
undoIntermediates()
|
||||
if undoErr := undoIntermediates(); undoErr != nil {
|
||||
logrus.Debugf("error cleaning up intermediate mount NS: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Bind mount in our filesystems.
|
||||
|
|
@ -516,7 +518,9 @@ func runUsingChroot(spec *specs.Spec, bundlePath string, ctty *os.File, stdin io
|
|||
return 1, err
|
||||
}
|
||||
defer func() {
|
||||
undoChroots()
|
||||
if undoErr := undoChroots(); undoErr != nil {
|
||||
logrus.Debugf("error cleaning up intermediate chroot bind mounts: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Create a pipe for passing configuration down to the next process.
|
||||
|
|
@ -565,7 +569,7 @@ func runUsingChroot(spec *specs.Spec, bundlePath string, ctty *os.File, stdin io
|
|||
cmd.UnshareFlags = syscall.CLONE_NEWUTS | syscall.CLONE_NEWNS
|
||||
requestedUserNS := false
|
||||
for _, ns := range spec.Linux.Namespaces {
|
||||
if ns.Type == specs.LinuxNamespaceType(specs.UserNamespace) {
|
||||
if ns.Type == specs.UserNamespace {
|
||||
requestedUserNS = true
|
||||
}
|
||||
}
|
||||
|
|
@ -979,6 +983,21 @@ func makeReadOnly(mntpoint string, flags uintptr) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func isDevNull(dev os.FileInfo) bool {
|
||||
if dev.Mode()&os.ModeCharDevice != 0 {
|
||||
stat, _ := dev.Sys().(*syscall.Stat_t)
|
||||
nullStat := syscall.Stat_t{}
|
||||
if err := syscall.Stat(os.DevNull, &nullStat); err != nil {
|
||||
logrus.Warnf("unable to stat /dev/null: %v", err)
|
||||
return false
|
||||
}
|
||||
if stat.Rdev == nullStat.Rdev {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// setupChrootBindMounts actually bind mounts things under the rootfs, and returns a
|
||||
// callback that will clean up its work.
|
||||
func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func() error, err error) {
|
||||
|
|
@ -1259,11 +1278,6 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func(
|
|||
if err != nil {
|
||||
target = t
|
||||
}
|
||||
// Get some info about the null device.
|
||||
nullinfo, err := os.Stat(os.DevNull)
|
||||
if err != nil {
|
||||
return undoBinds, errors.Wrapf(err, "error examining %q for masking in mount namespace", os.DevNull)
|
||||
}
|
||||
// Get some info about the target.
|
||||
targetinfo, err := os.Stat(target)
|
||||
if err != nil {
|
||||
|
|
@ -1281,12 +1295,11 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func(
|
|||
}
|
||||
isReadOnly := statfs.Flags&unix.MS_RDONLY != 0
|
||||
// Check if any of the IDs we're mapping could read it.
|
||||
isAccessible := true
|
||||
var stat unix.Stat_t
|
||||
if err = unix.Stat(target, &stat); err != nil {
|
||||
return undoBinds, errors.Wrapf(err, "error checking permissions on directory %q", target)
|
||||
}
|
||||
isAccessible = false
|
||||
isAccessible := false
|
||||
if stat.Mode&unix.S_IROTH|unix.S_IXOTH != 0 {
|
||||
isAccessible = true
|
||||
}
|
||||
|
|
@ -1352,8 +1365,8 @@ func setupChrootBindMounts(spec *specs.Spec, bundlePath string) (undoBinds func(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
// The target's not a directory, so bind mount os.DevNull over it, unless it's already os.DevNull.
|
||||
if !os.SameFile(nullinfo, targetinfo) {
|
||||
// If the target's is not a directory or os.DevNull, bind mount os.DevNull over it.
|
||||
if isDevNull(targetinfo) {
|
||||
if err = unix.Mount(os.DevNull, target, "", uintptr(syscall.MS_BIND|syscall.MS_RDONLY|syscall.MS_PRIVATE), ""); err != nil {
|
||||
return undoBinds, errors.Wrapf(err, "error masking non-directory %q in mount namespace", target)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
// +build linux
|
||||
|
||||
package chroot
|
||||
|
||||
func dedupeStringSlice(slice []string) []string {
|
||||
done := make([]string, 0, len(slice))
|
||||
m := make(map[string]struct{})
|
||||
for _, s := range slice {
|
||||
if _, present := m[s]; !present {
|
||||
m[s] = struct{}{}
|
||||
done = append(done, s)
|
||||
}
|
||||
}
|
||||
return done
|
||||
}
|
||||
|
|
@ -184,8 +184,8 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
|
|||
}
|
||||
// In case we're using caching, decide how to handle compression for a cache.
|
||||
// If we're using blob caching, set it up for the source.
|
||||
var maybeCachedSrc = types.ImageReference(src)
|
||||
var maybeCachedDest = types.ImageReference(dest)
|
||||
maybeCachedSrc := src
|
||||
maybeCachedDest := dest
|
||||
if options.BlobDirectory != "" {
|
||||
compress := types.PreserveOriginal
|
||||
if options.Compression != archive.Uncompressed {
|
||||
|
|
@ -210,7 +210,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
|
|||
systemContext.DirForceCompress = true
|
||||
}
|
||||
var manifestBytes []byte
|
||||
if manifestBytes, err = cp.Image(ctx, policyContext, maybeCachedDest, maybeCachedSrc, getCopyOptions(b.store, options.ReportWriter, maybeCachedSrc, nil, maybeCachedDest, systemContext, "")); err != nil {
|
||||
if manifestBytes, err = cp.Image(ctx, policyContext, maybeCachedDest, maybeCachedSrc, getCopyOptions(b.store, options.ReportWriter, nil, systemContext, "")); 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
|
||||
|
|
@ -301,7 +301,7 @@ func Push(ctx context.Context, image string, dest types.ImageReference, options
|
|||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
var maybeCachedSrc = types.ImageReference(src)
|
||||
maybeCachedSrc := src
|
||||
if options.BlobDirectory != "" {
|
||||
compress := types.PreserveOriginal
|
||||
if options.Compression != archive.Uncompressed {
|
||||
|
|
@ -321,7 +321,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, maybeCachedSrc, nil, dest, systemContext, options.ManifestType)); err != nil {
|
||||
if manifestBytes, err = cp.Image(ctx, policyContext, dest, maybeCachedSrc, getCopyOptions(options.Store, options.ReportWriter, nil, systemContext, options.ManifestType)); 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, sourceReference types.ImageReference, sourceSystemContext *types.SystemContext, destinationReference types.ImageReference, destinationSystemContext *types.SystemContext, manifestType string) *cp.Options {
|
||||
func getCopyOptions(store storage.Store, reportWriter io.Writer, sourceSystemContext *types.SystemContext, destinationSystemContext *types.SystemContext, manifestType string) *cp.Options {
|
||||
sourceCtx := getSystemContext(store, nil, "")
|
||||
if sourceSystemContext != nil {
|
||||
*sourceCtx = *sourceSystemContext
|
||||
|
|
|
|||
|
|
@ -565,7 +565,7 @@ func (b *Builder) SetHealthcheck(config *docker.HealthConfig) {
|
|||
}
|
||||
|
||||
// AddPrependedEmptyLayer adds an item to the history that we'll create when
|
||||
// commiting the image, after any history we inherit from the base image, but
|
||||
// committing the image, after any history we inherit from the base image, but
|
||||
// before the history item that we'll use to describe the new layer that we're
|
||||
// adding.
|
||||
func (b *Builder) AddPrependedEmptyLayer(created *time.Time, createdBy, author, comment string) {
|
||||
|
|
@ -589,7 +589,7 @@ func (b *Builder) ClearPrependedEmptyLayers() {
|
|||
}
|
||||
|
||||
// AddAppendedEmptyLayer adds an item to the history that we'll create when
|
||||
// commiting the image, after the history item that we'll use to describe the
|
||||
// committing the image, after the history item that we'll use to describe the
|
||||
// new layer that we're adding.
|
||||
func (b *Builder) AddAppendedEmptyLayer(created *time.Time, createdBy, author, comment string) {
|
||||
if created != nil {
|
||||
|
|
|
|||
|
|
@ -161,18 +161,11 @@ type V1Image struct {
|
|||
// V2Image stores the image configuration
|
||||
type V2Image struct {
|
||||
V1Image
|
||||
Parent ID `json:"parent,omitempty"`
|
||||
Parent ID `json:"parent,omitempty"` // nolint:govet
|
||||
RootFS *V2S2RootFS `json:"rootfs,omitempty"`
|
||||
History []V2S2History `json:"history,omitempty"`
|
||||
OSVersion string `json:"os.version,omitempty"`
|
||||
OSFeatures []string `json:"os.features,omitempty"`
|
||||
|
||||
// rawJSON caches the immutable JSON associated with this image.
|
||||
rawJSON []byte
|
||||
|
||||
// computedID is the ID computed from the hash of the image config.
|
||||
// Not to be confused with the legacy V1 ID in V1Image.
|
||||
computedID ID
|
||||
}
|
||||
|
||||
// github.com/docker/distribution/manifest/versioned.go
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
module github.com/containers/buildah
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.2.0 // indirect
|
||||
github.com/DataDog/zstd v1.4.0 // indirect
|
||||
github.com/Microsoft/hcsshim v0.8.3 // indirect
|
||||
github.com/VividCortex/ewma v1.1.1 // indirect
|
||||
github.com/blang/semver v3.5.0+incompatible // indirect
|
||||
github.com/containerd/continuity v0.0.0-20181203112020-004b46473808 // indirect
|
||||
github.com/containernetworking/cni v0.7.0-rc2
|
||||
github.com/containers/image v2.0.0+incompatible
|
||||
github.com/containers/storage v1.12.13
|
||||
github.com/cyphar/filepath-securejoin v0.2.1
|
||||
github.com/docker/distribution v0.0.0-20170817175659-5f6282db7d65
|
||||
github.com/docker/docker-credential-helpers v0.6.1 // indirect
|
||||
github.com/docker/go-units v0.3.3
|
||||
github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
|
||||
github.com/etcd-io/bbolt v1.3.2
|
||||
github.com/fsouza/go-dockerclient v1.3.0
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/gogo/protobuf v1.2.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
github.com/imdario/mergo v0.3.6 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/ishidawataru/sctp v0.0.0-20180918013207-6e2cb1366111 // indirect
|
||||
github.com/klauspost/compress v1.4.1 // indirect
|
||||
github.com/klauspost/cpuid v1.2.0 // indirect
|
||||
github.com/klauspost/pgzip v1.2.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.4 // indirect
|
||||
github.com/mattn/go-shellwords v1.0.3
|
||||
github.com/mistifyio/go-zfs v2.1.1+incompatible // indirect
|
||||
github.com/moby/moby v0.0.0-20171005181806-f8806b18b4b9 // indirect
|
||||
github.com/mtrmac/gpgme v0.0.0-20170102180018-b2432428689c // indirect
|
||||
github.com/onsi/ginkgo v1.6.0
|
||||
github.com/onsi/gomega v1.4.3
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/opencontainers/runc v1.0.0-rc8
|
||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7
|
||||
github.com/opencontainers/runtime-tools v0.9.0
|
||||
github.com/opencontainers/selinux v1.2.2
|
||||
github.com/openshift/imagebuilder v1.1.0
|
||||
github.com/ostreedev/ostree-go v0.0.0-20181112201119-9ab99253d365 // indirect
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13 // indirect
|
||||
github.com/seccomp/containers-golang v0.0.0-20180629143253-cdfdaa7543f4
|
||||
github.com/seccomp/libseccomp-golang v0.9.0
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/spf13/cobra v0.0.3
|
||||
github.com/spf13/pflag v1.0.3
|
||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
|
||||
github.com/tchap/go-patricia v2.2.6+incompatible // indirect
|
||||
github.com/ulikunitz/xz v0.5.5 // indirect
|
||||
github.com/vbatts/tar-split v0.10.2 // indirect
|
||||
github.com/vbauerster/mpb v3.3.4+incompatible // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.1.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc
|
||||
golang.org/x/net v0.0.0-20190107210223-45ffb0cd1ba0 // indirect
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894
|
||||
gopkg.in/yaml.v2 v2.2.2 // indirect
|
||||
k8s.io/client-go v0.0.0-20181219152756-3dd551c0f083 // indirect
|
||||
)
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
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/BurntSushi/toml v0.2.0 h1:OthAm9ZSUx4uAmn3WbPwc06nowWrByRwBsYRhbmFjBs=
|
||||
github.com/BurntSushi/toml v0.2.0/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
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 h1:zoIOcVf0xPN1tnMVbTtEdI+P8OofVk3NObnwOQ6nK2Q=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Microsoft/hcsshim v0.8.3 h1:KWCdVGOju81E0RL4ndn9/E6I4qMBi6kuPw1W4yBYlCw=
|
||||
github.com/Microsoft/hcsshim v0.8.3/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||
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/containerd/continuity v0.0.0-20180814194400-c7c5070e6f6e/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20181203112020-004b46473808 h1:4BX8f882bXEDKfWIf0wa8HRvpnBoPszJJXL+TVbBw4M=
|
||||
github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containernetworking/cni v0.7.0-rc2 h1:2GGDhbwdWPY53iT7LXy+LBP76Ch2D/hnw1U2zVFfGbk=
|
||||
github.com/containernetworking/cni v0.7.0-rc2/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containers/image v2.0.0+incompatible h1:FTr6Br7jlIKNCKMjSOMbAxKp2keQ0//jzJaYNTVhauk=
|
||||
github.com/containers/image v2.0.0+incompatible/go.mod h1:8Vtij257IWSanUQKe1tAeNOm2sRVkSqQTVQ1IlwI3+M=
|
||||
github.com/containers/storage v1.12.13 h1:GtaLCY8p1Drlk1Oew581jGvB137UaO+kpz0HII67T0A=
|
||||
github.com/containers/storage v1.12.13/go.mod h1:+RirK6VQAqskQlaTBrOG6ulDvn4si2QjFE1NZCn06MM=
|
||||
github.com/cyphar/filepath-securejoin v0.2.1 h1:5DPkzz/0MwUpvR4fxASKzgApeq2OMFY5FfYtrX28Coo=
|
||||
github.com/cyphar/filepath-securejoin v0.2.1/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docker/distribution v0.0.0-20170817175659-5f6282db7d65 h1:4zlOyrJUbYnrvlzChJ+jP2J3i77Jbhm336NEuCv7kZo=
|
||||
github.com/docker/distribution v0.0.0-20170817175659-5f6282db7d65/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v0.7.3-0.20180827131323-0c5f8d2b9b23 h1:mJtkfC9RUrUWHMk0cFDNhVoc9U3k2FRAzEZ+5pqSIHo=
|
||||
github.com/docker/docker v0.7.3-0.20180827131323-0c5f8d2b9b23/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
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=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/libnetwork v0.8.0-dev.2.0.20180608203834-19279f049241/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8=
|
||||
github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316 h1:moehPjPiGUaWdwgOl92xRyFHJyaqXDHcCyW9M6nmCK4=
|
||||
github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8=
|
||||
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/etcd-io/bbolt v1.3.2 h1:RLRQ0TKLX7DlBRXAJHvbmXL17Q3KNnTBtZ9B6Qo+/Y0=
|
||||
github.com/etcd-io/bbolt v1.3.2/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsouza/go-dockerclient v1.3.0 h1:tOXkq/5++XihrAvH5YNwCTdPeQg3XVcC6WI2FVy4ZS0=
|
||||
github.com/fsouza/go-dockerclient v1.3.0/go.mod h1:IN9UPc4/w7cXiARH2Yg99XxUHbAM+6rAi9hzBVbkWRU=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
||||
github.com/imdario/mergo v0.3.6/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/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/klauspost/compress v1.4.1 h1:8VMb5+0wMgdBykOV96DwNwKFQ+WTI4pzYURP99CcB9E=
|
||||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
|
||||
github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
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-shellwords v1.0.3 h1:K/VxK7SZ+cvuPgFSLKi5QPI9Vr/ipOf4C1gN+ntueUk=
|
||||
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
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/moby/moby v0.0.0-20171005181806-f8806b18b4b9/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
|
||||
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/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
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=
|
||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7 h1:Dliu5QO+4JYWu/yMshaMU7G3JN2POGpwjJN7gjy10Go=
|
||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-tools v0.9.0 h1:FYgwVsKRI/H9hU32MJ/4MLOzXWodKK5zsQavY8NPMkU=
|
||||
github.com/opencontainers/runtime-tools v0.9.0/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
||||
github.com/opencontainers/selinux v1.2.2 h1:Kx9J6eDG5/24A6DtUquGSpJQ+m2MUTahn4FtGEe8bFg=
|
||||
github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
|
||||
github.com/openshift/imagebuilder v1.1.0 h1:oT704SkwMEzmIMU/+Uv1Wmvt+p10q3v2WuYMeFI18c4=
|
||||
github.com/openshift/imagebuilder v1.1.0/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
|
||||
github.com/ostreedev/ostree-go v0.0.0-20181112201119-9ab99253d365 h1:5DKEDlc/DLftia3h4tk5K0KBiqBXogCc6EarWTlD3fM=
|
||||
github.com/ostreedev/ostree-go v0.0.0-20181112201119-9ab99253d365/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
|
||||
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13 h1:AUK/hm/tPsiNNASdb3J8fySVRZoI7fnK5mlOvdFD43o=
|
||||
github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
|
||||
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/libseccomp-golang v0.9.0 h1:S1pmhdFh5spQtVojA+4GUdWBqvI8ydYHxrx8iR6xN8o=
|
||||
github.com/seccomp/libseccomp-golang v0.9.0/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=
|
||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tchap/go-patricia v2.2.6+incompatible h1:JvoDL7JSoIP2HDE8AbDH3zC8QBPxmzYe32HHy5yQ+Ck=
|
||||
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||
github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=
|
||||
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/vbatts/tar-split v0.10.2 h1:CXd7HEKGkTLjBMinpObcJZU5Hm8EKlor2a1JtX6msXQ=
|
||||
github.com/vbatts/tar-split v0.10.2/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g=
|
||||
github.com/vbauerster/mpb v3.3.4+incompatible h1:DDIhnwmgTQIDZo+SWlEr5d6mJBxkOLBwCXPzunhEfJ4=
|
||||
github.com/vbauerster/mpb v3.3.4+incompatible/go.mod h1:zAHG26FUhVKETRu+MWqYXcI70POlC6N8up9p1dID7SU=
|
||||
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||
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/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 v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg=
|
||||
github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc h1:F5tKCVGp+MUAHhKp5MZtGqAlGX3+oCsiL1Q629FL90M=
|
||||
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
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-20190107210223-45ffb0cd1ba0 h1:1DW40AJQ7AP4nY6ORUGUdkpXyEC9W2GAXcOPaMZK0K8=
|
||||
golang.org/x/net v0.0.0-20190107210223-45ffb0cd1ba0/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
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=
|
||||
|
|
@ -23,7 +23,7 @@ import (
|
|||
"github.com/containers/storage/pkg/ioutils"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
specs "github.com/opencontainers/image-spec/specs-go"
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
|
@ -128,6 +128,10 @@ func computeLayerMIMEType(what string, layerCompression archive.Compression) (om
|
|||
// Until the image specs define a media type for xz-compressed layers, even if we know
|
||||
// how to decompress them, we can't try to compress layers with xz.
|
||||
return "", "", errors.New("media type for xz-compressed layers is not defined")
|
||||
case archive.Zstd:
|
||||
// Until the image specs define a media type for zstd-compressed layers, even if we know
|
||||
// how to decompress them, we can't try to compress layers with zstd.
|
||||
return "", "", errors.New("media type for zstd-compressed layers is not defined")
|
||||
default:
|
||||
logrus.Debugf("compressing %s with unknown compressor(?)", what)
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -209,7 +209,7 @@ func getSymbolicLink(path string) (string, error) {
|
|||
}
|
||||
// if isSymlink is true, check if resolvedPath is potentially another symlink
|
||||
// keep doing this till resolvedPath is not a symlink and isSymlink is false
|
||||
for isSymlink == true {
|
||||
for isSymlink {
|
||||
// Need to keep track of number of symlinks resolved
|
||||
// Will also return an error if the symlink points to itself as that will exceed maxSymlinksResolved
|
||||
if symLinksResolved >= maxSymlinksResolved {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,538 @@
|
|||
package imagebuildah
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/buildah"
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/image/docker/reference"
|
||||
is "github.com/containers/image/storage"
|
||||
"github.com/containers/image/transports"
|
||||
"github.com/containers/image/transports/alltransports"
|
||||
"github.com/containers/image/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/openshift/imagebuilder"
|
||||
"github.com/openshift/imagebuilder/dockerfile/parser"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// builtinAllowedBuildArgs is list of built-in allowed build args. Normally we
|
||||
// complain if we're given values for arguments which have no corresponding ARG
|
||||
// instruction in the Dockerfile, since that's usually an indication of a user
|
||||
// error, but for these values we make exceptions and ignore them.
|
||||
var builtinAllowedBuildArgs = map[string]bool{
|
||||
"HTTP_PROXY": true,
|
||||
"http_proxy": true,
|
||||
"HTTPS_PROXY": true,
|
||||
"https_proxy": true,
|
||||
"FTP_PROXY": true,
|
||||
"ftp_proxy": true,
|
||||
"NO_PROXY": true,
|
||||
"no_proxy": true,
|
||||
}
|
||||
|
||||
// Executor is a buildah-based implementation of the imagebuilder.Executor
|
||||
// interface. It coordinates the entire build by using one StageExecutors to
|
||||
// handle each stage of the build.
|
||||
type Executor struct {
|
||||
stages map[string]*StageExecutor
|
||||
store storage.Store
|
||||
contextDir string
|
||||
pullPolicy buildah.PullPolicy
|
||||
registry string
|
||||
ignoreUnrecognizedInstructions bool
|
||||
quiet bool
|
||||
runtime string
|
||||
runtimeArgs []string
|
||||
transientMounts []Mount
|
||||
compression archive.Compression
|
||||
output string
|
||||
outputFormat string
|
||||
additionalTags []string
|
||||
log func(format string, args ...interface{})
|
||||
in io.Reader
|
||||
out io.Writer
|
||||
err io.Writer
|
||||
signaturePolicyPath string
|
||||
systemContext *types.SystemContext
|
||||
reportWriter io.Writer
|
||||
isolation buildah.Isolation
|
||||
namespaceOptions []buildah.NamespaceOption
|
||||
configureNetwork buildah.NetworkConfigurationPolicy
|
||||
cniPluginPath string
|
||||
cniConfigDir string
|
||||
idmappingOptions *buildah.IDMappingOptions
|
||||
commonBuildOptions *buildah.CommonBuildOptions
|
||||
defaultMountsFilePath string
|
||||
iidfile string
|
||||
squash bool
|
||||
labels []string
|
||||
annotations []string
|
||||
layers bool
|
||||
useCache bool
|
||||
removeIntermediateCtrs bool
|
||||
forceRmIntermediateCtrs bool
|
||||
imageMap map[string]string // Used to map images that we create to handle the AS construct.
|
||||
containerMap map[string]*buildah.Builder // Used to map from image names to only-created-for-the-rootfs containers.
|
||||
baseMap map[string]bool // Holds the names of every base image, as given.
|
||||
rootfsMap map[string]bool // Holds the names of every stage whose rootfs is referenced in a COPY or ADD instruction.
|
||||
blobDirectory string
|
||||
excludes []string
|
||||
unusedArgs map[string]struct{}
|
||||
buildArgs map[string]string
|
||||
}
|
||||
|
||||
// NewExecutor creates a new instance of the imagebuilder.Executor interface.
|
||||
func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Node) (*Executor, error) {
|
||||
excludes, err := imagebuilder.ParseDockerignore(options.ContextDirectory)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exec := Executor{
|
||||
store: store,
|
||||
contextDir: options.ContextDirectory,
|
||||
excludes: excludes,
|
||||
pullPolicy: options.PullPolicy,
|
||||
registry: options.Registry,
|
||||
ignoreUnrecognizedInstructions: options.IgnoreUnrecognizedInstructions,
|
||||
quiet: options.Quiet,
|
||||
runtime: options.Runtime,
|
||||
runtimeArgs: options.RuntimeArgs,
|
||||
transientMounts: options.TransientMounts,
|
||||
compression: options.Compression,
|
||||
output: options.Output,
|
||||
outputFormat: options.OutputFormat,
|
||||
additionalTags: options.AdditionalTags,
|
||||
signaturePolicyPath: options.SignaturePolicyPath,
|
||||
systemContext: options.SystemContext,
|
||||
log: options.Log,
|
||||
in: options.In,
|
||||
out: options.Out,
|
||||
err: options.Err,
|
||||
reportWriter: options.ReportWriter,
|
||||
isolation: options.Isolation,
|
||||
namespaceOptions: options.NamespaceOptions,
|
||||
configureNetwork: options.ConfigureNetwork,
|
||||
cniPluginPath: options.CNIPluginPath,
|
||||
cniConfigDir: options.CNIConfigDir,
|
||||
idmappingOptions: options.IDMappingOptions,
|
||||
commonBuildOptions: options.CommonBuildOpts,
|
||||
defaultMountsFilePath: options.DefaultMountsFilePath,
|
||||
iidfile: options.IIDFile,
|
||||
squash: options.Squash,
|
||||
labels: append([]string{}, options.Labels...),
|
||||
annotations: append([]string{}, options.Annotations...),
|
||||
layers: options.Layers,
|
||||
useCache: !options.NoCache,
|
||||
removeIntermediateCtrs: options.RemoveIntermediateCtrs,
|
||||
forceRmIntermediateCtrs: options.ForceRmIntermediateCtrs,
|
||||
imageMap: make(map[string]string),
|
||||
containerMap: make(map[string]*buildah.Builder),
|
||||
baseMap: make(map[string]bool),
|
||||
rootfsMap: make(map[string]bool),
|
||||
blobDirectory: options.BlobDirectory,
|
||||
unusedArgs: make(map[string]struct{}),
|
||||
buildArgs: options.Args,
|
||||
}
|
||||
if exec.err == nil {
|
||||
exec.err = os.Stderr
|
||||
}
|
||||
if exec.out == nil {
|
||||
exec.out = os.Stdout
|
||||
}
|
||||
if exec.log == nil {
|
||||
stepCounter := 0
|
||||
exec.log = func(format string, args ...interface{}) {
|
||||
stepCounter++
|
||||
prefix := fmt.Sprintf("STEP %d: ", stepCounter)
|
||||
suffix := "\n"
|
||||
fmt.Fprintf(exec.err, prefix+format+suffix, args...)
|
||||
}
|
||||
}
|
||||
for arg := range options.Args {
|
||||
if _, isBuiltIn := builtinAllowedBuildArgs[arg]; !isBuiltIn {
|
||||
exec.unusedArgs[arg] = struct{}{}
|
||||
}
|
||||
}
|
||||
for _, line := range mainNode.Children {
|
||||
node := line
|
||||
for node != nil { // tokens on this line, though we only care about the first
|
||||
switch strings.ToUpper(node.Value) { // first token - instruction
|
||||
case "ARG":
|
||||
arg := node.Next
|
||||
if arg != nil {
|
||||
// We have to be careful here - it's either an argument
|
||||
// and value, or just an argument, since they can be
|
||||
// separated by either "=" or whitespace.
|
||||
list := strings.SplitN(arg.Value, "=", 2)
|
||||
if _, stillUnused := exec.unusedArgs[list[0]]; stillUnused {
|
||||
delete(exec.unusedArgs, list[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return &exec, nil
|
||||
}
|
||||
|
||||
// startStage creates a new stage executor that will be referenced whenever a
|
||||
// COPY or ADD statement uses a --from=NAME flag.
|
||||
func (b *Executor) startStage(name string, index, stages int, from, output string) *StageExecutor {
|
||||
if b.stages == nil {
|
||||
b.stages = make(map[string]*StageExecutor)
|
||||
}
|
||||
stage := &StageExecutor{
|
||||
executor: b,
|
||||
index: index,
|
||||
stages: stages,
|
||||
name: name,
|
||||
volumeCache: make(map[string]string),
|
||||
volumeCacheInfo: make(map[string]os.FileInfo),
|
||||
output: output,
|
||||
}
|
||||
b.stages[name] = stage
|
||||
b.stages[from] = stage
|
||||
if idx := strconv.Itoa(index); idx != name {
|
||||
b.stages[idx] = stage
|
||||
}
|
||||
return stage
|
||||
}
|
||||
|
||||
// resolveNameToImageRef creates a types.ImageReference for the output name in local storage
|
||||
func (b *Executor) resolveNameToImageRef(output string) (types.ImageReference, error) {
|
||||
imageRef, err := alltransports.ParseImageName(output)
|
||||
if err != nil {
|
||||
candidates, _, _, err := util.ResolveName(output, "", b.systemContext, b.store)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error parsing target image name %q", output)
|
||||
}
|
||||
if len(candidates) == 0 {
|
||||
return nil, errors.Errorf("error parsing target image name %q", output)
|
||||
}
|
||||
imageRef2, err2 := is.Transport.ParseStoreReference(b.store, candidates[0])
|
||||
if err2 != nil {
|
||||
return nil, errors.Wrapf(err, "error parsing target image name %q", output)
|
||||
}
|
||||
return imageRef2, nil
|
||||
}
|
||||
return imageRef, nil
|
||||
}
|
||||
|
||||
// getImageHistory returns the history of imageID.
|
||||
func (b *Executor) getImageHistory(ctx context.Context, imageID string) ([]v1.History, error) {
|
||||
imageRef, err := is.Transport.ParseStoreReference(b.store, "@"+imageID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error getting image reference %q", imageID)
|
||||
}
|
||||
ref, err := imageRef.NewImage(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error creating new image from reference to image %q", imageID)
|
||||
}
|
||||
defer ref.Close()
|
||||
oci, err := ref.OCIConfig(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error getting possibly-converted OCI config of image %q", imageID)
|
||||
}
|
||||
return oci.History, nil
|
||||
}
|
||||
|
||||
// getCreatedBy returns the command the image at node will be created by.
|
||||
func (b *Executor) getCreatedBy(node *parser.Node) string {
|
||||
if node == nil {
|
||||
return "/bin/sh"
|
||||
}
|
||||
if node.Value == "run" {
|
||||
buildArgs := b.getBuildArgs()
|
||||
if buildArgs != "" {
|
||||
return "|" + strconv.Itoa(len(strings.Split(buildArgs, " "))) + " " + buildArgs + " /bin/sh -c " + node.Original[4:]
|
||||
}
|
||||
return "/bin/sh -c " + node.Original[4:]
|
||||
}
|
||||
return "/bin/sh -c #(nop) " + node.Original
|
||||
}
|
||||
|
||||
// historyMatches returns true if a candidate history matches the history of our
|
||||
// base image (if we have one), plus the current instruction.
|
||||
// Used to verify whether a cache of the intermediate image exists and whether
|
||||
// to run the build again.
|
||||
func (b *Executor) historyMatches(baseHistory []v1.History, child *parser.Node, history []v1.History) bool {
|
||||
if len(baseHistory) >= len(history) {
|
||||
return false
|
||||
}
|
||||
if len(history)-len(baseHistory) != 1 {
|
||||
return false
|
||||
}
|
||||
for i := range baseHistory {
|
||||
if baseHistory[i].CreatedBy != history[i].CreatedBy {
|
||||
return false
|
||||
}
|
||||
if baseHistory[i].Comment != history[i].Comment {
|
||||
return false
|
||||
}
|
||||
if baseHistory[i].Author != history[i].Author {
|
||||
return false
|
||||
}
|
||||
if baseHistory[i].EmptyLayer != history[i].EmptyLayer {
|
||||
return false
|
||||
}
|
||||
if baseHistory[i].Created != nil && history[i].Created == nil {
|
||||
return false
|
||||
}
|
||||
if baseHistory[i].Created == nil && history[i].Created != nil {
|
||||
return false
|
||||
}
|
||||
if baseHistory[i].Created != nil && history[i].Created != nil && *baseHistory[i].Created != *history[i].Created {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return history[len(baseHistory)].CreatedBy == b.getCreatedBy(child)
|
||||
}
|
||||
|
||||
// getBuildArgs returns a string of the build-args specified during the build process
|
||||
// it excludes any build-args that were not used in the build process
|
||||
func (b *Executor) getBuildArgs() string {
|
||||
var buildArgs []string
|
||||
for k, v := range b.buildArgs {
|
||||
if _, ok := b.unusedArgs[k]; !ok {
|
||||
buildArgs = append(buildArgs, k+"="+v)
|
||||
}
|
||||
}
|
||||
sort.Strings(buildArgs)
|
||||
return strings.Join(buildArgs, " ")
|
||||
}
|
||||
|
||||
// Build takes care of the details of running Prepare/Execute/Commit/Delete
|
||||
// over each of the one or more parsed Dockerfiles and stages.
|
||||
func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (imageID string, ref reference.Canonical, err error) {
|
||||
if len(stages) == 0 {
|
||||
return "", nil, errors.New("error building: no stages to build")
|
||||
}
|
||||
var cleanupImages []string
|
||||
cleanupStages := make(map[int]*StageExecutor)
|
||||
|
||||
cleanup := func() error {
|
||||
var lastErr error
|
||||
// Clean up any containers associated with the final container
|
||||
// built by a stage, for stages that succeeded, since we no
|
||||
// longer need their filesystem contents.
|
||||
for _, stage := range cleanupStages {
|
||||
if err := stage.Delete(); err != nil {
|
||||
logrus.Debugf("Failed to cleanup stage containers: %v", err)
|
||||
lastErr = err
|
||||
}
|
||||
}
|
||||
cleanupStages = nil
|
||||
// Clean up any builders that we used to get data from images.
|
||||
for _, builder := range b.containerMap {
|
||||
if err := builder.Delete(); err != nil {
|
||||
logrus.Debugf("Failed to cleanup image containers: %v", err)
|
||||
lastErr = err
|
||||
}
|
||||
}
|
||||
b.containerMap = nil
|
||||
// Clean up any intermediate containers associated with stages,
|
||||
// since we're not keeping them for debugging.
|
||||
if b.removeIntermediateCtrs {
|
||||
if err := b.deleteSuccessfulIntermediateCtrs(); err != nil {
|
||||
logrus.Debugf("Failed to cleanup intermediate containers: %v", err)
|
||||
lastErr = err
|
||||
}
|
||||
}
|
||||
// Remove images from stages except the last one, since we're
|
||||
// not going to use them as a starting point for any new
|
||||
// stages.
|
||||
for i := range cleanupImages {
|
||||
removeID := cleanupImages[len(cleanupImages)-i-1]
|
||||
if removeID == imageID {
|
||||
continue
|
||||
}
|
||||
if _, err := b.store.DeleteImage(removeID, true); err != nil {
|
||||
logrus.Debugf("failed to remove intermediate image %q: %v", removeID, err)
|
||||
if b.forceRmIntermediateCtrs || errors.Cause(err) != storage.ErrImageUsedByContainer {
|
||||
lastErr = err
|
||||
}
|
||||
}
|
||||
}
|
||||
cleanupImages = nil
|
||||
return lastErr
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if cleanupErr := cleanup(); cleanupErr != nil {
|
||||
if err == nil {
|
||||
err = cleanupErr
|
||||
} else {
|
||||
err = errors.Wrap(err, cleanupErr.Error())
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Build maps of every named base image and every referenced stage root
|
||||
// filesystem. Individual stages can use them to determine whether or
|
||||
// not they can skip certain steps near the end of their stages.
|
||||
for _, stage := range stages {
|
||||
node := stage.Node // first line
|
||||
for node != nil { // each line
|
||||
for _, child := range node.Children { // tokens on this line, though we only care about the first
|
||||
switch strings.ToUpper(child.Value) { // first token - instruction
|
||||
case "FROM":
|
||||
if child.Next != nil { // second token on this line
|
||||
base := child.Next.Value
|
||||
if base != "scratch" {
|
||||
// TODO: this didn't undergo variable and arg
|
||||
// expansion, so if the AS clause in another
|
||||
// FROM instruction uses argument values,
|
||||
// we might not record the right value here.
|
||||
b.baseMap[base] = true
|
||||
logrus.Debugf("base: %q", base)
|
||||
}
|
||||
}
|
||||
case "ADD", "COPY":
|
||||
for _, flag := range child.Flags { // flags for this instruction
|
||||
if strings.HasPrefix(flag, "--from=") {
|
||||
// TODO: this didn't undergo variable and
|
||||
// arg expansion, so if the previous stage
|
||||
// was named using argument values, we might
|
||||
// not record the right value here.
|
||||
rootfs := flag[7:]
|
||||
b.rootfsMap[rootfs] = true
|
||||
logrus.Debugf("rootfs: %q", rootfs)
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
node = node.Next // next line
|
||||
}
|
||||
}
|
||||
|
||||
// Run through the build stages, one at a time.
|
||||
for stageIndex, stage := range stages {
|
||||
var lastErr error
|
||||
|
||||
ib := stage.Builder
|
||||
node := stage.Node
|
||||
base, err := ib.From(node)
|
||||
if err != nil {
|
||||
logrus.Debugf("Build(node.Children=%#v)", node.Children)
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
// If this is the last stage, then the image that we produce at
|
||||
// its end should be given the desired output name.
|
||||
output := ""
|
||||
if stageIndex == len(stages)-1 {
|
||||
output = b.output
|
||||
}
|
||||
|
||||
stageExecutor := b.startStage(stage.Name, stage.Position, len(stages), base, output)
|
||||
|
||||
// If this a single-layer build, or if it's a multi-layered
|
||||
// build and b.forceRmIntermediateCtrs is set, make sure we
|
||||
// remove the intermediate/build containers, regardless of
|
||||
// whether or not the stage's build fails.
|
||||
if b.forceRmIntermediateCtrs || !b.layers {
|
||||
cleanupStages[stage.Position] = stageExecutor
|
||||
}
|
||||
|
||||
// Build this stage.
|
||||
if imageID, ref, err = stageExecutor.Execute(ctx, stage, base); err != nil {
|
||||
lastErr = err
|
||||
}
|
||||
if lastErr != nil {
|
||||
return "", nil, lastErr
|
||||
}
|
||||
|
||||
// The stage succeeded, so remove its build container if we're
|
||||
// told to delete successful intermediate/build containers for
|
||||
// multi-layered builds.
|
||||
if b.removeIntermediateCtrs {
|
||||
cleanupStages[stage.Position] = stageExecutor
|
||||
}
|
||||
|
||||
// If this is an intermediate stage, make a note of the ID, so
|
||||
// that we can look it up later.
|
||||
if stageIndex < len(stages)-1 && imageID != "" {
|
||||
b.imageMap[stage.Name] = imageID
|
||||
// We're not populating the cache with intermediate
|
||||
// images, so add this one to the list of images that
|
||||
// we'll remove later.
|
||||
if !b.layers {
|
||||
cleanupImages = append(cleanupImages, imageID)
|
||||
}
|
||||
imageID = ""
|
||||
}
|
||||
}
|
||||
|
||||
if len(b.unusedArgs) > 0 {
|
||||
unusedList := make([]string, 0, len(b.unusedArgs))
|
||||
for k := range b.unusedArgs {
|
||||
unusedList = append(unusedList, k)
|
||||
}
|
||||
sort.Strings(unusedList)
|
||||
fmt.Fprintf(b.out, "[Warning] one or more build args were not consumed: %v\n", unusedList)
|
||||
}
|
||||
|
||||
if len(b.additionalTags) > 0 {
|
||||
if dest, err := b.resolveNameToImageRef(b.output); err == nil {
|
||||
switch dest.Transport().Name() {
|
||||
case is.Transport.Name():
|
||||
img, err := is.Transport.GetStoreImage(b.store, dest)
|
||||
if err != nil {
|
||||
return imageID, ref, errors.Wrapf(err, "error locating just-written image %q", transports.ImageName(dest))
|
||||
}
|
||||
if err = util.AddImageNames(b.store, "", b.systemContext, img, b.additionalTags); err != nil {
|
||||
return imageID, ref, errors.Wrapf(err, "error setting image names to %v", append(img.Names, b.additionalTags...))
|
||||
}
|
||||
logrus.Debugf("assigned names %v to image %q", img.Names, img.ID)
|
||||
default:
|
||||
logrus.Warnf("don't know how to add tags to images stored in %q transport", dest.Transport().Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := cleanup(); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
return imageID, ref, nil
|
||||
}
|
||||
|
||||
// deleteSuccessfulIntermediateCtrs goes through the container IDs in each
|
||||
// stage's containerIDs list and deletes the containers associated with those
|
||||
// IDs.
|
||||
func (b *Executor) deleteSuccessfulIntermediateCtrs() error {
|
||||
var lastErr error
|
||||
for _, s := range b.stages {
|
||||
for _, ctr := range s.containerIDs {
|
||||
if err := b.store.DeleteContainer(ctr); err != nil {
|
||||
logrus.Errorf("error deleting build container %q: %v\n", ctr, err)
|
||||
lastErr = err
|
||||
}
|
||||
}
|
||||
// The stages map includes some stages under multiple keys, so
|
||||
// clearing their lists after we process a given stage is
|
||||
// necessary to avoid triggering errors that would occur if we
|
||||
// tried to delete a given stage's containers multiple times.
|
||||
s.containerIDs = nil
|
||||
}
|
||||
return lastErr
|
||||
}
|
||||
1156
vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
generated
vendored
Normal file
1156
vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -12,6 +12,7 @@ import (
|
|||
|
||||
"github.com/containers/buildah"
|
||||
"github.com/containers/storage/pkg/chrootarchive"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
|
@ -105,21 +106,23 @@ func TempDirForURL(dir, prefix, url string) (name string, subdir string, err err
|
|||
return "", "", errors.Errorf("unreachable code reached")
|
||||
}
|
||||
|
||||
func dedupeStringSlice(slice []string) []string {
|
||||
done := make([]string, 0, len(slice))
|
||||
m := make(map[string]struct{})
|
||||
for _, s := range slice {
|
||||
if _, present := m[s]; !present {
|
||||
m[s] = struct{}{}
|
||||
done = append(done, s)
|
||||
}
|
||||
}
|
||||
return done
|
||||
}
|
||||
|
||||
// InitReexec is a wrapper for buildah.InitReexec(). It should be called at
|
||||
// the start of main(), and if it returns true, main() should return
|
||||
// immediately.
|
||||
func InitReexec() bool {
|
||||
return buildah.InitReexec()
|
||||
}
|
||||
|
||||
func convertMounts(mounts []Mount) []specs.Mount {
|
||||
specmounts := []specs.Mount{}
|
||||
for _, m := range mounts {
|
||||
s := specs.Mount{
|
||||
Destination: m.Destination,
|
||||
Type: m.Type,
|
||||
Source: m.Source,
|
||||
Options: m.Options,
|
||||
}
|
||||
specmounts = append(specmounts, s)
|
||||
}
|
||||
return specmounts
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/containers/buildah/docker"
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/image/manifest"
|
||||
is "github.com/containers/image/storage"
|
||||
"github.com/containers/image/types"
|
||||
"github.com/containers/storage"
|
||||
|
|
@ -47,6 +48,13 @@ func importBuilderDataFromImage(ctx context.Context, store storage.Store, system
|
|||
}
|
||||
}
|
||||
|
||||
imageDigest := ""
|
||||
if manifestBytes, _, err := src.Manifest(ctx); err == nil {
|
||||
if manifestDigest, err := manifest.Digest(manifestBytes); err == nil {
|
||||
imageDigest = manifestDigest.String()
|
||||
}
|
||||
}
|
||||
|
||||
defaultNamespaceOptions, err := DefaultNamespaceOptions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -57,6 +65,7 @@ func importBuilderDataFromImage(ctx context.Context, store storage.Store, system
|
|||
Type: containerType,
|
||||
FromImage: imageName,
|
||||
FromImageID: imageID,
|
||||
FromImageDigest: imageDigest,
|
||||
Container: containerName,
|
||||
ContainerID: containerID,
|
||||
ImageAnnotations: map[string]string{},
|
||||
|
|
|
|||
|
|
@ -27,10 +27,7 @@ type InfoData struct {
|
|||
func Info(store storage.Store) ([]InfoData, error) {
|
||||
info := []InfoData{}
|
||||
// get host information
|
||||
hostInfo, err := hostInfo()
|
||||
if err != nil {
|
||||
logrus.Error(err, "error getting host info")
|
||||
}
|
||||
hostInfo := hostInfo()
|
||||
info = append(info, InfoData{Type: "host", Data: hostInfo})
|
||||
|
||||
// get store information
|
||||
|
|
@ -42,7 +39,7 @@ func Info(store storage.Store) ([]InfoData, error) {
|
|||
return info, nil
|
||||
}
|
||||
|
||||
func hostInfo() (map[string]interface{}, error) {
|
||||
func hostInfo() map[string]interface{} {
|
||||
info := map[string]interface{}{}
|
||||
info["os"] = runtime.GOOS
|
||||
info["arch"] = runtime.GOARCH
|
||||
|
|
@ -115,8 +112,7 @@ func hostInfo() (map[string]interface{}, error) {
|
|||
}
|
||||
info["hostname"] = host
|
||||
|
||||
return info, nil
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
// top-level "store" info
|
||||
|
|
|
|||
|
|
@ -274,16 +274,7 @@ The build steps on Debian are otherwise the same as Ubuntu, above.
|
|||
|
||||
## Vendoring - Dependency Management
|
||||
|
||||
This project is using [vndr](https://github.com/LK4D4/vndr) for managing dependencies, which is a tedious and error-prone task. Doing it manually is likely to cause inconsistencies between the `./vendor` directory (i.e., the downloaded dependencies), the source code that imports those dependencies and the `vendor.conf` configuration file that describes which packages in which version (e.g., a release or git commit) are a dependency.
|
||||
|
||||
To ease updating dependencies, we provide the `make vendor` target, which fetches all dependencies mentioned in `vendor.conf`. `make vendor` whitelists certain packages to prevent the `vndr` tool from removing packages that the test suite (see `./test`) imports.
|
||||
|
||||
The CI of this project makes sure that each pull request leaves a clean vendor state behind by first running the aforementioned `make vendor` followed by running `./hack/tree_status.sh` which checks if any file in the git tree has changed.
|
||||
|
||||
### Vendor Troubleshooting
|
||||
|
||||
If the CI is complaining about a pull request leaving behind an unclean state, it is very likely right about it. Make sure to run `make vendor` and add all the changes to the commit. Also make sure that your local git tree does not include files not under version control that may reference other go packages. If some dependencies are removed but they should not, for instance, because the CI is needing them, then whitelist those dependencies in the `make vendor` target of the Makefile. Whitelisting a package will instruct `vndr` to not remove if during its cleanup phase.
|
||||
sd
|
||||
This project is using [go modules](https://github.com/golang/go/wiki/Modules) for dependency management. If the CI is complaining about a pull request leaving behind an unclean state, it is very likely right about it. After changing dependencies, make sure to run `make vendor` to synchronize the code with the go module and repopulate the `./vendor` directory.
|
||||
|
||||
## Configuration files
|
||||
|
||||
|
|
@ -383,3 +374,14 @@ cat /etc/containers/policy.json
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Vendoring
|
||||
|
||||
Buildah uses Go Modules for vendoring purposes. If you need to update or add a vendored package into Buildah, please follow this proceedure:
|
||||
* Enter into your sandbox `src/github.com/containers/buildah` and ensure that he GOPATH variable is set to the directory prior as noted above.
|
||||
* `export GO111MODULE=on`
|
||||
* Assuming you want to 'bump' the `github.com/containers/storage` package to version 1.12.13, use this command: `go get github.com/containers/storage@v1.12.13`
|
||||
* `make vendor`
|
||||
* `make`
|
||||
* `make install`
|
||||
* Then add any updated or added files with `git add` then do a `git commit` and create a PR.
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/image/manifest"
|
||||
"github.com/containers/image/pkg/sysregistries"
|
||||
is "github.com/containers/image/storage"
|
||||
"github.com/containers/image/transports"
|
||||
|
|
@ -254,6 +255,7 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
|
|||
}
|
||||
image := options.FromImage
|
||||
imageID := ""
|
||||
imageDigest := ""
|
||||
topLayer := ""
|
||||
if img != nil {
|
||||
image = getImageName(imageNamePrefix(image), img)
|
||||
|
|
@ -266,6 +268,11 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
|
|||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error instantiating image for %q", transports.ImageName(ref))
|
||||
}
|
||||
if manifestBytes, _, err := src.Manifest(ctx); err == nil {
|
||||
if manifestDigest, err := manifest.Digest(manifestBytes); err == nil {
|
||||
imageDigest = manifestDigest.String()
|
||||
}
|
||||
}
|
||||
defer src.Close()
|
||||
}
|
||||
|
||||
|
|
@ -327,6 +334,7 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
|
|||
Type: containerType,
|
||||
FromImage: image,
|
||||
FromImageID: imageID,
|
||||
FromImageDigest: imageDigest,
|
||||
Container: name,
|
||||
ContainerID: container.ID,
|
||||
ImageAnnotations: map[string]string{},
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import (
|
|||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/containers/storage/pkg/ioutils"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
|
@ -83,7 +83,7 @@ func makeFilename(blobSum digest.Digest, isConfig bool) string {
|
|||
|
||||
// NewBlobCache creates a new blob cache that wraps an image reference. Any blobs which are
|
||||
// written to the destination image created from the resulting reference will also be stored
|
||||
// as-is to the specifed directory or a temporary directory. The cache directory's contents
|
||||
// as-is to the specified directory or a temporary directory. The cache directory's contents
|
||||
// can be cleared by calling the returned BlobCache()'s ClearCache() method.
|
||||
// The compress argument controls whether or not the cache will try to substitute a compressed
|
||||
// or different version of a blob when preparing the list of layers when reading an image.
|
||||
|
|
@ -379,7 +379,9 @@ func saveStream(wg *sync.WaitGroup, decompressReader io.ReadCloser, tempFile *os
|
|||
_, err3 = io.Copy(io.MultiWriter(tempFile, digester.Hash()), decompressed)
|
||||
} else {
|
||||
// Drain the pipe to keep from stalling the PutBlob() thread.
|
||||
io.Copy(ioutil.Discard, decompressReader)
|
||||
if _, err := io.Copy(ioutil.Discard, decompressReader); err != nil {
|
||||
logrus.Debugf("error draining the pipe: %v", err)
|
||||
}
|
||||
}
|
||||
decompressReader.Close()
|
||||
decompressed.Close()
|
||||
|
|
|
|||
|
|
@ -118,7 +118,9 @@ func GetNameSpaceFlags(flags *NameSpaceResults) pflag.FlagSet {
|
|||
fs.StringVar(&flags.Network, string(specs.NetworkNamespace), "", "'container', `path` of network namespace to join, or 'host'")
|
||||
// TODO How do we alias net and network?
|
||||
fs.StringVar(&flags.Network, "net", "", "'container', `path` of network namespace to join, or 'host'")
|
||||
fs.MarkHidden("net")
|
||||
if err := fs.MarkHidden("net"); err != nil {
|
||||
panic(fmt.Sprintf("error marking net flag as hidden: %v", err))
|
||||
}
|
||||
fs.StringVar(&flags.CNIConfigDir, "cni-config-dir", util.DefaultCNIConfigDir, "`directory` of CNI configuration files")
|
||||
fs.StringVar(&flags.CNIPlugInPath, "cni-plugin-path", util.DefaultCNIPluginPath, "`path` of CNI network plugins")
|
||||
fs.StringVar(&flags.PID, string(specs.PIDNamespace), "", "container, `path` of PID namespace to join, or 'host'")
|
||||
|
|
@ -172,7 +174,9 @@ func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults,
|
|||
fs := pflag.FlagSet{}
|
||||
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")
|
||||
fs.MarkHidden("blob-cache")
|
||||
if err := fs.MarkHidden("blob-cache"); err != nil {
|
||||
panic(fmt.Sprintf("error marking net flag as hidden: %v", err))
|
||||
}
|
||||
fs.StringSliceVar(&flags.CapAdd, "cap-add", []string{}, "add the specified capability when running (default [])")
|
||||
fs.StringSliceVar(&flags.CapDrop, "cap-drop", []string{}, "drop the specified capability when running (default [])")
|
||||
fs.StringVar(&flags.CgroupParent, "cgroup-parent", "", "optional parent cgroup for the container")
|
||||
|
|
|
|||
|
|
@ -30,6 +30,17 @@ const (
|
|||
SeccompDefaultPath = "/usr/share/containers/seccomp.json"
|
||||
// SeccompOverridePath if this exists it overrides the default seccomp path
|
||||
SeccompOverridePath = "/etc/crio/seccomp.json"
|
||||
// TypeBind is the type for mounting host dir
|
||||
TypeBind = "bind"
|
||||
// TypeTmpfs is the type for mounting tmpfs
|
||||
TypeTmpfs = "tmpfs"
|
||||
)
|
||||
|
||||
var (
|
||||
errBadMntOption = errors.Errorf("invalid mount option")
|
||||
errDuplicateDest = errors.Errorf("duplicate mount destination")
|
||||
optionArgError = errors.Errorf("must provide an argument for option")
|
||||
noDestError = errors.Errorf("must set volume destination")
|
||||
)
|
||||
|
||||
// CommonBuildOptions parses the build options from the bud cli
|
||||
|
|
@ -168,13 +179,14 @@ func parseSecurityOpts(securityOpts []string, commonOpts *buildah.CommonBuildOpt
|
|||
return nil
|
||||
}
|
||||
|
||||
// ParseVolume parses the input of --volume
|
||||
func ParseVolume(volume string) (specs.Mount, error) {
|
||||
mount := specs.Mount{}
|
||||
arr := strings.SplitN(volume, ":", 3)
|
||||
if len(arr) < 2 {
|
||||
return mount, errors.Errorf("incorrect volume format %q, should be host-dir:ctr-dir[:option]", volume)
|
||||
}
|
||||
if err := ValidateVolumeHostDir(arr[0]); err != nil {
|
||||
if err := validateVolumeMountHostDir(arr[0]); err != nil {
|
||||
return mount, err
|
||||
}
|
||||
if err := ValidateVolumeCtrDir(arr[1]); err != nil {
|
||||
|
|
@ -183,7 +195,7 @@ func ParseVolume(volume string) (specs.Mount, error) {
|
|||
mountOptions := ""
|
||||
if len(arr) > 2 {
|
||||
mountOptions = arr[2]
|
||||
if err := ValidateVolumeOpts(arr[2]); err != nil {
|
||||
if _, err := ValidateVolumeOpts(strings.Split(arr[2], ",")); err != nil {
|
||||
return mount, err
|
||||
}
|
||||
}
|
||||
|
|
@ -208,7 +220,227 @@ func ParseVolumes(volumes []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getVolumeMounts(volumes []string) (map[string]specs.Mount, error) {
|
||||
finalVolumeMounts := make(map[string]specs.Mount)
|
||||
|
||||
for _, volume := range volumes {
|
||||
volumeMount, err := ParseVolume(volume)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := finalVolumeMounts[volumeMount.Destination]; ok {
|
||||
return nil, errors.Wrapf(errDuplicateDest, volumeMount.Destination)
|
||||
}
|
||||
finalVolumeMounts[volumeMount.Destination] = volumeMount
|
||||
}
|
||||
return finalVolumeMounts, nil
|
||||
}
|
||||
|
||||
// GetVolumes gets the volumes from --volume and --mount
|
||||
func GetVolumes(volumes []string, mounts []string) ([]specs.Mount, error) {
|
||||
unifiedMounts, err := getMounts(mounts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
volumeMounts, err := getVolumeMounts(volumes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for dest, mount := range volumeMounts {
|
||||
if _, ok := unifiedMounts[dest]; ok {
|
||||
return nil, errors.Wrapf(errDuplicateDest, dest)
|
||||
}
|
||||
unifiedMounts[dest] = mount
|
||||
}
|
||||
|
||||
finalMounts := make([]specs.Mount, 0, len(unifiedMounts))
|
||||
for _, mount := range unifiedMounts {
|
||||
finalMounts = append(finalMounts, mount)
|
||||
}
|
||||
return finalMounts, nil
|
||||
}
|
||||
|
||||
// getMounts takes user-provided input from the --mount flag and creates OCI
|
||||
// spec mounts.
|
||||
// buildah run --mount type=bind,src=/etc/resolv.conf,target=/etc/resolv.conf ...
|
||||
// buildah run --mount type=tmpfs,target=/dev/shm ...
|
||||
func getMounts(mounts []string) (map[string]specs.Mount, error) {
|
||||
finalMounts := make(map[string]specs.Mount)
|
||||
|
||||
errInvalidSyntax := errors.Errorf("incorrect mount format: should be --mount type=<bind|tmpfs>,[src=<host-dir>,]target=<ctr-dir>[,options]")
|
||||
|
||||
// TODO(vrothberg): the manual parsing can be replaced with a regular expression
|
||||
// to allow a more robust parsing of the mount format and to give
|
||||
// precise errors regarding supported format versus suppored options.
|
||||
for _, mount := range mounts {
|
||||
arr := strings.SplitN(mount, ",", 2)
|
||||
if len(arr) < 2 {
|
||||
return nil, errors.Wrapf(errInvalidSyntax, "%q", mount)
|
||||
}
|
||||
kv := strings.Split(arr[0], "=")
|
||||
// TODO: type is not explicitly required in Docker.
|
||||
// If not specified, it defaults to "volume".
|
||||
if len(kv) != 2 || kv[0] != "type" {
|
||||
return nil, errors.Wrapf(errInvalidSyntax, "%q", mount)
|
||||
}
|
||||
|
||||
tokens := strings.Split(arr[1], ",")
|
||||
switch kv[1] {
|
||||
case TypeBind:
|
||||
mount, err := GetBindMount(tokens)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := finalMounts[mount.Destination]; ok {
|
||||
return nil, errors.Wrapf(errDuplicateDest, mount.Destination)
|
||||
}
|
||||
finalMounts[mount.Destination] = mount
|
||||
case TypeTmpfs:
|
||||
mount, err := GetTmpfsMount(tokens)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := finalMounts[mount.Destination]; ok {
|
||||
return nil, errors.Wrapf(errDuplicateDest, mount.Destination)
|
||||
}
|
||||
finalMounts[mount.Destination] = mount
|
||||
default:
|
||||
return nil, errors.Errorf("invalid filesystem type %q", kv[1])
|
||||
}
|
||||
}
|
||||
|
||||
return finalMounts, nil
|
||||
}
|
||||
|
||||
// GetBindMount parses a single bind mount entry from the --mount flag.
|
||||
func GetBindMount(args []string) (specs.Mount, error) {
|
||||
newMount := specs.Mount{
|
||||
Type: TypeBind,
|
||||
}
|
||||
|
||||
setSource := false
|
||||
setDest := false
|
||||
|
||||
for _, val := range args {
|
||||
kv := strings.Split(val, "=")
|
||||
switch kv[0] {
|
||||
case "bind-nonrecursive":
|
||||
newMount.Options = append(newMount.Options, "bind")
|
||||
case "ro", "nosuid", "nodev", "noexec":
|
||||
// TODO: detect duplication of these options.
|
||||
// (Is this necessary?)
|
||||
newMount.Options = append(newMount.Options, kv[0])
|
||||
case "shared", "rshared", "private", "rprivate", "slave", "rslave", "Z", "z":
|
||||
newMount.Options = append(newMount.Options, kv[0])
|
||||
case "bind-propagation":
|
||||
if len(kv) == 1 {
|
||||
return newMount, errors.Wrapf(optionArgError, kv[0])
|
||||
}
|
||||
newMount.Options = append(newMount.Options, kv[1])
|
||||
case "src", "source":
|
||||
if len(kv) == 1 {
|
||||
return newMount, errors.Wrapf(optionArgError, kv[0])
|
||||
}
|
||||
if err := ValidateVolumeHostDir(kv[1]); err != nil {
|
||||
return newMount, err
|
||||
}
|
||||
newMount.Source = kv[1]
|
||||
setSource = true
|
||||
case "target", "dst", "destination":
|
||||
if len(kv) == 1 {
|
||||
return newMount, errors.Wrapf(optionArgError, kv[0])
|
||||
}
|
||||
if err := ValidateVolumeCtrDir(kv[1]); err != nil {
|
||||
return newMount, err
|
||||
}
|
||||
newMount.Destination = kv[1]
|
||||
setDest = true
|
||||
default:
|
||||
return newMount, errors.Wrapf(errBadMntOption, kv[0])
|
||||
}
|
||||
}
|
||||
|
||||
if !setDest {
|
||||
return newMount, noDestError
|
||||
}
|
||||
|
||||
if !setSource {
|
||||
newMount.Source = newMount.Destination
|
||||
}
|
||||
|
||||
opts, err := ValidateVolumeOpts(newMount.Options)
|
||||
if err != nil {
|
||||
return newMount, err
|
||||
}
|
||||
newMount.Options = opts
|
||||
|
||||
return newMount, nil
|
||||
}
|
||||
|
||||
// GetTmpfsMount parses a single tmpfs mount entry from the --mount flag
|
||||
func GetTmpfsMount(args []string) (specs.Mount, error) {
|
||||
newMount := specs.Mount{
|
||||
Type: TypeTmpfs,
|
||||
Source: TypeTmpfs,
|
||||
}
|
||||
|
||||
setDest := false
|
||||
|
||||
for _, val := range args {
|
||||
kv := strings.Split(val, "=")
|
||||
switch kv[0] {
|
||||
case "ro", "nosuid", "nodev", "noexec":
|
||||
newMount.Options = append(newMount.Options, kv[0])
|
||||
case "tmpfs-mode":
|
||||
if len(kv) == 1 {
|
||||
return newMount, errors.Wrapf(optionArgError, kv[0])
|
||||
}
|
||||
newMount.Options = append(newMount.Options, fmt.Sprintf("mode=%s", kv[1]))
|
||||
case "tmpfs-size":
|
||||
if len(kv) == 1 {
|
||||
return newMount, errors.Wrapf(optionArgError, kv[0])
|
||||
}
|
||||
newMount.Options = append(newMount.Options, fmt.Sprintf("size=%s", kv[1]))
|
||||
case "src", "source":
|
||||
return newMount, errors.Errorf("source is not supported with tmpfs mounts")
|
||||
case "target", "dst", "destination":
|
||||
if len(kv) == 1 {
|
||||
return newMount, errors.Wrapf(optionArgError, kv[0])
|
||||
}
|
||||
if err := ValidateVolumeCtrDir(kv[1]); err != nil {
|
||||
return newMount, err
|
||||
}
|
||||
newMount.Destination = kv[1]
|
||||
setDest = true
|
||||
default:
|
||||
return newMount, errors.Wrapf(errBadMntOption, kv[0])
|
||||
}
|
||||
}
|
||||
|
||||
if !setDest {
|
||||
return newMount, noDestError
|
||||
}
|
||||
|
||||
return newMount, nil
|
||||
}
|
||||
|
||||
// ValidateVolumeHostDir validates a volume mount's source directory
|
||||
func ValidateVolumeHostDir(hostDir string) error {
|
||||
if len(hostDir) == 0 {
|
||||
return errors.Errorf("host directory cannot be empty")
|
||||
}
|
||||
if filepath.IsAbs(hostDir) {
|
||||
if _, err := os.Stat(hostDir); err != nil {
|
||||
return errors.Wrapf(err, "error checking path %q", hostDir)
|
||||
}
|
||||
}
|
||||
// If hostDir is not an absolute path, that means the user wants to create a
|
||||
// named volume. This will be done later on in the code.
|
||||
return nil
|
||||
}
|
||||
|
||||
// validates the host path of buildah --volume
|
||||
func validateVolumeMountHostDir(hostDir string) error {
|
||||
if !filepath.IsAbs(hostDir) {
|
||||
return errors.Errorf("invalid host path, must be an absolute path %q", hostDir)
|
||||
}
|
||||
|
|
@ -218,41 +450,60 @@ func ValidateVolumeHostDir(hostDir string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ValidateVolumeCtrDir validates a volume mount's destination directory.
|
||||
func ValidateVolumeCtrDir(ctrDir string) error {
|
||||
if len(ctrDir) == 0 {
|
||||
return errors.Errorf("container directory cannot be empty")
|
||||
}
|
||||
if !filepath.IsAbs(ctrDir) {
|
||||
return errors.Errorf("invalid container path, must be an absolute path %q", ctrDir)
|
||||
return errors.Errorf("invalid container path %q, must be an absolute path", ctrDir)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateVolumeOpts(option string) error {
|
||||
var foundRootPropagation, foundRWRO, foundLabelChange int
|
||||
options := strings.Split(option, ",")
|
||||
// ValidateVolumeOpts validates a volume's options
|
||||
func ValidateVolumeOpts(options []string) ([]string, error) {
|
||||
var foundRootPropagation, foundRWRO, foundLabelChange, bindType int
|
||||
finalOpts := make([]string, 0, len(options))
|
||||
for _, opt := range options {
|
||||
switch opt {
|
||||
case "rw", "ro":
|
||||
if foundRWRO > 1 {
|
||||
return errors.Errorf("invalid options %q, can only specify 1 'rw' or 'ro' option", option)
|
||||
return nil, errors.Errorf("invalid options %q, can only specify 1 'rw' or 'ro' option", strings.Join(options, ", "))
|
||||
}
|
||||
foundRWRO++
|
||||
case "z", "Z", "O":
|
||||
if opt == "O" && unshare.IsRootless() {
|
||||
return errors.Errorf("invalid options %q, overlay mounts not supported in rootless mode", option)
|
||||
return nil, errors.Errorf("invalid options %q, overlay mounts not supported in rootless mode", strings.Join(options, ", "))
|
||||
}
|
||||
if foundLabelChange > 1 {
|
||||
return errors.Errorf("invalid options %q, can only specify 1 'z', 'Z', or 'O' option", option)
|
||||
return nil, errors.Errorf("invalid options %q, can only specify 1 'z', 'Z', or 'O' option", strings.Join(options, ", "))
|
||||
}
|
||||
foundLabelChange++
|
||||
case "private", "rprivate", "shared", "rshared", "slave", "rslave", "unbindable", "runbindable":
|
||||
if foundRootPropagation > 1 {
|
||||
return errors.Errorf("invalid options %q, can only specify 1 '[r]shared', '[r]private', '[r]slave' or '[r]unbindable' option", option)
|
||||
return nil, errors.Errorf("invalid options %q, can only specify 1 '[r]shared', '[r]private', '[r]slave' or '[r]unbindable' option", strings.Join(options, ", "))
|
||||
}
|
||||
foundRootPropagation++
|
||||
case "bind", "rbind":
|
||||
bindType++
|
||||
if bindType > 1 {
|
||||
return nil, errors.Errorf("invalid options %q, can only specify 1 '[r]bind' option", strings.Join(options, ", "))
|
||||
}
|
||||
case "cached", "delegated":
|
||||
// The discarded ops are OS X specific volume options
|
||||
// introduced in a recent Docker version.
|
||||
// They have no meaning on Linux, so here we silently
|
||||
// drop them. This matches Docker's behavior (the options
|
||||
// are intended to be always safe to use, even not on OS
|
||||
// X).
|
||||
continue
|
||||
default:
|
||||
return errors.Errorf("invalid option type %q", option)
|
||||
return nil, errors.Errorf("invalid option type %q", opt)
|
||||
}
|
||||
finalOpts = append(finalOpts, opt)
|
||||
}
|
||||
return nil
|
||||
return finalOpts, nil
|
||||
}
|
||||
|
||||
// validateExtraHost validates that the specified string is a valid extrahost and returns it.
|
||||
|
|
@ -538,7 +789,7 @@ func NamespaceOptions(c *cobra.Command) (namespaceOptions buildah.NamespaceOptio
|
|||
Host: true,
|
||||
})
|
||||
default:
|
||||
if what == specs.NetworkNamespace {
|
||||
if what == string(specs.NetworkNamespace) {
|
||||
if how == "none" {
|
||||
options.AddOrReplace(buildah.NamespaceOption{
|
||||
Name: what,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package parse
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -128,7 +128,9 @@ func (c *Cmd) Start() error {
|
|||
// Read the child's PID from the pipe.
|
||||
pidString := ""
|
||||
b := new(bytes.Buffer)
|
||||
io.Copy(b, pidRead)
|
||||
if _, err := io.Copy(b, pidRead); err != nil {
|
||||
return errors.Wrapf(err, "error reading child PID")
|
||||
}
|
||||
pidString = b.String()
|
||||
pid, err := strconv.Atoi(pidString)
|
||||
if err != nil {
|
||||
|
|
@ -457,32 +459,38 @@ func MaybeReexecUsingUserNamespace(evenForRoot bool) {
|
|||
|
||||
// Finish up.
|
||||
logrus.Debugf("running %+v with environment %+v, UID map %+v, and GID map %+v", cmd.Cmd.Args, os.Environ(), cmd.UidMappings, cmd.GidMappings)
|
||||
ExecRunnable(cmd)
|
||||
ExecRunnable(cmd, nil)
|
||||
}
|
||||
|
||||
// ExecRunnable runs the specified unshare command, captures its exit status,
|
||||
// and exits with the same status.
|
||||
func ExecRunnable(cmd Runnable) {
|
||||
func ExecRunnable(cmd Runnable, cleanup func()) {
|
||||
exit := func(status int) {
|
||||
if cleanup != nil {
|
||||
cleanup()
|
||||
}
|
||||
os.Exit(status)
|
||||
}
|
||||
if err := cmd.Run(); err != nil {
|
||||
if exitError, ok := errors.Cause(err).(*exec.ExitError); ok {
|
||||
if exitError.ProcessState.Exited() {
|
||||
if waitStatus, ok := exitError.ProcessState.Sys().(syscall.WaitStatus); ok {
|
||||
if waitStatus.Exited() {
|
||||
logrus.Errorf("%v", exitError)
|
||||
os.Exit(waitStatus.ExitStatus())
|
||||
exit(waitStatus.ExitStatus())
|
||||
}
|
||||
if waitStatus.Signaled() {
|
||||
logrus.Errorf("%v", exitError)
|
||||
os.Exit(int(waitStatus.Signal()) + 128)
|
||||
exit(int(waitStatus.Signal()) + 128)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logrus.Errorf("%v", err)
|
||||
logrus.Errorf("(unable to determine exit status)")
|
||||
os.Exit(1)
|
||||
exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
exit(0)
|
||||
}
|
||||
|
||||
// getHostIDMappings reads mappings from the named node under /proc.
|
||||
|
|
|
|||
|
|
@ -195,7 +195,9 @@ func Pull(ctx context.Context, imageName string, options PullOptions) (imageID s
|
|||
return "", errors.Wrapf(err, "internal error creating docker.Transport reference for %s", tagged.String())
|
||||
}
|
||||
if options.ReportWriter != nil {
|
||||
options.ReportWriter.Write([]byte("Pulling " + tagged.String() + "\n"))
|
||||
if _, err := options.ReportWriter.Write([]byte("Pulling " + tagged.String() + "\n")); err != nil {
|
||||
return "", errors.Wrapf(err, "error writing pull report")
|
||||
}
|
||||
}
|
||||
ref, err := pullImage(ctx, options.Store, taggedRef, options, systemContext)
|
||||
if err != nil {
|
||||
|
|
@ -263,7 +265,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, srcRef, sc, maybeCachedDestRef, nil, "")); err != nil {
|
||||
if _, err := cp.Image(ctx, policyContext, maybeCachedDestRef, srcRef, getCopyOptions(store, options.ReportWriter, sc, nil, "")); err != nil {
|
||||
logrus.Debugf("error copying src image [%q] to dest image [%q] err: %v", transports.ImageName(srcRef), destName, err)
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ func (b *Builder) Run(command []string, options RunOptions) error {
|
|||
}
|
||||
|
||||
if !(contains(volumes, "/etc/resolv.conf") || (len(b.CommonBuildOpts.DNSServers) == 1 && strings.ToLower(b.CommonBuildOpts.DNSServers[0]) == "none")) {
|
||||
resolvFile, err := b.addNetworkConfig(path, "/etc/resolv.conf", rootIDPair, b.CommonBuildOpts.DNSServers, b.CommonBuildOpts.DNSSearch, b.CommonBuildOpts.DNSOptions)
|
||||
resolvFile, err := b.addNetworkConfig(path, "/etc/resolv.conf", rootIDPair, b.CommonBuildOpts.DNSServers, b.CommonBuildOpts.DNSSearch, b.CommonBuildOpts.DNSOptions, namespaceOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -217,7 +217,7 @@ func (b *Builder) Run(command []string, options RunOptions) error {
|
|||
if options.NoPivot {
|
||||
moreCreateArgs = append(moreCreateArgs, "--no-pivot")
|
||||
}
|
||||
if err := setupRootlessSpecChanges(spec, path, rootUID, rootGID, b.CommonBuildOpts.ShmSize); err != nil {
|
||||
if err := setupRootlessSpecChanges(spec, path, b.CommonBuildOpts.ShmSize); err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, configureNetworks, moreCreateArgs, spec, mountPoint, path, Package+"-"+filepath.Base(path))
|
||||
|
|
@ -411,10 +411,7 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st
|
|||
}
|
||||
|
||||
// Get the list of files we need to bind into the container.
|
||||
bindFileMounts, err := runSetupBoundFiles(bundlePath, bindFiles)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bindFileMounts := runSetupBoundFiles(bundlePath, bindFiles)
|
||||
|
||||
// After this point we need to know the per-container persistent storage directory.
|
||||
cdir, err := b.store.ContainerDirectory(b.ContainerID)
|
||||
|
|
@ -462,7 +459,7 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st
|
|||
}
|
||||
|
||||
// addNetworkConfig copies files from host and sets them up to bind mount into container
|
||||
func (b *Builder) addNetworkConfig(rdir, hostPath string, chownOpts *idtools.IDPair, dnsServers, dnsSearch, dnsOptions []string) (string, error) {
|
||||
func (b *Builder) addNetworkConfig(rdir, hostPath string, chownOpts *idtools.IDPair, dnsServers, dnsSearch, dnsOptions []string, namespaceOptions NamespaceOptions) (string, error) {
|
||||
stat, err := os.Stat(hostPath)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "error statting %q for container %q", hostPath, b.ContainerID)
|
||||
|
|
@ -479,6 +476,16 @@ func (b *Builder) addNetworkConfig(rdir, hostPath string, chownOpts *idtools.IDP
|
|||
if len(dnsSearch) > 0 {
|
||||
search = dnsSearch
|
||||
}
|
||||
|
||||
if b.Isolation == IsolationOCIRootless {
|
||||
ns := namespaceOptions.Find(string(specs.NetworkNamespace))
|
||||
if ns != nil && !ns.Host && ns.Path == "" {
|
||||
// if we are using slirp4netns, also add the built-in DNS server.
|
||||
logrus.Debugf("adding slirp4netns 10.0.2.3 built-in DNS server")
|
||||
nameservers = append([]string{"10.0.2.3"}, nameservers...)
|
||||
}
|
||||
}
|
||||
|
||||
if len(dnsServers) != 0 {
|
||||
dns, err := getDNSIP(dnsServers)
|
||||
if err != nil {
|
||||
|
|
@ -589,7 +596,7 @@ func setupTerminal(g *generate.Generator, terminalPolicy TerminalPolicy, termina
|
|||
}
|
||||
}
|
||||
|
||||
func runUsingRuntime(isolation Isolation, options RunOptions, configureNetwork bool, configureNetworks, moreCreateArgs []string, spec *specs.Spec, rootPath, bundlePath, containerName string) (wstatus unix.WaitStatus, err error) {
|
||||
func runUsingRuntime(isolation Isolation, options RunOptions, configureNetwork bool, configureNetworks, moreCreateArgs []string, spec *specs.Spec, bundlePath, containerName string) (wstatus unix.WaitStatus, err error) {
|
||||
// Lock the caller to a single OS-level thread.
|
||||
runtime.LockOSThread()
|
||||
|
||||
|
|
@ -944,8 +951,8 @@ func setupRootlessNetwork(pid int) (teardown func(), err error) {
|
|||
}
|
||||
|
||||
return func() {
|
||||
cmd.Process.Kill()
|
||||
cmd.Wait()
|
||||
cmd.Process.Kill() // nolint:errcheck
|
||||
cmd.Wait() // nolint:errcheck
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -1131,17 +1138,17 @@ func runCopyStdio(stdio *sync.WaitGroup, copyPipes bool, stdioPipe [][]int, copy
|
|||
if err := setNonblock(rfd, readDesc[rfd], true); err != nil {
|
||||
return
|
||||
}
|
||||
setNonblock(wfd, writeDesc[wfd], false)
|
||||
setNonblock(wfd, writeDesc[wfd], false) // nolint:errcheck
|
||||
}
|
||||
|
||||
if copyPipes {
|
||||
setNonblock(stdioPipe[unix.Stdin][1], writeDesc[stdioPipe[unix.Stdin][1]], true)
|
||||
setNonblock(stdioPipe[unix.Stdin][1], writeDesc[stdioPipe[unix.Stdin][1]], true) // nolint:errcheck
|
||||
}
|
||||
|
||||
runCopyStdioPassData(stdio, copyPipes, stdioPipe, copyConsole, consoleListener, finishCopy, finishedCopy, spec, relayMap, relayBuffer, readDesc, writeDesc)
|
||||
runCopyStdioPassData(copyPipes, stdioPipe, finishCopy, relayMap, relayBuffer, readDesc, writeDesc)
|
||||
}
|
||||
|
||||
func runCopyStdioPassData(stdio *sync.WaitGroup, copyPipes bool, stdioPipe [][]int, copyConsole bool, consoleListener *net.UnixListener, finishCopy []int, finishedCopy chan struct{}, spec *specs.Spec, relayMap map[int]int, relayBuffer map[int]*bytes.Buffer, readDesc map[int]string, writeDesc map[int]string) {
|
||||
func runCopyStdioPassData(copyPipes bool, stdioPipe [][]int, finishCopy []int, relayMap map[int]int, relayBuffer map[int]*bytes.Buffer, readDesc map[int]string, writeDesc map[int]string) {
|
||||
closeStdin := false
|
||||
|
||||
// Pass data back and forth.
|
||||
|
|
@ -1383,7 +1390,7 @@ func runUsingRuntimeMain() {
|
|||
os.Exit(1)
|
||||
}
|
||||
// Run the container, start to finish.
|
||||
status, err := runUsingRuntime(options.Isolation, options.Options, options.ConfigureNetwork, options.ConfigureNetworks, options.MoreCreateArgs, options.Spec, options.RootPath, options.BundlePath, options.ContainerName)
|
||||
status, err := runUsingRuntime(options.Isolation, options.Options, options.ConfigureNetwork, options.ConfigureNetworks, options.MoreCreateArgs, options.Spec, options.BundlePath, options.ContainerName)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error running container: %v\n", err)
|
||||
os.Exit(1)
|
||||
|
|
@ -1439,7 +1446,7 @@ func setupNamespaces(g *generate.Generator, namespaceOptions NamespaceOptions, i
|
|||
|
||||
// If we've got mappings, we're going to have to create a user namespace.
|
||||
if len(idmapOptions.UIDMap) > 0 || len(idmapOptions.GIDMap) > 0 || configureUserns {
|
||||
if err := g.AddOrReplaceLinuxNamespace(specs.UserNamespace, ""); err != nil {
|
||||
if err := g.AddOrReplaceLinuxNamespace(string(specs.UserNamespace), ""); err != nil {
|
||||
return false, nil, false, errors.Wrapf(err, "error adding new %q namespace for run", string(specs.UserNamespace))
|
||||
}
|
||||
hostUidmap, hostGidmap, err := unshare.GetHostIDMappings("")
|
||||
|
|
@ -1463,17 +1470,17 @@ func setupNamespaces(g *generate.Generator, namespaceOptions NamespaceOptions, i
|
|||
}
|
||||
}
|
||||
if !specifiedNetwork {
|
||||
if err := g.AddOrReplaceLinuxNamespace(specs.NetworkNamespace, ""); err != nil {
|
||||
if err := g.AddOrReplaceLinuxNamespace(string(specs.NetworkNamespace), ""); err != nil {
|
||||
return false, nil, false, errors.Wrapf(err, "error adding new %q namespace for run", string(specs.NetworkNamespace))
|
||||
}
|
||||
configureNetwork = (policy != NetworkDisabled)
|
||||
}
|
||||
} else {
|
||||
if err := g.RemoveLinuxNamespace(specs.UserNamespace); err != nil {
|
||||
if err := g.RemoveLinuxNamespace(string(specs.UserNamespace)); err != nil {
|
||||
return false, nil, false, errors.Wrapf(err, "error removing %q namespace for run", string(specs.UserNamespace))
|
||||
}
|
||||
if !specifiedNetwork {
|
||||
if err := g.RemoveLinuxNamespace(specs.NetworkNamespace); err != nil {
|
||||
if err := g.RemoveLinuxNamespace(string(specs.NetworkNamespace)); err != nil {
|
||||
return false, nil, false, errors.Wrapf(err, "error removing %q namespace for run", string(specs.NetworkNamespace))
|
||||
}
|
||||
}
|
||||
|
|
@ -1544,7 +1551,7 @@ func (b *Builder) configureNamespaces(g *generate.Generator, options RunOptions)
|
|||
return configureNetwork, configureNetworks, nil
|
||||
}
|
||||
|
||||
func runSetupBoundFiles(bundlePath string, bindFiles map[string]string) (mounts []specs.Mount, err error) {
|
||||
func runSetupBoundFiles(bundlePath string, bindFiles map[string]string) (mounts []specs.Mount) {
|
||||
for dest, src := range bindFiles {
|
||||
options := []string{"rbind"}
|
||||
if strings.HasPrefix(src, bundlePath) {
|
||||
|
|
@ -1557,7 +1564,7 @@ func runSetupBoundFiles(bundlePath string, bindFiles map[string]string) (mounts
|
|||
Options: options,
|
||||
})
|
||||
}
|
||||
return mounts, nil
|
||||
return mounts
|
||||
}
|
||||
|
||||
func addRlimits(ulimit []string, g *generate.Generator) error {
|
||||
|
|
@ -1598,7 +1605,7 @@ func (b *Builder) runSetupVolumeMounts(mountLabel string, volumeMounts []string,
|
|||
return nil, errors.Wrapf(err, "error cleaning up overlay content for %s", b.ContainerID)
|
||||
}
|
||||
|
||||
parseMount := func(host, container string, options []string) (specs.Mount, error) {
|
||||
parseMount := func(mountType, host, container string, options []string) (specs.Mount, error) {
|
||||
var foundrw, foundro, foundz, foundZ, foundO bool
|
||||
var rootProp string
|
||||
for _, opt := range options {
|
||||
|
|
@ -1641,18 +1648,22 @@ func (b *Builder) runSetupVolumeMounts(mountLabel string, volumeMounts []string,
|
|||
if rootProp == "" {
|
||||
options = append(options, "private")
|
||||
}
|
||||
if mountType != "tmpfs" {
|
||||
mountType = "bind"
|
||||
options = append(options, "rbind")
|
||||
}
|
||||
return specs.Mount{
|
||||
Destination: container,
|
||||
Type: "bind",
|
||||
Type: mountType,
|
||||
Source: host,
|
||||
Options: append(options, "rbind"),
|
||||
Options: options,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Bind mount volumes specified for this particular Run() invocation
|
||||
for _, i := range optionMounts {
|
||||
logrus.Debugf("setting up mounted volume at %q", i.Destination)
|
||||
mount, err := parseMount(i.Source, i.Destination, i.Options)
|
||||
mount, err := parseMount(i.Type, i.Source, i.Destination, i.Options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1666,7 +1677,7 @@ func (b *Builder) runSetupVolumeMounts(mountLabel string, volumeMounts []string,
|
|||
options = strings.Split(spliti[2], ",")
|
||||
}
|
||||
options = append(options, "rbind")
|
||||
mount, err := parseMount(spliti[0], spliti[1], options)
|
||||
mount, err := parseMount("bind", spliti[0], spliti[1], options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1878,7 +1889,7 @@ func (b *Builder) configureEnvironment(g *generate.Generator, options RunOptions
|
|||
}
|
||||
}
|
||||
|
||||
func setupRootlessSpecChanges(spec *specs.Spec, bundleDir string, rootUID, rootGID uint32, shmSize string) error {
|
||||
func setupRootlessSpecChanges(spec *specs.Spec, bundleDir string, shmSize string) error {
|
||||
spec.Hostname = ""
|
||||
spec.Process.User.AdditionalGids = nil
|
||||
spec.Linux.Resources = nil
|
||||
|
|
|
|||
|
|
@ -107,4 +107,24 @@ lstat /home/myusername/~: no such file or directory
|
|||
|
||||
* Replace `~` with `$HOME` or the fully specified directory `/home/myusername`.
|
||||
* `$ sudo buildah push alpine oci:${HOME}/myalpine:latest`
|
||||
|
||||
|
||||
---
|
||||
### 5) Rootless buildah bud fails EPERM on NFS:
|
||||
|
||||
NFS enforces file creation on different UIDs on the server side and does not understand User Namespace.
|
||||
When a container root process like YUM attempts to create a file owned by a different UID, NFS Server denies the creation.
|
||||
NFS is also a problem for the file locks when the storage is on it.
|
||||
|
||||
#### Symptom
|
||||
```console
|
||||
$ buildah bud .
|
||||
ERRO[0014] Error while applying layer: ApplyLayer exit status 1 stdout: stderr: open /root/.bash_logout: permission denied
|
||||
error creating build container: Error committing the finished image: error adding layer with blob "sha256:a02a4930cb5d36f3290eb84f4bfa30668ef2e9fe3a1fb73ec015fc58b9958b17": ApplyLayer exit status 1 stdout: stderr: open /root/.bash_logout: permission denied
|
||||
```
|
||||
|
||||
#### Solution
|
||||
Choose one of the following:
|
||||
* Setup containers/storage in a different directory, not on an NFS share.
|
||||
* Otherwise just run buildah as root, via `sudo buildah`
|
||||
---
|
||||
|
|
@ -18,7 +18,7 @@ import (
|
|||
"github.com/containers/storage/pkg/pools"
|
||||
"github.com/containers/storage/pkg/reexec"
|
||||
"github.com/containers/storage/pkg/system"
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/selinux/go-selinux"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
|
|
@ -182,7 +182,6 @@ func (b *Builder) copyFileWithTar(tarIDMappingOptions *IDMappingOptions, chownOp
|
|||
}
|
||||
pipeWriter.Close()
|
||||
pipeWriter = nil
|
||||
return
|
||||
}(f)
|
||||
|
||||
untar := b.untar(chownOpts, hasher)
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto
|
|||
continue
|
||||
}
|
||||
middle := ""
|
||||
if prefix, ok := RegistryDefaultPathPrefix[registry]; ok && strings.IndexRune(name, '/') == -1 {
|
||||
if prefix, ok := RegistryDefaultPathPrefix[registry]; ok && !strings.ContainsRune(name, '/') {
|
||||
middle = prefix
|
||||
}
|
||||
candidate := path.Join(registry, middle, name)
|
||||
|
|
|
|||
|
|
@ -1,69 +0,0 @@
|
|||
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
|
||||
github.com/blang/semver v3.5.0
|
||||
github.com/BurntSushi/toml v0.2.0
|
||||
github.com/containerd/continuity 004b46473808b3e7a4a3049c20e4376c91eb966d
|
||||
github.com/containernetworking/cni v0.7.0-rc2
|
||||
github.com/containers/image v2.0.0
|
||||
github.com/cyphar/filepath-securejoin v0.2.1
|
||||
github.com/vbauerster/mpb v3.3.4
|
||||
github.com/mattn/go-isatty v0.0.4
|
||||
github.com/VividCortex/ewma v1.1.1
|
||||
github.com/containers/storage v1.12.10
|
||||
github.com/docker/distribution 5f6282db7d65e6d72ad7c2cc66310724a57be716
|
||||
github.com/docker/docker 54dddadc7d5d89fe0be88f76979f6f6ab0dede83
|
||||
github.com/docker/docker-credential-helpers v0.6.1
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/docker/go-units v0.3.2
|
||||
github.com/docker/libtrust aabc10ec26b754e797f9028f4589c5b7bd90dc20
|
||||
github.com/docker/libnetwork 1a06131fb8a047d919f7deaf02a4c414d7884b83
|
||||
github.com/fsouza/go-dockerclient v1.3.0
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/gogo/protobuf v1.2.0
|
||||
github.com/gorilla/context v1.1.1
|
||||
github.com/gorilla/mux v1.6.2
|
||||
github.com/hashicorp/errwrap v1.0.0
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
github.com/imdario/mergo v0.3.6
|
||||
github.com/mattn/go-shellwords v1.0.3
|
||||
github.com/Microsoft/go-winio v0.4.11
|
||||
github.com/Microsoft/hcsshim v0.8.3
|
||||
github.com/mistifyio/go-zfs v2.1.1
|
||||
github.com/moby/moby f8806b18b4b92c5e1980f6e11c917fad201cd73c
|
||||
github.com/mtrmac/gpgme b2432428689ca58c2b8e8dea9449d3295cf96fc9
|
||||
# TODO: Gotty has not been updated since 2012. Can we find a replacement?
|
||||
github.com/Nvveen/Gotty cd527374f1e5bff4938207604a14f2e38a9cf512
|
||||
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
||||
github.com/opencontainers/image-spec v1.0.0
|
||||
github.com/opencontainers/runc v1.0.0-rc6
|
||||
github.com/opencontainers/runtime-spec v1.0.0
|
||||
github.com/opencontainers/runtime-tools v0.8.0
|
||||
github.com/opencontainers/selinux v1.1
|
||||
github.com/openshift/imagebuilder v1.1.0
|
||||
github.com/ostreedev/ostree-go 9ab99253d365aac3a330d1f7281cf29f3d22820b
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/pquerna/ffjson d49c2bc1aa135aad0c6f4fc2056623ec78f5d5ac
|
||||
github.com/seccomp/libseccomp-golang v0.9.0
|
||||
github.com/seccomp/containers-golang v0.1
|
||||
github.com/sirupsen/logrus v1.0.0
|
||||
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
|
||||
github.com/tchap/go-patricia v2.2.6
|
||||
github.com/ulikunitz/xz v0.5.5
|
||||
github.com/vbatts/tar-split v0.10.2
|
||||
github.com/xeipuuv/gojsonpointer 4e3ac2762d5f479393488629ee9370b50873b3a6
|
||||
github.com/xeipuuv/gojsonreference bd5ef7bd5415a7ac448318e64f11a24cd21e594b
|
||||
github.com/xeipuuv/gojsonschema v1.1.0
|
||||
golang.org/x/crypto ff983b9c42bc9fbf91556e191cc8efb585c16908 https://github.com/golang/crypto
|
||||
golang.org/x/net 45ffb0cd1ba084b73e26dee67e667e1be5acce83 https://github.com/golang/net
|
||||
golang.org/x/sync 37e7f081c4d4c64e13b10787722085407fe5d15f https://github.com/golang/sync
|
||||
golang.org/x/sys 7fbe1cd0fcc20051e1fcb87fbabec4a1bacaaeba https://github.com/golang/sys
|
||||
golang.org/x/text e6919f6577db79269a6443b9dc46d18f2238fb5d https://github.com/golang/text
|
||||
gopkg.in/yaml.v2 v2.2.2
|
||||
k8s.io/client-go kubernetes-1.10.13-beta.0 https://github.com/kubernetes/client-go
|
||||
github.com/klauspost/pgzip v1.2.1
|
||||
github.com/klauspost/compress v1.4.1
|
||||
github.com/klauspost/cpuid v1.2.0
|
||||
github.com/onsi/gomega v1.4.3
|
||||
github.com/spf13/cobra v0.0.3
|
||||
github.com/spf13/pflag v1.0.3
|
||||
github.com/ishidawataru/sctp 07191f837fedd2f13d1ec7b5f885f0f3ec54b1cb
|
||||
github.com/etcd-io/bbolt v1.3.2
|
||||
|
|
@ -14,6 +14,45 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
// defaultPath is the default path to the resolv.conf that contains information to resolve DNS. See Path().
|
||||
defaultPath = "/etc/resolv.conf"
|
||||
// alternatePath is a path different from defaultPath, that may be used to resolve DNS. See Path().
|
||||
alternatePath = "/run/systemd/resolve/resolv.conf"
|
||||
)
|
||||
|
||||
var (
|
||||
detectSystemdResolvConfOnce sync.Once
|
||||
pathAfterSystemdDetection = defaultPath
|
||||
)
|
||||
|
||||
// Path returns the path to the resolv.conf file that libnetwork should use.
|
||||
//
|
||||
// When /etc/resolv.conf contains 127.0.0.53 as the only nameserver, then
|
||||
// it is assumed systemd-resolved manages DNS. Because inside the container 127.0.0.53
|
||||
// is not a valid DNS server, Path() returns /run/systemd/resolve/resolv.conf
|
||||
// which is the resolv.conf that systemd-resolved generates and manages.
|
||||
// Otherwise Path() returns /etc/resolv.conf.
|
||||
//
|
||||
// Errors are silenced as they will inevitably resurface at future open/read calls.
|
||||
//
|
||||
// More information at https://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html#/etc/resolv.conf
|
||||
func Path() string {
|
||||
detectSystemdResolvConfOnce.Do(func() {
|
||||
candidateResolvConf, err := ioutil.ReadFile(defaultPath)
|
||||
if err != nil {
|
||||
// silencing error as it will resurface at next calls trying to read defaultPath
|
||||
return
|
||||
}
|
||||
ns := GetNameservers(candidateResolvConf, types.IP)
|
||||
if len(ns) == 1 && ns[0] == "127.0.0.53" {
|
||||
pathAfterSystemdDetection = alternatePath
|
||||
logrus.Infof("detected 127.0.0.53 nameserver, assuming systemd-resolved, so using resolv.conf: %s", alternatePath)
|
||||
}
|
||||
})
|
||||
return pathAfterSystemdDetection
|
||||
}
|
||||
|
||||
var (
|
||||
// Note: the default IPv4 & IPv6 resolvers are set to Google's Public DNS
|
||||
defaultIPv4Dns = []string{"nameserver 8.8.8.8", "nameserver 8.8.4.4"}
|
||||
|
|
@ -50,15 +89,7 @@ type File struct {
|
|||
|
||||
// Get returns the contents of /etc/resolv.conf and its hash
|
||||
func Get() (*File, error) {
|
||||
resolv, err := ioutil.ReadFile("/etc/resolv.conf")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hash, err := ioutils.HashData(bytes.NewReader(resolv))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &File{Content: resolv, Hash: hash}, nil
|
||||
return GetSpecific(Path())
|
||||
}
|
||||
|
||||
// GetSpecific returns the contents of the user specified resolv.conf file and its hash
|
||||
|
|
@ -81,7 +112,7 @@ func GetIfChanged() (*File, error) {
|
|||
lastModified.Lock()
|
||||
defer lastModified.Unlock()
|
||||
|
||||
resolv, err := ioutil.ReadFile("/etc/resolv.conf")
|
||||
resolv, err := ioutil.ReadFile(Path())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ func (p PortBinding) HostAddr() (net.Addr, error) {
|
|||
case TCP:
|
||||
return &net.TCPAddr{IP: p.HostIP, Port: int(p.HostPort)}, nil
|
||||
case SCTP:
|
||||
return &sctp.SCTPAddr{IP: []net.IP{p.HostIP}, Port: int(p.HostPort)}, nil
|
||||
return &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: p.HostIP}}, Port: int(p.HostPort)}, nil
|
||||
default:
|
||||
return nil, ErrInvalidProtocolBinding(p.Proto.String())
|
||||
}
|
||||
|
|
@ -113,7 +113,7 @@ func (p PortBinding) ContainerAddr() (net.Addr, error) {
|
|||
case TCP:
|
||||
return &net.TCPAddr{IP: p.IP, Port: int(p.Port)}, nil
|
||||
case SCTP:
|
||||
return &sctp.SCTPAddr{IP: []net.IP{p.IP}, Port: int(p.Port)}, nil
|
||||
return &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: p.IP}}, Port: int(p.Port)}, nil
|
||||
default:
|
||||
return nil, ErrInvalidProtocolBinding(p.Proto.String())
|
||||
}
|
||||
|
|
@ -145,7 +145,12 @@ func (p *PortBinding) String() string {
|
|||
return ret
|
||||
}
|
||||
|
||||
// FromString reads the PortBinding structure from string
|
||||
// FromString reads the PortBinding structure from string s.
|
||||
// String s is a triple of "protocol/containerIP:port/hostIP:port"
|
||||
// containerIP and hostIP can be in dotted decimal ("192.0.2.1") or IPv6 ("2001:db8::68") form.
|
||||
// Zoned addresses ("169.254.0.23%eth0" or "fe80::1ff:fe23:4567:890a%eth0") are not supported.
|
||||
// If string s is incorrectly formatted or the IP addresses or ports cannot be parsed, FromString
|
||||
// returns an error.
|
||||
func (p *PortBinding) FromString(s string) error {
|
||||
ps := strings.Split(s, "/")
|
||||
if len(ps) != 3 {
|
||||
|
|
@ -167,21 +172,19 @@ func (p *PortBinding) FromString(s string) error {
|
|||
}
|
||||
|
||||
func parseIPPort(s string) (net.IP, uint16, error) {
|
||||
pp := strings.Split(s, ":")
|
||||
if len(pp) != 2 {
|
||||
return nil, 0, BadRequestErrorf("invalid format: %s", s)
|
||||
}
|
||||
|
||||
var ip net.IP
|
||||
if pp[0] != "" {
|
||||
if ip = net.ParseIP(pp[0]); ip == nil {
|
||||
return nil, 0, BadRequestErrorf("invalid ip: %s", pp[0])
|
||||
}
|
||||
}
|
||||
|
||||
port, err := strconv.ParseUint(pp[1], 10, 16)
|
||||
hoststr, portstr, err := net.SplitHostPort(s)
|
||||
if err != nil {
|
||||
return nil, 0, BadRequestErrorf("invalid port: %s", pp[1])
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
ip := net.ParseIP(hoststr)
|
||||
if ip == nil {
|
||||
return nil, 0, BadRequestErrorf("invalid ip: %s", hoststr)
|
||||
}
|
||||
|
||||
port, err := strconv.ParseUint(portstr, 10, 16)
|
||||
if err != nil {
|
||||
return nil, 0, BadRequestErrorf("invalid port: %s", portstr)
|
||||
}
|
||||
|
||||
return ip, uint16(port), nil
|
||||
|
|
@ -329,6 +332,8 @@ func CompareIPNet(a, b *net.IPNet) bool {
|
|||
}
|
||||
|
||||
// GetMinimalIP returns the address in its shortest form
|
||||
// If ip contains an IPv4-mapped IPv6 address, the 4-octet form of the IPv4 address will be returned.
|
||||
// Otherwise ip is returned unchanged.
|
||||
func GetMinimalIP(ip net.IP) net.IP {
|
||||
if ip != nil && ip.To4() != nil {
|
||||
return ip.To4()
|
||||
|
|
|
|||
|
|
@ -12,3 +12,5 @@
|
|||
|
||||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||
.glide/
|
||||
|
||||
example/example
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ go:
|
|||
- 1.7
|
||||
- 1.8
|
||||
- 1.9
|
||||
- "1.10"
|
||||
|
||||
script:
|
||||
- go test -v -race ./...
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
package sctp
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
//from https://github.com/golang/go
|
||||
// Boolean to int.
|
||||
func boolint(b bool) int {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
//from https://github.com/golang/go
|
||||
func ipToSockaddr(family int, ip net.IP, port int, zone string) (syscall.Sockaddr, error) {
|
||||
switch family {
|
||||
case syscall.AF_INET:
|
||||
if len(ip) == 0 {
|
||||
ip = net.IPv4zero
|
||||
}
|
||||
ip4 := ip.To4()
|
||||
if ip4 == nil {
|
||||
return nil, &net.AddrError{Err: "non-IPv4 address", Addr: ip.String()}
|
||||
}
|
||||
sa := &syscall.SockaddrInet4{Port: port}
|
||||
copy(sa.Addr[:], ip4)
|
||||
return sa, nil
|
||||
case syscall.AF_INET6:
|
||||
// In general, an IP wildcard address, which is either
|
||||
// "0.0.0.0" or "::", means the entire IP addressing
|
||||
// space. For some historical reason, it is used to
|
||||
// specify "any available address" on some operations
|
||||
// of IP node.
|
||||
//
|
||||
// When the IP node supports IPv4-mapped IPv6 address,
|
||||
// we allow an listener to listen to the wildcard
|
||||
// address of both IP addressing spaces by specifying
|
||||
// IPv6 wildcard address.
|
||||
if len(ip) == 0 || ip.Equal(net.IPv4zero) {
|
||||
ip = net.IPv6zero
|
||||
}
|
||||
// We accept any IPv6 address including IPv4-mapped
|
||||
// IPv6 address.
|
||||
ip6 := ip.To16()
|
||||
if ip6 == nil {
|
||||
return nil, &net.AddrError{Err: "non-IPv6 address", Addr: ip.String()}
|
||||
}
|
||||
//we set ZoneId to 0, as currently we use this functon only to probe the IP capabilities of the host
|
||||
//if real Zone handling is required, the zone cache implementation in golang/net should be pulled here
|
||||
sa := &syscall.SockaddrInet6{Port: port, ZoneId: 0}
|
||||
copy(sa.Addr[:], ip6)
|
||||
return sa, nil
|
||||
}
|
||||
return nil, &net.AddrError{Err: "invalid address family", Addr: ip.String()}
|
||||
}
|
||||
|
||||
//from https://github.com/golang/go
|
||||
func sockaddr(a *net.TCPAddr, family int) (syscall.Sockaddr, error) {
|
||||
if a == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return ipToSockaddr(family, a.IP, a.Port, a.Zone)
|
||||
}
|
||||
|
||||
//from https://github.com/golang/go
|
||||
type ipStackCapabilities struct {
|
||||
sync.Once // guards following
|
||||
ipv4Enabled bool
|
||||
ipv6Enabled bool
|
||||
ipv4MappedIPv6Enabled bool
|
||||
}
|
||||
|
||||
//from https://github.com/golang/go
|
||||
var ipStackCaps ipStackCapabilities
|
||||
|
||||
//from https://github.com/golang/go
|
||||
// supportsIPv4 reports whether the platform supports IPv4 networking
|
||||
// functionality.
|
||||
func supportsIPv4() bool {
|
||||
ipStackCaps.Once.Do(ipStackCaps.probe)
|
||||
return ipStackCaps.ipv4Enabled
|
||||
}
|
||||
|
||||
//from https://github.com/golang/go
|
||||
// supportsIPv6 reports whether the platform supports IPv6 networking
|
||||
// functionality.
|
||||
func supportsIPv6() bool {
|
||||
ipStackCaps.Once.Do(ipStackCaps.probe)
|
||||
return ipStackCaps.ipv6Enabled
|
||||
}
|
||||
|
||||
//from https://github.com/golang/go
|
||||
// supportsIPv4map reports whether the platform supports mapping an
|
||||
// IPv4 address inside an IPv6 address at transport layer
|
||||
// protocols. See RFC 4291, RFC 4038 and RFC 3493.
|
||||
func supportsIPv4map() bool {
|
||||
ipStackCaps.Once.Do(ipStackCaps.probe)
|
||||
return ipStackCaps.ipv4MappedIPv6Enabled
|
||||
}
|
||||
|
||||
//from https://github.com/golang/go
|
||||
// Probe probes IPv4, IPv6 and IPv4-mapped IPv6 communication
|
||||
// capabilities which are controlled by the IPV6_V6ONLY socket option
|
||||
// and kernel configuration.
|
||||
//
|
||||
// Should we try to use the IPv4 socket interface if we're only
|
||||
// dealing with IPv4 sockets? As long as the host system understands
|
||||
// IPv4-mapped IPv6, it's okay to pass IPv4-mapeed IPv6 addresses to
|
||||
// the IPv6 interface. That simplifies our code and is most
|
||||
// general. Unfortunately, we need to run on kernels built without
|
||||
// IPv6 support too. So probe the kernel to figure it out.
|
||||
func (p *ipStackCapabilities) probe() {
|
||||
s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
|
||||
switch err {
|
||||
case syscall.EAFNOSUPPORT, syscall.EPROTONOSUPPORT:
|
||||
case nil:
|
||||
syscall.Close(s)
|
||||
p.ipv4Enabled = true
|
||||
}
|
||||
var probes = []struct {
|
||||
laddr net.TCPAddr
|
||||
value int
|
||||
}{
|
||||
// IPv6 communication capability
|
||||
{laddr: net.TCPAddr{IP: net.IPv6loopback}, value: 1},
|
||||
// IPv4-mapped IPv6 address communication capability
|
||||
{laddr: net.TCPAddr{IP: net.IPv4(127, 0, 0, 1)}, value: 0},
|
||||
}
|
||||
|
||||
for i := range probes {
|
||||
s, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
defer syscall.Close(s)
|
||||
syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, probes[i].value)
|
||||
sa, err := sockaddr(&(probes[i].laddr), syscall.AF_INET6)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if err := syscall.Bind(s, sa); err != nil {
|
||||
continue
|
||||
}
|
||||
if i == 0 {
|
||||
p.ipv6Enabled = true
|
||||
} else {
|
||||
p.ipv4MappedIPv6Enabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//from https://github.com/golang/go
|
||||
//Change: we check the first IP address in the list of candidate SCTP IP addresses
|
||||
func (a *SCTPAddr) isWildcard() bool {
|
||||
if a == nil {
|
||||
return true
|
||||
}
|
||||
if 0 == len(a.IPAddrs) {
|
||||
return true
|
||||
}
|
||||
|
||||
return a.IPAddrs[0].IP.IsUnspecified()
|
||||
}
|
||||
|
||||
func (a *SCTPAddr) family() int {
|
||||
if a != nil {
|
||||
for _, ip := range a.IPAddrs {
|
||||
if ip.IP.To4() == nil {
|
||||
return syscall.AF_INET6
|
||||
}
|
||||
}
|
||||
}
|
||||
return syscall.AF_INET
|
||||
}
|
||||
|
||||
//from https://github.com/golang/go
|
||||
func favoriteAddrFamily(network string, laddr *SCTPAddr, raddr *SCTPAddr, mode string) (family int, ipv6only bool) {
|
||||
switch network[len(network)-1] {
|
||||
case '4':
|
||||
return syscall.AF_INET, false
|
||||
case '6':
|
||||
return syscall.AF_INET6, true
|
||||
}
|
||||
|
||||
if mode == "listen" && (laddr == nil || laddr.isWildcard()) {
|
||||
if supportsIPv4map() || !supportsIPv4() {
|
||||
return syscall.AF_INET6, false
|
||||
}
|
||||
if laddr == nil {
|
||||
return syscall.AF_INET, false
|
||||
}
|
||||
return laddr.family(), false
|
||||
}
|
||||
|
||||
if (laddr == nil || laddr.family() == syscall.AF_INET) &&
|
||||
(raddr == nil || raddr.family() == syscall.AF_INET) {
|
||||
return syscall.AF_INET, false
|
||||
}
|
||||
return syscall.AF_INET6, false
|
||||
}
|
||||
|
||||
//from https://github.com/golang/go
|
||||
//Changes: it is for SCTP only
|
||||
func setDefaultSockopts(s int, family int, ipv6only bool) error {
|
||||
if family == syscall.AF_INET6 {
|
||||
// Allow both IP versions even if the OS default
|
||||
// is otherwise. Note that some operating systems
|
||||
// never admit this option.
|
||||
syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only))
|
||||
}
|
||||
// Allow broadcast.
|
||||
return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
|
||||
}
|
||||
|
|
@ -197,37 +197,58 @@ func htons(h uint16) uint16 {
|
|||
|
||||
var ntohs = htons
|
||||
|
||||
func setNumOstreams(fd, num int) error {
|
||||
param := InitMsg{
|
||||
NumOstreams: uint16(num),
|
||||
}
|
||||
optlen := unsafe.Sizeof(param)
|
||||
_, _, err := setsockopt(fd, SCTP_INITMSG, uintptr(unsafe.Pointer(¶m)), uintptr(optlen))
|
||||
// setInitOpts sets options for an SCTP association initialization
|
||||
// see https://tools.ietf.org/html/rfc4960#page-25
|
||||
func setInitOpts(fd int, options InitMsg) error {
|
||||
optlen := unsafe.Sizeof(options)
|
||||
_, _, err := setsockopt(fd, SCTP_INITMSG, uintptr(unsafe.Pointer(&options)), uintptr(optlen))
|
||||
return err
|
||||
}
|
||||
|
||||
func setNumOstreams(fd, num int) error {
|
||||
return setInitOpts(fd, InitMsg{NumOstreams: uint16(num)})
|
||||
}
|
||||
|
||||
type SCTPAddr struct {
|
||||
IP []net.IP
|
||||
Port int
|
||||
IPAddrs []net.IPAddr
|
||||
Port int
|
||||
}
|
||||
|
||||
func (a *SCTPAddr) ToRawSockAddrBuf() []byte {
|
||||
buf := []byte{}
|
||||
p := htons(uint16(a.Port))
|
||||
for _, ip := range a.IP {
|
||||
if ip.To4() != nil {
|
||||
if len(a.IPAddrs) == 0 { // if a.IPAddrs list is empty - fall back to IPv4 zero addr
|
||||
s := syscall.RawSockaddrInet4{
|
||||
Family: syscall.AF_INET,
|
||||
Port: p,
|
||||
}
|
||||
copy(s.Addr[:], net.IPv4zero)
|
||||
return toBuf(s)
|
||||
}
|
||||
buf := []byte{}
|
||||
for _, ip := range a.IPAddrs {
|
||||
ipBytes := ip.IP
|
||||
if len(ipBytes) == 0 {
|
||||
ipBytes = net.IPv4zero
|
||||
}
|
||||
if ip4 := ipBytes.To4(); ip4 != nil {
|
||||
s := syscall.RawSockaddrInet4{
|
||||
Family: syscall.AF_INET,
|
||||
Port: p,
|
||||
}
|
||||
copy(s.Addr[:], ip.To4())
|
||||
copy(s.Addr[:], ip4)
|
||||
buf = append(buf, toBuf(s)...)
|
||||
} else {
|
||||
s := syscall.RawSockaddrInet6{
|
||||
Family: syscall.AF_INET6,
|
||||
Port: p,
|
||||
var scopeid uint32
|
||||
ifi, err := net.InterfaceByName(ip.Zone)
|
||||
if err == nil {
|
||||
scopeid = uint32(ifi.Index)
|
||||
}
|
||||
copy(s.Addr[:], ip)
|
||||
s := syscall.RawSockaddrInet6{
|
||||
Family: syscall.AF_INET6,
|
||||
Port: p,
|
||||
Scope_id: scopeid,
|
||||
}
|
||||
copy(s.Addr[:], ipBytes)
|
||||
buf = append(buf, toBuf(s)...)
|
||||
}
|
||||
}
|
||||
|
|
@ -237,15 +258,15 @@ func (a *SCTPAddr) ToRawSockAddrBuf() []byte {
|
|||
func (a *SCTPAddr) String() string {
|
||||
var b bytes.Buffer
|
||||
|
||||
for n, i := range a.IP {
|
||||
if a.IP[n].To4() != nil {
|
||||
for n, i := range a.IPAddrs {
|
||||
if i.IP.To4() != nil {
|
||||
b.WriteString(i.String())
|
||||
} else if a.IP[n].To16() != nil {
|
||||
} else if i.IP.To16() != nil {
|
||||
b.WriteRune('[')
|
||||
b.WriteString(i.String())
|
||||
b.WriteRune(']')
|
||||
}
|
||||
if n < len(a.IP)-1 {
|
||||
if n < len(a.IPAddrs)-1 {
|
||||
b.WriteRune('/')
|
||||
}
|
||||
}
|
||||
|
|
@ -260,6 +281,7 @@ func ResolveSCTPAddr(network, addrs string) (*SCTPAddr, error) {
|
|||
tcpnet := ""
|
||||
switch network {
|
||||
case "", "sctp":
|
||||
tcpnet = "tcp"
|
||||
case "sctp4":
|
||||
tcpnet = "tcp4"
|
||||
case "sctp6":
|
||||
|
|
@ -271,26 +293,26 @@ func ResolveSCTPAddr(network, addrs string) (*SCTPAddr, error) {
|
|||
if len(elems) == 0 {
|
||||
return nil, fmt.Errorf("invalid input: %s", addrs)
|
||||
}
|
||||
ipaddrs := make([]net.IP, 0, len(elems))
|
||||
ipaddrs := make([]net.IPAddr, 0, len(elems))
|
||||
for _, e := range elems[:len(elems)-1] {
|
||||
tcpa, err := net.ResolveTCPAddr(tcpnet, e+":")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ipaddrs = append(ipaddrs, tcpa.IP)
|
||||
ipaddrs = append(ipaddrs, net.IPAddr{IP: tcpa.IP, Zone: tcpa.Zone})
|
||||
}
|
||||
tcpa, err := net.ResolveTCPAddr(tcpnet, elems[len(elems)-1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if tcpa.IP != nil {
|
||||
ipaddrs = append(ipaddrs, tcpa.IP)
|
||||
ipaddrs = append(ipaddrs, net.IPAddr{IP: tcpa.IP, Zone: tcpa.Zone})
|
||||
} else {
|
||||
ipaddrs = nil
|
||||
}
|
||||
return &SCTPAddr{
|
||||
IP: ipaddrs,
|
||||
Port: tcpa.Port,
|
||||
IPAddrs: ipaddrs,
|
||||
Port: tcpa.Port,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -357,15 +379,12 @@ func (c *SCTPConn) Read(b []byte) (int, error) {
|
|||
}
|
||||
|
||||
func (c *SCTPConn) SetInitMsg(numOstreams, maxInstreams, maxAttempts, maxInitTimeout int) error {
|
||||
param := InitMsg{
|
||||
return setInitOpts(c.fd(), InitMsg{
|
||||
NumOstreams: uint16(numOstreams),
|
||||
MaxInstreams: uint16(maxInstreams),
|
||||
MaxAttempts: uint16(maxAttempts),
|
||||
MaxInitTimeout: uint16(maxInitTimeout),
|
||||
}
|
||||
optlen := unsafe.Sizeof(param)
|
||||
_, _, err := setsockopt(c.fd(), SCTP_INITMSG, uintptr(unsafe.Pointer(¶m)), uintptr(optlen))
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func (c *SCTPConn) SubscribeEvents(flags int) error {
|
||||
|
|
@ -473,7 +492,7 @@ func (c *SCTPConn) GetDefaultSentParam() (*SndRcvInfo, error) {
|
|||
|
||||
func resolveFromRawAddr(ptr unsafe.Pointer, n int) (*SCTPAddr, error) {
|
||||
addr := &SCTPAddr{
|
||||
IP: make([]net.IP, n),
|
||||
IPAddrs: make([]net.IPAddr, n),
|
||||
}
|
||||
|
||||
switch family := (*(*syscall.RawSockaddrAny)(ptr)).Addr.Family; family {
|
||||
|
|
@ -484,7 +503,7 @@ func resolveFromRawAddr(ptr unsafe.Pointer, n int) (*SCTPAddr, error) {
|
|||
for i := 0; i < n; i++ {
|
||||
a := *(*syscall.RawSockaddrInet4)(unsafe.Pointer(
|
||||
uintptr(ptr) + size*uintptr(i)))
|
||||
addr.IP[i] = a.Addr[:]
|
||||
addr.IPAddrs[i] = net.IPAddr{IP: a.Addr[:]}
|
||||
}
|
||||
case syscall.AF_INET6:
|
||||
addr.Port = int(ntohs(uint16((*(*syscall.RawSockaddrInet4)(ptr)).Port)))
|
||||
|
|
@ -493,7 +512,12 @@ func resolveFromRawAddr(ptr unsafe.Pointer, n int) (*SCTPAddr, error) {
|
|||
for i := 0; i < n; i++ {
|
||||
a := *(*syscall.RawSockaddrInet6)(unsafe.Pointer(
|
||||
uintptr(ptr) + size*uintptr(i)))
|
||||
addr.IP[i] = a.Addr[:]
|
||||
var zone string
|
||||
ifi, err := net.InterfaceByIndex(int(a.Scope_id))
|
||||
if err == nil {
|
||||
zone = ifi.Name
|
||||
}
|
||||
addr.IPAddrs[i] = net.IPAddr{IP: a.Addr[:], Zone: zone}
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown address family: %d", family)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
package sctp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"sync/atomic"
|
||||
|
|
@ -115,31 +114,14 @@ func (c *SCTPConn) Close() error {
|
|||
return syscall.EBADF
|
||||
}
|
||||
|
||||
// ListenSCTP - start listener on specified address/port
|
||||
func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
|
||||
af := syscall.AF_INET
|
||||
switch net {
|
||||
case "sctp":
|
||||
hasv6 := func(addr *SCTPAddr) bool {
|
||||
if addr == nil {
|
||||
return false
|
||||
}
|
||||
for _, ip := range addr.IP {
|
||||
if ip.To4() == nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
if hasv6(laddr) {
|
||||
af = syscall.AF_INET6
|
||||
}
|
||||
case "sctp4":
|
||||
case "sctp6":
|
||||
af = syscall.AF_INET6
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid net: %s", net)
|
||||
}
|
||||
return ListenSCTPExt(net, laddr, InitMsg{NumOstreams: SCTP_MAX_STREAM})
|
||||
}
|
||||
|
||||
// ListenSCTPExt - start listener on specified address/port with given SCTP options
|
||||
func ListenSCTPExt(network string, laddr *SCTPAddr, options InitMsg) (*SCTPListener, error) {
|
||||
af, ipv6only := favoriteAddrFamily(network, laddr, nil, "listen")
|
||||
sock, err := syscall.Socket(
|
||||
af,
|
||||
syscall.SOCK_STREAM,
|
||||
|
|
@ -148,11 +130,30 @@ func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = setNumOstreams(sock, SCTP_MAX_STREAM)
|
||||
|
||||
// close socket on error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
syscall.Close(sock)
|
||||
}
|
||||
}()
|
||||
if err = setDefaultSockopts(sock, af, ipv6only); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = setInitOpts(sock, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if laddr != nil && len(laddr.IP) != 0 {
|
||||
|
||||
if laddr != nil {
|
||||
// If IP address and/or port was not provided so far, let's use the unspecified IPv4 or IPv6 address
|
||||
if len(laddr.IPAddrs) == 0 {
|
||||
if af == syscall.AF_INET {
|
||||
laddr.IPAddrs = append(laddr.IPAddrs, net.IPAddr{IP: net.IPv4zero})
|
||||
} else if af == syscall.AF_INET6 {
|
||||
laddr.IPAddrs = append(laddr.IPAddrs, net.IPAddr{IP: net.IPv6zero})
|
||||
}
|
||||
}
|
||||
err := SCTPBind(sock, laddr, SCTP_BINDX_ADD_ADDR)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -167,40 +168,30 @@ func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (ln *SCTPListener) Accept() (net.Conn, error) {
|
||||
// AcceptSCTP waits for and returns the next SCTP connection to the listener.
|
||||
func (ln *SCTPListener) AcceptSCTP() (*SCTPConn, error) {
|
||||
fd, _, err := syscall.Accept4(ln.fd, 0)
|
||||
return NewSCTPConn(fd, nil), err
|
||||
}
|
||||
|
||||
// Accept waits for and returns the next connection connection to the listener.
|
||||
func (ln *SCTPListener) Accept() (net.Conn, error) {
|
||||
return ln.AcceptSCTP()
|
||||
}
|
||||
|
||||
func (ln *SCTPListener) Close() error {
|
||||
syscall.Shutdown(ln.fd, syscall.SHUT_RDWR)
|
||||
return syscall.Close(ln.fd)
|
||||
}
|
||||
|
||||
// DialSCTP - bind socket to laddr (if given) and connect to raddr
|
||||
func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) {
|
||||
af := syscall.AF_INET
|
||||
switch net {
|
||||
case "sctp":
|
||||
hasv6 := func(addr *SCTPAddr) bool {
|
||||
if addr == nil {
|
||||
return false
|
||||
}
|
||||
for _, ip := range addr.IP {
|
||||
if ip.To4() == nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
if hasv6(laddr) || hasv6(raddr) {
|
||||
af = syscall.AF_INET6
|
||||
}
|
||||
case "sctp4":
|
||||
case "sctp6":
|
||||
af = syscall.AF_INET6
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid net: %s", net)
|
||||
}
|
||||
return DialSCTPExt(net, laddr, raddr, InitMsg{NumOstreams: SCTP_MAX_STREAM})
|
||||
}
|
||||
|
||||
// DialSCTPExt - same as DialSCTP but with given SCTP options
|
||||
func DialSCTPExt(network string, laddr, raddr *SCTPAddr, options InitMsg) (*SCTPConn, error) {
|
||||
af, ipv6only := favoriteAddrFamily(network, laddr, raddr, "dial")
|
||||
sock, err := syscall.Socket(
|
||||
af,
|
||||
syscall.SOCK_STREAM,
|
||||
|
|
@ -209,11 +200,29 @@ func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = setNumOstreams(sock, SCTP_MAX_STREAM)
|
||||
|
||||
// close socket on error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
syscall.Close(sock)
|
||||
}
|
||||
}()
|
||||
if err = setDefaultSockopts(sock, af, ipv6only); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = setInitOpts(sock, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if laddr != nil {
|
||||
// If IP address and/or port was not provided so far, let's use the unspecified IPv4 or IPv6 address
|
||||
if len(laddr.IPAddrs) == 0 {
|
||||
if af == syscall.AF_INET {
|
||||
laddr.IPAddrs = append(laddr.IPAddrs, net.IPAddr{IP: net.IPv4zero})
|
||||
} else if af == syscall.AF_INET6 {
|
||||
laddr.IPAddrs = append(laddr.IPAddrs, net.IPAddr{IP: net.IPv6zero})
|
||||
}
|
||||
}
|
||||
err := SCTPBind(sock, laddr, SCTP_BINDX_ADD_ADDR)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -34,10 +34,18 @@ func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
|
|||
return nil, ErrUnsupported
|
||||
}
|
||||
|
||||
func ListenSCTPExt(net string, laddr *SCTPAddr, options InitMsg) (*SCTPListener, error) {
|
||||
return nil, ErrUnsupported
|
||||
}
|
||||
|
||||
func (ln *SCTPListener) Accept() (net.Conn, error) {
|
||||
return nil, ErrUnsupported
|
||||
}
|
||||
|
||||
func (ln *SCTPListener) AcceptSCTP() (*SCTPConn, error) {
|
||||
return nil, ErrUnsupported
|
||||
}
|
||||
|
||||
func (ln *SCTPListener) Close() error {
|
||||
return ErrUnsupported
|
||||
}
|
||||
|
|
@ -45,3 +53,7 @@ func (ln *SCTPListener) Close() error {
|
|||
func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) {
|
||||
return nil, ErrUnsupported
|
||||
}
|
||||
|
||||
func DialSCTPExt(network string, laddr, raddr *SCTPAddr, options InitMsg) (*SCTPConn, error) {
|
||||
return nil, ErrUnsupported
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import (
|
|||
"time"
|
||||
|
||||
units "github.com/docker/go-units"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -464,10 +465,39 @@ func WriteCgroupProc(dir string, pid int) error {
|
|||
}
|
||||
|
||||
// Dont attach any pid to the cgroup if -1 is specified as a pid
|
||||
if pid != -1 {
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, CgroupProcesses), []byte(strconv.Itoa(pid)), 0700); err != nil {
|
||||
return fmt.Errorf("failed to write %v to %v: %v", pid, CgroupProcesses, err)
|
||||
}
|
||||
if pid == -1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
cgroupProcessesFile, err := os.OpenFile(filepath.Join(dir, CgroupProcesses), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0700)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write %v to %v: %v", pid, CgroupProcesses, err)
|
||||
}
|
||||
defer cgroupProcessesFile.Close()
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
_, err = cgroupProcessesFile.WriteString(strconv.Itoa(pid))
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// EINVAL might mean that the task being added to cgroup.procs is in state
|
||||
// TASK_NEW. We should attempt to do so again.
|
||||
if isEINVAL(err) {
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
|
||||
return fmt.Errorf("failed to write %v to %v: %v", pid, CgroupProcesses, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func isEINVAL(err error) bool {
|
||||
switch err := err.(type) {
|
||||
case *os.PathError:
|
||||
return err.Err == unix.EINVAL
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ type IntelRdt struct {
|
|||
// Format: "L3:<cache_id0>=<cbm0>;<cache_id1>=<cbm1>;..."
|
||||
L3CacheSchema string `json:"l3_cache_schema,omitempty"`
|
||||
|
||||
// The schema of memory bandwidth percentage per L3 cache id
|
||||
// The schema of memory bandwidth per L3 cache id
|
||||
// Format: "MB:<cache_id0>=bandwidth0;<cache_id1>=bandwidth1;..."
|
||||
// The unit of memory bandwidth is specified in "percentages" by
|
||||
// default, and in "MBps" if MBA Software Controller is enabled.
|
||||
MemBwSchema string `json:"memBwSchema,omitempty"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,9 @@ type Process struct {
|
|||
// User specifies user information for the process.
|
||||
User User `json:"user"`
|
||||
// Args specifies the binary and arguments for the application to execute.
|
||||
Args []string `json:"args"`
|
||||
Args []string `json:"args,omitempty"`
|
||||
// CommandLine specifies the full command line for the application to execute on Windows.
|
||||
CommandLine string `json:"commandLine,omitempty" platform:"windows"`
|
||||
// Env populates the process environment for the process.
|
||||
Env []string `json:"env,omitempty"`
|
||||
// Cwd is the current working directory for the process and must be
|
||||
|
|
@ -181,17 +183,17 @@ const (
|
|||
// PIDNamespace for isolating process IDs
|
||||
PIDNamespace LinuxNamespaceType = "pid"
|
||||
// NetworkNamespace for isolating network devices, stacks, ports, etc
|
||||
NetworkNamespace = "network"
|
||||
NetworkNamespace LinuxNamespaceType = "network"
|
||||
// MountNamespace for isolating mount points
|
||||
MountNamespace = "mount"
|
||||
MountNamespace LinuxNamespaceType = "mount"
|
||||
// IPCNamespace for isolating System V IPC, POSIX message queues
|
||||
IPCNamespace = "ipc"
|
||||
IPCNamespace LinuxNamespaceType = "ipc"
|
||||
// UTSNamespace for isolating hostname and NIS domain name
|
||||
UTSNamespace = "uts"
|
||||
UTSNamespace LinuxNamespaceType = "uts"
|
||||
// UserNamespace for isolating user and group IDs
|
||||
UserNamespace = "user"
|
||||
UserNamespace LinuxNamespaceType = "user"
|
||||
// CgroupNamespace for isolating cgroup hierarchies
|
||||
CgroupNamespace = "cgroup"
|
||||
CgroupNamespace LinuxNamespaceType = "cgroup"
|
||||
)
|
||||
|
||||
// LinuxIDMapping specifies UID/GID mappings
|
||||
|
|
@ -217,6 +219,7 @@ type POSIXRlimit struct {
|
|||
// LinuxHugepageLimit structure corresponds to limiting kernel hugepages
|
||||
type LinuxHugepageLimit struct {
|
||||
// Pagesize is the hugepage size
|
||||
// Format: "<size><unit-prefix>B' (e.g. 64KB, 2MB, 1GB, etc.)
|
||||
Pagesize string `json:"pageSize"`
|
||||
// Limit is the limit of "hugepagesize" hugetlb usage
|
||||
Limit uint64 `json:"limit"`
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ func main() {
|
|||
|
||||
// Create a new network namespace
|
||||
newns, _ := netns.New()
|
||||
netns.Set(newns)
|
||||
defer newns.Close()
|
||||
|
||||
// Do something with the network namespace
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@ var SYS_SETNS = map[string]uintptr{
|
|||
"arm": 375,
|
||||
"mips": 4344,
|
||||
"mipsle": 4344,
|
||||
"mips64le": 4344,
|
||||
"ppc64": 350,
|
||||
"ppc64le": 350,
|
||||
"riscv64": 268,
|
||||
"s390x": 339,
|
||||
}[runtime.GOARCH]
|
||||
|
||||
|
|
@ -52,7 +54,8 @@ func Set(ns NsHandle) (err error) {
|
|||
return Setns(ns, CLONE_NEWNET)
|
||||
}
|
||||
|
||||
// New creates a new network namespace and returns a handle to it.
|
||||
// New creates a new network namespace, sets it as current and returns
|
||||
// a handle to it.
|
||||
func New() (ns NsHandle, err error) {
|
||||
if err := syscall.Unshare(CLONE_NEWNET); err != nil {
|
||||
return -1, err
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ github.com/containernetworking/cni/pkg/version
|
|||
github.com/containernetworking/cni/pkg/types/020
|
||||
# github.com/containernetworking/plugins v0.8.1
|
||||
github.com/containernetworking/plugins/pkg/ns
|
||||
# github.com/containers/buildah v1.9.0
|
||||
# github.com/containers/buildah v1.9.2
|
||||
github.com/containers/buildah
|
||||
github.com/containers/buildah/imagebuildah
|
||||
github.com/containers/buildah/pkg/chrootuser
|
||||
|
|
@ -218,7 +218,7 @@ github.com/docker/go-connections/sockets
|
|||
github.com/docker/go-metrics
|
||||
# github.com/docker/go-units v0.4.0
|
||||
github.com/docker/go-units
|
||||
# github.com/docker/libnetwork v0.8.0-dev.2.0.20180608203834-19279f049241
|
||||
# github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316
|
||||
github.com/docker/libnetwork/resolvconf
|
||||
github.com/docker/libnetwork/types
|
||||
github.com/docker/libnetwork/resolvconf/dns
|
||||
|
|
@ -269,7 +269,7 @@ github.com/ijc/Gotty
|
|||
github.com/imdario/mergo
|
||||
# github.com/inconshreveable/mousetrap v1.0.0
|
||||
github.com/inconshreveable/mousetrap
|
||||
# github.com/ishidawataru/sctp v0.0.0-20180213033435-07191f837fed
|
||||
# github.com/ishidawataru/sctp v0.0.0-20180918013207-6e2cb1366111
|
||||
github.com/ishidawataru/sctp
|
||||
# github.com/json-iterator/go v1.1.6
|
||||
github.com/json-iterator/go
|
||||
|
|
@ -344,14 +344,14 @@ github.com/opencontainers/go-digest
|
|||
# github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/opencontainers/image-spec/specs-go/v1
|
||||
github.com/opencontainers/image-spec/specs-go
|
||||
# github.com/opencontainers/runc v1.0.0-rc6
|
||||
# github.com/opencontainers/runc v1.0.0-rc8
|
||||
github.com/opencontainers/runc/libcontainer/user
|
||||
github.com/opencontainers/runc/libcontainer/apparmor
|
||||
github.com/opencontainers/runc/libcontainer/configs
|
||||
github.com/opencontainers/runc/libcontainer/devices
|
||||
github.com/opencontainers/runc/libcontainer/cgroups
|
||||
github.com/opencontainers/runc/libcontainer/system
|
||||
# github.com/opencontainers/runtime-spec v0.0.0-20181111125026-1722abf79c2f
|
||||
# github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7
|
||||
github.com/opencontainers/runtime-spec/specs-go
|
||||
# github.com/opencontainers/runtime-tools v0.9.0
|
||||
github.com/opencontainers/runtime-tools/generate
|
||||
|
|
@ -457,7 +457,7 @@ github.com/vbauerster/mpb/internal
|
|||
# github.com/vishvananda/netlink v1.0.0
|
||||
github.com/vishvananda/netlink
|
||||
github.com/vishvananda/netlink/nl
|
||||
# github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc
|
||||
# github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f
|
||||
github.com/vishvananda/netns
|
||||
# github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f
|
||||
github.com/xeipuuv/gojsonpointer
|
||||
|
|
|
|||
Loading…
Reference in New Issue