diff --git a/LICENSES/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE b/LICENSES/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE deleted file mode 100644 index e799c31320e..00000000000 --- a/LICENSES/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -= vendor/github.com/konsorten/go-windows-terminal-sequences licensed under: = - -(The MIT License) - -Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -= vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE 0fa4821e00ed8fa049781716357f27ed diff --git a/go.mod b/go.mod index 72a73de2b5b..b787c4c3a4b 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.0 github.com/davecgh/go-spew v1.1.1 github.com/docker/distribution v2.7.1+incompatible - github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible + github.com/docker/docker v20.10.2+incompatible github.com/docker/go-connections v0.4.0 github.com/docker/go-units v0.4.0 github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 @@ -49,7 +49,7 @@ require ( github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e github.com/golang/mock v1.4.4 github.com/golang/protobuf v1.4.3 - github.com/google/cadvisor v0.38.8 + github.com/google/cadvisor v0.39.0 github.com/google/go-cmp v0.5.2 github.com/google/gofuzz v1.1.0 github.com/google/uuid v1.1.2 @@ -65,14 +65,14 @@ require ( github.com/miekg/dns v1.1.35 github.com/moby/ipvs v1.0.1 github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb // indirect - github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976 + github.com/mrunalp/fileutils v0.5.0 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 github.com/mvdan/xurls v1.1.0 github.com/onsi/ginkgo v1.11.0 github.com/onsi/gomega v1.7.0 github.com/opencontainers/go-digest v1.0.0 - github.com/opencontainers/runc v1.0.0-rc92 - github.com/opencontainers/selinux v1.6.0 + github.com/opencontainers/runc v1.0.0-rc93 + github.com/opencontainers/selinux v1.8.0 github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.0 github.com/prometheus/client_model v0.2.0 @@ -197,13 +197,13 @@ replace ( github.com/chzyer/logex => github.com/chzyer/logex v1.1.10 github.com/chzyer/readline => github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e github.com/chzyer/test => github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 - github.com/cilium/ebpf => github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775 + github.com/cilium/ebpf => github.com/cilium/ebpf v0.2.0 github.com/clusterhq/flocker-go => github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313 github.com/cockroachdb/datadriven => github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa github.com/container-storage-interface/spec => github.com/container-storage-interface/spec v1.3.0 github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 - github.com/containerd/console => github.com/containerd/console v1.0.0 - github.com/containerd/containerd => github.com/containerd/containerd v1.4.1 + github.com/containerd/console => github.com/containerd/console v1.0.1 + github.com/containerd/containerd => github.com/containerd/containerd v1.4.4 github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3 @@ -219,14 +219,14 @@ replace ( github.com/coreos/go-systemd/v22 => github.com/coreos/go-systemd/v22 v22.1.0 github.com/coreos/pkg => github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f github.com/cpuguy83/go-md2man/v2 => github.com/cpuguy83/go-md2man/v2 v2.0.0 - github.com/creack/pty => github.com/creack/pty v1.1.9 + github.com/creack/pty => github.com/creack/pty v1.1.11 github.com/cyphar/filepath-securejoin => github.com/cyphar/filepath-securejoin v0.2.2 github.com/davecgh/go-spew => github.com/davecgh/go-spew v1.1.1 github.com/daviddengcn/go-colortext => github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd github.com/dgrijalva/jwt-go => github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dnaeon/go-vcr => github.com/dnaeon/go-vcr v1.0.1 github.com/docker/distribution => github.com/docker/distribution v2.7.1+incompatible - github.com/docker/docker => github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible + github.com/docker/docker => github.com/docker/docker v20.10.2+incompatible github.com/docker/go-connections => github.com/docker/go-connections v0.4.0 github.com/docker/go-units => github.com/docker/go-units v0.4.0 github.com/docopt/docopt-go => github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 @@ -275,7 +275,7 @@ replace ( github.com/golang/protobuf => github.com/golang/protobuf v1.4.3 github.com/golangplus/testing => github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e github.com/google/btree => github.com/google/btree v1.0.0 - github.com/google/cadvisor => github.com/google/cadvisor v0.38.8 + github.com/google/cadvisor => github.com/google/cadvisor v0.39.0 github.com/google/go-cmp => github.com/google/go-cmp v0.5.2 github.com/google/gofuzz => github.com/google/gofuzz v1.1.0 github.com/google/martian => github.com/google/martian v2.1.0+incompatible @@ -331,7 +331,7 @@ replace ( github.com/kisielk/errcheck => github.com/kisielk/errcheck v1.5.0 github.com/kisielk/gotool => github.com/kisielk/gotool v1.0.0 github.com/klauspost/cpuid => github.com/klauspost/cpuid v1.2.0 - github.com/konsorten/go-windows-terminal-sequences => github.com/konsorten/go-windows-terminal-sequences v1.0.3 + github.com/konsorten/go-windows-terminal-sequences => github.com/konsorten/go-windows-terminal-sequences v1.0.2 github.com/kr/logfmt => github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 github.com/kr/pretty => github.com/kr/pretty v0.2.0 github.com/kr/text => github.com/kr/text v0.2.0 @@ -365,14 +365,14 @@ replace ( github.com/mitchellh/mapstructure => github.com/mitchellh/mapstructure v1.1.2 github.com/moby/ipvs => github.com/moby/ipvs v1.0.1 github.com/moby/spdystream => github.com/moby/spdystream v0.2.0 - github.com/moby/sys/mountinfo => github.com/moby/sys/mountinfo v0.1.3 - github.com/moby/term => github.com/moby/term v0.0.0-20200312100748-672ec06f55cd + github.com/moby/sys/mountinfo => github.com/moby/sys/mountinfo v0.4.0 + github.com/moby/term => github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 github.com/modern-go/concurrent => github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd github.com/modern-go/reflect2 => github.com/modern-go/reflect2 v1.0.1 github.com/mohae/deepcopy => github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb github.com/monochromegane/go-gitignore => github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 github.com/morikuni/aec => github.com/morikuni/aec v1.0.0 - github.com/mrunalp/fileutils => github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976 + github.com/mrunalp/fileutils => github.com/mrunalp/fileutils v0.5.0 github.com/munnerz/goautoneg => github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 github.com/mvdan/xurls => github.com/mvdan/xurls v1.1.0 github.com/mwitkow/go-conntrack => github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 @@ -385,9 +385,9 @@ replace ( github.com/onsi/gomega => github.com/onsi/gomega v1.7.0 github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.1 - github.com/opencontainers/runc => github.com/opencontainers/runc v1.0.0-rc92 - github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6 - github.com/opencontainers/selinux => github.com/opencontainers/selinux v1.6.0 + github.com/opencontainers/runc => github.com/opencontainers/runc v1.0.0-rc93 + github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d + github.com/opencontainers/selinux => github.com/opencontainers/selinux v1.8.0 github.com/pascaldekloe/goe => github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c github.com/pelletier/go-toml => github.com/pelletier/go-toml v1.2.0 github.com/peterbourgon/diskv => github.com/peterbourgon/diskv v2.0.1+incompatible @@ -413,7 +413,7 @@ replace ( github.com/seccomp/libseccomp-golang => github.com/seccomp/libseccomp-golang v0.9.1 github.com/sergi/go-diff => github.com/sergi/go-diff v1.1.0 github.com/shurcooL/sanitized_anchor_name => github.com/shurcooL/sanitized_anchor_name v1.0.0 - github.com/sirupsen/logrus => github.com/sirupsen/logrus v1.6.0 + github.com/sirupsen/logrus => github.com/sirupsen/logrus v1.7.0 github.com/smartystreets/assertions => github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d github.com/smartystreets/goconvey => github.com/smartystreets/goconvey v1.6.4 github.com/soheilhy/cmux => github.com/soheilhy/cmux v0.1.4 @@ -427,7 +427,7 @@ replace ( github.com/stretchr/objx => github.com/stretchr/objx v0.2.0 github.com/stretchr/testify => github.com/stretchr/testify v1.6.1 github.com/subosito/gotenv => github.com/subosito/gotenv v1.2.0 - github.com/syndtr/gocapability => github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 + github.com/syndtr/gocapability => github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 github.com/thecodeteam/goscaleio => github.com/thecodeteam/goscaleio v0.1.0 github.com/tidwall/pretty => github.com/tidwall/pretty v1.0.0 github.com/tmc/grpc-websocket-proxy => github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 @@ -437,7 +437,7 @@ replace ( github.com/vishvananda/netlink => github.com/vishvananda/netlink v1.1.0 github.com/vishvananda/netns => github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae github.com/vmware/govmomi => github.com/vmware/govmomi v0.20.3 - github.com/willf/bitset => github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243 + github.com/willf/bitset => github.com/willf/bitset v1.1.11 github.com/xiang90/probing => github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 github.com/xlab/treeprint => github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca github.com/yuin/goldmark => github.com/yuin/goldmark v1.2.1 @@ -489,7 +489,7 @@ replace ( gopkg.in/yaml.v2 => gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c gotest.tools => gotest.tools v2.2.0+incompatible - gotest.tools/v3 => gotest.tools/v3 v3.0.2 + gotest.tools/v3 => gotest.tools/v3 v3.0.3 honnef.co/go/tools => honnef.co/go/tools v0.0.1-2020.1.3 k8s.io/api => ./staging/src/k8s.io/api k8s.io/apiextensions-apiserver => ./staging/src/k8s.io/apiextensions-apiserver diff --git a/go.sum b/go.sum index 950d396d66c..e5c36c22f36 100644 --- a/go.sum +++ b/go.sum @@ -87,8 +87,8 @@ github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlR github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775 h1:cHzBGGVew0ezFsq2grfy2RsB8hO/eNyBgOLHBCqfR1U= -github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= +github.com/cilium/ebpf v0.2.0 h1:Fv93L3KKckEcEHR3oApXVzyBTDA8WAm6VXhPE00N3f8= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313 h1:eIHD9GNM3Hp7kcRW5mvcz7WTR3ETeoYYKwpgA04kaXE= github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y= @@ -97,10 +97,10 @@ github.com/container-storage-interface/spec v1.3.0 h1:wMH4UIoWnK/TXYw8mbcIHgZmB6 github.com/container-storage-interface/spec v1.3.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4= github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 h1:qWj4qVYZ95vLWwqyNJCQg7rDsG5wPdze0UaPolH7DUk= github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= -github.com/containerd/console v1.0.0 h1:fU3UuQapBs+zLJu82NhR11Rif1ny2zfMMAyPJzSN5tQ= -github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= -github.com/containerd/containerd v1.4.1 h1:pASeJT3R3YyVn+94qEPk0SnU1OQ20Jd/T+SPKy9xehY= -github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/console v1.0.1 h1:u7SFAJyRqWcG6ogaMAx3KjSTy1e3hT9QxqX7Jco7dRc= +github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= +github.com/containerd/containerd v1.4.4 h1:rtRG4N6Ct7GNssATwgpvMGfnjnwfjnu/Zs9W3Ikzq+M= +github.com/containerd/containerd v1.4.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= @@ -126,7 +126,8 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbp github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -139,8 +140,8 @@ github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible h1:SiUATuP//KecDjpOK2tvZJgeScYAklvyjfK8JZlU6fo= -github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.2+incompatible h1:vFgEHPqWBTp4pTjdLwjAA4bSo3gvIGOYwuJTlEjVBCw= +github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= 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.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= @@ -217,8 +218,8 @@ github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e h1:KhcknUwkWHKZ github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/cadvisor v0.38.8 h1:3RQEwcEqPEcJ840AOCvDEjYvgpcbyXfEZd+UHlg1ETg= -github.com/google/cadvisor v0.38.8/go.mod h1:1OFB9sOOMkBdUBGCO/1SArawTnDscgMzTodacVDe8mA= +github.com/google/cadvisor v0.39.0 h1:jai6dmBP9QAYluNGqU18yVUTw6uuyAW0AqtZIjvl8Qg= +github.com/google/cadvisor v0.39.0/go.mod h1:rjQFmK4jPCpxeUdLq9bYhNFFsjgGOtpnDmDeap0+nsw= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= @@ -302,8 +303,7 @@ github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1q github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -352,10 +352,10 @@ github.com/moby/ipvs v1.0.1 h1:aoZ7fhLTXgDbzVrAnvV+XbKOU8kOET7B3+xULDF/1o0= github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/sys/mountinfo v0.1.3 h1:KIrhRO14+AkwKvG/g2yIpNMOUVZ02xNhOw8KY1WsLOI= -github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/sys/mountinfo v0.4.0 h1:1KInV3Huv18akCu58V7lzNlt+jFmqlu1EaErnEHE/VM= +github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= 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 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= @@ -366,8 +366,8 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976 h1:aZQToFSLH8ejFeSkTc3r3L4dPImcj7Ib/KgmkQqbGGg= -github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= +github.com/mrunalp/fileutils v0.5.0 h1:NKzVxiH7eSk+OQ4M+ZYW1K6h27RUV3MI6NUTsHhU6Z4= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mvdan/xurls v1.1.0 h1:OpuDelGQ1R1ueQ6sSryzi6P+1RtBpfQHM8fJwlE45ww= @@ -388,12 +388,12 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= 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 v1.0.0-rc92 h1:+IczUKCRzDzFDnw99O/PAqrcBBCoRp9xN3cB1SYSNS4= -github.com/opencontainers/runc v1.0.0-rc92/go.mod h1:X1zlU4p7wOlX4+WRCz+hvlRv8phdL7UqbYD+vQwNMmE= -github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6 h1:NhsM2gc769rVWDqJvapK37r+7+CBXI8xHhnfnt8uQsg= -github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.6.0 h1:+bIAS/Za3q5FTwWym4fTB0vObnfCf3G/NC7K6Jx62mY= -github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= +github.com/opencontainers/runc v1.0.0-rc93 h1:x2UMpOOVf3kQ8arv/EsDGwim8PTNqzL1/EYDr/+scOM= +github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= +github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d h1:pNa8metDkwZjb9g4T8s+krQ+HRgZAkqnXml+wNir/+s= +github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM= +github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -437,8 +437,8 @@ github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= @@ -465,8 +465,8 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -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/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/thecodeteam/goscaleio v0.1.0 h1:SB5tO98lawC+UK8ds/U2jyfOCH7GTcFztcF5x9gbut4= github.com/thecodeteam/goscaleio v0.1.0/go.mod h1:68sdkZAsK8bvEwBlbQnlLS+xU+hvLYM/iQ8KXej1AwM= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= @@ -482,8 +482,8 @@ github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae h1:4hwBBUfQCFe3C github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vmware/govmomi v0.20.3 h1:gpw/0Ku+6RgF3jsi7fnCLmlcikBHfKBCUcu1qgc16OU= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= -github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243 h1:R43TdZy32XXSXjJn7M/HhALJ9imq6ztLnChfYJpVDnM= -github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= +github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI= @@ -575,8 +575,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027 h1:Uusb3oh8XcdzDF/ndlI4ToKTYVlkCSJP39SRY2mfRAw= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= diff --git a/staging/src/k8s.io/apiextensions-apiserver/go.sum b/staging/src/k8s.io/apiextensions-apiserver/go.sum index 6bbb88fc7f8..b492beede55 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/go.sum +++ b/staging/src/k8s.io/apiextensions-apiserver/go.sum @@ -84,6 +84,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -244,8 +245,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -277,7 +276,7 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -341,8 +340,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= @@ -513,6 +512,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -665,8 +665,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/staging/src/k8s.io/apiserver/go.mod b/staging/src/k8s.io/apiserver/go.mod index 12669e81f0d..fb18491cc86 100644 --- a/staging/src/k8s.io/apiserver/go.mod +++ b/staging/src/k8s.io/apiserver/go.mod @@ -26,6 +26,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 github.com/pkg/errors v0.9.1 github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021 // indirect + github.com/sirupsen/logrus v1.7.0 // indirect github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.6.1 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect diff --git a/staging/src/k8s.io/apiserver/go.sum b/staging/src/k8s.io/apiserver/go.sum index fb3483a08d9..85399005cb2 100644 --- a/staging/src/k8s.io/apiserver/go.sum +++ b/staging/src/k8s.io/apiserver/go.sum @@ -73,6 +73,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbp github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -207,8 +208,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -229,7 +228,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182aff github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -281,8 +280,8 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= @@ -435,6 +434,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= @@ -581,8 +581,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/staging/src/k8s.io/cloud-provider/go.sum b/staging/src/k8s.io/cloud-provider/go.sum index 1a3375e58b0..c6ee77fdaa1 100644 --- a/staging/src/k8s.io/cloud-provider/go.sum +++ b/staging/src/k8s.io/cloud-provider/go.sum @@ -84,6 +84,8 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -243,8 +245,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -275,8 +275,8 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -340,8 +340,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= @@ -510,6 +510,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= @@ -658,9 +659,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/staging/src/k8s.io/component-base/go.mod b/staging/src/k8s.io/component-base/go.mod index 66ce03347db..152190a96f9 100644 --- a/staging/src/k8s.io/component-base/go.mod +++ b/staging/src/k8s.io/component-base/go.mod @@ -9,18 +9,18 @@ require ( github.com/go-logr/logr v0.4.0 github.com/google/go-cmp v0.5.2 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect - github.com/moby/term v0.0.0-20200312100748-672ec06f55cd + github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 github.com/prometheus/client_golang v1.7.1 github.com/prometheus/client_model v0.2.0 github.com/prometheus/common v0.10.0 github.com/prometheus/procfs v0.2.0 - github.com/sirupsen/logrus v1.6.0 // indirect github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.6.1 go.uber.org/atomic v1.4.0 // indirect go.uber.org/multierr v1.1.0 // indirect go.uber.org/zap v1.10.0 golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 + gotest.tools/v3 v3.0.3 // indirect k8s.io/apimachinery v0.0.0 k8s.io/client-go v0.0.0 k8s.io/klog/v2 v2.5.0 diff --git a/staging/src/k8s.io/component-base/go.sum b/staging/src/k8s.io/component-base/go.sum index 92f99ca64fc..e87da266bd5 100644 --- a/staging/src/k8s.io/component-base/go.sum +++ b/staging/src/k8s.io/component-base/go.sum @@ -54,6 +54,8 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -152,8 +154,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -169,8 +169,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182aff github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -214,8 +214,6 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -345,6 +343,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= @@ -476,9 +475,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/staging/src/k8s.io/controller-manager/go.sum b/staging/src/k8s.io/controller-manager/go.sum index 98d692d3078..048575df95d 100644 --- a/staging/src/k8s.io/controller-manager/go.sum +++ b/staging/src/k8s.io/controller-manager/go.sum @@ -105,8 +105,8 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbp github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -300,10 +300,6 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -338,8 +334,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182aff github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -421,12 +416,9 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -447,7 +439,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -597,7 +588,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -644,6 +634,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= @@ -808,10 +799,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/staging/src/k8s.io/kube-aggregator/go.sum b/staging/src/k8s.io/kube-aggregator/go.sum index c0a02b6cafd..0a0eb2d3a66 100644 --- a/staging/src/k8s.io/kube-aggregator/go.sum +++ b/staging/src/k8s.io/kube-aggregator/go.sum @@ -83,6 +83,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -244,8 +245,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -277,7 +276,7 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -342,8 +341,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= @@ -514,6 +513,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -666,8 +666,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/staging/src/k8s.io/kube-controller-manager/go.sum b/staging/src/k8s.io/kube-controller-manager/go.sum index ccddf688672..4367bb277bc 100644 --- a/staging/src/k8s.io/kube-controller-manager/go.sum +++ b/staging/src/k8s.io/kube-controller-manager/go.sum @@ -71,6 +71,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -207,7 +208,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -236,7 +236,7 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -292,7 +292,7 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -448,6 +448,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -586,8 +587,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/staging/src/k8s.io/kube-proxy/go.sum b/staging/src/k8s.io/kube-proxy/go.sum index 2cea866aae1..deda62f8c6f 100644 --- a/staging/src/k8s.io/kube-proxy/go.sum +++ b/staging/src/k8s.io/kube-proxy/go.sum @@ -50,6 +50,7 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -144,7 +145,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -159,7 +159,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -198,7 +198,6 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -324,6 +323,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -450,8 +450,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/staging/src/k8s.io/kube-scheduler/go.sum b/staging/src/k8s.io/kube-scheduler/go.sum index 2cea866aae1..deda62f8c6f 100644 --- a/staging/src/k8s.io/kube-scheduler/go.sum +++ b/staging/src/k8s.io/kube-scheduler/go.sum @@ -50,6 +50,7 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -144,7 +145,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -159,7 +159,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -198,7 +198,6 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -324,6 +323,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -450,8 +450,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/staging/src/k8s.io/kubectl/go.mod b/staging/src/k8s.io/kubectl/go.mod index 3766445d29e..c8c7e62b778 100644 --- a/staging/src/k8s.io/kubectl/go.mod +++ b/staging/src/k8s.io/kubectl/go.mod @@ -23,7 +23,7 @@ require ( github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de github.com/lithammer/dedent v1.1.0 github.com/mitchellh/go-wordwrap v1.0.0 - github.com/moby/term v0.0.0-20200312100748-672ec06f55cd + github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 github.com/onsi/ginkgo v1.11.0 github.com/onsi/gomega v1.7.0 github.com/opencontainers/go-digest v1.0.0 // indirect diff --git a/staging/src/k8s.io/kubectl/go.sum b/staging/src/k8s.io/kubectl/go.sum index d77317ab55c..b8312432fdf 100644 --- a/staging/src/k8s.io/kubectl/go.sum +++ b/staging/src/k8s.io/kubectl/go.sum @@ -78,6 +78,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -283,8 +285,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -324,8 +324,8 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -394,8 +394,6 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -567,6 +565,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -713,9 +712,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/staging/src/k8s.io/kubelet/go.sum b/staging/src/k8s.io/kubelet/go.sum index ee45debd4be..f9f1abdf168 100644 --- a/staging/src/k8s.io/kubelet/go.sum +++ b/staging/src/k8s.io/kubelet/go.sum @@ -50,6 +50,7 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -146,7 +147,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -161,7 +161,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -200,7 +200,6 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -326,6 +325,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= @@ -458,8 +458,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/staging/src/k8s.io/legacy-cloud-providers/go.sum b/staging/src/k8s.io/legacy-cloud-providers/go.sum index b91ba722169..859c4c65823 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/go.sum +++ b/staging/src/k8s.io/legacy-cloud-providers/go.sum @@ -94,6 +94,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -251,7 +252,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -282,7 +282,7 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -349,7 +349,7 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -514,6 +514,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= @@ -667,8 +668,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/staging/src/k8s.io/sample-apiserver/go.sum b/staging/src/k8s.io/sample-apiserver/go.sum index 1f8fd508e5e..e40e1497b15 100644 --- a/staging/src/k8s.io/sample-apiserver/go.sum +++ b/staging/src/k8s.io/sample-apiserver/go.sum @@ -83,6 +83,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -243,8 +244,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -275,7 +274,7 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -339,8 +338,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= @@ -511,6 +510,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -663,8 +663,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/cilium/ebpf/.clang-format b/vendor/github.com/cilium/ebpf/.clang-format new file mode 100644 index 00000000000..4eb94b1baa8 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/.clang-format @@ -0,0 +1,17 @@ +--- +Language: Cpp +BasedOnStyle: LLVM +AlignAfterOpenBracket: DontAlign +AlignConsecutiveAssignments: true +AlignEscapedNewlines: DontAlign +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortFunctionsOnASingleLine: false +BreakBeforeBraces: Attach +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: false +TabWidth: 4 +UseTab: ForContinuationAndIndentation +ColumnLimit: 1000 +... diff --git a/vendor/github.com/cilium/ebpf/.gitignore b/vendor/github.com/cilium/ebpf/.gitignore index f1c181ec9c5..38b15653c0f 100644 --- a/vendor/github.com/cilium/ebpf/.gitignore +++ b/vendor/github.com/cilium/ebpf/.gitignore @@ -4,6 +4,7 @@ *.dll *.so *.dylib +*.o # Test binary, build with `go test -c` *.test diff --git a/vendor/github.com/cilium/ebpf/abi.go b/vendor/github.com/cilium/ebpf/abi.go index d432eb46f42..f86a17ee722 100644 --- a/vendor/github.com/cilium/ebpf/abi.go +++ b/vendor/github.com/cilium/ebpf/abi.go @@ -88,12 +88,6 @@ type ProgramABI struct { Type ProgramType } -func newProgramABIFromSpec(spec *ProgramSpec) *ProgramABI { - return &ProgramABI{ - spec.Type, - } -} - func newProgramABIFromFd(fd *internal.FD) (string, *ProgramABI, error) { info, err := bpfGetProgInfoByFD(fd) if err != nil { diff --git a/vendor/github.com/cilium/ebpf/asm/instruction.go b/vendor/github.com/cilium/ebpf/asm/instruction.go index 8fbcf56647c..890dc008acf 100644 --- a/vendor/github.com/cilium/ebpf/asm/instruction.go +++ b/vendor/github.com/cilium/ebpf/asm/instruction.go @@ -12,6 +12,14 @@ import ( // InstructionSize is the size of a BPF instruction in bytes const InstructionSize = 8 +// RawInstructionOffset is an offset in units of raw BPF instructions. +type RawInstructionOffset uint64 + +// Bytes returns the offset of an instruction in bytes. +func (rio RawInstructionOffset) Bytes() uint64 { + return uint64(rio) * InstructionSize +} + // Instruction is a single eBPF instruction. type Instruction struct { OpCode OpCode @@ -155,6 +163,13 @@ func (ins *Instruction) isLoadFromMap() bool { return ins.OpCode == LoadImmOp(DWord) && (ins.Src == PseudoMapFD || ins.Src == PseudoMapValue) } +// IsFunctionCall returns true if the instruction calls another BPF function. +// +// This is not the same thing as a BPF helper call. +func (ins *Instruction) IsFunctionCall() bool { + return ins.OpCode.JumpOp() == Call && ins.Src == PseudoCall +} + // Format implements fmt.Formatter. func (ins Instruction) Format(f fmt.State, c rune) { if c != 'v' { @@ -310,28 +325,6 @@ func (insns Instructions) ReferenceOffsets() map[string][]int { return offsets } -func (insns Instructions) marshalledOffsets() (map[string]int, error) { - symbols := make(map[string]int) - - marshalledPos := 0 - for _, ins := range insns { - currentPos := marshalledPos - marshalledPos += ins.OpCode.marshalledInstructions() - - if ins.Symbol == "" { - continue - } - - if _, ok := symbols[ins.Symbol]; ok { - return nil, fmt.Errorf("duplicate symbol %s", ins.Symbol) - } - - symbols[ins.Symbol] = currentPos - } - - return symbols, nil -} - // Format implements fmt.Formatter. // // You can control indentation of symbols by @@ -370,21 +363,17 @@ func (insns Instructions) Format(f fmt.State, c rune) { symIndent = strings.Repeat(" ", symPadding) } - // Figure out how many digits we need to represent the highest - // offset. - highestOffset := 0 - for _, ins := range insns { - highestOffset += ins.OpCode.marshalledInstructions() - } + // Guess how many digits we need at most, by assuming that all instructions + // are double wide. + highestOffset := len(insns) * 2 offsetWidth := int(math.Ceil(math.Log10(float64(highestOffset)))) - offset := 0 - for _, ins := range insns { - if ins.Symbol != "" { - fmt.Fprintf(f, "%s%s:\n", symIndent, ins.Symbol) + iter := insns.Iterate() + for iter.Next() { + if iter.Ins.Symbol != "" { + fmt.Fprintf(f, "%s%s:\n", symIndent, iter.Ins.Symbol) } - fmt.Fprintf(f, "%s%*d: %v\n", indent, offsetWidth, offset, ins) - offset += ins.OpCode.marshalledInstructions() + fmt.Fprintf(f, "%s%*d: %v\n", indent, offsetWidth, iter.Offset, iter.Ins) } return @@ -392,43 +381,49 @@ func (insns Instructions) Format(f fmt.State, c rune) { // Marshal encodes a BPF program into the kernel format. func (insns Instructions) Marshal(w io.Writer, bo binary.ByteOrder) error { - absoluteOffsets, err := insns.marshalledOffsets() - if err != nil { - return err - } - - num := 0 for i, ins := range insns { - switch { - case ins.OpCode.JumpOp() == Call && ins.Src == PseudoCall && ins.Constant == -1: - // Rewrite bpf to bpf call - offset, ok := absoluteOffsets[ins.Reference] - if !ok { - return fmt.Errorf("instruction %d: reference to missing symbol %s", i, ins.Reference) - } - - ins.Constant = int64(offset - num - 1) - - case ins.OpCode.Class() == JumpClass && ins.Offset == -1: - // Rewrite jump to label - offset, ok := absoluteOffsets[ins.Reference] - if !ok { - return fmt.Errorf("instruction %d: reference to missing symbol %s", i, ins.Reference) - } - - ins.Offset = int16(offset - num - 1) - } - - n, err := ins.Marshal(w, bo) + _, err := ins.Marshal(w, bo) if err != nil { return fmt.Errorf("instruction %d: %w", i, err) } - - num += int(n / InstructionSize) } return nil } +// Iterate allows iterating a BPF program while keeping track of +// various offsets. +// +// Modifying the instruction slice will lead to undefined behaviour. +func (insns Instructions) Iterate() *InstructionIterator { + return &InstructionIterator{insns: insns} +} + +// InstructionIterator iterates over a BPF program. +type InstructionIterator struct { + insns Instructions + // The instruction in question. + Ins *Instruction + // The index of the instruction in the original instruction slice. + Index int + // The offset of the instruction in raw BPF instructions. This accounts + // for double-wide instructions. + Offset RawInstructionOffset +} + +// Next returns true as long as there are any instructions remaining. +func (iter *InstructionIterator) Next() bool { + if len(iter.insns) == 0 { + return false + } + + if iter.Ins != nil { + iter.Offset += RawInstructionOffset(iter.Ins.OpCode.rawInstructions()) + } + iter.Ins = &iter.insns[0] + iter.insns = iter.insns[1:] + return true +} + type bpfInstruction struct { OpCode OpCode Registers bpfRegisters diff --git a/vendor/github.com/cilium/ebpf/asm/opcode.go b/vendor/github.com/cilium/ebpf/asm/opcode.go index c99b6595ac5..dc4564a98d2 100644 --- a/vendor/github.com/cilium/ebpf/asm/opcode.go +++ b/vendor/github.com/cilium/ebpf/asm/opcode.go @@ -66,10 +66,10 @@ type OpCode uint8 // InvalidOpCode is returned by setters on OpCode const InvalidOpCode OpCode = 0xff -// marshalledInstructions returns the number of BPF instructions required +// rawInstructions returns the number of BPF instructions required // to encode this opcode. -func (op OpCode) marshalledInstructions() int { - if op == LoadImmOp(DWord) { +func (op OpCode) rawInstructions() int { + if op.isDWordLoad() { return 2 } return 1 diff --git a/vendor/github.com/cilium/ebpf/collection.go b/vendor/github.com/cilium/ebpf/collection.go index 0c8b65d94de..81ee2bd1a6b 100644 --- a/vendor/github.com/cilium/ebpf/collection.go +++ b/vendor/github.com/cilium/ebpf/collection.go @@ -4,6 +4,8 @@ import ( "errors" "fmt" "math" + "reflect" + "strings" "github.com/cilium/ebpf/asm" "github.com/cilium/ebpf/internal" @@ -11,7 +13,10 @@ import ( ) // CollectionOptions control loading a collection into the kernel. +// +// Maps and Programs are passed to NewMapWithOptions and NewProgramsWithOptions. type CollectionOptions struct { + Maps MapOptions Programs ProgramOptions } @@ -126,6 +131,65 @@ func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error return nil } +// Assign the contents of a collection spec to a struct. +// +// This function is a short-cut to manually checking the presence +// of maps and programs in a collection spec. +// +// The argument to must be a pointer to a struct. A field of the +// struct is updated with values from Programs or Maps if it +// has an `ebpf` tag and its type is *ProgramSpec or *MapSpec. +// The tag gives the name of the program or map as found in +// the CollectionSpec. +// +// struct { +// Foo *ebpf.ProgramSpec `ebpf:"xdp_foo"` +// Bar *ebpf.MapSpec `ebpf:"bar_map"` +// Ignored int +// } +// +// Returns an error if any of the fields can't be found, or +// if the same map or program is assigned multiple times. +func (cs *CollectionSpec) Assign(to interface{}) error { + valueOf := func(typ reflect.Type, name string) (reflect.Value, error) { + switch typ { + case reflect.TypeOf((*ProgramSpec)(nil)): + p := cs.Programs[name] + if p == nil { + return reflect.Value{}, fmt.Errorf("missing program %q", name) + } + return reflect.ValueOf(p), nil + case reflect.TypeOf((*MapSpec)(nil)): + m := cs.Maps[name] + if m == nil { + return reflect.Value{}, fmt.Errorf("missing map %q", name) + } + return reflect.ValueOf(m), nil + default: + return reflect.Value{}, fmt.Errorf("unsupported type %s", typ) + } + } + + return assignValues(to, valueOf) +} + +// LoadAndAssign creates a collection from a spec, and assigns it to a struct. +// +// See Collection.Assign for details. +func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions) error { + if opts == nil { + opts = &CollectionOptions{} + } + + coll, err := NewCollectionWithOptions(cs, *opts) + if err != nil { + return err + } + defer coll.Close() + + return coll.Assign(to) +} + // Collection is a collection of Programs and Maps associated // with their symbols type Collection struct { @@ -191,7 +255,7 @@ func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (col } } - m, err := newMapWithBTF(mapSpec, handle) + m, err := newMapWithBTF(mapSpec, handle, opts.Maps) if err != nil { return nil, fmt.Errorf("map %s: %w", mapName, err) } @@ -292,3 +356,105 @@ func (coll *Collection) DetachProgram(name string) *Program { delete(coll.Programs, name) return p } + +// Assign the contents of a collection to a struct. +// +// `to` must be a pointer to a struct like the following: +// +// struct { +// Foo *ebpf.Program `ebpf:"xdp_foo"` +// Bar *ebpf.Map `ebpf:"bar_map"` +// Ignored int +// } +// +// See CollectionSpec.Assign for the semantics of this function. +// +// DetachMap and DetachProgram is invoked for all assigned elements +// if the function is successful. +func (coll *Collection) Assign(to interface{}) error { + assignedMaps := make(map[string]struct{}) + assignedPrograms := make(map[string]struct{}) + valueOf := func(typ reflect.Type, name string) (reflect.Value, error) { + switch typ { + case reflect.TypeOf((*Program)(nil)): + p := coll.Programs[name] + if p == nil { + return reflect.Value{}, fmt.Errorf("missing program %q", name) + } + assignedPrograms[name] = struct{}{} + return reflect.ValueOf(p), nil + case reflect.TypeOf((*Map)(nil)): + m := coll.Maps[name] + if m == nil { + return reflect.Value{}, fmt.Errorf("missing map %q", name) + } + assignedMaps[name] = struct{}{} + return reflect.ValueOf(m), nil + default: + return reflect.Value{}, fmt.Errorf("unsupported type %s", typ) + } + } + + if err := assignValues(to, valueOf); err != nil { + return err + } + + for name := range assignedPrograms { + coll.DetachProgram(name) + } + + for name := range assignedMaps { + coll.DetachMap(name) + } + + return nil +} + +func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Value, error)) error { + v := reflect.ValueOf(to) + if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { + return fmt.Errorf("%T is not a pointer to a struct", to) + } + + type elem struct { + typ reflect.Type + name string + } + + var ( + s = v.Elem() + sT = s.Type() + assignedTo = make(map[elem]string) + ) + for i := 0; i < sT.NumField(); i++ { + field := sT.Field(i) + + name := field.Tag.Get("ebpf") + if name == "" { + continue + } + if strings.Contains(name, ",") { + return fmt.Errorf("field %s: ebpf tag contains a comma", field.Name) + } + + e := elem{field.Type, name} + if assignedField := assignedTo[e]; assignedField != "" { + return fmt.Errorf("field %s: %q was already assigned to %s", field.Name, name, assignedField) + } + + value, err := valueOf(field.Type, name) + if err != nil { + return fmt.Errorf("field %s: %w", field.Name, err) + } + + fieldValue := s.Field(i) + if !fieldValue.CanSet() { + return fmt.Errorf("can't set value of field %s", field.Name) + } + + fieldValue.Set(value) + assignedTo[e] = field.Name + } + + return nil +} diff --git a/vendor/github.com/cilium/ebpf/doc.go b/vendor/github.com/cilium/ebpf/doc.go index d96e6b1e6d9..f7f34da8f44 100644 --- a/vendor/github.com/cilium/ebpf/doc.go +++ b/vendor/github.com/cilium/ebpf/doc.go @@ -12,6 +12,5 @@ // eBPF code should be compiled ahead of time using clang, and shipped with // your application as any other resource. // -// This package doesn't include code required to attach eBPF to Linux -// subsystems, since this varies per subsystem. +// Use the link subpackage to attach a loaded program to a hook in the kernel. package ebpf diff --git a/vendor/github.com/cilium/ebpf/elf_reader.go b/vendor/github.com/cilium/ebpf/elf_reader.go index 77acaed8d96..2b564dae047 100644 --- a/vendor/github.com/cilium/ebpf/elf_reader.go +++ b/vendor/github.com/cilium/ebpf/elf_reader.go @@ -1,6 +1,7 @@ package ebpf import ( + "bufio" "bytes" "debug/elf" "encoding/binary" @@ -236,7 +237,7 @@ func (ec *elfCode) loadPrograms(progSections map[elf.SectionIndex]*elf.Section, func (ec *elfCode) loadInstructions(section *elf.Section, symbols, relocations map[uint64]elf.Symbol) (asm.Instructions, uint64, error) { var ( - r = section.Open() + r = bufio.NewReader(section.Open()) insns asm.Instructions offset uint64 ) @@ -389,7 +390,7 @@ func (ec *elfCode) loadMaps(maps map[string]*MapSpec, mapSections map[elf.Sectio } var ( - r = sec.Open() + r = bufio.NewReader(sec.Open()) size = sec.Size / uint64(len(syms)) ) for i, offset := 0, uint64(0); i < len(syms); i, offset = i+1, offset+size { @@ -482,6 +483,7 @@ func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) { var ( mapType, flags, maxEntries uint32 + pinType PinType ) for _, member := range btfMapMembers { switch member.Name { @@ -529,9 +531,7 @@ func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) { return nil, fmt.Errorf("can't get pinning: %w", err) } - if pinning != 0 { - return nil, fmt.Errorf("'pinning' attribute not supported: %w", ErrNotSupported) - } + pinType = PinType(pinning) case "key", "value": default: @@ -540,12 +540,14 @@ func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) { } return &MapSpec{ + Name: SanitizeName(name, -1), Type: MapType(mapType), KeySize: keySize, ValueSize: valueSize, MaxEntries: maxEntries, Flags: flags, BTF: btfMap, + Pinning: pinType, }, nil } @@ -636,6 +638,8 @@ func getProgType(sectionName string) (ProgramType, AttachType, string) { "lirc_mode2": {LircMode2, AttachLircMode2}, "flow_dissector": {FlowDissector, AttachFlowDissector}, "iter/": {Tracing, AttachTraceIter}, + "sk_lookup/": {SkLookup, AttachSkLookup}, + "lsm/": {LSM, AttachLSMMac}, "cgroup_skb/ingress": {CGroupSKB, AttachCGroupInetIngress}, "cgroup_skb/egress": {CGroupSKB, AttachCGroupInetEgress}, @@ -684,7 +688,7 @@ func (ec *elfCode) loadRelocations(sections map[elf.SectionIndex]*elf.Section) ( return nil, nil, fmt.Errorf("section %s: relocations are less than 16 bytes", sec.Name) } - r := sec.Open() + r := bufio.NewReader(sec.Open()) for off := uint64(0); off < sec.Size; off += sec.Entsize { ent := io.LimitReader(r, int64(sec.Entsize)) diff --git a/vendor/github.com/cilium/ebpf/go.mod b/vendor/github.com/cilium/ebpf/go.mod index a05cf85eddd..2d100442502 100644 --- a/vendor/github.com/cilium/ebpf/go.mod +++ b/vendor/github.com/cilium/ebpf/go.mod @@ -1,5 +1,8 @@ module github.com/cilium/ebpf -go 1.13 +go 1.14 -require golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 +require ( + github.com/google/go-cmp v0.5.2 + golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 +) diff --git a/vendor/github.com/cilium/ebpf/go.sum b/vendor/github.com/cilium/ebpf/go.sum index e8b62417e81..47dd82f2921 100644 --- a/vendor/github.com/cilium/ebpf/go.sum +++ b/vendor/github.com/cilium/ebpf/go.sum @@ -1,2 +1,6 @@ +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/vendor/github.com/cilium/ebpf/internal/btf/btf.go b/vendor/github.com/cilium/ebpf/internal/btf/btf.go index 3dd000a284e..7a904a02c2c 100644 --- a/vendor/github.com/cilium/ebpf/internal/btf/btf.go +++ b/vendor/github.com/cilium/ebpf/internal/btf/btf.go @@ -31,7 +31,7 @@ var ( type Spec struct { rawTypes []rawType strings stringTable - types map[string][]Type + types map[string][]namedType funcInfos map[string]extInfo lineInfos map[string]extInfo byteOrder binary.ByteOrder @@ -59,29 +59,9 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) { } defer file.Close() - var ( - btfSection *elf.Section - btfExtSection *elf.Section - sectionSizes = make(map[string]uint32) - ) - - for _, sec := range file.Sections { - switch sec.Name { - case ".BTF": - btfSection = sec - case ".BTF.ext": - btfExtSection = sec - default: - if sec.Type != elf.SHT_PROGBITS && sec.Type != elf.SHT_NOBITS { - break - } - - if sec.Size > math.MaxUint32 { - return nil, fmt.Errorf("section %s exceeds maximum size", sec.Name) - } - - sectionSizes[sec.Name] = uint32(sec.Size) - } + btfSection, btfExtSection, sectionSizes, err := findBtfSections(file) + if err != nil { + return nil, err } if btfSection == nil { @@ -129,6 +109,51 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) { return spec, nil } +func findBtfSections(file *elf.File) (*elf.Section, *elf.Section, map[string]uint32, error) { + var ( + btfSection *elf.Section + btfExtSection *elf.Section + sectionSizes = make(map[string]uint32) + ) + + for _, sec := range file.Sections { + switch sec.Name { + case ".BTF": + btfSection = sec + case ".BTF.ext": + btfExtSection = sec + default: + if sec.Type != elf.SHT_PROGBITS && sec.Type != elf.SHT_NOBITS { + break + } + + if sec.Size > math.MaxUint32 { + return nil, nil, nil, fmt.Errorf("section %s exceeds maximum size", sec.Name) + } + + sectionSizes[sec.Name] = uint32(sec.Size) + } + } + return btfSection, btfExtSection, sectionSizes, nil +} + +func loadSpecFromVmlinux(rd io.ReaderAt) (*Spec, error) { + file, err := elf.NewFile(rd) + if err != nil { + return nil, err + } + defer file.Close() + + btfSection, _, _, err := findBtfSections(file) + if err != nil { + return nil, fmt.Errorf(".BTF ELF section: %s", err) + } + if btfSection == nil { + return nil, fmt.Errorf("unable to find .BTF ELF section") + } + return loadNakedSpec(btfSection.Open(), file.ByteOrder, nil, nil) +} + func loadNakedSpec(btf io.ReadSeeker, bo binary.ByteOrder, sectionSizes map[string]uint32, variableOffsets map[variable]uint32) (*Spec, error) { rawTypes, rawStrings, err := parseBTF(btf, bo) if err != nil { @@ -176,16 +201,43 @@ func LoadKernelSpec() (*Spec, error) { } func loadKernelSpec() (*Spec, error) { - fh, err := os.Open("/sys/kernel/btf/vmlinux") - if os.IsNotExist(err) { - return nil, fmt.Errorf("can't open kernel BTF at /sys/kernel/btf/vmlinux: %w", ErrNotFound) - } + release, err := unix.KernelRelease() if err != nil { - return nil, fmt.Errorf("can't read kernel BTF: %s", err) + return nil, fmt.Errorf("can't read kernel release number: %w", err) } - defer fh.Close() - return loadNakedSpec(fh, internal.NativeEndian, nil, nil) + fh, err := os.Open("/sys/kernel/btf/vmlinux") + if err == nil { + defer fh.Close() + + return loadNakedSpec(fh, internal.NativeEndian, nil, nil) + } + + // use same list of locations as libbpf + // https://github.com/libbpf/libbpf/blob/9a3a42608dbe3731256a5682a125ac1e23bced8f/src/btf.c#L3114-L3122 + locations := []string{ + "/boot/vmlinux-%s", + "/lib/modules/%s/vmlinux-%[1]s", + "/lib/modules/%s/build/vmlinux", + "/usr/lib/modules/%s/kernel/vmlinux", + "/usr/lib/debug/boot/vmlinux-%s", + "/usr/lib/debug/boot/vmlinux-%s.debug", + "/usr/lib/debug/lib/modules/%s/vmlinux", + } + + for _, loc := range locations { + path := fmt.Sprintf(loc, release) + + fh, err := os.Open(path) + if err != nil { + continue + } + defer fh.Close() + + return loadSpecFromVmlinux(fh) + } + + return nil, fmt.Errorf("no BTF for kernel version %s: %w", release, internal.ErrNotSupported) } func parseBTF(btf io.ReadSeeker, bo binary.ByteOrder) ([]rawType, stringTable, error) { @@ -402,9 +454,19 @@ func (s *Spec) Map(name string) (*Map, []Member, error) { switch member.Name { case "key": key = member.Type + if pk, isPtr := key.(*Pointer); !isPtr { + return nil, nil, fmt.Errorf("key type is not a pointer: %T", key) + } else { + key = pk.Target + } case "value": value = member.Type + if vk, isPtr := value.(*Pointer); !isPtr { + return nil, nil, fmt.Errorf("value type is not a pointer: %T", value) + } else { + value = vk.Target + } } } @@ -441,11 +503,16 @@ func (s *Spec) FindType(name string, typ Type) error { candidate Type ) - for _, typ := range s.types[name] { + for _, typ := range s.types[essentialName(name)] { if reflect.TypeOf(typ) != wanted { continue } + // Match against the full name, not just the essential one. + if typ.name() != name { + continue + } + if candidate != nil { return fmt.Errorf("type %s: multiple candidates for %T", name, typ) } @@ -621,9 +688,7 @@ type bpfLoadBTFAttr struct { } func bpfLoadBTF(attr *bpfLoadBTFAttr) (*internal.FD, error) { - const _BTFLoad = 18 - - fd, err := internal.BPF(_BTFLoad, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) + fd, err := internal.BPF(internal.BPF_BTF_LOAD, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) if err != nil { return nil, err } diff --git a/vendor/github.com/cilium/ebpf/internal/btf/btf_types.go b/vendor/github.com/cilium/ebpf/internal/btf/btf_types.go index e34a87ecb45..a4cde3fe827 100644 --- a/vendor/github.com/cilium/ebpf/internal/btf/btf_types.go +++ b/vendor/github.com/cilium/ebpf/internal/btf/btf_types.go @@ -40,10 +40,12 @@ const ( ) const ( - btfTypeKindShift = 24 - btfTypeKindLen = 4 - btfTypeVlenShift = 0 - btfTypeVlenMask = 16 + btfTypeKindShift = 24 + btfTypeKindLen = 4 + btfTypeVlenShift = 0 + btfTypeVlenMask = 16 + btfTypeKindFlagShift = 31 + btfTypeKindFlagMask = 1 ) // btfType is equivalent to struct btf_type in Documentation/bpf/btf.rst. @@ -136,6 +138,10 @@ func (bt *btfType) SetVlen(vlen int) { bt.setInfo(uint32(vlen), btfTypeVlenMask, btfTypeVlenShift) } +func (bt *btfType) KindFlag() bool { + return bt.info(btfTypeKindFlagMask, btfTypeKindFlagShift) == 1 +} + func (bt *btfType) Linkage() btfFuncLinkage { return btfFuncLinkage(bt.info(btfTypeVlenMask, btfTypeVlenShift)) } @@ -257,3 +263,7 @@ func readTypes(r io.Reader, bo binary.ByteOrder) ([]rawType, error) { types = append(types, rawType{header, data}) } } + +func intEncoding(raw uint32) (IntEncoding, uint32, byte) { + return IntEncoding((raw & 0x0f000000) >> 24), (raw & 0x00ff0000) >> 16, byte(raw & 0x000000ff) +} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go b/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go index 28918ae9e0c..c1c82ec7f80 100644 --- a/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go +++ b/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go @@ -1,6 +1,7 @@ package btf import ( + "bufio" "bytes" "encoding/binary" "errors" @@ -58,7 +59,8 @@ func parseExtInfos(r io.ReadSeeker, bo binary.ByteOrder, strings stringTable) (f return nil, nil, fmt.Errorf("can't seek to function info section: %v", err) } - funcInfo, err = parseExtInfo(io.LimitReader(r, int64(header.FuncInfoLen)), bo, strings) + buf := bufio.NewReader(io.LimitReader(r, int64(header.FuncInfoLen))) + funcInfo, err = parseExtInfo(buf, bo, strings) if err != nil { return nil, nil, fmt.Errorf("function info: %w", err) } @@ -67,7 +69,8 @@ func parseExtInfos(r io.ReadSeeker, bo binary.ByteOrder, strings stringTable) (f return nil, nil, fmt.Errorf("can't seek to line info section: %v", err) } - lineInfo, err = parseExtInfo(io.LimitReader(r, int64(header.LineInfoLen)), bo, strings) + buf = bufio.NewReader(io.LimitReader(r, int64(header.LineInfoLen))) + lineInfo, err = parseExtInfo(buf, bo, strings) if err != nil { return nil, nil, fmt.Errorf("line info: %w", err) } @@ -127,6 +130,8 @@ func (ei extInfo) MarshalBinary() ([]byte, error) { } func parseExtInfo(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[string]extInfo, error) { + const maxRecordSize = 256 + var recordSize uint32 if err := binary.Read(r, bo, &recordSize); err != nil { return nil, fmt.Errorf("can't read record size: %v", err) @@ -136,6 +141,9 @@ func parseExtInfo(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[st // Need at least insnOff return nil, errors.New("record size too short") } + if recordSize > maxRecordSize { + return nil, fmt.Errorf("record size %v exceeds %v", recordSize, maxRecordSize) + } result := make(map[string]extInfo) for { diff --git a/vendor/github.com/cilium/ebpf/internal/btf/fuzz.go b/vendor/github.com/cilium/ebpf/internal/btf/fuzz.go new file mode 100644 index 00000000000..37e043fd378 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/btf/fuzz.go @@ -0,0 +1,49 @@ +// +build gofuzz + +// Use with https://github.com/dvyukov/go-fuzz + +package btf + +import ( + "bytes" + "encoding/binary" + + "github.com/cilium/ebpf/internal" +) + +func FuzzSpec(data []byte) int { + if len(data) < binary.Size(btfHeader{}) { + return -1 + } + + spec, err := loadNakedSpec(bytes.NewReader(data), internal.NativeEndian, nil, nil) + if err != nil { + if spec != nil { + panic("spec is not nil") + } + return 0 + } + if spec == nil { + panic("spec is nil") + } + return 1 +} + +func FuzzExtInfo(data []byte) int { + if len(data) < binary.Size(btfExtHeader{}) { + return -1 + } + + table := stringTable("\x00foo\x00barfoo\x00") + info, err := parseExtInfo(bytes.NewReader(data), internal.NativeEndian, table) + if err != nil { + if info != nil { + panic("info is not nil") + } + return 0 + } + if info == nil { + panic("info is nil") + } + return 1 +} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/types.go b/vendor/github.com/cilium/ebpf/internal/btf/types.go index 264142abc0a..a93039bd518 100644 --- a/vendor/github.com/cilium/ebpf/internal/btf/types.go +++ b/vendor/github.com/cilium/ebpf/internal/btf/types.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "math" + "strings" ) const maxTypeDepth = 32 @@ -23,9 +24,19 @@ type Type interface { // Make a copy of the type, without copying Type members. copy() Type + // Enumerate all nested Types. Repeated calls must visit nested + // types in the same order. walk(*copyStack) } +// namedType is a type with a name. +// +// Most named types simply embed Name. +type namedType interface { + Type + name() string +} + // Name identifies a type. // // Anonymous types have an empty name. @@ -43,15 +54,30 @@ func (v *Void) size() uint32 { return 0 } func (v *Void) copy() Type { return (*Void)(nil) } func (v *Void) walk(*copyStack) {} +type IntEncoding byte + +const ( + Signed IntEncoding = 1 << iota + Char + Bool +) + // Int is an integer of a given length. type Int struct { TypeID Name // The size of the integer in bytes. - Size uint32 + Size uint32 + Encoding IntEncoding + // Offset is the starting bit offset. Currently always 0. + // See https://www.kernel.org/doc/html/latest/bpf/btf.html#btf-kind-int + Offset uint32 + Bits byte } +var _ namedType = (*Int)(nil) + func (i *Int) size() uint32 { return i.Size } func (i *Int) walk(*copyStack) {} func (i *Int) copy() Type { @@ -109,6 +135,10 @@ func (s *Struct) copy() Type { return &cpy } +func (s *Struct) members() []Member { + return s.Members +} + // Union is a compound type where members occupy the same memory. type Union struct { TypeID @@ -133,25 +163,51 @@ func (u *Union) copy() Type { return &cpy } +func (u *Union) members() []Member { + return u.Members +} + +type composite interface { + members() []Member +} + +var ( + _ composite = (*Struct)(nil) + _ composite = (*Union)(nil) +) + // Member is part of a Struct or Union. // // It is not a valid Type. type Member struct { Name - Type Type - Offset uint32 + Type Type + // Offset is the bit offset of this member + Offset uint32 + BitfieldSize uint32 } // Enum lists possible values. type Enum struct { TypeID Name + Values []EnumValue +} + +// EnumValue is part of an Enum +// +// Is is not a valid Type +type EnumValue struct { + Name + Value int32 } func (e *Enum) size() uint32 { return 4 } func (e *Enum) walk(*copyStack) {} func (e *Enum) copy() Type { cpy := *e + cpy.Values = make([]EnumValue, len(e.Values)) + copy(cpy.Values, e.Values) return &cpy } @@ -180,36 +236,39 @@ func (td *Typedef) copy() Type { return &cpy } -// Volatile is a modifier. +// Volatile is a qualifier. type Volatile struct { TypeID Type Type } +func (v *Volatile) qualify() Type { return v.Type } func (v *Volatile) walk(cs *copyStack) { cs.push(&v.Type) } func (v *Volatile) copy() Type { cpy := *v return &cpy } -// Const is a modifier. +// Const is a qualifier. type Const struct { TypeID Type Type } +func (c *Const) qualify() Type { return c.Type } func (c *Const) walk(cs *copyStack) { cs.push(&c.Type) } func (c *Const) copy() Type { cpy := *c return &cpy } -// Restrict is a modifier. +// Restrict is a qualifier. type Restrict struct { TypeID Type Type } +func (r *Restrict) qualify() Type { return r.Type } func (r *Restrict) walk(cs *copyStack) { cs.push(&r.Type) } func (r *Restrict) copy() Type { cpy := *r @@ -233,15 +292,28 @@ func (f *Func) copy() Type { type FuncProto struct { TypeID Return Type - // Parameters not supported yet + Params []FuncParam +} + +func (fp *FuncProto) walk(cs *copyStack) { + cs.push(&fp.Return) + for i := range fp.Params { + cs.push(&fp.Params[i].Type) + } } -func (fp *FuncProto) walk(cs *copyStack) { cs.push(&fp.Return) } func (fp *FuncProto) copy() Type { cpy := *fp + cpy.Params = make([]FuncParam, len(fp.Params)) + copy(cpy.Params, fp.Params) return &cpy } +type FuncParam struct { + Name + Type Type +} + // Var is a global variable. type Var struct { TypeID @@ -298,6 +370,16 @@ var ( _ sizer = (*Datasec)(nil) ) +type qualifier interface { + qualify() Type +} + +var ( + _ qualifier = (*Const)(nil) + _ qualifier = (*Restrict)(nil) + _ qualifier = (*Volatile)(nil) +) + // Sizeof returns the size of a type in bytes. // // Returns an error if the size can't be computed. @@ -326,14 +408,9 @@ func Sizeof(typ Type) (int, error) { case *Typedef: typ = v.Type continue - case *Volatile: - typ = v.Type - continue - case *Const: - typ = v.Type - continue - case *Restrict: - typ = v.Type + + case qualifier: + typ = v.qualify() continue default: @@ -383,7 +460,7 @@ func copyType(typ Type) Type { } // copyStack keeps track of pointers to types which still -// need to be copied. +// need to be visited. type copyStack []*Type // push adds a type to the stack. @@ -403,19 +480,13 @@ func (cs *copyStack) pop() *Type { return t } -type namer interface { - name() string -} - -var _ namer = Name("") - // inflateRawTypes takes a list of raw btf types linked via type IDs, and turns // it into a graph of Types connected via pointers. // // Returns a map of named types (so, where NameOff is non-zero). Since BTF ignores // compilation units, multiple types may share the same name. A Type may form a // cyclic graph by pointing at itself. -func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map[string][]Type, err error) { +func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map[string][]namedType, err error) { type fixupDef struct { id TypeID expectedKind btfKind @@ -427,7 +498,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map fixups = append(fixups, fixupDef{id, expectedKind, typ}) } - convertMembers := func(raw []btfMember) ([]Member, error) { + convertMembers := func(raw []btfMember, kindFlag bool) ([]Member, error) { // NB: The fixup below relies on pre-allocating this array to // work, since otherwise append might re-allocate members. members := make([]Member, 0, len(raw)) @@ -436,10 +507,15 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map if err != nil { return nil, fmt.Errorf("can't get name for member %d: %w", i, err) } - members = append(members, Member{ + m := Member{ Name: name, Offset: btfMember.Offset, - }) + } + if kindFlag { + m.BitfieldSize = btfMember.Offset >> 24 + m.Offset &= 0xffffff + } + members = append(members, m) } for i := range members { fixup(raw[i].Type, kindUnknown, &members[i].Type) @@ -449,7 +525,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map types := make([]Type, 0, len(rawTypes)) types = append(types, (*Void)(nil)) - namedTypes = make(map[string][]Type) + namedTypes = make(map[string][]namedType) for i, raw := range rawTypes { var ( @@ -466,7 +542,8 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map switch raw.Kind() { case kindInt: - typ = &Int{id, name, raw.Size()} + encoding, offset, bits := intEncoding(*raw.data.(*uint32)) + typ = &Int{id, name, raw.Size(), encoding, offset, bits} case kindPointer: ptr := &Pointer{id, nil} @@ -483,21 +560,33 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map typ = arr case kindStruct: - members, err := convertMembers(raw.data.([]btfMember)) + members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag()) if err != nil { return nil, fmt.Errorf("struct %s (id %d): %w", name, id, err) } typ = &Struct{id, name, raw.Size(), members} case kindUnion: - members, err := convertMembers(raw.data.([]btfMember)) + members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag()) if err != nil { return nil, fmt.Errorf("union %s (id %d): %w", name, id, err) } typ = &Union{id, name, raw.Size(), members} case kindEnum: - typ = &Enum{id, name} + rawvals := raw.data.([]btfEnum) + vals := make([]EnumValue, 0, len(rawvals)) + for i, btfVal := range rawvals { + name, err := rawStrings.LookupName(btfVal.NameOff) + if err != nil { + return nil, fmt.Errorf("can't get name for enum value %d: %s", i, err) + } + vals = append(vals, EnumValue{ + Name: name, + Value: btfVal.Val, + }) + } + typ = &Enum{id, name, vals} case kindForward: typ = &Fwd{id, name} @@ -528,7 +617,22 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map typ = fn case kindFuncProto: - fp := &FuncProto{id, nil} + rawparams := raw.data.([]btfParam) + params := make([]FuncParam, 0, len(rawparams)) + for i, param := range rawparams { + name, err := rawStrings.LookupName(param.NameOff) + if err != nil { + return nil, fmt.Errorf("can't get name for func proto parameter %d: %s", i, err) + } + params = append(params, FuncParam{ + Name: name, + }) + } + for i := range params { + fixup(rawparams[i].Type, kindUnknown, ¶ms[i].Type) + } + + fp := &FuncProto{id, nil, params} fixup(raw.Type(), kindUnknown, &fp.Return) typ = fp @@ -557,9 +661,9 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map types = append(types, typ) - if namer, ok := typ.(namer); ok { - if name := namer.name(); name != "" { - namedTypes[name] = append(namedTypes[name], typ) + if named, ok := typ.(namedType); ok { + if name := essentialName(named.name()); name != "" { + namedTypes[name] = append(namedTypes[name], named) } } } @@ -585,3 +689,12 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map return namedTypes, nil } + +// essentialName returns name without a ___ suffix. +func essentialName(name string) string { + lastIdx := strings.LastIndex(name, "___") + if lastIdx > 0 { + return name[:lastIdx] + } + return name +} diff --git a/vendor/github.com/cilium/ebpf/internal/feature.go b/vendor/github.com/cilium/ebpf/internal/feature.go index 7375b21ef98..8f282db64df 100644 --- a/vendor/github.com/cilium/ebpf/internal/feature.go +++ b/vendor/github.com/cilium/ebpf/internal/feature.go @@ -20,6 +20,9 @@ type UnsupportedFeatureError struct { } func (ufe *UnsupportedFeatureError) Error() string { + if ufe.MinimumVersion.Unspecified() { + return fmt.Sprintf("%s not supported", ufe.Name) + } return fmt.Sprintf("%s not supported (requires >= %s)", ufe.Name, ufe.MinimumVersion) } @@ -120,3 +123,8 @@ func (v Version) Less(other Version) bool { } return false } + +// Unspecified returns true if the version is all zero. +func (v Version) Unspecified() bool { + return v[0] == 0 && v[1] == 0 && v[2] == 0 +} diff --git a/vendor/github.com/cilium/ebpf/internal/syscall.go b/vendor/github.com/cilium/ebpf/internal/syscall.go index efbf40327c6..9c5e0b3edd1 100644 --- a/vendor/github.com/cilium/ebpf/internal/syscall.go +++ b/vendor/github.com/cilium/ebpf/internal/syscall.go @@ -137,3 +137,30 @@ func BPFObjGet(fileName string) (*FD, error) { } return NewFD(uint32(ptr)), nil } + +type bpfObjGetInfoByFDAttr struct { + fd uint32 + infoLen uint32 + info Pointer +} + +// BPFObjGetInfoByFD wraps BPF_OBJ_GET_INFO_BY_FD. +// +// Available from 4.13. +func BPFObjGetInfoByFD(fd *FD, info unsafe.Pointer, size uintptr) error { + value, err := fd.Value() + if err != nil { + return err + } + + attr := bpfObjGetInfoByFDAttr{ + fd: value, + infoLen: uint32(size), + info: NewPointer(info), + } + _, err = BPF(BPF_OBJ_GET_INFO_BY_FD, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) + if err != nil { + return fmt.Errorf("fd %v: %w", fd, err) + } + return nil +} diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go index 9363d0be81c..d8135c1836b 100644 --- a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go +++ b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go @@ -3,6 +3,7 @@ package unix import ( + "bytes" "syscall" linux "golang.org/x/sys/unix" @@ -19,6 +20,7 @@ const ( EPERM = linux.EPERM ESRCH = linux.ESRCH ENODEV = linux.ENODEV + BPF_F_NUMA_NODE = linux.BPF_F_NUMA_NODE BPF_F_RDONLY_PROG = linux.BPF_F_RDONLY_PROG BPF_F_WRONLY_PROG = linux.BPF_F_WRONLY_PROG BPF_OBJ_NAME_LEN = linux.BPF_OBJ_NAME_LEN @@ -148,3 +150,15 @@ func Gettid() int { func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) { return linux.Tgkill(tgid, tid, sig) } + +func KernelRelease() (string, error) { + var uname Utsname + err := Uname(&uname) + if err != nil { + return "", err + } + + end := bytes.IndexByte(uname.Release[:], 0) + release := string(uname.Release[:end]) + return release, nil +} diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go index 2dea950f888..416b8d2f5de 100644 --- a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go +++ b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go @@ -20,6 +20,7 @@ const ( EPERM = syscall.EPERM ESRCH = syscall.ESRCH ENODEV = syscall.ENODEV + BPF_F_NUMA_NODE = 0 BPF_F_RDONLY_PROG = 0 BPF_F_WRONLY_PROG = 0 BPF_OBJ_NAME_LEN = 0x10 @@ -215,3 +216,7 @@ func Gettid() int { func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) { return errNonLinux } + +func KernelRelease() (string, error) { + return "", errNonLinux +} diff --git a/vendor/github.com/cilium/ebpf/linker.go b/vendor/github.com/cilium/ebpf/linker.go index 1bb8f61c25a..fc4ad9dffa2 100644 --- a/vendor/github.com/cilium/ebpf/linker.go +++ b/vendor/github.com/cilium/ebpf/linker.go @@ -84,3 +84,50 @@ func needSection(insns, section asm.Instructions) (bool, error) { // None of the functions in the section are called. return false, nil } + +func fixupJumpsAndCalls(insns asm.Instructions) error { + symbolOffsets := make(map[string]asm.RawInstructionOffset) + iter := insns.Iterate() + for iter.Next() { + ins := iter.Ins + + if ins.Symbol == "" { + continue + } + + if _, ok := symbolOffsets[ins.Symbol]; ok { + return fmt.Errorf("duplicate symbol %s", ins.Symbol) + } + + symbolOffsets[ins.Symbol] = iter.Offset + } + + iter = insns.Iterate() + for iter.Next() { + i := iter.Index + offset := iter.Offset + ins := iter.Ins + + switch { + case ins.IsFunctionCall() && ins.Constant == -1: + // Rewrite bpf to bpf call + callOffset, ok := symbolOffsets[ins.Reference] + if !ok { + return fmt.Errorf("instruction %d: reference to missing symbol %s", i, ins.Reference) + } + + ins.Constant = int64(callOffset - offset - 1) + + case ins.OpCode.Class() == asm.JumpClass && ins.Offset == -1: + // Rewrite jump to label + jumpOffset, ok := symbolOffsets[ins.Reference] + if !ok { + return fmt.Errorf("instruction %d: reference to missing symbol %s", i, ins.Reference) + } + + ins.Offset = int16(jumpOffset - offset - 1) + } + } + + return nil +} diff --git a/vendor/github.com/cilium/ebpf/map.go b/vendor/github.com/cilium/ebpf/map.go index 461b995a54b..5c9028d9de5 100644 --- a/vendor/github.com/cilium/ebpf/map.go +++ b/vendor/github.com/cilium/ebpf/map.go @@ -3,6 +3,8 @@ package ebpf import ( "errors" "fmt" + "io" + "path/filepath" "strings" "github.com/cilium/ebpf/internal" @@ -17,6 +19,14 @@ var ( ErrIterationAborted = errors.New("iteration aborted") ) +// MapOptions control loading a map into the kernel. +type MapOptions struct { + // The base path to pin maps in if requested via PinByName. + // Existing maps will be re-used if they are compatible, otherwise an + // error is returned. + PinPath string +} + // MapID represents the unique ID of an eBPF map type MapID uint32 @@ -31,6 +41,15 @@ type MapSpec struct { MaxEntries uint32 Flags uint32 + // Automatically pin and load a map from MapOptions.PinPath. + // Generates an error if an existing pinned map is incompatible with the MapSpec. + Pinning PinType + + // Specify numa node during map creation + // (effective only if unix.BPF_F_NUMA_NODE flag is set, + // which can be imported from golang.org/x/sys/unix) + NumaNode uint32 + // The initial contents of the map. May be nil. Contents []MapKV @@ -69,6 +88,26 @@ type MapKV struct { Value interface{} } +func (ms *MapSpec) checkCompatibility(m *Map) error { + switch { + case m.abi.Type != ms.Type: + return fmt.Errorf("expected type %v, got %v", ms.Type, m.abi.Type) + + case m.abi.KeySize != ms.KeySize: + return fmt.Errorf("expected key size %v, got %v", ms.KeySize, m.abi.KeySize) + + case m.abi.ValueSize != ms.ValueSize: + return fmt.Errorf("expected value size %v, got %v", ms.ValueSize, m.abi.ValueSize) + + case m.abi.MaxEntries != ms.MaxEntries: + return fmt.Errorf("expected max entries %v, got %v", ms.MaxEntries, m.abi.MaxEntries) + + case m.abi.Flags != ms.Flags: + return fmt.Errorf("expected flags %v, got %v", ms.Flags, m.abi.Flags) + } + return nil +} + // Map represents a Map file descriptor. // // It is not safe to close a map which is used by other goroutines. @@ -105,15 +144,22 @@ func NewMapFromFD(fd int) (*Map, error) { // NewMap creates a new Map. // +// It's equivalent to calling NewMapWithOptions with default options. +func NewMap(spec *MapSpec) (*Map, error) { + return NewMapWithOptions(spec, MapOptions{}) +} + +// NewMapWithOptions creates a new Map. +// // Creating a map for the first time will perform feature detection // by creating small, temporary maps. // // The caller is responsible for ensuring the process' rlimit is set // sufficiently high for locking memory during map creation. This can be done -// by calling unix.Setrlimit with unix.RLIMIT_MEMLOCK prior to calling NewMap. -func NewMap(spec *MapSpec) (*Map, error) { +// by calling unix.Setrlimit with unix.RLIMIT_MEMLOCK prior to calling NewMapWithOptions. +func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) { if spec.BTF == nil { - return newMapWithBTF(spec, nil) + return newMapWithBTF(spec, nil, opts) } handle, err := btf.NewHandle(btf.MapSpec(spec.BTF)) @@ -121,28 +167,75 @@ func NewMap(spec *MapSpec) (*Map, error) { return nil, fmt.Errorf("can't load BTF: %w", err) } - return newMapWithBTF(spec, handle) + return newMapWithBTF(spec, handle, opts) } -func newMapWithBTF(spec *MapSpec, handle *btf.Handle) (*Map, error) { - if spec.Type != ArrayOfMaps && spec.Type != HashOfMaps { - return createMap(spec, nil, handle) +func newMapWithBTF(spec *MapSpec, handle *btf.Handle, opts MapOptions) (*Map, error) { + switch spec.Pinning { + case PinByName: + if spec.Name == "" || opts.PinPath == "" { + return nil, fmt.Errorf("pin by name: missing Name or PinPath") + } + + m, err := LoadPinnedMap(filepath.Join(opts.PinPath, spec.Name)) + if errors.Is(err, unix.ENOENT) { + break + } + if err != nil { + return nil, fmt.Errorf("load pinned map: %s", err) + } + + if err := spec.checkCompatibility(m); err != nil { + m.Close() + return nil, fmt.Errorf("use pinned map %s: %s", spec.Name, err) + } + + return m, nil + + case PinNone: + // Nothing to do here + + default: + return nil, fmt.Errorf("unsupported pin type %d", int(spec.Pinning)) } - if spec.InnerMap == nil { - return nil, fmt.Errorf("%s requires InnerMap", spec.Type) + var innerFd *internal.FD + if spec.Type == ArrayOfMaps || spec.Type == HashOfMaps { + if spec.InnerMap == nil { + return nil, fmt.Errorf("%s requires InnerMap", spec.Type) + } + + template, err := createMap(spec.InnerMap, nil, handle, opts) + if err != nil { + return nil, err + } + defer template.Close() + + innerFd = template.fd } - template, err := createMap(spec.InnerMap, nil, handle) + m, err := createMap(spec, innerFd, handle, opts) if err != nil { return nil, err } - defer template.Close() - return createMap(spec, template.fd, handle) + if spec.Pinning == PinByName { + if err := m.Pin(filepath.Join(opts.PinPath, spec.Name)); err != nil { + m.Close() + return nil, fmt.Errorf("pin map: %s", err) + } + } + + return m, nil } -func createMap(spec *MapSpec, inner *internal.FD, handle *btf.Handle) (*Map, error) { +func createMap(spec *MapSpec, inner *internal.FD, handle *btf.Handle, opts MapOptions) (_ *Map, err error) { + closeOnError := func(closer io.Closer) { + if err != nil { + closer.Close() + } + } + abi := newMapABIFromSpec(spec) switch spec.Type { @@ -190,6 +283,7 @@ func createMap(spec *MapSpec, inner *internal.FD, handle *btf.Handle) (*Map, err valueSize: abi.ValueSize, maxEntries: abi.MaxEntries, flags: abi.Flags, + numaNode: spec.NumaNode, } if inner != nil { @@ -214,6 +308,7 @@ func createMap(spec *MapSpec, inner *internal.FD, handle *btf.Handle) (*Map, err if err != nil { return nil, fmt.Errorf("map create: %w", err) } + defer closeOnError(fd) m, err := newMap(fd, spec.Name, abi) if err != nil { @@ -221,13 +316,11 @@ func createMap(spec *MapSpec, inner *internal.FD, handle *btf.Handle) (*Map, err } if err := m.populate(spec.Contents); err != nil { - m.Close() return nil, fmt.Errorf("map create: can't set initial contents: %w", err) } if spec.Freeze { if err := m.Freeze(); err != nil { - m.Close() return nil, fmt.Errorf("can't freeze map: %w", err) } } @@ -263,7 +356,34 @@ func (m *Map) String() string { return fmt.Sprintf("%s#%v", m.abi.Type, m.fd) } -// ABI gets the ABI of the Map +// Type returns the underlying type of the map. +func (m *Map) Type() MapType { + return m.abi.Type +} + +// KeySize returns the size of the map key in bytes. +func (m *Map) KeySize() uint32 { + return m.abi.KeySize +} + +// ValueSize returns the size of the map value in bytes. +func (m *Map) ValueSize() uint32 { + return m.abi.ValueSize +} + +// MaxEntries returns the maximum number of elements the map can hold. +func (m *Map) MaxEntries() uint32 { + return m.abi.MaxEntries +} + +// Flags returns the flags of the map. +func (m *Map) Flags() uint32 { + return m.abi.Flags +} + +// ABI gets the ABI of the Map. +// +// Deprecated: use Type, KeySize, ValueSize, MaxEntries and Flags instead. func (m *Map) ABI() MapABI { return m.abi } @@ -544,7 +664,7 @@ func (m *Map) Clone() (*Map, error) { // Pin persists the map past the lifetime of the process that created it. // -// This requires bpffs to be mounted above fileName. See http://cilium.readthedocs.io/en/doc-1.0/kubernetes/install/#mounting-the-bpf-fs-optional +// This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs func (m *Map) Pin(fileName string) error { return internal.BPFObjPin(fileName, m.fd) } @@ -789,6 +909,8 @@ func NewMapFromID(id MapID) (*Map, error) { } // ID returns the systemwide unique ID of the map. +// +// Requires at least Linux 4.13. func (m *Map) ID() (MapID, error) { info, err := bpfGetMapInfoByFD(m.fd) if err != nil { diff --git a/vendor/github.com/cilium/ebpf/prog.go b/vendor/github.com/cilium/ebpf/prog.go index 429203f07e8..67cfff67eb1 100644 --- a/vendor/github.com/cilium/ebpf/prog.go +++ b/vendor/github.com/cilium/ebpf/prog.go @@ -208,8 +208,15 @@ func convertProgramSpec(spec *ProgramSpec, handle *btf.Handle) (*bpfProgLoadAttr return nil, fmt.Errorf("can't load %s program on %s", spec.ByteOrder, internal.NativeEndian) } + insns := make(asm.Instructions, len(spec.Instructions)) + copy(insns, spec.Instructions) + + if err := fixupJumpsAndCalls(insns); err != nil { + return nil, err + } + buf := bytes.NewBuffer(make([]byte, 0, len(spec.Instructions)*asm.InstructionSize)) - err := spec.Instructions.Marshal(buf, internal.NativeEndian) + err := insns.Marshal(buf, internal.NativeEndian) if err != nil { return nil, err } @@ -269,7 +276,14 @@ func (p *Program) String() string { return fmt.Sprintf("%s#%v", p.abi.Type, p.fd) } -// ABI gets the ABI of the Program +// Type returns the underlying type of the program. +func (p *Program) Type() ProgramType { + return p.abi.Type +} + +// ABI gets the ABI of the Program. +// +// Deprecated: use Type instead. func (p *Program) ABI() ProgramABI { return p.abi } @@ -308,7 +322,7 @@ func (p *Program) Clone() (*Program, error) { // Pin persists the Program past the lifetime of the process that created it // -// This requires bpffs to be mounted above fileName. See http://cilium.readthedocs.io/en/doc-1.0/kubernetes/install/#mounting-the-bpf-fs-optional +// This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs func (p *Program) Pin(fileName string) error { if err := internal.BPFObjPin(fileName, p.fd); err != nil { return fmt.Errorf("can't pin program: %w", err) @@ -595,12 +609,16 @@ func (p *Program) ID() (ProgramID, error) { return ProgramID(info.id), nil } -func resolveBTFType(name string, progType ProgramType, attachType AttachType) (btf.Type, error) { +func findKernelType(name string, typ btf.Type) error { kernel, err := btf.LoadKernelSpec() if err != nil { - return nil, fmt.Errorf("can't resolve BTF type %s: %w", name, err) + return fmt.Errorf("can't load kernel spec: %w", err) } + return kernel.FindType(name, typ) +} + +func resolveBTFType(name string, progType ProgramType, attachType AttachType) (btf.Type, error) { type match struct { p ProgramType a AttachType @@ -608,10 +626,30 @@ func resolveBTFType(name string, progType ProgramType, attachType AttachType) (b target := match{progType, attachType} switch target { + case match{LSM, AttachLSMMac}: + var target btf.Func + err := findKernelType("bpf_lsm_"+name, &target) + if errors.Is(err, btf.ErrNotFound) { + return nil, &internal.UnsupportedFeatureError{ + Name: name + " LSM hook", + } + } + if err != nil { + return nil, fmt.Errorf("resolve BTF for LSM hook %s: %w", name, err) + } + + return &target, nil + case match{Tracing, AttachTraceIter}: var target btf.Func - if err := kernel.FindType("bpf_iter_"+name, &target); err != nil { - return nil, fmt.Errorf("can't resolve BTF for iterator %s: %w", name, err) + err := findKernelType("bpf_iter_"+name, &target) + if errors.Is(err, btf.ErrNotFound) { + return nil, &internal.UnsupportedFeatureError{ + Name: name + " iterator", + } + } + if err != nil { + return nil, fmt.Errorf("resolve BTF for iterator %s: %w", name, err) } return &target, nil diff --git a/vendor/github.com/cilium/ebpf/readme.md b/vendor/github.com/cilium/ebpf/readme.md index cc8e89c75a9..298db57c300 100644 --- a/vendor/github.com/cilium/ebpf/readme.md +++ b/vendor/github.com/cilium/ebpf/readme.md @@ -1,10 +1,13 @@ eBPF ------- -[![](https://godoc.org/github.com/cilium/ebpf?status.svg)](https://godoc.org/github.com/cilium/ebpf) +[![PkgGoDev](https://pkg.go.dev/badge/github.com/cilium/ebpf)](https://pkg.go.dev/github.com/cilium/ebpf) eBPF is a pure Go library that provides utilities for loading, compiling, and debugging eBPF programs. It has minimal external dependencies and is intended to be used in long running processes. -[ebpf/asm](https://godoc.org/github.com/cilium/ebpf/asm) contains a basic assembler. +* [asm](https://pkg.go.dev/github.com/cilium/ebpf/asm) contains a basic assembler. +* [link](https://pkg.go.dev/github.com/cilium/ebpf/link) allows attaching eBPF to various hooks. +* [perf](https://pkg.go.dev/github.com/cilium/ebpf/perf) allows reading from a PERF_EVENT_ARRAY. +* [cmd/bpf2go](https://pkg.go.dev/github.com/cilium/ebpf/cmd/bpf2go) allows embedding eBPF in Go. The library is maintained by [Cloudflare](https://www.cloudflare.com) and [Cilium](https://www.cilium.io). Feel free to [join](https://cilium.herokuapp.com/) the [libbpf-go](https://cilium.slack.com/messages/libbpf-go) channel on Slack. @@ -20,6 +23,7 @@ right now**. Expect to update your code if you want to follow along. ## Useful resources -* [Cilium eBPF documentation](https://cilium.readthedocs.io/en/latest/bpf/#bpf-guide) (recommended) +* [eBPF.io](https://ebpf.io) (recommended) +* [Cilium eBPF documentation](https://docs.cilium.io/en/latest/bpf/#bpf-guide) (recommended) * [Linux documentation on BPF](http://elixir.free-electrons.com/linux/latest/source/Documentation/networking/filter.txt) * [eBPF features by Linux version](https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md) diff --git a/vendor/github.com/cilium/ebpf/run-tests.sh b/vendor/github.com/cilium/ebpf/run-tests.sh index c43a90ddd0d..bd349f95160 100644 --- a/vendor/github.com/cilium/ebpf/run-tests.sh +++ b/vendor/github.com/cilium/ebpf/run-tests.sh @@ -12,7 +12,8 @@ if [[ "${1:-}" = "--in-vm" ]]; then export CGO_ENABLED=0 export GOFLAGS=-mod=readonly export GOPATH=/run/go-path - export GOPROXY=file:///run/go-root/pkg/mod/cache/download + export GOPROXY=file:///run/go-path/pkg/mod/cache/download + export GOSUMDB=off export GOCACHE=/run/go-cache elfs="" @@ -21,7 +22,9 @@ if [[ "${1:-}" = "--in-vm" ]]; then fi echo Running tests... - /usr/local/bin/go test -coverprofile="$1/coverage.txt" -covermode=atomic -v -elfs "$elfs" ./... + # TestLibBPFCompat runs separately to pass the "-elfs" flag only for it: https://github.com/cilium/ebpf/pull/119 + go test -v -count 1 -run TestLibBPFCompat -elfs "$elfs" + go test -v -count 1 ./... touch "$1/success" exit 0 fi @@ -66,11 +69,12 @@ fi echo Testing on "${kernel_version}" $sudo virtme-run --kimg "${tmp_dir}/${kernel}" --memory 512M --pwd \ + --rw \ --rwdir=/run/input="${input}" \ --rwdir=/run/output="${output}" \ --rodir=/run/go-path="$(go env GOPATH)" \ --rwdir=/run/go-cache="$(go env GOCACHE)" \ - --script-sh "$(realpath "$0") --in-vm /run/output" \ + --script-sh "PATH=\"$PATH\" $(realpath "$0") --in-vm /run/output" \ --qemu-opts -smp 2 # need at least two CPUs for some tests if [[ ! -e "${output}/success" ]]; then @@ -78,11 +82,11 @@ if [[ ! -e "${output}/success" ]]; then exit 1 else echo "Test successful on ${kernel_version}" - if [[ -v CODECOV_TOKEN ]]; then - curl --fail -s https://codecov.io/bash > "${tmp_dir}/codecov.sh" - chmod +x "${tmp_dir}/codecov.sh" - "${tmp_dir}/codecov.sh" -f "${output}/coverage.txt" - fi +# if [[ -v CODECOV_TOKEN ]]; then +# curl --fail -s https://codecov.io/bash > "${tmp_dir}/codecov.sh" +# chmod +x "${tmp_dir}/codecov.sh" +# "${tmp_dir}/codecov.sh" -f "${output}/coverage.txt" +# fi fi $sudo rm -r "${input}" diff --git a/vendor/github.com/cilium/ebpf/syscalls.go b/vendor/github.com/cilium/ebpf/syscalls.go index 2b713d06a0c..ff5c8e6c3c3 100644 --- a/vendor/github.com/cilium/ebpf/syscalls.go +++ b/vendor/github.com/cilium/ebpf/syscalls.go @@ -129,12 +129,6 @@ type bpfProgTestRunAttr struct { duration uint32 } -type bpfObjGetInfoByFDAttr struct { - fd uint32 - infoLen uint32 - info internal.Pointer // May be either bpfMapInfo or bpfProgInfo -} - type bpfGetFDByIDAttr struct { id uint32 next uint32 @@ -353,28 +347,9 @@ func bpfMapFreeze(m *internal.FD) error { return err } -func bpfGetObjectInfoByFD(fd *internal.FD, info unsafe.Pointer, size uintptr) error { - value, err := fd.Value() - if err != nil { - return err - } - - // available from 4.13 - attr := bpfObjGetInfoByFDAttr{ - fd: value, - infoLen: uint32(size), - info: internal.NewPointer(info), - } - _, err = internal.BPF(internal.BPF_OBJ_GET_INFO_BY_FD, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - if err != nil { - return fmt.Errorf("fd %d: %w", fd, err) - } - return nil -} - func bpfGetProgInfoByFD(fd *internal.FD) (*bpfProgInfo, error) { var info bpfProgInfo - if err := bpfGetObjectInfoByFD(fd, unsafe.Pointer(&info), unsafe.Sizeof(info)); err != nil { + if err := internal.BPFObjGetInfoByFD(fd, unsafe.Pointer(&info), unsafe.Sizeof(info)); err != nil { return nil, fmt.Errorf("can't get program info: %w", err) } return &info, nil @@ -382,7 +357,7 @@ func bpfGetProgInfoByFD(fd *internal.FD) (*bpfProgInfo, error) { func bpfGetMapInfoByFD(fd *internal.FD) (*bpfMapInfo, error) { var info bpfMapInfo - err := bpfGetObjectInfoByFD(fd, unsafe.Pointer(&info), unsafe.Sizeof(info)) + err := internal.BPFObjGetInfoByFD(fd, unsafe.Pointer(&info), unsafe.Sizeof(info)) if err != nil { return nil, fmt.Errorf("can't get map info: %w", err) } diff --git a/vendor/github.com/cilium/ebpf/types.go b/vendor/github.com/cilium/ebpf/types.go index 1ffc62123be..dd82dfd4d43 100644 --- a/vendor/github.com/cilium/ebpf/types.go +++ b/vendor/github.com/cilium/ebpf/types.go @@ -1,6 +1,6 @@ package ebpf -//go:generate stringer -output types_string.go -type=MapType,ProgramType,AttachType +//go:generate stringer -output types_string.go -type=MapType,ProgramType,AttachType,PinType // MapType indicates the type map structure // that will be initialized in the kernel. @@ -96,60 +96,37 @@ type ProgramType uint32 // eBPF program types const ( - // Unrecognized program type UnspecifiedProgram ProgramType = iota - // SocketFilter socket or seccomp filter SocketFilter - // Kprobe program Kprobe - // SchedCLS traffic control shaper SchedCLS - // SchedACT routing control shaper SchedACT - // TracePoint program TracePoint - // XDP program XDP - // PerfEvent program PerfEvent - // CGroupSKB program CGroupSKB - // CGroupSock program CGroupSock - // LWTIn program LWTIn - // LWTOut program LWTOut - // LWTXmit program LWTXmit - // SockOps program SockOps - // SkSKB program SkSKB - // CGroupDevice program CGroupDevice - // SkMsg program SkMsg - // RawTracepoint program RawTracepoint - // CGroupSockAddr program CGroupSockAddr - // LWTSeg6Local program LWTSeg6Local - // LircMode2 program LircMode2 - // SkReuseport program SkReuseport - // FlowDissector program FlowDissector - // CGroupSysctl program CGroupSysctl - // RawTracepointWritable program RawTracepointWritable - // CGroupSockopt program CGroupSockopt - // Tracing program Tracing + StructOps + Extension + LSM + SkLookup ) // AttachType of the eBPF program, needed to differentiate allowed context accesses in @@ -190,7 +167,28 @@ const ( AttachModifyReturn AttachLSMMac AttachTraceIter + AttachCgroupInet4GetPeername + AttachCgroupInet6GetPeername + AttachCgroupInet4GetSockname + AttachCgroupInet6GetSockname + AttachXDPDevMap + AttachCgroupInetSockRelease + AttachXDPCPUMap + AttachSkLookup + AttachXDP ) // AttachFlags of the eBPF program used in BPF_PROG_ATTACH command type AttachFlags uint32 + +// PinType determines whether a map is pinned into a BPFFS. +type PinType int + +// Valid pin types. +// +// Mirrors enum libbpf_pin_type. +const ( + PinNone PinType = iota + // Pin an object by using its name as the filename. + PinByName +) diff --git a/vendor/github.com/cilium/ebpf/types_string.go b/vendor/github.com/cilium/ebpf/types_string.go index c7139578ec6..976bd76be01 100644 --- a/vendor/github.com/cilium/ebpf/types_string.go +++ b/vendor/github.com/cilium/ebpf/types_string.go @@ -1,4 +1,4 @@ -// Code generated by "stringer -output types_string.go -type=MapType,ProgramType,AttachType"; DO NOT EDIT. +// Code generated by "stringer -output types_string.go -type=MapType,ProgramType,AttachType,PinType"; DO NOT EDIT. package ebpf @@ -77,11 +77,15 @@ func _() { _ = x[RawTracepointWritable-24] _ = x[CGroupSockopt-25] _ = x[Tracing-26] + _ = x[StructOps-27] + _ = x[Extension-28] + _ = x[LSM-29] + _ = x[SkLookup-30] } -const _ProgramType_name = "UnspecifiedProgramSocketFilterKprobeSchedCLSSchedACTTracePointXDPPerfEventCGroupSKBCGroupSockLWTInLWTOutLWTXmitSockOpsSkSKBCGroupDeviceSkMsgRawTracepointCGroupSockAddrLWTSeg6LocalLircMode2SkReuseportFlowDissectorCGroupSysctlRawTracepointWritableCGroupSockoptTracing" +const _ProgramType_name = "UnspecifiedProgramSocketFilterKprobeSchedCLSSchedACTTracePointXDPPerfEventCGroupSKBCGroupSockLWTInLWTOutLWTXmitSockOpsSkSKBCGroupDeviceSkMsgRawTracepointCGroupSockAddrLWTSeg6LocalLircMode2SkReuseportFlowDissectorCGroupSysctlRawTracepointWritableCGroupSockoptTracingStructOpsExtensionLSMSkLookup" -var _ProgramType_index = [...]uint16{0, 18, 30, 36, 44, 52, 62, 65, 74, 83, 93, 98, 104, 111, 118, 123, 135, 140, 153, 167, 179, 188, 199, 212, 224, 245, 258, 265} +var _ProgramType_index = [...]uint16{0, 18, 30, 36, 44, 52, 62, 65, 74, 83, 93, 98, 104, 111, 118, 123, 135, 140, 153, 167, 179, 188, 199, 212, 224, 245, 258, 265, 274, 283, 286, 294} func (i ProgramType) String() string { if i >= ProgramType(len(_ProgramType_index)-1) { @@ -123,11 +127,20 @@ func _() { _ = x[AttachModifyReturn-26] _ = x[AttachLSMMac-27] _ = x[AttachTraceIter-28] + _ = x[AttachCgroupInet4GetPeername-29] + _ = x[AttachCgroupInet6GetPeername-30] + _ = x[AttachCgroupInet4GetSockname-31] + _ = x[AttachCgroupInet6GetSockname-32] + _ = x[AttachXDPDevMap-33] + _ = x[AttachCgroupInetSockRelease-34] + _ = x[AttachXDPCPUMap-35] + _ = x[AttachSkLookup-36] + _ = x[AttachXDP-37] } -const _AttachType_name = "AttachNoneAttachCGroupInetEgressAttachCGroupInetSockCreateAttachCGroupSockOpsAttachSkSKBStreamParserAttachSkSKBStreamVerdictAttachCGroupDeviceAttachSkMsgVerdictAttachCGroupInet4BindAttachCGroupInet6BindAttachCGroupInet4ConnectAttachCGroupInet6ConnectAttachCGroupInet4PostBindAttachCGroupInet6PostBindAttachCGroupUDP4SendmsgAttachCGroupUDP6SendmsgAttachLircMode2AttachFlowDissectorAttachCGroupSysctlAttachCGroupUDP4RecvmsgAttachCGroupUDP6RecvmsgAttachCGroupGetsockoptAttachCGroupSetsockoptAttachTraceRawTpAttachTraceFEntryAttachTraceFExitAttachModifyReturnAttachLSMMacAttachTraceIter" +const _AttachType_name = "AttachNoneAttachCGroupInetEgressAttachCGroupInetSockCreateAttachCGroupSockOpsAttachSkSKBStreamParserAttachSkSKBStreamVerdictAttachCGroupDeviceAttachSkMsgVerdictAttachCGroupInet4BindAttachCGroupInet6BindAttachCGroupInet4ConnectAttachCGroupInet6ConnectAttachCGroupInet4PostBindAttachCGroupInet6PostBindAttachCGroupUDP4SendmsgAttachCGroupUDP6SendmsgAttachLircMode2AttachFlowDissectorAttachCGroupSysctlAttachCGroupUDP4RecvmsgAttachCGroupUDP6RecvmsgAttachCGroupGetsockoptAttachCGroupSetsockoptAttachTraceRawTpAttachTraceFEntryAttachTraceFExitAttachModifyReturnAttachLSMMacAttachTraceIterAttachCgroupInet4GetPeernameAttachCgroupInet6GetPeernameAttachCgroupInet4GetSocknameAttachCgroupInet6GetSocknameAttachXDPDevMapAttachCgroupInetSockReleaseAttachXDPCPUMapAttachSkLookupAttachXDP" -var _AttachType_index = [...]uint16{0, 10, 32, 58, 77, 100, 124, 142, 160, 181, 202, 226, 250, 275, 300, 323, 346, 361, 380, 398, 421, 444, 466, 488, 504, 521, 537, 555, 567, 582} +var _AttachType_index = [...]uint16{0, 10, 32, 58, 77, 100, 124, 142, 160, 181, 202, 226, 250, 275, 300, 323, 346, 361, 380, 398, 421, 444, 466, 488, 504, 521, 537, 555, 567, 582, 610, 638, 666, 694, 709, 736, 751, 765, 774} func (i AttachType) String() string { if i >= AttachType(len(_AttachType_index)-1) { @@ -135,3 +148,21 @@ func (i AttachType) String() string { } return _AttachType_name[_AttachType_index[i]:_AttachType_index[i+1]] } +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[PinNone-0] + _ = x[PinByName-1] +} + +const _PinType_name = "PinNonePinByName" + +var _PinType_index = [...]uint8{0, 7, 16} + +func (i PinType) String() string { + if i < 0 || i >= PinType(len(_PinType_index)-1) { + return "PinType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _PinType_name[_PinType_index[i]:_PinType_index[i+1]] +} diff --git a/vendor/github.com/containerd/console/.golangci.yml b/vendor/github.com/containerd/console/.golangci.yml new file mode 100644 index 00000000000..fcba5e885f0 --- /dev/null +++ b/vendor/github.com/containerd/console/.golangci.yml @@ -0,0 +1,20 @@ +linters: + enable: + - structcheck + - varcheck + - staticcheck + - unconvert + - gofmt + - goimports + - golint + - ineffassign + - vet + - unused + - misspell + disable: + - errcheck + +run: + timeout: 3m + skip-dirs: + - vendor diff --git a/vendor/github.com/containerd/console/.travis.yml b/vendor/github.com/containerd/console/.travis.yml deleted file mode 100644 index 16827ec3e8f..00000000000 --- a/vendor/github.com/containerd/console/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -language: go -go: - - "1.12.x" - - "1.13.x" - -go_import_path: github.com/containerd/console - -env: - - GO111MODULE=on - -install: - - pushd ..; go get -u github.com/vbatts/git-validation; popd - - pushd ..; go get -u github.com/kunalkushwaha/ltag; popd - -before_script: - - pushd ..; git clone https://github.com/containerd/project; popd - -script: - - DCO_VERBOSITY=-q ../project/script/validate/dco - - ../project/script/validate/fileheader ../project/ - - travis_wait ../project/script/validate/vendor - - go test -race - - GOOS=openbsd go build - - GOOS=openbsd go test -c - - GOOS=solaris go build - - GOOS=solaris go test -c - - GOOS=windows go test diff --git a/vendor/github.com/containerd/console/console.go b/vendor/github.com/containerd/console/console.go index 6a36d147767..f989d28a41c 100644 --- a/vendor/github.com/containerd/console/console.go +++ b/vendor/github.com/containerd/console/console.go @@ -61,18 +61,24 @@ type WinSize struct { y uint16 } -// Current returns the current processes console -func Current() Console { - c, err := ConsoleFromFile(os.Stdin) - if err != nil { - // stdin should always be a console for the design - // of this function - panic(err) +// Current returns the current process' console +func Current() (c Console) { + var err error + // Usually all three streams (stdin, stdout, and stderr) + // are open to the same console, but some might be redirected, + // so try all three. + for _, s := range []*os.File{os.Stderr, os.Stdout, os.Stdin} { + if c, err = ConsoleFromFile(s); err == nil { + return c + } } - return c + // One of the std streams should always be a console + // for the design of this function. + panic(err) } // ConsoleFromFile returns a console using the provided file +// nolint:golint func ConsoleFromFile(f File) (Console, error) { if err := checkConsole(f); err != nil { return nil, err diff --git a/vendor/github.com/containerd/console/console_unix.go b/vendor/github.com/containerd/console/console_unix.go index 315f1d0c90e..a78687523a3 100644 --- a/vendor/github.com/containerd/console/console_unix.go +++ b/vendor/github.com/containerd/console/console_unix.go @@ -1,4 +1,4 @@ -// +build darwin freebsd linux openbsd solaris +// +build darwin freebsd linux netbsd openbsd solaris /* Copyright The containerd Authors. diff --git a/vendor/github.com/containerd/console/go.mod b/vendor/github.com/containerd/console/go.mod index 97b587d62d2..60bf028ee52 100644 --- a/vendor/github.com/containerd/console/go.mod +++ b/vendor/github.com/containerd/console/go.mod @@ -3,6 +3,6 @@ module github.com/containerd/console go 1.13 require ( - github.com/pkg/errors v0.8.1 - golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e + github.com/pkg/errors v0.9.1 + golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f ) diff --git a/vendor/github.com/containerd/console/go.sum b/vendor/github.com/containerd/console/go.sum index 25205cc9b69..6b9363c40a9 100644 --- a/vendor/github.com/containerd/console/go.sum +++ b/vendor/github.com/containerd/console/go.sum @@ -1,4 +1,4 @@ -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f h1:6Sc1XOXTulBN6imkqo6XoAXDEzoQ4/ro6xy7Vn8+rOM= +golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/containerd/console/tc_darwin.go b/vendor/github.com/containerd/console/tc_darwin.go index b0128abb0c6..787154580f6 100644 --- a/vendor/github.com/containerd/console/tc_darwin.go +++ b/vendor/github.com/containerd/console/tc_darwin.go @@ -19,7 +19,6 @@ package console import ( "fmt" "os" - "unsafe" "golang.org/x/sys/unix" ) @@ -29,18 +28,10 @@ const ( cmdTcSet = unix.TIOCSETA ) -func ioctl(fd, flag, data uintptr) error { - if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, flag, data); err != 0 { - return err - } - return nil -} - // unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. // unlockpt should be called before opening the slave side of a pty. func unlockpt(f *os.File) error { - var u int32 - return ioctl(f.Fd(), unix.TIOCPTYUNLK, uintptr(unsafe.Pointer(&u))) + return unix.IoctlSetPointerInt(int(f.Fd()), unix.TIOCPTYUNLK, 0) } // ptsname retrieves the name of the first available pts for the given master. diff --git a/vendor/github.com/containerd/console/tc_linux.go b/vendor/github.com/containerd/console/tc_linux.go index 1bdd68e6d55..75f8694f7fc 100644 --- a/vendor/github.com/containerd/console/tc_linux.go +++ b/vendor/github.com/containerd/console/tc_linux.go @@ -19,7 +19,6 @@ package console import ( "fmt" "os" - "unsafe" "golang.org/x/sys/unix" ) @@ -32,17 +31,13 @@ const ( // unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. // unlockpt should be called before opening the slave side of a pty. func unlockpt(f *os.File) error { - var u int32 - if _, _, err := unix.Syscall(unix.SYS_IOCTL, f.Fd(), unix.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))); err != 0 { - return err - } - return nil + return unix.IoctlSetPointerInt(int(f.Fd()), unix.TIOCSPTLCK, 0) } // ptsname retrieves the name of the first available pts for the given master. func ptsname(f *os.File) (string, error) { - var u uint32 - if _, _, err := unix.Syscall(unix.SYS_IOCTL, f.Fd(), unix.TIOCGPTN, uintptr(unsafe.Pointer(&u))); err != 0 { + u, err := unix.IoctlGetInt(int(f.Fd()), unix.TIOCGPTN) + if err != nil { return "", err } return fmt.Sprintf("/dev/pts/%d", u), nil diff --git a/vendor/github.com/containerd/console/tc_netbsd.go b/vendor/github.com/containerd/console/tc_netbsd.go new file mode 100644 index 00000000000..71227aefdff --- /dev/null +++ b/vendor/github.com/containerd/console/tc_netbsd.go @@ -0,0 +1,45 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package console + +import ( + "bytes" + "os" + + "golang.org/x/sys/unix" +) + +const ( + cmdTcGet = unix.TIOCGETA + cmdTcSet = unix.TIOCSETA +) + +// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f. +// unlockpt should be called before opening the slave side of a pty. +// This does not exist on NetBSD, it does not allocate controlling terminals on open +func unlockpt(f *os.File) error { + return nil +} + +// ptsname retrieves the name of the first available pts for the given master. +func ptsname(f *os.File) (string, error) { + ptm, err := unix.IoctlGetPtmget(int(f.Fd()), unix.TIOCPTSNAME) + if err != nil { + return "", err + } + return string(ptm.Sn[:bytes.IndexByte(ptm.Sn[:], 0)]), nil +} diff --git a/vendor/github.com/containerd/console/tc_unix.go b/vendor/github.com/containerd/console/tc_unix.go index 7ae773c53ea..5cd4c550ce8 100644 --- a/vendor/github.com/containerd/console/tc_unix.go +++ b/vendor/github.com/containerd/console/tc_unix.go @@ -1,4 +1,4 @@ -// +build darwin freebsd linux openbsd solaris +// +build darwin freebsd linux netbsd openbsd solaris /* Copyright The containerd Authors. diff --git a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go b/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go index d951b268325..af56c7de2ba 100644 --- a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go +++ b/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go @@ -2106,7 +2106,7 @@ func (m *Container) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > postIndex { @@ -2469,7 +2469,7 @@ func (m *Container) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > postIndex { @@ -2486,10 +2486,7 @@ func (m *Container) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthContainers - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > l { @@ -2608,10 +2605,7 @@ func (m *Container_Runtime) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthContainers - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > l { @@ -2694,10 +2688,7 @@ func (m *GetContainerRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthContainers - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > l { @@ -2781,10 +2772,7 @@ func (m *GetContainerResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthContainers - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > l { @@ -2867,10 +2855,7 @@ func (m *ListContainersRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthContainers - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > l { @@ -2955,10 +2940,7 @@ func (m *ListContainersResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthContainers - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > l { @@ -3042,10 +3024,7 @@ func (m *CreateContainerRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthContainers - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > l { @@ -3129,10 +3108,7 @@ func (m *CreateContainerResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthContainers - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > l { @@ -3252,10 +3228,7 @@ func (m *UpdateContainerRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthContainers - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > l { @@ -3339,10 +3312,7 @@ func (m *UpdateContainerResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthContainers - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > l { @@ -3425,10 +3395,7 @@ func (m *DeleteContainerRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthContainers - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > l { @@ -3515,10 +3482,7 @@ func (m *ListContainerMessage) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthContainers - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthContainers } if (iNdEx + skippy) > l { diff --git a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.pb.go b/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.pb.go index 5ac5af11b92..484b469c6e4 100644 --- a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.pb.go +++ b/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.pb.go @@ -4347,10 +4347,7 @@ func (m *CreateTaskRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -4452,10 +4449,7 @@ func (m *CreateTaskResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -4570,10 +4564,7 @@ func (m *StartRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -4643,10 +4634,7 @@ func (m *StartResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -4729,10 +4717,7 @@ func (m *DeleteTaskRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -4886,10 +4871,7 @@ func (m *DeleteResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -5004,10 +4986,7 @@ func (m *DeleteProcessRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -5122,10 +5101,7 @@ func (m *GetRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -5212,10 +5188,7 @@ func (m *GetResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -5298,10 +5271,7 @@ func (m *ListTasksRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -5386,10 +5356,7 @@ func (m *ListTasksResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -5543,10 +5510,7 @@ func (m *KillRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -5813,10 +5777,7 @@ func (m *ExecProcessRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -5867,10 +5828,7 @@ func (m *ExecProcessResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -6023,10 +5981,7 @@ func (m *ResizePtyRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -6161,10 +6116,7 @@ func (m *CloseIORequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -6247,10 +6199,7 @@ func (m *PauseTaskRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -6333,10 +6282,7 @@ func (m *ResumeTaskRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -6419,10 +6365,7 @@ func (m *ListPidsRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -6507,10 +6450,7 @@ func (m *ListPidsResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -6661,10 +6601,7 @@ func (m *CheckpointTaskRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -6749,10 +6686,7 @@ func (m *CheckpointTaskResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -6871,10 +6805,7 @@ func (m *UpdateTaskRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -6957,10 +6888,7 @@ func (m *MetricsRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -7045,10 +6973,7 @@ func (m *MetricsResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -7163,10 +7088,7 @@ func (m *WaitRequest) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { @@ -7269,10 +7191,7 @@ func (m *WaitResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTasks - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTasks } if (iNdEx + skippy) > l { diff --git a/vendor/github.com/containerd/containerd/api/services/version/v1/version.pb.go b/vendor/github.com/containerd/containerd/api/services/version/v1/version.pb.go index 81b8c339539..b742c6ae62f 100644 --- a/vendor/github.com/containerd/containerd/api/services/version/v1/version.pb.go +++ b/vendor/github.com/containerd/containerd/api/services/version/v1/version.pb.go @@ -374,10 +374,7 @@ func (m *VersionResponse) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthVersion - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthVersion } if (iNdEx + skippy) > l { diff --git a/vendor/github.com/containerd/containerd/api/types/descriptor.pb.go b/vendor/github.com/containerd/containerd/api/types/descriptor.pb.go index 437d41f23ad..fe71dbf4330 100644 --- a/vendor/github.com/containerd/containerd/api/types/descriptor.pb.go +++ b/vendor/github.com/containerd/containerd/api/types/descriptor.pb.go @@ -479,7 +479,7 @@ func (m *Descriptor) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthDescriptor } if (iNdEx + skippy) > postIndex { @@ -496,10 +496,7 @@ func (m *Descriptor) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthDescriptor - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthDescriptor } if (iNdEx + skippy) > l { diff --git a/vendor/github.com/containerd/containerd/api/types/metrics.pb.go b/vendor/github.com/containerd/containerd/api/types/metrics.pb.go index 89a8d9cd6ff..75773e442ab 100644 --- a/vendor/github.com/containerd/containerd/api/types/metrics.pb.go +++ b/vendor/github.com/containerd/containerd/api/types/metrics.pb.go @@ -348,10 +348,7 @@ func (m *Metric) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthMetrics - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthMetrics } if (iNdEx + skippy) > l { diff --git a/vendor/github.com/containerd/containerd/api/types/mount.pb.go b/vendor/github.com/containerd/containerd/api/types/mount.pb.go index 6872e4120e1..d0a0bee761f 100644 --- a/vendor/github.com/containerd/containerd/api/types/mount.pb.go +++ b/vendor/github.com/containerd/containerd/api/types/mount.pb.go @@ -392,10 +392,7 @@ func (m *Mount) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthMount - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthMount } if (iNdEx + skippy) > l { diff --git a/vendor/github.com/containerd/containerd/api/types/platform.pb.go b/vendor/github.com/containerd/containerd/api/types/platform.pb.go index c03d8b077bf..a0f78c8a769 100644 --- a/vendor/github.com/containerd/containerd/api/types/platform.pb.go +++ b/vendor/github.com/containerd/containerd/api/types/platform.pb.go @@ -333,10 +333,7 @@ func (m *Platform) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthPlatform - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthPlatform } if (iNdEx + skippy) > l { diff --git a/vendor/github.com/containerd/containerd/api/types/task/task.pb.go b/vendor/github.com/containerd/containerd/api/types/task/task.pb.go index ae824ff45c4..f511bbd058c 100644 --- a/vendor/github.com/containerd/containerd/api/types/task/task.pb.go +++ b/vendor/github.com/containerd/containerd/api/types/task/task.pb.go @@ -772,10 +772,7 @@ func (m *Process) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTask - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTask } if (iNdEx + skippy) > l { @@ -881,10 +878,7 @@ func (m *ProcessInfo) Unmarshal(dAtA []byte) error { if err != nil { return err } - if skippy < 0 { - return ErrInvalidLengthTask - } - if (iNdEx + skippy) < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTask } if (iNdEx + skippy) > l { diff --git a/vendor/github.com/containerd/containerd/log/context.go b/vendor/github.com/containerd/containerd/log/context.go new file mode 100644 index 00000000000..21599c4fd64 --- /dev/null +++ b/vendor/github.com/containerd/containerd/log/context.go @@ -0,0 +1,60 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package log + +import ( + "context" + + "github.com/sirupsen/logrus" +) + +var ( + // G is an alias for GetLogger. + // + // We may want to define this locally to a package to get package tagged log + // messages. + G = GetLogger + + // L is an alias for the standard logger. + L = logrus.NewEntry(logrus.StandardLogger()) +) + +type ( + loggerKey struct{} +) + +// RFC3339NanoFixed is time.RFC3339Nano with nanoseconds padded using zeros to +// ensure the formatted time is always the same number of characters. +const RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" + +// WithLogger returns a new context with the provided logger. Use in +// combination with logger.WithField(s) for great effect. +func WithLogger(ctx context.Context, logger *logrus.Entry) context.Context { + return context.WithValue(ctx, loggerKey{}, logger) +} + +// GetLogger retrieves the current logger from the context. If no logger is +// available, the default logger is returned. +func GetLogger(ctx context.Context) *logrus.Entry { + logger := ctx.Value(loggerKey{}) + + if logger == nil { + return L + } + + return logger.(*logrus.Entry) +} diff --git a/vendor/github.com/containerd/containerd/platforms/compare.go b/vendor/github.com/containerd/containerd/platforms/compare.go new file mode 100644 index 00000000000..3ad22a10d0c --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/compare.go @@ -0,0 +1,229 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +import specs "github.com/opencontainers/image-spec/specs-go/v1" + +// MatchComparer is able to match and compare platforms to +// filter and sort platforms. +type MatchComparer interface { + Matcher + + Less(specs.Platform, specs.Platform) bool +} + +// Only returns a match comparer for a single platform +// using default resolution logic for the platform. +// +// For ARMv8, will also match ARMv7, ARMv6 and ARMv5 (for 32bit runtimes) +// For ARMv7, will also match ARMv6 and ARMv5 +// For ARMv6, will also match ARMv5 +func Only(platform specs.Platform) MatchComparer { + platform = Normalize(platform) + if platform.Architecture == "arm" { + if platform.Variant == "v8" { + return orderedPlatformComparer{ + matchers: []Matcher{ + &matcher{ + Platform: platform, + }, + &matcher{ + Platform: specs.Platform{ + Architecture: platform.Architecture, + OS: platform.OS, + OSVersion: platform.OSVersion, + OSFeatures: platform.OSFeatures, + Variant: "v7", + }, + }, + &matcher{ + Platform: specs.Platform{ + Architecture: platform.Architecture, + OS: platform.OS, + OSVersion: platform.OSVersion, + OSFeatures: platform.OSFeatures, + Variant: "v6", + }, + }, + &matcher{ + Platform: specs.Platform{ + Architecture: platform.Architecture, + OS: platform.OS, + OSVersion: platform.OSVersion, + OSFeatures: platform.OSFeatures, + Variant: "v5", + }, + }, + }, + } + } + if platform.Variant == "v7" { + return orderedPlatformComparer{ + matchers: []Matcher{ + &matcher{ + Platform: platform, + }, + &matcher{ + Platform: specs.Platform{ + Architecture: platform.Architecture, + OS: platform.OS, + OSVersion: platform.OSVersion, + OSFeatures: platform.OSFeatures, + Variant: "v6", + }, + }, + &matcher{ + Platform: specs.Platform{ + Architecture: platform.Architecture, + OS: platform.OS, + OSVersion: platform.OSVersion, + OSFeatures: platform.OSFeatures, + Variant: "v5", + }, + }, + }, + } + } + if platform.Variant == "v6" { + return orderedPlatformComparer{ + matchers: []Matcher{ + &matcher{ + Platform: platform, + }, + &matcher{ + Platform: specs.Platform{ + Architecture: platform.Architecture, + OS: platform.OS, + OSVersion: platform.OSVersion, + OSFeatures: platform.OSFeatures, + Variant: "v5", + }, + }, + }, + } + } + } + + return singlePlatformComparer{ + Matcher: &matcher{ + Platform: platform, + }, + } +} + +// Ordered returns a platform MatchComparer which matches any of the platforms +// but orders them in order they are provided. +func Ordered(platforms ...specs.Platform) MatchComparer { + matchers := make([]Matcher, len(platforms)) + for i := range platforms { + matchers[i] = NewMatcher(platforms[i]) + } + return orderedPlatformComparer{ + matchers: matchers, + } +} + +// Any returns a platform MatchComparer which matches any of the platforms +// with no preference for ordering. +func Any(platforms ...specs.Platform) MatchComparer { + matchers := make([]Matcher, len(platforms)) + for i := range platforms { + matchers[i] = NewMatcher(platforms[i]) + } + return anyPlatformComparer{ + matchers: matchers, + } +} + +// All is a platform MatchComparer which matches all platforms +// with preference for ordering. +var All MatchComparer = allPlatformComparer{} + +type singlePlatformComparer struct { + Matcher +} + +func (c singlePlatformComparer) Less(p1, p2 specs.Platform) bool { + return c.Match(p1) && !c.Match(p2) +} + +type orderedPlatformComparer struct { + matchers []Matcher +} + +func (c orderedPlatformComparer) Match(platform specs.Platform) bool { + for _, m := range c.matchers { + if m.Match(platform) { + return true + } + } + return false +} + +func (c orderedPlatformComparer) Less(p1 specs.Platform, p2 specs.Platform) bool { + for _, m := range c.matchers { + p1m := m.Match(p1) + p2m := m.Match(p2) + if p1m && !p2m { + return true + } + if p1m || p2m { + return false + } + } + return false +} + +type anyPlatformComparer struct { + matchers []Matcher +} + +func (c anyPlatformComparer) Match(platform specs.Platform) bool { + for _, m := range c.matchers { + if m.Match(platform) { + return true + } + } + return false +} + +func (c anyPlatformComparer) Less(p1, p2 specs.Platform) bool { + var p1m, p2m bool + for _, m := range c.matchers { + if !p1m && m.Match(p1) { + p1m = true + } + if !p2m && m.Match(p2) { + p2m = true + } + if p1m && p2m { + return false + } + } + // If one matches, and the other does, sort match first + return p1m && !p2m +} + +type allPlatformComparer struct{} + +func (allPlatformComparer) Match(specs.Platform) bool { + return true +} + +func (allPlatformComparer) Less(specs.Platform, specs.Platform) bool { + return false +} diff --git a/vendor/github.com/containerd/containerd/platforms/cpuinfo.go b/vendor/github.com/containerd/containerd/platforms/cpuinfo.go new file mode 100644 index 00000000000..db65a726b90 --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/cpuinfo.go @@ -0,0 +1,122 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +import ( + "bufio" + "os" + "runtime" + "strings" + + "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/log" + "github.com/pkg/errors" +) + +// Present the ARM instruction set architecture, eg: v7, v8 +var cpuVariant string + +func init() { + if isArmArch(runtime.GOARCH) { + cpuVariant = getCPUVariant() + } else { + cpuVariant = "" + } +} + +// For Linux, the kernel has already detected the ABI, ISA and Features. +// So we don't need to access the ARM registers to detect platform information +// by ourselves. We can just parse these information from /proc/cpuinfo +func getCPUInfo(pattern string) (info string, err error) { + if !isLinuxOS(runtime.GOOS) { + return "", errors.Wrapf(errdefs.ErrNotImplemented, "getCPUInfo for OS %s", runtime.GOOS) + } + + cpuinfo, err := os.Open("/proc/cpuinfo") + if err != nil { + return "", err + } + defer cpuinfo.Close() + + // Start to Parse the Cpuinfo line by line. For SMP SoC, we parse + // the first core is enough. + scanner := bufio.NewScanner(cpuinfo) + for scanner.Scan() { + newline := scanner.Text() + list := strings.Split(newline, ":") + + if len(list) > 1 && strings.EqualFold(strings.TrimSpace(list[0]), pattern) { + return strings.TrimSpace(list[1]), nil + } + } + + // Check whether the scanner encountered errors + err = scanner.Err() + if err != nil { + return "", err + } + + return "", errors.Wrapf(errdefs.ErrNotFound, "getCPUInfo for pattern: %s", pattern) +} + +func getCPUVariant() string { + if runtime.GOOS == "windows" || runtime.GOOS == "darwin" { + // Windows/Darwin only supports v7 for ARM32 and v8 for ARM64 and so we can use + // runtime.GOARCH to determine the variants + var variant string + switch runtime.GOARCH { + case "arm64": + variant = "v8" + case "arm": + variant = "v7" + default: + variant = "unknown" + } + + return variant + } + + variant, err := getCPUInfo("Cpu architecture") + if err != nil { + log.L.WithError(err).Error("failure getting variant") + return "" + } + + switch strings.ToLower(variant) { + case "8", "aarch64": + // special case: if running a 32-bit userspace on aarch64, the variant should be "v7" + if runtime.GOARCH == "arm" { + variant = "v7" + } else { + variant = "v8" + } + case "7", "7m", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)": + variant = "v7" + case "6", "6tej": + variant = "v6" + case "5", "5t", "5te", "5tej": + variant = "v5" + case "4", "4t": + variant = "v4" + case "3": + variant = "v3" + default: + variant = "unknown" + } + + return variant +} diff --git a/vendor/github.com/containerd/containerd/platforms/database.go b/vendor/github.com/containerd/containerd/platforms/database.go new file mode 100644 index 00000000000..6ede94061eb --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/database.go @@ -0,0 +1,114 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +import ( + "runtime" + "strings" +) + +// isLinuxOS returns true if the operating system is Linux. +// +// The OS value should be normalized before calling this function. +func isLinuxOS(os string) bool { + return os == "linux" +} + +// These function are generated from https://golang.org/src/go/build/syslist.go. +// +// We use switch statements because they are slightly faster than map lookups +// and use a little less memory. + +// isKnownOS returns true if we know about the operating system. +// +// The OS value should be normalized before calling this function. +func isKnownOS(os string) bool { + switch os { + case "aix", "android", "darwin", "dragonfly", "freebsd", "hurd", "illumos", "js", "linux", "nacl", "netbsd", "openbsd", "plan9", "solaris", "windows", "zos": + return true + } + return false +} + +// isArmArch returns true if the architecture is ARM. +// +// The arch value should be normalized before being passed to this function. +func isArmArch(arch string) bool { + switch arch { + case "arm", "arm64": + return true + } + return false +} + +// isKnownArch returns true if we know about the architecture. +// +// The arch value should be normalized before being passed to this function. +func isKnownArch(arch string) bool { + switch arch { + case "386", "amd64", "amd64p32", "arm", "armbe", "arm64", "arm64be", "ppc64", "ppc64le", "mips", "mipsle", "mips64", "mips64le", "mips64p32", "mips64p32le", "ppc", "riscv", "riscv64", "s390", "s390x", "sparc", "sparc64", "wasm": + return true + } + return false +} + +func normalizeOS(os string) string { + if os == "" { + return runtime.GOOS + } + os = strings.ToLower(os) + + switch os { + case "macos": + os = "darwin" + } + return os +} + +// normalizeArch normalizes the architecture. +func normalizeArch(arch, variant string) (string, string) { + arch, variant = strings.ToLower(arch), strings.ToLower(variant) + switch arch { + case "i386": + arch = "386" + variant = "" + case "x86_64", "x86-64": + arch = "amd64" + variant = "" + case "aarch64", "arm64": + arch = "arm64" + switch variant { + case "8", "v8": + variant = "" + } + case "armhf": + arch = "arm" + variant = "v7" + case "armel": + arch = "arm" + variant = "v6" + case "arm": + switch variant { + case "", "7": + variant = "v7" + case "5", "6", "8": + variant = "v" + variant + } + } + + return arch, variant +} diff --git a/vendor/github.com/containerd/containerd/platforms/defaults.go b/vendor/github.com/containerd/containerd/platforms/defaults.go new file mode 100644 index 00000000000..a14d80e58cb --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/defaults.go @@ -0,0 +1,38 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +import ( + "runtime" + + specs "github.com/opencontainers/image-spec/specs-go/v1" +) + +// DefaultString returns the default string specifier for the platform. +func DefaultString() string { + return Format(DefaultSpec()) +} + +// DefaultSpec returns the current platform's default platform specification. +func DefaultSpec() specs.Platform { + return specs.Platform{ + OS: runtime.GOOS, + Architecture: runtime.GOARCH, + // The Variant field will be empty if arch != ARM. + Variant: cpuVariant, + } +} diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_unix.go b/vendor/github.com/containerd/containerd/platforms/defaults_unix.go new file mode 100644 index 00000000000..e8a7d5ffa0d --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/defaults_unix.go @@ -0,0 +1,24 @@ +// +build !windows + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +// Default returns the default matcher for the platform. +func Default() MatchComparer { + return Only(DefaultSpec()) +} diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_windows.go b/vendor/github.com/containerd/containerd/platforms/defaults_windows.go new file mode 100644 index 00000000000..0defbd36c04 --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/defaults_windows.go @@ -0,0 +1,31 @@ +// +build windows + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +import ( + specs "github.com/opencontainers/image-spec/specs-go/v1" +) + +// Default returns the default matcher for the platform. +func Default() MatchComparer { + return Ordered(DefaultSpec(), specs.Platform{ + OS: "linux", + Architecture: "amd64", + }) +} diff --git a/vendor/github.com/containerd/containerd/platforms/platforms.go b/vendor/github.com/containerd/containerd/platforms/platforms.go new file mode 100644 index 00000000000..77d3f184ec1 --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/platforms.go @@ -0,0 +1,278 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Package platforms provides a toolkit for normalizing, matching and +// specifying container platforms. +// +// Centered around OCI platform specifications, we define a string-based +// specifier syntax that can be used for user input. With a specifier, users +// only need to specify the parts of the platform that are relevant to their +// context, providing an operating system or architecture or both. +// +// How do I use this package? +// +// The vast majority of use cases should simply use the match function with +// user input. The first step is to parse a specifier into a matcher: +// +// m, err := Parse("linux") +// if err != nil { ... } +// +// Once you have a matcher, use it to match against the platform declared by a +// component, typically from an image or runtime. Since extracting an images +// platform is a little more involved, we'll use an example against the +// platform default: +// +// if ok := m.Match(Default()); !ok { /* doesn't match */ } +// +// This can be composed in loops for resolving runtimes or used as a filter for +// fetch and select images. +// +// More details of the specifier syntax and platform spec follow. +// +// Declaring Platform Support +// +// Components that have strict platform requirements should use the OCI +// platform specification to declare their support. Typically, this will be +// images and runtimes that should make these declaring which platform they +// support specifically. This looks roughly as follows: +// +// type Platform struct { +// Architecture string +// OS string +// Variant string +// } +// +// Most images and runtimes should at least set Architecture and OS, according +// to their GOARCH and GOOS values, respectively (follow the OCI image +// specification when in doubt). ARM should set variant under certain +// discussions, which are outlined below. +// +// Platform Specifiers +// +// While the OCI platform specifications provide a tool for components to +// specify structured information, user input typically doesn't need the full +// context and much can be inferred. To solve this problem, we introduced +// "specifiers". A specifier has the format +// `||/[/]`. The user can provide either the +// operating system or the architecture or both. +// +// An example of a common specifier is `linux/amd64`. If the host has a default +// of runtime that matches this, the user can simply provide the component that +// matters. For example, if a image provides amd64 and arm64 support, the +// operating system, `linux` can be inferred, so they only have to provide +// `arm64` or `amd64`. Similar behavior is implemented for operating systems, +// where the architecture may be known but a runtime may support images from +// different operating systems. +// +// Normalization +// +// Because not all users are familiar with the way the Go runtime represents +// platforms, several normalizations have been provided to make this package +// easier to user. +// +// The following are performed for architectures: +// +// Value Normalized +// aarch64 arm64 +// armhf arm +// armel arm/v6 +// i386 386 +// x86_64 amd64 +// x86-64 amd64 +// +// We also normalize the operating system `macos` to `darwin`. +// +// ARM Support +// +// To qualify ARM architecture, the Variant field is used to qualify the arm +// version. The most common arm version, v7, is represented without the variant +// unless it is explicitly provided. This is treated as equivalent to armhf. A +// previous architecture, armel, will be normalized to arm/v6. +// +// While these normalizations are provided, their support on arm platforms has +// not yet been fully implemented and tested. +package platforms + +import ( + "regexp" + "runtime" + "strconv" + "strings" + + "github.com/containerd/containerd/errdefs" + specs "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/pkg/errors" +) + +var ( + specifierRe = regexp.MustCompile(`^[A-Za-z0-9_-]+$`) +) + +// Matcher matches platforms specifications, provided by an image or runtime. +type Matcher interface { + Match(platform specs.Platform) bool +} + +// NewMatcher returns a simple matcher based on the provided platform +// specification. The returned matcher only looks for equality based on os, +// architecture and variant. +// +// One may implement their own matcher if this doesn't provide the required +// functionality. +// +// Applications should opt to use `Match` over directly parsing specifiers. +func NewMatcher(platform specs.Platform) Matcher { + return &matcher{ + Platform: Normalize(platform), + } +} + +type matcher struct { + specs.Platform +} + +func (m *matcher) Match(platform specs.Platform) bool { + normalized := Normalize(platform) + return m.OS == normalized.OS && + m.Architecture == normalized.Architecture && + m.Variant == normalized.Variant +} + +func (m *matcher) String() string { + return Format(m.Platform) +} + +// Parse parses the platform specifier syntax into a platform declaration. +// +// Platform specifiers are in the format `||/[/]`. +// The minimum required information for a platform specifier is the operating +// system or architecture. If there is only a single string (no slashes), the +// value will be matched against the known set of operating systems, then fall +// back to the known set of architectures. The missing component will be +// inferred based on the local environment. +func Parse(specifier string) (specs.Platform, error) { + if strings.Contains(specifier, "*") { + // TODO(stevvooe): need to work out exact wildcard handling + return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q: wildcards not yet supported", specifier) + } + + parts := strings.Split(specifier, "/") + + for _, part := range parts { + if !specifierRe.MatchString(part) { + return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q is an invalid component of %q: platform specifier component must match %q", part, specifier, specifierRe.String()) + } + } + + var p specs.Platform + switch len(parts) { + case 1: + // in this case, we will test that the value might be an OS, then look + // it up. If it is not known, we'll treat it as an architecture. Since + // we have very little information about the platform here, we are + // going to be a little more strict if we don't know about the argument + // value. + p.OS = normalizeOS(parts[0]) + if isKnownOS(p.OS) { + // picks a default architecture + p.Architecture = runtime.GOARCH + if p.Architecture == "arm" && cpuVariant != "v7" { + p.Variant = cpuVariant + } + + return p, nil + } + + p.Architecture, p.Variant = normalizeArch(parts[0], "") + if p.Architecture == "arm" && p.Variant == "v7" { + p.Variant = "" + } + if isKnownArch(p.Architecture) { + p.OS = runtime.GOOS + return p, nil + } + + return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q: unknown operating system or architecture", specifier) + case 2: + // In this case, we treat as a regular os/arch pair. We don't care + // about whether or not we know of the platform. + p.OS = normalizeOS(parts[0]) + p.Architecture, p.Variant = normalizeArch(parts[1], "") + if p.Architecture == "arm" && p.Variant == "v7" { + p.Variant = "" + } + + return p, nil + case 3: + // we have a fully specified variant, this is rare + p.OS = normalizeOS(parts[0]) + p.Architecture, p.Variant = normalizeArch(parts[1], parts[2]) + if p.Architecture == "arm64" && p.Variant == "" { + p.Variant = "v8" + } + + return p, nil + } + + return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q: cannot parse platform specifier", specifier) +} + +// MustParse is like Parses but panics if the specifier cannot be parsed. +// Simplifies initialization of global variables. +func MustParse(specifier string) specs.Platform { + p, err := Parse(specifier) + if err != nil { + panic("platform: Parse(" + strconv.Quote(specifier) + "): " + err.Error()) + } + return p +} + +// Format returns a string specifier from the provided platform specification. +func Format(platform specs.Platform) string { + if platform.OS == "" { + return "unknown" + } + + return joinNotEmpty(platform.OS, platform.Architecture, platform.Variant) +} + +func joinNotEmpty(s ...string) string { + var ss []string + for _, s := range s { + if s == "" { + continue + } + + ss = append(ss, s) + } + + return strings.Join(ss, "/") +} + +// Normalize validates and translate the platform to the canonical value. +// +// For example, if "Aarch64" is encountered, we change it to "arm64" or if +// "x86_64" is encountered, it becomes "amd64". +func Normalize(platform specs.Platform) specs.Platform { + platform.OS = normalizeOS(platform.OS) + platform.Architecture, platform.Variant = normalizeArch(platform.Architecture, platform.Variant) + + // these fields are deprecated, remove them + platform.OSFeatures = nil + platform.OSVersion = "" + + return platform +} diff --git a/vendor/github.com/docker/docker/AUTHORS b/vendor/github.com/docker/docker/AUTHORS index c5f725bc19d..dffacff1120 100644 --- a/vendor/github.com/docker/docker/AUTHORS +++ b/vendor/github.com/docker/docker/AUTHORS @@ -4,6 +4,7 @@ Aanand Prasad Aaron Davidson Aaron Feng +Aaron Hnatiw Aaron Huslage Aaron L. Xu Aaron Lehmann @@ -17,6 +18,7 @@ Abhishek Chanda Abhishek Sharma Abin Shahab Adam Avilla +Adam Dobrawy Adam Eijdenberg Adam Kunk Adam Miller @@ -43,6 +45,7 @@ AJ Bowen Ajey Charantimath ajneu Akash Gupta +Akhil Mohan Akihiro Matsushima Akihiro Suda Akim Demaille @@ -50,10 +53,12 @@ Akira Koyasu Akshay Karle Al Tobey alambike +Alan Hoyle Alan Scherger Alan Thompson Albert Callarisa Albert Zhang +Albin Kerouanton Alejandro González Hevia Aleksa Sarai Aleksandrs Fadins @@ -107,11 +112,13 @@ Amy Lindburg Anand Patil AnandkumarPatel Anatoly Borodin +Anca Iordache Anchal Agrawal Anda Xu Anders Janmyr Andre Dublin <81dublin@gmail.com> Andre Granovsky +Andrea Denisse Gómez Andrea Luzzardi Andrea Turli Andreas Elvers @@ -176,8 +183,10 @@ Anusha Ragunathan apocas Arash Deshmeh ArikaChen +Arko Dasgupta Arnaud Lefebvre Arnaud Porterie +Arnaud Rebillout Arthur Barr Arthur Gautier Artur Meyster @@ -210,10 +219,12 @@ Benjamin Atkin Benjamin Baker Benjamin Boudreau Benjamin Yolken +Benny Ng Benoit Chesneau Bernerd Schaefer Bernhard M. Wiedemann Bert Goethals +Bertrand Roussel Bevisy Zhang Bharath Thiruveedula Bhiraj Butala @@ -226,6 +237,7 @@ Bingshen Wang Blake Geno Boaz Shuster bobby abbott +Boqin Qin Boris Pruessmann Boshi Lian Bouke Haarsma @@ -279,6 +291,7 @@ Carl Loa Odin Carl X. Su Carlo Mion Carlos Alexandro Becker +Carlos de Paula Carlos Sanchez Carol Fager-Higgins Cary @@ -328,6 +341,7 @@ Chris Gibson Chris Khoo Chris McKinnel Chris McKinnel +Chris Price Chris Seto Chris Snow Chris St. Pierre @@ -354,7 +368,7 @@ Christopher Currie Christopher Jones Christopher Latham Christopher Rigor -Christy Perez +Christy Norman Chun Chen Ciro S. Costa Clayton Coleman @@ -374,8 +388,10 @@ Corey Farrell Cory Forsyth cressie176 CrimsonGlory +Cristian Ariza Cristian Staretu cristiano balducci +Cristina Yenyxe Gonzalez Garcia Cruceru Calin-Cristian CUI Wei Cyprian Gracz @@ -402,12 +418,14 @@ Dan Williams Dani Hodovic Dani Louca Daniel Antlinger +Daniel Black Daniel Dao Daniel Exner Daniel Farrell Daniel Garcia Daniel Gasienica Daniel Grunwell +Daniel Helfand Daniel Hiltgen Daniel J Walsh Daniel Menet @@ -417,12 +435,14 @@ Daniel Norberg Daniel Nordberg Daniel Robinson Daniel S +Daniel Sweet Daniel Von Fange Daniel Watkins Daniel X Moore Daniel YC Lin Daniel Zhang Danny Berger +Danny Milosavljevic Danny Yates Danyal Khaliq Darren Coxall @@ -487,6 +507,7 @@ Derek McGowan Deric Crago Deshi Xiao devmeyster +Devon Estes Devvyn Murphy Dharmit Shah Dhawal Yogesh Bhanushali @@ -516,6 +537,8 @@ Dmitry Smirnov Dmitry V. Krivenok Dmitry Vorobev Dolph Mathews +Dominic Tubach +Dominic Yin Dominik Dingel Dominik Finkbeiner Dominik Honnef @@ -534,7 +557,7 @@ Douglas Curtis Dr Nic Williams dragon788 Dražen Lučanin -Drew Erny +Drew Erny Drew Hubl Dustin Sallings Ed Costello @@ -584,6 +607,7 @@ Erik Weathers Erno Hopearuoho Erwin van der Koogh Ethan Bell +Ethan Mosbaugh Euan Kemp Eugen Krizo Eugene Yakubovich @@ -595,6 +619,7 @@ Evan Phoenix Evan Wies Evelyn Xu Everett Toews +Evgeniy Makhrov Evgeny Shmarnev Evgeny Vereshchagin Ewa Czechowska @@ -620,6 +645,7 @@ Fareed Dudhia Fathi Boudra Federico Gimenez Felipe Oliveira +Felipe Ruhland Felix Abecassis Felix Geisendörfer Felix Hupfeld @@ -640,6 +666,7 @@ Florian Florian Klein Florian Maier Florian Noeding +Florian Schmaus Florian Weingarten Florin Asavoaie Florin Patan @@ -654,6 +681,7 @@ Frank Groeneveld Frank Herrmann Frank Macreery Frank Rosquin +frankyang Fred Lifton Frederick F. Kautz IV Frederik Loeffert @@ -675,7 +703,7 @@ Gareth Rushgrove Garrett Barboza Gary Schaetz Gaurav -gautam, prasanna +Gaurav Singh Gaël PORTAY Genki Takiuchi GennadySpb @@ -701,11 +729,12 @@ Gleb M Borisov Glyn Normington GoBella Goffert van Gool +Goldwyn Rodrigues Gopikannan Venugopalsamy Gosuke Miyashita Gou Rao Govinda Fichtner -Grant Millar +Grant Millar Grant Reaber Graydon Hoare Greg Fausak @@ -724,14 +753,17 @@ Guruprasad Gustav Sinder gwx296173 Günter Zöchbauer +Haichao Yang haikuoliu Hakan Özler Hamish Hutchings +Hannes Ljungberg Hans Kristian Flaatten Hans Rødtang Hao Shu Wei Hao Zhang <21521210@zju.edu.cn> Harald Albers +Harald Niesche Harley Laue Harold Cooper Harrison Turton @@ -751,9 +783,13 @@ Hobofan Hollie Teal Hong Xu Hongbin Lu +Hongxu Jia +Honza Pokorny +Hsing-Hui Hsu hsinko <21551195@zju.edu.cn> Hu Keping Hu Tao +HuanHuan Ye Huanzhong Zhang Huayi Zhang Hugo Duncan @@ -790,6 +826,7 @@ Ingo Gottwald Innovimax Isaac Dupree Isabel Jimenez +Isaiah Grace Isao Jonas Iskander Sharipov Ivan Babrou @@ -805,6 +842,7 @@ Jacob Edelman Jacob Tomlinson Jacob Vallejo Jacob Wen +Jaime Cepeda Jaivish Kothari Jake Champlin Jake Moshenko @@ -819,12 +857,13 @@ James Kyburz James Kyle James Lal James Mills -James Nesbitt +James Nesbitt James Nugent James Turnbull James Watkins-Harvey Jamie Hannaford Jamshid Afshar +Jan Chren Jan Keromnes Jan Koprowski Jan Pazdziora @@ -839,6 +878,7 @@ Jared Hocutt Jaroslaw Zabiello jaseg Jasmine Hegman +Jason A. Donenfeld Jason Divock Jason Giedymin Jason Green @@ -886,7 +926,7 @@ Jeroen Franse Jeroen Jacobs Jesse Dearing Jesse Dubay -Jessica Frazelle +Jessica Frazelle Jezeniel Zapanta Jhon Honce Ji.Zhilong @@ -894,9 +934,11 @@ Jian Liao Jian Zhang Jiang Jinyang Jie Luo +Jie Ma Jihyun Hwang Jilles Oldenbeuving Jim Alateras +Jim Ehrismann Jim Galasyn Jim Minter Jim Perrin @@ -934,7 +976,7 @@ John Feminella John Gardiner Myers John Gossman John Harris -John Howard (VM) +John Howard John Laswell John Maguire John Mulhausen @@ -948,6 +990,8 @@ John Willis Jon Johnson Jon Surrell Jon Wedaman +Jonas Dohse +Jonas Heinrich Jonas Pfenniger Jonathan A. Schweder Jonathan A. Sternberg @@ -997,10 +1041,13 @@ Julien Dubois Julien Kassar Julien Maitrehenry Julien Pervillé +Julien Pivotto +Julio Guerra Julio Montes Jun-Ru Chang Jussi Nummelin Justas Brazauskas +Justen Martin Justin Cormack Justin Force Justin Menga @@ -1009,6 +1056,7 @@ Justin Simonelis Justin Terry Justyn Temme Jyrki Puttonen +Jérémy Leherpeur Jérôme Petazzoni Jörg Thalheim K. Heller @@ -1046,6 +1094,7 @@ Ken Reese Kenfe-Mickaël Laventure Kenjiro Nakayama Kent Johnson +Kenta Tada Kevin "qwazerty" Houdebert Kevin Burke Kevin Clark @@ -1056,6 +1105,7 @@ Kevin Kern Kevin Menard Kevin Meredith Kevin P. Kucharczyk +Kevin Parsons Kevin Richardson Kevin Shi Kevin Wallace @@ -1146,6 +1196,7 @@ longliqiang88 <394564827@qq.com> Lorenz Leutgeb Lorenzo Fontana Lotus Fenn +Louis Delossantos Louis Opter Luca Favatella Luca Marturana @@ -1154,9 +1205,11 @@ Luca-Bogdan Grigorescu Lucas Chan Lucas Chi Lucas Molas +Lucas Silvestre Luciano Mores Luis Martínez de Bartolomé Izquierdo Luiz Svoboda +Lukas Heeren Lukas Waslowski lukaspustina Lukasz Zajaczkowski @@ -1256,6 +1309,7 @@ Matthieu Hauglustaine Mattias Jernberg Mauricio Garavaglia mauriyouth +Max Harmathy Max Shytikov Maxim Fedchyshyn Maxim Ivanov @@ -1296,6 +1350,7 @@ Michael Stapelberg Michael Steinert Michael Thies Michael West +Michael Zhao Michal Fojtik Michal Gebauer Michal Jemala @@ -1312,6 +1367,7 @@ Miguel Morales Mihai Borobocea Mihuleacc Sergiu Mike Brown +Mike Bush Mike Casas Mike Chelen Mike Danese @@ -1380,6 +1436,7 @@ Neyazul Haque Nghia Tran Niall O'Higgins Nicholas E. Rabenau +Nick Adcock Nick DeCoursin Nick Irvine Nick Neisen @@ -1403,6 +1460,7 @@ Nik Nyby Nikhil Chawla NikolaMandic Nikolas Garofil +Nikolay Edigaryev Nikolay Milovanov Nirmal Mehta Nishant Totla @@ -1418,6 +1476,7 @@ Nuutti Kotivuori nzwsch O.S. Tezer objectified +Odin Ugedal Oguz Bilgic Oh Jinkyun Ohad Schneider @@ -1428,6 +1487,7 @@ Oliver Reason Olivier Gambier Olle Jonsson Olli Janatuinen +Olly Pomeroy Omri Shiv Oriol Francès Oskar Niburski @@ -1437,6 +1497,7 @@ Ovidio Mallo Panagiotis Moustafellos Paolo G. Giarrusso Pascal +Pascal Bach Pascal Borreli Pascal Hartig Patrick Böänziger @@ -1461,6 +1522,7 @@ Paul Nasrat Paul Weaver Paulo Ribeiro Pavel Lobashov +Pavel Matěja Pavel Pletenev Pavel Pospisil Pavel Sutyrin @@ -1572,6 +1634,7 @@ Riku Voipio Riley Guerin Ritesh H Shukla Riyaz Faizullabhoy +Rob Gulewich Rob Vesse Robert Bachmann Robert Bittle @@ -1580,11 +1643,13 @@ Robert Schneider Robert Stern Robert Terhaar Robert Wallis +Robert Wang Roberto G. Hashioka Roberto Muñoz Fernández Robin Naundorf Robin Schneider Robin Speekenbrink +Robin Thoni robpc Rodolfo Carvalho Rodrigo Vaz @@ -1599,6 +1664,7 @@ Roland Kammerer Roland Moriz Roma Sokolov Roman Dudin +Roman Mazur Roman Strashkin Ron Smits Ron Williams @@ -1618,6 +1684,7 @@ Rozhnov Alexandr Rudolph Gottesheim Rui Cao Rui Lopes +Ruilin Li Runshen Zhu Russ Magee Ryan Abrams @@ -1656,6 +1723,7 @@ Sam J Sharpe Sam Neirinck Sam Reis Sam Rijs +Sam Whited Sambuddha Basu Sami Wagiaalla Samuel Andaya @@ -1670,6 +1738,7 @@ sapphiredev Sargun Dhillon Sascha Andres Sascha Grunert +SataQiu Satnam Singh Satoshi Amemiya Satoshi Tagomori @@ -1718,6 +1787,7 @@ Shijun Qin Shishir Mahajan Shoubhik Bose Shourya Sarcar +Shu-Wai Chow shuai-z Shukui Yang Shuwei Hao @@ -1728,6 +1798,7 @@ Silas Sewell Silvan Jegen Simão Reis Simei He +Simon Barendse Simon Eskildsen Simon Ferquel Simon Leinen @@ -1736,6 +1807,7 @@ Simon Taranto Simon Vikstrom Sindhu S Sjoerd Langkemper +skanehira Solganik Alexander Solomon Hykes Song Gao @@ -1747,18 +1819,21 @@ Sridatta Thatipamala Sridhar Ratnakumar Srini Brahmaroutu Srinivasan Srivatsan +Staf Wagemakers Stanislav Bondarenko +Stanislav Levin Steeve Morin Stefan Berger Stefan J. Wernli Stefan Praszalowicz Stefan S. -Stefan Scherer +Stefan Scherer Stefan Staudenmeyer Stefan Weil Stephan Spindler +Stephen Benjamin Stephen Crosby -Stephen Day +Stephen Day Stephen Drake Stephen Rust Steve Desmond @@ -1773,10 +1848,12 @@ Steven Iveson Steven Merrill Steven Richards Steven Taylor +Stig Larsson Subhajit Ghosh Sujith Haridasan Sun Gengze <690388648@qq.com> Sun Jianbo +Sune Keller Sunny Gogoi Suryakumar Sudar Sven Dowideit @@ -1827,6 +1904,8 @@ Tianyi Wang Tibor Vass Tiffany Jernigan Tiffany Low +Till Wegmüller +Tim Tim Bart Tim Bosse Tim Dettrick @@ -1878,7 +1957,7 @@ Tony Miller toogley Torstein Husebø Tõnis Tiigi -tpng +Trace Andreason tracylihui <793912329@qq.com> Trapier Marshall Travis Cline @@ -1901,6 +1980,7 @@ Utz Bacher vagrant Vaidas Jablonskis vanderliang +Velko Ivanov Veres Lajos Victor Algaze Victor Coisne @@ -1912,11 +1992,13 @@ Victor Palma Victor Vieux Victoria Bialas Vijaya Kumar K +Vikram bir Singh Viktor Stanchev Viktor Vojnovski VinayRaghavanKS Vincent Batts Vincent Bernat +Vincent Boulineau Vincent Demeester Vincent Giersch Vincent Mayers @@ -1947,6 +2029,8 @@ Wang Long Wang Ping Wang Xing Wang Yuexiao +Wang Yumu <37442693@qq.com> +wanghuaiqing Ward Vandewege WarheadsSE Wassim Dhif @@ -1963,12 +2047,14 @@ Wen Cheng Ma Wendel Fleming Wenjun Tang Wenkai Yin +wenlxie Wentao Zhang Wenxuan Zhao Wenyu You <21551128@zju.edu.cn> Wenzhi Liang Wes Morgan Wewang Xiaorenfine +Wiktor Kwapisiewicz Will Dietz Will Rouesnel Will Weaver @@ -1979,6 +2065,8 @@ William Hubbs William Martin William Riancho William Thurston +Wilson Júnior +Wing-Kam Wong WiseTrem Wolfgang Powisch Wonjun Kim @@ -1988,6 +2076,7 @@ Xianglin Gao Xianlu Bird Xiao YongBiao XiaoBing Jiang +Xiaodong Liu Xiaodong Zhang Xiaoxi He Xiaoxu Chen @@ -1996,6 +2085,7 @@ xichengliudui <1693291525@qq.com> xiekeyang Ximo Guanter Gonzálbez Xinbo Weng +Xinfeng Liu Xinzi Zhou Xiuming Chen Xuecong Liao @@ -2010,6 +2100,7 @@ Yang Pengfei yangchenliang Yanqiang Miao Yao Zaiyong +Yash Murty Yassine Tijani Yasunori Mahata Yazhong Liu @@ -2024,6 +2115,7 @@ Yongxin Li Yongzhi Pan Yosef Fertel You-Sheng Yang (楊有勝) +youcai Youcef YEKHLEF Yu Changchun Yu Chengxia @@ -2055,11 +2147,13 @@ Zhenan Ye <21551168@zju.edu.cn> zhenghenghuo Zhenhai Gao Zhenkun Bi +zhipengzuo Zhou Hao Zhoulin Xie Zhu Guihua Zhu Kunjia Zhuoyun Wei +Ziheng Liu Zilin Du zimbatm Ziming Dong @@ -2068,12 +2162,13 @@ zmarouf Zoltan Tombol Zou Yu zqh -Zuhayr Elahi +Zuhayr Elahi Zunayed Ali Álex González Álvaro Lázaro Átila Camurça Alves 尹吉峰 +屈骏 徐俊杰 慕陶 搏通 diff --git a/vendor/github.com/docker/docker/api/common.go b/vendor/github.com/docker/docker/api/common.go index aa146cdaeb1..1565e2af647 100644 --- a/vendor/github.com/docker/docker/api/common.go +++ b/vendor/github.com/docker/docker/api/common.go @@ -3,7 +3,7 @@ package api // import "github.com/docker/docker/api" // Common constants for daemon and client. const ( // DefaultVersion of Current REST API - DefaultVersion = "1.40" + DefaultVersion = "1.41" // NoBaseImageSpecifier is the symbol used by the FROM // command to specify that no base image is to be used. diff --git a/vendor/github.com/docker/docker/api/swagger.yaml b/vendor/github.com/docker/docker/api/swagger.yaml index 70b09a0e3b7..9f1019681af 100644 --- a/vendor/github.com/docker/docker/api/swagger.yaml +++ b/vendor/github.com/docker/docker/api/swagger.yaml @@ -19,10 +19,10 @@ produces: consumes: - "application/json" - "text/plain" -basePath: "/v1.40" +basePath: "/v1.41" info: title: "Docker Engine API" - version: "1.40" + version: "1.41" x-logo: url: "https://docs.docker.com/images/logo-docker-main.png" description: | @@ -55,8 +55,8 @@ info: the URL is not supported by the daemon, a HTTP `400 Bad Request` error message is returned. - If you omit the version-prefix, the current version of the API (v1.40) is used. - For example, calling `/info` is the same as calling `/v1.40/info`. Using the + If you omit the version-prefix, the current version of the API (v1.41) is used. + For example, calling `/info` is the same as calling `/v1.41/info`. Using the API without a version-prefix is deprecated and will be removed in a future release. Engine releases in the near future should support this version of the API, @@ -528,7 +528,13 @@ definitions: items: $ref: "#/definitions/DeviceRequest" KernelMemory: - description: "Kernel memory limit in bytes." + description: | + Kernel memory limit in bytes. + +


+ + > **Deprecated**: This field is deprecated as the kernel 5.4 deprecated + > `kmem.limit_in_bytes`. type: "integer" format: "int64" example: 209715200 @@ -625,6 +631,27 @@ definitions: type: "integer" format: "int64" + Limit: + description: | + An object describing a limit on resources which can be requested by a task. + type: "object" + properties: + NanoCPUs: + type: "integer" + format: "int64" + example: 4000000000 + MemoryBytes: + type: "integer" + format: "int64" + example: 8272408576 + Pids: + description: | + Limits the maximum number of PIDs in the container. Set `0` for unlimited. + type: "integer" + format: "int64" + default: 0 + example: 100 + ResourceObject: description: | An object describing the resources which can be advertised by a node and @@ -885,15 +912,6 @@ definitions: $ref: "#/definitions/Mount" # Applicable to UNIX platforms - Capabilities: - type: "array" - description: | - A list of kernel capabilities to be available for container (this - overrides the default set). - - Conflicts with options 'CapAdd' and 'CapDrop'" - items: - type: "string" CapAdd: type: "array" description: | @@ -908,6 +926,19 @@ definitions: with option 'Capabilities'. items: type: "string" + CgroupnsMode: + type: "string" + enum: + - "private" + - "host" + description: | + cgroup namespace mode for the container. Possible values are: + + - `"private"`: the container runs in its own private cgroup namespace + - `"host"`: use the host system's cgroup namespace + + If not specified, the daemon default is used, which can either be `"private"` + or `"host"`, depending on daemon version, kernel support and configuration. Dns: type: "array" description: "A list of DNS servers for the container to use." @@ -3253,6 +3284,44 @@ definitions: type: "object" additionalProperties: type: "string" + # This option is not used by Windows containers + CapabilityAdd: + type: "array" + description: | + A list of kernel capabilities to add to the default set + for the container. + items: + type: "string" + example: + - "CAP_NET_RAW" + - "CAP_SYS_ADMIN" + - "CAP_SYS_CHROOT" + - "CAP_SYSLOG" + CapabilityDrop: + type: "array" + description: | + A list of kernel capabilities to drop from the default set + for the container. + items: + type: "string" + example: + - "CAP_NET_RAW" + Ulimits: + description: | + A list of resource limits to set in the container. For example: `{"Name": "nofile", "Soft": 1024, "Hard": 2048}`" + type: "array" + items: + type: "object" + properties: + Name: + description: "Name of ulimit" + type: "string" + Soft: + description: "Soft limit" + type: "integer" + Hard: + description: "Hard limit" + type: "integer" NetworkAttachmentSpec: description: | Read-only spec type for non-swarm containers attached to swarm overlay @@ -3277,7 +3346,7 @@ definitions: properties: Limits: description: "Define resources limits." - $ref: "#/definitions/ResourceObject" + $ref: "#/definitions/Limit" Reservation: description: "Define resources reservation." $ref: "#/definitions/ResourceObject" @@ -3487,6 +3556,12 @@ definitions: type: "integer" DesiredState: $ref: "#/definitions/TaskState" + JobIteration: + description: | + If the Service this Task belongs to is a job-mode service, contains + the JobIteration of the Service this Task was created for. Absent if + the Task was created for a Replicated or Global Service. + $ref: "#/definitions/ObjectVersion" example: ID: "0kzzo1i0y4jz6027t0k7aezc7" Version: @@ -3579,6 +3654,29 @@ definitions: format: "int64" Global: type: "object" + ReplicatedJob: + description: | + The mode used for services with a finite number of tasks that run + to a completed state. + type: "object" + properties: + MaxConcurrent: + description: | + The maximum number of replicas to run simultaneously. + type: "integer" + format: "int64" + default: 1 + TotalCompletions: + description: | + The total number of replicas desired to reach the Completed + state. If unset, will default to the value of `MaxConcurrent` + type: "integer" + format: "int64" + GlobalJob: + description: | + The mode used for services which run a task to the completed state + on each valid node. + type: "object" UpdateConfig: description: "Specification for the update strategy of the service." type: "object" @@ -3785,6 +3883,61 @@ definitions: format: "dateTime" Message: type: "string" + ServiceStatus: + description: | + The status of the service's tasks. Provided only when requested as + part of a ServiceList operation. + type: "object" + properties: + RunningTasks: + description: | + The number of tasks for the service currently in the Running state. + type: "integer" + format: "uint64" + example: 7 + DesiredTasks: + description: | + The number of tasks for the service desired to be running. + For replicated services, this is the replica count from the + service spec. For global services, this is computed by taking + count of all tasks for the service with a Desired State other + than Shutdown. + type: "integer" + format: "uint64" + example: 10 + CompletedTasks: + description: | + The number of tasks for a job that are in the Completed state. + This field must be cross-referenced with the service type, as the + value of 0 may mean the service is not in a job mode, or it may + mean the job-mode service has no tasks yet Completed. + type: "integer" + format: "uint64" + JobStatus: + description: | + The status of the service when it is in one of ReplicatedJob or + GlobalJob modes. Absent on Replicated and Global mode services. The + JobIteration is an ObjectVersion, but unlike the Service's version, + does not need to be sent with an update request. + type: "object" + properties: + JobIteration: + description: | + JobIteration is a value increased each time a Job is executed, + successfully or otherwise. "Executed", in this case, means the + job as a whole has been started, not that an individual Task has + been launched. A job is "Executed" when its ServiceSpec is + updated. JobIteration can be used to disambiguate Tasks belonging + to different executions of a job. Though JobIteration will + increase with each subsequent execution, it may not necessarily + increase by 1, and so JobIteration should not be used to + $ref: "#/definitions/ObjectVersion" + LastExecution: + description: | + The last time, as observed by the server, that this job was + started. + type: "string" + format: "dateTime" example: ID: "9mnpnzenvg8p8tdbtq4wvbkcz" Version: @@ -4288,44 +4441,6 @@ definitions: on Windows. type: "string" example: "/var/lib/docker" - SystemStatus: - description: | - Status information about this node (standalone Swarm API). - -


- - > **Note**: The information returned in this field is only propagated - > by the Swarm standalone API, and is empty (`null`) when using - > built-in swarm mode. - type: "array" - items: - type: "array" - items: - type: "string" - example: - - ["Role", "primary"] - - ["State", "Healthy"] - - ["Strategy", "spread"] - - ["Filters", "health, port, containerslots, dependency, affinity, constraint, whitelist"] - - ["Nodes", "2"] - - [" swarm-agent-00", "192.168.99.102:2376"] - - [" └ ID", "5CT6:FBGO:RVGO:CZL4:PB2K:WCYN:2JSV:KSHH:GGFW:QOPG:6J5Q:IOZ2|192.168.99.102:2376"] - - [" └ Status", "Healthy"] - - [" └ Containers", "1 (1 Running, 0 Paused, 0 Stopped)"] - - [" └ Reserved CPUs", "0 / 1"] - - [" └ Reserved Memory", "0 B / 1.021 GiB"] - - [" └ Labels", "kernelversion=4.4.74-boot2docker, operatingsystem=Boot2Docker 17.06.0-ce (TCL 7.2); HEAD : 0672754 - Thu Jun 29 00:06:31 UTC 2017, ostype=linux, provider=virtualbox, storagedriver=aufs"] - - [" └ UpdatedAt", "2017-08-09T10:03:46Z"] - - [" └ ServerVersion", "17.06.0-ce"] - - [" swarm-manager", "192.168.99.101:2376"] - - [" └ ID", "TAMD:7LL3:SEF7:LW2W:4Q2X:WVFH:RTXX:JSYS:XY2P:JEHL:ZMJK:JGIW|192.168.99.101:2376"] - - [" └ Status", "Healthy"] - - [" └ Containers", "2 (2 Running, 0 Paused, 0 Stopped)"] - - [" └ Reserved CPUs", "0 / 1"] - - [" └ Reserved Memory", "0 B / 1.021 GiB"] - - [" └ Labels", "kernelversion=4.4.74-boot2docker, operatingsystem=Boot2Docker 17.06.0-ce (TCL 7.2); HEAD : 0672754 - Thu Jun 29 00:06:31 UTC 2017, ostype=linux, provider=virtualbox, storagedriver=aufs"] - - [" └ UpdatedAt", "2017-08-09T10:04:11Z"] - - [" └ ServerVersion", "17.06.0-ce"] Plugins: $ref: "#/definitions/PluginsInfo" MemoryLimit: @@ -4337,7 +4452,13 @@ definitions: type: "boolean" example: true KernelMemory: - description: "Indicates if the host has kernel memory limit support enabled." + description: | + Indicates if the host has kernel memory limit support enabled. + +


+ + > **Deprecated**: This field is deprecated as the kernel 5.4 deprecated + > `kmem.limit_in_bytes`. type: "boolean" example: true CpuCfsPeriod: @@ -4420,6 +4541,13 @@ definitions: enum: ["cgroupfs", "systemd", "none"] default: "cgroupfs" example: "cgroupfs" + CgroupVersion: + description: | + The version of the cgroup. + type: "string" + enum: ["1", "2"] + default: "1" + example: "1" NEventsListener: description: "Number of event listeners subscribed." type: "integer" @@ -4439,6 +4567,17 @@ definitions: or "Windows Server 2016 Datacenter" type: "string" example: "Alpine Linux v3.5" + OSVersion: + description: | + Version of the host's operating system + +


+ + > **Note**: The information returned in this field, including its + > very existence, and the formatting of values, should not be considered + > stable, and may change without notice. + type: "string" + example: "16.04" OSType: description: | Generic type of the operating system of the host, as returned by the @@ -4555,7 +4694,7 @@ definitions:


- > **Note**: This field is only propagated when using standalone Swarm + > **Deprecated**: This field is only propagated when using standalone Swarm > mode, and overlay networking using an external k/v store. Overlay > networks with Swarm mode enabled use the built-in raft store, and > this field will be empty. @@ -4569,7 +4708,7 @@ definitions:


- > **Note**: This field is only propagated when using standalone Swarm + > **Deprecated**: This field is only propagated when using standalone Swarm > mode, and overlay networking using an external k/v store. Overlay > networks with Swarm mode enabled use the built-in raft store, and > this field will be empty. @@ -4674,6 +4813,25 @@ definitions: such as number of nodes, and expiration are included. type: "string" example: "Community Engine" + DefaultAddressPools: + description: | + List of custom default address pools for local networks, which can be + specified in the daemon.json file or dockerd option. + + Example: a Base "10.10.0.0/16" with Size 24 will define the set of 256 + 10.10.[0-255].0/24 address pools. + type: "array" + items: + type: "object" + properties: + Base: + description: "The network address in CIDR format" + type: "string" + example: "10.10.0.0/16" + Size: + description: "The network pool size" + type: "integer" + example: "24" Warnings: description: | List of warnings / informational messages about missing features, or @@ -5482,9 +5640,6 @@ paths: type: "string" LogPath: type: "string" - Node: - description: "TODO" - type: "object" Name: type: "string" RestartCount: @@ -5971,6 +6126,12 @@ paths: nil then for compatibility with older daemons the length of the corresponding `cpu_usage.percpu_usage` array should be used. + On a cgroup v2 host, the following fields are not set + * `blkio_stats`: all fields other than `io_service_bytes_recursive` + * `cpu_stats`: `cpu_usage.percpu_usage` + * `memory_stats`: `max_usage` and `failcnt` + Also, `memory_stats.stats` fields are incompatible with cgroup v1. + To calculate the values shown by the `stats` command of the docker cli tool the following formulas can be used: * used_memory = `memory_stats.usage - memory_stats.stats.cache` @@ -6103,6 +6264,13 @@ paths: it will disconnect. type: "boolean" default: true + - name: "one-shot" + in: "query" + description: | + Only get a single stat instead of waiting for 2 cycles. Must be used + with `stream=false`. + type: "boolean" + default: false tags: ["Container"] /containers/{id}/resize: post: @@ -6755,7 +6923,7 @@ paths: type: "string" - name: "v" in: "query" - description: "Remove the volumes associated with the container." + description: "Remove anonymous volumes associated with the container." type: "boolean" default: false - name: "force" @@ -7855,7 +8023,7 @@ paths: API-Version: type: "string" description: "Max API Version the server supports" - BuildKit-Version: + Builder-Version: type: "string" description: "Default version of docker image builder" Docker-Experimental: @@ -7894,7 +8062,7 @@ paths: API-Version: type: "string" description: "Max API Version the server supports" - BuildKit-Version: + Builder-Version: type: "string" description: "Default version of docker image builder" Docker-Experimental: @@ -7979,13 +8147,13 @@ paths: Various objects within Docker report events when something happens to them. - Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `exec_die`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, and `update` + Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `exec_die`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, `update`, and `prune` - Images report these events: `delete`, `import`, `load`, `pull`, `push`, `save`, `tag`, and `untag` + Images report these events: `delete`, `import`, `load`, `pull`, `push`, `save`, `tag`, `untag`, and `prune` - Volumes report these events: `create`, `mount`, `unmount`, and `destroy` + Volumes report these events: `create`, `mount`, `unmount`, `destroy`, and `prune` - Networks report these events: `create`, `connect`, `disconnect`, `destroy`, `update`, and `remove` + Networks report these events: `create`, `connect`, `disconnect`, `destroy`, `update`, `remove`, and `prune` The Docker daemon reports these events: `reload` @@ -7997,6 +8165,8 @@ paths: Configs report these events: `create`, `update`, and `remove` + The Builder reports `prune` events + operationId: "SystemEvents" produces: - "application/json" @@ -10071,6 +10241,11 @@ paths: - `label=` - `mode=["replicated"|"global"]` - `name=` + - name: "status" + in: "query" + type: "boolean" + description: | + Include service status, with count of running and desired tasks. tags: ["Service"] /services/create: post: diff --git a/vendor/github.com/docker/docker/api/types/client.go b/vendor/github.com/docker/docker/api/types/client.go index fe90617eec3..9c464b73e25 100644 --- a/vendor/github.com/docker/docker/api/types/client.go +++ b/vendor/github.com/docker/docker/api/types/client.go @@ -205,7 +205,7 @@ const ( // BuilderV1 is the first generation builder in docker daemon BuilderV1 BuilderVersion = "1" // BuilderBuildKit is builder based on moby/buildkit project - BuilderBuildKit = "2" + BuilderBuildKit BuilderVersion = "2" ) // ImageBuildResponse holds information @@ -265,7 +265,7 @@ type ImagePullOptions struct { // if the privilege request fails. type RequestPrivilegeFunc func() (string, error) -//ImagePushOptions holds information to push images. +// ImagePushOptions holds information to push images. type ImagePushOptions ImagePullOptions // ImageRemoveOptions holds parameters to remove images. @@ -363,6 +363,10 @@ type ServiceUpdateOptions struct { // ServiceListOptions holds parameters to list services with. type ServiceListOptions struct { Filters filters.Args + + // Status indicates whether the server should include the service task + // count of running and desired tasks. + Status bool } // ServiceInspectOptions holds parameters related to the "service inspect" diff --git a/vendor/github.com/docker/docker/api/types/configs.go b/vendor/github.com/docker/docker/api/types/configs.go index 178e911a7af..3dd133a3a58 100644 --- a/vendor/github.com/docker/docker/api/types/configs.go +++ b/vendor/github.com/docker/docker/api/types/configs.go @@ -3,6 +3,7 @@ package types // import "github.com/docker/docker/api/types" import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" + specs "github.com/opencontainers/image-spec/specs-go/v1" ) // configs holds structs used for internal communication between the @@ -15,6 +16,7 @@ type ContainerCreateConfig struct { Config *container.Config HostConfig *container.HostConfig NetworkingConfig *network.NetworkingConfig + Platform *specs.Platform AdjustCPUShares bool } diff --git a/vendor/github.com/docker/docker/api/types/container/container_changes.go b/vendor/github.com/docker/docker/api/types/container/container_changes.go index 222d141007e..16dd5019eef 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_changes.go +++ b/vendor/github.com/docker/docker/api/types/container/container_changes.go @@ -1,8 +1,7 @@ package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- -// DO NOT EDIT THIS FILE -// This file was generated by `swagger generate operation` +// Code generated by `swagger generate operation`. DO NOT EDIT. // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/container/container_create.go b/vendor/github.com/docker/docker/api/types/container/container_create.go index 1ec9c3728ba..d0c852f84d5 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_create.go +++ b/vendor/github.com/docker/docker/api/types/container/container_create.go @@ -1,8 +1,7 @@ package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- -// DO NOT EDIT THIS FILE -// This file was generated by `swagger generate operation` +// Code generated by `swagger generate operation`. DO NOT EDIT. // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/container/container_top.go b/vendor/github.com/docker/docker/api/types/container/container_top.go index bd34cd6b692..63381da3674 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_top.go +++ b/vendor/github.com/docker/docker/api/types/container/container_top.go @@ -1,8 +1,7 @@ package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- -// DO NOT EDIT THIS FILE -// This file was generated by `swagger generate operation` +// Code generated by `swagger generate operation`. DO NOT EDIT. // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/container/container_update.go b/vendor/github.com/docker/docker/api/types/container/container_update.go index 33addedf779..c10f175ea82 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_update.go +++ b/vendor/github.com/docker/docker/api/types/container/container_update.go @@ -1,8 +1,7 @@ package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- -// DO NOT EDIT THIS FILE -// This file was generated by `swagger generate operation` +// Code generated by `swagger generate operation`. DO NOT EDIT. // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/container/container_wait.go b/vendor/github.com/docker/docker/api/types/container/container_wait.go index 94b6a20e159..49e05ae6694 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_wait.go +++ b/vendor/github.com/docker/docker/api/types/container/container_wait.go @@ -1,8 +1,7 @@ package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- -// DO NOT EDIT THIS FILE -// This file was generated by `swagger generate operation` +// Code generated by `swagger generate operation`. DO NOT EDIT. // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/container/host_config.go b/vendor/github.com/docker/docker/api/types/container/host_config.go index c3de3d976a5..2d1cbaa9abd 100644 --- a/vendor/github.com/docker/docker/api/types/container/host_config.go +++ b/vendor/github.com/docker/docker/api/types/container/host_config.go @@ -7,9 +7,32 @@ import ( "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/strslice" "github.com/docker/go-connections/nat" - "github.com/docker/go-units" + units "github.com/docker/go-units" ) +// CgroupnsMode represents the cgroup namespace mode of the container +type CgroupnsMode string + +// IsPrivate indicates whether the container uses its own private cgroup namespace +func (c CgroupnsMode) IsPrivate() bool { + return c == "private" +} + +// IsHost indicates whether the container shares the host's cgroup namespace +func (c CgroupnsMode) IsHost() bool { + return c == "host" +} + +// IsEmpty indicates whether the container cgroup namespace mode is unset +func (c CgroupnsMode) IsEmpty() bool { + return c == "" +} + +// Valid indicates whether the cgroup namespace mode is valid +func (c CgroupnsMode) Valid() bool { + return c.IsEmpty() || c.IsPrivate() || c.IsHost() +} + // Isolation represents the isolation technology of a container. The supported // values are platform specific type Isolation string @@ -122,7 +145,7 @@ func (n NetworkMode) ConnectedContainer() string { return "" } -//UserDefined indicates user-created network +// UserDefined indicates user-created network func (n NetworkMode) UserDefined() string { if n.IsUserDefined() { return string(n) @@ -338,7 +361,7 @@ type Resources struct { Devices []DeviceMapping // List of devices to map inside the container DeviceCgroupRules []string // List of rule to be added to the device cgroup DeviceRequests []DeviceRequest // List of device requests for device drivers - KernelMemory int64 // Kernel memory limit (in bytes) + KernelMemory int64 // Kernel memory limit (in bytes), Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes KernelMemoryTCP int64 // Hard limit for kernel TCP buffer memory (in bytes) MemoryReservation int64 // Memory soft limit (in bytes) MemorySwap int64 // Total memory usage (memory + swap); set `-1` to enable unlimited swap @@ -380,10 +403,10 @@ type HostConfig struct { // Applicable to UNIX platforms CapAdd strslice.StrSlice // List of kernel capabilities to add to the container CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container - Capabilities []string `json:"Capabilities"` // List of kernel capabilities to be available for container (this overrides the default set) - DNS []string `json:"Dns"` // List of DNS server to lookup - DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for - DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for + CgroupnsMode CgroupnsMode // Cgroup namespace mode to use for the container + DNS []string `json:"Dns"` // List of DNS server to lookup + DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for + DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for ExtraHosts []string // List of extra hosts GroupAdd []string // List of additional groups that the container process will run as IpcMode IpcMode // IPC namespace to use for the container diff --git a/vendor/github.com/docker/docker/api/types/error_response_ext.go b/vendor/github.com/docker/docker/api/types/error_response_ext.go new file mode 100644 index 00000000000..f84f034cd54 --- /dev/null +++ b/vendor/github.com/docker/docker/api/types/error_response_ext.go @@ -0,0 +1,6 @@ +package types + +// Error returns the error message +func (e ErrorResponse) Error() string { + return e.Message +} diff --git a/vendor/github.com/docker/docker/api/types/events/events.go b/vendor/github.com/docker/docker/api/types/events/events.go index 027c6edb722..aa8fba81548 100644 --- a/vendor/github.com/docker/docker/api/types/events/events.go +++ b/vendor/github.com/docker/docker/api/types/events/events.go @@ -1,6 +1,8 @@ package events // import "github.com/docker/docker/api/types/events" const ( + // BuilderEventType is the event type that the builder generates + BuilderEventType = "builder" // ContainerEventType is the event type that containers generate ContainerEventType = "container" // DaemonEventType is the event type that daemon generate diff --git a/vendor/github.com/docker/docker/api/types/filters/parse.go b/vendor/github.com/docker/docker/api/types/filters/parse.go index 0bd2e1e1853..4bc91cffd6e 100644 --- a/vendor/github.com/docker/docker/api/types/filters/parse.go +++ b/vendor/github.com/docker/docker/api/types/filters/parse.go @@ -66,7 +66,7 @@ func ToJSON(a Args) (string, error) { // then the encoded format will use an older legacy format where the values are a // list of strings, instead of a set. // -// Deprecated: Use ToJSON +// Deprecated: do not use in any new code; use ToJSON instead func ToParamWithVersion(version string, a Args) (string, error) { if a.Len() == 0 { return "", nil @@ -154,7 +154,7 @@ func (args Args) Len() int { func (args Args) MatchKVList(key string, sources map[string]string) bool { fieldValues := args.fields[key] - //do not filter if there is no filter set or cannot determine filter + // do not filter if there is no filter set or cannot determine filter if len(fieldValues) == 0 { return true } @@ -200,7 +200,7 @@ func (args Args) Match(field, source string) bool { // ExactMatch returns true if the source matches exactly one of the values. func (args Args) ExactMatch(key, source string) bool { fieldValues, ok := args.fields[key] - //do not filter if there is no filter set or cannot determine filter + // do not filter if there is no filter set or cannot determine filter if !ok || len(fieldValues) == 0 { return true } @@ -213,7 +213,7 @@ func (args Args) ExactMatch(key, source string) bool { // matches exactly the value. func (args Args) UniqueExactMatch(key, source string) bool { fieldValues := args.fields[key] - //do not filter if there is no filter set or cannot determine filter + // do not filter if there is no filter set or cannot determine filter if len(fieldValues) == 0 { return true } diff --git a/vendor/github.com/docker/docker/api/types/image/image_history.go b/vendor/github.com/docker/docker/api/types/image/image_history.go index b5a7a0c4901..e302bb0aebb 100644 --- a/vendor/github.com/docker/docker/api/types/image/image_history.go +++ b/vendor/github.com/docker/docker/api/types/image/image_history.go @@ -1,8 +1,7 @@ package image // import "github.com/docker/docker/api/types/image" // ---------------------------------------------------------------------------- -// DO NOT EDIT THIS FILE -// This file was generated by `swagger generate operation` +// Code generated by `swagger generate operation`. DO NOT EDIT. // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/mount/mount.go b/vendor/github.com/docker/docker/api/types/mount/mount.go index ab4446b38f6..443b8d07a9f 100644 --- a/vendor/github.com/docker/docker/api/types/mount/mount.go +++ b/vendor/github.com/docker/docker/api/types/mount/mount.go @@ -113,7 +113,7 @@ type TmpfsOptions struct { // TODO(stevvooe): There are several more tmpfs flags, specified in the // daemon, that are accepted. Only the most basic are added for now. // - // From docker/docker/pkg/mount/flags.go: + // From https://github.com/moby/sys/blob/mount/v0.1.1/mount/flags.go#L47-L56 // // var validFlags = map[string]bool{ // "": true, diff --git a/vendor/github.com/docker/docker/api/types/network/network.go b/vendor/github.com/docker/docker/api/types/network/network.go index 71e97338fdc..437b184c67b 100644 --- a/vendor/github.com/docker/docker/api/types/network/network.go +++ b/vendor/github.com/docker/docker/api/types/network/network.go @@ -1,7 +1,6 @@ package network // import "github.com/docker/docker/api/types/network" import ( "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/errdefs" ) // Address represents an IP address @@ -13,7 +12,7 @@ type Address struct { // IPAM represents IP Address Management type IPAM struct { Driver string - Options map[string]string //Per network IPAM driver options + Options map[string]string // Per network IPAM driver options Config []IPAMConfig } @@ -123,5 +122,5 @@ var acceptedFilters = map[string]bool{ // ValidateFilters validates the list of filter args with the available filters. func ValidateFilters(filter filters.Args) error { - return errdefs.InvalidParameter(filter.Validate(acceptedFilters)) + return filter.Validate(acceptedFilters) } diff --git a/vendor/github.com/docker/docker/api/types/registry/registry.go b/vendor/github.com/docker/docker/api/types/registry/registry.go index 8789ad3b321..53e47084c8d 100644 --- a/vendor/github.com/docker/docker/api/types/registry/registry.go +++ b/vendor/github.com/docker/docker/api/types/registry/registry.go @@ -4,7 +4,7 @@ import ( "encoding/json" "net" - "github.com/opencontainers/image-spec/specs-go/v1" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // ServiceConfig stores daemon registry services configuration. diff --git a/vendor/github.com/docker/docker/api/types/seccomp.go b/vendor/github.com/docker/docker/api/types/seccomp.go deleted file mode 100644 index 2259c6be1e6..00000000000 --- a/vendor/github.com/docker/docker/api/types/seccomp.go +++ /dev/null @@ -1,94 +0,0 @@ -package types // import "github.com/docker/docker/api/types" - -// Seccomp represents the config for a seccomp profile for syscall restriction. -type Seccomp struct { - DefaultAction Action `json:"defaultAction"` - // Architectures is kept to maintain backward compatibility with the old - // seccomp profile. - Architectures []Arch `json:"architectures,omitempty"` - ArchMap []Architecture `json:"archMap,omitempty"` - Syscalls []*Syscall `json:"syscalls"` -} - -// Architecture is used to represent a specific architecture -// and its sub-architectures -type Architecture struct { - Arch Arch `json:"architecture"` - SubArches []Arch `json:"subArchitectures"` -} - -// Arch used for architectures -type Arch string - -// Additional architectures permitted to be used for system calls -// By default only the native architecture of the kernel is permitted -const ( - ArchX86 Arch = "SCMP_ARCH_X86" - ArchX86_64 Arch = "SCMP_ARCH_X86_64" - ArchX32 Arch = "SCMP_ARCH_X32" - ArchARM Arch = "SCMP_ARCH_ARM" - ArchAARCH64 Arch = "SCMP_ARCH_AARCH64" - ArchMIPS Arch = "SCMP_ARCH_MIPS" - ArchMIPS64 Arch = "SCMP_ARCH_MIPS64" - ArchMIPS64N32 Arch = "SCMP_ARCH_MIPS64N32" - ArchMIPSEL Arch = "SCMP_ARCH_MIPSEL" - ArchMIPSEL64 Arch = "SCMP_ARCH_MIPSEL64" - ArchMIPSEL64N32 Arch = "SCMP_ARCH_MIPSEL64N32" - ArchPPC Arch = "SCMP_ARCH_PPC" - ArchPPC64 Arch = "SCMP_ARCH_PPC64" - ArchPPC64LE Arch = "SCMP_ARCH_PPC64LE" - ArchS390 Arch = "SCMP_ARCH_S390" - ArchS390X Arch = "SCMP_ARCH_S390X" -) - -// Action taken upon Seccomp rule match -type Action string - -// Define actions for Seccomp rules -const ( - ActKill Action = "SCMP_ACT_KILL" - ActTrap Action = "SCMP_ACT_TRAP" - ActErrno Action = "SCMP_ACT_ERRNO" - ActTrace Action = "SCMP_ACT_TRACE" - ActAllow Action = "SCMP_ACT_ALLOW" -) - -// Operator used to match syscall arguments in Seccomp -type Operator string - -// Define operators for syscall arguments in Seccomp -const ( - OpNotEqual Operator = "SCMP_CMP_NE" - OpLessThan Operator = "SCMP_CMP_LT" - OpLessEqual Operator = "SCMP_CMP_LE" - OpEqualTo Operator = "SCMP_CMP_EQ" - OpGreaterEqual Operator = "SCMP_CMP_GE" - OpGreaterThan Operator = "SCMP_CMP_GT" - OpMaskedEqual Operator = "SCMP_CMP_MASKED_EQ" -) - -// Arg used for matching specific syscall arguments in Seccomp -type Arg struct { - Index uint `json:"index"` - Value uint64 `json:"value"` - ValueTwo uint64 `json:"valueTwo"` - Op Operator `json:"op"` -} - -// Filter is used to conditionally apply Seccomp rules -type Filter struct { - Caps []string `json:"caps,omitempty"` - Arches []string `json:"arches,omitempty"` - MinKernel string `json:"minKernel,omitempty"` -} - -// Syscall is used to match a group of syscalls in Seccomp -type Syscall struct { - Name string `json:"name,omitempty"` - Names []string `json:"names,omitempty"` - Action Action `json:"action"` - Args []*Arg `json:"args"` - Comment string `json:"comment"` - Includes Filter `json:"includes"` - Excludes Filter `json:"excludes"` -} diff --git a/vendor/github.com/docker/docker/api/types/swarm/container.go b/vendor/github.com/docker/docker/api/types/swarm/container.go index 48190c1762f..af5e1c0bc27 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/container.go +++ b/vendor/github.com/docker/docker/api/types/swarm/container.go @@ -5,6 +5,7 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/mount" + "github.com/docker/go-units" ) // DNSConfig specifies DNS related configurations in resolver configuration file (resolv.conf) @@ -67,10 +68,13 @@ type ContainerSpec struct { // The format of extra hosts on swarmkit is specified in: // http://man7.org/linux/man-pages/man5/hosts.5.html // IP_address canonical_hostname [aliases...] - Hosts []string `json:",omitempty"` - DNSConfig *DNSConfig `json:",omitempty"` - Secrets []*SecretReference `json:",omitempty"` - Configs []*ConfigReference `json:",omitempty"` - Isolation container.Isolation `json:",omitempty"` - Sysctls map[string]string `json:",omitempty"` + Hosts []string `json:",omitempty"` + DNSConfig *DNSConfig `json:",omitempty"` + Secrets []*SecretReference `json:",omitempty"` + Configs []*ConfigReference `json:",omitempty"` + Isolation container.Isolation `json:",omitempty"` + Sysctls map[string]string `json:",omitempty"` + CapabilityAdd []string `json:",omitempty"` + CapabilityDrop []string `json:",omitempty"` + Ulimits []*units.Ulimit `json:",omitempty"` } diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go index 1fdc9b04361..e45045866a6 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go +++ b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-gogo. +// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: plugin.proto -// DO NOT EDIT! /* Package runtime is a generated protocol buffer package. @@ -38,6 +37,7 @@ type PluginSpec struct { Remote string `protobuf:"bytes,2,opt,name=remote,proto3" json:"remote,omitempty"` Privileges []*PluginPrivilege `protobuf:"bytes,3,rep,name=privileges" json:"privileges,omitempty"` Disabled bool `protobuf:"varint,4,opt,name=disabled,proto3" json:"disabled,omitempty"` + Env []string `protobuf:"bytes,5,rep,name=env" json:"env,omitempty"` } func (m *PluginSpec) Reset() { *m = PluginSpec{} } @@ -73,6 +73,13 @@ func (m *PluginSpec) GetDisabled() bool { return false } +func (m *PluginSpec) GetEnv() []string { + if m != nil { + return m.Env + } + return nil +} + // PluginPrivilege describes a permission the user has to accept // upon installing a plugin. type PluginPrivilege struct { @@ -160,6 +167,21 @@ func (m *PluginSpec) MarshalTo(dAtA []byte) (int, error) { } i++ } + if len(m.Env) > 0 { + for _, s := range m.Env { + dAtA[i] = 0x2a + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } return i, nil } @@ -208,24 +230,6 @@ func (m *PluginPrivilege) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func encodeFixed64Plugin(dAtA []byte, offset int, v uint64) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - dAtA[offset+4] = uint8(v >> 32) - dAtA[offset+5] = uint8(v >> 40) - dAtA[offset+6] = uint8(v >> 48) - dAtA[offset+7] = uint8(v >> 56) - return offset + 8 -} -func encodeFixed32Plugin(dAtA []byte, offset int, v uint32) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - return offset + 4 -} func encodeVarintPlugin(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) @@ -255,6 +259,12 @@ func (m *PluginSpec) Size() (n int) { if m.Disabled { n += 2 } + if len(m.Env) > 0 { + for _, s := range m.Env { + l = len(s) + n += 1 + l + sovPlugin(uint64(l)) + } + } return n } @@ -429,6 +439,35 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error { } } m.Disabled = bool(v != 0) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlugin + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPlugin + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Env = append(m.Env, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPlugin(dAtA[iNdEx:]) @@ -695,18 +734,21 @@ var ( func init() { proto.RegisterFile("plugin.proto", fileDescriptorPlugin) } var fileDescriptorPlugin = []byte{ - // 196 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0xc8, 0x29, 0x4d, - 0xcf, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x6a, 0x63, 0xe4, 0xe2, 0x0a, 0x00, 0x0b, - 0x04, 0x17, 0xa4, 0x26, 0x0b, 0x09, 0x71, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30, 0x2a, 0x30, - 0x6a, 0x70, 0x06, 0x81, 0xd9, 0x42, 0x62, 0x5c, 0x6c, 0x45, 0xa9, 0xb9, 0xf9, 0x25, 0xa9, 0x12, - 0x4c, 0x60, 0x51, 0x28, 0x4f, 0xc8, 0x80, 0x8b, 0xab, 0xa0, 0x28, 0xb3, 0x2c, 0x33, 0x27, 0x35, - 0x3d, 0xb5, 0x58, 0x82, 0x59, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x40, 0x0f, 0x62, 0x58, 0x00, 0x4c, - 0x22, 0x08, 0x49, 0x8d, 0x90, 0x14, 0x17, 0x47, 0x4a, 0x66, 0x71, 0x62, 0x52, 0x4e, 0x6a, 0x8a, - 0x04, 0x8b, 0x02, 0xa3, 0x06, 0x47, 0x10, 0x9c, 0xaf, 0x14, 0xcb, 0xc5, 0x8f, 0xa6, 0x15, 0xab, - 0x63, 0x14, 0xb8, 0xb8, 0x53, 0x52, 0x8b, 0x93, 0x8b, 0x32, 0x0b, 0x4a, 0x32, 0xf3, 0xf3, 0xa0, - 0x2e, 0x42, 0x16, 0x12, 0x12, 0xe1, 0x62, 0x2d, 0x4b, 0xcc, 0x29, 0x4d, 0x05, 0xbb, 0x88, 0x33, - 0x08, 0xc2, 0x71, 0xe2, 0x39, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, - 0x18, 0x93, 0xd8, 0xc0, 0x9e, 0x37, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xb8, 0x84, 0xad, 0x79, - 0x0c, 0x01, 0x00, 0x00, + // 256 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x4d, 0x4b, 0xc3, 0x30, + 0x18, 0xc7, 0x89, 0xdd, 0xc6, 0xfa, 0x4c, 0x70, 0x04, 0x91, 0xe2, 0xa1, 0x94, 0x9d, 0x7a, 0x6a, + 0x45, 0x2f, 0x82, 0x37, 0x0f, 0x9e, 0x47, 0xbc, 0x09, 0x1e, 0xd2, 0xf6, 0xa1, 0x06, 0x9b, 0x17, + 0x92, 0xb4, 0xe2, 0x37, 0xf1, 0x23, 0x79, 0xf4, 0x23, 0x48, 0x3f, 0x89, 0x98, 0x75, 0x32, 0x64, + 0xa7, 0xff, 0x4b, 0xc2, 0x9f, 0x1f, 0x0f, 0x9c, 0x9a, 0xae, 0x6f, 0x85, 0x2a, 0x8c, 0xd5, 0x5e, + 0x6f, 0x3e, 0x08, 0xc0, 0x36, 0x14, 0x8f, 0x06, 0x6b, 0x4a, 0x61, 0xa6, 0xb8, 0xc4, 0x84, 0x64, + 0x24, 0x8f, 0x59, 0xf0, 0xf4, 0x02, 0x16, 0x16, 0xa5, 0xf6, 0x98, 0x9c, 0x84, 0x76, 0x4a, 0xf4, + 0x0a, 0xc0, 0x58, 0x31, 0x88, 0x0e, 0x5b, 0x74, 0x49, 0x94, 0x45, 0xf9, 0xea, 0x7a, 0x5d, 0xec, + 0xc6, 0xb6, 0xfb, 0x07, 0x76, 0xf0, 0x87, 0x5e, 0xc2, 0xb2, 0x11, 0x8e, 0x57, 0x1d, 0x36, 0xc9, + 0x2c, 0x23, 0xf9, 0x92, 0xfd, 0x65, 0xba, 0x86, 0x08, 0xd5, 0x90, 0xcc, 0xb3, 0x28, 0x8f, 0xd9, + 0xaf, 0xdd, 0x3c, 0xc3, 0xd9, 0xbf, 0xb1, 0xa3, 0x78, 0x19, 0xac, 0x1a, 0x74, 0xb5, 0x15, 0xc6, + 0x0b, 0xad, 0x26, 0xc6, 0xc3, 0x8a, 0x9e, 0xc3, 0x7c, 0xe0, 0x5d, 0x8f, 0x81, 0x31, 0x66, 0xbb, + 0x70, 0xff, 0xf0, 0x39, 0xa6, 0xe4, 0x6b, 0x4c, 0xc9, 0xf7, 0x98, 0x92, 0xa7, 0xdb, 0x56, 0xf8, + 0x97, 0xbe, 0x2a, 0x6a, 0x2d, 0xcb, 0x46, 0xd7, 0xaf, 0x68, 0xf7, 0xc2, 0x8d, 0x28, 0xfd, 0xbb, + 0x41, 0x57, 0xba, 0x37, 0x6e, 0x65, 0x69, 0x7b, 0xe5, 0x85, 0xc4, 0xbb, 0x49, 0xab, 0x45, 0x38, + 0xe4, 0xcd, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x99, 0xa8, 0xd9, 0x9b, 0x58, 0x01, 0x00, 0x00, } diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto index 6d63b7783fd..9ef169046b4 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto +++ b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto @@ -9,6 +9,7 @@ message PluginSpec { string remote = 2; repeated PluginPrivilege privileges = 3; bool disabled = 4; + repeated string env = 5; } // PluginPrivilege describes a permission the user has to accept diff --git a/vendor/github.com/docker/docker/api/types/swarm/service.go b/vendor/github.com/docker/docker/api/types/swarm/service.go index abf192e7594..6eb452d24d1 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/service.go +++ b/vendor/github.com/docker/docker/api/types/swarm/service.go @@ -10,6 +10,17 @@ type Service struct { PreviousSpec *ServiceSpec `json:",omitempty"` Endpoint Endpoint `json:",omitempty"` UpdateStatus *UpdateStatus `json:",omitempty"` + + // ServiceStatus is an optional, extra field indicating the number of + // desired and running tasks. It is provided primarily as a shortcut to + // calculating these values client-side, which otherwise would require + // listing all tasks for a service, an operation that could be + // computation and network expensive. + ServiceStatus *ServiceStatus `json:",omitempty"` + + // JobStatus is the status of a Service which is in one of ReplicatedJob or + // GlobalJob modes. It is absent on Replicated and Global services. + JobStatus *JobStatus `json:",omitempty"` } // ServiceSpec represents the spec of a service. @@ -32,8 +43,10 @@ type ServiceSpec struct { // ServiceMode represents the mode of a service. type ServiceMode struct { - Replicated *ReplicatedService `json:",omitempty"` - Global *GlobalService `json:",omitempty"` + Replicated *ReplicatedService `json:",omitempty"` + Global *GlobalService `json:",omitempty"` + ReplicatedJob *ReplicatedJob `json:",omitempty"` + GlobalJob *GlobalJob `json:",omitempty"` } // UpdateState is the state of a service update. @@ -70,6 +83,32 @@ type ReplicatedService struct { // GlobalService is a kind of ServiceMode. type GlobalService struct{} +// ReplicatedJob is the a type of Service which executes a defined Tasks +// in parallel until the specified number of Tasks have succeeded. +type ReplicatedJob struct { + // MaxConcurrent indicates the maximum number of Tasks that should be + // executing simultaneously for this job at any given time. There may be + // fewer Tasks that MaxConcurrent executing simultaneously; for example, if + // there are fewer than MaxConcurrent tasks needed to reach + // TotalCompletions. + // + // If this field is empty, it will default to a max concurrency of 1. + MaxConcurrent *uint64 `json:",omitempty"` + + // TotalCompletions is the total number of Tasks desired to run to + // completion. + // + // If this field is empty, the value of MaxConcurrent will be used. + TotalCompletions *uint64 `json:",omitempty"` +} + +// GlobalJob is the type of a Service which executes a Task on every Node +// matching the Service's placement constraints. These tasks run to completion +// and then exit. +// +// This type is deliberately empty. +type GlobalJob struct{} + const ( // UpdateFailureActionPause PAUSE UpdateFailureActionPause = "pause" @@ -122,3 +161,42 @@ type UpdateConfig struct { // started, or the new task is started before the old task is shut down. Order string } + +// ServiceStatus represents the number of running tasks in a service and the +// number of tasks desired to be running. +type ServiceStatus struct { + // RunningTasks is the number of tasks for the service actually in the + // Running state + RunningTasks uint64 + + // DesiredTasks is the number of tasks desired to be running by the + // service. For replicated services, this is the replica count. For global + // services, this is computed by taking the number of tasks with desired + // state of not-Shutdown. + DesiredTasks uint64 + + // CompletedTasks is the number of tasks in the state Completed, if this + // service is in ReplicatedJob or GlobalJob mode. This field must be + // cross-referenced with the service type, because the default value of 0 + // may mean that a service is not in a job mode, or it may mean that the + // job has yet to complete any tasks. + CompletedTasks uint64 +} + +// JobStatus is the status of a job-type service. +type JobStatus struct { + // JobIteration is a value increased each time a Job is executed, + // successfully or otherwise. "Executed", in this case, means the job as a + // whole has been started, not that an individual Task has been launched. A + // job is "Executed" when its ServiceSpec is updated. JobIteration can be + // used to disambiguate Tasks belonging to different executions of a job. + // + // Though JobIteration will increase with each subsequent execution, it may + // not necessarily increase by 1, and so JobIteration should not be used to + // keep track of the number of times a job has been executed. + JobIteration Version + + // LastExecution is the time that the job was last executed, as observed by + // Swarm manager. + LastExecution time.Time `json:",omitempty"` +} diff --git a/vendor/github.com/docker/docker/api/types/swarm/task.go b/vendor/github.com/docker/docker/api/types/swarm/task.go index d5a57df5db5..a6f7ab7b5c7 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/task.go +++ b/vendor/github.com/docker/docker/api/types/swarm/task.go @@ -56,6 +56,12 @@ type Task struct { DesiredState TaskState `json:",omitempty"` NetworksAttachments []NetworkAttachment `json:",omitempty"` GenericResources []GenericResource `json:",omitempty"` + + // JobIteration is the JobIteration of the Service that this Task was + // spawned from, if the Service is a ReplicatedJob or GlobalJob. This is + // used to determine which Tasks belong to which run of the job. This field + // is absent if the Service mode is Replicated or Global. + JobIteration *Version `json:",omitempty"` } // TaskSpec represents the spec of a task. @@ -85,13 +91,21 @@ type TaskSpec struct { Runtime RuntimeType `json:",omitempty"` } -// Resources represents resources (CPU/Memory). +// Resources represents resources (CPU/Memory) which can be advertised by a +// node and requested to be reserved for a task. type Resources struct { NanoCPUs int64 `json:",omitempty"` MemoryBytes int64 `json:",omitempty"` GenericResources []GenericResource `json:",omitempty"` } +// Limit describes limits on resources which can be requested by a task. +type Limit struct { + NanoCPUs int64 `json:",omitempty"` + MemoryBytes int64 `json:",omitempty"` + Pids int64 `json:",omitempty"` +} + // GenericResource represents a "user defined" resource which can // be either an integer (e.g: SSD=3) or a string (e.g: SSD=sda1) type GenericResource struct { @@ -119,7 +133,7 @@ type DiscreteGenericResource struct { // ResourceRequirements represents resources requirements. type ResourceRequirements struct { - Limits *Resources `json:",omitempty"` + Limits *Limit `json:",omitempty"` Reservations *Resources `json:",omitempty"` } diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/docker/docker/api/types/types.go index a39ffcb7be2..e3a159912e2 100644 --- a/vendor/github.com/docker/docker/api/types/types.go +++ b/vendor/github.com/docker/docker/api/types/types.go @@ -39,6 +39,7 @@ type ImageInspect struct { Author string Config *container.Config Architecture string + Variant string `json:",omitempty"` Os string OsVersion string `json:",omitempty"` Size int64 @@ -153,11 +154,11 @@ type Info struct { Images int Driver string DriverStatus [][2]string - SystemStatus [][2]string + SystemStatus [][2]string `json:",omitempty"` // SystemStatus is only propagated by the Swarm standalone API Plugins PluginsInfo MemoryLimit bool SwapLimit bool - KernelMemory bool + KernelMemory bool // Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes KernelMemoryTCP bool CPUCfsPeriod bool `json:"CpuCfsPeriod"` CPUCfsQuota bool `json:"CpuCfsQuota"` @@ -174,9 +175,11 @@ type Info struct { SystemTime string LoggingDriver string CgroupDriver string + CgroupVersion string `json:",omitempty"` NEventsListener int KernelVersion string OperatingSystem string + OSVersion string OSType string Architecture string IndexServerAddress string @@ -192,23 +195,24 @@ type Info struct { Labels []string ExperimentalBuild bool ServerVersion string - ClusterStore string - ClusterAdvertise string + ClusterStore string `json:",omitempty"` // Deprecated: host-discovery and overlay networks with external k/v stores are deprecated + ClusterAdvertise string `json:",omitempty"` // Deprecated: host-discovery and overlay networks with external k/v stores are deprecated Runtimes map[string]Runtime DefaultRuntime string Swarm swarm.Info // LiveRestoreEnabled determines whether containers should be kept // running when the daemon is shutdown or upon daemon start if // running containers are detected - LiveRestoreEnabled bool - Isolation container.Isolation - InitBinary string - ContainerdCommit Commit - RuncCommit Commit - InitCommit Commit - SecurityOptions []string - ProductLicense string `json:",omitempty"` - Warnings []string + LiveRestoreEnabled bool + Isolation container.Isolation + InitBinary string + ContainerdCommit Commit + RuncCommit Commit + InitCommit Commit + SecurityOptions []string + ProductLicense string `json:",omitempty"` + DefaultAddressPools []NetworkAddressPool `json:",omitempty"` + Warnings []string } // KeyValue holds a key/value pair @@ -216,6 +220,12 @@ type KeyValue struct { Key, Value string } +// NetworkAddressPool is a temp struct used by Info struct +type NetworkAddressPool struct { + Base string + Size int +} + // SecurityOpt contains the name and options of a security option type SecurityOpt struct { Name string @@ -316,7 +326,7 @@ type ContainerState struct { } // ContainerNode stores information about the node that a container -// is running on. It's only available in Docker Swarm +// is running on. It's only used by the Docker Swarm standalone API type ContainerNode struct { ID string IPAddress string `json:"IP"` @@ -340,7 +350,7 @@ type ContainerJSONBase struct { HostnamePath string HostsPath string LogPath string - Node *ContainerNode `json:",omitempty"` + Node *ContainerNode `json:",omitempty"` // Node is only propagated by Docker Swarm standalone API Name string RestartCount int Driver string @@ -508,6 +518,16 @@ type Checkpoint struct { type Runtime struct { Path string `json:"path"` Args []string `json:"runtimeArgs,omitempty"` + + // This is exposed here only for internal use + // It is not currently supported to specify custom shim configs + Shim *ShimConfig `json:"-"` +} + +// ShimConfig is used by runtime to configure containerd shims +type ShimConfig struct { + Binary string + Opts interface{} } // DiskUsage contains response of Engine API: diff --git a/vendor/github.com/docker/docker/api/types/volume/volume_create.go b/vendor/github.com/docker/docker/api/types/volume/volume_create.go index 700aa804f85..8538078dd66 100644 --- a/vendor/github.com/docker/docker/api/types/volume/volume_create.go +++ b/vendor/github.com/docker/docker/api/types/volume/volume_create.go @@ -1,8 +1,7 @@ package volume // import "github.com/docker/docker/api/types/volume" // ---------------------------------------------------------------------------- -// DO NOT EDIT THIS FILE -// This file was generated by `swagger generate operation` +// Code generated by `swagger generate operation`. DO NOT EDIT. // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/volume/volume_list.go b/vendor/github.com/docker/docker/api/types/volume/volume_list.go index 5a79ad64370..be06179bf48 100644 --- a/vendor/github.com/docker/docker/api/types/volume/volume_list.go +++ b/vendor/github.com/docker/docker/api/types/volume/volume_list.go @@ -1,8 +1,7 @@ package volume // import "github.com/docker/docker/api/types/volume" // ---------------------------------------------------------------------------- -// DO NOT EDIT THIS FILE -// This file was generated by `swagger generate operation` +// Code generated by `swagger generate operation`. DO NOT EDIT. // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/client/client.go b/vendor/github.com/docker/docker/client/client.go index b63d4d6d498..68064ca9c5f 100644 --- a/vendor/github.com/docker/docker/client/client.go +++ b/vendor/github.com/docker/docker/client/client.go @@ -7,8 +7,8 @@ https://docs.docker.com/engine/reference/api/ Usage You use the library by creating a client object and calling methods on it. The -client can be created either from environment variables with NewEnvClient, or -configured manually with NewClient. +client can be created either from environment variables with NewClientWithOpts(client.FromEnv), +or configured manually with NewClient(). For example, to list running containers (the equivalent of "docker ps"): @@ -252,7 +252,8 @@ func (cli *Client) DaemonHost() string { // HTTPClient returns a copy of the HTTP client bound to the server func (cli *Client) HTTPClient() *http.Client { - return &*cli.client + c := *cli.client + return &c } // ParseHostURL parses a url string, validates the string is a host url, and diff --git a/vendor/github.com/docker/docker/client/client_unix.go b/vendor/github.com/docker/docker/client/client_unix.go index 178ff67409a..9d0f0dcbf0b 100644 --- a/vendor/github.com/docker/docker/client/client_unix.go +++ b/vendor/github.com/docker/docker/client/client_unix.go @@ -1,4 +1,4 @@ -// +build linux freebsd openbsd netbsd darwin dragonfly +// +build linux freebsd openbsd netbsd darwin solaris illumos dragonfly package client // import "github.com/docker/docker/client" diff --git a/vendor/github.com/docker/docker/client/container_create.go b/vendor/github.com/docker/docker/client/container_create.go index 5b795e0c17c..b1d5fea5bd5 100644 --- a/vendor/github.com/docker/docker/client/container_create.go +++ b/vendor/github.com/docker/docker/client/container_create.go @@ -5,20 +5,23 @@ import ( "encoding/json" "net/url" + "github.com/containerd/containerd/platforms" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/versions" + specs "github.com/opencontainers/image-spec/specs-go/v1" ) type configWrapper struct { *container.Config HostConfig *container.HostConfig NetworkingConfig *network.NetworkingConfig + Platform *specs.Platform } // ContainerCreate creates a new container based in the given configuration. // It can be associated with a name, but it's not mandatory. -func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (container.ContainerCreateCreatedBody, error) { +func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (container.ContainerCreateCreatedBody, error) { var response container.ContainerCreateCreatedBody if err := cli.NewVersionError("1.25", "stop timeout"); config != nil && config.StopTimeout != nil && err != nil { @@ -30,7 +33,15 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config hostConfig.AutoRemove = false } + if err := cli.NewVersionError("1.41", "specify container image platform"); platform != nil && err != nil { + return response, err + } + query := url.Values{} + if platform != nil { + query.Set("platform", platforms.Format(*platform)) + } + if containerName != "" { query.Set("name", containerName) } diff --git a/vendor/github.com/docker/docker/client/container_list.go b/vendor/github.com/docker/docker/client/container_list.go index 1e7a63a9c06..a973de597fd 100644 --- a/vendor/github.com/docker/docker/client/container_list.go +++ b/vendor/github.com/docker/docker/client/container_list.go @@ -35,6 +35,7 @@ func (cli *Client) ContainerList(ctx context.Context, options types.ContainerLis } if options.Filters.Len() > 0 { + //nolint:staticcheck // ignore SA1019 for old code filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters) if err != nil { diff --git a/vendor/github.com/docker/docker/client/container_stats.go b/vendor/github.com/docker/docker/client/container_stats.go index 6ef44c77480..0a6488dde82 100644 --- a/vendor/github.com/docker/docker/client/container_stats.go +++ b/vendor/github.com/docker/docker/client/container_stats.go @@ -24,3 +24,19 @@ func (cli *Client) ContainerStats(ctx context.Context, containerID string, strea osType := getDockerOS(resp.header.Get("Server")) return types.ContainerStats{Body: resp.body, OSType: osType}, err } + +// ContainerStatsOneShot gets a single stat entry from a container. +// It differs from `ContainerStats` in that the API should not wait to prime the stats +func (cli *Client) ContainerStatsOneShot(ctx context.Context, containerID string) (types.ContainerStats, error) { + query := url.Values{} + query.Set("stream", "0") + query.Set("one-shot", "1") + + resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil) + if err != nil { + return types.ContainerStats{}, err + } + + osType := getDockerOS(resp.header.Get("Server")) + return types.ContainerStats{Body: resp.body, OSType: osType}, err +} diff --git a/vendor/github.com/docker/docker/client/errors.go b/vendor/github.com/docker/docker/client/errors.go index 001c1028814..041bc8d49c4 100644 --- a/vendor/github.com/docker/docker/client/errors.go +++ b/vendor/github.com/docker/docker/client/errors.go @@ -24,8 +24,7 @@ func (err errConnectionFailed) Error() string { // IsErrConnectionFailed returns true if the error is caused by connection failed. func IsErrConnectionFailed(err error) bool { - _, ok := errors.Cause(err).(errConnectionFailed) - return ok + return errors.As(err, &errConnectionFailed{}) } // ErrorConnectionFailed returns an error with host in the error message when connection to docker daemon failed. @@ -42,8 +41,9 @@ type notFound interface { // IsErrNotFound returns true if the error is a NotFound error, which is returned // by the API when some object is not found. func IsErrNotFound(err error) bool { - if _, ok := err.(notFound); ok { - return ok + var e notFound + if errors.As(err, &e) { + return true } return errdefs.IsNotFound(err) } diff --git a/vendor/github.com/docker/docker/client/events.go b/vendor/github.com/docker/docker/client/events.go index 6e56538955e..f0dc9d9e12f 100644 --- a/vendor/github.com/docker/docker/client/events.go +++ b/vendor/github.com/docker/docker/client/events.go @@ -90,6 +90,7 @@ func buildEventsQueryParams(cliVersion string, options types.EventsOptions) (url } if options.Filters.Len() > 0 { + //nolint:staticcheck // ignore SA1019 for old code filterJSON, err := filters.ToParamWithVersion(cliVersion, options.Filters) if err != nil { return nil, err diff --git a/vendor/github.com/docker/docker/client/hijack.go b/vendor/github.com/docker/docker/client/hijack.go index e9c9a752f83..e1dc49ef0f6 100644 --- a/vendor/github.com/docker/docker/client/hijack.go +++ b/vendor/github.com/docker/docker/client/hijack.go @@ -24,7 +24,7 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu } apiPath := cli.getAPIPath(ctx, path, query) - req, err := http.NewRequest("POST", apiPath, bodyEncoded) + req, err := http.NewRequest(http.MethodPost, apiPath, bodyEncoded) if err != nil { return types.HijackedResponse{}, err } @@ -40,7 +40,7 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu // DialHijack returns a hijacked connection with negotiated protocol proto. func (cli *Client) DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error) { - req, err := http.NewRequest("POST", url, nil) + req, err := http.NewRequest(http.MethodPost, url, nil) if err != nil { return nil, err } @@ -87,6 +87,8 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto // Server hijacks the connection, error 'connection closed' expected resp, err := clientconn.Do(req) + + //nolint:staticcheck // ignore SA1019 for connecting to old (pre go1.8) daemons if err != httputil.ErrPersistEOF { if err != nil { return nil, err diff --git a/vendor/github.com/docker/docker/client/image_import.go b/vendor/github.com/docker/docker/client/image_import.go index c2972ea950e..d3336d4106a 100644 --- a/vendor/github.com/docker/docker/client/image_import.go +++ b/vendor/github.com/docker/docker/client/image_import.go @@ -14,7 +14,7 @@ import ( // It returns the JSON content in the response body. func (cli *Client) ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) { if ref != "" { - //Check if the given image name can be resolved + // Check if the given image name can be resolved if _, err := reference.ParseNormalizedNamed(ref); err != nil { return nil, err } diff --git a/vendor/github.com/docker/docker/client/image_list.go b/vendor/github.com/docker/docker/client/image_list.go index 4fa8c006b2e..a4d7505094c 100644 --- a/vendor/github.com/docker/docker/client/image_list.go +++ b/vendor/github.com/docker/docker/client/image_list.go @@ -24,6 +24,7 @@ func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions } } if optionFilters.Len() > 0 { + //nolint:staticcheck // ignore SA1019 for old code filterJSON, err := filters.ToParamWithVersion(cli.version, optionFilters) if err != nil { return images, err diff --git a/vendor/github.com/docker/docker/client/image_push.go b/vendor/github.com/docker/docker/client/image_push.go index 49d412ee375..845580d4a4c 100644 --- a/vendor/github.com/docker/docker/client/image_push.go +++ b/vendor/github.com/docker/docker/client/image_push.go @@ -25,15 +25,14 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options types.Im return nil, errors.New("cannot push a digest reference") } - tag := "" name := reference.FamiliarName(ref) - - if nameTaggedRef, isNamedTagged := ref.(reference.NamedTagged); isNamedTagged { - tag = nameTaggedRef.Tag() - } - query := url.Values{} - query.Set("tag", tag) + if !options.All { + ref = reference.TagNameOnly(ref) + if tagged, ok := ref.(reference.Tagged); ok { + query.Set("tag", tagged.Tag()) + } + } resp, err := cli.tryImagePush(ctx, name, query, options.RegistryAuth) if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { diff --git a/vendor/github.com/docker/docker/client/interface.go b/vendor/github.com/docker/docker/client/interface.go index cde64be4b56..aabad4a9110 100644 --- a/vendor/github.com/docker/docker/client/interface.go +++ b/vendor/github.com/docker/docker/client/interface.go @@ -16,6 +16,7 @@ import ( "github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/swarm" volumetypes "github.com/docker/docker/api/types/volume" + specs "github.com/opencontainers/image-spec/specs-go/v1" ) // CommonAPIClient is the common methods between stable and experimental versions of APIClient. @@ -47,7 +48,7 @@ type CommonAPIClient interface { type ContainerAPIClient interface { ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error) ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.IDResponse, error) - ContainerCreate(ctx context.Context, config *containertypes.Config, hostConfig *containertypes.HostConfig, networkingConfig *networktypes.NetworkingConfig, containerName string) (containertypes.ContainerCreateCreatedBody, error) + ContainerCreate(ctx context.Context, config *containertypes.Config, hostConfig *containertypes.HostConfig, networkingConfig *networktypes.NetworkingConfig, platform *specs.Platform, containerName string) (containertypes.ContainerCreateCreatedBody, error) ContainerDiff(ctx context.Context, container string) ([]containertypes.ContainerChangeResponseItem, error) ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error) ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error) @@ -67,6 +68,7 @@ type ContainerAPIClient interface { ContainerRestart(ctx context.Context, container string, timeout *time.Duration) error ContainerStatPath(ctx context.Context, container, path string) (types.ContainerPathStat, error) ContainerStats(ctx context.Context, container string, stream bool) (types.ContainerStats, error) + ContainerStatsOneShot(ctx context.Context, container string) (types.ContainerStats, error) ContainerStart(ctx context.Context, container string, options types.ContainerStartOptions) error ContainerStop(ctx context.Context, container string, timeout *time.Duration) error ContainerTop(ctx context.Context, container string, arguments []string) (containertypes.ContainerTopOKBody, error) diff --git a/vendor/github.com/docker/docker/client/network_list.go b/vendor/github.com/docker/docker/client/network_list.go index 7130c1364eb..ed2acb55711 100644 --- a/vendor/github.com/docker/docker/client/network_list.go +++ b/vendor/github.com/docker/docker/client/network_list.go @@ -13,6 +13,7 @@ import ( func (cli *Client) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) { query := url.Values{} if options.Filters.Len() > 0 { + //nolint:staticcheck // ignore SA1019 for old code filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters) if err != nil { return nil, err diff --git a/vendor/github.com/docker/docker/client/ping.go b/vendor/github.com/docker/docker/client/ping.go index 90f39ec14f9..a9af001ef46 100644 --- a/vendor/github.com/docker/docker/client/ping.go +++ b/vendor/github.com/docker/docker/client/ping.go @@ -17,9 +17,9 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) { var ping types.Ping // Using cli.buildRequest() + cli.doRequest() instead of cli.sendRequest() - // because ping requests are used during API version negotiation, so we want + // because ping requests are used during API version negotiation, so we want // to hit the non-versioned /_ping endpoint, not /v1.xx/_ping - req, err := cli.buildRequest("HEAD", path.Join(cli.basePath, "/_ping"), nil, nil) + req, err := cli.buildRequest(http.MethodHead, path.Join(cli.basePath, "/_ping"), nil, nil) if err != nil { return ping, err } @@ -35,7 +35,7 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) { return ping, err } - req, err = cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil) + req, err = cli.buildRequest(http.MethodGet, path.Join(cli.basePath, "/_ping"), nil, nil) if err != nil { return ping, err } diff --git a/vendor/github.com/docker/docker/client/plugin_list.go b/vendor/github.com/docker/docker/client/plugin_list.go index 8285cecd6e1..cf1935e2f5e 100644 --- a/vendor/github.com/docker/docker/client/plugin_list.go +++ b/vendor/github.com/docker/docker/client/plugin_list.go @@ -15,6 +15,7 @@ func (cli *Client) PluginList(ctx context.Context, filter filters.Args) (types.P query := url.Values{} if filter.Len() > 0 { + //nolint:staticcheck // ignore SA1019 for old code filterJSON, err := filters.ToParamWithVersion(cli.version, filter) if err != nil { return plugins, err diff --git a/vendor/github.com/docker/docker/client/request.go b/vendor/github.com/docker/docker/client/request.go index 44e0a22c4f6..813eac2c9e0 100644 --- a/vendor/github.com/docker/docker/client/request.go +++ b/vendor/github.com/docker/docker/client/request.go @@ -29,12 +29,12 @@ type serverResponse struct { // head sends an http request to the docker API using the method HEAD. func (cli *Client) head(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) { - return cli.sendRequest(ctx, "HEAD", path, query, nil, headers) + return cli.sendRequest(ctx, http.MethodHead, path, query, nil, headers) } // get sends an http request to the docker API using the method GET with a specific Go context. func (cli *Client) get(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) { - return cli.sendRequest(ctx, "GET", path, query, nil, headers) + return cli.sendRequest(ctx, http.MethodGet, path, query, nil, headers) } // post sends an http request to the docker API using the method POST with a specific Go context. @@ -43,30 +43,21 @@ func (cli *Client) post(ctx context.Context, path string, query url.Values, obj if err != nil { return serverResponse{}, err } - return cli.sendRequest(ctx, "POST", path, query, body, headers) + return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers) } func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) { - return cli.sendRequest(ctx, "POST", path, query, body, headers) -} - -// put sends an http request to the docker API using the method PUT. -func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) { - body, headers, err := encodeBody(obj, headers) - if err != nil { - return serverResponse{}, err - } - return cli.sendRequest(ctx, "PUT", path, query, body, headers) + return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers) } // putRaw sends an http request to the docker API using the method PUT. func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) { - return cli.sendRequest(ctx, "PUT", path, query, body, headers) + return cli.sendRequest(ctx, http.MethodPut, path, query, body, headers) } // delete sends an http request to the docker API using the method DELETE. func (cli *Client) delete(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) { - return cli.sendRequest(ctx, "DELETE", path, query, nil, headers) + return cli.sendRequest(ctx, http.MethodDelete, path, query, nil, headers) } type headers map[string][]string @@ -88,7 +79,7 @@ func encodeBody(obj interface{}, headers headers) (io.Reader, headers, error) { } func (cli *Client) buildRequest(method, path string, body io.Reader, headers headers) (*http.Request, error) { - expectedPayload := (method == "POST" || method == "PUT") + expectedPayload := (method == http.MethodPost || method == http.MethodPut) if expectedPayload && body == nil { body = bytes.NewReader([]byte{}) } diff --git a/vendor/github.com/docker/docker/client/service_create.go b/vendor/github.com/docker/docker/client/service_create.go index 620fc6cff75..e0428bf98b3 100644 --- a/vendor/github.com/docker/docker/client/service_create.go +++ b/vendor/github.com/docker/docker/client/service_create.go @@ -9,14 +9,13 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" - "github.com/opencontainers/go-digest" + digest "github.com/opencontainers/go-digest" "github.com/pkg/errors" ) // ServiceCreate creates a new Service. func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (types.ServiceCreateResponse, error) { - var distErr error - + var response types.ServiceCreateResponse headers := map[string][]string{ "version": {cli.version}, } @@ -31,46 +30,28 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, } if err := validateServiceSpec(service); err != nil { - return types.ServiceCreateResponse{}, err + return response, err } // ensure that the image is tagged - var imgPlatforms []swarm.Platform - if service.TaskTemplate.ContainerSpec != nil { + var resolveWarning string + switch { + case service.TaskTemplate.ContainerSpec != nil: if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" { service.TaskTemplate.ContainerSpec.Image = taggedImg } if options.QueryRegistry { - var img string - img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.ContainerSpec.Image, options.EncodedRegistryAuth) - if img != "" { - service.TaskTemplate.ContainerSpec.Image = img - } + resolveWarning = resolveContainerSpecImage(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth) } - } - - // ensure that the image is tagged - if service.TaskTemplate.PluginSpec != nil { + case service.TaskTemplate.PluginSpec != nil: if taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != "" { service.TaskTemplate.PluginSpec.Remote = taggedImg } if options.QueryRegistry { - var img string - img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.PluginSpec.Remote, options.EncodedRegistryAuth) - if img != "" { - service.TaskTemplate.PluginSpec.Remote = img - } + resolveWarning = resolvePluginSpecRemote(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth) } } - if service.TaskTemplate.Placement == nil && len(imgPlatforms) > 0 { - service.TaskTemplate.Placement = &swarm.Placement{} - } - if len(imgPlatforms) > 0 { - service.TaskTemplate.Placement.Platforms = imgPlatforms - } - - var response types.ServiceCreateResponse resp, err := cli.post(ctx, "/services/create", nil, service, headers) defer ensureReaderClosed(resp) if err != nil { @@ -78,14 +59,45 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, } err = json.NewDecoder(resp.body).Decode(&response) - - if distErr != nil { - response.Warnings = append(response.Warnings, digestWarning(service.TaskTemplate.ContainerSpec.Image)) + if resolveWarning != "" { + response.Warnings = append(response.Warnings, resolveWarning) } return response, err } +func resolveContainerSpecImage(ctx context.Context, cli DistributionAPIClient, taskSpec *swarm.TaskSpec, encodedAuth string) string { + var warning string + if img, imgPlatforms, err := imageDigestAndPlatforms(ctx, cli, taskSpec.ContainerSpec.Image, encodedAuth); err != nil { + warning = digestWarning(taskSpec.ContainerSpec.Image) + } else { + taskSpec.ContainerSpec.Image = img + if len(imgPlatforms) > 0 { + if taskSpec.Placement == nil { + taskSpec.Placement = &swarm.Placement{} + } + taskSpec.Placement.Platforms = imgPlatforms + } + } + return warning +} + +func resolvePluginSpecRemote(ctx context.Context, cli DistributionAPIClient, taskSpec *swarm.TaskSpec, encodedAuth string) string { + var warning string + if img, imgPlatforms, err := imageDigestAndPlatforms(ctx, cli, taskSpec.PluginSpec.Remote, encodedAuth); err != nil { + warning = digestWarning(taskSpec.PluginSpec.Remote) + } else { + taskSpec.PluginSpec.Remote = img + if len(imgPlatforms) > 0 { + if taskSpec.Placement == nil { + taskSpec.Placement = &swarm.Placement{} + } + taskSpec.Placement.Platforms = imgPlatforms + } + } + return warning +} + func imageDigestAndPlatforms(ctx context.Context, cli DistributionAPIClient, image, encodedAuth string) (string, []swarm.Platform, error) { distributionInspect, err := cli.DistributionInspect(ctx, image, encodedAuth) var platforms []swarm.Platform @@ -119,7 +131,7 @@ func imageDigestAndPlatforms(ctx context.Context, cli DistributionAPIClient, ima // imageWithDigestString takes an image string and a digest, and updates // the image string if it didn't originally contain a digest. It returns -// an empty string if there are no updates. +// image unmodified in other situations. func imageWithDigestString(image string, dgst digest.Digest) string { namedRef, err := reference.ParseNormalizedNamed(image) if err == nil { @@ -131,7 +143,7 @@ func imageWithDigestString(image string, dgst digest.Digest) string { } } } - return "" + return image } // imageWithTagString takes an image string, and returns a tagged image diff --git a/vendor/github.com/docker/docker/client/service_list.go b/vendor/github.com/docker/docker/client/service_list.go index 64d35e71598..f97ec75a5cb 100644 --- a/vendor/github.com/docker/docker/client/service_list.go +++ b/vendor/github.com/docker/docker/client/service_list.go @@ -23,6 +23,10 @@ func (cli *Client) ServiceList(ctx context.Context, options types.ServiceListOpt query.Set("filters", filterJSON) } + if options.Status { + query.Set("status", "true") + } + resp, err := cli.get(ctx, "/services", query, nil) defer ensureReaderClosed(resp) if err != nil { diff --git a/vendor/github.com/docker/docker/client/service_update.go b/vendor/github.com/docker/docker/client/service_update.go index cd0f59e2133..c63895f74f2 100644 --- a/vendor/github.com/docker/docker/client/service_update.go +++ b/vendor/github.com/docker/docker/client/service_update.go @@ -15,8 +15,8 @@ import ( // of swarm.Service, which can be found using ServiceInspectWithRaw. func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) { var ( - query = url.Values{} - distErr error + query = url.Values{} + response = types.ServiceUpdateResponse{} ) headers := map[string][]string{ @@ -38,46 +38,28 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version query.Set("version", strconv.FormatUint(version.Index, 10)) if err := validateServiceSpec(service); err != nil { - return types.ServiceUpdateResponse{}, err + return response, err } - var imgPlatforms []swarm.Platform // ensure that the image is tagged - if service.TaskTemplate.ContainerSpec != nil { + var resolveWarning string + switch { + case service.TaskTemplate.ContainerSpec != nil: if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" { service.TaskTemplate.ContainerSpec.Image = taggedImg } if options.QueryRegistry { - var img string - img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.ContainerSpec.Image, options.EncodedRegistryAuth) - if img != "" { - service.TaskTemplate.ContainerSpec.Image = img - } + resolveWarning = resolveContainerSpecImage(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth) } - } - - // ensure that the image is tagged - if service.TaskTemplate.PluginSpec != nil { + case service.TaskTemplate.PluginSpec != nil: if taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != "" { service.TaskTemplate.PluginSpec.Remote = taggedImg } if options.QueryRegistry { - var img string - img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.PluginSpec.Remote, options.EncodedRegistryAuth) - if img != "" { - service.TaskTemplate.PluginSpec.Remote = img - } + resolveWarning = resolvePluginSpecRemote(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth) } } - if service.TaskTemplate.Placement == nil && len(imgPlatforms) > 0 { - service.TaskTemplate.Placement = &swarm.Placement{} - } - if len(imgPlatforms) > 0 { - service.TaskTemplate.Placement.Platforms = imgPlatforms - } - - var response types.ServiceUpdateResponse resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, service, headers) defer ensureReaderClosed(resp) if err != nil { @@ -85,9 +67,8 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version } err = json.NewDecoder(resp.body).Decode(&response) - - if distErr != nil { - response.Warnings = append(response.Warnings, digestWarning(service.TaskTemplate.ContainerSpec.Image)) + if resolveWarning != "" { + response.Warnings = append(response.Warnings, resolveWarning) } return response, err diff --git a/vendor/github.com/docker/docker/client/volume_list.go b/vendor/github.com/docker/docker/client/volume_list.go index 2380d563821..942498dde2c 100644 --- a/vendor/github.com/docker/docker/client/volume_list.go +++ b/vendor/github.com/docker/docker/client/volume_list.go @@ -15,6 +15,7 @@ func (cli *Client) VolumeList(ctx context.Context, filter filters.Args) (volumet query := url.Values{} if filter.Len() > 0 { + //nolint:staticcheck // ignore SA1019 for old code filterJSON, err := filters.ToParamWithVersion(cli.version, filter) if err != nil { return volumes, err diff --git a/vendor/github.com/docker/docker/errdefs/helpers.go b/vendor/github.com/docker/docker/errdefs/helpers.go index c9916e01354..fe06fb6f703 100644 --- a/vendor/github.com/docker/docker/errdefs/helpers.go +++ b/vendor/github.com/docker/docker/errdefs/helpers.go @@ -10,6 +10,10 @@ func (e errNotFound) Cause() error { return e.error } +func (e errNotFound) Unwrap() error { + return e.error +} + // NotFound is a helper to create an error of the class with the same name from any error type func NotFound(err error) error { if err == nil || IsNotFound(err) { @@ -26,6 +30,10 @@ func (e errInvalidParameter) Cause() error { return e.error } +func (e errInvalidParameter) Unwrap() error { + return e.error +} + // InvalidParameter is a helper to create an error of the class with the same name from any error type func InvalidParameter(err error) error { if err == nil || IsInvalidParameter(err) { @@ -42,6 +50,10 @@ func (e errConflict) Cause() error { return e.error } +func (e errConflict) Unwrap() error { + return e.error +} + // Conflict is a helper to create an error of the class with the same name from any error type func Conflict(err error) error { if err == nil || IsConflict(err) { @@ -58,6 +70,10 @@ func (e errUnauthorized) Cause() error { return e.error } +func (e errUnauthorized) Unwrap() error { + return e.error +} + // Unauthorized is a helper to create an error of the class with the same name from any error type func Unauthorized(err error) error { if err == nil || IsUnauthorized(err) { @@ -74,6 +90,10 @@ func (e errUnavailable) Cause() error { return e.error } +func (e errUnavailable) Unwrap() error { + return e.error +} + // Unavailable is a helper to create an error of the class with the same name from any error type func Unavailable(err error) error { if err == nil || IsUnavailable(err) { @@ -90,6 +110,10 @@ func (e errForbidden) Cause() error { return e.error } +func (e errForbidden) Unwrap() error { + return e.error +} + // Forbidden is a helper to create an error of the class with the same name from any error type func Forbidden(err error) error { if err == nil || IsForbidden(err) { @@ -106,6 +130,10 @@ func (e errSystem) Cause() error { return e.error } +func (e errSystem) Unwrap() error { + return e.error +} + // System is a helper to create an error of the class with the same name from any error type func System(err error) error { if err == nil || IsSystem(err) { @@ -122,6 +150,10 @@ func (e errNotModified) Cause() error { return e.error } +func (e errNotModified) Unwrap() error { + return e.error +} + // NotModified is a helper to create an error of the class with the same name from any error type func NotModified(err error) error { if err == nil || IsNotModified(err) { @@ -138,6 +170,10 @@ func (e errNotImplemented) Cause() error { return e.error } +func (e errNotImplemented) Unwrap() error { + return e.error +} + // NotImplemented is a helper to create an error of the class with the same name from any error type func NotImplemented(err error) error { if err == nil || IsNotImplemented(err) { @@ -154,6 +190,10 @@ func (e errUnknown) Cause() error { return e.error } +func (e errUnknown) Unwrap() error { + return e.error +} + // Unknown is a helper to create an error of the class with the same name from any error type func Unknown(err error) error { if err == nil || IsUnknown(err) { @@ -170,6 +210,10 @@ func (e errCancelled) Cause() error { return e.error } +func (e errCancelled) Unwrap() error { + return e.error +} + // Cancelled is a helper to create an error of the class with the same name from any error type func Cancelled(err error) error { if err == nil || IsCancelled(err) { @@ -186,6 +230,10 @@ func (e errDeadline) Cause() error { return e.error } +func (e errDeadline) Unwrap() error { + return e.error +} + // Deadline is a helper to create an error of the class with the same name from any error type func Deadline(err error) error { if err == nil || IsDeadline(err) { @@ -202,6 +250,10 @@ func (e errDataLoss) Cause() error { return e.error } +func (e errDataLoss) Unwrap() error { + return e.error +} + // DataLoss is a helper to create an error of the class with the same name from any error type func DataLoss(err error) error { if err == nil || IsDataLoss(err) { diff --git a/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go b/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go index a68b566cea2..cf8d04b1b20 100644 --- a/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go +++ b/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go @@ -7,8 +7,8 @@ import ( "strings" "time" - "github.com/docker/docker/pkg/term" - "github.com/docker/go-units" + units "github.com/docker/go-units" + "github.com/moby/term" "github.com/morikuni/aec" ) @@ -139,13 +139,13 @@ type JSONMessage struct { Stream string `json:"stream,omitempty"` Status string `json:"status,omitempty"` Progress *JSONProgress `json:"progressDetail,omitempty"` - ProgressMessage string `json:"progress,omitempty"` //deprecated + ProgressMessage string `json:"progress,omitempty"` // deprecated ID string `json:"id,omitempty"` From string `json:"from,omitempty"` Time int64 `json:"time,omitempty"` TimeNano int64 `json:"timeNano,omitempty"` Error *JSONError `json:"errorDetail,omitempty"` - ErrorMessage string `json:"error,omitempty"` //deprecated + ErrorMessage string `json:"error,omitempty"` // deprecated // Aux contains out-of-band data, such as digests for push signing and image id after building. Aux *json.RawMessage `json:"aux,omitempty"` } @@ -177,8 +177,8 @@ func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error { if isTerminal && jm.Stream == "" && jm.Progress != nil { clearLine(out) endl = "\r" - fmt.Fprintf(out, endl) - } else if jm.Progress != nil && jm.Progress.String() != "" { //disable progressbar in non-terminal + fmt.Fprint(out, endl) + } else if jm.Progress != nil && jm.Progress.String() != "" { // disable progressbar in non-terminal return nil } if jm.TimeNano != 0 { @@ -194,7 +194,7 @@ func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error { } if jm.Progress != nil && isTerminal { fmt.Fprintf(out, "%s %s%s", jm.Status, jm.Progress.String(), endl) - } else if jm.ProgressMessage != "" { //deprecated + } else if jm.ProgressMessage != "" { // deprecated fmt.Fprintf(out, "%s %s%s", jm.Status, jm.ProgressMessage, endl) } else if jm.Stream != "" { fmt.Fprintf(out, "%s%s", jm.Stream, endl) diff --git a/vendor/github.com/docker/docker/pkg/term/ascii.go b/vendor/github.com/docker/docker/pkg/term/ascii.go deleted file mode 100644 index 87bca8d4acd..00000000000 --- a/vendor/github.com/docker/docker/pkg/term/ascii.go +++ /dev/null @@ -1,66 +0,0 @@ -package term // import "github.com/docker/docker/pkg/term" - -import ( - "fmt" - "strings" -) - -// ASCII list the possible supported ASCII key sequence -var ASCII = []string{ - "ctrl-@", - "ctrl-a", - "ctrl-b", - "ctrl-c", - "ctrl-d", - "ctrl-e", - "ctrl-f", - "ctrl-g", - "ctrl-h", - "ctrl-i", - "ctrl-j", - "ctrl-k", - "ctrl-l", - "ctrl-m", - "ctrl-n", - "ctrl-o", - "ctrl-p", - "ctrl-q", - "ctrl-r", - "ctrl-s", - "ctrl-t", - "ctrl-u", - "ctrl-v", - "ctrl-w", - "ctrl-x", - "ctrl-y", - "ctrl-z", - "ctrl-[", - "ctrl-\\", - "ctrl-]", - "ctrl-^", - "ctrl-_", -} - -// ToBytes converts a string representing a suite of key-sequence to the corresponding ASCII code. -func ToBytes(keys string) ([]byte, error) { - codes := []byte{} -next: - for _, key := range strings.Split(keys, ",") { - if len(key) != 1 { - for code, ctrl := range ASCII { - if ctrl == key { - codes = append(codes, byte(code)) - continue next - } - } - if key == "DEL" { - codes = append(codes, 127) - } else { - return nil, fmt.Errorf("Unknown character: '%s'", key) - } - } else { - codes = append(codes, key[0]) - } - } - return codes, nil -} diff --git a/vendor/github.com/docker/docker/pkg/term/proxy.go b/vendor/github.com/docker/docker/pkg/term/proxy.go deleted file mode 100644 index da733e58484..00000000000 --- a/vendor/github.com/docker/docker/pkg/term/proxy.go +++ /dev/null @@ -1,78 +0,0 @@ -package term // import "github.com/docker/docker/pkg/term" - -import ( - "io" -) - -// EscapeError is special error which returned by a TTY proxy reader's Read() -// method in case its detach escape sequence is read. -type EscapeError struct{} - -func (EscapeError) Error() string { - return "read escape sequence" -} - -// escapeProxy is used only for attaches with a TTY. It is used to proxy -// stdin keypresses from the underlying reader and look for the passed in -// escape key sequence to signal a detach. -type escapeProxy struct { - escapeKeys []byte - escapeKeyPos int - r io.Reader -} - -// NewEscapeProxy returns a new TTY proxy reader which wraps the given reader -// and detects when the specified escape keys are read, in which case the Read -// method will return an error of type EscapeError. -func NewEscapeProxy(r io.Reader, escapeKeys []byte) io.Reader { - return &escapeProxy{ - escapeKeys: escapeKeys, - r: r, - } -} - -func (r *escapeProxy) Read(buf []byte) (int, error) { - nr, err := r.r.Read(buf) - - if len(r.escapeKeys) == 0 { - return nr, err - } - - preserve := func() { - // this preserves the original key presses in the passed in buffer - nr += r.escapeKeyPos - preserve := make([]byte, 0, r.escapeKeyPos+len(buf)) - preserve = append(preserve, r.escapeKeys[:r.escapeKeyPos]...) - preserve = append(preserve, buf...) - r.escapeKeyPos = 0 - copy(buf[0:nr], preserve) - } - - if nr != 1 || err != nil { - if r.escapeKeyPos > 0 { - preserve() - } - return nr, err - } - - if buf[0] != r.escapeKeys[r.escapeKeyPos] { - if r.escapeKeyPos > 0 { - preserve() - } - return nr, nil - } - - if r.escapeKeyPos == len(r.escapeKeys)-1 { - return 0, EscapeError{} - } - - // Looks like we've got an escape key, but we need to match again on the next - // read. - // Store the current escape key we found so we can look for the next one on - // the next read. - // Since this is an escape key, make sure we don't let the caller read it - // If later on we find that this is not the escape sequence, we'll add the - // keys back - r.escapeKeyPos++ - return nr - r.escapeKeyPos, nil -} diff --git a/vendor/github.com/docker/docker/pkg/term/tc.go b/vendor/github.com/docker/docker/pkg/term/tc.go deleted file mode 100644 index 01bcaa8abb1..00000000000 --- a/vendor/github.com/docker/docker/pkg/term/tc.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build !windows - -package term // import "github.com/docker/docker/pkg/term" - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/unix" -) - -func tcget(fd uintptr, p *Termios) syscall.Errno { - _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(p))) - return err -} - -func tcset(fd uintptr, p *Termios) syscall.Errno { - _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(p))) - return err -} diff --git a/vendor/github.com/docker/docker/pkg/term/term.go b/vendor/github.com/docker/docker/pkg/term/term.go deleted file mode 100644 index 0589a955194..00000000000 --- a/vendor/github.com/docker/docker/pkg/term/term.go +++ /dev/null @@ -1,124 +0,0 @@ -// +build !windows - -// Package term provides structures and helper functions to work with -// terminal (state, sizes). -package term // import "github.com/docker/docker/pkg/term" - -import ( - "errors" - "fmt" - "io" - "os" - "os/signal" - - "golang.org/x/sys/unix" -) - -var ( - // ErrInvalidState is returned if the state of the terminal is invalid. - ErrInvalidState = errors.New("Invalid terminal state") -) - -// State represents the state of the terminal. -type State struct { - termios Termios -} - -// Winsize represents the size of the terminal window. -type Winsize struct { - Height uint16 - Width uint16 - x uint16 - y uint16 -} - -// StdStreams returns the standard streams (stdin, stdout, stderr). -func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { - return os.Stdin, os.Stdout, os.Stderr -} - -// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal. -func GetFdInfo(in interface{}) (uintptr, bool) { - var inFd uintptr - var isTerminalIn bool - if file, ok := in.(*os.File); ok { - inFd = file.Fd() - isTerminalIn = IsTerminal(inFd) - } - return inFd, isTerminalIn -} - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal(fd uintptr) bool { - var termios Termios - return tcget(fd, &termios) == 0 -} - -// RestoreTerminal restores the terminal connected to the given file descriptor -// to a previous state. -func RestoreTerminal(fd uintptr, state *State) error { - if state == nil { - return ErrInvalidState - } - if err := tcset(fd, &state.termios); err != 0 { - return err - } - return nil -} - -// SaveState saves the state of the terminal connected to the given file descriptor. -func SaveState(fd uintptr) (*State, error) { - var oldState State - if err := tcget(fd, &oldState.termios); err != 0 { - return nil, err - } - - return &oldState, nil -} - -// DisableEcho applies the specified state to the terminal connected to the file -// descriptor, with echo disabled. -func DisableEcho(fd uintptr, state *State) error { - newState := state.termios - newState.Lflag &^= unix.ECHO - - if err := tcset(fd, &newState); err != 0 { - return err - } - handleInterrupt(fd, state) - return nil -} - -// SetRawTerminal puts the terminal connected to the given file descriptor into -// raw mode and returns the previous state. On UNIX, this puts both the input -// and output into raw mode. On Windows, it only puts the input into raw mode. -func SetRawTerminal(fd uintptr) (*State, error) { - oldState, err := MakeRaw(fd) - if err != nil { - return nil, err - } - handleInterrupt(fd, oldState) - return oldState, err -} - -// SetRawTerminalOutput puts the output of terminal connected to the given file -// descriptor into raw mode. On UNIX, this does nothing and returns nil for the -// state. On Windows, it disables LF -> CRLF translation. -func SetRawTerminalOutput(fd uintptr) (*State, error) { - return nil, nil -} - -func handleInterrupt(fd uintptr, state *State) { - sigchan := make(chan os.Signal, 1) - signal.Notify(sigchan, os.Interrupt) - go func() { - for range sigchan { - // quit cleanly and the new terminal item is on a new line - fmt.Println() - signal.Stop(sigchan) - close(sigchan) - RestoreTerminal(fd, state) - os.Exit(1) - } - }() -} diff --git a/vendor/github.com/docker/docker/pkg/term/term_windows.go b/vendor/github.com/docker/docker/pkg/term/term_windows.go deleted file mode 100644 index a3c3db13157..00000000000 --- a/vendor/github.com/docker/docker/pkg/term/term_windows.go +++ /dev/null @@ -1,221 +0,0 @@ -package term // import "github.com/docker/docker/pkg/term" - -import ( - "io" - "os" - "os/signal" - "syscall" // used for STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and STD_ERROR_HANDLE - - "github.com/Azure/go-ansiterm/winterm" - "github.com/docker/docker/pkg/term/windows" -) - -// State holds the console mode for the terminal. -type State struct { - mode uint32 -} - -// Winsize is used for window size. -type Winsize struct { - Height uint16 - Width uint16 -} - -// vtInputSupported is true if winterm.ENABLE_VIRTUAL_TERMINAL_INPUT is supported by the console -var vtInputSupported bool - -// StdStreams returns the standard streams (stdin, stdout, stderr). -func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { - // Turn on VT handling on all std handles, if possible. This might - // fail, in which case we will fall back to terminal emulation. - var emulateStdin, emulateStdout, emulateStderr bool - fd := os.Stdin.Fd() - if mode, err := winterm.GetConsoleMode(fd); err == nil { - // Validate that winterm.ENABLE_VIRTUAL_TERMINAL_INPUT is supported, but do not set it. - if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_INPUT); err != nil { - emulateStdin = true - } else { - vtInputSupported = true - } - // Unconditionally set the console mode back even on failure because SetConsoleMode - // remembers invalid bits on input handles. - winterm.SetConsoleMode(fd, mode) - } - - fd = os.Stdout.Fd() - if mode, err := winterm.GetConsoleMode(fd); err == nil { - // Validate winterm.DISABLE_NEWLINE_AUTO_RETURN is supported, but do not set it. - if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING|winterm.DISABLE_NEWLINE_AUTO_RETURN); err != nil { - emulateStdout = true - } else { - winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING) - } - } - - fd = os.Stderr.Fd() - if mode, err := winterm.GetConsoleMode(fd); err == nil { - // Validate winterm.DISABLE_NEWLINE_AUTO_RETURN is supported, but do not set it. - if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING|winterm.DISABLE_NEWLINE_AUTO_RETURN); err != nil { - emulateStderr = true - } else { - winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING) - } - } - - // Temporarily use STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and - // STD_ERROR_HANDLE from syscall rather than x/sys/windows as long as - // go-ansiterm hasn't switch to x/sys/windows. - // TODO: switch back to x/sys/windows once go-ansiterm has switched - if emulateStdin { - stdIn = windowsconsole.NewAnsiReader(syscall.STD_INPUT_HANDLE) - } else { - stdIn = os.Stdin - } - - if emulateStdout { - stdOut = windowsconsole.NewAnsiWriter(syscall.STD_OUTPUT_HANDLE) - } else { - stdOut = os.Stdout - } - - if emulateStderr { - stdErr = windowsconsole.NewAnsiWriter(syscall.STD_ERROR_HANDLE) - } else { - stdErr = os.Stderr - } - - return -} - -// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal. -func GetFdInfo(in interface{}) (uintptr, bool) { - return windowsconsole.GetHandleInfo(in) -} - -// GetWinsize returns the window size based on the specified file descriptor. -func GetWinsize(fd uintptr) (*Winsize, error) { - info, err := winterm.GetConsoleScreenBufferInfo(fd) - if err != nil { - return nil, err - } - - winsize := &Winsize{ - Width: uint16(info.Window.Right - info.Window.Left + 1), - Height: uint16(info.Window.Bottom - info.Window.Top + 1), - } - - return winsize, nil -} - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal(fd uintptr) bool { - return windowsconsole.IsConsole(fd) -} - -// RestoreTerminal restores the terminal connected to the given file descriptor -// to a previous state. -func RestoreTerminal(fd uintptr, state *State) error { - return winterm.SetConsoleMode(fd, state.mode) -} - -// SaveState saves the state of the terminal connected to the given file descriptor. -func SaveState(fd uintptr) (*State, error) { - mode, e := winterm.GetConsoleMode(fd) - if e != nil { - return nil, e - } - - return &State{mode: mode}, nil -} - -// DisableEcho disables echo for the terminal connected to the given file descriptor. -// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx -func DisableEcho(fd uintptr, state *State) error { - mode := state.mode - mode &^= winterm.ENABLE_ECHO_INPUT - mode |= winterm.ENABLE_PROCESSED_INPUT | winterm.ENABLE_LINE_INPUT - err := winterm.SetConsoleMode(fd, mode) - if err != nil { - return err - } - - // Register an interrupt handler to catch and restore prior state - restoreAtInterrupt(fd, state) - return nil -} - -// SetRawTerminal puts the terminal connected to the given file descriptor into -// raw mode and returns the previous state. On UNIX, this puts both the input -// and output into raw mode. On Windows, it only puts the input into raw mode. -func SetRawTerminal(fd uintptr) (*State, error) { - state, err := MakeRaw(fd) - if err != nil { - return nil, err - } - - // Register an interrupt handler to catch and restore prior state - restoreAtInterrupt(fd, state) - return state, err -} - -// SetRawTerminalOutput puts the output of terminal connected to the given file -// descriptor into raw mode. On UNIX, this does nothing and returns nil for the -// state. On Windows, it disables LF -> CRLF translation. -func SetRawTerminalOutput(fd uintptr) (*State, error) { - state, err := SaveState(fd) - if err != nil { - return nil, err - } - - // Ignore failures, since winterm.DISABLE_NEWLINE_AUTO_RETURN might not be supported on this - // version of Windows. - winterm.SetConsoleMode(fd, state.mode|winterm.DISABLE_NEWLINE_AUTO_RETURN) - return state, err -} - -// MakeRaw puts the terminal (Windows Console) connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be restored. -func MakeRaw(fd uintptr) (*State, error) { - state, err := SaveState(fd) - if err != nil { - return nil, err - } - - mode := state.mode - - // See - // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx - // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx - - // Disable these modes - mode &^= winterm.ENABLE_ECHO_INPUT - mode &^= winterm.ENABLE_LINE_INPUT - mode &^= winterm.ENABLE_MOUSE_INPUT - mode &^= winterm.ENABLE_WINDOW_INPUT - mode &^= winterm.ENABLE_PROCESSED_INPUT - - // Enable these modes - mode |= winterm.ENABLE_EXTENDED_FLAGS - mode |= winterm.ENABLE_INSERT_MODE - mode |= winterm.ENABLE_QUICK_EDIT_MODE - if vtInputSupported { - mode |= winterm.ENABLE_VIRTUAL_TERMINAL_INPUT - } - - err = winterm.SetConsoleMode(fd, mode) - if err != nil { - return nil, err - } - return state, nil -} - -func restoreAtInterrupt(fd uintptr, state *State) { - sigchan := make(chan os.Signal, 1) - signal.Notify(sigchan, os.Interrupt) - - go func() { - _ = <-sigchan - RestoreTerminal(fd, state) - os.Exit(0) - }() -} diff --git a/vendor/github.com/docker/docker/pkg/term/termios_bsd.go b/vendor/github.com/docker/docker/pkg/term/termios_bsd.go deleted file mode 100644 index 48b16f52039..00000000000 --- a/vendor/github.com/docker/docker/pkg/term/termios_bsd.go +++ /dev/null @@ -1,42 +0,0 @@ -// +build darwin freebsd openbsd netbsd - -package term // import "github.com/docker/docker/pkg/term" - -import ( - "unsafe" - - "golang.org/x/sys/unix" -) - -const ( - getTermios = unix.TIOCGETA - setTermios = unix.TIOCSETA -) - -// Termios is the Unix API for terminal I/O. -type Termios unix.Termios - -// MakeRaw put the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd uintptr) (*State, error) { - var oldState State - if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { - return nil, err - } - - newState := oldState.termios - newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON) - newState.Oflag &^= unix.OPOST - newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN) - newState.Cflag &^= (unix.CSIZE | unix.PARENB) - newState.Cflag |= unix.CS8 - newState.Cc[unix.VMIN] = 1 - newState.Cc[unix.VTIME] = 0 - - if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 { - return nil, err - } - - return &oldState, nil -} diff --git a/vendor/github.com/docker/docker/pkg/term/termios_linux.go b/vendor/github.com/docker/docker/pkg/term/termios_linux.go deleted file mode 100644 index 6d4c63fdb75..00000000000 --- a/vendor/github.com/docker/docker/pkg/term/termios_linux.go +++ /dev/null @@ -1,39 +0,0 @@ -package term // import "github.com/docker/docker/pkg/term" - -import ( - "golang.org/x/sys/unix" -) - -const ( - getTermios = unix.TCGETS - setTermios = unix.TCSETS -) - -// Termios is the Unix API for terminal I/O. -type Termios unix.Termios - -// MakeRaw put the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd uintptr) (*State, error) { - termios, err := unix.IoctlGetTermios(int(fd), getTermios) - if err != nil { - return nil, err - } - - var oldState State - oldState.termios = Termios(*termios) - - termios.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON) - termios.Oflag &^= unix.OPOST - termios.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN) - termios.Cflag &^= (unix.CSIZE | unix.PARENB) - termios.Cflag |= unix.CS8 - termios.Cc[unix.VMIN] = 1 - termios.Cc[unix.VTIME] = 0 - - if err := unix.IoctlSetTermios(int(fd), setTermios, termios); err != nil { - return nil, err - } - return &oldState, nil -} diff --git a/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go b/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go deleted file mode 100644 index 1d7c452cc84..00000000000 --- a/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go +++ /dev/null @@ -1,263 +0,0 @@ -// +build windows - -package windowsconsole // import "github.com/docker/docker/pkg/term/windows" - -import ( - "bytes" - "errors" - "fmt" - "io" - "os" - "strings" - "unsafe" - - ansiterm "github.com/Azure/go-ansiterm" - "github.com/Azure/go-ansiterm/winterm" -) - -const ( - escapeSequence = ansiterm.KEY_ESC_CSI -) - -// ansiReader wraps a standard input file (e.g., os.Stdin) providing ANSI sequence translation. -type ansiReader struct { - file *os.File - fd uintptr - buffer []byte - cbBuffer int - command []byte -} - -// NewAnsiReader returns an io.ReadCloser that provides VT100 terminal emulation on top of a -// Windows console input handle. -func NewAnsiReader(nFile int) io.ReadCloser { - initLogger() - file, fd := winterm.GetStdFile(nFile) - return &ansiReader{ - file: file, - fd: fd, - command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH), - buffer: make([]byte, 0), - } -} - -// Close closes the wrapped file. -func (ar *ansiReader) Close() (err error) { - return ar.file.Close() -} - -// Fd returns the file descriptor of the wrapped file. -func (ar *ansiReader) Fd() uintptr { - return ar.fd -} - -// Read reads up to len(p) bytes of translated input events into p. -func (ar *ansiReader) Read(p []byte) (int, error) { - if len(p) == 0 { - return 0, nil - } - - // Previously read bytes exist, read as much as we can and return - if len(ar.buffer) > 0 { - logger.Debugf("Reading previously cached bytes") - - originalLength := len(ar.buffer) - copiedLength := copy(p, ar.buffer) - - if copiedLength == originalLength { - ar.buffer = make([]byte, 0, len(p)) - } else { - ar.buffer = ar.buffer[copiedLength:] - } - - logger.Debugf("Read from cache p[%d]: % x", copiedLength, p) - return copiedLength, nil - } - - // Read and translate key events - events, err := readInputEvents(ar.fd, len(p)) - if err != nil { - return 0, err - } else if len(events) == 0 { - logger.Debug("No input events detected") - return 0, nil - } - - keyBytes := translateKeyEvents(events, []byte(escapeSequence)) - - // Save excess bytes and right-size keyBytes - if len(keyBytes) > len(p) { - logger.Debugf("Received %d keyBytes, only room for %d bytes", len(keyBytes), len(p)) - ar.buffer = keyBytes[len(p):] - keyBytes = keyBytes[:len(p)] - } else if len(keyBytes) == 0 { - logger.Debug("No key bytes returned from the translator") - return 0, nil - } - - copiedLength := copy(p, keyBytes) - if copiedLength != len(keyBytes) { - return 0, errors.New("unexpected copy length encountered") - } - - logger.Debugf("Read p[%d]: % x", copiedLength, p) - logger.Debugf("Read keyBytes[%d]: % x", copiedLength, keyBytes) - return copiedLength, nil -} - -// readInputEvents polls until at least one event is available. -func readInputEvents(fd uintptr, maxBytes int) ([]winterm.INPUT_RECORD, error) { - // Determine the maximum number of records to retrieve - // -- Cast around the type system to obtain the size of a single INPUT_RECORD. - // unsafe.Sizeof requires an expression vs. a type-reference; the casting - // tricks the type system into believing it has such an expression. - recordSize := int(unsafe.Sizeof(*((*winterm.INPUT_RECORD)(unsafe.Pointer(&maxBytes))))) - countRecords := maxBytes / recordSize - if countRecords > ansiterm.MAX_INPUT_EVENTS { - countRecords = ansiterm.MAX_INPUT_EVENTS - } else if countRecords == 0 { - countRecords = 1 - } - logger.Debugf("[windows] readInputEvents: Reading %v records (buffer size %v, record size %v)", countRecords, maxBytes, recordSize) - - // Wait for and read input events - events := make([]winterm.INPUT_RECORD, countRecords) - nEvents := uint32(0) - eventsExist, err := winterm.WaitForSingleObject(fd, winterm.WAIT_INFINITE) - if err != nil { - return nil, err - } - - if eventsExist { - err = winterm.ReadConsoleInput(fd, events, &nEvents) - if err != nil { - return nil, err - } - } - - // Return a slice restricted to the number of returned records - logger.Debugf("[windows] readInputEvents: Read %v events", nEvents) - return events[:nEvents], nil -} - -// KeyEvent Translation Helpers - -var arrowKeyMapPrefix = map[uint16]string{ - winterm.VK_UP: "%s%sA", - winterm.VK_DOWN: "%s%sB", - winterm.VK_RIGHT: "%s%sC", - winterm.VK_LEFT: "%s%sD", -} - -var keyMapPrefix = map[uint16]string{ - winterm.VK_UP: "\x1B[%sA", - winterm.VK_DOWN: "\x1B[%sB", - winterm.VK_RIGHT: "\x1B[%sC", - winterm.VK_LEFT: "\x1B[%sD", - winterm.VK_HOME: "\x1B[1%s~", // showkey shows ^[[1 - winterm.VK_END: "\x1B[4%s~", // showkey shows ^[[4 - winterm.VK_INSERT: "\x1B[2%s~", - winterm.VK_DELETE: "\x1B[3%s~", - winterm.VK_PRIOR: "\x1B[5%s~", - winterm.VK_NEXT: "\x1B[6%s~", - winterm.VK_F1: "", - winterm.VK_F2: "", - winterm.VK_F3: "\x1B[13%s~", - winterm.VK_F4: "\x1B[14%s~", - winterm.VK_F5: "\x1B[15%s~", - winterm.VK_F6: "\x1B[17%s~", - winterm.VK_F7: "\x1B[18%s~", - winterm.VK_F8: "\x1B[19%s~", - winterm.VK_F9: "\x1B[20%s~", - winterm.VK_F10: "\x1B[21%s~", - winterm.VK_F11: "\x1B[23%s~", - winterm.VK_F12: "\x1B[24%s~", -} - -// translateKeyEvents converts the input events into the appropriate ANSI string. -func translateKeyEvents(events []winterm.INPUT_RECORD, escapeSequence []byte) []byte { - var buffer bytes.Buffer - for _, event := range events { - if event.EventType == winterm.KEY_EVENT && event.KeyEvent.KeyDown != 0 { - buffer.WriteString(keyToString(&event.KeyEvent, escapeSequence)) - } - } - - return buffer.Bytes() -} - -// keyToString maps the given input event record to the corresponding string. -func keyToString(keyEvent *winterm.KEY_EVENT_RECORD, escapeSequence []byte) string { - if keyEvent.UnicodeChar == 0 { - return formatVirtualKey(keyEvent.VirtualKeyCode, keyEvent.ControlKeyState, escapeSequence) - } - - _, alt, control := getControlKeys(keyEvent.ControlKeyState) - if control { - // TODO(azlinux): Implement following control sequences - // -D Signals the end of input from the keyboard; also exits current shell. - // -H Deletes the first character to the left of the cursor. Also called the ERASE key. - // -Q Restarts printing after it has been stopped with -s. - // -S Suspends printing on the screen (does not stop the program). - // -U Deletes all characters on the current line. Also called the KILL key. - // -E Quits current command and creates a core - - } - - // +Key generates ESC N Key - if !control && alt { - return ansiterm.KEY_ESC_N + strings.ToLower(string(keyEvent.UnicodeChar)) - } - - return string(keyEvent.UnicodeChar) -} - -// formatVirtualKey converts a virtual key (e.g., up arrow) into the appropriate ANSI string. -func formatVirtualKey(key uint16, controlState uint32, escapeSequence []byte) string { - shift, alt, control := getControlKeys(controlState) - modifier := getControlKeysModifier(shift, alt, control) - - if format, ok := arrowKeyMapPrefix[key]; ok { - return fmt.Sprintf(format, escapeSequence, modifier) - } - - if format, ok := keyMapPrefix[key]; ok { - return fmt.Sprintf(format, modifier) - } - - return "" -} - -// getControlKeys extracts the shift, alt, and ctrl key states. -func getControlKeys(controlState uint32) (shift, alt, control bool) { - shift = 0 != (controlState & winterm.SHIFT_PRESSED) - alt = 0 != (controlState & (winterm.LEFT_ALT_PRESSED | winterm.RIGHT_ALT_PRESSED)) - control = 0 != (controlState & (winterm.LEFT_CTRL_PRESSED | winterm.RIGHT_CTRL_PRESSED)) - return shift, alt, control -} - -// getControlKeysModifier returns the ANSI modifier for the given combination of control keys. -func getControlKeysModifier(shift, alt, control bool) string { - if shift && alt && control { - return ansiterm.KEY_CONTROL_PARAM_8 - } - if alt && control { - return ansiterm.KEY_CONTROL_PARAM_7 - } - if shift && control { - return ansiterm.KEY_CONTROL_PARAM_6 - } - if control { - return ansiterm.KEY_CONTROL_PARAM_5 - } - if shift && alt { - return ansiterm.KEY_CONTROL_PARAM_4 - } - if alt { - return ansiterm.KEY_CONTROL_PARAM_3 - } - if shift { - return ansiterm.KEY_CONTROL_PARAM_2 - } - return "" -} diff --git a/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go b/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go deleted file mode 100644 index 7799a03fc59..00000000000 --- a/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go +++ /dev/null @@ -1,64 +0,0 @@ -// +build windows - -package windowsconsole // import "github.com/docker/docker/pkg/term/windows" - -import ( - "io" - "os" - - ansiterm "github.com/Azure/go-ansiterm" - "github.com/Azure/go-ansiterm/winterm" -) - -// ansiWriter wraps a standard output file (e.g., os.Stdout) providing ANSI sequence translation. -type ansiWriter struct { - file *os.File - fd uintptr - infoReset *winterm.CONSOLE_SCREEN_BUFFER_INFO - command []byte - escapeSequence []byte - inAnsiSequence bool - parser *ansiterm.AnsiParser -} - -// NewAnsiWriter returns an io.Writer that provides VT100 terminal emulation on top of a -// Windows console output handle. -func NewAnsiWriter(nFile int) io.Writer { - initLogger() - file, fd := winterm.GetStdFile(nFile) - info, err := winterm.GetConsoleScreenBufferInfo(fd) - if err != nil { - return nil - } - - parser := ansiterm.CreateParser("Ground", winterm.CreateWinEventHandler(fd, file)) - logger.Infof("newAnsiWriter: parser %p", parser) - - aw := &ansiWriter{ - file: file, - fd: fd, - infoReset: info, - command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH), - escapeSequence: []byte(ansiterm.KEY_ESC_CSI), - parser: parser, - } - - logger.Infof("newAnsiWriter: aw.parser %p", aw.parser) - logger.Infof("newAnsiWriter: %v", aw) - return aw -} - -func (aw *ansiWriter) Fd() uintptr { - return aw.fd -} - -// Write writes len(p) bytes from p to the underlying data stream. -func (aw *ansiWriter) Write(p []byte) (total int, err error) { - if len(p) == 0 { - return 0, nil - } - - logger.Infof("Write: % x", p) - logger.Infof("Write: %s", string(p)) - return aw.parser.Parse(p) -} diff --git a/vendor/github.com/docker/docker/pkg/term/windows/console.go b/vendor/github.com/docker/docker/pkg/term/windows/console.go deleted file mode 100644 index 52740197580..00000000000 --- a/vendor/github.com/docker/docker/pkg/term/windows/console.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build windows - -package windowsconsole // import "github.com/docker/docker/pkg/term/windows" - -import ( - "os" - - "github.com/Azure/go-ansiterm/winterm" -) - -// GetHandleInfo returns file descriptor and bool indicating whether the file is a console. -func GetHandleInfo(in interface{}) (uintptr, bool) { - switch t := in.(type) { - case *ansiReader: - return t.Fd(), true - case *ansiWriter: - return t.Fd(), true - } - - var inFd uintptr - var isTerminal bool - - if file, ok := in.(*os.File); ok { - inFd = file.Fd() - isTerminal = IsConsole(inFd) - } - return inFd, isTerminal -} - -// IsConsole returns true if the given file descriptor is a Windows Console. -// The code assumes that GetConsoleMode will return an error for file descriptors that are not a console. -func IsConsole(fd uintptr) bool { - _, e := winterm.GetConsoleMode(fd) - return e == nil -} diff --git a/vendor/github.com/docker/docker/pkg/term/windows/windows.go b/vendor/github.com/docker/docker/pkg/term/windows/windows.go deleted file mode 100644 index 3e5593ca6a6..00000000000 --- a/vendor/github.com/docker/docker/pkg/term/windows/windows.go +++ /dev/null @@ -1,33 +0,0 @@ -// These files implement ANSI-aware input and output streams for use by the Docker Windows client. -// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create -// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls. - -package windowsconsole // import "github.com/docker/docker/pkg/term/windows" - -import ( - "io/ioutil" - "os" - "sync" - - "github.com/Azure/go-ansiterm" - "github.com/sirupsen/logrus" -) - -var logger *logrus.Logger -var initOnce sync.Once - -func initLogger() { - initOnce.Do(func() { - logFile := ioutil.Discard - - if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" { - logFile, _ = os.Create("ansiReaderWriter.log") - } - - logger = &logrus.Logger{ - Out: logFile, - Formatter: new(logrus.TextFormatter), - Level: logrus.DebugLevel, - } - }) -} diff --git a/vendor/github.com/docker/docker/pkg/term/winsize.go b/vendor/github.com/docker/docker/pkg/term/winsize.go deleted file mode 100644 index a19663ad834..00000000000 --- a/vendor/github.com/docker/docker/pkg/term/winsize.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build !windows - -package term // import "github.com/docker/docker/pkg/term" - -import ( - "golang.org/x/sys/unix" -) - -// GetWinsize returns the window size based on the specified file descriptor. -func GetWinsize(fd uintptr) (*Winsize, error) { - uws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ) - ws := &Winsize{Height: uws.Row, Width: uws.Col, x: uws.Xpixel, y: uws.Ypixel} - return ws, err -} - -// SetWinsize tries to set the specified window size for the specified file descriptor. -func SetWinsize(fd uintptr, ws *Winsize) error { - uws := &unix.Winsize{Row: ws.Height, Col: ws.Width, Xpixel: ws.x, Ypixel: ws.y} - return unix.IoctlSetWinsize(int(fd), unix.TIOCSWINSZ, uws) -} diff --git a/vendor/github.com/google/cadvisor/container/common/helpers.go b/vendor/github.com/google/cadvisor/container/common/helpers.go index 4382ffb7c0d..4eba4af2c3a 100644 --- a/vendor/github.com/google/cadvisor/container/common/helpers.go +++ b/vendor/github.com/google/cadvisor/container/common/helpers.go @@ -30,6 +30,7 @@ import ( "github.com/karrick/godirwalk" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/pkg/errors" + "golang.org/x/sys/unix" "k8s.io/klog/v2" ) @@ -68,6 +69,16 @@ func findFileInAncestorDir(current, file, limit string) (string, error) { } } +var bootTime = func() time.Time { + now := time.Now() + var sysinfo unix.Sysinfo_t + if err := unix.Sysinfo(&sysinfo); err != nil { + return now + } + sinceBoot := time.Duration(sysinfo.Uptime) * time.Second + return now.Add(-1 * sinceBoot).Truncate(time.Minute) +}() + func GetSpec(cgroupPaths map[string]string, machineInfoFactory info.MachineInfoFactory, hasNetwork, hasFilesystem bool) (info.ContainerSpec, error) { var spec info.ContainerSpec @@ -75,17 +86,28 @@ func GetSpec(cgroupPaths map[string]string, machineInfoFactory info.MachineInfoF // Get the lowest creation time from all hierarchies as the container creation time. now := time.Now() lowestTime := now - for _, cgroupPath := range cgroupPaths { - // The modified time of the cgroup directory changes whenever a subcontainer is created. + for _, cgroupPathDir := range cgroupPaths { + dir, err := os.Stat(cgroupPathDir) + if err == nil && dir.ModTime().Before(lowestTime) { + lowestTime = dir.ModTime() + } + // The modified time of the cgroup directory sometimes changes whenever a subcontainer is created. // eg. /docker will have creation time matching the creation of latest docker container. - // Use clone_children as a workaround as it isn't usually modified. It is only likely changed - // immediately after creating a container. - cgroupPath = path.Join(cgroupPath, "cgroup.clone_children") - fi, err := os.Stat(cgroupPath) + // Use clone_children/events as a workaround as it isn't usually modified. It is only likely changed + // immediately after creating a container. If the directory modified time is lower, we use that. + cgroupPathFile := path.Join(cgroupPathDir, "cgroup.clone_children") + if cgroups.IsCgroup2UnifiedMode() { + cgroupPathFile = path.Join(cgroupPathDir, "cgroup.events") + } + fi, err := os.Stat(cgroupPathFile) if err == nil && fi.ModTime().Before(lowestTime) { lowestTime = fi.ModTime() } } + if lowestTime.Before(bootTime) { + lowestTime = bootTime + } + if lowestTime != now { spec.CreationTime = lowestTime } diff --git a/vendor/github.com/google/cadvisor/container/docker/factory.go b/vendor/github.com/google/cadvisor/container/docker/factory.go index f0118166e2d..1490a88f41b 100644 --- a/vendor/github.com/google/cadvisor/container/docker/factory.go +++ b/vendor/github.com/google/cadvisor/container/docker/factory.go @@ -347,23 +347,25 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics var ( thinPoolWatcher *devicemapper.ThinPoolWatcher thinPoolName string + zfsWatcher *zfs.ZfsWatcher ) - if storageDriver(dockerInfo.Driver) == devicemapperStorageDriver { - thinPoolWatcher, err = startThinPoolWatcher(dockerInfo) - if err != nil { - klog.Errorf("devicemapper filesystem stats will not be reported: %v", err) + if includedMetrics.Has(container.DiskUsageMetrics) { + if storageDriver(dockerInfo.Driver) == devicemapperStorageDriver { + thinPoolWatcher, err = startThinPoolWatcher(dockerInfo) + if err != nil { + klog.Errorf("devicemapper filesystem stats will not be reported: %v", err) + } + + // Safe to ignore error - driver status should always be populated. + status, _ := StatusFromDockerInfo(*dockerInfo) + thinPoolName = status.DriverStatus[dockerutil.DriverStatusPoolName] } - // Safe to ignore error - driver status should always be populated. - status, _ := StatusFromDockerInfo(*dockerInfo) - thinPoolName = status.DriverStatus[dockerutil.DriverStatusPoolName] - } - - var zfsWatcher *zfs.ZfsWatcher - if storageDriver(dockerInfo.Driver) == zfsStorageDriver { - zfsWatcher, err = startZfsWatcher(dockerInfo) - if err != nil { - klog.Errorf("zfs filesystem stats will not be reported: %v", err) + if storageDriver(dockerInfo.Driver) == zfsStorageDriver { + zfsWatcher, err = startZfsWatcher(dockerInfo) + if err != nil { + klog.Errorf("zfs filesystem stats will not be reported: %v", err) + } } } diff --git a/vendor/github.com/google/cadvisor/container/docker/handler.go b/vendor/github.com/google/cadvisor/container/docker/handler.go index e2c904ca886..e9afc752446 100644 --- a/vendor/github.com/google/cadvisor/container/docker/handler.go +++ b/vendor/github.com/google/cadvisor/container/docker/handler.go @@ -398,11 +398,14 @@ func (h *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error { fsType string ) + var fsInfo *info.FsInfo + // Docker does not impose any filesystem limits for containers. So use capacity as limit. for _, fs := range mi.Filesystems { if fs.Device == device { limit = fs.Capacity fsType = fs.Type + fsInfo = &fs break } } @@ -413,11 +416,45 @@ func (h *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error { fsStat.Usage = usage.TotalUsageBytes fsStat.Inodes = usage.InodeUsage + if fsInfo != nil { + fileSystems, err := h.fsInfo.GetGlobalFsInfo() + + if err == nil { + addDiskStats(fileSystems, fsInfo, &fsStat) + } else { + klog.Errorf("Unable to obtain diskstats for filesystem %s: %v", fsStat.Device, err) + } + } + stats.Filesystem = append(stats.Filesystem, fsStat) return nil } +func addDiskStats(fileSystems []fs.Fs, fsInfo *info.FsInfo, fsStats *info.FsStats) { + if fsInfo == nil { + return + } + + for _, fileSys := range fileSystems { + if fsInfo.DeviceMajor == fileSys.DiskStats.Major && + fsInfo.DeviceMinor == fileSys.DiskStats.Minor { + fsStats.ReadsCompleted = fileSys.DiskStats.ReadsCompleted + fsStats.ReadsMerged = fileSys.DiskStats.ReadsMerged + fsStats.SectorsRead = fileSys.DiskStats.SectorsRead + fsStats.ReadTime = fileSys.DiskStats.ReadTime + fsStats.WritesCompleted = fileSys.DiskStats.WritesCompleted + fsStats.WritesMerged = fileSys.DiskStats.WritesMerged + fsStats.SectorsWritten = fileSys.DiskStats.SectorsWritten + fsStats.WriteTime = fileSys.DiskStats.WriteTime + fsStats.IoInProgress = fileSys.DiskStats.IoInProgress + fsStats.IoTime = fileSys.DiskStats.IoTime + fsStats.WeightedIoTime = fileSys.DiskStats.WeightedIoTime + break + } + } +} + // TODO(vmarmol): Get from libcontainer API instead of cgroup manager when we don't have to support older Dockers. func (h *dockerContainerHandler) GetStats() (*info.ContainerStats, error) { stats, err := h.libcontainerHandler.GetStats() diff --git a/vendor/github.com/google/cadvisor/container/factory.go b/vendor/github.com/google/cadvisor/container/factory.go index 652070b1b48..56d198976ef 100644 --- a/vendor/github.com/google/cadvisor/container/factory.go +++ b/vendor/github.com/google/cadvisor/container/factory.go @@ -63,6 +63,7 @@ const ( ReferencedMemoryMetrics MetricKind = "referenced_memory" CPUTopologyMetrics MetricKind = "cpu_topology" ResctrlMetrics MetricKind = "resctrl" + CPUSetMetrics MetricKind = "cpuset" ) // AllMetrics represents all kinds of metrics that cAdvisor supported. @@ -87,6 +88,7 @@ var AllMetrics = MetricSet{ ReferencedMemoryMetrics: struct{}{}, CPUTopologyMetrics: struct{}{}, ResctrlMetrics: struct{}{}, + CPUSetMetrics: struct{}{}, } func (mk MetricKind) String() string { diff --git a/vendor/github.com/google/cadvisor/container/libcontainer/handler.go b/vendor/github.com/google/cadvisor/container/libcontainer/handler.go index 6e8a73432ae..4bfb6aef88a 100644 --- a/vendor/github.com/google/cadvisor/container/libcontainer/handler.go +++ b/vendor/github.com/google/cadvisor/container/libcontainer/handler.go @@ -70,21 +70,22 @@ func NewHandler(cgroupManager cgroups.Manager, rootFs string, pid int, includedM // Get cgroup and networking stats of the specified container func (h *Handler) GetStats() (*info.ContainerStats, error) { - var cgroupStats *cgroups.Stats - readCgroupStats := true + ignoreStatsError := false if cgroups.IsCgroup2UnifiedMode() { - // On cgroup v2 there are no stats at the root cgroup - // so check whether it is the root cgroup + // On cgroup v2 the root cgroup stats have been introduced in recent kernel versions, + // so not all kernel versions have all the data. This means that stat fetching can fail + // due to lacking cgroup stat files, but that some data is provided. if h.cgroupManager.Path("") == fs2.UnifiedMountpoint { - readCgroupStats = false + ignoreStatsError = true } } - var err error - if readCgroupStats { - cgroupStats, err = h.cgroupManager.GetStats() - if err != nil { + + cgroupStats, err := h.cgroupManager.GetStats() + if err != nil { + if !ignoreStatsError { return nil, err } + klog.V(4).Infof("Ignoring errors when gathering stats for root cgroup since some controllers don't have stats on the root cgroup: %v", err) } libcontainerStats := &libcontainer.Stats{ CgroupStats: cgroupStats, @@ -793,7 +794,12 @@ func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) { ret.Memory.MaxUsage = s.MemoryStats.Usage.MaxUsage ret.Memory.Failcnt = s.MemoryStats.Usage.Failcnt - if s.MemoryStats.UseHierarchy { + if cgroups.IsCgroup2UnifiedMode() { + ret.Memory.Cache = s.MemoryStats.Stats["file"] + ret.Memory.RSS = s.MemoryStats.Stats["anon"] + ret.Memory.Swap = s.MemoryStats.SwapUsage.Usage + ret.Memory.MappedFile = s.MemoryStats.Stats["file_mapped"] + } else if s.MemoryStats.UseHierarchy { ret.Memory.Cache = s.MemoryStats.Stats["total_cache"] ret.Memory.RSS = s.MemoryStats.Stats["total_rss"] ret.Memory.Swap = s.MemoryStats.Stats["total_swap"] @@ -829,6 +835,10 @@ func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) { ret.Memory.WorkingSet = workingSet } +func setCPUSetStats(s *cgroups.Stats, ret *info.ContainerStats) { + ret.CpuSet.MemoryMigrate = s.CPUSetStats.MemoryMigrate +} + func getNumaStats(memoryStats map[uint8]uint64) map[uint8]uint64 { stats := make(map[uint8]uint64, len(memoryStats)) for node, usage := range memoryStats { @@ -906,6 +916,9 @@ func newContainerStats(libcontainerStats *libcontainer.Stats, includedMetrics co if includedMetrics.Has(container.HugetlbUsageMetrics) { setHugepageStats(s, ret) } + if includedMetrics.Has(container.CPUSetMetrics) { + setCPUSetStats(s, ret) + } } if len(libcontainerStats.Interfaces) > 0 { setNetworkStats(libcontainerStats, ret) diff --git a/vendor/github.com/google/cadvisor/fs/fs.go b/vendor/github.com/google/cadvisor/fs/fs.go index fd2772f9983..91a2d1f2649 100644 --- a/vendor/github.com/google/cadvisor/fs/fs.go +++ b/vendor/github.com/google/cadvisor/fs/fs.go @@ -33,9 +33,9 @@ import ( "github.com/google/cadvisor/devicemapper" "github.com/google/cadvisor/utils" zfs "github.com/mistifyio/go-zfs" + mount "github.com/moby/sys/mountinfo" "k8s.io/klog/v2" - "k8s.io/utils/mount" ) const ( @@ -85,7 +85,7 @@ type RealFsInfo struct { // Labels are intent-specific tags that are auto-detected. labels map[string]string // Map from mountpoint to mount information. - mounts map[string]mount.MountInfo + mounts map[string]mount.Info // devicemapper client dmsetup devicemapper.DmsetupClient // fsUUIDToDeviceName is a map from the filesystem UUID to its device name. @@ -93,7 +93,11 @@ type RealFsInfo struct { } func NewFsInfo(context Context) (FsInfo, error) { - mounts, err := mount.ParseMountInfo("/proc/self/mountinfo") + fileReader, err := os.Open("/proc/self/mountinfo") + if err != nil { + return nil, err + } + mounts, err := mount.GetMountsFromReader(fileReader, nil) if err != nil { return nil, err } @@ -110,13 +114,13 @@ func NewFsInfo(context Context) (FsInfo, error) { fsInfo := &RealFsInfo{ partitions: processMounts(mounts, excluded), labels: make(map[string]string), - mounts: make(map[string]mount.MountInfo), + mounts: make(map[string]mount.Info), dmsetup: devicemapper.NewDmsetupClient(), fsUUIDToDeviceName: fsUUIDToDeviceName, } - for _, mount := range mounts { - fsInfo.mounts[mount.MountPoint] = mount + for _, mnt := range mounts { + fsInfo.mounts[mnt.Mountpoint] = *mnt } // need to call this before the log line below printing out the partitions, as this function may @@ -147,10 +151,10 @@ func getFsUUIDToDeviceNameMap() (map[string]string, error) { fsUUIDToDeviceName := make(map[string]string) for _, file := range files { - path := filepath.Join(dir, file.Name()) - target, err := os.Readlink(path) + fpath := filepath.Join(dir, file.Name()) + target, err := os.Readlink(fpath) if err != nil { - klog.Warningf("Failed to resolve symlink for %q", path) + klog.Warningf("Failed to resolve symlink for %q", fpath) continue } device, err := filepath.Abs(filepath.Join(dir, target)) @@ -162,11 +166,12 @@ func getFsUUIDToDeviceNameMap() (map[string]string, error) { return fsUUIDToDeviceName, nil } -func processMounts(mounts []mount.MountInfo, excludedMountpointPrefixes []string) map[string]partition { +func processMounts(mounts []*mount.Info, excludedMountpointPrefixes []string) map[string]partition { partitions := make(map[string]partition) supportedFsType := map[string]bool{ - // all ext systems are checked through prefix. + // all ext and nfs systems are checked through prefix + // because there are a number of families (e.g., ext3, ext4, nfs3, nfs4...) "btrfs": true, "overlay": true, "tmpfs": true, @@ -174,20 +179,21 @@ func processMounts(mounts []mount.MountInfo, excludedMountpointPrefixes []string "zfs": true, } - for _, mount := range mounts { - if !strings.HasPrefix(mount.FsType, "ext") && !supportedFsType[mount.FsType] { + for _, mnt := range mounts { + if !strings.HasPrefix(mnt.FSType, "ext") && !strings.HasPrefix(mnt.FSType, "nfs") && + !supportedFsType[mnt.FSType] { continue } // Avoid bind mounts, exclude tmpfs. - if _, ok := partitions[mount.Source]; ok { - if mount.FsType != "tmpfs" { + if _, ok := partitions[mnt.Source]; ok { + if mnt.FSType != "tmpfs" { continue } } hasPrefix := false for _, prefix := range excludedMountpointPrefixes { - if strings.HasPrefix(mount.MountPoint, prefix) { + if strings.HasPrefix(mnt.Mountpoint, prefix) { hasPrefix = true break } @@ -197,31 +203,31 @@ func processMounts(mounts []mount.MountInfo, excludedMountpointPrefixes []string } // using mountpoint to replace device once fstype it tmpfs - if mount.FsType == "tmpfs" { - mount.Source = mount.MountPoint + if mnt.FSType == "tmpfs" { + mnt.Source = mnt.Mountpoint } // btrfs fix: following workaround fixes wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo. // instead of using values from /proc/self/mountinfo we use stat to get Ids from btrfs mount point - if mount.FsType == "btrfs" && mount.Major == 0 && strings.HasPrefix(mount.Source, "/dev/") { - major, minor, err := getBtrfsMajorMinorIds(&mount) + if mnt.FSType == "btrfs" && mnt.Major == 0 && strings.HasPrefix(mnt.Source, "/dev/") { + major, minor, err := getBtrfsMajorMinorIds(mnt) if err != nil { klog.Warningf("%s", err) } else { - mount.Major = major - mount.Minor = minor + mnt.Major = major + mnt.Minor = minor } } // overlay fix: Making mount source unique for all overlay mounts, using the mount's major and minor ids. - if mount.FsType == "overlay" { - mount.Source = fmt.Sprintf("%s_%d-%d", mount.Source, mount.Major, mount.Minor) + if mnt.FSType == "overlay" { + mnt.Source = fmt.Sprintf("%s_%d-%d", mnt.Source, mnt.Major, mnt.Minor) } - partitions[mount.Source] = partition{ - fsType: mount.FsType, - mountpoint: mount.MountPoint, - major: uint(mount.Major), - minor: uint(mount.Minor), + partitions[mnt.Source] = partition{ + fsType: mnt.FSType, + mountpoint: mnt.Mountpoint, + major: uint(mnt.Major), + minor: uint(mnt.Minor), } } @@ -256,12 +262,12 @@ func (i *RealFsInfo) getDockerDeviceMapperInfo(context DockerContext) (string, * } // addSystemRootLabel attempts to determine which device contains the mount for /. -func (i *RealFsInfo) addSystemRootLabel(mounts []mount.MountInfo) { +func (i *RealFsInfo) addSystemRootLabel(mounts []*mount.Info) { for _, m := range mounts { - if m.MountPoint == "/" { + if m.Mountpoint == "/" { i.partitions[m.Source] = partition{ - fsType: m.FsType, - mountpoint: m.MountPoint, + fsType: m.FSType, + mountpoint: m.Mountpoint, major: uint(m.Major), minor: uint(m.Minor), } @@ -272,7 +278,7 @@ func (i *RealFsInfo) addSystemRootLabel(mounts []mount.MountInfo) { } // addDockerImagesLabel attempts to determine which device contains the mount for docker images. -func (i *RealFsInfo) addDockerImagesLabel(context Context, mounts []mount.MountInfo) { +func (i *RealFsInfo) addDockerImagesLabel(context Context, mounts []*mount.Info) { dockerDev, dockerPartition, err := i.getDockerDeviceMapperInfo(context.Docker) if err != nil { klog.Warningf("Could not get Docker devicemapper device: %v", err) @@ -285,7 +291,7 @@ func (i *RealFsInfo) addDockerImagesLabel(context Context, mounts []mount.MountI } } -func (i *RealFsInfo) addCrioImagesLabel(context Context, mounts []mount.MountInfo) { +func (i *RealFsInfo) addCrioImagesLabel(context Context, mounts []*mount.Info) { if context.Crio.Root != "" { crioPath := context.Crio.Root crioImagePaths := map[string]struct{}{ @@ -324,20 +330,19 @@ func getDockerImagePaths(context Context) map[string]struct{} { // This method compares the mountpoints with possible container image mount points. If a match is found, // the label is added to the partition. -func (i *RealFsInfo) updateContainerImagesPath(label string, mounts []mount.MountInfo, containerImagePaths map[string]struct{}) { - var useMount *mount.MountInfo +func (i *RealFsInfo) updateContainerImagesPath(label string, mounts []*mount.Info, containerImagePaths map[string]struct{}) { + var useMount *mount.Info for _, m := range mounts { - if _, ok := containerImagePaths[m.MountPoint]; ok { - if useMount == nil || (len(useMount.MountPoint) < len(m.MountPoint)) { - useMount = new(mount.MountInfo) - *useMount = m + if _, ok := containerImagePaths[m.Mountpoint]; ok { + if useMount == nil || (len(useMount.Mountpoint) < len(m.Mountpoint)) { + useMount = m } } } if useMount != nil { i.partitions[useMount.Source] = partition{ - fsType: useMount.FsType, - mountpoint: useMount.MountPoint, + fsType: useMount.FSType, + mountpoint: useMount.Mountpoint, major: uint(useMount.Major), minor: uint(useMount.Minor), } @@ -354,7 +359,7 @@ func (i *RealFsInfo) GetDeviceForLabel(label string) (string, error) { } func (i *RealFsInfo) GetLabelsForDevice(device string) ([]string, error) { - labels := []string{} + var labels []string for label, dev := range i.labels { if dev == device { labels = append(labels, label) @@ -462,12 +467,12 @@ func getDiskStatsMap(diskStatsFile string) (map[string]DiskStats, error) { // 8 50 sdd2 40 0 280 223 7 0 22 108 0 330 330 deviceName := path.Join("/dev", words[2]) - var error error + var err error devInfo := make([]uint64, 2) for i := 0; i < len(devInfo); i++ { - devInfo[i], error = strconv.ParseUint(words[i], 10, 64) - if error != nil { - return nil, error + devInfo[i], err = strconv.ParseUint(words[i], 10, 64) + if err != nil { + return nil, err } } @@ -478,11 +483,22 @@ func getDiskStatsMap(diskStatsFile string) (map[string]DiskStats, error) { return nil, fmt.Errorf("could not parse all 11 columns of /proc/diskstats") } for i := offset; i < wordLength; i++ { - stats[i-offset], error = strconv.ParseUint(words[i], 10, 64) - if error != nil { - return nil, error + stats[i-offset], err = strconv.ParseUint(words[i], 10, 64) + if err != nil { + return nil, err } } + + major64, err := strconv.ParseUint(words[0], 10, 64) + if err != nil { + return nil, err + } + + minor64, err := strconv.ParseUint(words[1], 10, 64) + if err != nil { + return nil, err + } + diskStats := DiskStats{ MajorNum: devInfo[0], MinorNum: devInfo[1], @@ -497,6 +513,8 @@ func getDiskStatsMap(diskStatsFile string) (map[string]DiskStats, error) { IoInProgress: stats[8], IoTime: stats[9], WeightedIoTime: stats[10], + Major: major64, + Minor: minor64, } diskStatsMap[deviceName] = diskStats } @@ -527,8 +545,8 @@ func (i *RealFsInfo) GetDeviceInfoByFsUUID(uuid string) (*DeviceInfo, error) { return &DeviceInfo{deviceName, p.major, p.minor}, nil } -func (i *RealFsInfo) mountInfoFromDir(dir string) (*mount.MountInfo, bool) { - mount, found := i.mounts[dir] +func (i *RealFsInfo) mountInfoFromDir(dir string) (*mount.Info, bool) { + mnt, found := i.mounts[dir] // try the parent dir if not found until we reach the root dir // this is an issue on btrfs systems where the directory is not // the subvolume @@ -536,15 +554,15 @@ func (i *RealFsInfo) mountInfoFromDir(dir string) (*mount.MountInfo, bool) { pathdir, _ := filepath.Split(dir) // break when we reach root if pathdir == "/" { - mount, found = i.mounts["/"] + mnt, found = i.mounts["/"] break } // trim "/" from the new parent path otherwise the next possible // filepath.Split in the loop will not split the string any further dir = strings.TrimSuffix(pathdir, "/") - mount, found = i.mounts[dir] + mnt, found = i.mounts[dir] } - return &mount, found + return &mnt, found } func (i *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) { @@ -563,13 +581,13 @@ func (i *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) { } } - mount, found := i.mountInfoFromDir(dir) - if found && mount.FsType == "btrfs" && mount.Major == 0 && strings.HasPrefix(mount.Source, "/dev/") { - major, minor, err := getBtrfsMajorMinorIds(mount) + mnt, found := i.mountInfoFromDir(dir) + if found && mnt.FSType == "btrfs" && mnt.Major == 0 && strings.HasPrefix(mnt.Source, "/dev/") { + major, minor, err := getBtrfsMajorMinorIds(mnt) if err != nil { klog.Warningf("%s", err) } else { - return &DeviceInfo{mount.Source, uint(major), uint(minor)}, nil + return &DeviceInfo{mnt.Source, uint(major), uint(minor)}, nil } } return nil, fmt.Errorf("could not find device with major: %d, minor: %d in cached partitions map", major, minor) @@ -755,7 +773,7 @@ func getZfstats(poolName string) (uint64, uint64, uint64, error) { } // Get major and minor Ids for a mount point using btrfs as filesystem. -func getBtrfsMajorMinorIds(mount *mount.MountInfo) (int, int, error) { +func getBtrfsMajorMinorIds(mount *mount.Info) (int, int, error) { // btrfs fix: following workaround fixes wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo. // instead of using values from /proc/self/mountinfo we use stat to get Ids from btrfs mount point @@ -768,9 +786,9 @@ func getBtrfsMajorMinorIds(mount *mount.MountInfo) (int, int, error) { klog.V(4).Infof("btrfs mount %#v", mount) if buf.Mode&syscall.S_IFMT == syscall.S_IFBLK { - err := syscall.Stat(mount.MountPoint, buf) + err := syscall.Stat(mount.Mountpoint, buf) if err != nil { - err = fmt.Errorf("stat failed on %s with error: %s", mount.MountPoint, err) + err = fmt.Errorf("stat failed on %s with error: %s", mount.Mountpoint, err) return 0, 0, err } diff --git a/vendor/github.com/google/cadvisor/fs/types.go b/vendor/github.com/google/cadvisor/fs/types.go index 93294ebcc27..0445a17adbe 100644 --- a/vendor/github.com/google/cadvisor/fs/types.go +++ b/vendor/github.com/google/cadvisor/fs/types.go @@ -77,6 +77,8 @@ type DiskStats struct { IoInProgress uint64 IoTime uint64 WeightedIoTime uint64 + Major uint64 + Minor uint64 } type UsageInfo struct { diff --git a/vendor/github.com/google/cadvisor/info/v1/container.go b/vendor/github.com/google/cadvisor/info/v1/container.go index 08cff3940f1..9fe04fddea2 100644 --- a/vendor/github.com/google/cadvisor/info/v1/container.go +++ b/vendor/github.com/google/cadvisor/info/v1/container.go @@ -399,6 +399,10 @@ type MemoryStats struct { HierarchicalData MemoryStatsMemoryData `json:"hierarchical_data,omitempty"` } +type CPUSetStats struct { + MemoryMigrate uint64 `json:"memory_migrate"` +} + type MemoryNumaStats struct { File map[uint8]uint64 `json:"file,omitempty"` Anon map[uint8]uint64 `json:"anon,omitempty"` @@ -957,6 +961,8 @@ type ContainerStats struct { // Resource Control (resctrl) statistics Resctrl ResctrlStats `json:"resctrl,omitempty"` + + CpuSet CPUSetStats `json:"cpuset,omitempty"` } func timeEq(t1, t2 time.Time, tolerance time.Duration) bool { diff --git a/vendor/github.com/google/cadvisor/machine/machine.go b/vendor/github.com/google/cadvisor/machine/machine.go index 917569377dd..706bba63782 100644 --- a/vendor/github.com/google/cadvisor/machine/machine.go +++ b/vendor/github.com/google/cadvisor/machine/machine.go @@ -16,18 +16,15 @@ package machine import ( - "bytes" "fmt" "io/ioutil" "os" "path" - "path/filepath" "regexp" - "strconv" - "strings" - // s390/s390x changes "runtime" + "strconv" + "strings" info "github.com/google/cadvisor/info/v1" "github.com/google/cadvisor/utils" @@ -54,9 +51,6 @@ var ( maxFreqFile = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" ) -const sysFsCPUCoreID = "core_id" -const sysFsCPUPhysicalPackageID = "physical_package_id" -const sysFsCPUTopology = "topology" const memTypeFileName = "dimm_mem_type" const sizeFileName = "size" @@ -66,7 +60,7 @@ func GetPhysicalCores(procInfo []byte) int { if numCores == 0 { // read number of cores from /sys/bus/cpu/devices/cpu*/topology/core_id to deal with processors // for which 'core id' is not available in /proc/cpuinfo - numCores = getUniqueCPUPropertyCount(cpuBusPath, sysFsCPUCoreID) + numCores = sysfs.GetUniqueCPUPropertyCount(cpuBusPath, sysfs.CPUCoreID) } if numCores == 0 { klog.Errorf("Cannot read number of physical cores correctly, number of cores set to %d", numCores) @@ -80,7 +74,7 @@ func GetSockets(procInfo []byte) int { if numSocket == 0 { // read number of sockets from /sys/bus/cpu/devices/cpu*/topology/physical_package_id to deal with processors // for which 'physical id' is not available in /proc/cpuinfo - numSocket = getUniqueCPUPropertyCount(cpuBusPath, sysFsCPUPhysicalPackageID) + numSocket = sysfs.GetUniqueCPUPropertyCount(cpuBusPath, sysfs.CPUPhysicalPackageID) } if numSocket == 0 { klog.Errorf("Cannot read number of sockets correctly, number of sockets set to %d", numSocket) @@ -236,39 +230,6 @@ func parseCapacity(b []byte, r *regexp.Regexp) (uint64, error) { return m * 1024, err } -// Looks for sysfs cpu path containing given CPU property, e.g. core_id or physical_package_id -// and returns number of unique values of given property, exemplary usage: getting number of CPU physical cores -func getUniqueCPUPropertyCount(cpuBusPath string, propertyName string) int { - pathPattern := cpuBusPath + "cpu*[0-9]" - sysCPUPaths, err := filepath.Glob(pathPattern) - if err != nil { - klog.Errorf("Cannot find files matching pattern (pathPattern: %s), number of unique %s set to 0", pathPattern, propertyName) - return 0 - } - uniques := make(map[string]bool) - for _, sysCPUPath := range sysCPUPaths { - onlinePath := filepath.Join(sysCPUPath, "online") - onlineVal, err := ioutil.ReadFile(onlinePath) - if err != nil { - klog.Warningf("Cannot determine CPU %s online state, skipping", sysCPUPath) - continue - } - onlineVal = bytes.TrimSpace(onlineVal) - if len(onlineVal) == 0 || onlineVal[0] != 49 { - klog.Warningf("CPU %s is offline, skipping", sysCPUPath) - continue - } - propertyPath := filepath.Join(sysCPUPath, sysFsCPUTopology, propertyName) - propertyVal, err := ioutil.ReadFile(propertyPath) - if err != nil { - klog.Errorf("Cannot open %s, number of unique %s set to 0", propertyPath, propertyName) - return 0 - } - uniques[string(propertyVal)] = true - } - return len(uniques) -} - // getUniqueMatchesCount returns number of unique matches in given argument using provided regular expression func getUniqueMatchesCount(s string, r *regexp.Regexp) int { matches := r.FindAllString(s, -1) diff --git a/vendor/github.com/google/cadvisor/manager/container.go b/vendor/github.com/google/cadvisor/manager/container.go index c599300d84b..c776e10d640 100644 --- a/vendor/github.com/google/cadvisor/manager/container.go +++ b/vendor/github.com/google/cadvisor/manager/container.go @@ -38,7 +38,7 @@ import ( "github.com/google/cadvisor/summary" "github.com/google/cadvisor/utils/cpuload" - units "github.com/docker/go-units" + "github.com/docker/go-units" "k8s.io/klog/v2" "k8s.io/utils/clock" ) @@ -47,9 +47,14 @@ import ( var enableLoadReader = flag.Bool("enable_load_reader", false, "Whether to enable cpu load reader") var HousekeepingInterval = flag.Duration("housekeeping_interval", 1*time.Second, "Interval between container housekeepings") +// TODO: replace regular expressions with something simpler, such as strings.Split(). // cgroup type chosen to fetch the cgroup path of a process. -// Memory has been chosen, as it is one of the default cgroups that is enabled for most containers. -var cgroupPathRegExp = regexp.MustCompile(`memory[^:]*:(.*?)[,;$]`) +// Memory has been chosen, as it is one of the default cgroups that is enabled for most containers... +var cgroupMemoryPathRegExp = regexp.MustCompile(`memory[^:]*:(.*?)[,;$]`) + +// ... but there are systems (e.g. Raspberry Pi 4) where memory cgroup controller is disabled by default. +// We should check cpu cgroup then. +var cgroupCPUPathRegExp = regexp.MustCompile(`cpu[^:]*:(.*?)[,;$]`) type containerInfo struct { info.ContainerReference @@ -138,7 +143,10 @@ func (cd *containerData) allowErrorLogging() bool { // periodic housekeeping to reset. This should be used sparingly, as calling OnDemandHousekeeping frequently // can have serious performance costs. func (cd *containerData) OnDemandHousekeeping(maxAge time.Duration) { - if cd.clock.Since(cd.statsLastUpdatedTime) > maxAge { + cd.lock.Lock() + timeSinceStatsLastUpdate := cd.clock.Since(cd.statsLastUpdatedTime) + cd.lock.Unlock() + if timeSinceStatsLastUpdate > maxAge { housekeepingFinishedChan := make(chan struct{}) cd.onDemandChan <- housekeepingFinishedChan select { @@ -195,20 +203,28 @@ func (cd *containerData) DerivedStats() (v2.DerivedStats, error) { return cd.summaryReader.DerivedStats() } -func (cd *containerData) getCgroupPath(cgroups string) (string, error) { +func (cd *containerData) getCgroupPath(cgroups string) string { if cgroups == "-" { - return "/", nil + return "/" } if strings.HasPrefix(cgroups, "0::") { - return cgroups[3:], nil + return cgroups[3:] } - matches := cgroupPathRegExp.FindSubmatch([]byte(cgroups)) + matches := cgroupMemoryPathRegExp.FindSubmatch([]byte(cgroups)) if len(matches) != 2 { - klog.V(3).Infof("failed to get memory cgroup path from %q", cgroups) - // return root in case of failures - memory hierarchy might not be enabled. - return "/", nil + klog.V(3).Infof( + "failed to get memory cgroup path from %q, will try to get cpu cgroup path", + cgroups, + ) + // On some systems (e.g. Raspberry PI 4) cgroup memory controlled is disabled by default. + matches = cgroupCPUPathRegExp.FindSubmatch([]byte(cgroups)) + if len(matches) != 2 { + klog.V(3).Infof("failed to get cpu cgroup path from %q; assuming root cgroup", cgroups) + // return root in case of failures - memory hierarchy might not be enabled. + return "/" + } } - return string(matches[1]), nil + return string(matches[1]) } // Returns contents of a file inside the container root. @@ -271,10 +287,7 @@ func (cd *containerData) getContainerPids(inHostNamespace bool) ([]string, error return nil, fmt.Errorf("expected at least %d fields, found %d: output: %q", expectedFields, len(fields), line) } pid := fields[0] - cgroup, err := cd.getCgroupPath(fields[1]) - if err != nil { - return nil, fmt.Errorf("could not parse cgroup path from %q: %v", fields[1], err) - } + cgroup := cd.getCgroupPath(fields[1]) if cd.info.Name == cgroup { pids = append(pids, pid) } @@ -283,106 +296,130 @@ func (cd *containerData) getContainerPids(inHostNamespace bool) ([]string, error } func (cd *containerData) GetProcessList(cadvisorContainer string, inHostNamespace bool) ([]v2.ProcessInfo, error) { - // report all processes for root. - isRoot := cd.info.Name == "/" - rootfs := "/" - if !inHostNamespace { - rootfs = "/rootfs" - } format := "user,pid,ppid,stime,pcpu,pmem,rss,vsz,stat,time,comm,psr,cgroup" out, err := cd.getPsOutput(inHostNamespace, format) if err != nil { return nil, err } - expectedFields := 13 + return cd.parseProcessList(cadvisorContainer, inHostNamespace, out) +} + +func (cd *containerData) parseProcessList(cadvisorContainer string, inHostNamespace bool, out []byte) ([]v2.ProcessInfo, error) { + rootfs := "/" + if !inHostNamespace { + rootfs = "/rootfs" + } processes := []v2.ProcessInfo{} lines := strings.Split(string(out), "\n") for _, line := range lines[1:] { - if len(line) == 0 { + processInfo, err := cd.parsePsLine(line, cadvisorContainer, inHostNamespace) + if err != nil { + return nil, fmt.Errorf("could not parse line %s: %v", line, err) + } + if processInfo == nil { continue } - fields := strings.Fields(line) - if len(fields) < expectedFields { - return nil, fmt.Errorf("expected at least %d fields, found %d: output: %q", expectedFields, len(fields), line) - } - pid, err := strconv.Atoi(fields[1]) - if err != nil { - return nil, fmt.Errorf("invalid pid %q: %v", fields[1], err) - } - ppid, err := strconv.Atoi(fields[2]) - if err != nil { - return nil, fmt.Errorf("invalid ppid %q: %v", fields[2], err) - } - percentCPU, err := strconv.ParseFloat(fields[4], 32) - if err != nil { - return nil, fmt.Errorf("invalid cpu percent %q: %v", fields[4], err) - } - percentMem, err := strconv.ParseFloat(fields[5], 32) - if err != nil { - return nil, fmt.Errorf("invalid memory percent %q: %v", fields[5], err) - } - rss, err := strconv.ParseUint(fields[6], 0, 64) - if err != nil { - return nil, fmt.Errorf("invalid rss %q: %v", fields[6], err) - } - // convert to bytes - rss *= 1024 - vs, err := strconv.ParseUint(fields[7], 0, 64) - if err != nil { - return nil, fmt.Errorf("invalid virtual size %q: %v", fields[7], err) - } - // convert to bytes - vs *= 1024 - psr, err := strconv.Atoi(fields[11]) - if err != nil { - return nil, fmt.Errorf("invalid pid %q: %v", fields[1], err) - } - - cgroup, err := cd.getCgroupPath(fields[12]) - if err != nil { - return nil, fmt.Errorf("could not parse cgroup path from %q: %v", fields[11], err) - } - // Remove the ps command we just ran from cadvisor container. - // Not necessary, but makes the cadvisor page look cleaner. - if !inHostNamespace && cadvisorContainer == cgroup && fields[10] == "ps" { - continue - } - var cgroupPath string - if isRoot { - cgroupPath = cgroup - } var fdCount int - dirPath := path.Join(rootfs, "/proc", strconv.Itoa(pid), "fd") + dirPath := path.Join(rootfs, "/proc", strconv.Itoa(processInfo.Pid), "fd") fds, err := ioutil.ReadDir(dirPath) if err != nil { klog.V(4).Infof("error while listing directory %q to measure fd count: %v", dirPath, err) continue } fdCount = len(fds) + processInfo.FdCount = fdCount - if isRoot || cd.info.Name == cgroup { - processes = append(processes, v2.ProcessInfo{ - User: fields[0], - Pid: pid, - Ppid: ppid, - StartTime: fields[3], - PercentCpu: float32(percentCPU), - PercentMemory: float32(percentMem), - RSS: rss, - VirtualSize: vs, - Status: fields[8], - RunningTime: fields[9], - Cmd: fields[10], - CgroupPath: cgroupPath, - FdCount: fdCount, - Psr: psr, - }) - } + processes = append(processes, *processInfo) } return processes, nil } +func (cd *containerData) isRoot() bool { + return cd.info.Name == "/" +} + +func (cd *containerData) parsePsLine(line, cadvisorContainer string, inHostNamespace bool) (*v2.ProcessInfo, error) { + const expectedFields = 13 + if len(line) == 0 { + return nil, nil + } + + info := v2.ProcessInfo{} + var err error + + fields := strings.Fields(line) + if len(fields) < expectedFields { + return nil, fmt.Errorf("expected at least %d fields, found %d: output: %q", expectedFields, len(fields), line) + } + info.User = fields[0] + info.StartTime = fields[3] + info.Status = fields[8] + info.RunningTime = fields[9] + + info.Pid, err = strconv.Atoi(fields[1]) + if err != nil { + return nil, fmt.Errorf("invalid pid %q: %v", fields[1], err) + } + info.Ppid, err = strconv.Atoi(fields[2]) + if err != nil { + return nil, fmt.Errorf("invalid ppid %q: %v", fields[2], err) + } + + percentCPU, err := strconv.ParseFloat(fields[4], 32) + if err != nil { + return nil, fmt.Errorf("invalid cpu percent %q: %v", fields[4], err) + } + info.PercentCpu = float32(percentCPU) + percentMem, err := strconv.ParseFloat(fields[5], 32) + if err != nil { + return nil, fmt.Errorf("invalid memory percent %q: %v", fields[5], err) + } + info.PercentMemory = float32(percentMem) + + info.RSS, err = strconv.ParseUint(fields[6], 0, 64) + if err != nil { + return nil, fmt.Errorf("invalid rss %q: %v", fields[6], err) + } + info.VirtualSize, err = strconv.ParseUint(fields[7], 0, 64) + if err != nil { + return nil, fmt.Errorf("invalid virtual size %q: %v", fields[7], err) + } + // convert to bytes + info.RSS *= 1024 + info.VirtualSize *= 1024 + + // According to `man ps`: The following user-defined format specifiers may contain spaces: args, cmd, comm, command, + // fname, ucmd, ucomm, lstart, bsdstart, start. + // Therefore we need to be able to parse comm that consists of multiple space-separated parts. + info.Cmd = strings.Join(fields[10:len(fields)-2], " ") + + // These are last two parts of the line. We create a subslice of `fields` to handle comm that includes spaces. + lastTwoFields := fields[len(fields)-2:] + info.Psr, err = strconv.Atoi(lastTwoFields[0]) + if err != nil { + return nil, fmt.Errorf("invalid psr %q: %v", lastTwoFields[0], err) + } + info.CgroupPath = cd.getCgroupPath(lastTwoFields[1]) + + // Remove the ps command we just ran from cadvisor container. + // Not necessary, but makes the cadvisor page look cleaner. + if !inHostNamespace && cadvisorContainer == info.CgroupPath && info.Cmd == "ps" { + return nil, nil + } + + // Do not report processes from other containers when non-root container requested. + if !cd.isRoot() && info.CgroupPath != cd.info.Name { + return nil, nil + } + + // Remove cgroup information when non-root container requested. + if !cd.isRoot() { + info.CgroupPath = "" + } + return &info, nil +} + func newContainerData(containerName string, memoryCache *memory.InMemoryCache, handler container.ContainerHandler, logUsage bool, collectorManager collector.CollectorManager, maxHousekeepingInterval time.Duration, allowDynamicHousekeeping bool, clock clock.Clock) (*containerData, error) { if memoryCache == nil { return nil, fmt.Errorf("nil memory storage") @@ -516,7 +553,7 @@ func (cd *containerData) housekeeping() { usageCPUNs := uint64(0) for i := range stats { if i > 0 { - usageCPUNs += (stats[i].Cpu.Usage.Total - stats[i-1].Cpu.Usage.Total) + usageCPUNs += stats[i].Cpu.Usage.Total - stats[i-1].Cpu.Usage.Total } } usageMemory := stats[numSamples-1].Memory.Usage @@ -555,6 +592,8 @@ func (cd *containerData) housekeepingTick(timer <-chan time.Time, longHousekeepi klog.V(3).Infof("[%s] Housekeeping took %s", cd.info.Name, duration) } cd.notifyOnDemand() + cd.lock.Lock() + defer cd.lock.Unlock() cd.statsLastUpdatedTime = cd.clock.Now() return true } diff --git a/vendor/github.com/google/cadvisor/metrics/prometheus.go b/vendor/github.com/google/cadvisor/metrics/prometheus.go index 1064e045a2c..7d3f24a99da 100644 --- a/vendor/github.com/google/cadvisor/metrics/prometheus.go +++ b/vendor/github.com/google/cadvisor/metrics/prometheus.go @@ -455,6 +455,16 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri }, }...) } + if includedMetrics.Has(container.CPUSetMetrics) { + c.containerMetrics = append(c.containerMetrics, containerMetric{ + name: "container_memory_migrate", + help: "Memory migrate status.", + valueType: prometheus.GaugeValue, + getValues: func(s *info.ContainerStats) metricValues { + return metricValues{{value: float64(s.CpuSet.MemoryMigrate), timestamp: s.Timestamp}} + }, + }) + } if includedMetrics.Has(container.MemoryNumaMetrics) { c.containerMetrics = append(c.containerMetrics, []containerMetric{ { @@ -757,6 +767,28 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri }, s.Timestamp) }, }, + { + name: "container_blkio_device_usage_total", + help: "Blkio Device bytes usage", + valueType: prometheus.CounterValue, + extraLabels: []string{"device", "major", "minor", "operation"}, + getValues: func(s *info.ContainerStats) metricValues { + var values metricValues + for _, diskStat := range s.DiskIo.IoServiceBytes { + for operation, value := range diskStat.Stats { + values = append(values, metricValue{ + value: float64(value), + labels: []string{diskStat.Device, + strconv.Itoa(int(diskStat.Major)), + strconv.Itoa(int(diskStat.Minor)), + operation}, + timestamp: s.Timestamp, + }) + } + } + return values + }, + }, }...) } if includedMetrics.Has(container.NetworkUsageMetrics) { diff --git a/vendor/github.com/google/cadvisor/metrics/prometheus_fake.go b/vendor/github.com/google/cadvisor/metrics/prometheus_fake.go index 6368c0b75eb..822b3f82c97 100644 --- a/vendor/github.com/google/cadvisor/metrics/prometheus_fake.go +++ b/vendor/github.com/google/cadvisor/metrics/prometheus_fake.go @@ -524,6 +524,21 @@ func (p testSubcontainersInfoProvider) GetRequestedContainersInfo(string, v2.Req TxQueued: 0, }, }, + DiskIo: info.DiskIoStats{ + IoServiceBytes: []info.PerDiskStats{{ + Device: "/dev/sdb", + Major: 8, + Minor: 0, + Stats: map[string]uint64{ + "Async": 1, + "Discard": 2, + "Read": 3, + "Sync": 4, + "Total": 5, + "Write": 6, + }, + }}, + }, Filesystem: []info.FsStats{ { Device: "sda1", @@ -708,6 +723,7 @@ func (p testSubcontainersInfoProvider) GetRequestedContainersInfo(string, v2.Req }, }, }, + CpuSet: info.CPUSetStats{MemoryMigrate: 1}, }, }, }, diff --git a/vendor/github.com/google/cadvisor/resctrl/collector.go b/vendor/github.com/google/cadvisor/resctrl/collector.go index 210156a89b1..f677b8d0441 100644 --- a/vendor/github.com/google/cadvisor/resctrl/collector.go +++ b/vendor/github.com/google/cadvisor/resctrl/collector.go @@ -26,19 +26,19 @@ import ( ) type collector struct { - resctrl intelrdt.IntelRdtManager + resctrl intelrdt.Manager stats.NoopDestroy } func newCollector(id string, resctrlPath string) *collector { collector := &collector{ - resctrl: intelrdt.IntelRdtManager{ - Config: &configs.Config{ + resctrl: intelrdt.NewManager( + &configs.Config{ IntelRdt: &configs.IntelRdt{}, }, - Id: id, - Path: resctrlPath, - }, + id, + resctrlPath, + ), } return collector diff --git a/vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go b/vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go index e652874e52d..32dc838fb91 100644 --- a/vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go +++ b/vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go @@ -28,7 +28,7 @@ import ( var ( legacyContainerRegexp = regexp.MustCompile(`Task in (.*) killed as a result of limit of (.*)`) // Starting in 5.0 linux kernels, the OOM message changed - containerRegexp = regexp.MustCompile(`oom-kill:constraint=(.*),nodemask=(.*),cpuset=(.*),mems_allowed=(.*),oom_memcg=(.*) (.*),task_memcg=(.*),task=(.*),pid=(.*),uid=(.*)`) + containerRegexp = regexp.MustCompile(`oom-kill:constraint=(.*),nodemask=(.*),cpuset=(.*),mems_allowed=(.*),oom_memcg=(.*),task_memcg=(.*),task=(.*),pid=(.*),uid=(.*)`) lastLineRegexp = regexp.MustCompile(`Killed process ([0-9]+) \((.+)\)`) firstLineRegexp = regexp.MustCompile(`invoked oom-killer:`) ) @@ -76,15 +76,15 @@ func getContainerName(line string, currentOomInstance *OomInstance) (bool, error // Fall back to the legacy format if it isn't found here. return false, getLegacyContainerName(line, currentOomInstance) } - currentOomInstance.ContainerName = parsedLine[7] + currentOomInstance.ContainerName = parsedLine[6] currentOomInstance.VictimContainerName = parsedLine[5] currentOomInstance.Constraint = parsedLine[1] - pid, err := strconv.Atoi(parsedLine[9]) + pid, err := strconv.Atoi(parsedLine[8]) if err != nil { return false, err } currentOomInstance.Pid = pid - currentOomInstance.ProcessName = parsedLine[8] + currentOomInstance.ProcessName = parsedLine[7] return true, nil } diff --git a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go index becc4afc475..1be228a0e5f 100644 --- a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go +++ b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go @@ -16,7 +16,6 @@ package sysfs import ( "bytes" - "errors" "fmt" "io/ioutil" "os" @@ -37,9 +36,21 @@ const ( ppcDevTree = "/proc/device-tree" s390xDevTree = "/etc" // s390/s390x changes - coreIDFilePath = "/topology/core_id" - packageIDFilePath = "/topology/physical_package_id" - meminfoFile = "meminfo" + meminfoFile = "meminfo" + + sysFsCPUTopology = "topology" + + // CPUPhysicalPackageID is a physical package id of cpu#. Typically corresponds to a physical socket number, + // but the actual value is architecture and platform dependent. + CPUPhysicalPackageID = "physical_package_id" + // CPUCoreID is the CPU core ID of cpu#. Typically it is the hardware platform's identifier + // (rather than the kernel's). The actual value is architecture and platform dependent. + CPUCoreID = "core_id" + + coreIDFilePath = "/" + sysFsCPUTopology + "/core_id" + packageIDFilePath = "/" + sysFsCPUTopology + "/physical_package_id" + + // memory size calculations cpuDirPattern = "cpu*[0-9]" nodeDirPattern = "node*[0-9]" @@ -325,9 +336,9 @@ func (fs *realSysFs) GetSystemUUID() (string, error) { if id, err := ioutil.ReadFile(path.Join(dmiDir, "id", "product_uuid")); err == nil { return strings.TrimSpace(string(id)), nil } else if id, err = ioutil.ReadFile(path.Join(ppcDevTree, "system-id")); err == nil { - return strings.TrimSpace(string(id)), nil + return strings.TrimSpace(strings.TrimRight(string(id), "\000")), nil } else if id, err = ioutil.ReadFile(path.Join(ppcDevTree, "vm,uuid")); err == nil { - return strings.TrimSpace(string(id)), nil + return strings.TrimSpace(strings.TrimRight(string(id), "\000")), nil } else if id, err = ioutil.ReadFile(path.Join(s390xDevTree, "machine-id")); err == nil { return strings.TrimSpace(string(id)), nil } else { @@ -335,25 +346,152 @@ func (fs *realSysFs) GetSystemUUID() (string, error) { } } -func (fs *realSysFs) IsCPUOnline(dir string) bool { - cpuPath := fmt.Sprintf("%s/online", dir) - content, err := ioutil.ReadFile(cpuPath) +func (fs *realSysFs) IsCPUOnline(cpuPath string) bool { + onlinePath, err := filepath.Abs(cpuPath + "/../online") if err != nil { - pathErr, ok := err.(*os.PathError) - if ok { - if errors.Is(pathErr.Unwrap(), os.ErrNotExist) && isZeroCPU(dir) { - return true - } - } - klog.Warningf("unable to read %s: %s", cpuPath, err.Error()) + klog.V(1).Infof("Unable to get absolute path for %s", cpuPath) return false } - trimmed := bytes.TrimSpace(content) - return len(trimmed) == 1 && trimmed[0] == 49 + + // Quick check to determine if file exists: if it does not then kernel CPU hotplug is disabled and all CPUs are online. + _, err = os.Stat(onlinePath) + if err != nil && os.IsNotExist(err) { + return true + } + if err != nil { + klog.V(1).Infof("Unable to stat %s: %s", onlinePath, err) + } + + cpuID, err := getCPUID(cpuPath) + if err != nil { + klog.V(1).Infof("Unable to get CPU ID from path %s: %s", cpuPath, err) + return false + } + + isOnline, err := isCPUOnline(onlinePath, cpuID) + if err != nil { + klog.V(1).Infof("Unable to get online CPUs list: %s", err) + return false + } + return isOnline } -func isZeroCPU(dir string) bool { - regex := regexp.MustCompile("cpu([0-9]*)") +func getCPUID(dir string) (uint16, error) { + regex := regexp.MustCompile("cpu([0-9]+)") matches := regex.FindStringSubmatch(dir) - return len(matches) == 2 && matches[1] == "0" + if len(matches) == 2 { + id, err := strconv.Atoi(matches[1]) + if err != nil { + return 0, err + } + return uint16(id), nil + } + return 0, fmt.Errorf("can't get CPU ID from %s", dir) +} + +// isCPUOnline is copied from github.com/opencontainers/runc/libcontainer/cgroups/fs and modified to suite cAdvisor +// needs as Apache 2.0 license allows. +// It parses CPU list (such as: 0,3-5,10) into a struct that allows to determine quickly if CPU or particular ID is online. +// see: https://github.com/opencontainers/runc/blob/ab27e12cebf148aa5d1ee3ad13d9fc7ae12bf0b6/libcontainer/cgroups/fs/cpuset.go#L45 +func isCPUOnline(path string, cpuID uint16) (bool, error) { + fileContent, err := ioutil.ReadFile(path) + if err != nil { + return false, err + } + if len(fileContent) == 0 { + return false, fmt.Errorf("%s found to be empty", path) + } + + cpuList := strings.TrimSpace(string(fileContent)) + for _, s := range strings.Split(cpuList, ",") { + splitted := strings.SplitN(s, "-", 3) + switch len(splitted) { + case 3: + return false, fmt.Errorf("invalid values in %s", path) + case 2: + min, err := strconv.ParseUint(splitted[0], 10, 16) + if err != nil { + return false, err + } + max, err := strconv.ParseUint(splitted[1], 10, 16) + if err != nil { + return false, err + } + if min > max { + return false, fmt.Errorf("invalid values in %s", path) + } + for i := min; i <= max; i++ { + if uint16(i) == cpuID { + return true, nil + } + } + case 1: + value, err := strconv.ParseUint(s, 10, 16) + if err != nil { + return false, err + } + if uint16(value) == cpuID { + return true, nil + } + } + } + + return false, nil +} + +// Looks for sysfs cpu path containing given CPU property, e.g. core_id or physical_package_id +// and returns number of unique values of given property, exemplary usage: getting number of CPU physical cores +func GetUniqueCPUPropertyCount(cpuBusPath string, propertyName string) int { + absCPUBusPath, err := filepath.Abs(cpuBusPath) + if err != nil { + klog.Errorf("Cannot make %s absolute", cpuBusPath) + return 0 + } + pathPattern := absCPUBusPath + "/cpu*[0-9]" + sysCPUPaths, err := filepath.Glob(pathPattern) + if err != nil { + klog.Errorf("Cannot find files matching pattern (pathPattern: %s), number of unique %s set to 0", pathPattern, propertyName) + return 0 + } + onlinePath, err := filepath.Abs(cpuBusPath + "/online") + if err != nil { + klog.V(1).Infof("Unable to get absolute path for %s", cpuBusPath+"/../online") + return 0 + } + + if err != nil { + klog.V(1).Infof("Unable to get online CPUs list: %s", err) + return 0 + } + uniques := make(map[string]bool) + for _, sysCPUPath := range sysCPUPaths { + cpuID, err := getCPUID(sysCPUPath) + if err != nil { + klog.V(1).Infof("Unable to get CPU ID from path %s: %s", sysCPUPath, err) + return 0 + } + isOnline, err := isCPUOnline(onlinePath, cpuID) + if err != nil && !os.IsNotExist(err) { + klog.V(1).Infof("Unable to determine CPU online state: %s", err) + continue + } + if !isOnline && !os.IsNotExist(err) { + continue + } + propertyPath := filepath.Join(sysCPUPath, sysFsCPUTopology, propertyName) + propertyVal, err := ioutil.ReadFile(propertyPath) + if err != nil { + klog.Warningf("Cannot open %s, assuming 0 for %s of CPU %d", propertyPath, propertyName, cpuID) + propertyVal = []byte("0") + } + packagePath := filepath.Join(sysCPUPath, sysFsCPUTopology, CPUPhysicalPackageID) + packageVal, err := ioutil.ReadFile(packagePath) + if err != nil { + klog.Warningf("Cannot open %s, assuming 0 %s of CPU %d", packagePath, CPUPhysicalPackageID, cpuID) + packageVal = []byte("0") + + } + uniques[fmt.Sprintf("%s_%s", bytes.TrimSpace(propertyVal), bytes.TrimSpace(packageVal))] = true + } + return len(uniques) } diff --git a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go new file mode 100644 index 00000000000..86b8d02467e --- /dev/null +++ b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go @@ -0,0 +1,19 @@ +// +build !x86 + +// Copyright 2021 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sysfs + +var isX86 = false diff --git a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go new file mode 100644 index 00000000000..fd6ff358f6f --- /dev/null +++ b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go @@ -0,0 +1,19 @@ +// +build x86 + +// Copyright 2021 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sysfs + +var isX86 = true diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE b/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE deleted file mode 100644 index 14127cd831e..00000000000 --- a/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -(The MIT License) - -Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md b/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md deleted file mode 100644 index 09a4a35c9bb..00000000000 --- a/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Windows Terminal Sequences - -This library allow for enabling Windows terminal color support for Go. - -See [Console Virtual Terminal Sequences](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences) for details. - -## Usage - -```go -import ( - "syscall" - - sequences "github.com/konsorten/go-windows-terminal-sequences" -) - -func main() { - sequences.EnableVirtualTerminalProcessing(syscall.Stdout, true) -} - -``` - -## Authors - -The tool is sponsored by the [marvin + konsorten GmbH](http://www.konsorten.de). - -We thank all the authors who provided code to this library: - -* Felix Kollmann -* Nicolas Perraut -* @dirty49374 - -## License - -(The MIT License) - -Copyright (c) 2018 marvin + konsorten GmbH (open-source@konsorten.de) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod b/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod deleted file mode 100644 index 716c6131256..00000000000 --- a/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod +++ /dev/null @@ -1 +0,0 @@ -module github.com/konsorten/go-windows-terminal-sequences diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go deleted file mode 100644 index 57f530ae83f..00000000000 --- a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build windows - -package sequences - -import ( - "syscall" -) - -var ( - kernel32Dll *syscall.LazyDLL = syscall.NewLazyDLL("Kernel32.dll") - setConsoleMode *syscall.LazyProc = kernel32Dll.NewProc("SetConsoleMode") -) - -func EnableVirtualTerminalProcessing(stream syscall.Handle, enable bool) error { - const ENABLE_VIRTUAL_TERMINAL_PROCESSING uint32 = 0x4 - - var mode uint32 - err := syscall.GetConsoleMode(syscall.Stdout, &mode) - if err != nil { - return err - } - - if enable { - mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING - } else { - mode &^= ENABLE_VIRTUAL_TERMINAL_PROCESSING - } - - ret, _, err := setConsoleMode.Call(uintptr(stream), uintptr(mode)) - if ret == 0 { - return err - } - - return nil -} diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go deleted file mode 100644 index df61a6f2f6f..00000000000 --- a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build linux darwin - -package sequences - -import ( - "fmt" -) - -func EnableVirtualTerminalProcessing(stream uintptr, enable bool) error { - return fmt.Errorf("windows only package") -} diff --git a/vendor/github.com/moby/sys/mountinfo/doc.go b/vendor/github.com/moby/sys/mountinfo/doc.go new file mode 100644 index 00000000000..b80e05efd05 --- /dev/null +++ b/vendor/github.com/moby/sys/mountinfo/doc.go @@ -0,0 +1,44 @@ +// Package mountinfo provides a set of functions to retrieve information about OS mounts. +// +// Currently it supports Linux. For historical reasons, there is also some support for FreeBSD and OpenBSD, +// and a shallow implementation for Windows, but in general this is Linux-only package, so +// the rest of the document only applies to Linux, unless explicitly specified otherwise. +// +// In Linux, information about mounts seen by the current process is available from +// /proc/self/mountinfo. Note that due to mount namespaces, different processes can +// see different mounts. A per-process mountinfo table is available from /proc//mountinfo, +// where is a numerical process identifier. +// +// In general, /proc is not a very efficient interface, and mountinfo is not an exception. +// For example, there is no way to get information about a specific mount point (i.e. it +// is all-or-nothing). This package tries to hide the /proc ineffectiveness by using +// parse filters while reading mountinfo. A filter can skip some entries, or stop +// processing the rest of the file once the needed information is found. +// +// For mountinfo filters that accept path as an argument, the path must be absolute, +// having all symlinks resolved, and being cleaned (i.e. no extra slashes or dots). +// One way to achieve all of the above is to employ filepath.Abs followed by +// filepath.EvalSymlinks (the latter calls filepath.Clean on the result so +// there is no need to explicitly call filepath.Clean). +// +// NOTE that in many cases there is no need to consult mountinfo at all. Here are some +// of the cases where mountinfo should not be parsed: +// +// 1. Before performing a mount. Usually, this is not needed, but if required (say to +// prevent over-mounts), to check whether a directory is mounted, call os.Lstat +// on it and its parent directory, and compare their st.Sys().(*syscall.Stat_t).Dev +// fields -- if they differ, then the directory is the mount point. NOTE this does +// not work for bind mounts. Optionally, the filesystem type can also be checked +// by calling unix.Statfs and checking the Type field (i.e. filesystem type). +// +// 2. After performing a mount. If there is no error returned, the mount succeeded; +// checking the mount table for a new mount is redundant and expensive. +// +// 3. Before performing an unmount. It is more efficient to do an unmount and ignore +// a specific error (EINVAL) which tells the directory is not mounted. +// +// 4. After performing an unmount. If there is no error returned, the unmount succeeded. +// +// 5. To find the mount point root of a specific directory. You can perform os.Stat() +// on the directory and traverse up until the Dev field of a parent directory differs. +package mountinfo diff --git a/vendor/github.com/moby/sys/mountinfo/go.mod b/vendor/github.com/moby/sys/mountinfo/go.mod index 10d9a15a6c7..9749ea96d9d 100644 --- a/vendor/github.com/moby/sys/mountinfo/go.mod +++ b/vendor/github.com/moby/sys/mountinfo/go.mod @@ -1,3 +1,5 @@ module github.com/moby/sys/mountinfo go 1.14 + +require golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 diff --git a/vendor/github.com/moby/sys/mountinfo/go.sum b/vendor/github.com/moby/sys/mountinfo/go.sum new file mode 100644 index 00000000000..2a5be7ea843 --- /dev/null +++ b/vendor/github.com/moby/sys/mountinfo/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/moby/sys/mountinfo/mounted_linux.go b/vendor/github.com/moby/sys/mountinfo/mounted_linux.go new file mode 100644 index 00000000000..bc9f6b2ad3d --- /dev/null +++ b/vendor/github.com/moby/sys/mountinfo/mounted_linux.go @@ -0,0 +1,58 @@ +package mountinfo + +import ( + "os" + "path/filepath" + + "golang.org/x/sys/unix" +) + +// mountedByOpenat2 is a method of detecting a mount that works for all kinds +// of mounts (incl. bind mounts), but requires a recent (v5.6+) linux kernel. +func mountedByOpenat2(path string) (bool, error) { + dir, last := filepath.Split(path) + + dirfd, err := unix.Openat2(unix.AT_FDCWD, dir, &unix.OpenHow{ + Flags: unix.O_PATH | unix.O_CLOEXEC, + }) + if err != nil { + if err == unix.ENOENT { // not a mount + return false, nil + } + return false, &os.PathError{Op: "openat2", Path: dir, Err: err} + } + fd, err := unix.Openat2(dirfd, last, &unix.OpenHow{ + Flags: unix.O_PATH | unix.O_CLOEXEC | unix.O_NOFOLLOW, + Resolve: unix.RESOLVE_NO_XDEV, + }) + _ = unix.Close(dirfd) + switch err { + case nil: // definitely not a mount + _ = unix.Close(fd) + return false, nil + case unix.EXDEV: // definitely a mount + return true, nil + case unix.ENOENT: // not a mount + return false, nil + } + // not sure + return false, &os.PathError{Op: "openat2", Path: path, Err: err} +} + +func mounted(path string) (bool, error) { + // Try a fast path, using openat2() with RESOLVE_NO_XDEV. + mounted, err := mountedByOpenat2(path) + if err == nil { + return mounted, nil + } + // Another fast path: compare st.st_dev fields. + mounted, err = mountedByStat(path) + // This does not work for bind mounts, so false negative + // is possible, therefore only trust if return is true. + if mounted && err == nil { + return mounted, nil + } + + // Fallback to parsing mountinfo + return mountedByMountinfo(path) +} diff --git a/vendor/github.com/moby/sys/mountinfo/mounted_unix.go b/vendor/github.com/moby/sys/mountinfo/mounted_unix.go new file mode 100644 index 00000000000..efb03978b1e --- /dev/null +++ b/vendor/github.com/moby/sys/mountinfo/mounted_unix.go @@ -0,0 +1,66 @@ +// +build linux freebsd,cgo openbsd,cgo + +package mountinfo + +import ( + "errors" + "fmt" + "os" + "path/filepath" + + "golang.org/x/sys/unix" +) + +func mountedByStat(path string) (bool, error) { + var st unix.Stat_t + + if err := unix.Lstat(path, &st); err != nil { + if err == unix.ENOENT { + // Treat ENOENT as "not mounted". + return false, nil + } + return false, &os.PathError{Op: "stat", Path: path, Err: err} + } + dev := st.Dev + parent := filepath.Dir(path) + if err := unix.Lstat(parent, &st); err != nil { + return false, &os.PathError{Op: "stat", Path: parent, Err: err} + } + if dev != st.Dev { + // Device differs from that of parent, + // so definitely a mount point. + return true, nil + } + // NB: this does not detect bind mounts on Linux. + return false, nil +} + +func normalizePath(path string) (realPath string, err error) { + if realPath, err = filepath.Abs(path); err != nil { + return "", fmt.Errorf("unable to get absolute path for %q: %w", path, err) + } + if realPath, err = filepath.EvalSymlinks(realPath); err != nil { + return "", fmt.Errorf("failed to canonicalise path for %q: %w", path, err) + } + if _, err := os.Stat(realPath); err != nil { + return "", fmt.Errorf("failed to stat target of %q: %w", path, err) + } + return realPath, nil +} + +func mountedByMountinfo(path string) (bool, error) { + path, err := normalizePath(path) + if err != nil { + if errors.Is(err, unix.ENOENT) { + // treat ENOENT as "not mounted" + return false, nil + } + return false, err + } + entries, err := GetMounts(SingleEntryFilter(path)) + if err != nil { + return false, err + } + + return len(entries) > 0, nil +} diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo.go b/vendor/github.com/moby/sys/mountinfo/mountinfo.go index 136b14167b2..fe828c8f583 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo.go @@ -1,6 +1,8 @@ package mountinfo -import "io" +import ( + "os" +) // GetMounts retrieves a list of mounts for the current running process, // with an optional filter applied (use nil for no filter). @@ -8,23 +10,17 @@ func GetMounts(f FilterFunc) ([]*Info, error) { return parseMountTable(f) } -// GetMountsFromReader retrieves a list of mounts from the -// reader provided, with an optional filter applied (use nil -// for no filter). This can be useful in tests or benchmarks -// that provide a fake mountinfo data. -func GetMountsFromReader(reader io.Reader, f FilterFunc) ([]*Info, error) { - return parseInfoFile(reader, f) -} - -// Mounted determines if a specified mountpoint has been mounted. -// On Linux it looks at /proc/self/mountinfo. -func Mounted(mountpoint string) (bool, error) { - entries, err := GetMounts(SingleEntryFilter(mountpoint)) - if err != nil { - return false, err +// Mounted determines if a specified path is a mount point. +// +// The argument must be an absolute path, with all symlinks resolved, and clean. +// One way to ensure it is to process the path using filepath.Abs followed by +// filepath.EvalSymlinks before calling this function. +func Mounted(path string) (bool, error) { + // root is always mounted + if path == string(os.PathSeparator) { + return true, nil } - - return len(entries) > 0, nil + return mounted(path) } // Info reveals information about a particular mounted filesystem. This @@ -50,18 +46,18 @@ type Info struct { // Mountpoint indicates the mount point relative to the process's root. Mountpoint string - // Opts represents mount-specific options. - Opts string + // Options represents mount-specific options. + Options string // Optional represents optional fields. Optional string - // Fstype indicates the type of filesystem, such as EXT3. - Fstype string + // FSType indicates the type of filesystem, such as EXT3. + FSType string // Source indicates filesystem specific information or "none". Source string - // VfsOpts represents per super block options. - VfsOpts string + // VFSOptions represents per super block options. + VFSOptions string } diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go similarity index 73% rename from vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go rename to vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go index a7dbb1b46b7..b1c12d02b51 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go @@ -1,3 +1,5 @@ +// +build freebsd,cgo openbsd,cgo + package mountinfo /* @@ -33,7 +35,7 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) { var mountinfo Info var skip, stop bool mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0]) - mountinfo.Fstype = C.GoString(&entry.f_fstypename[0]) + mountinfo.FSType = C.GoString(&entry.f_fstypename[0]) mountinfo.Source = C.GoString(&entry.f_mntfromname[0]) if filter != nil { @@ -51,3 +53,15 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) { } return out, nil } + +func mounted(path string) (bool, error) { + // Fast path: compare st.st_dev fields. + // This should always work for FreeBSD and OpenBSD. + mounted, err := mountedByStat(path) + if err == nil { + return mounted, nil + } + + // Fallback to parsing mountinfo + return mountedByMountinfo(path) +} diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go index 79502646597..5869b2cee39 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go @@ -6,16 +6,16 @@ import "strings" // used to filter out mountinfo entries we're not interested in, // and/or stop further processing if we found what we wanted. // -// It takes a pointer to the Info struct (not fully populated, -// currently only Mountpoint, Fstype, Source, and (on Linux) -// VfsOpts are filled in), and returns two booleans: +// It takes a pointer to the Info struct (fully populated with all available +// fields on the GOOS platform), and returns two booleans: // -// - skip: true if the entry should be skipped -// - stop: true if parsing should be stopped after the entry +// skip: true if the entry should be skipped; +// +// stop: true if parsing should be stopped after the entry. type FilterFunc func(*Info) (skip, stop bool) // PrefixFilter discards all entries whose mount points -// do not start with a specific prefix +// do not start with a specific prefix. func PrefixFilter(prefix string) FilterFunc { return func(m *Info) (bool, bool) { skip := !strings.HasPrefix(m.Mountpoint, prefix) @@ -23,7 +23,7 @@ func PrefixFilter(prefix string) FilterFunc { } } -// SingleEntryFilter looks for a specific entry +// SingleEntryFilter looks for a specific entry. func SingleEntryFilter(mp string) FilterFunc { return func(m *Info) (bool, bool) { if m.Mountpoint == mp { @@ -36,8 +36,8 @@ func SingleEntryFilter(mp string) FilterFunc { // ParentsFilter returns all entries whose mount points // can be parents of a path specified, discarding others. // -// For example, given `/var/lib/docker/something`, entries -// like `/var/lib/docker`, `/var` and `/` are returned. +// For example, given /var/lib/docker/something, entries +// like /var/lib/docker, /var and / are returned. func ParentsFilter(path string) FilterFunc { return func(m *Info) (bool, bool) { skip := !strings.HasPrefix(path, m.Mountpoint) @@ -45,12 +45,12 @@ func ParentsFilter(path string) FilterFunc { } } -// FstypeFilter returns all entries that match provided fstype(s). -func FstypeFilter(fstype ...string) FilterFunc { +// FSTypeFilter returns all entries that match provided fstype(s). +func FSTypeFilter(fstype ...string) FilterFunc { return func(m *Info) (bool, bool) { for _, t := range fstype { - if m.Fstype == t { - return false, false // don't skeep, keep going + if m.FSType == t { + return false, false // don't skip, keep going } } return true, false // skip, keep going diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go index 2d630c8dc58..e591c836538 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go @@ -1,5 +1,3 @@ -// +build go1.13 - package mountinfo import ( @@ -11,14 +9,18 @@ import ( "strings" ) -func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) { +// GetMountsFromReader retrieves a list of mounts from the +// reader provided, with an optional filter applied (use nil +// for no filter). This can be useful in tests or benchmarks +// that provide a fake mountinfo data. +// +// This function is Linux-specific. +func GetMountsFromReader(r io.Reader, filter FilterFunc) ([]*Info, error) { s := bufio.NewScanner(r) out := []*Info{} - var err error for s.Scan() { - if err = s.Err(); err != nil { - return nil, err - } + var err error + /* See http://man7.org/linux/man-pages/man5/proc.5.html @@ -70,26 +72,19 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) { p := &Info{} - // Fill in the fields that a filter might check - p.Mountpoint, err = strconv.Unquote(`"` + fields[4] + `"`) + p.Mountpoint, err = unescape(fields[4]) if err != nil { - return nil, fmt.Errorf("Parsing '%s' failed: unable to unquote mount point field: %w", fields[4], err) + return nil, fmt.Errorf("Parsing '%s' failed: mount point: %w", fields[4], err) } - p.Fstype = fields[sepIdx+1] - p.Source = fields[sepIdx+2] - p.VfsOpts = fields[sepIdx+3] - - // Run a filter soon so we can skip parsing/adding entries - // the caller is not interested in - var skip, stop bool - if filter != nil { - skip, stop = filter(p) - if skip { - continue - } + p.FSType, err = unescape(fields[sepIdx+1]) + if err != nil { + return nil, fmt.Errorf("Parsing '%s' failed: fstype: %w", fields[sepIdx+1], err) } - - // Fill in the rest of the fields + p.Source, err = unescape(fields[sepIdx+2]) + if err != nil { + return nil, fmt.Errorf("Parsing '%s' failed: source: %w", fields[sepIdx+2], err) + } + p.VFSOptions = fields[sepIdx+3] // ignore any numbers parsing errors, as there should not be any p.ID, _ = strconv.Atoi(fields[0]) @@ -101,12 +96,12 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) { p.Major, _ = strconv.Atoi(mm[0]) p.Minor, _ = strconv.Atoi(mm[1]) - p.Root, err = strconv.Unquote(`"` + fields[3] + `"`) + p.Root, err = unescape(fields[3]) if err != nil { - return nil, fmt.Errorf("Parsing '%s' failed: unable to unquote root field: %w", fields[3], err) + return nil, fmt.Errorf("Parsing '%s' failed: root: %w", fields[3], err) } - p.Opts = fields[5] + p.Options = fields[5] // zero or more optional fields switch { @@ -118,11 +113,23 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) { p.Optional = strings.Join(fields[6:sepIdx-1], " ") } + // Run the filter after parsing all of the fields. + var skip, stop bool + if filter != nil { + skip, stop = filter(p) + if skip { + continue + } + } + out = append(out, p) if stop { break } } + if err := s.Err(); err != nil { + return nil, err + } return out, nil } @@ -135,12 +142,17 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) { } defer f.Close() - return parseInfoFile(f, filter) + return GetMountsFromReader(f, filter) } -// PidMountInfo collects the mounts for a specific process ID. If the process -// ID is unknown, it is better to use `GetMounts` which will inspect -// "/proc/self/mountinfo" instead. +// PidMountInfo retrieves the list of mounts from a given process' mount +// namespace. Unless there is a need to get mounts from a mount namespace +// different from that of a calling process, use GetMounts. +// +// This function is Linux-specific. +// +// Deprecated: this will be removed before v1; use GetMountsFromReader with +// opened /proc//mountinfo as an argument instead. func PidMountInfo(pid int) ([]*Info, error) { f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid)) if err != nil { @@ -148,5 +160,63 @@ func PidMountInfo(pid int) ([]*Info, error) { } defer f.Close() - return parseInfoFile(f, nil) + return GetMountsFromReader(f, nil) +} + +// A few specific characters in mountinfo path entries (root and mountpoint) +// are escaped using a backslash followed by a character's ascii code in octal. +// +// space -- as \040 +// tab (aka \t) -- as \011 +// newline (aka \n) -- as \012 +// backslash (aka \\) -- as \134 +// +// This function converts path from mountinfo back, i.e. it unescapes the above sequences. +func unescape(path string) (string, error) { + // try to avoid copying + if strings.IndexByte(path, '\\') == -1 { + return path, nil + } + + // The following code is UTF-8 transparent as it only looks for some + // specific characters (backslash and 0..7) with values < utf8.RuneSelf, + // and everything else is passed through as is. + buf := make([]byte, len(path)) + bufLen := 0 + for i := 0; i < len(path); i++ { + if path[i] != '\\' { + buf[bufLen] = path[i] + bufLen++ + continue + } + s := path[i:] + if len(s) < 4 { + // too short + return "", fmt.Errorf("bad escape sequence %q: too short", s) + } + c := s[1] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7': + v := c - '0' + for j := 2; j < 4; j++ { // one digit already; two more + if s[j] < '0' || s[j] > '7' { + return "", fmt.Errorf("bad escape sequence %q: not a digit", s[:3]) + } + x := s[j] - '0' + v = (v << 3) | x + } + if v > 255 { + return "", fmt.Errorf("bad escape sequence %q: out of range" + s[:3]) + } + buf[bufLen] = v + bufLen++ + i += 3 + continue + default: + return "", fmt.Errorf("bad escape sequence %q: not a digit" + s[:3]) + + } + } + + return string(buf[:bufLen]), nil } diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go index dc186921189..d33ebca0968 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go @@ -1,17 +1,18 @@ -// +build !windows,!linux,!freebsd freebsd,!cgo +// +build !windows,!linux,!freebsd,!openbsd freebsd,!cgo openbsd,!cgo package mountinfo import ( "fmt" - "io" "runtime" ) +var errNotImplemented = fmt.Errorf("not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) + func parseMountTable(_ FilterFunc) ([]*Info, error) { - return nil, fmt.Errorf("mount.parseMountTable is not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) + return nil, errNotImplemented } -func parseInfoFile(_ io.Reader, f FilterFunc) ([]*Info, error) { - return parseMountTable(f) +func mounted(path string) (bool, error) { + return false, errNotImplemented } diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go index 69ffdc52b6b..13fad165e5d 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go @@ -1,12 +1,10 @@ package mountinfo -import "io" - func parseMountTable(_ FilterFunc) ([]*Info, error) { // Do NOT return an error! return nil, nil } -func parseInfoFile(_ io.Reader, f FilterFunc) ([]*Info, error) { - return parseMountTable(f) +func mounted(_ string) (bool, error) { + return false, nil } diff --git a/vendor/github.com/moby/term/.gitignore b/vendor/github.com/moby/term/.gitignore index df63b129a79..b0747ff010a 100644 --- a/vendor/github.com/moby/term/.gitignore +++ b/vendor/github.com/moby/term/.gitignore @@ -1,24 +1,8 @@ -# Docker project generated files to ignore -# if you want to ignore files created by your editor/tools, -# please consider a global .gitignore https://help.github.com/articles/ignoring-files -*.exe -*.exe~ -*.gz -*.orig -test.main -.*.swp -.DS_Store -# a .bashrc may be added to customize the build environment -.bashrc -.editorconfig -.gopath/ -.go-pkg-cache/ -.idea/ -autogen/ -bundles/ -cmd/dockerd/dockerd -contrib/builder/rpm/*/changelog -vendor/pkg/ -go-test-report.json +# if you want to ignore files created by your editor/tools, consider using a +# global .gitignore or .git/info/exclude see https://help.github.com/articles/ignoring-files +.* +!.github +!.gitignore profile.out -junit-report.xml +# support running go modules in vendor mode for local development +vendor/ diff --git a/vendor/github.com/moby/term/README.md b/vendor/github.com/moby/term/README.md new file mode 100644 index 00000000000..0ce92cc3398 --- /dev/null +++ b/vendor/github.com/moby/term/README.md @@ -0,0 +1,36 @@ +# term - utilities for dealing with terminals + +![Test](https://github.com/moby/term/workflows/Test/badge.svg) [![GoDoc](https://godoc.org/github.com/moby/term?status.svg)](https://godoc.org/github.com/moby/term) [![Go Report Card](https://goreportcard.com/badge/github.com/moby/term)](https://goreportcard.com/report/github.com/moby/term) + +term provides structures and helper functions to work with terminal (state, sizes). + +#### Using term + +```go +package main + +import ( + "log" + "os" + + "github.com/moby/term" +) + +func main() { + fd := os.Stdin.Fd() + if term.IsTerminal(fd) { + ws, err := term.GetWinsize(fd) + if err != nil { + log.Fatalf("term.GetWinsize: %s", err) + } + log.Printf("%d:%d\n", ws.Height, ws.Width) + } +} +``` + +## Contributing + +Want to hack on term? [Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md) apply. + +## Copyright and license +Code and documentation copyright 2015 Docker, inc. Code released under the Apache 2.0 license. Docs released under Creative commons. diff --git a/vendor/github.com/moby/term/ascii.go b/vendor/github.com/moby/term/ascii.go index 7c445686f3b..55873c0556c 100644 --- a/vendor/github.com/moby/term/ascii.go +++ b/vendor/github.com/moby/term/ascii.go @@ -1,4 +1,4 @@ -package term // import "github.com/moby/term" +package term import ( "fmt" diff --git a/vendor/github.com/moby/term/go.mod b/vendor/github.com/moby/term/go.mod index 9f23ce0d5e4..f453204333a 100644 --- a/vendor/github.com/moby/term/go.mod +++ b/vendor/github.com/moby/term/go.mod @@ -4,10 +4,9 @@ go 1.13 require ( github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 - github.com/google/go-cmp v0.3.1 + github.com/creack/pty v1.1.11 + github.com/google/go-cmp v0.4.0 github.com/pkg/errors v0.9.1 // indirect - github.com/sirupsen/logrus v1.4.2 - golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 - gotest.tools v2.2.0+incompatible - gotest.tools/v3 v3.0.2 // indirect + golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a + gotest.tools/v3 v3.0.2 ) diff --git a/vendor/github.com/moby/term/go.sum b/vendor/github.com/moby/term/go.sum index 413bf366683..441e06137ac 100644 --- a/vendor/github.com/moby/term/go.sum +++ b/vendor/github.com/moby/term/go.sum @@ -1,33 +1,23 @@ 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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/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/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 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 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a h1:i47hUS795cOydZI4AwJQCKXOr4BvxzvikwDoDtHhP2Y= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= diff --git a/vendor/github.com/moby/term/proxy.go b/vendor/github.com/moby/term/proxy.go index 9573222f9fa..c47756b89a9 100644 --- a/vendor/github.com/moby/term/proxy.go +++ b/vendor/github.com/moby/term/proxy.go @@ -1,4 +1,4 @@ -package term // import "github.com/moby/term" +package term import ( "io" @@ -19,6 +19,7 @@ type escapeProxy struct { escapeKeys []byte escapeKeyPos int r io.Reader + buf []byte } // NewEscapeProxy returns a new TTY proxy reader which wraps the given reader @@ -31,48 +32,57 @@ func NewEscapeProxy(r io.Reader, escapeKeys []byte) io.Reader { } } -func (r *escapeProxy) Read(buf []byte) (int, error) { - nr, err := r.r.Read(buf) - - if len(r.escapeKeys) == 0 { - return nr, err - } - - preserve := func() { - // this preserves the original key presses in the passed in buffer - nr += r.escapeKeyPos - preserve := make([]byte, 0, r.escapeKeyPos+len(buf)) - preserve = append(preserve, r.escapeKeys[:r.escapeKeyPos]...) - preserve = append(preserve, buf...) - r.escapeKeyPos = 0 - copy(buf[0:nr], preserve) - } - - if nr != 1 || err != nil { - if r.escapeKeyPos > 0 { - preserve() - } - return nr, err - } - - if buf[0] != r.escapeKeys[r.escapeKeyPos] { - if r.escapeKeyPos > 0 { - preserve() - } - return nr, nil - } - - if r.escapeKeyPos == len(r.escapeKeys)-1 { +func (r *escapeProxy) Read(buf []byte) (n int, err error) { + if len(r.escapeKeys) > 0 && r.escapeKeyPos == len(r.escapeKeys) { return 0, EscapeError{} } - // Looks like we've got an escape key, but we need to match again on the next - // read. - // Store the current escape key we found so we can look for the next one on - // the next read. - // Since this is an escape key, make sure we don't let the caller read it - // If later on we find that this is not the escape sequence, we'll add the - // keys back - r.escapeKeyPos++ - return nr - r.escapeKeyPos, nil + if len(r.buf) > 0 { + n = copy(buf, r.buf) + r.buf = r.buf[n:] + } + + nr, err := r.r.Read(buf[n:]) + n += nr + if len(r.escapeKeys) == 0 { + return n, err + } + + for i := 0; i < n; i++ { + if buf[i] == r.escapeKeys[r.escapeKeyPos] { + r.escapeKeyPos++ + + // Check if the full escape sequence is matched. + if r.escapeKeyPos == len(r.escapeKeys) { + n = i + 1 - r.escapeKeyPos + if n < 0 { + n = 0 + } + return n, EscapeError{} + } + continue + } + + // If we need to prepend a partial escape sequence from the previous + // read, make sure the new buffer size doesn't exceed len(buf). + // Otherwise, preserve any extra data in a buffer for the next read. + if i < r.escapeKeyPos { + preserve := make([]byte, 0, r.escapeKeyPos+n) + preserve = append(preserve, r.escapeKeys[:r.escapeKeyPos]...) + preserve = append(preserve, buf[:n]...) + n = copy(buf, preserve) + i += r.escapeKeyPos + r.buf = append(r.buf, preserve[n:]...) + } + r.escapeKeyPos = 0 + } + + // If we're in the middle of reading an escape sequence, make sure we don't + // let the caller read it. If later on we find that this is not the escape + // sequence, we'll prepend it back to buf. + n -= r.escapeKeyPos + if n < 0 { + n = 0 + } + return n, err } diff --git a/vendor/github.com/moby/term/tc.go b/vendor/github.com/moby/term/tc.go index 162dfb2b2f5..65556027a6d 100644 --- a/vendor/github.com/moby/term/tc.go +++ b/vendor/github.com/moby/term/tc.go @@ -1,20 +1,19 @@ // +build !windows -package term // import "github.com/moby/term" +package term import ( - "syscall" - "unsafe" - "golang.org/x/sys/unix" ) -func tcget(fd uintptr, p *Termios) syscall.Errno { - _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(p))) - return err +func tcget(fd uintptr) (*Termios, error) { + p, err := unix.IoctlGetTermios(int(fd), getTermios) + if err != nil { + return nil, err + } + return p, nil } -func tcset(fd uintptr, p *Termios) syscall.Errno { - _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(p))) - return err +func tcset(fd uintptr, p *Termios) error { + return unix.IoctlSetTermios(int(fd), setTermios, p) } diff --git a/vendor/github.com/moby/term/term.go b/vendor/github.com/moby/term/term.go index 6d643516f39..29c6acf1c7e 100644 --- a/vendor/github.com/moby/term/term.go +++ b/vendor/github.com/moby/term/term.go @@ -2,7 +2,7 @@ // Package term provides structures and helper functions to work with // terminal (state, sizes). -package term // import "github.com/moby/term" +package term import ( "errors" @@ -50,8 +50,8 @@ func GetFdInfo(in interface{}) (uintptr, bool) { // IsTerminal returns true if the given file descriptor is a terminal. func IsTerminal(fd uintptr) bool { - var termios Termios - return tcget(fd, &termios) == 0 + _, err := tcget(fd) + return err == nil } // RestoreTerminal restores the terminal connected to the given file descriptor @@ -60,20 +60,16 @@ func RestoreTerminal(fd uintptr, state *State) error { if state == nil { return ErrInvalidState } - if err := tcset(fd, &state.termios); err != 0 { - return err - } - return nil + return tcset(fd, &state.termios) } // SaveState saves the state of the terminal connected to the given file descriptor. func SaveState(fd uintptr) (*State, error) { - var oldState State - if err := tcget(fd, &oldState.termios); err != 0 { + termios, err := tcget(fd) + if err != nil { return nil, err } - - return &oldState, nil + return &State{termios: *termios}, nil } // DisableEcho applies the specified state to the terminal connected to the file @@ -82,7 +78,7 @@ func DisableEcho(fd uintptr, state *State) error { newState := state.termios newState.Lflag &^= unix.ECHO - if err := tcset(fd, &newState); err != 0 { + if err := tcset(fd, &newState); err != nil { return err } handleInterrupt(fd, state) diff --git a/vendor/github.com/moby/term/term_windows.go b/vendor/github.com/moby/term/term_windows.go index 1649c230647..ba82960d4a6 100644 --- a/vendor/github.com/moby/term/term_windows.go +++ b/vendor/github.com/moby/term/term_windows.go @@ -1,13 +1,12 @@ -package term // import "github.com/moby/term" +package term import ( "io" "os" "os/signal" - "syscall" // used for STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and STD_ERROR_HANDLE - "github.com/Azure/go-ansiterm/winterm" windowsconsole "github.com/moby/term/windows" + "golang.org/x/sys/windows" ) // State holds the console mode for the terminal. @@ -28,37 +27,42 @@ var vtInputSupported bool func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { // Turn on VT handling on all std handles, if possible. This might // fail, in which case we will fall back to terminal emulation. - var emulateStdin, emulateStdout, emulateStderr bool - fd := os.Stdin.Fd() - if mode, err := winterm.GetConsoleMode(fd); err == nil { + var ( + emulateStdin, emulateStdout, emulateStderr bool + + mode uint32 + ) + + fd := windows.Handle(os.Stdin.Fd()) + if err := windows.GetConsoleMode(fd, &mode); err == nil { // Validate that winterm.ENABLE_VIRTUAL_TERMINAL_INPUT is supported, but do not set it. - if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_INPUT); err != nil { + if err = windows.SetConsoleMode(fd, mode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT); err != nil { emulateStdin = true } else { vtInputSupported = true } // Unconditionally set the console mode back even on failure because SetConsoleMode // remembers invalid bits on input handles. - winterm.SetConsoleMode(fd, mode) + _ = windows.SetConsoleMode(fd, mode) } - fd = os.Stdout.Fd() - if mode, err := winterm.GetConsoleMode(fd); err == nil { + fd = windows.Handle(os.Stdout.Fd()) + if err := windows.GetConsoleMode(fd, &mode); err == nil { // Validate winterm.DISABLE_NEWLINE_AUTO_RETURN is supported, but do not set it. - if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING|winterm.DISABLE_NEWLINE_AUTO_RETURN); err != nil { + if err = windows.SetConsoleMode(fd, mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING|windows.DISABLE_NEWLINE_AUTO_RETURN); err != nil { emulateStdout = true } else { - winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING) + _ = windows.SetConsoleMode(fd, mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) } } - fd = os.Stderr.Fd() - if mode, err := winterm.GetConsoleMode(fd); err == nil { + fd = windows.Handle(os.Stderr.Fd()) + if err := windows.GetConsoleMode(fd, &mode); err == nil { // Validate winterm.DISABLE_NEWLINE_AUTO_RETURN is supported, but do not set it. - if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING|winterm.DISABLE_NEWLINE_AUTO_RETURN); err != nil { + if err = windows.SetConsoleMode(fd, mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING|windows.DISABLE_NEWLINE_AUTO_RETURN); err != nil { emulateStderr = true } else { - winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING) + _ = windows.SetConsoleMode(fd, mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) } } @@ -67,19 +71,22 @@ func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { // go-ansiterm hasn't switch to x/sys/windows. // TODO: switch back to x/sys/windows once go-ansiterm has switched if emulateStdin { - stdIn = windowsconsole.NewAnsiReader(syscall.STD_INPUT_HANDLE) + h := uint32(windows.STD_INPUT_HANDLE) + stdIn = windowsconsole.NewAnsiReader(int(h)) } else { stdIn = os.Stdin } if emulateStdout { - stdOut = windowsconsole.NewAnsiWriter(syscall.STD_OUTPUT_HANDLE) + h := uint32(windows.STD_OUTPUT_HANDLE) + stdOut = windowsconsole.NewAnsiWriter(int(h)) } else { stdOut = os.Stdout } if emulateStderr { - stdErr = windowsconsole.NewAnsiWriter(syscall.STD_ERROR_HANDLE) + h := uint32(windows.STD_ERROR_HANDLE) + stdErr = windowsconsole.NewAnsiWriter(int(h)) } else { stdErr = os.Stderr } @@ -94,8 +101,8 @@ func GetFdInfo(in interface{}) (uintptr, bool) { // GetWinsize returns the window size based on the specified file descriptor. func GetWinsize(fd uintptr) (*Winsize, error) { - info, err := winterm.GetConsoleScreenBufferInfo(fd) - if err != nil { + var info windows.ConsoleScreenBufferInfo + if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil { return nil, err } @@ -109,20 +116,23 @@ func GetWinsize(fd uintptr) (*Winsize, error) { // IsTerminal returns true if the given file descriptor is a terminal. func IsTerminal(fd uintptr) bool { - return windowsconsole.IsConsole(fd) + var mode uint32 + err := windows.GetConsoleMode(windows.Handle(fd), &mode) + return err == nil } // RestoreTerminal restores the terminal connected to the given file descriptor // to a previous state. func RestoreTerminal(fd uintptr, state *State) error { - return winterm.SetConsoleMode(fd, state.mode) + return windows.SetConsoleMode(windows.Handle(fd), state.mode) } // SaveState saves the state of the terminal connected to the given file descriptor. func SaveState(fd uintptr) (*State, error) { - mode, e := winterm.GetConsoleMode(fd) - if e != nil { - return nil, e + var mode uint32 + + if err := windows.GetConsoleMode(windows.Handle(fd), &mode); err != nil { + return nil, err } return &State{mode: mode}, nil @@ -132,9 +142,9 @@ func SaveState(fd uintptr) (*State, error) { // -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx func DisableEcho(fd uintptr, state *State) error { mode := state.mode - mode &^= winterm.ENABLE_ECHO_INPUT - mode |= winterm.ENABLE_PROCESSED_INPUT | winterm.ENABLE_LINE_INPUT - err := winterm.SetConsoleMode(fd, mode) + mode &^= windows.ENABLE_ECHO_INPUT + mode |= windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT + err := windows.SetConsoleMode(windows.Handle(fd), mode) if err != nil { return err } @@ -169,7 +179,7 @@ func SetRawTerminalOutput(fd uintptr) (*State, error) { // Ignore failures, since winterm.DISABLE_NEWLINE_AUTO_RETURN might not be supported on this // version of Windows. - winterm.SetConsoleMode(fd, state.mode|winterm.DISABLE_NEWLINE_AUTO_RETURN) + _ = windows.SetConsoleMode(windows.Handle(fd), state.mode|windows.DISABLE_NEWLINE_AUTO_RETURN) return state, err } @@ -188,21 +198,21 @@ func MakeRaw(fd uintptr) (*State, error) { // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx // Disable these modes - mode &^= winterm.ENABLE_ECHO_INPUT - mode &^= winterm.ENABLE_LINE_INPUT - mode &^= winterm.ENABLE_MOUSE_INPUT - mode &^= winterm.ENABLE_WINDOW_INPUT - mode &^= winterm.ENABLE_PROCESSED_INPUT + mode &^= windows.ENABLE_ECHO_INPUT + mode &^= windows.ENABLE_LINE_INPUT + mode &^= windows.ENABLE_MOUSE_INPUT + mode &^= windows.ENABLE_WINDOW_INPUT + mode &^= windows.ENABLE_PROCESSED_INPUT // Enable these modes - mode |= winterm.ENABLE_EXTENDED_FLAGS - mode |= winterm.ENABLE_INSERT_MODE - mode |= winterm.ENABLE_QUICK_EDIT_MODE + mode |= windows.ENABLE_EXTENDED_FLAGS + mode |= windows.ENABLE_INSERT_MODE + mode |= windows.ENABLE_QUICK_EDIT_MODE if vtInputSupported { - mode |= winterm.ENABLE_VIRTUAL_TERMINAL_INPUT + mode |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT } - err = winterm.SetConsoleMode(fd, mode) + err = windows.SetConsoleMode(windows.Handle(fd), mode) if err != nil { return nil, err } @@ -215,7 +225,7 @@ func restoreAtInterrupt(fd uintptr, state *State) { go func() { _ = <-sigchan - RestoreTerminal(fd, state) + _ = RestoreTerminal(fd, state) os.Exit(0) }() } diff --git a/vendor/github.com/moby/term/termios_linux.go b/vendor/github.com/moby/term/termios.go similarity index 62% rename from vendor/github.com/moby/term/termios_linux.go rename to vendor/github.com/moby/term/termios.go index be39ff56cc0..0f028e2273a 100644 --- a/vendor/github.com/moby/term/termios_linux.go +++ b/vendor/github.com/moby/term/termios.go @@ -1,28 +1,24 @@ -package term // import "github.com/moby/term" +// +build !windows + +package term import ( "golang.org/x/sys/unix" ) -const ( - getTermios = unix.TCGETS - setTermios = unix.TCSETS -) - // Termios is the Unix API for terminal I/O. -type Termios unix.Termios +type Termios = unix.Termios -// MakeRaw put the terminal connected to the given file descriptor into raw +// MakeRaw puts the terminal connected to the given file descriptor into raw // mode and returns the previous state of the terminal so that it can be // restored. func MakeRaw(fd uintptr) (*State, error) { - termios, err := unix.IoctlGetTermios(int(fd), getTermios) + termios, err := tcget(fd) if err != nil { return nil, err } - var oldState State - oldState.termios = Termios(*termios) + oldState := State{termios: *termios} termios.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON) termios.Oflag &^= unix.OPOST @@ -32,7 +28,7 @@ func MakeRaw(fd uintptr) (*State, error) { termios.Cc[unix.VMIN] = 1 termios.Cc[unix.VTIME] = 0 - if err := unix.IoctlSetTermios(int(fd), setTermios, termios); err != nil { + if err := tcset(fd, termios); err != nil { return nil, err } return &oldState, nil diff --git a/vendor/github.com/moby/term/termios_bsd.go b/vendor/github.com/moby/term/termios_bsd.go index da785106657..922dd4baab0 100644 --- a/vendor/github.com/moby/term/termios_bsd.go +++ b/vendor/github.com/moby/term/termios_bsd.go @@ -1,10 +1,8 @@ // +build darwin freebsd openbsd netbsd -package term // import "github.com/moby/term" +package term import ( - "unsafe" - "golang.org/x/sys/unix" ) @@ -12,31 +10,3 @@ const ( getTermios = unix.TIOCGETA setTermios = unix.TIOCSETA ) - -// Termios is the Unix API for terminal I/O. -type Termios unix.Termios - -// MakeRaw put the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd uintptr) (*State, error) { - var oldState State - if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { - return nil, err - } - - newState := oldState.termios - newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON) - newState.Oflag &^= unix.OPOST - newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN) - newState.Cflag &^= (unix.CSIZE | unix.PARENB) - newState.Cflag |= unix.CS8 - newState.Cc[unix.VMIN] = 1 - newState.Cc[unix.VTIME] = 0 - - if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 { - return nil, err - } - - return &oldState, nil -} diff --git a/vendor/github.com/moby/term/termios_nonbsd.go b/vendor/github.com/moby/term/termios_nonbsd.go new file mode 100644 index 00000000000..038fd61ba1e --- /dev/null +++ b/vendor/github.com/moby/term/termios_nonbsd.go @@ -0,0 +1,12 @@ +//+build !darwin,!freebsd,!netbsd,!openbsd,!windows + +package term + +import ( + "golang.org/x/sys/unix" +) + +const ( + getTermios = unix.TCGETS + setTermios = unix.TCSETS +) diff --git a/vendor/github.com/moby/term/windows/ansi_reader.go b/vendor/github.com/moby/term/windows/ansi_reader.go index 5114b63ebf1..155251521b0 100644 --- a/vendor/github.com/moby/term/windows/ansi_reader.go +++ b/vendor/github.com/moby/term/windows/ansi_reader.go @@ -1,6 +1,6 @@ // +build windows -package windowsconsole // import "github.com/moby/term/windows" +package windowsconsole import ( "bytes" @@ -31,7 +31,6 @@ type ansiReader struct { // NewAnsiReader returns an io.ReadCloser that provides VT100 terminal emulation on top of a // Windows console input handle. func NewAnsiReader(nFile int) io.ReadCloser { - initLogger() file, fd := winterm.GetStdFile(nFile) return &ansiReader{ file: file, @@ -59,8 +58,6 @@ func (ar *ansiReader) Read(p []byte) (int, error) { // Previously read bytes exist, read as much as we can and return if len(ar.buffer) > 0 { - logger.Debugf("Reading previously cached bytes") - originalLength := len(ar.buffer) copiedLength := copy(p, ar.buffer) @@ -70,16 +67,14 @@ func (ar *ansiReader) Read(p []byte) (int, error) { ar.buffer = ar.buffer[copiedLength:] } - logger.Debugf("Read from cache p[%d]: % x", copiedLength, p) return copiedLength, nil } // Read and translate key events - events, err := readInputEvents(ar.fd, len(p)) + events, err := readInputEvents(ar, len(p)) if err != nil { return 0, err } else if len(events) == 0 { - logger.Debug("No input events detected") return 0, nil } @@ -87,11 +82,9 @@ func (ar *ansiReader) Read(p []byte) (int, error) { // Save excess bytes and right-size keyBytes if len(keyBytes) > len(p) { - logger.Debugf("Received %d keyBytes, only room for %d bytes", len(keyBytes), len(p)) ar.buffer = keyBytes[len(p):] keyBytes = keyBytes[:len(p)] } else if len(keyBytes) == 0 { - logger.Debug("No key bytes returned from the translator") return 0, nil } @@ -100,13 +93,11 @@ func (ar *ansiReader) Read(p []byte) (int, error) { return 0, errors.New("unexpected copy length encountered") } - logger.Debugf("Read p[%d]: % x", copiedLength, p) - logger.Debugf("Read keyBytes[%d]: % x", copiedLength, keyBytes) return copiedLength, nil } // readInputEvents polls until at least one event is available. -func readInputEvents(fd uintptr, maxBytes int) ([]winterm.INPUT_RECORD, error) { +func readInputEvents(ar *ansiReader, maxBytes int) ([]winterm.INPUT_RECORD, error) { // Determine the maximum number of records to retrieve // -- Cast around the type system to obtain the size of a single INPUT_RECORD. // unsafe.Sizeof requires an expression vs. a type-reference; the casting @@ -118,25 +109,23 @@ func readInputEvents(fd uintptr, maxBytes int) ([]winterm.INPUT_RECORD, error) { } else if countRecords == 0 { countRecords = 1 } - logger.Debugf("[windows] readInputEvents: Reading %v records (buffer size %v, record size %v)", countRecords, maxBytes, recordSize) // Wait for and read input events events := make([]winterm.INPUT_RECORD, countRecords) nEvents := uint32(0) - eventsExist, err := winterm.WaitForSingleObject(fd, winterm.WAIT_INFINITE) + eventsExist, err := winterm.WaitForSingleObject(ar.fd, winterm.WAIT_INFINITE) if err != nil { return nil, err } if eventsExist { - err = winterm.ReadConsoleInput(fd, events, &nEvents) + err = winterm.ReadConsoleInput(ar.fd, events, &nEvents) if err != nil { return nil, err } } // Return a slice restricted to the number of returned records - logger.Debugf("[windows] readInputEvents: Read %v events", nEvents) return events[:nEvents], nil } diff --git a/vendor/github.com/moby/term/windows/ansi_writer.go b/vendor/github.com/moby/term/windows/ansi_writer.go index 51bf9aa48cf..ccb5ef07757 100644 --- a/vendor/github.com/moby/term/windows/ansi_writer.go +++ b/vendor/github.com/moby/term/windows/ansi_writer.go @@ -1,6 +1,6 @@ // +build windows -package windowsconsole // import "github.com/moby/term/windows" +package windowsconsole import ( "io" @@ -24,7 +24,6 @@ type ansiWriter struct { // NewAnsiWriter returns an io.Writer that provides VT100 terminal emulation on top of a // Windows console output handle. func NewAnsiWriter(nFile int) io.Writer { - initLogger() file, fd := winterm.GetStdFile(nFile) info, err := winterm.GetConsoleScreenBufferInfo(fd) if err != nil { @@ -32,9 +31,8 @@ func NewAnsiWriter(nFile int) io.Writer { } parser := ansiterm.CreateParser("Ground", winterm.CreateWinEventHandler(fd, file)) - logger.Infof("newAnsiWriter: parser %p", parser) - aw := &ansiWriter{ + return &ansiWriter{ file: file, fd: fd, infoReset: info, @@ -42,10 +40,6 @@ func NewAnsiWriter(nFile int) io.Writer { escapeSequence: []byte(ansiterm.KEY_ESC_CSI), parser: parser, } - - logger.Infof("newAnsiWriter: aw.parser %p", aw.parser) - logger.Infof("newAnsiWriter: %v", aw) - return aw } func (aw *ansiWriter) Fd() uintptr { @@ -58,7 +52,5 @@ func (aw *ansiWriter) Write(p []byte) (total int, err error) { return 0, nil } - logger.Infof("Write: % x", p) - logger.Infof("Write: %s", string(p)) return aw.parser.Parse(p) } diff --git a/vendor/github.com/moby/term/windows/console.go b/vendor/github.com/moby/term/windows/console.go index 54e0fe839fc..993694ddcd9 100644 --- a/vendor/github.com/moby/term/windows/console.go +++ b/vendor/github.com/moby/term/windows/console.go @@ -1,11 +1,11 @@ // +build windows -package windowsconsole // import "github.com/moby/term/windows" +package windowsconsole import ( "os" - "github.com/Azure/go-ansiterm/winterm" + "golang.org/x/sys/windows" ) // GetHandleInfo returns file descriptor and bool indicating whether the file is a console. @@ -22,14 +22,18 @@ func GetHandleInfo(in interface{}) (uintptr, bool) { if file, ok := in.(*os.File); ok { inFd = file.Fd() - isTerminal = IsConsole(inFd) + isTerminal = isConsole(inFd) } return inFd, isTerminal } // IsConsole returns true if the given file descriptor is a Windows Console. // The code assumes that GetConsoleMode will return an error for file descriptors that are not a console. -func IsConsole(fd uintptr) bool { - _, e := winterm.GetConsoleMode(fd) - return e == nil +// Deprecated: use golang.org/x/sys/windows.GetConsoleMode() or golang.org/x/term.IsTerminal() +var IsConsole = isConsole + +func isConsole(fd uintptr) bool { + var mode uint32 + err := windows.GetConsoleMode(windows.Handle(fd), &mode) + return err == nil } diff --git a/vendor/github.com/moby/term/windows/doc.go b/vendor/github.com/moby/term/windows/doc.go new file mode 100644 index 00000000000..54265fffaff --- /dev/null +++ b/vendor/github.com/moby/term/windows/doc.go @@ -0,0 +1,5 @@ +// These files implement ANSI-aware input and output streams for use by the Docker Windows client. +// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create +// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls. + +package windowsconsole diff --git a/vendor/github.com/moby/term/windows/windows.go b/vendor/github.com/moby/term/windows/windows.go deleted file mode 100644 index bb03e060181..00000000000 --- a/vendor/github.com/moby/term/windows/windows.go +++ /dev/null @@ -1,34 +0,0 @@ -// +build windows -// These files implement ANSI-aware input and output streams for use by the Docker Windows client. -// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create -// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls. - -package windowsconsole // import "github.com/moby/term/windows" - -import ( - "io/ioutil" - "os" - "sync" - - ansiterm "github.com/Azure/go-ansiterm" - "github.com/sirupsen/logrus" -) - -var logger *logrus.Logger -var initOnce sync.Once - -func initLogger() { - initOnce.Do(func() { - logFile := ioutil.Discard - - if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" { - logFile, _ = os.Create("ansiReaderWriter.log") - } - - logger = &logrus.Logger{ - Out: logFile, - Formatter: new(logrus.TextFormatter), - Level: logrus.DebugLevel, - } - }) -} diff --git a/vendor/github.com/moby/term/winsize.go b/vendor/github.com/moby/term/winsize.go index 29a0463dc46..1ef98d59961 100644 --- a/vendor/github.com/moby/term/winsize.go +++ b/vendor/github.com/moby/term/winsize.go @@ -1,6 +1,6 @@ // +build !windows -package term // import "github.com/moby/term" +package term import ( "golang.org/x/sys/unix" diff --git a/vendor/github.com/mrunalp/fileutils/fileutils.go b/vendor/github.com/mrunalp/fileutils/fileutils.go index 136bbd9fb24..7421e6207f6 100644 --- a/vendor/github.com/mrunalp/fileutils/fileutils.go +++ b/vendor/github.com/mrunalp/fileutils/fileutils.go @@ -22,7 +22,7 @@ func CopyFile(source string, dest string) error { uid := int(st.Uid) gid := int(st.Gid) - modeType := si.Mode()&os.ModeType + modeType := si.Mode() & os.ModeType // Handle symlinks if modeType == os.ModeSymlink { @@ -52,19 +52,7 @@ func CopyFile(source string, dest string) error { // Handle regular files if si.Mode().IsRegular() { - sf, err := os.Open(source) - if err != nil { - return err - } - defer sf.Close() - - df, err := os.Create(dest) - if err != nil { - return err - } - defer df.Close() - - _, err = io.Copy(df, sf) + err = copyInternal(source, dest) if err != nil { return err } @@ -85,6 +73,28 @@ func CopyFile(source string, dest string) error { return nil } +func copyInternal(source, dest string) (retErr error) { + sf, err := os.Open(source) + if err != nil { + return err + } + defer sf.Close() + + df, err := os.Create(dest) + if err != nil { + return err + } + defer func() { + err := df.Close() + if retErr == nil { + retErr = err + } + }() + + _, err = io.Copy(df, sf) + return err +} + // CopyDirectory copies the files under the source directory // to dest directory. The dest directory is created if it // does not exist. diff --git a/vendor/github.com/mrunalp/fileutils/go.mod b/vendor/github.com/mrunalp/fileutils/go.mod new file mode 100644 index 00000000000..d8971cabc46 --- /dev/null +++ b/vendor/github.com/mrunalp/fileutils/go.mod @@ -0,0 +1,3 @@ +module github.com/mrunalp/fileutils + +go 1.13 diff --git a/vendor/github.com/opencontainers/runc/libcontainer/README.md b/vendor/github.com/opencontainers/runc/libcontainer/README.md index 6803ef56c5b..8b25d5c1c01 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/README.md +++ b/vendor/github.com/opencontainers/runc/libcontainer/README.md @@ -60,87 +60,87 @@ defaultMountFlags := unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV config := &configs.Config{ Rootfs: "/your/path/to/rootfs", Capabilities: &configs.Capabilities{ - Bounding: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - Effective: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - Inheritable: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - Permitted: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - Ambient: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - }, + Bounding: []string{ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE", + }, + Effective: []string{ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE", + }, + Inheritable: []string{ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE", + }, + Permitted: []string{ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE", + }, + Ambient: []string{ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE", + }, + }, Namespaces: configs.Namespaces([]configs.Namespace{ {Type: configs.NEWNS}, {Type: configs.NEWUTS}, diff --git a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_linux.go similarity index 67% rename from vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go rename to vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_linux.go index debfc1e489e..73965f12d83 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_linux.go @@ -1,8 +1,7 @@ -// +build apparmor,linux - package apparmor import ( + "bytes" "fmt" "io/ioutil" "os" @@ -12,11 +11,9 @@ import ( // IsEnabled returns true if apparmor is enabled for the host. func IsEnabled() bool { - if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil && os.Getenv("container") == "" { - if _, err = os.Stat("/sbin/apparmor_parser"); err == nil { - buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled") - return err == nil && len(buf) > 1 && buf[0] == 'Y' - } + if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil { + buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled") + return err == nil && bytes.HasPrefix(buf, []byte("Y")) } return false } @@ -24,9 +21,7 @@ func IsEnabled() bool { func setProcAttr(attr, value string) error { // Under AppArmor you can only change your own attr, so use /proc/self/ // instead of /proc// like libapparmor does - path := fmt.Sprintf("/proc/self/attr/%s", attr) - - f, err := os.OpenFile(path, os.O_WRONLY, 0) + f, err := os.OpenFile("/proc/self/attr/"+attr, os.O_WRONLY, 0) if err != nil { return err } @@ -36,14 +31,13 @@ func setProcAttr(attr, value string) error { return err } - _, err = fmt.Fprintf(f, "%s", value) + _, err = f.WriteString(value) return err } // changeOnExec reimplements aa_change_onexec from libapparmor in Go func changeOnExec(name string) error { - value := "exec " + name - if err := setProcAttr("exec", value); err != nil { + if err := setProcAttr("exec", "exec "+name); err != nil { return fmt.Errorf("apparmor failed to apply profile: %s", err) } return nil diff --git a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_unsupported.go similarity index 91% rename from vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go rename to vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_unsupported.go index d4110cf0bc6..0bc473f810b 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_unsupported.go @@ -1,4 +1,4 @@ -// +build !apparmor !linux +// +build !linux package apparmor diff --git a/vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities.go b/vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities.go new file mode 100644 index 00000000000..adbf6330c48 --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities.go @@ -0,0 +1,96 @@ +// +build linux + +package capabilities + +import ( + "fmt" + "strings" + + "github.com/opencontainers/runc/libcontainer/configs" + "github.com/syndtr/gocapability/capability" +) + +const allCapabilityTypes = capability.CAPS | capability.BOUNDS | capability.AMBS + +var capabilityMap map[string]capability.Cap + +func init() { + capabilityMap = make(map[string]capability.Cap, capability.CAP_LAST_CAP+1) + for _, c := range capability.List() { + if c > capability.CAP_LAST_CAP { + continue + } + capabilityMap["CAP_"+strings.ToUpper(c.String())] = c + } +} + +// New creates a new Caps from the given Capabilities config. +func New(capConfig *configs.Capabilities) (*Caps, error) { + var ( + err error + caps Caps + ) + + if caps.bounding, err = capSlice(capConfig.Bounding); err != nil { + return nil, err + } + if caps.effective, err = capSlice(capConfig.Effective); err != nil { + return nil, err + } + if caps.inheritable, err = capSlice(capConfig.Inheritable); err != nil { + return nil, err + } + if caps.permitted, err = capSlice(capConfig.Permitted); err != nil { + return nil, err + } + if caps.ambient, err = capSlice(capConfig.Ambient); err != nil { + return nil, err + } + if caps.pid, err = capability.NewPid2(0); err != nil { + return nil, err + } + if err = caps.pid.Load(); err != nil { + return nil, err + } + return &caps, nil +} + +func capSlice(caps []string) ([]capability.Cap, error) { + out := make([]capability.Cap, len(caps)) + for i, c := range caps { + v, ok := capabilityMap[c] + if !ok { + return nil, fmt.Errorf("unknown capability %q", c) + } + out[i] = v + } + return out, nil +} + +// Caps holds the capabilities for a container. +type Caps struct { + pid capability.Capabilities + bounding []capability.Cap + effective []capability.Cap + inheritable []capability.Cap + permitted []capability.Cap + ambient []capability.Cap +} + +// ApplyBoundingSet sets the capability bounding set to those specified in the whitelist. +func (c *Caps) ApplyBoundingSet() error { + c.pid.Clear(capability.BOUNDS) + c.pid.Set(capability.BOUNDS, c.bounding...) + return c.pid.Apply(capability.BOUNDS) +} + +// Apply sets all the capabilities for the current process in the config. +func (c *Caps) ApplyCaps() error { + c.pid.Clear(allCapabilityTypes) + c.pid.Set(capability.BOUNDS, c.bounding...) + c.pid.Set(capability.PERMITTED, c.permitted...) + c.pid.Set(capability.INHERITABLE, c.inheritable...) + c.pid.Set(capability.EFFECTIVE, c.effective...) + c.pid.Set(capability.AMBIENT, c.ambient...) + return c.pid.Apply(allCapabilityTypes) +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities_unsupported.go new file mode 100644 index 00000000000..a3e82ac1fd4 --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/capabilities/capabilities_unsupported.go @@ -0,0 +1,3 @@ +// +build !linux + +package capabilities diff --git a/vendor/github.com/opencontainers/runc/libcontainer/capabilities_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/capabilities_linux.go deleted file mode 100644 index 9daef29e480..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/capabilities_linux.go +++ /dev/null @@ -1,117 +0,0 @@ -// +build linux - -package libcontainer - -import ( - "fmt" - "strings" - - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/syndtr/gocapability/capability" -) - -const allCapabilityTypes = capability.CAPS | capability.BOUNDS | capability.AMBS - -var capabilityMap map[string]capability.Cap - -func init() { - capabilityMap = make(map[string]capability.Cap) - last := capability.CAP_LAST_CAP - // workaround for RHEL6 which has no /proc/sys/kernel/cap_last_cap - if last == capability.Cap(63) { - last = capability.CAP_BLOCK_SUSPEND - } - for _, cap := range capability.List() { - if cap > last { - continue - } - capKey := fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String())) - capabilityMap[capKey] = cap - } -} - -func newContainerCapList(capConfig *configs.Capabilities) (*containerCapabilities, error) { - bounding := []capability.Cap{} - for _, c := range capConfig.Bounding { - v, ok := capabilityMap[c] - if !ok { - return nil, fmt.Errorf("unknown capability %q", c) - } - bounding = append(bounding, v) - } - effective := []capability.Cap{} - for _, c := range capConfig.Effective { - v, ok := capabilityMap[c] - if !ok { - return nil, fmt.Errorf("unknown capability %q", c) - } - effective = append(effective, v) - } - inheritable := []capability.Cap{} - for _, c := range capConfig.Inheritable { - v, ok := capabilityMap[c] - if !ok { - return nil, fmt.Errorf("unknown capability %q", c) - } - inheritable = append(inheritable, v) - } - permitted := []capability.Cap{} - for _, c := range capConfig.Permitted { - v, ok := capabilityMap[c] - if !ok { - return nil, fmt.Errorf("unknown capability %q", c) - } - permitted = append(permitted, v) - } - ambient := []capability.Cap{} - for _, c := range capConfig.Ambient { - v, ok := capabilityMap[c] - if !ok { - return nil, fmt.Errorf("unknown capability %q", c) - } - ambient = append(ambient, v) - } - pid, err := capability.NewPid2(0) - if err != nil { - return nil, err - } - err = pid.Load() - if err != nil { - return nil, err - } - return &containerCapabilities{ - bounding: bounding, - effective: effective, - inheritable: inheritable, - permitted: permitted, - ambient: ambient, - pid: pid, - }, nil -} - -type containerCapabilities struct { - pid capability.Capabilities - bounding []capability.Cap - effective []capability.Cap - inheritable []capability.Cap - permitted []capability.Cap - ambient []capability.Cap -} - -// ApplyBoundingSet sets the capability bounding set to those specified in the whitelist. -func (c *containerCapabilities) ApplyBoundingSet() error { - c.pid.Clear(capability.BOUNDS) - c.pid.Set(capability.BOUNDS, c.bounding...) - return c.pid.Apply(capability.BOUNDS) -} - -// Apply sets all the capabilities for the current process in the config. -func (c *containerCapabilities) ApplyCaps() error { - c.pid.Clear(allCapabilityTypes) - c.pid.Set(capability.BOUNDS, c.bounding...) - c.pid.Set(capability.PERMITTED, c.permitted...) - c.pid.Set(capability.INHERITABLE, c.inheritable...) - c.pid.Set(capability.EFFECTIVE, c.effective...) - c.pid.Set(capability.AMBIENT, c.ambient...) - return c.pid.Apply(allCapabilityTypes) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/devices/devices_emulator.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/devices/devices_emulator.go index 6afedbc6e73..3572a5eae8e 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/devices/devices_emulator.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/devices/devices_emulator.go @@ -27,29 +27,29 @@ import ( "sort" "strconv" - "github.com/opencontainers/runc/libcontainer/configs" + "github.com/opencontainers/runc/libcontainer/devices" "github.com/pkg/errors" ) -// deviceMeta is a DeviceRule without the Allow or Permissions fields, and no +// deviceMeta is a Rule without the Allow or Permissions fields, and no // wildcard-type support. It's effectively the "match" portion of a metadata // rule, for the purposes of our emulation. type deviceMeta struct { - node configs.DeviceType + node devices.Type major int64 minor int64 } -// deviceRule is effectively the tuple (deviceMeta, DevicePermissions). +// deviceRule is effectively the tuple (deviceMeta, Permissions). type deviceRule struct { meta deviceMeta - perms configs.DevicePermissions + perms devices.Permissions } // deviceRules is a mapping of device metadata rules to the associated // permissions in the ruleset. -type deviceRules map[deviceMeta]configs.DevicePermissions +type deviceRules map[deviceMeta]devices.Permissions func (r deviceRules) orderedEntries() []deviceRule { var rules []deviceRule @@ -103,9 +103,9 @@ func parseLine(line string) (*deviceRule, error) { // TODO: Double-check that the entire file is "a *:* rwm". return nil, nil case "b": - rule.meta.node = configs.BlockDevice + rule.meta.node = devices.BlockDevice case "c": - rule.meta.node = configs.CharDevice + rule.meta.node = devices.CharDevice default: // Should never happen! return nil, errors.Errorf("unknown device type %q", node) @@ -113,7 +113,7 @@ func parseLine(line string) (*deviceRule, error) { // Parse the major number. if major == "*" { - rule.meta.major = configs.Wildcard + rule.meta.major = devices.Wildcard } else { val, err := strconv.ParseUint(major, 10, 32) if err != nil { @@ -124,7 +124,7 @@ func parseLine(line string) (*deviceRule, error) { // Parse the minor number. if minor == "*" { - rule.meta.minor = configs.Wildcard + rule.meta.minor = devices.Wildcard } else { val, err := strconv.ParseUint(minor, 10, 32) if err != nil { @@ -134,7 +134,7 @@ func parseLine(line string) (*deviceRule, error) { } // Parse the access permissions. - rule.perms = configs.DevicePermissions(perms) + rule.perms = devices.Permissions(perms) if !rule.perms.IsValid() || rule.perms.IsEmpty() { // Should never happen! return nil, errors.Errorf("parse access mode: contained unknown modes or is empty: %q", perms) @@ -144,7 +144,7 @@ func parseLine(line string) (*deviceRule, error) { func (e *Emulator) addRule(rule deviceRule) error { if e.rules == nil { - e.rules = make(map[deviceMeta]configs.DevicePermissions) + e.rules = make(map[deviceMeta]devices.Permissions) } // Merge with any pre-existing permissions. @@ -169,9 +169,9 @@ func (e *Emulator) rmRule(rule deviceRule) error { // to mention it'd be really slow (the kernel side is implemented as a // linked-list of exceptions). for _, partialMeta := range []deviceMeta{ - {node: rule.meta.node, major: configs.Wildcard, minor: rule.meta.minor}, - {node: rule.meta.node, major: rule.meta.major, minor: configs.Wildcard}, - {node: rule.meta.node, major: configs.Wildcard, minor: configs.Wildcard}, + {node: rule.meta.node, major: devices.Wildcard, minor: rule.meta.minor}, + {node: rule.meta.node, major: rule.meta.major, minor: devices.Wildcard}, + {node: rule.meta.node, major: devices.Wildcard, minor: devices.Wildcard}, } { // This wildcard rule is equivalent to the requested rule, so skip it. if rule.meta == partialMeta { @@ -202,7 +202,7 @@ func (e *Emulator) rmRule(rule deviceRule) error { func (e *Emulator) allow(rule *deviceRule) error { // This cgroup is configured as a black-list. Reset the entire emulator, // and put is into black-list mode. - if rule == nil || rule.meta.node == configs.WildcardDevice { + if rule == nil || rule.meta.node == devices.WildcardDevice { *e = Emulator{ defaultAllow: true, rules: nil, @@ -222,7 +222,7 @@ func (e *Emulator) allow(rule *deviceRule) error { func (e *Emulator) deny(rule *deviceRule) error { // This cgroup is configured as a white-list. Reset the entire emulator, // and put is into white-list mode. - if rule == nil || rule.meta.node == configs.WildcardDevice { + if rule == nil || rule.meta.node == devices.WildcardDevice { *e = Emulator{ defaultAllow: false, rules: nil, @@ -239,7 +239,7 @@ func (e *Emulator) deny(rule *deviceRule) error { return err } -func (e *Emulator) Apply(rule configs.DeviceRule) error { +func (e *Emulator) Apply(rule devices.Rule) error { if !rule.Type.CanCgroup() { return errors.Errorf("cannot add rule [%#v] with non-cgroup type %q", rule, rule.Type) } @@ -252,7 +252,7 @@ func (e *Emulator) Apply(rule configs.DeviceRule) error { }, perms: rule.Permissions, } - if innerRule.meta.node == configs.WildcardDevice { + if innerRule.meta.node == devices.WildcardDevice { innerRule = nil } @@ -307,8 +307,8 @@ func EmulatorFromList(list io.Reader) (*Emulator, error) { // This function is the sole reason for all of Emulator -- to allow us // to figure out how to update a containers' cgroups without causing spurrious // device errors (if possible). -func (source *Emulator) Transition(target *Emulator) ([]*configs.DeviceRule, error) { - var transitionRules []*configs.DeviceRule +func (source *Emulator) Transition(target *Emulator) ([]*devices.Rule, error) { + var transitionRules []*devices.Rule oldRules := source.rules // If the default policy doesn't match, we need to include a "disruptive" @@ -319,11 +319,11 @@ func (source *Emulator) Transition(target *Emulator) ([]*configs.DeviceRule, err // deny rules are in place in a black-list cgroup. Thus if the source is a // black-list we also have to include a disruptive rule. if source.IsBlacklist() || source.defaultAllow != target.defaultAllow { - transitionRules = append(transitionRules, &configs.DeviceRule{ + transitionRules = append(transitionRules, &devices.Rule{ Type: 'a', Major: -1, Minor: -1, - Permissions: configs.DevicePermissions("rwm"), + Permissions: devices.Permissions("rwm"), Allow: target.defaultAllow, }) // The old rules are only relevant if we aren't starting out with a @@ -342,7 +342,7 @@ func (source *Emulator) Transition(target *Emulator) ([]*configs.DeviceRule, err newPerms := target.rules[meta] droppedPerms := oldPerms.Difference(newPerms) if !droppedPerms.IsEmpty() { - transitionRules = append(transitionRules, &configs.DeviceRule{ + transitionRules = append(transitionRules, &devices.Rule{ Type: meta.node, Major: meta.major, Minor: meta.minor, @@ -360,7 +360,7 @@ func (source *Emulator) Transition(target *Emulator) ([]*configs.DeviceRule, err oldPerms := oldRules[meta] gainedPerms := newPerms.Difference(oldPerms) if !gainedPerms.IsEmpty() { - transitionRules = append(transitionRules, &configs.DeviceRule{ + transitionRules = append(transitionRules, &devices.Rule{ Type: meta.node, Major: meta.major, Minor: meta.minor, diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go index b593eb43e17..a173fd4a16f 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/ebpf/devicefilter/devicefilter.go @@ -1,4 +1,4 @@ -// Package devicefilter containes eBPF device filter program +// Package devicefilter contains eBPF device filter program // // The implementation is based on https://github.com/containers/crun/blob/0.10.2/src/libcrun/ebpf.c // @@ -7,11 +7,11 @@ package devicefilter import ( - "fmt" "math" + "strconv" "github.com/cilium/ebpf/asm" - "github.com/opencontainers/runc/libcontainer/configs" + "github.com/opencontainers/runc/libcontainer/devices" "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -22,7 +22,7 @@ const ( ) // DeviceFilter returns eBPF device filter program and its license string -func DeviceFilter(devices []*configs.DeviceRule) (asm.Instructions, string, error) { +func DeviceFilter(devices []*devices.Rule) (asm.Instructions, string, error) { p := &program{} p.init() for i := len(devices) - 1; i >= 0; i-- { @@ -68,7 +68,7 @@ func (p *program) init() { } // appendDevice needs to be called from the last element of OCI linux.resources.devices to the head element. -func (p *program) appendDevice(dev *configs.DeviceRule) error { +func (p *program) appendDevice(dev *devices.Rule) error { if p.blockID < 0 { return errors.New("the program is finalized") } @@ -88,7 +88,7 @@ func (p *program) appendDevice(dev *configs.DeviceRule) error { hasType = false default: // if not specified in OCI json, typ is set to DeviceTypeAll - return errors.Errorf("invalid DeviceType %q", string(dev.Type)) + return errors.Errorf("invalid Type %q", string(dev.Type)) } if dev.Major > math.MaxUint32 { return errors.Errorf("invalid major %d", dev.Major) @@ -114,9 +114,11 @@ func (p *program) appendDevice(dev *configs.DeviceRule) error { // If the access is rwm, skip the check. hasAccess := bpfAccess != (unix.BPF_DEVCG_ACC_READ | unix.BPF_DEVCG_ACC_WRITE | unix.BPF_DEVCG_ACC_MKNOD) - blockSym := fmt.Sprintf("block-%d", p.blockID) - nextBlockSym := fmt.Sprintf("block-%d", p.blockID+1) - prevBlockLastIdx := len(p.insts) - 1 + var ( + blockSym = "block-" + strconv.Itoa(p.blockID) + nextBlockSym = "block-" + strconv.Itoa(p.blockID+1) + prevBlockLastIdx = len(p.insts) - 1 + ) if hasType { p.insts = append(p.insts, // if (R2 != bpfType) goto next @@ -158,7 +160,7 @@ func (p *program) finalize() (asm.Instructions, error) { // acceptBlock with asm.Return() is already inserted return p.insts, nil } - blockSym := fmt.Sprintf("block-%d", p.blockID) + blockSym := "block-" + strconv.Itoa(p.blockID) p.insts = append(p.insts, // R0 <- 0 asm.Mov.Imm32(asm.R0, 0).Sym(blockSym), diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go index 031a6bbdab2..dca2a622078 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go @@ -6,7 +6,6 @@ import ( "bufio" "fmt" "os" - "path/filepath" "strconv" "strings" @@ -105,9 +104,9 @@ func splitBlkioStatLine(r rune) bool { return r == ' ' || r == ':' } -func getBlkioStat(path string) ([]cgroups.BlkioStatEntry, error) { +func getBlkioStat(dir, file string) ([]cgroups.BlkioStatEntry, error) { var blkioStats []cgroups.BlkioStatEntry - f, err := os.Open(path) + f, err := fscommon.OpenFile(dir, file, os.O_RDONLY) if err != nil { if os.IsNotExist(err) { return blkioStats, nil @@ -125,7 +124,7 @@ func getBlkioStat(path string) ([]cgroups.BlkioStatEntry, error) { // skip total line continue } else { - return nil, fmt.Errorf("Invalid line found while parsing %s: %s", path, sc.Text()) + return nil, fmt.Errorf("Invalid line found while parsing %s/%s: %s", dir, file, sc.Text()) } } @@ -158,73 +157,134 @@ func getBlkioStat(path string) ([]cgroups.BlkioStatEntry, error) { } func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error { - // Try to read CFQ stats available on all CFQ enabled kernels first - if blkioStats, err := getBlkioStat(filepath.Join(path, "blkio.io_serviced_recursive")); err == nil && blkioStats != nil { - return getCFQStats(path, stats) + type blkioStatInfo struct { + filename string + blkioStatEntriesPtr *[]cgroups.BlkioStatEntry + } + var bfqDebugStats = []blkioStatInfo{ + { + filename: "blkio.bfq.sectors_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.SectorsRecursive, + }, + { + filename: "blkio.bfq.io_service_time_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoServiceTimeRecursive, + }, + { + filename: "blkio.bfq.io_wait_time_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoWaitTimeRecursive, + }, + { + filename: "blkio.bfq.io_merged_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoMergedRecursive, + }, + { + filename: "blkio.bfq.io_queued_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoQueuedRecursive, + }, + { + filename: "blkio.bfq.time_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoTimeRecursive, + }, + { + filename: "blkio.bfq.io_serviced_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive, + }, + { + filename: "blkio.bfq.io_service_bytes_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive, + }, + } + var bfqStats = []blkioStatInfo{ + { + filename: "blkio.bfq.io_serviced_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive, + }, + { + filename: "blkio.bfq.io_service_bytes_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive, + }, + } + var cfqStats = []blkioStatInfo{ + { + filename: "blkio.sectors_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.SectorsRecursive, + }, + { + filename: "blkio.io_service_time_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoServiceTimeRecursive, + }, + { + filename: "blkio.io_wait_time_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoWaitTimeRecursive, + }, + { + filename: "blkio.io_merged_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoMergedRecursive, + }, + { + filename: "blkio.io_queued_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoQueuedRecursive, + }, + { + filename: "blkio.time_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoTimeRecursive, + }, + { + filename: "blkio.io_serviced_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive, + }, + { + filename: "blkio.io_service_bytes_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive, + }, + } + var throttleRecursiveStats = []blkioStatInfo{ + { + filename: "blkio.throttle.io_serviced_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive, + }, + { + filename: "blkio.throttle.io_service_bytes_recursive", + blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive, + }, + } + var baseStats = []blkioStatInfo{ + { + filename: "blkio.throttle.io_serviced", + blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive, + }, + { + filename: "blkio.throttle.io_service_bytes", + blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive, + }, + } + var orderedStats = [][]blkioStatInfo{ + bfqDebugStats, + bfqStats, + cfqStats, + throttleRecursiveStats, + baseStats, } - return getStats(path, stats) // Use generic stats as fallback -} -func getCFQStats(path string, stats *cgroups.Stats) error { var blkioStats []cgroups.BlkioStatEntry var err error - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.sectors_recursive")); err != nil { - return err + for _, statGroup := range orderedStats { + for i, statInfo := range statGroup { + if blkioStats, err = getBlkioStat(path, statInfo.filename); err != nil || blkioStats == nil { + // if error occurs on first file, move to next group + if i == 0 { + break + } + return err + } + *statInfo.blkioStatEntriesPtr = blkioStats + //finish if all stats are gathered + if i == len(statGroup)-1 { + return nil + } + } } - stats.BlkioStats.SectorsRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_service_bytes_recursive")); err != nil { - return err - } - stats.BlkioStats.IoServiceBytesRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_serviced_recursive")); err != nil { - return err - } - stats.BlkioStats.IoServicedRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_queued_recursive")); err != nil { - return err - } - stats.BlkioStats.IoQueuedRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_service_time_recursive")); err != nil { - return err - } - stats.BlkioStats.IoServiceTimeRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_wait_time_recursive")); err != nil { - return err - } - stats.BlkioStats.IoWaitTimeRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_merged_recursive")); err != nil { - return err - } - stats.BlkioStats.IoMergedRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.time_recursive")); err != nil { - return err - } - stats.BlkioStats.IoTimeRecursive = blkioStats - - return nil -} - -func getStats(path string, stats *cgroups.Stats) error { - var blkioStats []cgroups.BlkioStatEntry - var err error - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.throttle.io_service_bytes")); err != nil { - return err - } - stats.BlkioStats.IoServiceBytesRecursive = blkioStats - - if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.throttle.io_serviced")); err != nil { - return err - } - stats.BlkioStats.IoServicedRecursive = blkioStats - return nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go index 6fb1c2078a5..1d5f455d6a4 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go @@ -6,7 +6,6 @@ import ( "bufio" "fmt" "os" - "path/filepath" "strconv" "github.com/opencontainers/runc/libcontainer/cgroups" @@ -87,7 +86,7 @@ func (s *CpuGroup) Set(path string, cgroup *configs.Cgroup) error { } func (s *CpuGroup) GetStats(path string, stats *cgroups.Stats) error { - f, err := os.Open(filepath.Join(path, "cpu.stat")) + f, err := fscommon.OpenFile(path, "cpu.stat", os.O_RDONLY) if err != nil { if os.IsNotExist(err) { return nil diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go index 1a18971bc5a..129de6a01cd 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go @@ -5,7 +5,6 @@ package fs import ( "bufio" "fmt" - "io/ioutil" "os" "path/filepath" "strconv" @@ -83,8 +82,7 @@ func (s *CpuacctGroup) GetStats(path string, stats *cgroups.Stats) error { // Returns user and kernel usage breakdown in nanoseconds. func getCpuUsageBreakdown(path string) (uint64, uint64, error) { - userModeUsage := uint64(0) - kernelModeUsage := uint64(0) + var userModeUsage, kernelModeUsage uint64 const ( userField = "user" systemField = "system" @@ -93,11 +91,11 @@ func getCpuUsageBreakdown(path string) (uint64, uint64, error) { // Expected format: // user // system - data, err := ioutil.ReadFile(filepath.Join(path, cgroupCpuacctStat)) + data, err := fscommon.ReadFile(path, cgroupCpuacctStat) if err != nil { return 0, 0, err } - fields := strings.Fields(string(data)) + fields := strings.Fields(data) if len(fields) < 4 { return 0, 0, fmt.Errorf("failure - %s is expected to have at least 4 fields", filepath.Join(path, cgroupCpuacctStat)) } @@ -119,11 +117,11 @@ func getCpuUsageBreakdown(path string) (uint64, uint64, error) { func getPercpuUsage(path string) ([]uint64, error) { percpuUsage := []uint64{} - data, err := ioutil.ReadFile(filepath.Join(path, "cpuacct.usage_percpu")) + data, err := fscommon.ReadFile(path, "cpuacct.usage_percpu") if err != nil { return percpuUsage, err } - for _, value := range strings.Fields(string(data)) { + for _, value := range strings.Fields(data) { value, err := strconv.ParseUint(value, 10, 64) if err != nil { return percpuUsage, fmt.Errorf("Unable to convert param value to uint64: %s", err) @@ -137,7 +135,7 @@ func getPercpuUsageInModes(path string) ([]uint64, []uint64, error) { usageKernelMode := []uint64{} usageUserMode := []uint64{} - file, err := os.Open(filepath.Join(path, cgroupCpuacctUsageAll)) + file, err := fscommon.OpenFile(path, cgroupCpuacctUsageAll, os.O_RDONLY) if os.IsNotExist(err) { return usageKernelMode, usageUserMode, nil } else if err != nil { diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go index ba17519baea..5bde025b4b9 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go @@ -3,17 +3,17 @@ package fs import ( - "bytes" - "io/ioutil" + "fmt" "os" "path/filepath" + "strconv" + "strings" - "github.com/moby/sys/mountinfo" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" "github.com/opencontainers/runc/libcontainer/configs" - libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils" "github.com/pkg/errors" + "golang.org/x/sys/unix" ) type CpusetGroup struct { @@ -41,30 +41,107 @@ func (s *CpusetGroup) Set(path string, cgroup *configs.Cgroup) error { return nil } -func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error { - return nil -} - -// Get the source mount point of directory passed in as argument. -func getMount(dir string) (string, error) { - mi, err := mountinfo.GetMounts(mountinfo.ParentsFilter(dir)) +func getCpusetStat(path string, filename string) ([]uint16, error) { + var extracted []uint16 + fileContent, err := fscommon.GetCgroupParamString(path, filename) if err != nil { - return "", err + return extracted, err } - if len(mi) < 1 { - return "", errors.Errorf("Can't find mount point of %s", dir) + if len(fileContent) == 0 { + return extracted, fmt.Errorf("%s found to be empty", filepath.Join(path, filename)) } - // find the longest mount point - var idx, maxlen int - for i := range mi { - if len(mi[i].Mountpoint) > maxlen { - maxlen = len(mi[i].Mountpoint) - idx = i + for _, s := range strings.Split(fileContent, ",") { + splitted := strings.SplitN(s, "-", 3) + switch len(splitted) { + case 3: + return extracted, fmt.Errorf("invalid values in %s", filepath.Join(path, filename)) + case 2: + min, err := strconv.ParseUint(splitted[0], 10, 16) + if err != nil { + return extracted, err + } + max, err := strconv.ParseUint(splitted[1], 10, 16) + if err != nil { + return extracted, err + } + if min > max { + return extracted, fmt.Errorf("invalid values in %s", filepath.Join(path, filename)) + } + for i := min; i <= max; i++ { + extracted = append(extracted, uint16(i)) + } + case 1: + value, err := strconv.ParseUint(s, 10, 16) + if err != nil { + return extracted, err + } + extracted = append(extracted, uint16(value)) } } - return mi[idx].Mountpoint, nil + return extracted, nil +} + +func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error { + var err error + + stats.CPUSetStats.CPUs, err = getCpusetStat(path, "cpuset.cpus") + if err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + stats.CPUSetStats.CPUExclusive, err = fscommon.GetCgroupParamUint(path, "cpuset.cpu_exclusive") + if err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + stats.CPUSetStats.Mems, err = getCpusetStat(path, "cpuset.mems") + if err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + stats.CPUSetStats.MemHardwall, err = fscommon.GetCgroupParamUint(path, "cpuset.mem_hardwall") + if err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + stats.CPUSetStats.MemExclusive, err = fscommon.GetCgroupParamUint(path, "cpuset.mem_exclusive") + if err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + stats.CPUSetStats.MemoryMigrate, err = fscommon.GetCgroupParamUint(path, "cpuset.memory_migrate") + if err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + stats.CPUSetStats.MemorySpreadPage, err = fscommon.GetCgroupParamUint(path, "cpuset.memory_spread_page") + if err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + stats.CPUSetStats.MemorySpreadSlab, err = fscommon.GetCgroupParamUint(path, "cpuset.memory_spread_slab") + if err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + stats.CPUSetStats.MemoryPressure, err = fscommon.GetCgroupParamUint(path, "cpuset.memory_pressure") + if err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + stats.CPUSetStats.SchedLoadBalance, err = fscommon.GetCgroupParamUint(path, "cpuset.sched_load_balance") + if err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + stats.CPUSetStats.SchedRelaxDomainLevel, err = fscommon.GetCgroupParamInt(path, "cpuset.sched_relax_domain_level") + if err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + + return nil } func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) error { @@ -73,18 +150,13 @@ func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) erro if dir == "" { return nil } - root, err := getMount(dir) - if err != nil { - return err - } - root = filepath.Dir(root) // 'ensureParent' start with parent because we don't want to // explicitly inherit from parent, it could conflict with // 'cpuset.cpu_exclusive'. - if err := s.ensureParent(filepath.Dir(dir), root); err != nil { + if err := cpusetEnsureParent(filepath.Dir(dir)); err != nil { return err } - if err := os.MkdirAll(dir, 0755); err != nil { + if err := os.Mkdir(dir, 0755); err != nil && !os.IsExist(err) { return err } // We didn't inherit cpuset configs from parent, but we have @@ -103,59 +175,61 @@ func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) erro return cgroups.WriteCgroupProc(dir, pid) } -func (s *CpusetGroup) getSubsystemSettings(parent string) (cpus []byte, mems []byte, err error) { - if cpus, err = ioutil.ReadFile(filepath.Join(parent, "cpuset.cpus")); err != nil { +func getCpusetSubsystemSettings(parent string) (cpus, mems string, err error) { + if cpus, err = fscommon.ReadFile(parent, "cpuset.cpus"); err != nil { return } - if mems, err = ioutil.ReadFile(filepath.Join(parent, "cpuset.mems")); err != nil { + if mems, err = fscommon.ReadFile(parent, "cpuset.mems"); err != nil { return } return cpus, mems, nil } -// ensureParent makes sure that the parent directory of current is created -// and populated with the proper cpus and mems files copied from -// it's parent. -func (s *CpusetGroup) ensureParent(current, root string) error { +// cpusetEnsureParent makes sure that the parent directories of current +// are created and populated with the proper cpus and mems files copied +// from their respective parent. It does that recursively, starting from +// the top of the cpuset hierarchy (i.e. cpuset cgroup mount point). +func cpusetEnsureParent(current string) error { + var st unix.Statfs_t + parent := filepath.Dir(current) - if libcontainerUtils.CleanPath(parent) == root { + err := unix.Statfs(parent, &st) + if err == nil && st.Type != unix.CGROUP_SUPER_MAGIC { return nil } - // Avoid infinite recursion. - if parent == current { - return errors.New("cpuset: cgroup parent path outside cgroup root") + // Treat non-existing directory as cgroupfs as it will be created, + // and the root cpuset directory obviously exists. + if err != nil && err != unix.ENOENT { + return &os.PathError{Op: "statfs", Path: parent, Err: err} } - if err := s.ensureParent(parent, root); err != nil { + + if err := cpusetEnsureParent(parent); err != nil { return err } - if err := os.MkdirAll(current, 0755); err != nil { + if err := os.Mkdir(current, 0755); err != nil && !os.IsExist(err) { return err } - return s.copyIfNeeded(current, parent) + return cpusetCopyIfNeeded(current, parent) } -// copyIfNeeded copies the cpuset.cpus and cpuset.mems from the parent +// cpusetCopyIfNeeded copies the cpuset.cpus and cpuset.mems from the parent // directory to the current directory if the file's contents are 0 -func (s *CpusetGroup) copyIfNeeded(current, parent string) error { - var ( - err error - currentCpus, currentMems []byte - parentCpus, parentMems []byte - ) - - if currentCpus, currentMems, err = s.getSubsystemSettings(current); err != nil { +func cpusetCopyIfNeeded(current, parent string) error { + currentCpus, currentMems, err := getCpusetSubsystemSettings(current) + if err != nil { return err } - if parentCpus, parentMems, err = s.getSubsystemSettings(parent); err != nil { + parentCpus, parentMems, err := getCpusetSubsystemSettings(parent) + if err != nil { return err } - if s.isEmpty(currentCpus) { + if isEmptyCpuset(currentCpus) { if err := fscommon.WriteFile(current, "cpuset.cpus", string(parentCpus)); err != nil { return err } } - if s.isEmpty(currentMems) { + if isEmptyCpuset(currentMems) { if err := fscommon.WriteFile(current, "cpuset.mems", string(parentMems)); err != nil { return err } @@ -163,13 +237,13 @@ func (s *CpusetGroup) copyIfNeeded(current, parent string) error { return nil } -func (s *CpusetGroup) isEmpty(b []byte) bool { - return len(bytes.Trim(b, "\n")) == 0 +func isEmptyCpuset(str string) bool { + return str == "" || str == "\n" } func (s *CpusetGroup) ensureCpusAndMems(path string, cgroup *configs.Cgroup) error { if err := s.Set(path, cgroup); err != nil { return err } - return s.copyIfNeeded(path, filepath.Dir(path)) + return cpusetCopyIfNeeded(path, filepath.Dir(path)) } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go index fd8f00d5bfd..9a37e68ec65 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go @@ -8,9 +8,10 @@ import ( "reflect" "github.com/opencontainers/runc/libcontainer/cgroups" - "github.com/opencontainers/runc/libcontainer/cgroups/devices" + cgroupdevices "github.com/opencontainers/runc/libcontainer/cgroups/devices" "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" "github.com/opencontainers/runc/libcontainer/configs" + "github.com/opencontainers/runc/libcontainer/devices" "github.com/opencontainers/runc/libcontainer/system" ) @@ -34,17 +35,17 @@ func (s *DevicesGroup) Apply(path string, d *cgroupData) error { return join(path, d.pid) } -func loadEmulator(path string) (*devices.Emulator, error) { +func loadEmulator(path string) (*cgroupdevices.Emulator, error) { list, err := fscommon.ReadFile(path, "devices.list") if err != nil { return nil, err } - return devices.EmulatorFromList(bytes.NewBufferString(list)) + return cgroupdevices.EmulatorFromList(bytes.NewBufferString(list)) } -func buildEmulator(rules []*configs.DeviceRule) (*devices.Emulator, error) { +func buildEmulator(rules []*devices.Rule) (*cgroupdevices.Emulator, error) { // This defaults to a white-list -- which is what we want! - emu := &devices.Emulator{} + emu := &cgroupdevices.Emulator{} for _, rule := range rules { if err := emu.Apply(*rule); err != nil { return nil, err diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go index 11cb1646f48..25aff4f863f 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go @@ -28,33 +28,54 @@ func (s *FreezerGroup) Apply(path string, d *cgroupData) error { func (s *FreezerGroup) Set(path string, cgroup *configs.Cgroup) error { switch cgroup.Resources.Freezer { - case configs.Frozen, configs.Thawed: - for { - // In case this loop does not exit because it doesn't get the expected - // state, let's write again this state, hoping it's going to be properly - // set this time. Otherwise, this loop could run infinitely, waiting for - // a state change that would never happen. - if err := fscommon.WriteFile(path, "freezer.state", string(cgroup.Resources.Freezer)); err != nil { + case configs.Frozen: + // As per older kernel docs (freezer-subsystem.txt before + // kernel commit ef9fe980c6fcc1821), if FREEZING is seen, + // userspace should either retry or thaw. While current + // kernel cgroup v1 docs no longer mention a need to retry, + // the kernel (tested on v5.4, Ubuntu 20.04) can't reliably + // freeze a cgroup while new processes keep appearing in it + // (either via fork/clone or by writing new PIDs to + // cgroup.procs). + // + // The number of retries below is chosen to have a decent + // chance to succeed even in the worst case scenario (runc + // pause/unpause with parallel runc exec). + // + // Adding any amount of sleep in between retries did not + // increase the chances of successful freeze. + for i := 0; i < 1000; i++ { + if err := fscommon.WriteFile(path, "freezer.state", string(configs.Frozen)); err != nil { return err } - state, err := s.GetState(path) + state, err := fscommon.ReadFile(path, "freezer.state") if err != nil { return err } - if state == cgroup.Resources.Freezer { - break + state = strings.TrimSpace(state) + switch state { + case "FREEZING": + continue + case string(configs.Frozen): + return nil + default: + // should never happen + return fmt.Errorf("unexpected state %s while freezing", strings.TrimSpace(state)) } - - time.Sleep(1 * time.Millisecond) } + // Despite our best efforts, it got stuck in FREEZING. + // Leaving it in this state is bad and dangerous, so + // let's (try to) thaw it back and error out. + _ = fscommon.WriteFile(path, "freezer.state", string(configs.Thawed)) + return errors.New("unable to freeze") + case configs.Thawed: + return fscommon.WriteFile(path, "freezer.state", string(configs.Thawed)) case configs.Undefined: return nil default: return fmt.Errorf("Invalid argument '%s' to freezer.state", string(cgroup.Resources.Freezer)) } - - return nil } func (s *FreezerGroup) GetStats(path string, stats *cgroups.Stats) error { diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs.go index 3ccf3a3c61d..a42ce4535e9 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs.go @@ -3,11 +3,9 @@ package fs import ( - "bufio" "fmt" "os" "path/filepath" - "strings" "sync" "github.com/opencontainers/runc/libcontainer/cgroups" @@ -133,46 +131,19 @@ func getCgroupRoot() (string, error) { return cgroupRoot, nil } - // slow path: parse mountinfo, find the first mount where fs=cgroup - // (e.g. "/sys/fs/cgroup/memory"), use its parent. - f, err := os.Open("/proc/self/mountinfo") + // slow path: parse mountinfo + mi, err := cgroups.GetCgroupMounts(false) if err != nil { return "", err } - defer f.Close() - - var root string - scanner := bufio.NewScanner(f) - for scanner.Scan() { - text := scanner.Text() - fields := strings.Split(text, " ") - // Safe as mountinfo encodes mountpoints with spaces as \040. - index := strings.Index(text, " - ") - postSeparatorFields := strings.Fields(text[index+3:]) - numPostFields := len(postSeparatorFields) - - // This is an error as we can't detect if the mount is for "cgroup" - if numPostFields == 0 { - return "", fmt.Errorf("mountinfo: found no fields post '-' in %q", text) - } - - if postSeparatorFields[0] == "cgroup" { - // Check that the mount is properly formatted. - if numPostFields < 3 { - return "", fmt.Errorf("Error found less than 3 fields post '-' in %q", text) - } - - root = filepath.Dir(fields[4]) - break - } - } - if err := scanner.Err(); err != nil { - return "", err - } - if root == "" { + if len(mi) < 1 { return "", errors.New("no cgroup mount found in mountinfo") } + // Get the first cgroup mount (e.g. "/sys/fs/cgroup/memory"), + // use its parent directory. + root := filepath.Dir(mi[0].Mountpoint) + if _, err := os.Stat(root); err != nil { return "", err } @@ -218,28 +189,31 @@ func (m *manager) Apply(pid int) (err error) { m.mu.Lock() defer m.mu.Unlock() - var c = m.cgroups - - d, err := getCgroupData(m.cgroups, pid) - if err != nil { - return err + c := m.cgroups + if c.Resources.Unified != nil { + return cgroups.ErrV1NoUnified } m.paths = make(map[string]string) if c.Paths != nil { + cgMap, err := cgroups.ParseCgroupFile("/proc/self/cgroup") + if err != nil { + return err + } for name, path := range c.Paths { - _, err := d.path(name) - if err != nil { - if cgroups.IsNotFound(err) { - continue - } - return err + // XXX(kolyshkin@): why this check is needed? + if _, ok := cgMap[name]; ok { + m.paths[name] = path } - m.paths[name] = path } return cgroups.EnterPid(m.paths, pid) } + d, err := getCgroupData(m.cgroups, pid) + if err != nil { + return err + } + for _, sys := range subsystems { p, err := d.path(sys.Name()) if err != nil { @@ -274,11 +248,7 @@ func (m *manager) Destroy() error { } m.mu.Lock() defer m.mu.Unlock() - if err := cgroups.RemovePaths(m.paths); err != nil { - return err - } - m.paths = make(map[string]string) - return nil + return cgroups.RemovePaths(m.paths) } func (m *manager) Path(subsys string) string { @@ -313,6 +283,9 @@ func (m *manager) Set(container *configs.Config) error { if m.cgroups != nil && m.cgroups.Paths != nil { return nil } + if container.Cgroups.Resources.Unified != nil { + return cgroups.ErrV1NoUnified + } m.mu.Lock() defer m.mu.Unlock() @@ -425,16 +398,6 @@ func join(path string, pid int) error { return cgroups.WriteCgroupProc(path, pid) } -func removePath(p string, err error) error { - if err != nil { - return err - } - if p != "" { - return os.RemoveAll(p) - } - return nil -} - func (m *manager) GetPaths() map[string]string { m.mu.Lock() defer m.mu.Unlock() diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go index d32d02da1ca..861793411e6 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go @@ -5,7 +5,6 @@ package fs import ( "fmt" "strconv" - "strings" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" @@ -25,7 +24,7 @@ func (s *HugetlbGroup) Apply(path string, d *cgroupData) error { func (s *HugetlbGroup) Set(path string, cgroup *configs.Cgroup) error { for _, hugetlb := range cgroup.Resources.HugetlbLimit { - if err := fscommon.WriteFile(path, strings.Join([]string{"hugetlb", hugetlb.Pagesize, "limit_in_bytes"}, "."), strconv.FormatUint(hugetlb.Limit, 10)); err != nil { + if err := fscommon.WriteFile(path, "hugetlb."+hugetlb.Pagesize+".limit_in_bytes", strconv.FormatUint(hugetlb.Limit, 10)); err != nil { return err } } @@ -39,21 +38,21 @@ func (s *HugetlbGroup) GetStats(path string, stats *cgroups.Stats) error { return nil } for _, pageSize := range HugePageSizes { - usage := strings.Join([]string{"hugetlb", pageSize, "usage_in_bytes"}, ".") + usage := "hugetlb." + pageSize + ".usage_in_bytes" value, err := fscommon.GetCgroupParamUint(path, usage) if err != nil { return fmt.Errorf("failed to parse %s - %v", usage, err) } hugetlbStats.Usage = value - maxUsage := strings.Join([]string{"hugetlb", pageSize, "max_usage_in_bytes"}, ".") + maxUsage := "hugetlb." + pageSize + ".max_usage_in_bytes" value, err = fscommon.GetCgroupParamUint(path, maxUsage) if err != nil { return fmt.Errorf("failed to parse %s - %v", maxUsage, err) } hugetlbStats.MaxUsage = value - failcnt := strings.Join([]string{"hugetlb", pageSize, "failcnt"}, ".") + failcnt := "hugetlb." + pageSize + ".failcnt" value, err = fscommon.GetCgroupParamUint(path, failcnt) if err != nil { return fmt.Errorf("failed to parse %s - %v", failcnt, err) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/kmem.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/kmem.go index 8d97a6791a4..86858f9083e 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/kmem.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/kmem.go @@ -5,11 +5,11 @@ package fs import ( "errors" "fmt" - "io/ioutil" "path/filepath" "strconv" "github.com/opencontainers/runc/libcontainer/cgroups" + "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" "golang.org/x/sys/unix" ) @@ -42,7 +42,7 @@ func setKernelMemory(path string, kernelMemoryLimit int64) error { // doesn't support it we *must* error out. return errors.New("kernel memory accounting not supported by this kernel") } - if err := ioutil.WriteFile(filepath.Join(path, cgroupKernelMemoryLimit), []byte(strconv.FormatInt(kernelMemoryLimit, 10)), 0700); err != nil { + if err := fscommon.WriteFile(path, cgroupKernelMemoryLimit, strconv.FormatInt(kernelMemoryLimit, 10)); err != nil { // Check if the error number returned by the syscall is "EBUSY" // The EBUSY signal is returned on attempts to write to the // memory.kmem.limit_in_bytes file if the cgroup has children or @@ -50,7 +50,7 @@ func setKernelMemory(path string, kernelMemoryLimit int64) error { if errors.Is(err, unix.EBUSY) { return fmt.Errorf("failed to set %s, because either tasks have already joined this cgroup or it has children", cgroupKernelMemoryLimit) } - return fmt.Errorf("failed to write %v to %v: %v", kernelMemoryLimit, cgroupKernelMemoryLimit, err) + return err } return nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go index 41adcd38f47..61be6d7e9a6 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go @@ -7,7 +7,6 @@ import ( "fmt" "math" "os" - "path" "path/filepath" "strconv" "strings" @@ -18,16 +17,8 @@ import ( ) const ( - numaNodeSymbol = "N" - numaStatColumnSeparator = " " - numaStatKeyValueSeparator = "=" - numaStatMaxColumns = math.MaxUint8 + 1 - numaStatValueIndex = 1 - numaStatTypeIndex = 0 - numaStatColumnSliceLength = 2 - cgroupMemorySwapLimit = "memory.memsw.limit_in_bytes" - cgroupMemoryLimit = "memory.limit_in_bytes" - cgroupMemoryPagesByNuma = "memory.numa_stat" + cgroupMemorySwapLimit = "memory.memsw.limit_in_bytes" + cgroupMemoryLimit = "memory.limit_in_bytes" ) type MemoryGroup struct { @@ -160,7 +151,7 @@ func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error { func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error { // Set stats from memory.stat. - statsFile, err := os.Open(filepath.Join(path, "memory.stat")) + statsFile, err := fscommon.OpenFile(path, "memory.stat", os.O_RDONLY) if err != nil { if os.IsNotExist(err) { return nil @@ -200,8 +191,7 @@ func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error { } stats.MemoryStats.KernelTCPUsage = kernelTCPUsage - useHierarchy := strings.Join([]string{"memory", "use_hierarchy"}, ".") - value, err := fscommon.GetCgroupParamUint(path, useHierarchy) + value, err := fscommon.GetCgroupParamUint(path, "memory.use_hierarchy") if err != nil { return err } @@ -233,12 +223,14 @@ func getMemoryData(path, name string) (cgroups.MemoryData, error) { moduleName := "memory" if name != "" { - moduleName = strings.Join([]string{"memory", name}, ".") + moduleName = "memory." + name } - usage := strings.Join([]string{moduleName, "usage_in_bytes"}, ".") - maxUsage := strings.Join([]string{moduleName, "max_usage_in_bytes"}, ".") - failcnt := strings.Join([]string{moduleName, "failcnt"}, ".") - limit := strings.Join([]string{moduleName, "limit_in_bytes"}, ".") + var ( + usage = moduleName + ".usage_in_bytes" + maxUsage = moduleName + ".max_usage_in_bytes" + failcnt = moduleName + ".failcnt" + limit = moduleName + ".limit_in_bytes" + ) value, err := fscommon.GetCgroupParamUint(path, usage) if err != nil { @@ -277,47 +269,81 @@ func getMemoryData(path, name string) (cgroups.MemoryData, error) { } func getPageUsageByNUMA(cgroupPath string) (cgroups.PageUsageByNUMA, error) { + const ( + maxColumns = math.MaxUint8 + 1 + filename = "memory.numa_stat" + ) stats := cgroups.PageUsageByNUMA{} - file, err := os.Open(path.Join(cgroupPath, cgroupMemoryPagesByNuma)) + file, err := fscommon.OpenFile(cgroupPath, filename, os.O_RDONLY) if os.IsNotExist(err) { return stats, nil } else if err != nil { return stats, err } + // File format is documented in linux/Documentation/cgroup-v1/memory.txt + // and it looks like this: + // + // total= N0= N1= ... + // file= N0= N1= ... + // anon= N0= N1= ... + // unevictable= N0= N1= ... + // hierarchical_= N0= N1= ... + scanner := bufio.NewScanner(file) for scanner.Scan() { - var statsType string - statsByType := cgroups.PageStats{Nodes: map[uint8]uint64{}} - columns := strings.SplitN(scanner.Text(), numaStatColumnSeparator, numaStatMaxColumns) + var field *cgroups.PageStats - for _, column := range columns { - pagesByNode := strings.SplitN(column, numaStatKeyValueSeparator, numaStatColumnSliceLength) + line := scanner.Text() + columns := strings.SplitN(line, " ", maxColumns) + for i, column := range columns { + byNode := strings.SplitN(column, "=", 2) + // Some custom kernels have non-standard fields, like + // numa_locality 0 0 0 0 0 0 0 0 0 0 + // numa_exectime 0 + if len(byNode) < 2 { + if i == 0 { + // Ignore/skip those. + break + } else { + // The first column was already validated, + // so be strict to the rest. + return stats, fmt.Errorf("malformed line %q in %s", + line, filename) + } + } + key, val := byNode[0], byNode[1] + if i == 0 { // First column: key is name, val is total. + field = getNUMAField(&stats, key) + if field == nil { // unknown field (new kernel?) + break + } + field.Total, err = strconv.ParseUint(val, 0, 64) + if err != nil { + return stats, err + } + field.Nodes = map[uint8]uint64{} + } else { // Subsequent columns: key is N, val is usage. + if len(key) < 2 || key[0] != 'N' { + // This is definitely an error. + return stats, fmt.Errorf("malformed line %q in %s", + line, filename) + } - if strings.HasPrefix(pagesByNode[numaStatTypeIndex], numaNodeSymbol) { - nodeID, err := strconv.ParseUint(pagesByNode[numaStatTypeIndex][1:], 10, 8) + n, err := strconv.ParseUint(key[1:], 10, 8) if err != nil { return cgroups.PageUsageByNUMA{}, err } - statsByType.Nodes[uint8(nodeID)], err = strconv.ParseUint(pagesByNode[numaStatValueIndex], 0, 64) - if err != nil { - return cgroups.PageUsageByNUMA{}, err - } - } else { - statsByType.Total, err = strconv.ParseUint(pagesByNode[numaStatValueIndex], 0, 64) + usage, err := strconv.ParseUint(val, 10, 64) if err != nil { return cgroups.PageUsageByNUMA{}, err } - statsType = pagesByNode[numaStatTypeIndex] + field.Nodes[uint8(n)] = usage } - err := addNUMAStatsByType(&stats, statsByType, statsType) - if err != nil { - return cgroups.PageUsageByNUMA{}, err - } } } err = scanner.Err() @@ -328,26 +354,24 @@ func getPageUsageByNUMA(cgroupPath string) (cgroups.PageUsageByNUMA, error) { return stats, nil } -func addNUMAStatsByType(stats *cgroups.PageUsageByNUMA, byTypeStats cgroups.PageStats, statsType string) error { - switch statsType { +func getNUMAField(stats *cgroups.PageUsageByNUMA, name string) *cgroups.PageStats { + switch name { case "total": - stats.Total = byTypeStats + return &stats.Total case "file": - stats.File = byTypeStats + return &stats.File case "anon": - stats.Anon = byTypeStats + return &stats.Anon case "unevictable": - stats.Unevictable = byTypeStats + return &stats.Unevictable case "hierarchical_total": - stats.Hierarchical.Total = byTypeStats + return &stats.Hierarchical.Total case "hierarchical_file": - stats.Hierarchical.File = byTypeStats + return &stats.Hierarchical.File case "hierarchical_anon": - stats.Hierarchical.Anon = byTypeStats + return &stats.Hierarchical.Anon case "hierarchical_unevictable": - stats.Hierarchical.Unevictable = byTypeStats - default: - return fmt.Errorf("unsupported NUMA page type found: %s", statsType) + return &stats.Hierarchical.Unevictable } return nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go index 9a5af709d24..7cada9149d4 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go @@ -19,7 +19,7 @@ func (s *NameGroup) Name() string { func (s *NameGroup) Apply(path string, d *cgroupData) error { if s.Join { // ignore errors if the named cgroup does not exist - join(path, d.pid) + _ = join(path, d.pid) } return nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpu.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpu.go index edf1060ecb4..0dffe6648e9 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpu.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/cpu.go @@ -5,7 +5,6 @@ package fs2 import ( "bufio" "os" - "path/filepath" "strconv" "github.com/opencontainers/runc/libcontainer/cgroups" @@ -50,7 +49,7 @@ func setCpu(dirPath string, cgroup *configs.Cgroup) error { return nil } func statCpu(dirPath string, stats *cgroups.Stats) error { - f, err := os.Open(filepath.Join(dirPath, "cpu.stat")) + f, err := fscommon.OpenFile(dirPath, "cpu.stat", os.O_RDONLY) if err != nil { return err } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/create.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/create.go index 7be9ece0bf4..30cf51ee68b 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/create.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/create.go @@ -1,19 +1,17 @@ package fs2 import ( - "bytes" "fmt" - "io/ioutil" "os" "path/filepath" "strings" + "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" "github.com/opencontainers/runc/libcontainer/configs" ) -func supportedControllers(cgroup *configs.Cgroup) ([]byte, error) { - const file = UnifiedMountpoint + "/cgroup.controllers" - return ioutil.ReadFile(file) +func supportedControllers(cgroup *configs.Cgroup) (string, error) { + return fscommon.ReadFile(UnifiedMountpoint, "/cgroup.controllers") } // needAnyControllers returns whether we enable some supported controllers or not, @@ -31,7 +29,7 @@ func needAnyControllers(cgroup *configs.Cgroup) (bool, error) { return false, err } avail := make(map[string]struct{}) - for _, ctr := range strings.Fields(string(content)) { + for _, ctr := range strings.Fields(content) { avail[ctr] = struct{}{} } @@ -81,8 +79,12 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) { return err } - ctrs := bytes.Fields(content) - res := append([]byte("+"), bytes.Join(ctrs, []byte(" +"))...) + const ( + cgTypeFile = "cgroup.type" + cgStCtlFile = "cgroup.subtree_control" + ) + ctrs := strings.Fields(content) + res := "+" + strings.Join(ctrs, " +") elements := strings.Split(path, "/") elements = elements[3:] @@ -103,9 +105,9 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) { } }() } - cgTypeFile := filepath.Join(current, "cgroup.type") - cgType, _ := ioutil.ReadFile(cgTypeFile) - switch strings.TrimSpace(string(cgType)) { + cgType, _ := fscommon.ReadFile(current, cgTypeFile) + cgType = strings.TrimSpace(cgType) + switch cgType { // If the cgroup is in an invalid mode (usually this means there's an internal // process in the cgroup tree, because we created a cgroup under an // already-populated-by-other-processes cgroup), then we have to error out if @@ -120,7 +122,7 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) { // since that means we're a properly delegated cgroup subtree) but in // this case there's not much we can do and it's better than giving an // error. - _ = ioutil.WriteFile(cgTypeFile, []byte("threaded"), 0644) + _ = fscommon.WriteFile(current, cgTypeFile, "threaded") } // If the cgroup is in (threaded) or (domain threaded) mode, we can only use thread-aware controllers // (and you cannot usually take a cgroup out of threaded mode). @@ -128,18 +130,17 @@ func CreateCgroupPath(path string, c *configs.Cgroup) (Err error) { fallthrough case "threaded": if containsDomainController(c) { - return fmt.Errorf("cannot enter cgroupv2 %q with domain controllers -- it is in %s mode", current, strings.TrimSpace(string(cgType))) + return fmt.Errorf("cannot enter cgroupv2 %q with domain controllers -- it is in %s mode", current, cgType) } } } // enable all supported controllers if i < len(elements)-1 { - file := filepath.Join(current, "cgroup.subtree_control") - if err := ioutil.WriteFile(file, res, 0644); err != nil { + if err := fscommon.WriteFile(current, cgStCtlFile, res); err != nil { // try write one by one - allCtrs := bytes.Split(res, []byte(" ")) + allCtrs := strings.Split(res, " ") for _, ctr := range allCtrs { - _ = ioutil.WriteFile(file, ctr, 0644) + _ = fscommon.WriteFile(current, cgStCtlFile, ctr) } } // Some controllers might not be enabled when rootless or containerized, diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/devices.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/devices.go index 053ec33e01a..4c793a1cc1a 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/devices.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/devices.go @@ -6,11 +6,12 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups/ebpf" "github.com/opencontainers/runc/libcontainer/cgroups/ebpf/devicefilter" "github.com/opencontainers/runc/libcontainer/configs" + "github.com/opencontainers/runc/libcontainer/devices" "github.com/pkg/errors" "golang.org/x/sys/unix" ) -func isRWM(perms configs.DevicePermissions) bool { +func isRWM(perms devices.Permissions) bool { var r, w, m bool for _, perm := range perms { switch perm { @@ -61,7 +62,7 @@ func setDevices(dirPath string, cgroup *configs.Cgroup) error { // // The real issue is that BPF_F_ALLOW_MULTI makes it hard to have a // race-free blacklist because it acts as a whitelist by default, and - // having a deny-everything program cannot be overriden by other + // having a deny-everything program cannot be overridden by other // programs. You could temporarily insert a deny-everything program // but that would result in spurrious failures during updates. if _, err := ebpf.LoadAttachCgroupDeviceFilter(insts, license, dirFD); err != nil { diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/freezer.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/freezer.go index 213ff65a111..441531fd77d 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/freezer.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/freezer.go @@ -19,7 +19,7 @@ func setFreezer(dirPath string, state configs.FreezerState) error { // freeze the container (since without the freezer cgroup, that's a // no-op). if state == configs.Undefined || state == configs.Thawed { - err = nil + return nil } return errors.Wrap(err, "freezer not supported") } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/fs2.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/fs2.go index 7be26211a3d..3f0b9e0d7e1 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/fs2.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/fs2.go @@ -3,15 +3,14 @@ package fs2 import ( - "io/ioutil" + "fmt" "os" - "path/filepath" "strings" "github.com/opencontainers/runc/libcontainer/cgroups" + "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" "github.com/opencontainers/runc/libcontainer/configs" "github.com/pkg/errors" - "golang.org/x/sys/unix" ) type manager struct { @@ -52,15 +51,14 @@ func (m *manager) getControllers() error { return nil } - file := filepath.Join(m.dirPath, "cgroup.controllers") - data, err := ioutil.ReadFile(file) + data, err := fscommon.ReadFile(m.dirPath, "cgroup.controllers") if err != nil { if m.rootless && m.config.Path == "" { return nil } return err } - fields := strings.Fields(string(data)) + fields := strings.Fields(data) m.controllers = make(map[string]struct{}, len(fields)) for _, c := range fields { m.controllers[c] = struct{}{} @@ -157,45 +155,8 @@ func (m *manager) Freeze(state configs.FreezerState) error { return nil } -func rmdir(path string) error { - err := unix.Rmdir(path) - if err == nil || err == unix.ENOENT { - return nil - } - return &os.PathError{Op: "rmdir", Path: path, Err: err} -} - -// removeCgroupPath aims to remove cgroup path recursively -// Because there may be subcgroups in it. -func removeCgroupPath(path string) error { - // try the fast path first - if err := rmdir(path); err == nil { - return nil - } - - infos, err := ioutil.ReadDir(path) - if err != nil { - if os.IsNotExist(err) { - err = nil - } - return err - } - for _, info := range infos { - if info.IsDir() { - // We should remove subcgroups dir first - if err = removeCgroupPath(filepath.Join(path, info.Name())); err != nil { - break - } - } - } - if err == nil { - err = rmdir(path) - } - return err -} - func (m *manager) Destroy() error { - return removeCgroupPath(m.dirPath) + return cgroups.RemovePath(m.dirPath) } func (m *manager) Path(_ string) string { @@ -245,10 +206,40 @@ func (m *manager) Set(container *configs.Config) error { if err := setFreezer(m.dirPath, container.Cgroups.Freezer); err != nil { return err } + if err := m.setUnified(container.Cgroups.Unified); err != nil { + return err + } m.config = container.Cgroups return nil } +func (m *manager) setUnified(res map[string]string) error { + for k, v := range res { + if strings.Contains(k, "/") { + return fmt.Errorf("unified resource %q must be a file name (no slashes)", k) + } + if err := fscommon.WriteFile(m.dirPath, k, v); err != nil { + errC := errors.Cause(err) + // Check for both EPERM and ENOENT since O_CREAT is used by WriteFile. + if errors.Is(errC, os.ErrPermission) || errors.Is(errC, os.ErrNotExist) { + // Check if a controller is available, + // to give more specific error if not. + sk := strings.SplitN(k, ".", 2) + if len(sk) != 2 { + return fmt.Errorf("unified resource %q must be in the form CONTROLLER.PARAMETER", k) + } + c := sk[0] + if _, ok := m.controllers[c]; !ok && c != "cgroup" { + return fmt.Errorf("unified resource %q can't be set: controller %q not available", k, c) + } + } + return errors.Wrapf(err, "can't set unified resource %q", k) + } + } + + return nil +} + func (m *manager) GetPaths() map[string]string { paths := make(map[string]string, 1) paths[""] = m.dirPath diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/hugetlb.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/hugetlb.go index 4a399aaecd5..18cd411ce08 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/hugetlb.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/hugetlb.go @@ -3,10 +3,7 @@ package fs2 import ( - "io/ioutil" - "path/filepath" "strconv" - "strings" "github.com/pkg/errors" @@ -24,7 +21,7 @@ func setHugeTlb(dirPath string, cgroup *configs.Cgroup) error { return nil } for _, hugetlb := range cgroup.Resources.HugetlbLimit { - if err := fscommon.WriteFile(dirPath, strings.Join([]string{"hugetlb", hugetlb.Pagesize, "max"}, "."), strconv.FormatUint(hugetlb.Limit, 10)); err != nil { + if err := fscommon.WriteFile(dirPath, "hugetlb."+hugetlb.Pagesize+".max", strconv.FormatUint(hugetlb.Limit, 10)); err != nil { return err } } @@ -40,22 +37,20 @@ func statHugeTlb(dirPath string, stats *cgroups.Stats) error { hugetlbStats := cgroups.HugetlbStats{} for _, pagesize := range hugePageSizes { - usage := strings.Join([]string{"hugetlb", pagesize, "current"}, ".") - value, err := fscommon.GetCgroupParamUint(dirPath, usage) + value, err := fscommon.GetCgroupParamUint(dirPath, "hugetlb."+pagesize+".current") if err != nil { - return errors.Wrapf(err, "failed to parse hugetlb.%s.current file", pagesize) + return err } hugetlbStats.Usage = value - fileName := strings.Join([]string{"hugetlb", pagesize, "events"}, ".") - filePath := filepath.Join(dirPath, fileName) - contents, err := ioutil.ReadFile(filePath) + fileName := "hugetlb." + pagesize + ".events" + contents, err := fscommon.ReadFile(dirPath, fileName) if err != nil { - return errors.Wrapf(err, "failed to parse hugetlb.%s.events file", pagesize) + return errors.Wrap(err, "failed to read stats") } - _, value, err = fscommon.GetCgroupParamKeyValue(string(contents)) + _, value, err = fscommon.GetCgroupParamKeyValue(contents) if err != nil { - return errors.Wrapf(err, "failed to parse hugetlb.%s.events file", pagesize) + return errors.Wrap(err, "failed to parse "+fileName) } hugetlbStats.Failcnt = value diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/io.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/io.go index bbe3ac064b3..e01ea001b35 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/io.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/io.go @@ -5,7 +5,6 @@ package fs2 import ( "bufio" "os" - "path/filepath" "strconv" "strings" @@ -60,8 +59,7 @@ func setIo(dirPath string, cgroup *configs.Cgroup) error { func readCgroup2MapFile(dirPath string, name string) (map[string][]string, error) { ret := map[string][]string{} - p := filepath.Join(dirPath, name) - f, err := os.Open(p) + f, err := fscommon.OpenFile(dirPath, name, os.O_RDONLY) if err != nil { return nil, err } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/memory.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/memory.go index 51d12c08653..1c6913bf0f5 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/memory.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/memory.go @@ -5,9 +5,7 @@ package fs2 import ( "bufio" "os" - "path/filepath" "strconv" - "strings" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" @@ -76,7 +74,7 @@ func setMemory(dirPath string, cgroup *configs.Cgroup) error { func statMemory(dirPath string, stats *cgroups.Stats) error { // Set stats from memory.stat. - statsFile, err := os.Open(filepath.Join(dirPath, "memory.stat")) + statsFile, err := fscommon.OpenFile(dirPath, "memory.stat", os.O_RDONLY) if err != nil { return err } @@ -112,10 +110,10 @@ func getMemoryDataV2(path, name string) (cgroups.MemoryData, error) { moduleName := "memory" if name != "" { - moduleName = strings.Join([]string{"memory", name}, ".") + moduleName = "memory." + name } - usage := strings.Join([]string{moduleName, "current"}, ".") - limit := strings.Join([]string{moduleName, "max"}, ".") + usage := moduleName + ".current" + limit := moduleName + ".max" value, err := fscommon.GetCgroupParamUint(path, usage) if err != nil { diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/pids.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/pids.go index b8153d28398..16e1c21957a 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/pids.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs2/pids.go @@ -3,7 +3,6 @@ package fs2 import ( - "io/ioutil" "path/filepath" "strings" @@ -34,15 +33,15 @@ func setPids(dirPath string, cgroup *configs.Cgroup) error { func statPidsWithoutController(dirPath string, stats *cgroups.Stats) error { // if the controller is not enabled, let's read PIDS from cgroups.procs // (or threads if cgroup.threads is enabled) - contents, err := ioutil.ReadFile(filepath.Join(dirPath, "cgroup.procs")) + contents, err := fscommon.ReadFile(dirPath, "cgroup.procs") if errors.Is(err, unix.ENOTSUP) { - contents, err = ioutil.ReadFile(filepath.Join(dirPath, "cgroup.threads")) + contents, err = fscommon.ReadFile(dirPath, "cgroup.threads") } if err != nil { return err } pids := make(map[string]string) - for _, i := range strings.Split(string(contents), "\n") { + for _, i := range strings.Split(contents, "\n") { if i != "" { pids[i] = i } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/fscommon.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/fscommon.go index 46e06dc62d3..ae2613cdbd1 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/fscommon.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/fscommon.go @@ -3,46 +3,47 @@ package fscommon import ( - "io/ioutil" + "bytes" "os" - securejoin "github.com/cyphar/filepath-securejoin" "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) +// WriteFile writes data to a cgroup file in dir. +// It is supposed to be used for cgroup files only. func WriteFile(dir, file, data string) error { - if dir == "" { - return errors.Errorf("no directory specified for %s", file) - } - path, err := securejoin.SecureJoin(dir, file) + fd, err := OpenFile(dir, file, unix.O_WRONLY) if err != nil { return err } - if err := retryingWriteFile(path, []byte(data), 0700); err != nil { - return errors.Wrapf(err, "failed to write %q to %q", data, path) + defer fd.Close() + if err := retryingWriteFile(fd, data); err != nil { + return errors.Wrapf(err, "failed to write %q", data) } return nil } +// ReadFile reads data from a cgroup file in dir. +// It is supposed to be used for cgroup files only. func ReadFile(dir, file string) (string, error) { - if dir == "" { - return "", errors.Errorf("no directory specified for %s", file) - } - path, err := securejoin.SecureJoin(dir, file) + fd, err := OpenFile(dir, file, unix.O_RDONLY) if err != nil { return "", err } - data, err := ioutil.ReadFile(path) - return string(data), err + defer fd.Close() + var buf bytes.Buffer + + _, err = buf.ReadFrom(fd) + return buf.String(), err } -func retryingWriteFile(filename string, data []byte, perm os.FileMode) error { +func retryingWriteFile(fd *os.File, data string) error { for { - err := ioutil.WriteFile(filename, data, perm) + _, err := fd.Write([]byte(data)) if errors.Is(err, unix.EINTR) { - logrus.Infof("interrupted while writing %s to %s", string(data), filename) + logrus.Infof("interrupted while writing %s to %s", data, fd.Name()) continue } return err diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/open.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/open.go new file mode 100644 index 00000000000..0a7e3d95282 --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/open.go @@ -0,0 +1,103 @@ +package fscommon + +import ( + "os" + "strings" + "sync" + + securejoin "github.com/cyphar/filepath-securejoin" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" +) + +const ( + cgroupfsDir = "/sys/fs/cgroup" + cgroupfsPrefix = cgroupfsDir + "/" +) + +var ( + // Set to true by fs unit tests + TestMode bool + + cgroupFd int = -1 + prepOnce sync.Once + prepErr error + resolveFlags uint64 +) + +func prepareOpenat2() error { + prepOnce.Do(func() { + fd, err := unix.Openat2(-1, cgroupfsDir, &unix.OpenHow{ + Flags: unix.O_DIRECTORY | unix.O_PATH}) + if err != nil { + prepErr = &os.PathError{Op: "openat2", Path: cgroupfsDir, Err: err} + if err != unix.ENOSYS { + logrus.Warnf("falling back to securejoin: %s", prepErr) + } else { + logrus.Debug("openat2 not available, falling back to securejoin") + } + return + } + var st unix.Statfs_t + if err = unix.Fstatfs(fd, &st); err != nil { + prepErr = &os.PathError{Op: "statfs", Path: cgroupfsDir, Err: err} + logrus.Warnf("falling back to securejoin: %s", prepErr) + return + } + + cgroupFd = fd + + resolveFlags = unix.RESOLVE_BENEATH | unix.RESOLVE_NO_MAGICLINKS + if st.Type == unix.CGROUP2_SUPER_MAGIC { + // cgroupv2 has a single mountpoint and no "cpu,cpuacct" symlinks + resolveFlags |= unix.RESOLVE_NO_XDEV | unix.RESOLVE_NO_SYMLINKS + } + + }) + + return prepErr +} + +// OpenFile opens a cgroup file in a given dir with given flags. +// It is supposed to be used for cgroup files only. +func OpenFile(dir, file string, flags int) (*os.File, error) { + if dir == "" { + return nil, errors.Errorf("no directory specified for %s", file) + } + mode := os.FileMode(0) + if TestMode && flags&os.O_WRONLY != 0 { + // "emulate" cgroup fs for unit tests + flags |= os.O_TRUNC | os.O_CREATE + mode = 0o600 + } + reldir := strings.TrimPrefix(dir, cgroupfsPrefix) + if len(reldir) == len(dir) { // non-standard path, old system? + return openWithSecureJoin(dir, file, flags, mode) + } + if prepareOpenat2() != nil { + return openWithSecureJoin(dir, file, flags, mode) + } + + relname := reldir + "/" + file + fd, err := unix.Openat2(cgroupFd, relname, + &unix.OpenHow{ + Resolve: resolveFlags, + Flags: uint64(flags) | unix.O_CLOEXEC, + Mode: uint64(mode), + }) + if err != nil { + return nil, &os.PathError{Op: "openat2", Path: dir + "/" + file, Err: err} + } + + return os.NewFile(uintptr(fd), cgroupfsPrefix+relname), nil +} + +func openWithSecureJoin(dir, file string, flags int, mode os.FileMode) (*os.File, error) { + path, err := securejoin.SecureJoin(dir, file) + if err != nil { + return nil, err + } + + return os.OpenFile(path, flags, mode) +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/utils.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/utils.go index 46c3c7799ee..2e4e837f2b8 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/utils.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/utils.go @@ -5,9 +5,7 @@ package fscommon import ( "errors" "fmt" - "io/ioutil" "math" - "path/filepath" "strconv" "strings" ) @@ -16,8 +14,9 @@ var ( ErrNotValidFormat = errors.New("line is not a valid key value format") ) -// Saturates negative values at zero and returns a uint64. -// Due to kernel bugs, some of the memory cgroup stats can be negative. +// ParseUint converts a string to an uint64 integer. +// Negative values are returned at zero as, due to kernel bugs, +// some of the memory cgroup stats can be negative. func ParseUint(s string, base, bitSize int) (uint64, error) { value, err := strconv.ParseUint(s, base, bitSize) if err != nil { @@ -36,15 +35,16 @@ func ParseUint(s string, base, bitSize int) (uint64, error) { return value, nil } -// Parses a cgroup param and returns as name, value -// i.e. "io_service_bytes 1234" will return as io_service_bytes, 1234 +// GetCgroupParamKeyValue parses a space-separated "name value" kind of cgroup +// parameter and returns its components. For example, "io_service_bytes 1234" +// will return as "io_service_bytes", 1234. func GetCgroupParamKeyValue(t string) (string, uint64, error) { parts := strings.Fields(t) switch len(parts) { case 2: value, err := ParseUint(parts[1], 10, 64) if err != nil { - return "", 0, fmt.Errorf("unable to convert param value (%q) to uint64: %v", parts[1], err) + return "", 0, fmt.Errorf("unable to convert to uint64: %v", err) } return parts[0], value, nil @@ -53,31 +53,50 @@ func GetCgroupParamKeyValue(t string) (string, uint64, error) { } } -// Gets a single uint64 value from the specified cgroup file. -func GetCgroupParamUint(cgroupPath, cgroupFile string) (uint64, error) { - fileName := filepath.Join(cgroupPath, cgroupFile) - contents, err := ioutil.ReadFile(fileName) +// GetCgroupParamUint reads a single uint64 value from the specified cgroup file. +// If the value read is "max", the math.MaxUint64 is returned. +func GetCgroupParamUint(path, file string) (uint64, error) { + contents, err := GetCgroupParamString(path, file) if err != nil { return 0, err } - trimmed := strings.TrimSpace(string(contents)) - if trimmed == "max" { + contents = strings.TrimSpace(contents) + if contents == "max" { return math.MaxUint64, nil } - res, err := ParseUint(trimmed, 10, 64) + res, err := ParseUint(contents, 10, 64) if err != nil { - return res, fmt.Errorf("unable to parse %q as a uint from Cgroup file %q", string(contents), fileName) + return res, fmt.Errorf("unable to parse file %q", path+"/"+file) } return res, nil } -// Gets a string value from the specified cgroup file -func GetCgroupParamString(cgroupPath, cgroupFile string) (string, error) { - contents, err := ioutil.ReadFile(filepath.Join(cgroupPath, cgroupFile)) +// GetCgroupParamInt reads a single int64 value from specified cgroup file. +// If the value read is "max", the math.MaxInt64 is returned. +func GetCgroupParamInt(path, file string) (int64, error) { + contents, err := ReadFile(path, file) + if err != nil { + return 0, err + } + contents = strings.TrimSpace(contents) + if contents == "max" { + return math.MaxInt64, nil + } + + res, err := strconv.ParseInt(contents, 10, 64) + if err != nil { + return res, fmt.Errorf("unable to parse %q as a int from Cgroup file %q", contents, path+"/"+file) + } + return res, nil +} + +// GetCgroupParamString reads a string from the specified cgroup file. +func GetCgroupParamString(path, file string) (string, error) { + contents, err := ReadFile(path, file) if err != nil { return "", err } - return strings.TrimSpace(string(contents)), nil + return strings.TrimSpace(contents), nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go index 7ac81660595..e7f9c462635 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go @@ -39,6 +39,33 @@ type CpuStats struct { ThrottlingData ThrottlingData `json:"throttling_data,omitempty"` } +type CPUSetStats struct { + // List of the physical numbers of the CPUs on which processes + // in that cpuset are allowed to execute + CPUs []uint16 `json:"cpus,omitempty"` + // cpu_exclusive flag + CPUExclusive uint64 `json:"cpu_exclusive"` + // List of memory nodes on which processes in that cpuset + // are allowed to allocate memory + Mems []uint16 `json:"mems,omitempty"` + // mem_hardwall flag + MemHardwall uint64 `json:"mem_hardwall"` + // mem_exclusive flag + MemExclusive uint64 `json:"mem_exclusive"` + // memory_migrate flag + MemoryMigrate uint64 `json:"memory_migrate"` + // memory_spread page flag + MemorySpreadPage uint64 `json:"memory_spread_page"` + // memory_spread slab flag + MemorySpreadSlab uint64 `json:"memory_spread_slab"` + // memory_pressure + MemoryPressure uint64 `json:"memory_pressure"` + // sched_load balance flag + SchedLoadBalance uint64 `json:"sched_load_balance"` + // sched_relax_domain_level + SchedRelaxDomainLevel int64 `json:"sched_relax_domain_level"` +} + type MemoryData struct { Usage uint64 `json:"usage,omitempty"` MaxUsage uint64 `json:"max_usage,omitempty"` @@ -121,6 +148,7 @@ type HugetlbStats struct { type Stats struct { CpuStats CpuStats `json:"cpu_stats,omitempty"` + CPUSetStats CPUSetStats `json:"cpuset_stats,omitempty"` MemoryStats MemoryStats `json:"memory_stats,omitempty"` PidsStats PidsStats `json:"pids_stats,omitempty"` BlkioStats BlkioStats `json:"blkio_stats,omitempty"` diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/common.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/common.go index b567f3e1fcb..6d5def71257 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/common.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/common.go @@ -13,12 +13,20 @@ import ( systemdDbus "github.com/coreos/go-systemd/v22/dbus" dbus "github.com/godbus/dbus/v5" - "github.com/opencontainers/runc/libcontainer/cgroups/devices" + cgroupdevices "github.com/opencontainers/runc/libcontainer/cgroups/devices" "github.com/opencontainers/runc/libcontainer/configs" + "github.com/opencontainers/runc/libcontainer/devices" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) +const ( + // Default kernel value for cpu quota period is 100000 us (100 ms), same for v1 and v2. + // v1: https://www.kernel.org/doc/html/latest/scheduler/sched-bwc.html and + // v2: https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html + defCPUQuotaPeriod = uint64(100000) +) + var ( connOnce sync.Once connDbus *systemdDbus.Conn @@ -26,7 +34,6 @@ var ( versionOnce sync.Once version int - versionErr error isRunningSystemdOnce sync.Once isRunningSystemd bool @@ -81,11 +88,11 @@ func ExpandSlice(slice string) (string, error) { return path, nil } -func groupPrefix(ruleType configs.DeviceType) (string, error) { +func groupPrefix(ruleType devices.Type) (string, error) { switch ruleType { - case configs.BlockDevice: + case devices.BlockDevice: return "block-", nil - case configs.CharDevice: + case devices.CharDevice: return "char-", nil default: return "", errors.Errorf("device type %v has no group prefix", ruleType) @@ -93,10 +100,10 @@ func groupPrefix(ruleType configs.DeviceType) (string, error) { } // findDeviceGroup tries to find the device group name (as listed in -// /proc/devices) with the type prefixed as requried for DeviceAllow, for a +// /proc/devices) with the type prefixed as required for DeviceAllow, for a // given (type, major) combination. If more than one device group exists, an // arbitrary one is chosen. -func findDeviceGroup(ruleType configs.DeviceType, ruleMajor int64) (string, error) { +func findDeviceGroup(ruleType devices.Type, ruleMajor int64) (string, error) { fh, err := os.Open("/proc/devices") if err != nil { return "", err @@ -109,7 +116,7 @@ func findDeviceGroup(ruleType configs.DeviceType, ruleMajor int64) (string, erro } scanner := bufio.NewScanner(fh) - var currentType configs.DeviceType + var currentType devices.Type for scanner.Scan() { // We need to strip spaces because the first number is column-aligned. line := strings.TrimSpace(scanner.Text()) @@ -117,10 +124,10 @@ func findDeviceGroup(ruleType configs.DeviceType, ruleMajor int64) (string, erro // Handle the "header" lines. switch line { case "Block devices:": - currentType = configs.BlockDevice + currentType = devices.BlockDevice continue case "Character devices:": - currentType = configs.CharDevice + currentType = devices.CharDevice continue case "": continue @@ -156,7 +163,7 @@ func findDeviceGroup(ruleType configs.DeviceType, ruleMajor int64) (string, erro // generateDeviceProperties takes the configured device rules and generates a // corresponding set of systemd properties to configure the devices correctly. -func generateDeviceProperties(rules []*configs.DeviceRule) ([]systemdDbus.Property, error) { +func generateDeviceProperties(rules []*devices.Rule) ([]systemdDbus.Property, error) { // DeviceAllow is the type "a(ss)" which means we need a temporary struct // to represent it in Go. type deviceAllowEntry struct { @@ -172,7 +179,7 @@ func generateDeviceProperties(rules []*configs.DeviceRule) ([]systemdDbus.Proper } // Figure out the set of rules. - configEmu := &devices.Emulator{} + configEmu := &cgroupdevices.Emulator{} for _, rule := range rules { if err := configEmu.Apply(*rule); err != nil { return nil, errors.Wrap(err, "apply rule for systemd") @@ -199,7 +206,7 @@ func generateDeviceProperties(rules []*configs.DeviceRule) ([]systemdDbus.Proper // Now generate the set of rules we actually need to apply. Unlike the // normal devices cgroup, in "strict" mode systemd defaults to a deny-all // whitelist which is the default for devices.Emulator. - baseEmu := &devices.Emulator{} + baseEmu := &cgroupdevices.Emulator{} finalRules, err := baseEmu.Transition(configEmu) if err != nil { return nil, errors.Wrap(err, "get simplified rules for systemd") @@ -211,7 +218,7 @@ func generateDeviceProperties(rules []*configs.DeviceRule) ([]systemdDbus.Proper return nil, errors.Errorf("[internal error] cannot add deny rule to systemd DeviceAllow list: %v", *rule) } switch rule.Type { - case configs.BlockDevice, configs.CharDevice: + case devices.BlockDevice, devices.CharDevice: default: // Should never happen. return nil, errors.Errorf("invalid device type for DeviceAllow: %v", rule.Type) @@ -243,9 +250,9 @@ func generateDeviceProperties(rules []*configs.DeviceRule) ([]systemdDbus.Proper // so we'll give a warning in that case (note that the fallback code // will insert any rules systemd couldn't handle). What amazing fun. - if rule.Major == configs.Wildcard { + if rule.Major == devices.Wildcard { // "_ *:n _" rules aren't supported by systemd. - if rule.Minor != configs.Wildcard { + if rule.Minor != devices.Wildcard { logrus.Warnf("systemd doesn't support '*:n' device rules -- temporarily ignoring rule: %v", *rule) continue } @@ -256,7 +263,7 @@ func generateDeviceProperties(rules []*configs.DeviceRule) ([]systemdDbus.Proper return nil, err } entry.Path = prefix + "*" - } else if rule.Minor == configs.Wildcard { + } else if rule.Minor == devices.Wildcard { // "_ n:* _" rules require a device group from /proc/devices. group, err := findDeviceGroup(rule.Type, rule.Major) if err != nil { @@ -271,9 +278,9 @@ func generateDeviceProperties(rules []*configs.DeviceRule) ([]systemdDbus.Proper } else { // "_ n:m _" rules are just a path in /dev/{block,char}/. switch rule.Type { - case configs.BlockDevice: + case devices.BlockDevice: entry.Path = fmt.Sprintf("/dev/block/%d:%d", rule.Major, rule.Minor) - case configs.CharDevice: + case devices.CharDevice: entry.Path = fmt.Sprintf("/dev/char/%d:%d", rule.Major, rule.Minor) } } @@ -307,7 +314,7 @@ func newProp(name string, units interface{}) systemdDbus.Property { func getUnitName(c *configs.Cgroup) string { // by default, we create a scope unless the user explicitly asks for a slice. if !strings.HasSuffix(c.Name, ".slice") { - return fmt.Sprintf("%s-%s.scope", c.ScopePrefix, c.Name) + return c.ScopePrefix + "-" + c.Name + ".scope" } return c.Name } @@ -325,6 +332,9 @@ func isUnitExists(err error) bool { func startUnit(dbusConnection *systemdDbus.Conn, unitName string, properties []systemdDbus.Property) error { statusChan := make(chan string, 1) if _, err := dbusConnection.StartTransientUnit(unitName, "replace", properties, statusChan); err == nil { + timeout := time.NewTimer(30 * time.Second) + defer timeout.Stop() + select { case s := <-statusChan: close(statusChan) @@ -333,8 +343,9 @@ func startUnit(dbusConnection *systemdDbus.Conn, unitName string, properties []s dbusConnection.ResetFailedUnit(unitName) return errors.Errorf("error creating systemd unit `%s`: got `%s`", unitName, s) } - case <-time.After(time.Second): - logrus.Warnf("Timed out while waiting for StartTransientUnit(%s) completion signal from dbus. Continuing...", unitName) + case <-timeout.C: + dbusConnection.ResetFailedUnit(unitName) + return errors.New("Timeout waiting for systemd to create " + unitName) } } else if !isUnitExists(err) { return err @@ -360,20 +371,20 @@ func stopUnit(dbusConnection *systemdDbus.Conn, unitName string) error { return nil } -func systemdVersion(conn *systemdDbus.Conn) (int, error) { +func systemdVersion(conn *systemdDbus.Conn) int { versionOnce.Do(func() { version = -1 verStr, err := conn.GetManagerProperty("Version") - if err != nil { - versionErr = err - return + if err == nil { + version, err = systemdVersionAtoi(verStr) } - version, versionErr = systemdVersionAtoi(verStr) - return + if err != nil { + logrus.WithError(err).Error("unable to get systemd version") + } }) - return version, versionErr + return version } func systemdVersionAtoi(verStr string) (int, error) { @@ -394,12 +405,13 @@ func systemdVersionAtoi(verStr string) (int, error) { func addCpuQuota(conn *systemdDbus.Conn, properties *[]systemdDbus.Property, quota int64, period uint64) { if period != 0 { // systemd only supports CPUQuotaPeriodUSec since v242 - sdVer, err := systemdVersion(conn) - if err != nil { - logrus.Warnf("systemdVersion: %s", err) - } else if sdVer >= 242 { + sdVer := systemdVersion(conn) + if sdVer >= 242 { *properties = append(*properties, newProp("CPUQuotaPeriodUSec", period)) + } else { + logrus.Debugf("systemd v%d is too old to support CPUQuotaPeriodSec "+ + " (setting will still be applied to cgroupfs)", sdVer) } } if quota != 0 || period != 0 { @@ -407,10 +419,8 @@ func addCpuQuota(conn *systemdDbus.Conn, properties *[]systemdDbus.Property, quo cpuQuotaPerSecUSec := uint64(math.MaxUint64) if quota > 0 { if period == 0 { - // assume the default kernel value of 100000 us (100 ms), same for v1 and v2. - // v1: https://www.kernel.org/doc/html/latest/scheduler/sched-bwc.html and - // v2: https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html - period = 100000 + // assume the default + period = defCPUQuotaPeriod } // systemd converts CPUQuotaPerSecUSec (microseconds per CPU second) to CPUQuota // (integer percentage of CPU) internally. This means that if a fractional percent of @@ -425,3 +435,37 @@ func addCpuQuota(conn *systemdDbus.Conn, properties *[]systemdDbus.Property, quo newProp("CPUQuotaPerSecUSec", cpuQuotaPerSecUSec)) } } + +func addCpuset(conn *systemdDbus.Conn, props *[]systemdDbus.Property, cpus, mems string) error { + if cpus == "" && mems == "" { + return nil + } + + // systemd only supports AllowedCPUs/AllowedMemoryNodes since v244 + sdVer := systemdVersion(conn) + if sdVer < 244 { + logrus.Debugf("systemd v%d is too old to support AllowedCPUs/AllowedMemoryNodes"+ + " (settings will still be applied to cgroupfs)", sdVer) + return nil + } + + if cpus != "" { + bits, err := rangeToBits(cpus) + if err != nil { + return fmt.Errorf("resources.CPU.Cpus=%q conversion error: %w", + cpus, err) + } + *props = append(*props, + newProp("AllowedCPUs", bits)) + } + if mems != "" { + bits, err := rangeToBits(mems) + if err != nil { + return fmt.Errorf("resources.CPU.Mems=%q conversion error: %w", + mems, err) + } + *props = append(*props, + newProp("AllowedMemoryNodes", bits)) + } + return nil +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/cpuset.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/cpuset.go new file mode 100644 index 00000000000..07098218883 --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/cpuset.go @@ -0,0 +1,67 @@ +package systemd + +import ( + "encoding/binary" + "strconv" + "strings" + + "github.com/pkg/errors" + "github.com/willf/bitset" +) + +// rangeToBits converts a text representation of a CPU mask (as written to +// or read from cgroups' cpuset.* files, e.g. "1,3-5") to a slice of bytes +// with the corresponding bits set (as consumed by systemd over dbus as +// AllowedCPUs/AllowedMemoryNodes unit property value). +func rangeToBits(str string) ([]byte, error) { + bits := &bitset.BitSet{} + + for _, r := range strings.Split(str, ",") { + // allow extra spaces around + r = strings.TrimSpace(r) + // allow empty elements (extra commas) + if r == "" { + continue + } + ranges := strings.SplitN(r, "-", 2) + if len(ranges) > 1 { + start, err := strconv.ParseUint(ranges[0], 10, 32) + if err != nil { + return nil, err + } + end, err := strconv.ParseUint(ranges[1], 10, 32) + if err != nil { + return nil, err + } + if start > end { + return nil, errors.New("invalid range: " + r) + } + for i := uint(start); i <= uint(end); i++ { + bits.Set(i) + } + } else { + val, err := strconv.ParseUint(ranges[0], 10, 32) + if err != nil { + return nil, err + } + bits.Set(uint(val)) + } + } + + val := bits.Bytes() + if len(val) == 0 { + // do not allow empty values + return nil, errors.New("empty value") + } + ret := make([]byte, len(val)*8) + for i := range val { + // bitset uses BigEndian internally + binary.BigEndian.PutUint64(ret[i*8:], val[len(val)-1-i]) + } + // remove upper all-zero bytes + for ret[0] == 0 { + ret = ret[1:] + } + + return ret, nil +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/user.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/user.go index cb070cec8b7..8fe91688477 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/user.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/user.go @@ -57,7 +57,7 @@ func DetectUID() (int, error) { } b, err := exec.Command("busctl", "--user", "--no-pager", "status").CombinedOutput() if err != nil { - return -1, errors.Wrap(err, "could not execute `busctl --user --no-pager status`") + return -1, errors.Wrapf(err, "could not execute `busctl --user --no-pager status`: %q", string(b)) } scanner := bufio.NewScanner(bytes.NewReader(b)) for scanner.Scan() { @@ -102,5 +102,5 @@ func DetectUserDbusSessionBusAddress() (string, error) { return strings.TrimPrefix(s, "DBUS_SESSION_BUS_ADDRESS="), nil } } - return "", errors.New("could not detect DBUS_SESSION_BUS_ADDRESS from `systemctl --user --no-pager show-environment`") + return "", errors.New("could not detect DBUS_SESSION_BUS_ADDRESS from `systemctl --user --no-pager show-environment`. Make sure you have installed the dbus-user-session or dbus-daemon package and then run: `systemctl --user start dbus`") } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v1.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v1.go index 7217b0af79c..64af1d94b3e 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v1.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v1.go @@ -4,7 +4,6 @@ package systemd import ( "errors" - "io/ioutil" "os" "path/filepath" "strings" @@ -13,6 +12,7 @@ import ( systemdDbus "github.com/coreos/go-systemd/v22/dbus" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups/fs" + "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" "github.com/opencontainers/runc/libcontainer/configs" "github.com/sirupsen/logrus" ) @@ -90,6 +90,11 @@ func genV1ResourcesProperties(c *configs.Cgroup, conn *systemdDbus.Conn) ([]syst newProp("TasksMax", uint64(r.PidsLimit))) } + err = addCpuset(conn, &properties, r.CpusetCpus, r.CpusetMems) + if err != nil { + return nil, err + } + return properties, nil } @@ -101,20 +106,23 @@ func (m *legacyManager) Apply(pid int) error { properties []systemdDbus.Property ) + if c.Resources.Unified != nil { + return cgroups.ErrV1NoUnified + } + m.mu.Lock() defer m.mu.Unlock() if c.Paths != nil { paths := make(map[string]string) + cgMap, err := cgroups.ParseCgroupFile("/proc/self/cgroup") + if err != nil { + return err + } + // XXX(kolyshkin@): why this check is needed? for name, path := range c.Paths { - _, err := getSubsystemPath(m.cgroups, name) - if err != nil { - // Don't fail if a cgroup hierarchy was not found, just skip this subsystem - if cgroups.IsNotFound(err) { - continue - } - return err + if _, ok := cgMap[name]; ok { + paths[name] = path } - paths[name] = path } m.paths = paths return cgroups.EnterPid(m.paths, pid) @@ -179,14 +187,16 @@ func (m *legacyManager) Apply(pid int) error { return err } - if err := joinCgroups(c, pid); err != nil { - return err - } - paths := make(map[string]string) for _, s := range legacySubsystems { subsystemPath, err := getSubsystemPath(m.cgroups, s.Name()) if err != nil { + // Even if it's `not found` error, we'll return err + // because devices cgroup is hard requirement for + // container security. + if s.Name() == "devices" { + return err + } // Don't fail if a cgroup hierarchy was not found, just skip this subsystem if cgroups.IsNotFound(err) { continue @@ -196,6 +206,11 @@ func (m *legacyManager) Apply(pid int) error { paths[s.Name()] = subsystemPath } m.paths = paths + + if err := m.joinCgroups(pid); err != nil { + return err + } + return nil } @@ -212,17 +227,14 @@ func (m *legacyManager) Destroy() error { } unitName := getUnitName(m.cgroups) - err = stopUnit(dbusConnection, unitName) + stopErr := stopUnit(dbusConnection, unitName) // Both on success and on error, cleanup all the cgroups we are aware of. // Some of them were created directly by Apply() and are not managed by systemd. if err := cgroups.RemovePaths(m.paths); err != nil { return err } - if err != nil { - return err - } - m.paths = make(map[string]string) - return nil + + return stopErr } func (m *legacyManager) Path(subsys string) string { @@ -231,48 +243,25 @@ func (m *legacyManager) Path(subsys string) string { return m.paths[subsys] } -func join(c *configs.Cgroup, subsystem string, pid int) (string, error) { - path, err := getSubsystemPath(c, subsystem) - if err != nil { - return "", err - } - - if err := os.MkdirAll(path, 0755); err != nil { - return "", err - } - if err := cgroups.WriteCgroupProc(path, pid); err != nil { - return "", err - } - return path, nil -} - -func joinCgroups(c *configs.Cgroup, pid int) error { +func (m *legacyManager) joinCgroups(pid int) error { for _, sys := range legacySubsystems { name := sys.Name() switch name { case "name=systemd": // let systemd handle this case "cpuset": - path, err := getSubsystemPath(c, name) - if err != nil && !cgroups.IsNotFound(err) { - return err - } - s := &fs.CpusetGroup{} - if err := s.ApplyDir(path, c, pid); err != nil { - return err - } - default: - _, err := join(c, name, pid) - if err != nil { - // Even if it's `not found` error, we'll return err - // because devices cgroup is hard requirement for - // container security. - if name == "devices" { + if path, ok := m.paths[name]; ok { + s := &fs.CpusetGroup{} + if err := s.ApplyDir(path, m.cgroups, pid); err != nil { return err } - // For other subsystems, omit the `not found` error - // because they are optional. - if !cgroups.IsNotFound(err) { + } + default: + if path, ok := m.paths[name]; ok { + if err := os.MkdirAll(path, 0755); err != nil { + return err + } + if err := cgroups.WriteCgroupProc(path, pid); err != nil { return err } } @@ -283,7 +272,7 @@ func joinCgroups(c *configs.Cgroup, pid int) error { } func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) { - mountpoint, err := cgroups.FindCgroupMountpoint(c.Path, subsystem) + mountpoint, err := cgroups.FindCgroupMountpoint("", subsystem) if err != nil { return "", err } @@ -309,15 +298,14 @@ func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) { } func (m *legacyManager) Freeze(state configs.FreezerState) error { - path, err := getSubsystemPath(m.cgroups, "freezer") - if err != nil { - return err + path, ok := m.paths["freezer"] + if !ok { + return errSubsystemDoesNotExist } prevState := m.cgroups.Resources.Freezer m.cgroups.Resources.Freezer = state freezer := &fs.FreezerGroup{} - err = freezer.Set(path, m.cgroups) - if err != nil { + if err := freezer.Set(path, m.cgroups); err != nil { m.cgroups.Resources.Freezer = prevState return err } @@ -325,17 +313,17 @@ func (m *legacyManager) Freeze(state configs.FreezerState) error { } func (m *legacyManager) GetPids() ([]int, error) { - path, err := getSubsystemPath(m.cgroups, "devices") - if err != nil { - return nil, err + path, ok := m.paths["devices"] + if !ok { + return nil, errSubsystemDoesNotExist } return cgroups.GetPids(path) } func (m *legacyManager) GetAllPids() ([]int, error) { - path, err := getSubsystemPath(m.cgroups, "devices") - if err != nil { - return nil, err + path, ok := m.paths["devices"] + if !ok { + return nil, errSubsystemDoesNotExist } return cgroups.GetAllPids(path) } @@ -363,6 +351,9 @@ func (m *legacyManager) Set(container *configs.Config) error { if m.cgroups.Paths != nil { return nil } + if container.Cgroups.Resources.Unified != nil { + return cgroups.ErrV1NoUnified + } dbusConnection, err := getDbusConnection(false) if err != nil { return err @@ -406,9 +397,9 @@ func (m *legacyManager) Set(container *configs.Config) error { for _, sys := range legacySubsystems { // Get the subsystem path, but don't error out for not found cgroups. - path, err := getSubsystemPath(container.Cgroups, sys.Name()) - if err != nil && !cgroups.IsNotFound(err) { - return err + path, ok := m.paths[sys.Name()] + if !ok { + continue } if err := sys.Set(path, container.Cgroups); err != nil { return err @@ -420,7 +411,10 @@ func (m *legacyManager) Set(container *configs.Config) error { func enableKmem(c *configs.Cgroup) error { path, err := getSubsystemPath(c, "memory") - if err != nil && !cgroups.IsNotFound(err) { + if err != nil { + if cgroups.IsNotFound(err) { + return nil + } return err } @@ -429,7 +423,7 @@ func enableKmem(c *configs.Cgroup) error { } // do not try to enable the kernel memory if we already have // tasks in the cgroup. - content, err := ioutil.ReadFile(filepath.Join(path, "tasks")) + content, err := fscommon.ReadFile(path, "tasks") if err != nil { return err } @@ -450,9 +444,9 @@ func (m *legacyManager) GetCgroups() (*configs.Cgroup, error) { } func (m *legacyManager) GetFreezerState() (configs.FreezerState, error) { - path, err := getSubsystemPath(m.cgroups, "freezer") - if err != nil && !cgroups.IsNotFound(err) { - return configs.Undefined, err + path, ok := m.paths["freezer"] + if !ok { + return configs.Undefined, nil } freezer := &fs.FreezerGroup{} return freezer.GetState(path) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v2.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v2.go index e1a6622a0d3..70b5b368e86 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v2.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/v2.go @@ -3,6 +3,8 @@ package systemd import ( + "fmt" + "math" "os" "path/filepath" "strconv" @@ -34,6 +36,133 @@ func NewUnifiedManager(config *configs.Cgroup, path string, rootless bool) cgrou } } +// unifiedResToSystemdProps tries to convert from Cgroup.Resources.Unified +// key/value map (where key is cgroupfs file name) to systemd unit properties. +// This is on a best-effort basis, so the properties that are not known +// (to this function and/or systemd) are ignored (but logged with "debug" +// log level). +// +// For the list of keys, see https://www.kernel.org/doc/Documentation/cgroup-v2.txt +// +// For the list of systemd unit properties, see systemd.resource-control(5). +func unifiedResToSystemdProps(conn *systemdDbus.Conn, res map[string]string) (props []systemdDbus.Property, _ error) { + var err error + + for k, v := range res { + if strings.Contains(k, "/") { + return nil, fmt.Errorf("unified resource %q must be a file name (no slashes)", k) + } + sk := strings.SplitN(k, ".", 2) + if len(sk) != 2 { + return nil, fmt.Errorf("unified resource %q must be in the form CONTROLLER.PARAMETER", k) + } + // Kernel is quite forgiving to extra whitespace + // around the value, and so should we. + v = strings.TrimSpace(v) + // Please keep cases in alphabetical order. + switch k { + case "cpu.max": + // value: quota [period] + quota := int64(0) // 0 means "unlimited" for addCpuQuota, if period is set + period := defCPUQuotaPeriod + sv := strings.Fields(v) + if len(sv) < 1 || len(sv) > 2 { + return nil, fmt.Errorf("unified resource %q value invalid: %q", k, v) + } + // quota + if sv[0] != "max" { + quota, err = strconv.ParseInt(sv[0], 10, 64) + if err != nil { + return nil, fmt.Errorf("unified resource %q period value conversion error: %w", k, err) + } + } + // period + if len(sv) == 2 { + period, err = strconv.ParseUint(sv[1], 10, 64) + if err != nil { + return nil, fmt.Errorf("unified resource %q quota value conversion error: %w", k, err) + } + } + addCpuQuota(conn, &props, quota, period) + + case "cpu.weight": + num, err := strconv.ParseUint(v, 10, 64) + if err != nil { + return nil, fmt.Errorf("unified resource %q value conversion error: %w", k, err) + } + props = append(props, + newProp("CPUWeight", num)) + + case "cpuset.cpus", "cpuset.mems": + bits, err := rangeToBits(v) + if err != nil { + return nil, fmt.Errorf("unified resource %q=%q conversion error: %w", k, v, err) + } + m := map[string]string{ + "cpuset.cpus": "AllowedCPUs", + "cpuset.mems": "AllowedMemoryNodes", + } + // systemd only supports these properties since v244 + sdVer := systemdVersion(conn) + if sdVer >= 244 { + props = append(props, + newProp(m[k], bits)) + } else { + logrus.Debugf("systemd v%d is too old to support %s"+ + " (setting will still be applied to cgroupfs)", + sdVer, m[k]) + } + + case "memory.high", "memory.low", "memory.min", "memory.max", "memory.swap.max": + num := uint64(math.MaxUint64) + if v != "max" { + num, err = strconv.ParseUint(v, 10, 64) + if err != nil { + return nil, fmt.Errorf("unified resource %q value conversion error: %w", k, err) + } + } + m := map[string]string{ + "memory.high": "MemoryHigh", + "memory.low": "MemoryLow", + "memory.min": "MemoryMin", + "memory.max": "MemoryMax", + "memory.swap.max": "MemorySwapMax", + } + props = append(props, + newProp(m[k], num)) + + case "pids.max": + num := uint64(math.MaxUint64) + if v != "max" { + var err error + num, err = strconv.ParseUint(v, 10, 64) + if err != nil { + return nil, fmt.Errorf("unified resource %q value conversion error: %w", k, err) + } + } + props = append(props, + newProp("TasksAccounting", true), + newProp("TasksMax", num)) + + case "memory.oom.group": + // Setting this to 1 is roughly equivalent to OOMPolicy=kill + // (as per systemd.service(5) and + // https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html), + // but it's not clear what to do if it is unset or set + // to 0 in runc update, as there are two other possible + // values for OOMPolicy (continue/stop). + fallthrough + + default: + // Ignore the unknown resource here -- will still be + // applied in Set which calls fs2.Set. + logrus.Debugf("don't know how to convert unified resource %q=%q to systemd unit property; skipping (will still be applied to cgroupfs)", k, v) + } + } + + return props, nil +} + func genV2ResourcesProperties(c *configs.Cgroup, conn *systemdDbus.Conn) ([]systemdDbus.Property, error) { var properties []systemdDbus.Property r := c.Resources @@ -80,8 +209,22 @@ func genV2ResourcesProperties(c *configs.Cgroup, conn *systemdDbus.Conn) ([]syst newProp("TasksMax", uint64(r.PidsLimit))) } + err = addCpuset(conn, &properties, r.CpusetCpus, r.CpusetMems) + if err != nil { + return nil, err + } + // ignore r.KernelMemory + // convert Resources.Unified map to systemd properties + if r.Unified != nil { + unifiedProps, err := unifiedResToSystemdProps(conn, r.Unified) + if err != nil { + return nil, err + } + properties = append(properties, unifiedProps...) + } + return properties, nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go index 6e88b5dff6f..840817e398a 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go @@ -15,7 +15,9 @@ import ( "sync" "time" - units "github.com/docker/go-units" + "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" + "github.com/opencontainers/runc/libcontainer/system" + "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) @@ -29,19 +31,19 @@ var ( isUnified bool ) -// HugePageSizeUnitList is a list of the units used by the linux kernel when -// naming the HugePage control files. -// https://www.kernel.org/doc/Documentation/cgroup-v1/hugetlb.txt -// TODO Since the kernel only use KB, MB and GB; TB and PB should be removed, -// depends on https://github.com/docker/go-units/commit/a09cd47f892041a4fac473133d181f5aea6fa393 -var HugePageSizeUnitList = []string{"B", "KB", "MB", "GB", "TB", "PB"} - // IsCgroup2UnifiedMode returns whether we are running in cgroup v2 unified mode. func IsCgroup2UnifiedMode() bool { isUnifiedOnce.Do(func() { var st unix.Statfs_t - if err := unix.Statfs(unifiedMountpoint, &st); err != nil { - panic("cannot statfs cgroup root") + err := unix.Statfs(unifiedMountpoint, &st) + if err != nil { + if os.IsNotExist(err) && system.RunningInUserNS() { + // ignore the "not found" error if running in userns + logrus.WithError(err).Debugf("%s missing, assuming cgroup v1", unifiedMountpoint) + isUnified = false + return + } + panic(fmt.Sprintf("cannot statfs cgroup root: %s", err)) } isUnified = st.Type == unix.CGROUP2_SUPER_MAGIC }) @@ -86,11 +88,11 @@ func GetAllSubsystems() ([]string, error) { // - freezer: implemented in kernel 5.2 // We assume these are always available, as it is hard to detect availability. pseudo := []string{"devices", "freezer"} - data, err := ioutil.ReadFile("/sys/fs/cgroup/cgroup.controllers") + data, err := fscommon.ReadFile("/sys/fs/cgroup", "cgroup.controllers") if err != nil { return nil, err } - subsystems := append(pseudo, strings.Fields(string(data))...) + subsystems := append(pseudo, strings.Fields(data)...) return subsystems, nil } f, err := os.Open("/proc/cgroups") @@ -207,20 +209,66 @@ func EnterPid(cgroupPaths map[string]string, pid int) error { return nil } +func rmdir(path string) error { + err := unix.Rmdir(path) + if err == nil || err == unix.ENOENT { + return nil + } + return &os.PathError{Op: "rmdir", Path: path, Err: err} +} + +// RemovePath aims to remove cgroup path. It does so recursively, +// by removing any subdirectories (sub-cgroups) first. +func RemovePath(path string) error { + // try the fast path first + if err := rmdir(path); err == nil { + return nil + } + + infos, err := ioutil.ReadDir(path) + if err != nil { + if os.IsNotExist(err) { + err = nil + } + return err + } + for _, info := range infos { + if info.IsDir() { + // We should remove subcgroups dir first + if err = RemovePath(filepath.Join(path, info.Name())); err != nil { + break + } + } + } + if err == nil { + err = rmdir(path) + } + return err +} + // RemovePaths iterates over the provided paths removing them. // We trying to remove all paths five times with increasing delay between tries. // If after all there are not removed cgroups - appropriate error will be // returned. func RemovePaths(paths map[string]string) (err error) { + const retries = 5 delay := 10 * time.Millisecond - for i := 0; i < 5; i++ { + for i := 0; i < retries; i++ { if i != 0 { time.Sleep(delay) delay *= 2 } for s, p := range paths { - os.RemoveAll(p) - // TODO: here probably should be logging + if err := RemovePath(p); err != nil { + // do not log intermediate iterations + switch i { + case 0: + logrus.WithError(err).Warnf("Failed to remove cgroup (will retry)") + case retries - 1: + logrus.WithError(err).Error("Failed to remove cgroup") + } + + } _, err := os.Stat(p) // We need this strange way of checking cgroups existence because // RemoveAll almost always returns error, even on already removed @@ -230,6 +278,8 @@ func RemovePaths(paths map[string]string) (err error) { } } if len(paths) == 0 { + //nolint:ineffassign,staticcheck // done to help garbage collecting: opencontainers/runc#2506 + paths = make(map[string]string) return nil } } @@ -237,27 +287,50 @@ func RemovePaths(paths map[string]string) (err error) { } func GetHugePageSize() ([]string, error) { - files, err := ioutil.ReadDir("/sys/kernel/mm/hugepages") + dir, err := os.OpenFile("/sys/kernel/mm/hugepages", unix.O_DIRECTORY|unix.O_RDONLY, 0) if err != nil { - return []string{}, err + return nil, err } - var fileNames []string - for _, st := range files { - fileNames = append(fileNames, st.Name()) + files, err := dir.Readdirnames(0) + dir.Close() + if err != nil { + return nil, err } - return getHugePageSizeFromFilenames(fileNames) + + return getHugePageSizeFromFilenames(files) } func getHugePageSizeFromFilenames(fileNames []string) ([]string, error) { - var pageSizes []string - for _, fileName := range fileNames { - nameArray := strings.Split(fileName, "-") - pageSize, err := units.RAMInBytes(nameArray[1]) - if err != nil { - return []string{}, err + pageSizes := make([]string, 0, len(fileNames)) + + for _, file := range fileNames { + // example: hugepages-1048576kB + val := strings.TrimPrefix(file, "hugepages-") + if len(val) == len(file) { + // unexpected file name: no prefix found + continue } - sizeString := units.CustomSize("%g%s", float64(pageSize), 1024.0, HugePageSizeUnitList) - pageSizes = append(pageSizes, sizeString) + // The suffix is always "kB" (as of Linux 5.9) + eLen := len(val) - 2 + val = strings.TrimSuffix(val, "kB") + if len(val) != eLen { + logrus.Warnf("GetHugePageSize: %s: invalid filename suffix (expected \"kB\")", file) + continue + } + size, err := strconv.Atoi(val) + if err != nil { + return nil, err + } + // Model after https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/hugetlb_cgroup.c?id=eff48ddeab782e35e58ccc8853f7386bbae9dec4#n574 + // but in our case the size is in KB already. + if size >= (1 << 20) { + val = strconv.Itoa(size>>20) + "GB" + } else if size >= (1 << 10) { + val = strconv.Itoa(size>>10) + "MB" + } else { + val += "KB" + } + pageSizes = append(pageSizes, val) } return pageSizes, nil @@ -303,14 +376,14 @@ func WriteCgroupProc(dir string, pid int) error { return nil } - cgroupProcessesFile, err := os.OpenFile(filepath.Join(dir, CgroupProcesses), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0700) + file, err := fscommon.OpenFile(dir, CgroupProcesses, os.O_WRONLY) if err != nil { return fmt.Errorf("failed to write %v to %v: %v", pid, CgroupProcesses, err) } - defer cgroupProcessesFile.Close() + defer file.Close() for i := 0; i < 5; i++ { - _, err = cgroupProcessesFile.WriteString(strconv.Itoa(pid)) + _, err = file.WriteString(strconv.Itoa(pid)) if err == nil { return nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/v1_utils.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/v1_utils.go index a94f208616e..95ec9dff028 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/v1_utils.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/v1_utils.go @@ -1,16 +1,16 @@ package cgroups import ( - "bufio" "errors" "fmt" - "io" "os" "path/filepath" "strings" + "sync" "syscall" securejoin "github.com/cyphar/filepath-securejoin" + "github.com/moby/sys/mountinfo" "golang.org/x/sys/unix" ) @@ -23,7 +23,12 @@ const ( ) var ( - errUnified = errors.New("not implemented for cgroup v2 unified hierarchy") + errUnified = errors.New("not implemented for cgroup v2 unified hierarchy") + ErrV1NoUnified = errors.New("invalid configuration: cannot use unified on cgroup v1") + + readMountinfoOnce sync.Once + readMountinfoErr error + cgroupMountinfo []*mountinfo.Info ) type NotFoundError struct { @@ -90,6 +95,21 @@ func tryDefaultPath(cgroupPath, subsystem string) string { return path } +// readCgroupMountinfo returns a list of cgroup v1 mounts (i.e. the ones +// with fstype of "cgroup") for the current running process. +// +// The results are cached (to avoid re-reading mountinfo which is relatively +// expensive), so it is assumed that cgroup mounts are not being changed. +func readCgroupMountinfo() ([]*mountinfo.Info, error) { + readMountinfoOnce.Do(func() { + cgroupMountinfo, readMountinfoErr = mountinfo.GetMounts( + mountinfo.FSTypeFilter("cgroup"), + ) + }) + + return cgroupMountinfo, readMountinfoErr +} + // https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt func FindCgroupMountpoint(cgroupPath, subsystem string) (string, error) { if IsCgroup2UnifiedMode() { @@ -110,56 +130,28 @@ func FindCgroupMountpointAndRoot(cgroupPath, subsystem string) (string, string, return "", "", errUnified } - // Avoid parsing mountinfo by checking if subsystem is valid/available. - if !isSubsystemAvailable(subsystem) { - return "", "", NewNotFoundError(subsystem) - } - - f, err := os.Open("/proc/self/mountinfo") + mi, err := readCgroupMountinfo() if err != nil { return "", "", err } - defer f.Close() - return findCgroupMountpointAndRootFromReader(f, cgroupPath, subsystem) + return findCgroupMountpointAndRootFromMI(mi, cgroupPath, subsystem) } -func findCgroupMountpointAndRootFromReader(reader io.Reader, cgroupPath, subsystem string) (string, string, error) { - scanner := bufio.NewScanner(reader) - for scanner.Scan() { - txt := scanner.Text() - fields := strings.Fields(txt) - if len(fields) < 9 { - continue - } - if strings.HasPrefix(fields[4], cgroupPath) { - for _, opt := range strings.Split(fields[len(fields)-1], ",") { +func findCgroupMountpointAndRootFromMI(mounts []*mountinfo.Info, cgroupPath, subsystem string) (string, string, error) { + for _, mi := range mounts { + if strings.HasPrefix(mi.Mountpoint, cgroupPath) { + for _, opt := range strings.Split(mi.VFSOptions, ",") { if opt == subsystem { - return fields[4], fields[3], nil + return mi.Mountpoint, mi.Root, nil } } } } - if err := scanner.Err(); err != nil { - return "", "", err - } return "", "", NewNotFoundError(subsystem) } -func isSubsystemAvailable(subsystem string) bool { - if IsCgroup2UnifiedMode() { - panic("don't call isSubsystemAvailable from cgroupv2 code") - } - - cgroups, err := ParseCgroupFile("/proc/self/cgroup") - if err != nil { - return false - } - _, avail := cgroups[subsystem] - return avail -} - func (m Mount) GetOwnCgroup(cgroups map[string]string) (string, error) { if len(m.Subsystems) == 0 { return "", fmt.Errorf("no subsystem for mount") @@ -168,25 +160,15 @@ func (m Mount) GetOwnCgroup(cgroups map[string]string) (string, error) { return getControllerPath(m.Subsystems[0], cgroups) } -func getCgroupMountsHelper(ss map[string]bool, mi io.Reader, all bool) ([]Mount, error) { +func getCgroupMountsHelper(ss map[string]bool, mounts []*mountinfo.Info, all bool) ([]Mount, error) { res := make([]Mount, 0, len(ss)) - scanner := bufio.NewScanner(mi) numFound := 0 - for scanner.Scan() && numFound < len(ss) { - txt := scanner.Text() - sepIdx := strings.Index(txt, " - ") - if sepIdx == -1 { - return nil, fmt.Errorf("invalid mountinfo format") - } - if txt[sepIdx+3:sepIdx+10] == "cgroup2" || txt[sepIdx+3:sepIdx+9] != "cgroup" { - continue - } - fields := strings.Split(txt, " ") + for _, mi := range mounts { m := Mount{ - Mountpoint: fields[4], - Root: fields[3], + Mountpoint: mi.Mountpoint, + Root: mi.Root, } - for _, opt := range strings.Split(fields[len(fields)-1], ",") { + for _, opt := range strings.Split(mi.VFSOptions, ",") { seen, known := ss[opt] if !known || (!all && seen) { continue @@ -199,19 +181,18 @@ func getCgroupMountsHelper(ss map[string]bool, mi io.Reader, all bool) ([]Mount, if len(m.Subsystems) > 0 || all { res = append(res, m) } - } - if err := scanner.Err(); err != nil { - return nil, err + if !all && numFound >= len(ss) { + break + } } return res, nil } func getCgroupMountsV1(all bool) ([]Mount, error) { - f, err := os.Open("/proc/self/mountinfo") + mi, err := readCgroupMountinfo() if err != nil { return nil, err } - defer f.Close() allSubsystems, err := ParseCgroupFile("/proc/self/cgroup") if err != nil { @@ -222,7 +203,8 @@ func getCgroupMountsV1(all bool) ([]Mount, error) { for s := range allSubsystems { allMap[s] = false } - return getCgroupMountsHelper(allMap, f, all) + + return getCgroupMountsHelper(allMap, mi, all) } // GetOwnCgroup returns the relative path to the cgroup docker is running in. diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go index 6e90ae16b50..aada5d62f19 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go @@ -2,6 +2,7 @@ package configs import ( systemdDbus "github.com/coreos/go-systemd/v22/dbus" + "github.com/opencontainers/runc/libcontainer/devices" ) type FreezerState string @@ -42,7 +43,7 @@ type Cgroup struct { type Resources struct { // Devices is the set of access rules for devices in the container. - Devices []*DeviceRule `json:"devices"` + Devices []*devices.Rule `json:"devices"` // Memory limit (in bytes) Memory int64 `json:"memory"` @@ -127,6 +128,9 @@ type Resources struct { // CpuWeight sets a proportional bandwidth limit. CpuWeight uint64 `json:"cpu_weight"` + // Unified is cgroupv2-only key-value map. + Unified map[string]string `json:"unified"` + // SkipDevices allows to skip configuring device permissions. // Used by e.g. kubelet while creating a parent cgroup (kubepods) // common for many containers. diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go index 540f0f85d29..e1cd1626565 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go @@ -7,6 +7,7 @@ import ( "os/exec" "time" + "github.com/opencontainers/runc/libcontainer/devices" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -92,6 +93,9 @@ type Config struct { // Path to a directory containing the container's root filesystem. Rootfs string `json:"rootfs"` + // Umask is the umask to use inside of the container. + Umask *uint32 `json:"umask"` + // Readonlyfs will remount the container's rootfs as readonly where only externally mounted // bind mounts are writtable. Readonlyfs bool `json:"readonlyfs"` @@ -104,7 +108,7 @@ type Config struct { Mounts []*Mount `json:"mounts"` // The device nodes that should be automatically created within the container upon container start. Note, make sure that the node is marked as allowed in the cgroup as well! - Devices []*Device `json:"devices"` + Devices []*devices.Device `json:"devices"` MountLabel string `json:"mount_label"` diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/device_windows.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/device_windows.go deleted file mode 100644 index 729289393fe..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/configs/device_windows.go +++ /dev/null @@ -1,5 +0,0 @@ -package configs - -func (d *DeviceRule) Mkdev() (uint64, error) { - return 0, nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/devices.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/devices.go new file mode 100644 index 00000000000..b9e3664ceaa --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/devices.go @@ -0,0 +1,17 @@ +package configs + +import "github.com/opencontainers/runc/libcontainer/devices" + +type ( + // Deprecated: use libcontainer/devices.Device + Device = devices.Device + + // Deprecated: use libcontainer/devices.Rule + DeviceRule = devices.Rule + + // Deprecated: use libcontainer/devices.Type + DeviceType = devices.Type + + // Deprecated: use libcontainer/devices.Permissions + DevicePermissions = devices.Permissions +) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go index 1bbaef9bd94..d52d6fcd147 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go @@ -56,7 +56,7 @@ func IsNamespaceSupported(ns NamespaceType) bool { if nsFile == "" { return false } - _, err := os.Stat(fmt.Sprintf("/proc/self/ns/%s", nsFile)) + _, err := os.Stat("/proc/self/ns/" + nsFile) // a namespace is supported if it exists and we have permissions to read it supported = err == nil supportedNamespaces[ns] = supported diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go index 49b5f4c69fe..63abdb00cb0 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/validate/validator.go @@ -6,10 +6,12 @@ import ( "os" "path/filepath" "strings" + "sync" "github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/intelrdt" selinux "github.com/opencontainers/selinux/go-selinux" + "golang.org/x/sys/unix" ) type Validator interface { @@ -144,6 +146,12 @@ func (v *ConfigValidator) sysctl(config *configs.Config) error { "kernel.shm_rmid_forced": true, } + var ( + netOnce sync.Once + hostnet bool + hostnetErr error + ) + for s := range config.Sysctl { if validSysctlMap[s] || strings.HasPrefix(s, "fs.mqueue.") { if config.Namespaces.Contains(configs.NEWIPC) { @@ -153,16 +161,27 @@ func (v *ConfigValidator) sysctl(config *configs.Config) error { } } if strings.HasPrefix(s, "net.") { - if config.Namespaces.Contains(configs.NEWNET) { - if path := config.Namespaces.PathOf(configs.NEWNET); path != "" { - if err := checkHostNs(s, path); err != nil { - return err - } + // Is container using host netns? + // Here "host" means "current", not "initial". + netOnce.Do(func() { + if !config.Namespaces.Contains(configs.NEWNET) { + hostnet = true + return } - continue - } else { - return fmt.Errorf("sysctl %q is not allowed in the hosts network namespace", s) + path := config.Namespaces.PathOf(configs.NEWNET) + if path == "" { + // own netns, so hostnet = false + return + } + hostnet, hostnetErr = isHostNetNS(path) + }) + if hostnetErr != nil { + return hostnetErr } + if hostnet { + return fmt.Errorf("sysctl %q not allowed in host network namespace", s) + } + continue } if config.Namespaces.Contains(configs.NEWUTS) { switch s { @@ -182,21 +201,21 @@ func (v *ConfigValidator) sysctl(config *configs.Config) error { func (v *ConfigValidator) intelrdt(config *configs.Config) error { if config.IntelRdt != nil { - if !intelrdt.IsCatEnabled() && !intelrdt.IsMbaEnabled() { + if !intelrdt.IsCATEnabled() && !intelrdt.IsMBAEnabled() { return errors.New("intelRdt is specified in config, but Intel RDT is not supported or enabled") } - if !intelrdt.IsCatEnabled() && config.IntelRdt.L3CacheSchema != "" { + if !intelrdt.IsCATEnabled() && config.IntelRdt.L3CacheSchema != "" { return errors.New("intelRdt.l3CacheSchema is specified in config, but Intel RDT/CAT is not enabled") } - if !intelrdt.IsMbaEnabled() && config.IntelRdt.MemBwSchema != "" { + if !intelrdt.IsMBAEnabled() && config.IntelRdt.MemBwSchema != "" { return errors.New("intelRdt.memBwSchema is specified in config, but Intel RDT/MBA is not enabled") } - if intelrdt.IsCatEnabled() && config.IntelRdt.L3CacheSchema == "" { + if intelrdt.IsCATEnabled() && config.IntelRdt.L3CacheSchema == "" { return errors.New("Intel RDT/CAT is enabled and intelRdt is specified in config, but intelRdt.l3CacheSchema is empty") } - if intelrdt.IsMbaEnabled() && config.IntelRdt.MemBwSchema == "" { + if intelrdt.IsMBAEnabled() && config.IntelRdt.MemBwSchema == "" { return errors.New("Intel RDT/MBA is enabled and intelRdt is specified in config, but intelRdt.memBwSchema is empty") } } @@ -204,43 +223,17 @@ func (v *ConfigValidator) intelrdt(config *configs.Config) error { return nil } -func isSymbolicLink(path string) (bool, error) { - fi, err := os.Lstat(path) - if err != nil { - return false, err +func isHostNetNS(path string) (bool, error) { + const currentProcessNetns = "/proc/self/ns/net" + + var st1, st2 unix.Stat_t + + if err := unix.Stat(currentProcessNetns, &st1); err != nil { + return false, fmt.Errorf("unable to stat %q: %s", currentProcessNetns, err) + } + if err := unix.Stat(path, &st2); err != nil { + return false, fmt.Errorf("unable to stat %q: %s", path, err) } - return fi.Mode()&os.ModeSymlink == os.ModeSymlink, nil -} - -// checkHostNs checks whether network sysctl is used in host namespace. -func checkHostNs(sysctlConfig string, path string) error { - var currentProcessNetns = "/proc/self/ns/net" - // readlink on the current processes network namespace - destOfCurrentProcess, err := os.Readlink(currentProcessNetns) - if err != nil { - return fmt.Errorf("read soft link %q error", currentProcessNetns) - } - - // First check if the provided path is a symbolic link - symLink, err := isSymbolicLink(path) - if err != nil { - return fmt.Errorf("could not check that %q is a symlink: %v", path, err) - } - - if symLink == false { - // The provided namespace is not a symbolic link, - // it is not the host namespace. - return nil - } - - // readlink on the path provided in the struct - destOfContainer, err := os.Readlink(path) - if err != nil { - return fmt.Errorf("read soft link %q error", path) - } - if destOfContainer == destOfCurrentProcess { - return fmt.Errorf("sysctl %q is not allowed in the hosts network namespace", sysctlConfig) - } - return nil + return (st1.Dev == st2.Dev) && (st1.Ino == st2.Ino), nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go index e2f64fcb9fe..3dca29e4c3f 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/container_linux.go @@ -14,6 +14,7 @@ import ( "os/exec" "path/filepath" "reflect" + "strconv" "strings" "sync" "time" @@ -363,24 +364,10 @@ func (c *linuxContainer) start(process *Process) error { } parent.forwardChildLogs() if err := parent.start(); err != nil { - // terminate the process to ensure that it properly is reaped. - if err := ignoreTerminateErrors(parent.terminate()); err != nil { - logrus.Warn(err) - } return newSystemErrorWithCause(err, "starting container process") } - // generate a timestamp indicating when the container was started - c.created = time.Now().UTC() - if process.Init { - c.state = &createdState{ - c: c, - } - state, err := c.updateState(parent) - if err != nil { - return err - } - c.initProcessStartTime = state.InitProcessStartTime + if process.Init { if c.config.Hooks != nil { s, err := c.currentOCIState() if err != nil { @@ -463,7 +450,7 @@ func (c *linuxContainer) includeExecFifo(cmd *exec.Cmd) error { cmd.ExtraFiles = append(cmd.ExtraFiles, os.NewFile(uintptr(fifoFd), fifoName)) cmd.Env = append(cmd.Env, - fmt.Sprintf("_LIBCONTAINER_FIFOFD=%d", stdioFdCount+len(cmd.ExtraFiles)-1)) + "_LIBCONTAINER_FIFOFD="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1)) return nil } @@ -506,24 +493,24 @@ func (c *linuxContainer) commandTemplate(p *Process, childInitPipe *os.File, chi if cmd.SysProcAttr == nil { cmd.SysProcAttr = &unix.SysProcAttr{} } - cmd.Env = append(cmd.Env, fmt.Sprintf("GOMAXPROCS=%s", os.Getenv("GOMAXPROCS"))) + cmd.Env = append(cmd.Env, "GOMAXPROCS="+os.Getenv("GOMAXPROCS")) cmd.ExtraFiles = append(cmd.ExtraFiles, p.ExtraFiles...) if p.ConsoleSocket != nil { cmd.ExtraFiles = append(cmd.ExtraFiles, p.ConsoleSocket) cmd.Env = append(cmd.Env, - fmt.Sprintf("_LIBCONTAINER_CONSOLE=%d", stdioFdCount+len(cmd.ExtraFiles)-1), + "_LIBCONTAINER_CONSOLE="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1), ) } cmd.ExtraFiles = append(cmd.ExtraFiles, childInitPipe) cmd.Env = append(cmd.Env, - fmt.Sprintf("_LIBCONTAINER_INITPIPE=%d", stdioFdCount+len(cmd.ExtraFiles)-1), - fmt.Sprintf("_LIBCONTAINER_STATEDIR=%s", c.root), + "_LIBCONTAINER_INITPIPE="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1), + "_LIBCONTAINER_STATEDIR="+c.root, ) cmd.ExtraFiles = append(cmd.ExtraFiles, childLogPipe) cmd.Env = append(cmd.Env, - fmt.Sprintf("_LIBCONTAINER_LOGPIPE=%d", stdioFdCount+len(cmd.ExtraFiles)-1), - fmt.Sprintf("_LIBCONTAINER_LOGLEVEL=%s", p.LogLevel), + "_LIBCONTAINER_LOGPIPE="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1), + "_LIBCONTAINER_LOGLEVEL="+p.LogLevel, ) // NOTE: when running a container with no PID namespace and the parent process spawning the container is @@ -693,8 +680,7 @@ var criuFeatures *criurpc.CriuFeatures func (c *linuxContainer) checkCriuFeatures(criuOpts *CriuOpts, rpcOpts *criurpc.CriuOpts, criuFeat *criurpc.CriuFeatures) error { - var t criurpc.CriuReqType - t = criurpc.CriuReqType_FEATURE_CHECK + t := criurpc.CriuReqType_FEATURE_CHECK // make sure the features we are looking for are really not from // some previous check @@ -777,11 +763,7 @@ func (c *linuxContainer) checkCriuVersion(minVersion int) error { const descriptorsFilename = "descriptors.json" func (c *linuxContainer) addCriuDumpMount(req *criurpc.CriuReq, m *configs.Mount) { - mountDest := m.Destination - if strings.HasPrefix(mountDest, c.config.Rootfs) { - mountDest = mountDest[len(c.config.Rootfs):] - } - + mountDest := strings.TrimPrefix(m.Destination, c.config.Rootfs) extMnt := &criurpc.ExtMountMap{ Key: proto.String(mountDest), Val: proto.String(mountDest), @@ -853,7 +835,7 @@ func (c *linuxContainer) criuSupportsExtNS(t configs.NamespaceType) bool { return c.checkCriuVersion(minVersion) == nil } -func (c *linuxContainer) criuNsToKey(t configs.NamespaceType) string { +func criuNsToKey(t configs.NamespaceType) string { return "extRoot" + strings.Title(configs.NsName(t)) + "NS" } @@ -873,12 +855,50 @@ func (c *linuxContainer) handleCheckpointingExternalNamespaces(rpcOpts *criurpc. if err := unix.Stat(nsPath, &ns); err != nil { return err } - criuExternal := fmt.Sprintf("%s[%d]:%s", configs.NsName(t), ns.Ino, c.criuNsToKey(t)) + criuExternal := fmt.Sprintf("%s[%d]:%s", configs.NsName(t), ns.Ino, criuNsToKey(t)) rpcOpts.External = append(rpcOpts.External, criuExternal) return nil } +func (c *linuxContainer) handleRestoringNamespaces(rpcOpts *criurpc.CriuOpts, extraFiles *[]*os.File) error { + for _, ns := range c.config.Namespaces { + switch ns.Type { + case configs.NEWNET, configs.NEWPID: + // If the container is running in a network or PID namespace and has + // a path to the network or PID namespace configured, we will dump + // that network or PID namespace as an external namespace and we + // will expect that the namespace exists during restore. + // This basically means that CRIU will ignore the namespace + // and expect it to be setup correctly. + if err := c.handleRestoringExternalNamespaces(rpcOpts, extraFiles, ns.Type); err != nil { + return err + } + default: + // For all other namespaces except NET and PID CRIU has + // a simpler way of joining the existing namespace if set + nsPath := c.config.Namespaces.PathOf(ns.Type) + if nsPath == "" { + continue + } + if ns.Type == configs.NEWCGROUP { + // CRIU has no code to handle NEWCGROUP + return fmt.Errorf("Do not know how to handle namespace %v", ns.Type) + } + // CRIU has code to handle NEWTIME, but it does not seem to be defined in runc + + // CRIU will issue a warning for NEWUSER: + // criu/namespaces.c: 'join-ns with user-namespace is not fully tested and dangerous' + rpcOpts.JoinNs = append(rpcOpts.JoinNs, &criurpc.JoinNamespace{ + Ns: proto.String(configs.NsName(ns.Type)), + NsFile: proto.String(nsPath), + }) + } + } + + return nil +} + func (c *linuxContainer) handleRestoringExternalNamespaces(rpcOpts *criurpc.CriuOpts, extraFiles *[]*os.File, t configs.NamespaceType) error { if !c.criuSupportsExtNS(t) { return nil @@ -897,11 +917,12 @@ func (c *linuxContainer) handleRestoringExternalNamespaces(rpcOpts *criurpc.Criu logrus.Errorf("If a specific network namespace is defined it must exist: %s", err) return fmt.Errorf("Requested network namespace %v does not exist", nsPath) } - inheritFd := new(criurpc.InheritFd) - inheritFd.Key = proto.String(c.criuNsToKey(t)) - // The offset of four is necessary because 0, 1, 2 and 3 is already - // used by stdin, stdout, stderr, 'criu swrk' socket. - inheritFd.Fd = proto.Int32(int32(4 + len(*extraFiles))) + inheritFd := &criurpc.InheritFd{ + Key: proto.String(criuNsToKey(t)), + // The offset of four is necessary because 0, 1, 2 and 3 are + // already used by stdin, stdout, stderr, 'criu swrk' socket. + Fd: proto.Int32(int32(4 + len(*extraFiles))), + } rpcOpts.InheritFd = append(rpcOpts.InheritFd, inheritFd) // All open FDs need to be transferred to CRIU via extraFiles *extraFiles = append(*extraFiles, nsFd) @@ -1120,11 +1141,7 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error { } func (c *linuxContainer) addCriuRestoreMount(req *criurpc.CriuReq, m *configs.Mount) { - mountDest := m.Destination - if strings.HasPrefix(mountDest, c.config.Rootfs) { - mountDest = mountDest[len(c.config.Rootfs):] - } - + mountDest := strings.TrimPrefix(m.Destination, c.config.Rootfs) extMnt := &criurpc.ExtMountMap{ Key: proto.String(mountDest), Val: proto.String(m.Source), @@ -1309,15 +1326,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error { c.handleCriuConfigurationFile(req.Opts) - // Same as during checkpointing. If the container has a specific network namespace - // assigned to it, this now expects that the checkpoint will be restored in a - // already created network namespace. - if err := c.handleRestoringExternalNamespaces(req.Opts, &extraFiles, configs.NEWNET); err != nil { - return err - } - - // Same for PID namespaces. - if err := c.handleRestoringExternalNamespaces(req.Opts, &extraFiles, configs.NEWPID); err != nil { + if err := c.handleRestoringNamespaces(req.Opts, &extraFiles); err != nil { return err } @@ -1540,7 +1549,7 @@ func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts * buf := make([]byte, 10*4096) oob := make([]byte, 4096) - for true { + for { n, oobn, _, _, err := criuClientCon.ReadMsgUnix(buf, oob) if req.Opts != nil && req.Opts.StatusFd != nil { // Close status_fd as soon as we got something back from criu, @@ -1792,10 +1801,6 @@ func (c *linuxContainer) saveState(s *State) (retErr error) { return os.Rename(tmpFile.Name(), stateFilePath) } -func (c *linuxContainer) deleteState() error { - return os.Remove(filepath.Join(c.root, stateFilename)) -} - func (c *linuxContainer) currentStatus() (Status, error) { if err := c.refreshState(); err != nil { return -1, err @@ -2042,7 +2047,7 @@ func (c *linuxContainer) bootstrapData(cloneFlags uintptr, nsMaps map[configs.Na // write oom_score_adj r.AddData(&Bytemsg{ Type: OomScoreAdjAttr, - Value: []byte(fmt.Sprintf("%d", *c.config.OomScoreAdj)), + Value: []byte(strconv.Itoa(*c.config.OomScoreAdj)), }) } @@ -2062,9 +2067,21 @@ func ignoreTerminateErrors(err error) error { if err == nil { return nil } + // terminate() might return an error from ether Kill or Wait. + // The (*Cmd).Wait documentation says: "If the command fails to run + // or doesn't complete successfully, the error is of type *ExitError". + // Filter out such errors (like "exit status 1" or "signal: killed"). + var exitErr *exec.ExitError + if errors.As(err, &exitErr) { + return nil + } + // TODO: use errors.Is(err, os.ErrProcessDone) here and + // remove "process already finished" string comparison below + // once go 1.16 is minimally supported version. + s := err.Error() - switch { - case strings.Contains(s, "process already finished"), strings.Contains(s, "Wait was already called"): + if strings.Contains(s, "process already finished") || + strings.Contains(s, "Wait was already called") { return nil } return err diff --git a/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go index 1d119246d1e..11cbdb2db98 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/criu_opts_linux.go @@ -1,14 +1,6 @@ package libcontainer -// cgroup restoring strategy provided by criu -type cgMode uint32 - -const ( - CRIU_CG_MODE_SOFT cgMode = 3 + iota // restore cgroup properties if only dir created by criu - CRIU_CG_MODE_FULL // always restore all cgroups and their properties - CRIU_CG_MODE_STRICT // restore all, requiring them to not present in the system - CRIU_CG_MODE_DEFAULT // the same as CRIU_CG_MODE_SOFT -) +import criu "github.com/checkpoint-restore/go-criu/v4/rpc" type CriuPageServerInfo struct { Address string // IP address of CRIU page server @@ -32,7 +24,7 @@ type CriuOpts struct { PreDump bool // call criu predump to perform iterative checkpoint PageServer CriuPageServerInfo // allow to dump to criu page server VethPairs []VethPairName // pass the veth to criu when restore - ManageCgroupsMode cgMode // dump or restore cgroup mode + ManageCgroupsMode criu.CriuCgMode // dump or restore cgroup mode EmptyNs uint32 // don't c/r properties for namespace from this mask AutoDedup bool // auto deduplication for incremental dumps LazyPages bool // restore memory pages lazily using userfaultfd diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/device.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/device.go similarity index 63% rename from vendor/github.com/opencontainers/runc/libcontainer/configs/device.go rename to vendor/github.com/opencontainers/runc/libcontainer/devices/device.go index 632bf6ac49c..3eb73cc7c76 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/configs/device.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/device.go @@ -1,4 +1,4 @@ -package configs +package devices import ( "fmt" @@ -11,7 +11,7 @@ const ( ) type Device struct { - DeviceRule + Rule // Path to the device. Path string `json:"path"` @@ -26,10 +26,10 @@ type Device struct { Gid uint32 `json:"gid"` } -// DevicePermissions is a cgroupv1-style string to represent device access. It +// Permissions is a cgroupv1-style string to represent device access. It // has to be a string for backward compatibility reasons, hence why it has // methods to do set operations. -type DevicePermissions string +type Permissions string const ( deviceRead uint = (1 << iota) @@ -37,7 +37,7 @@ const ( deviceMknod ) -func (p DevicePermissions) toSet() uint { +func (p Permissions) toSet() uint { var set uint for _, perm := range p { switch perm { @@ -52,7 +52,7 @@ func (p DevicePermissions) toSet() uint { return set } -func fromSet(set uint) DevicePermissions { +func fromSet(set uint) Permissions { var perm string if set&deviceRead == deviceRead { perm += "r" @@ -63,53 +63,53 @@ func fromSet(set uint) DevicePermissions { if set&deviceMknod == deviceMknod { perm += "m" } - return DevicePermissions(perm) + return Permissions(perm) } -// Union returns the union of the two sets of DevicePermissions. -func (p DevicePermissions) Union(o DevicePermissions) DevicePermissions { +// Union returns the union of the two sets of Permissions. +func (p Permissions) Union(o Permissions) Permissions { lhs := p.toSet() rhs := o.toSet() return fromSet(lhs | rhs) } -// Difference returns the set difference of the two sets of DevicePermissions. +// Difference returns the set difference of the two sets of Permissions. // In set notation, A.Difference(B) gives you A\B. -func (p DevicePermissions) Difference(o DevicePermissions) DevicePermissions { +func (p Permissions) Difference(o Permissions) Permissions { lhs := p.toSet() rhs := o.toSet() return fromSet(lhs &^ rhs) } -// Intersection computes the intersection of the two sets of DevicePermissions. -func (p DevicePermissions) Intersection(o DevicePermissions) DevicePermissions { +// Intersection computes the intersection of the two sets of Permissions. +func (p Permissions) Intersection(o Permissions) Permissions { lhs := p.toSet() rhs := o.toSet() return fromSet(lhs & rhs) } -// IsEmpty returns whether the set of permissions in a DevicePermissions is +// IsEmpty returns whether the set of permissions in a Permissions is // empty. -func (p DevicePermissions) IsEmpty() bool { - return p == DevicePermissions("") +func (p Permissions) IsEmpty() bool { + return p == Permissions("") } // IsValid returns whether the set of permissions is a subset of valid // permissions (namely, {r,w,m}). -func (p DevicePermissions) IsValid() bool { +func (p Permissions) IsValid() bool { return p == fromSet(p.toSet()) } -type DeviceType rune +type Type rune const ( - WildcardDevice DeviceType = 'a' - BlockDevice DeviceType = 'b' - CharDevice DeviceType = 'c' // or 'u' - FifoDevice DeviceType = 'p' + WildcardDevice Type = 'a' + BlockDevice Type = 'b' + CharDevice Type = 'c' // or 'u' + FifoDevice Type = 'p' ) -func (t DeviceType) IsValid() bool { +func (t Type) IsValid() bool { switch t { case WildcardDevice, BlockDevice, CharDevice, FifoDevice: return true @@ -118,7 +118,7 @@ func (t DeviceType) IsValid() bool { } } -func (t DeviceType) CanMknod() bool { +func (t Type) CanMknod() bool { switch t { case BlockDevice, CharDevice, FifoDevice: return true @@ -127,7 +127,7 @@ func (t DeviceType) CanMknod() bool { } } -func (t DeviceType) CanCgroup() bool { +func (t Type) CanCgroup() bool { switch t { case WildcardDevice, BlockDevice, CharDevice: return true @@ -136,10 +136,10 @@ func (t DeviceType) CanCgroup() bool { } } -type DeviceRule struct { +type Rule struct { // Type of device ('c' for char, 'b' for block). If set to 'a', this rule // acts as a wildcard and all fields other than Allow are ignored. - Type DeviceType `json:"type"` + Type Type `json:"type"` // Major is the device's major number. Major int64 `json:"major"` @@ -149,13 +149,13 @@ type DeviceRule struct { // Permissions is the set of permissions that this rule applies to (in the // cgroupv1 format -- any combination of "rwm"). - Permissions DevicePermissions `json:"permissions"` + Permissions Permissions `json:"permissions"` // Allow specifies whether this rule is allowed. Allow bool `json:"allow"` } -func (d *DeviceRule) CgroupString() string { +func (d *Rule) CgroupString() string { var ( major = strconv.FormatInt(d.Major, 10) minor = strconv.FormatInt(d.Minor, 10) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/device_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/device_unix.go similarity index 79% rename from vendor/github.com/opencontainers/runc/libcontainer/configs/device_unix.go rename to vendor/github.com/opencontainers/runc/libcontainer/devices/device_unix.go index 650c46848a1..a400341e440 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/configs/device_unix.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/device_unix.go @@ -1,6 +1,6 @@ // +build !windows -package configs +package devices import ( "errors" @@ -8,7 +8,7 @@ import ( "golang.org/x/sys/unix" ) -func (d *DeviceRule) Mkdev() (uint64, error) { +func (d *Rule) Mkdev() (uint64, error) { if d.Major == Wildcard || d.Minor == Wildcard { return 0, errors.New("cannot mkdev() device with wildcards") } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/device_windows.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/device_windows.go new file mode 100644 index 00000000000..8511bf00e07 --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/device_windows.go @@ -0,0 +1,5 @@ +package devices + +func (d *Rule) Mkdev() (uint64, error) { + return 0, nil +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices.go new file mode 100644 index 00000000000..5011f373d2c --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices.go @@ -0,0 +1,112 @@ +package devices + +import ( + "errors" + "io/ioutil" + "os" + "path/filepath" + + "golang.org/x/sys/unix" +) + +var ( + // ErrNotADevice denotes that a file is not a valid linux device. + ErrNotADevice = errors.New("not a device node") +) + +// Testing dependencies +var ( + unixLstat = unix.Lstat + ioutilReadDir = ioutil.ReadDir +) + +// Given the path to a device and its cgroup_permissions(which cannot be easily queried) look up the +// information about a linux device and return that information as a Device struct. +func DeviceFromPath(path, permissions string) (*Device, error) { + var stat unix.Stat_t + err := unixLstat(path, &stat) + if err != nil { + return nil, err + } + + var ( + devType Type + mode = stat.Mode + devNumber = uint64(stat.Rdev) + major = unix.Major(devNumber) + minor = unix.Minor(devNumber) + ) + switch mode & unix.S_IFMT { + case unix.S_IFBLK: + devType = BlockDevice + case unix.S_IFCHR: + devType = CharDevice + case unix.S_IFIFO: + devType = FifoDevice + default: + return nil, ErrNotADevice + } + return &Device{ + Rule: Rule{ + Type: devType, + Major: int64(major), + Minor: int64(minor), + Permissions: Permissions(permissions), + }, + Path: path, + FileMode: os.FileMode(mode), + Uid: stat.Uid, + Gid: stat.Gid, + }, nil +} + +// HostDevices returns all devices that can be found under /dev directory. +func HostDevices() ([]*Device, error) { + return GetDevices("/dev") +} + +// GetDevices recursively traverses a directory specified by path +// and returns all devices found there. +func GetDevices(path string) ([]*Device, error) { + files, err := ioutilReadDir(path) + if err != nil { + return nil, err + } + var out []*Device + for _, f := range files { + switch { + case f.IsDir(): + switch f.Name() { + // ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825 + // ".udev" added to address https://github.com/opencontainers/runc/issues/2093 + case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts", ".udev": + continue + default: + sub, err := GetDevices(filepath.Join(path, f.Name())) + if err != nil { + return nil, err + } + + out = append(out, sub...) + continue + } + case f.Name() == "console": + continue + } + device, err := DeviceFromPath(filepath.Join(path, f.Name()), "rwm") + if err != nil { + if err == ErrNotADevice { + continue + } + if os.IsNotExist(err) { + continue + } + return nil, err + } + if device.Type == FifoDevice { + continue + } + out = append(out, device) + } + return out, nil +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go index 59548ef8819..5cd374162b9 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/factory_linux.go @@ -148,11 +148,11 @@ func RootlessCgroupfs(l *LinuxFactory) error { // containers that use the Intel RDT "resource control" filesystem to // create and manage Intel RDT resources (e.g., L3 cache, memory bandwidth). func IntelRdtFs(l *LinuxFactory) error { - l.NewIntelRdtManager = func(config *configs.Config, id string, path string) intelrdt.Manager { - return &intelrdt.IntelRdtManager{ - Config: config, - Id: id, - Path: path, + if !intelrdt.IsCATEnabled() && !intelrdt.IsMBAEnabled() { + l.NewIntelRdtManager = nil + } else { + l.NewIntelRdtManager = func(config *configs.Config, id string, path string) intelrdt.Manager { + return intelrdt.NewManager(config, id, path) } } return nil @@ -276,7 +276,7 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err newgidmapPath: l.NewgidmapPath, cgroupManager: l.NewCgroupsManager(config.Cgroups, nil), } - if intelrdt.IsCatEnabled() || intelrdt.IsMbaEnabled() { + if l.NewIntelRdtManager != nil { c.intelRdtManager = l.NewIntelRdtManager(config, id, "") } c.state = &stoppedState{c: c} @@ -318,13 +318,13 @@ func (l *LinuxFactory) Load(id string) (Container, error) { root: containerRoot, created: state.Created, } + if l.NewIntelRdtManager != nil { + c.intelRdtManager = l.NewIntelRdtManager(&state.Config, id, state.IntelRdtPath) + } c.state = &loadedState{c: c} if err := c.refreshState(); err != nil { return nil, err } - if intelrdt.IsCatEnabled() || intelrdt.IsMbaEnabled() { - c.intelRdtManager = l.NewIntelRdtManager(&state.Config, id, state.IntelRdtPath) - } return c, nil } @@ -335,35 +335,28 @@ func (l *LinuxFactory) Type() string { // StartInitialization loads a container by opening the pipe fd from the parent to read the configuration and state // This is a low level implementation detail of the reexec and should not be consumed externally func (l *LinuxFactory) StartInitialization() (err error) { - var ( - pipefd, fifofd int - consoleSocket *os.File - envInitPipe = os.Getenv("_LIBCONTAINER_INITPIPE") - envFifoFd = os.Getenv("_LIBCONTAINER_FIFOFD") - envConsole = os.Getenv("_LIBCONTAINER_CONSOLE") - ) - // Get the INITPIPE. - pipefd, err = strconv.Atoi(envInitPipe) + envInitPipe := os.Getenv("_LIBCONTAINER_INITPIPE") + pipefd, err := strconv.Atoi(envInitPipe) if err != nil { return fmt.Errorf("unable to convert _LIBCONTAINER_INITPIPE=%s to int: %s", envInitPipe, err) } - - var ( - pipe = os.NewFile(uintptr(pipefd), "pipe") - it = initType(os.Getenv("_LIBCONTAINER_INITTYPE")) - ) + pipe := os.NewFile(uintptr(pipefd), "pipe") defer pipe.Close() // Only init processes have FIFOFD. - fifofd = -1 + fifofd := -1 + envInitType := os.Getenv("_LIBCONTAINER_INITTYPE") + it := initType(envInitType) if it == initStandard { + envFifoFd := os.Getenv("_LIBCONTAINER_FIFOFD") if fifofd, err = strconv.Atoi(envFifoFd); err != nil { return fmt.Errorf("unable to convert _LIBCONTAINER_FIFOFD=%s to int: %s", envFifoFd, err) } } - if envConsole != "" { + var consoleSocket *os.File + if envConsole := os.Getenv("_LIBCONTAINER_CONSOLE"); envConsole != "" { console, err := strconv.Atoi(envConsole) if err != nil { return fmt.Errorf("unable to convert _LIBCONTAINER_CONSOLE=%s to int: %s", envConsole, err) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go index f2dc17e00e9..c57af0eebb8 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/init_linux.go @@ -3,6 +3,7 @@ package libcontainer import ( + "bytes" "encoding/json" "fmt" "io" @@ -12,9 +13,8 @@ import ( "strings" "unsafe" - "golang.org/x/sys/unix" - "github.com/containerd/console" + "github.com/opencontainers/runc/libcontainer/capabilities" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/system" @@ -24,6 +24,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" + "golang.org/x/sys/unix" ) type initType string @@ -128,19 +129,13 @@ func finalizeNamespace(config *initConfig) error { return errors.Wrap(err, "close exec fds") } - if config.Cwd != "" { - if err := unix.Chdir(config.Cwd); err != nil { - return fmt.Errorf("chdir to cwd (%q) set in config.json failed: %v", config.Cwd, err) - } - } - - capabilities := &configs.Capabilities{} + caps := &configs.Capabilities{} if config.Capabilities != nil { - capabilities = config.Capabilities + caps = config.Capabilities } else if config.Config.Capabilities != nil { - capabilities = config.Config.Capabilities + caps = config.Config.Capabilities } - w, err := newContainerCapList(capabilities) + w, err := capabilities.New(caps) if err != nil { return err } @@ -155,6 +150,14 @@ func finalizeNamespace(config *initConfig) error { if err := setupUser(config); err != nil { return errors.Wrap(err, "setup user") } + // Change working directory AFTER the user has been set up. + // Otherwise, if the cwd is also a volume that's been chowned to the container user (and not the user running runc), + // this command will EPERM. + if config.Cwd != "" { + if err := unix.Chdir(config.Cwd); err != nil { + return fmt.Errorf("chdir to cwd (%q) set in config.json failed: %v", config.Cwd, err) + } + } if err := system.ClearKeepCaps(); err != nil { return errors.Wrap(err, "clear keep caps") } @@ -304,7 +307,7 @@ func setupUser(config *initConfig) error { // There's nothing we can do about /etc/group entries, so we silently // ignore setting groups here (since the user didn't explicitly ask us to // set the group). - allowSupGroups := !config.RootlessEUID && strings.TrimSpace(string(setgroups)) != "deny" + allowSupGroups := !config.RootlessEUID && string(bytes.TrimSpace(setgroups)) != "deny" if allowSupGroups { suppGroups := append(execUser.Sgids, addGroups...) @@ -431,6 +434,7 @@ func setupRlimits(limits []configs.Rlimit, pid int) error { const _P_PID = 1 +//nolint:structcheck,unused type siginfo struct { si_signo int32 si_errno int32 @@ -480,7 +484,9 @@ func signalAllProcesses(m cgroups.Manager, s os.Signal) error { } pids, err := m.GetAllPids() if err != nil { - m.Freeze(configs.Thawed) + if err := m.Freeze(configs.Thawed); err != nil { + logrus.Warn(err) + } return err } for _, pid := range pids { diff --git a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/cmt.go b/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/cmt.go index 5c406e10207..ed950973f08 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/cmt.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/cmt.go @@ -6,17 +6,20 @@ var ( // Check if Intel RDT/CMT is enabled. func IsCMTEnabled() bool { + featuresInit() return cmtEnabled } func getCMTNumaNodeStats(numaPath string) (*CMTNumaNodeStats, error) { stats := &CMTNumaNodeStats{} - llcOccupancy, err := getIntelRdtParamUint(numaPath, "llc_occupancy") - if err != nil { - return nil, err + if enabledMonFeatures.llcOccupancy { + llcOccupancy, err := getIntelRdtParamUint(numaPath, "llc_occupancy") + if err != nil { + return nil, err + } + stats.LLCOccupancy = llcOccupancy } - stats.LLCOccupancy = llcOccupancy return stats, nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/intelrdt.go b/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/intelrdt.go index 5b19d55a2d7..3fa11b8002d 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/intelrdt.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/intelrdt.go @@ -4,7 +4,9 @@ package intelrdt import ( "bufio" + "bytes" "fmt" + "io" "io/ioutil" "os" "path/filepath" @@ -12,6 +14,7 @@ import ( "strings" "sync" + "github.com/moby/sys/mountinfo" "github.com/opencontainers/runc/libcontainer/configs" ) @@ -162,11 +165,19 @@ type Manager interface { } // This implements interface Manager -type IntelRdtManager struct { +type intelRdtManager struct { mu sync.Mutex - Config *configs.Config - Id string - Path string + config *configs.Config + id string + path string +} + +func NewManager(config *configs.Config, id string, path string) Manager { + return &intelRdtManager{ + config: config, + id: id, + path: path, + } } const ( @@ -179,11 +190,14 @@ var ( intelRdtRootLock sync.Mutex // The flag to indicate if Intel RDT/CAT is enabled - isCatEnabled bool + catEnabled bool // The flag to indicate if Intel RDT/MBA is enabled - isMbaEnabled bool + mbaEnabled bool // The flag to indicate if Intel RDT/MBA Software Controller is enabled - isMbaScEnabled bool + mbaScEnabled bool + + // For Intel RDT initialization + initOnce sync.Once ) type intelRdtData struct { @@ -192,94 +206,80 @@ type intelRdtData struct { pid int } -// Check if Intel RDT sub-features are enabled in init() -func init() { - // 1. Check if hardware and kernel support Intel RDT sub-features - flagsSet, err := parseCpuInfoFile("/proc/cpuinfo") - if err != nil { - return - } - - // 2. Check if Intel RDT "resource control" filesystem is mounted - // The user guarantees to mount the filesystem - if !isIntelRdtMounted() { - return - } - - // 3. Double check if Intel RDT sub-features are available in - // "resource control" filesystem. Intel RDT sub-features can be - // selectively disabled or enabled by kernel command line - // (e.g., rdt=!l3cat,mba) in 4.14 and newer kernel - if flagsSet.CAT { - if _, err := os.Stat(filepath.Join(intelRdtRoot, "info", "L3")); err == nil { - isCatEnabled = true - } - } - if isMbaScEnabled { - // We confirm MBA Software Controller is enabled in step 2, - // MBA should be enabled because MBA Software Controller - // depends on MBA - isMbaEnabled = true - } else if flagsSet.MBA { - if _, err := os.Stat(filepath.Join(intelRdtRoot, "info", "MB")); err == nil { - isMbaEnabled = true - } - } - - if flagsSet.MBMTotal || flagsSet.MBMLocal { - if _, err := os.Stat(filepath.Join(intelRdtRoot, "info", "L3_MON")); err == nil { - mbmEnabled = true - cmtEnabled = true - } - - enabledMonFeatures, err = getMonFeatures(intelRdtRoot) +// Check if Intel RDT sub-features are enabled in featuresInit() +func featuresInit() { + initOnce.Do(func() { + // 1. Check if hardware and kernel support Intel RDT sub-features + flagsSet, err := parseCpuInfoFile("/proc/cpuinfo") if err != nil { return } - } + + // 2. Check if Intel RDT "resource control" filesystem is mounted + // The user guarantees to mount the filesystem + if !isIntelRdtMounted() { + return + } + + // 3. Double check if Intel RDT sub-features are available in + // "resource control" filesystem. Intel RDT sub-features can be + // selectively disabled or enabled by kernel command line + // (e.g., rdt=!l3cat,mba) in 4.14 and newer kernel + if flagsSet.CAT { + if _, err := os.Stat(filepath.Join(intelRdtRoot, "info", "L3")); err == nil { + catEnabled = true + } + } + if mbaScEnabled { + // We confirm MBA Software Controller is enabled in step 2, + // MBA should be enabled because MBA Software Controller + // depends on MBA + mbaEnabled = true + } else if flagsSet.MBA { + if _, err := os.Stat(filepath.Join(intelRdtRoot, "info", "MB")); err == nil { + mbaEnabled = true + } + } + if flagsSet.MBMTotal || flagsSet.MBMLocal || flagsSet.CMT { + if _, err := os.Stat(filepath.Join(intelRdtRoot, "info", "L3_MON")); err != nil { + return + } + enabledMonFeatures, err = getMonFeatures(intelRdtRoot) + if err != nil { + return + } + if enabledMonFeatures.mbmTotalBytes || enabledMonFeatures.mbmLocalBytes { + mbmEnabled = true + } + if enabledMonFeatures.llcOccupancy { + cmtEnabled = true + } + } + }) } // Return the mount point path of Intel RDT "resource control" filesysem -func findIntelRdtMountpointDir() (string, error) { - f, err := os.Open("/proc/self/mountinfo") +func findIntelRdtMountpointDir(f io.Reader) (string, error) { + mi, err := mountinfo.GetMountsFromReader(f, func(m *mountinfo.Info) (bool, bool) { + // similar to mountinfo.FSTypeFilter but stops after the first match + if m.FSType == "resctrl" { + return false, true // don't skip, stop + } + return true, false // skip, keep going + }) if err != nil { return "", err } - defer f.Close() - - s := bufio.NewScanner(f) - for s.Scan() { - text := s.Text() - fields := strings.Split(text, " ") - // Safe as mountinfo encodes mountpoints with spaces as \040. - index := strings.Index(text, " - ") - postSeparatorFields := strings.Fields(text[index+3:]) - numPostFields := len(postSeparatorFields) - - // This is an error as we can't detect if the mount is for "Intel RDT" - if numPostFields == 0 { - return "", fmt.Errorf("Found no fields post '-' in %q", text) - } - - if postSeparatorFields[0] == "resctrl" { - // Check that the mount is properly formatted. - if numPostFields < 3 { - return "", fmt.Errorf("Error found less than 3 fields post '-' in %q", text) - } - - // Check if MBA Software Controller is enabled through mount option "-o mba_MBps" - if strings.Contains(postSeparatorFields[2], "mba_MBps") { - isMbaScEnabled = true - } - - return fields[4], nil - } - } - if err := s.Err(); err != nil { - return "", err + if len(mi) < 1 { + return "", NewNotFoundError("Intel RDT") } - return "", NewNotFoundError("Intel RDT") + // Check if MBA Software Controller is enabled through mount option "-o mba_MBps" + if strings.Contains(","+mi[0].VFSOptions+",", ",mba_MBps,") { + mbaScEnabled = true + } + + return mi[0].Mountpoint, nil } // Gets the root path of Intel RDT "resource control" filesystem @@ -291,7 +291,12 @@ func getIntelRdtRoot() (string, error) { return intelRdtRoot, nil } - root, err := findIntelRdtMountpointDir() + f, err := os.Open("/proc/self/mountinfo") + if err != nil { + return "", err + } + root, err := findIntelRdtMountpointDir(f) + f.Close() if err != nil { return "", err } @@ -306,11 +311,7 @@ func getIntelRdtRoot() (string, error) { func isIntelRdtMounted() bool { _, err := getIntelRdtRoot() - if err != nil { - return false - } - - return true + return err == nil } type cpuInfoFlags struct { @@ -320,6 +321,8 @@ type cpuInfoFlags struct { // Memory Bandwidth Monitoring related. MBMTotal bool MBMLocal bool + + CMT bool // Cache Monitoring Technology } func parseCpuInfoFile(path string) (cpuInfoFlags, error) { @@ -349,6 +352,8 @@ func parseCpuInfoFile(path string) (cpuInfoFlags, error) { infoFlags.MBMTotal = true case "cqm_mbm_local": infoFlags.MBMLocal = true + case "cqm_occup_llc": + infoFlags.CMT = true } } return infoFlags, nil @@ -387,7 +392,7 @@ func getIntelRdtParamUint(path, file string) (uint64, error) { return 0, err } - res, err := parseUint(strings.TrimSpace(string(contents)), 10, 64) + res, err := parseUint(string(bytes.TrimSpace(contents)), 10, 64) if err != nil { return res, fmt.Errorf("unable to parse %q as a uint from file %q", string(contents), fileName) } @@ -401,14 +406,14 @@ func getIntelRdtParamString(path, file string) (string, error) { return "", err } - return strings.TrimSpace(string(contents)), nil + return string(bytes.TrimSpace(contents)), nil } func writeFile(dir, file, data string) error { if dir == "" { return fmt.Errorf("no such directory for %s", file) } - if err := ioutil.WriteFile(filepath.Join(dir, file), []byte(data+"\n"), 0700); err != nil { + if err := ioutil.WriteFile(filepath.Join(dir, file), []byte(data+"\n"), 0o600); err != nil { return fmt.Errorf("failed to write %v to %v: %v", data, file, err) } return nil @@ -515,7 +520,7 @@ func WriteIntelRdtTasks(dir string, pid int) error { // Don't attach any pid if -1 is specified as a pid if pid != -1 { - if err := ioutil.WriteFile(filepath.Join(dir, IntelRdtTasks), []byte(strconv.Itoa(pid)), 0700); err != nil { + if err := ioutil.WriteFile(filepath.Join(dir, IntelRdtTasks), []byte(strconv.Itoa(pid)), 0o600); err != nil { return fmt.Errorf("failed to write %v to %v: %v", pid, IntelRdtTasks, err) } } @@ -523,18 +528,21 @@ func WriteIntelRdtTasks(dir string, pid int) error { } // Check if Intel RDT/CAT is enabled -func IsCatEnabled() bool { - return isCatEnabled +func IsCATEnabled() bool { + featuresInit() + return catEnabled } // Check if Intel RDT/MBA is enabled -func IsMbaEnabled() bool { - return isMbaEnabled +func IsMBAEnabled() bool { + featuresInit() + return mbaEnabled } // Check if Intel RDT/MBA Software Controller is enabled -func IsMbaScEnabled() bool { - return isMbaScEnabled +func IsMBAScEnabled() bool { + featuresInit() + return mbaScEnabled } // Get the 'container_id' path in Intel RDT "resource control" filesystem @@ -549,51 +557,51 @@ func GetIntelRdtPath(id string) (string, error) { } // Applies Intel RDT configuration to the process with the specified pid -func (m *IntelRdtManager) Apply(pid int) (err error) { +func (m *intelRdtManager) Apply(pid int) (err error) { // If intelRdt is not specified in config, we do nothing - if m.Config.IntelRdt == nil { + if m.config.IntelRdt == nil { return nil } - d, err := getIntelRdtData(m.Config, pid) + d, err := getIntelRdtData(m.config, pid) if err != nil && !IsNotFound(err) { return err } m.mu.Lock() defer m.mu.Unlock() - path, err := d.join(m.Id) + path, err := d.join(m.id) if err != nil { return err } - m.Path = path + m.path = path return nil } // Destroys the Intel RDT 'container_id' group -func (m *IntelRdtManager) Destroy() error { +func (m *intelRdtManager) Destroy() error { m.mu.Lock() defer m.mu.Unlock() if err := os.RemoveAll(m.GetPath()); err != nil { return err } - m.Path = "" + m.path = "" return nil } // Returns Intel RDT path to save in a state file and to be able to // restore the object later -func (m *IntelRdtManager) GetPath() string { - if m.Path == "" { - m.Path, _ = GetIntelRdtPath(m.Id) +func (m *intelRdtManager) GetPath() string { + if m.path == "" { + m.path, _ = GetIntelRdtPath(m.id) } - return m.Path + return m.path } // Returns statistics for Intel RDT -func (m *IntelRdtManager) GetStats() (*Stats, error) { +func (m *intelRdtManager) GetStats() (*Stats, error) { // If intelRdt is not specified in config - if m.Config.IntelRdt == nil { + if m.config.IntelRdt == nil { return nil, nil } @@ -620,7 +628,7 @@ func (m *IntelRdtManager) GetStats() (*Stats, error) { } schemaStrings := strings.Split(tmpStrings, "\n") - if IsCatEnabled() { + if IsCATEnabled() { // The read-only L3 cache information l3CacheInfo, err := getL3CacheInfo() if err != nil { @@ -643,7 +651,7 @@ func (m *IntelRdtManager) GetStats() (*Stats, error) { } } - if IsMbaEnabled() { + if IsMBAEnabled() { // The read-only memory bandwidth information memBwInfo, err := getMemBwInfo() if err != nil { @@ -666,16 +674,18 @@ func (m *IntelRdtManager) GetStats() (*Stats, error) { } } - err = getMonitoringStats(containerPath, stats) - if err != nil { - return nil, err + if IsMBMEnabled() || IsCMTEnabled() { + err = getMonitoringStats(containerPath, stats) + if err != nil { + return nil, err + } } return stats, nil } // Set Intel RDT "resource control" filesystem as configured. -func (m *IntelRdtManager) Set(container *configs.Config) error { +func (m *intelRdtManager) Set(container *configs.Config) error { // About L3 cache schema: // It has allocation bitmasks/values for L3 cache on each socket, // which contains L3 cache id and capacity bitmask (CBM). @@ -753,7 +763,7 @@ func (m *IntelRdtManager) Set(container *configs.Config) error { func (raw *intelRdtData) join(id string) (string, error) { path := filepath.Join(raw.root, id) - if err := os.MkdirAll(path, 0755); err != nil { + if err := os.MkdirAll(path, 0o755); err != nil { return "", NewLastCmdError(err) } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/mbm.go b/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/mbm.go index 3730bab5644..93063ee0190 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/mbm.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/mbm.go @@ -9,6 +9,7 @@ var ( // Check if Intel RDT/MBM is enabled. func IsMBMEnabled() bool { + featuresInit() return mbmEnabled } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/monitoring.go b/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/monitoring.go index 4ccc8eae050..78c2f624c96 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/monitoring.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/monitoring.go @@ -2,11 +2,12 @@ package intelrdt import ( "bufio" - "github.com/sirupsen/logrus" "io" "io/ioutil" "os" "path/filepath" + + "github.com/sirupsen/logrus" ) var ( @@ -21,10 +22,10 @@ type monFeatures struct { func getMonFeatures(intelRdtRoot string) (monFeatures, error) { file, err := os.Open(filepath.Join(intelRdtRoot, "info", "L3_MON", "mon_features")) - defer file.Close() if err != nil { return monFeatures{}, err } + defer file.Close() return parseMonFeatures(file) } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/stats.go b/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/stats.go index eeb0ee9f0d8..70df0d14e6c 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/stats.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/intelrdt/stats.go @@ -17,15 +17,15 @@ type MemBwInfo struct { type MBMNumaNodeStats struct { // The 'mbm_total_bytes' in 'container_id' group. - MBMTotalBytes uint64 `json:"mbm_total_bytes,omitempty"` + MBMTotalBytes uint64 `json:"mbm_total_bytes"` // The 'mbm_local_bytes' in 'container_id' group. - MBMLocalBytes uint64 `json:"mbm_local_bytes,omitempty"` + MBMLocalBytes uint64 `json:"mbm_local_bytes"` } type CMTNumaNodeStats struct { // The 'llc_occupancy' in 'container_id' group. - LLCOccupancy uint64 `json:"llc_occupancy,omitempty"` + LLCOccupancy uint64 `json:"llc_occupancy"` } type Stats struct { diff --git a/vendor/github.com/opencontainers/runc/libcontainer/network_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/network_linux.go index 938d8ce0640..a0a87b9842a 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/network_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/network_linux.go @@ -3,11 +3,11 @@ package libcontainer import ( + "bytes" "fmt" "io/ioutil" "path/filepath" "strconv" - "strings" "github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/types" @@ -79,7 +79,7 @@ func readSysfsNetworkStats(ethInterface, statsFile string) (uint64, error) { if err != nil { return 0, err } - return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64) + return strconv.ParseUint(string(bytes.TrimSpace(data)), 10, 64) } // loopback is a network strategy that provides a basic loopback device diff --git a/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go index cb8c724a206..834268b9957 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/process_linux.go @@ -11,6 +11,7 @@ import ( "os/exec" "path/filepath" "strconv" + "time" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups/fs2" @@ -85,21 +86,29 @@ func (p *setnsProcess) signal(sig os.Signal) error { return unix.Kill(p.pid(), s) } -func (p *setnsProcess) start() (err error) { +func (p *setnsProcess) start() (retErr error) { defer p.messageSockPair.parent.Close() - err = p.cmd.Start() + err := p.cmd.Start() // close the write-side of the pipes (controlled by child) p.messageSockPair.child.Close() p.logFilePair.child.Close() if err != nil { return newSystemErrorWithCause(err, "starting setns process") } + defer func() { + if retErr != nil { + err := ignoreTerminateErrors(p.terminate()) + if err != nil { + logrus.WithError(err).Warn("unable to terminate setnsProcess") + } + } + }() if p.bootstrapData != nil { if _, err := io.Copy(p.messageSockPair.parent, p.bootstrapData); err != nil { return newSystemErrorWithCause(err, "copying bootstrap data to pipe") } } - if err = p.execSetns(); err != nil { + if err := p.execSetns(); err != nil { return newSystemErrorWithCause(err, "executing setns process") } if len(p.cgroupPaths) > 0 { @@ -312,6 +321,11 @@ func (p *initProcess) start() (retErr error) { } defer func() { if retErr != nil { + // terminate the process to ensure we can remove cgroups + if err := ignoreTerminateErrors(p.terminate()); err != nil { + logrus.WithError(err).Warn("unable to terminate initProcess") + } + p.manager.Destroy() if p.intelRdtManager != nil { p.intelRdtManager.Destroy() @@ -411,6 +425,28 @@ func (p *initProcess) start() (retErr error) { } } } + + // generate a timestamp indicating when the container was started + p.container.created = time.Now().UTC() + p.container.state = &createdState{ + c: p.container, + } + + // NOTE: If the procRun state has been synced and the + // runc-create process has been killed for some reason, + // the runc-init[2:stage] process will be leaky. And + // the runc command also fails to parse root directory + // because the container doesn't have state.json. + // + // In order to cleanup the runc-init[2:stage] by + // runc-delete/stop, we should store the status before + // procRun sync. + state, uerr := p.container.updateState(p) + if uerr != nil { + return newSystemErrorWithCause(err, "store init state") + } + p.container.initProcessStartTime = state.InitProcessStartTime + // Sync with child. if err := writeSync(p.messageSockPair.parent, procRun); err != nil { return newSystemErrorWithCause(err, "writing syncT 'run'") @@ -475,14 +511,11 @@ func (p *initProcess) start() (retErr error) { func (p *initProcess) wait() (*os.ProcessState, error) { err := p.cmd.Wait() - if err != nil { - return p.cmd.ProcessState, err - } // we should kill all processes in cgroup when init is died if we use host PID namespace if p.sharePidns { signalAllProcesses(p.manager, unix.SIGKILL) } - return p.cmd.ProcessState, nil + return p.cmd.ProcessState, err } func (p *initProcess) terminate() error { diff --git a/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go index e00df0a2c12..411496ab7c6 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/rootfs_linux.go @@ -18,11 +18,12 @@ import ( "github.com/mrunalp/fileutils" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/configs" + "github.com/opencontainers/runc/libcontainer/devices" "github.com/opencontainers/runc/libcontainer/system" + "github.com/opencontainers/runc/libcontainer/utils" libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils" "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/selinux/go-selinux/label" - "golang.org/x/sys/unix" ) @@ -156,7 +157,11 @@ func finalizeRootfs(config *configs.Config) (err error) { } } - unix.Umask(0022) + if config.Umask != nil { + unix.Umask(int(*config.Umask)) + } else { + unix.Umask(0022) + } return nil } @@ -328,17 +333,20 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string, enableCgroupns b if err := os.MkdirAll(dest, 0755); err != nil { return err } - if err := mountPropagate(m, rootfs, mountLabel); err != nil { - // older kernels do not support labeling of /dev/mqueue - if err := mountPropagate(m, rootfs, ""); err != nil { - return err - } - return label.SetFileLabel(dest, mountLabel) + if err := mountPropagate(m, rootfs, ""); err != nil { + return err } - return nil + return label.SetFileLabel(dest, mountLabel) case "tmpfs": copyUp := m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP tmpDir := "" + // dest might be an absolute symlink, so it needs + // to be resolved under rootfs. + dest, err := securejoin.SecureJoin(rootfs, m.Destination) + if err != nil { + return err + } + m.Destination = dest stat, err := os.Stat(dest) if err != nil { if err := os.MkdirAll(dest, 0755); err != nil { @@ -382,6 +390,12 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string, enableCgroupns b return err } } + // Initially mounted rw in mountPropagate, remount to ro if flag set. + if m.Flags&unix.MS_RDONLY != 0 { + if err := remount(m, rootfs); err != nil { + return err + } + } return nil case "bind": if err := prepareBindMount(m, rootfs); err != nil { @@ -475,28 +489,6 @@ func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) { // if source is nil, don't stat the filesystem. This is used for restore of a checkpoint. func checkProcMount(rootfs, dest, source string) error { const procPath = "/proc" - // White list, it should be sub directories of invalid destinations - validDestinations := []string{ - // These entries can be bind mounted by files emulated by fuse, - // so commands like top, free displays stats in container. - "/proc/cpuinfo", - "/proc/diskstats", - "/proc/meminfo", - "/proc/stat", - "/proc/swaps", - "/proc/uptime", - "/proc/loadavg", - "/proc/net/dev", - } - for _, valid := range validDestinations { - path, err := filepath.Rel(filepath.Join(rootfs, valid), dest) - if err != nil { - return err - } - if path == "." { - return nil - } - } path, err := filepath.Rel(filepath.Join(rootfs, procPath), dest) if err != nil { return err @@ -522,6 +514,30 @@ func checkProcMount(rootfs, dest, source string) error { } return fmt.Errorf("%q cannot be mounted because it is not of type proc", dest) } + + // Here dest is definitely under /proc. Do not allow those, + // except for a few specific entries emulated by lxcfs. + validProcMounts := []string{ + "/proc/cpuinfo", + "/proc/diskstats", + "/proc/meminfo", + "/proc/stat", + "/proc/swaps", + "/proc/uptime", + "/proc/loadavg", + "/proc/slabinfo", + "/proc/net/dev", + } + for _, valid := range validProcMounts { + path, err := filepath.Rel(filepath.Join(rootfs, valid), dest) + if err != nil { + return err + } + if path == "." { + return nil + } + } + return fmt.Errorf("%q cannot be mounted because it is inside /proc", dest) } @@ -590,6 +606,12 @@ func createDevices(config *configs.Config) error { useBindMount := system.RunningInUserNS() || config.Namespaces.Contains(configs.NEWUSER) oldMask := unix.Umask(0000) for _, node := range config.Devices { + + // The /dev/ptmx device is setup by setupPtmx() + if utils.CleanPath(node.Path) == "/dev/ptmx" { + continue + } + // containers running in a user namespace are not allowed to mknod // devices so we can just bind mount it from the host. if err := createDeviceNode(config.Rootfs, node, useBindMount); err != nil { @@ -601,7 +623,7 @@ func createDevices(config *configs.Config) error { return nil } -func bindMountDeviceNode(dest string, node *configs.Device) error { +func bindMountDeviceNode(dest string, node *devices.Device) error { f, err := os.Create(dest) if err != nil && !os.IsExist(err) { return err @@ -613,7 +635,7 @@ func bindMountDeviceNode(dest string, node *configs.Device) error { } // Creates the device node in the rootfs of the container. -func createDeviceNode(rootfs string, node *configs.Device, bind bool) error { +func createDeviceNode(rootfs string, node *devices.Device, bind bool) error { if node.Path == "" { // The node only exists for cgroup reasons, ignore it here. return nil @@ -636,14 +658,14 @@ func createDeviceNode(rootfs string, node *configs.Device, bind bool) error { return nil } -func mknodDevice(dest string, node *configs.Device) error { +func mknodDevice(dest string, node *devices.Device) error { fileMode := node.FileMode switch node.Type { - case configs.BlockDevice: + case devices.BlockDevice: fileMode |= unix.S_IFBLK - case configs.CharDevice: + case devices.CharDevice: fileMode |= unix.S_IFCHR - case configs.FifoDevice: + case devices.FifoDevice: fileMode |= unix.S_IFIFO default: return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path) @@ -728,7 +750,19 @@ func prepareRoot(config *configs.Config) error { } func setReadonly() error { - return unix.Mount("/", "/", "bind", unix.MS_BIND|unix.MS_REMOUNT|unix.MS_RDONLY|unix.MS_REC, "") + flags := uintptr(unix.MS_BIND | unix.MS_REMOUNT | unix.MS_RDONLY) + + err := unix.Mount("", "/", "", flags, "") + if err == nil { + return nil + } + var s unix.Statfs_t + if err := unix.Statfs("/", &s); err != nil { + return &os.PathError{Op: "statfs", Path: "/", Err: err} + } + flags |= uintptr(s.Flags) + return unix.Mount("", "/", "", flags, "") + } func setupPtmx(config *configs.Config) error { @@ -802,24 +836,46 @@ func pivotRoot(rootfs string) error { } func msMoveRoot(rootfs string) error { + // Before we move the root and chroot we have to mask all "full" sysfs and + // procfs mounts which exist on the host. This is because while the kernel + // has protections against mounting procfs if it has masks, when using + // chroot(2) the *host* procfs mount is still reachable in the mount + // namespace and the kernel permits procfs mounts inside --no-pivot + // containers. + // + // Users shouldn't be using --no-pivot except in exceptional circumstances, + // but to avoid such a trivial security flaw we apply a best-effort + // protection here. The kernel only allows a mount of a pseudo-filesystem + // like procfs or sysfs if there is a *full* mount (the root of the + // filesystem is mounted) without any other locked mount points covering a + // subtree of the mount. + // + // So we try to unmount (or mount tmpfs on top of) any mountpoint which is + // a full mount of either sysfs or procfs (since those are the most + // concerning filesystems to us). mountinfos, err := mountinfo.GetMounts(func(info *mountinfo.Info) (skip, stop bool) { - skip = false - stop = false - // Collect every sysfs and proc file systems, except those under the container rootfs - if (info.Fstype != "proc" && info.Fstype != "sysfs") || strings.HasPrefix(info.Mountpoint, rootfs) { + // Collect every sysfs and procfs filesystem, except for those which + // are non-full mounts or are inside the rootfs of the container. + if info.Root != "/" || + (info.FSType != "proc" && info.FSType != "sysfs") || + strings.HasPrefix(info.Mountpoint, rootfs) { skip = true - return } return }) if err != nil { return err } - for _, info := range mountinfos { p := info.Mountpoint // Be sure umount events are not propagated to the host. if err := unix.Mount("", p, "", unix.MS_SLAVE|unix.MS_REC, ""); err != nil { + if err == unix.ENOENT { + // If the mountpoint doesn't exist that means that we've + // already blasted away some parent directory of the mountpoint + // and so we don't care about this error. + continue + } return err } if err := unix.Unmount(p, unix.MNT_DETACH); err != nil { @@ -834,6 +890,8 @@ func msMoveRoot(rootfs string) error { } } } + + // Move the rootfs on top of "/" in our mount namespace. if err := unix.Mount(rootfs, "/", "", unix.MS_MOVE, ""); err != nil { return err } @@ -950,6 +1008,12 @@ func mountPropagate(m *configs.Mount, rootfs string, mountLabel string) error { flags &= ^unix.MS_RDONLY } + // Mount it rw to allow chmod operation. A remount will be performed + // later to make it ro if set. + if m.Device == "tmpfs" { + flags &= ^unix.MS_RDONLY + } + copyUp := m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP if !(copyUp || strings.HasPrefix(dest, rootfs)) { dest = filepath.Join(rootfs, dest) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go index c3212279875..b54b7eead3b 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/config.go @@ -49,7 +49,7 @@ var archs = map[string]string{ // Attempting to convert a string that is not a valid operator results in an // error. func ConvertStringToOperator(in string) (configs.Operator, error) { - if op, ok := operators[in]; ok == true { + if op, ok := operators[in]; ok { return op, nil } return 0, fmt.Errorf("string %s is not a valid operator for seccomp", in) @@ -62,7 +62,7 @@ func ConvertStringToOperator(in string) (configs.Operator, error) { // Attempting to convert a string that is not a valid action results in an // error. func ConvertStringToAction(in string) (configs.Action, error) { - if act, ok := actions[in]; ok == true { + if act, ok := actions[in]; ok { return act, nil } return 0, fmt.Errorf("string %s is not a valid action for seccomp", in) @@ -70,7 +70,7 @@ func ConvertStringToAction(in string) (configs.Action, error) { // ConvertStringToArch converts a string into a Seccomp comparison arch. func ConvertStringToArch(in string) (string, error) { - if arch, ok := archs[in]; ok == true { + if arch, ok := archs[in]; ok { return arch, nil } return "", fmt.Errorf("string %s is not a valid arch for seccomp", in) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go new file mode 100644 index 00000000000..cdbd59da095 --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_linux.go @@ -0,0 +1,628 @@ +// +build linux,cgo,seccomp + +package patchbpf + +import ( + "encoding/binary" + "io" + "os" + "runtime" + "unsafe" + + "github.com/opencontainers/runc/libcontainer/configs" + "github.com/opencontainers/runc/libcontainer/utils" + + "github.com/pkg/errors" + libseccomp "github.com/seccomp/libseccomp-golang" + "github.com/sirupsen/logrus" + "golang.org/x/net/bpf" + "golang.org/x/sys/unix" +) + +// #cgo pkg-config: libseccomp +/* +#include +#include +#include +#include + +const uint32_t C_ACT_ERRNO_ENOSYS = SCMP_ACT_ERRNO(ENOSYS); + +// Copied from . + +#ifndef SECCOMP_SET_MODE_FILTER +# define SECCOMP_SET_MODE_FILTER 1 +#endif +const uintptr_t C_SET_MODE_FILTER = SECCOMP_SET_MODE_FILTER; + +#ifndef SECCOMP_FILTER_FLAG_LOG +# define SECCOMP_FILTER_FLAG_LOG (1UL << 1) +#endif +const uintptr_t C_FILTER_FLAG_LOG = SECCOMP_FILTER_FLAG_LOG; + +// We use the AUDIT_ARCH_* values because those are the ones used by the kernel +// and SCMP_ARCH_* sometimes has fake values (such as SCMP_ARCH_X32). But we +// use so we get libseccomp's fallback definitions of AUDIT_ARCH_*. + +const uint32_t C_AUDIT_ARCH_I386 = AUDIT_ARCH_I386; +const uint32_t C_AUDIT_ARCH_X86_64 = AUDIT_ARCH_X86_64; +const uint32_t C_AUDIT_ARCH_ARM = AUDIT_ARCH_ARM; +const uint32_t C_AUDIT_ARCH_AARCH64 = AUDIT_ARCH_AARCH64; +const uint32_t C_AUDIT_ARCH_MIPS = AUDIT_ARCH_MIPS; +const uint32_t C_AUDIT_ARCH_MIPS64 = AUDIT_ARCH_MIPS64; +const uint32_t C_AUDIT_ARCH_MIPS64N32 = AUDIT_ARCH_MIPS64N32; +const uint32_t C_AUDIT_ARCH_MIPSEL = AUDIT_ARCH_MIPSEL; +const uint32_t C_AUDIT_ARCH_MIPSEL64 = AUDIT_ARCH_MIPSEL64; +const uint32_t C_AUDIT_ARCH_MIPSEL64N32 = AUDIT_ARCH_MIPSEL64N32; +const uint32_t C_AUDIT_ARCH_PPC = AUDIT_ARCH_PPC; +const uint32_t C_AUDIT_ARCH_PPC64 = AUDIT_ARCH_PPC64; +const uint32_t C_AUDIT_ARCH_PPC64LE = AUDIT_ARCH_PPC64LE; +const uint32_t C_AUDIT_ARCH_S390 = AUDIT_ARCH_S390; +const uint32_t C_AUDIT_ARCH_S390X = AUDIT_ARCH_S390X; +*/ +import "C" + +var retErrnoEnosys = uint32(C.C_ACT_ERRNO_ENOSYS) + +func isAllowAction(action configs.Action) bool { + switch action { + // Trace is considered an "allow" action because a good tracer should + // support future syscalls (by handling -ENOSYS on its own), and giving + // -ENOSYS will be disruptive for emulation. + case configs.Allow, configs.Log, configs.Trace: + return true + default: + return false + } +} + +func parseProgram(rdr io.Reader) ([]bpf.RawInstruction, error) { + var program []bpf.RawInstruction +loop: + for { + // Read the next instruction. We have to use NativeEndian because + // seccomp_export_bpf outputs the program in *host* endian-ness. + var insn unix.SockFilter + if err := binary.Read(rdr, utils.NativeEndian, &insn); err != nil { + switch err { + case io.EOF: + // Parsing complete. + break loop + case io.ErrUnexpectedEOF: + // Parsing stopped mid-instruction. + return nil, errors.Wrap(err, "program parsing halted mid-instruction") + default: + // All other errors. + return nil, errors.Wrap(err, "parsing instructions") + } + } + program = append(program, bpf.RawInstruction{ + Op: insn.Code, + Jt: insn.Jt, + Jf: insn.Jf, + K: insn.K, + }) + } + return program, nil +} + +func disassembleFilter(filter *libseccomp.ScmpFilter) ([]bpf.Instruction, error) { + rdr, wtr, err := os.Pipe() + if err != nil { + return nil, errors.Wrap(err, "creating scratch pipe") + } + defer wtr.Close() + defer rdr.Close() + + if err := filter.ExportBPF(wtr); err != nil { + return nil, errors.Wrap(err, "exporting BPF") + } + // Close so that the reader actually gets EOF. + _ = wtr.Close() + + // Parse the instructions. + rawProgram, err := parseProgram(rdr) + if err != nil { + return nil, errors.Wrap(err, "parsing generated BPF filter") + } + program, ok := bpf.Disassemble(rawProgram) + if !ok { + return nil, errors.Errorf("could not disassemble entire BPF filter") + } + return program, nil +} + +type nativeArch uint32 + +const invalidArch nativeArch = 0 + +func archToNative(arch libseccomp.ScmpArch) (nativeArch, error) { + switch arch { + case libseccomp.ArchNative: + // Convert to actual native architecture. + arch, err := libseccomp.GetNativeArch() + if err != nil { + return invalidArch, errors.Wrap(err, "get native arch") + } + return archToNative(arch) + case libseccomp.ArchX86: + return nativeArch(C.C_AUDIT_ARCH_I386), nil + case libseccomp.ArchAMD64, libseccomp.ArchX32: + // NOTE: x32 is treated like x86_64 except all x32 syscalls have the + // 30th bit of the syscall number set to indicate that it's not a + // normal x86_64 syscall. + return nativeArch(C.C_AUDIT_ARCH_X86_64), nil + case libseccomp.ArchARM: + return nativeArch(C.C_AUDIT_ARCH_ARM), nil + case libseccomp.ArchARM64: + return nativeArch(C.C_AUDIT_ARCH_AARCH64), nil + case libseccomp.ArchMIPS: + return nativeArch(C.C_AUDIT_ARCH_MIPS), nil + case libseccomp.ArchMIPS64: + return nativeArch(C.C_AUDIT_ARCH_MIPS64), nil + case libseccomp.ArchMIPS64N32: + return nativeArch(C.C_AUDIT_ARCH_MIPS64N32), nil + case libseccomp.ArchMIPSEL: + return nativeArch(C.C_AUDIT_ARCH_MIPSEL), nil + case libseccomp.ArchMIPSEL64: + return nativeArch(C.C_AUDIT_ARCH_MIPSEL64), nil + case libseccomp.ArchMIPSEL64N32: + return nativeArch(C.C_AUDIT_ARCH_MIPSEL64N32), nil + case libseccomp.ArchPPC: + return nativeArch(C.C_AUDIT_ARCH_PPC), nil + case libseccomp.ArchPPC64: + return nativeArch(C.C_AUDIT_ARCH_PPC64), nil + case libseccomp.ArchPPC64LE: + return nativeArch(C.C_AUDIT_ARCH_PPC64LE), nil + case libseccomp.ArchS390: + return nativeArch(C.C_AUDIT_ARCH_S390), nil + case libseccomp.ArchS390X: + return nativeArch(C.C_AUDIT_ARCH_S390X), nil + default: + return invalidArch, errors.Errorf("unknown architecture: %v", arch) + } +} + +type lastSyscallMap map[nativeArch]map[libseccomp.ScmpArch]libseccomp.ScmpSyscall + +// Figure out largest syscall number referenced in the filter for each +// architecture. We will be generating code based on the native architecture +// representation, but SCMP_ARCH_X32 means we have to track cases where the +// same architecture has different largest syscalls based on the mode. +func findLastSyscalls(config *configs.Seccomp) (lastSyscallMap, error) { + lastSyscalls := make(lastSyscallMap) + // Only loop over architectures which are present in the filter. Any other + // architectures will get the libseccomp bad architecture action anyway. + for _, ociArch := range config.Architectures { + arch, err := libseccomp.GetArchFromString(ociArch) + if err != nil { + return nil, errors.Wrap(err, "validating seccomp architecture") + } + + // Map native architecture to a real architecture value to avoid + // doubling-up the lastSyscall mapping. + if arch == libseccomp.ArchNative { + nativeArch, err := libseccomp.GetNativeArch() + if err != nil { + return nil, errors.Wrap(err, "get native arch") + } + arch = nativeArch + } + + // Figure out native architecture representation of the architecture. + nativeArch, err := archToNative(arch) + if err != nil { + return nil, errors.Wrapf(err, "cannot map architecture %v to AUDIT_ARCH_ constant", arch) + } + + if _, ok := lastSyscalls[nativeArch]; !ok { + lastSyscalls[nativeArch] = map[libseccomp.ScmpArch]libseccomp.ScmpSyscall{} + } + if _, ok := lastSyscalls[nativeArch][arch]; ok { + // Because of ArchNative we may hit the same entry multiple times. + // Just skip it if we've seen this (nativeArch, ScmpArch) + // combination before. + continue + } + + // Find the largest syscall in the filter for this architecture. + var largestSyscall libseccomp.ScmpSyscall + for _, rule := range config.Syscalls { + sysno, err := libseccomp.GetSyscallFromNameByArch(rule.Name, arch) + if err != nil { + // Ignore unknown syscalls. + continue + } + if sysno > largestSyscall { + largestSyscall = sysno + } + } + if largestSyscall != 0 { + lastSyscalls[nativeArch][arch] = largestSyscall + } else { + logrus.Warnf("could not find any syscalls for arch %s", ociArch) + delete(lastSyscalls[nativeArch], arch) + } + } + return lastSyscalls, nil +} + +// FIXME FIXME FIXME +// +// This solution is less than ideal. In the future it would be great to have +// per-arch information about which syscalls were added in which kernel +// versions so we can create far more accurate filter rules (handling holes in +// the syscall table and determining -ENOSYS requirements based on kernel +// minimum version alone. +// +// This implementation can in principle cause issues with syscalls like +// close_range(2) which were added out-of-order in the syscall table between +// kernel releases. +func generateEnosysStub(lastSyscalls lastSyscallMap) ([]bpf.Instruction, error) { + // A jump-table for each nativeArch used to generate the initial + // conditional jumps -- measured from the *END* of the program so they + // remain valid after prepending to the tail. + archJumpTable := map[nativeArch]uint32{} + + // Generate our own -ENOSYS rules for each architecture. They have to be + // generated in reverse (prepended to the tail of the program) because the + // JumpIf jumps need to be computed from the end of the program. + programTail := []bpf.Instruction{ + // Fall-through rules jump into the filter. + bpf.Jump{Skip: 1}, + // Rules which jump to here get -ENOSYS. + bpf.RetConstant{Val: retErrnoEnosys}, + } + + // Generate the syscall -ENOSYS rules. + for nativeArch, maxSyscalls := range lastSyscalls { + // The number of instructions from the tail of this section which need + // to be jumped in order to reach the -ENOSYS return. If the section + // does not jump, it will fall through to the actual filter. + baseJumpEnosys := uint32(len(programTail) - 1) + baseJumpFilter := baseJumpEnosys + 1 + + // Add the load instruction for the syscall number -- we jump here + // directly from the arch code so we need to do it here. Sadly we can't + // share this code between architecture branches. + section := []bpf.Instruction{ + // load [0] + bpf.LoadAbsolute{Off: 0, Size: 4}, // NOTE: We assume sizeof(int) == 4. + } + + switch len(maxSyscalls) { + case 0: + // No syscalls found for this arch -- skip it and move on. + continue + case 1: + // Get the only syscall in the map. + var sysno libseccomp.ScmpSyscall + for _, no := range maxSyscalls { + sysno = no + } + + // The simplest case just boils down to a single jgt instruction, + // with special handling if baseJumpEnosys is larger than 255 (and + // thus a long jump is required). + var sectionTail []bpf.Instruction + if baseJumpEnosys+1 <= 255 { + sectionTail = []bpf.Instruction{ + // jgt [syscall],[baseJumpEnosys+1] + bpf.JumpIf{ + Cond: bpf.JumpGreaterThan, + Val: uint32(sysno), + SkipTrue: uint8(baseJumpEnosys + 1)}, + // ja [baseJumpFilter] + bpf.Jump{Skip: baseJumpFilter}, + } + } else { + sectionTail = []bpf.Instruction{ + // jle [syscall],1 + bpf.JumpIf{Cond: bpf.JumpLessOrEqual, Val: uint32(sysno), SkipTrue: 1}, + // ja [baseJumpEnosys+1] + bpf.Jump{Skip: baseJumpEnosys + 1}, + // ja [baseJumpFilter] + bpf.Jump{Skip: baseJumpFilter}, + } + } + + // If we're on x86 we need to add a check for x32 and if we're in + // the wrong mode we jump over the section. + if uint32(nativeArch) == uint32(C.C_AUDIT_ARCH_X86_64) { + // Grab the only architecture in the map. + var scmpArch libseccomp.ScmpArch + for arch := range maxSyscalls { + scmpArch = arch + } + + // Generate a prefix to check the mode. + switch scmpArch { + case libseccomp.ArchAMD64: + sectionTail = append([]bpf.Instruction{ + // jset (1<<30),[len(tail)-1] + bpf.JumpIf{Cond: bpf.JumpBitsSet, + Val: 1 << 30, + SkipTrue: uint8(len(sectionTail) - 1)}, + }, sectionTail...) + case libseccomp.ArchX32: + sectionTail = append([]bpf.Instruction{ + // jset (1<<30),0,[len(tail)-1] + bpf.JumpIf{Cond: bpf.JumpBitsNotSet, + Val: 1 << 30, + SkipTrue: uint8(len(sectionTail) - 1)}, + }, sectionTail...) + default: + return nil, errors.Errorf("unknown amd64 native architecture %#x", scmpArch) + } + } + + section = append(section, sectionTail...) + case 2: + // x32 and x86_64 are a unique case, we can't handle any others. + if uint32(nativeArch) != uint32(C.C_AUDIT_ARCH_X86_64) { + return nil, errors.Errorf("unknown architecture overlap on native arch %#x", nativeArch) + } + + x32sysno, ok := maxSyscalls[libseccomp.ArchX32] + if !ok { + return nil, errors.Errorf("missing %v in overlapping x86_64 arch: %v", libseccomp.ArchX32, maxSyscalls) + } + x86sysno, ok := maxSyscalls[libseccomp.ArchAMD64] + if !ok { + return nil, errors.Errorf("missing %v in overlapping x86_64 arch: %v", libseccomp.ArchAMD64, maxSyscalls) + } + + // The x32 ABI indicates that a syscall is being made by an x32 + // process by setting the 30th bit of the syscall number, but we + // need to do some special-casing depending on whether we need to + // do long jumps. + if baseJumpEnosys+2 <= 255 { + // For the simple case we want to have something like: + // jset (1<<30),1 + // jgt [x86 syscall],[baseJumpEnosys+2],1 + // jgt [x32 syscall],[baseJumpEnosys+1] + // ja [baseJumpFilter] + section = append(section, []bpf.Instruction{ + // jset (1<<30),1 + bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: 1 << 30, SkipTrue: 1}, + // jgt [x86 syscall],[baseJumpEnosys+1],1 + bpf.JumpIf{ + Cond: bpf.JumpGreaterThan, + Val: uint32(x86sysno), + SkipTrue: uint8(baseJumpEnosys + 2), SkipFalse: 1}, + // jgt [x32 syscall],[baseJumpEnosys] + bpf.JumpIf{ + Cond: bpf.JumpGreaterThan, + Val: uint32(x32sysno), + SkipTrue: uint8(baseJumpEnosys + 1)}, + // ja [baseJumpFilter] + bpf.Jump{Skip: baseJumpFilter}, + }...) + } else { + // But if the [baseJumpEnosys+2] jump is larger than 255 we + // need to do a long jump like so: + // jset (1<<30),1 + // jgt [x86 syscall],1,2 + // jle [x32 syscall],1 + // ja [baseJumpEnosys+1] + // ja [baseJumpFilter] + section = append(section, []bpf.Instruction{ + // jset (1<<30),1 + bpf.JumpIf{Cond: bpf.JumpBitsSet, Val: 1 << 30, SkipTrue: 1}, + // jgt [x86 syscall],1,2 + bpf.JumpIf{ + Cond: bpf.JumpGreaterThan, + Val: uint32(x86sysno), + SkipTrue: 1, SkipFalse: 2}, + // jle [x32 syscall],[baseJumpEnosys] + bpf.JumpIf{ + Cond: bpf.JumpLessOrEqual, + Val: uint32(x32sysno), + SkipTrue: 1}, + // ja [baseJumpEnosys+1] + bpf.Jump{Skip: baseJumpEnosys + 1}, + // ja [baseJumpFilter] + bpf.Jump{Skip: baseJumpFilter}, + }...) + } + default: + return nil, errors.Errorf("invalid number of architecture overlaps: %v", len(maxSyscalls)) + } + + // Prepend this section to the tail. + programTail = append(section, programTail...) + + // Update jump table. + archJumpTable[nativeArch] = uint32(len(programTail)) + } + + // Add a dummy "jump to filter" for any architecture we might miss below. + // Such architectures will probably get the BadArch action of the filter + // regardless. + programTail = append([]bpf.Instruction{ + // ja [end of stub and start of filter] + bpf.Jump{Skip: uint32(len(programTail))}, + }, programTail...) + + // Generate the jump rules for each architecture. This has to be done in + // reverse as well for the same reason as above. We add to programTail + // directly because the jumps are impacted by each architecture rule we add + // as well. + // + // TODO: Maybe we want to optimise to avoid long jumps here? So sort the + // architectures based on how large the jumps are going to be, or + // re-sort the candidate architectures each time to make sure that we + // pick the largest jump which is going to be smaller than 255. + for nativeArch := range lastSyscalls { + // We jump forwards but the jump table is calculated from the *END*. + jump := uint32(len(programTail)) - archJumpTable[nativeArch] + + // Same routine as above -- this is a basic jeq check, complicated + // slightly if it turns out that we need to do a long jump. + if jump <= 255 { + programTail = append([]bpf.Instruction{ + // jeq [arch],[jump] + bpf.JumpIf{ + Cond: bpf.JumpEqual, + Val: uint32(nativeArch), + SkipTrue: uint8(jump)}, + }, programTail...) + } else { + programTail = append([]bpf.Instruction{ + // jne [arch],1 + bpf.JumpIf{ + Cond: bpf.JumpNotEqual, + Val: uint32(nativeArch), + SkipTrue: 1}, + // ja [jump] + bpf.Jump{Skip: jump}, + }, programTail...) + } + } + + // Prepend the load instruction for the architecture. + programTail = append([]bpf.Instruction{ + // load [4] + bpf.LoadAbsolute{Off: 4, Size: 4}, // NOTE: We assume sizeof(int) == 4. + }, programTail...) + + // And that's all folks! + return programTail, nil +} + +func assemble(program []bpf.Instruction) ([]unix.SockFilter, error) { + rawProgram, err := bpf.Assemble(program) + if err != nil { + return nil, errors.Wrap(err, "assembling program") + } + + // Convert to []unix.SockFilter for unix.SockFilter. + var filter []unix.SockFilter + for _, insn := range rawProgram { + filter = append(filter, unix.SockFilter{ + Code: insn.Op, + Jt: insn.Jt, + Jf: insn.Jf, + K: insn.K, + }) + } + return filter, nil +} + +func generatePatch(config *configs.Seccomp) ([]bpf.Instruction, error) { + // We only add the stub if the default action is not permissive. + if isAllowAction(config.DefaultAction) { + logrus.Debugf("seccomp: skipping -ENOSYS stub filter generation") + return nil, nil + } + + lastSyscalls, err := findLastSyscalls(config) + if err != nil { + return nil, errors.Wrap(err, "finding last syscalls for -ENOSYS stub") + } + stubProgram, err := generateEnosysStub(lastSyscalls) + if err != nil { + return nil, errors.Wrap(err, "generating -ENOSYS stub") + } + return stubProgram, nil +} + +func enosysPatchFilter(config *configs.Seccomp, filter *libseccomp.ScmpFilter) ([]unix.SockFilter, error) { + program, err := disassembleFilter(filter) + if err != nil { + return nil, errors.Wrap(err, "disassembling original filter") + } + + patch, err := generatePatch(config) + if err != nil { + return nil, errors.Wrap(err, "generating patch for filter") + } + fullProgram := append(patch, program...) + + logrus.Debugf("seccomp: prepending -ENOSYS stub filter to user filter...") + for idx, insn := range patch { + logrus.Debugf(" [%4.1d] %s", idx, insn) + } + logrus.Debugf(" [....] --- original filter ---") + + fprog, err := assemble(fullProgram) + if err != nil { + return nil, errors.Wrap(err, "assembling modified filter") + } + return fprog, nil +} + +func filterFlags(filter *libseccomp.ScmpFilter) (flags uint, noNewPrivs bool, err error) { + // Ignore the error since pre-2.4 libseccomp is treated as API level 0. + apiLevel, _ := libseccomp.GetApi() + + noNewPrivs, err = filter.GetNoNewPrivsBit() + if err != nil { + return 0, false, errors.Wrap(err, "fetch no_new_privs filter bit") + } + + if apiLevel >= 3 { + if logBit, err := filter.GetLogBit(); err != nil { + return 0, false, errors.Wrap(err, "fetch SECCOMP_FILTER_FLAG_LOG bit") + } else if logBit { + flags |= uint(C.C_FILTER_FLAG_LOG) + } + } + + // TODO: Support seccomp flags not yet added to libseccomp-golang... + return +} + +func sysSeccompSetFilter(flags uint, filter []unix.SockFilter) (err error) { + fprog := unix.SockFprog{ + Len: uint16(len(filter)), + Filter: &filter[0], + } + // If no seccomp flags were requested we can use the old-school prctl(2). + if flags == 0 { + err = unix.Prctl(unix.PR_SET_SECCOMP, + unix.SECCOMP_MODE_FILTER, + uintptr(unsafe.Pointer(&fprog)), 0, 0) + } else { + _, _, err = unix.RawSyscall(unix.SYS_SECCOMP, + uintptr(C.C_SET_MODE_FILTER), + uintptr(flags), uintptr(unsafe.Pointer(&fprog))) + } + runtime.KeepAlive(filter) + runtime.KeepAlive(fprog) + return +} + +// PatchAndLoad takes a seccomp configuration and a libseccomp filter which has +// been pre-configured with the set of rules in the seccomp config. It then +// patches said filter to handle -ENOSYS in a much nicer manner than the +// default libseccomp default action behaviour, and loads the patched filter +// into the kernel for the current process. +func PatchAndLoad(config *configs.Seccomp, filter *libseccomp.ScmpFilter) error { + // Generate a patched filter. + fprog, err := enosysPatchFilter(config, filter) + if err != nil { + return errors.Wrap(err, "patching filter") + } + + // Get the set of libseccomp flags set. + seccompFlags, noNewPrivs, err := filterFlags(filter) + if err != nil { + return errors.Wrap(err, "fetch seccomp filter flags") + } + + // Set no_new_privs if it was requested, though in runc we handle + // no_new_privs separately so warn if we hit this path. + if noNewPrivs { + logrus.Warnf("potentially misconfigured filter -- setting no_new_privs in seccomp path") + if err := unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil { + return errors.Wrap(err, "enable no_new_privs bit") + } + } + + // Finally, load the filter. + if err := sysSeccompSetFilter(seccompFlags, fprog); err != nil { + return errors.Wrap(err, "loading seccomp filter") + } + return nil +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_unsupported.go new file mode 100644 index 00000000000..682131e49cc --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/patchbpf/enosys_unsupported.go @@ -0,0 +1,3 @@ +// +build !linux !cgo !seccomp + +package patchbpf diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go index 73ddf3d1827..5e7b365c563 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go @@ -10,8 +10,9 @@ import ( "strings" "github.com/opencontainers/runc/libcontainer/configs" - libseccomp "github.com/seccomp/libseccomp-golang" + "github.com/opencontainers/runc/libcontainer/seccomp/patchbpf" + libseccomp "github.com/seccomp/libseccomp-golang" "golang.org/x/sys/unix" ) @@ -54,7 +55,6 @@ func InitSeccomp(config *configs.Seccomp) error { if err != nil { return fmt.Errorf("error validating Seccomp architecture: %s", err) } - if err := filter.AddArch(scmpArch); err != nil { return fmt.Errorf("error adding architecture to seccomp filter: %s", err) } @@ -70,16 +70,13 @@ func InitSeccomp(config *configs.Seccomp) error { if call == nil { return errors.New("encountered nil syscall while initializing Seccomp") } - - if err = matchCall(filter, call); err != nil { + if err := matchCall(filter, call); err != nil { return err } } - - if err = filter.Load(); err != nil { + if err := patchbpf.PatchAndLoad(config, filter); err != nil { return fmt.Errorf("error loading seccomp filter into kernel: %s", err) } - return nil } @@ -190,7 +187,7 @@ func matchCall(filter *libseccomp.ScmpFilter, call *configs.Syscall) error { // Unconditional match - just add the rule if len(call.Args) == 0 { - if err = filter.AddRule(callNum, callAct); err != nil { + if err := filter.AddRule(callNum, callAct); err != nil { return fmt.Errorf("error adding seccomp filter rule for syscall %s: %s", call.Name, err) } } else { @@ -224,14 +221,14 @@ func matchCall(filter *libseccomp.ScmpFilter, call *configs.Syscall) error { for _, cond := range conditions { condArr := []libseccomp.ScmpCondition{cond} - if err = filter.AddRuleConditional(callNum, callAct, condArr); err != nil { + if err := filter.AddRuleConditional(callNum, callAct, condArr); err != nil { return fmt.Errorf("error adding seccomp rule for syscall %s: %s", call.Name, err) } } } else { // No conditions share same argument // Use new, proper behavior - if err = filter.AddRuleConditional(callNum, callAct, conditions); err != nil { + if err := filter.AddRuleConditional(callNum, callAct, conditions); err != nil { return fmt.Errorf("error adding seccomp rule for syscall %s: %s", call.Name, err) } } @@ -266,3 +263,8 @@ func parseStatusFile(path string) (map[string]string, error) { return status, nil } + +// Version returns major, minor, and micro. +func Version() (uint, uint, uint) { + return libseccomp.GetLibraryVersion() +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go index 44df1ad4c26..244886a42e5 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_unsupported.go @@ -22,3 +22,8 @@ func InitSeccomp(config *configs.Seccomp) error { func IsEnabled() bool { return false } + +// Version returns major, minor, and micro. +func Version() (uint, uint, uint) { + return 0, 0, 0 +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go index 0b9cd885208..6b1e9a6e97c 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/setns_init_linux.go @@ -3,7 +3,6 @@ package libcontainer import ( - "fmt" "os" "runtime" @@ -25,7 +24,7 @@ type linuxSetnsInit struct { } func (l *linuxSetnsInit) getSessionRingName() string { - return fmt.Sprintf("_ses.%s", l.config.ContainerId) + return "_ses." + l.config.ContainerId } func (l *linuxSetnsInit) Init() error { diff --git a/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go index b20ce1485f8..7ec506c462e 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/standard_init_linux.go @@ -3,10 +3,10 @@ package libcontainer import ( - "fmt" "os" "os/exec" "runtime" + "strconv" "github.com/opencontainers/runc/libcontainer/apparmor" "github.com/opencontainers/runc/libcontainer/configs" @@ -40,7 +40,7 @@ func (l *linuxStandardInit) getSessionRingParams() (string, uint32, uint32) { // Create a unique per session container name that we can join in setns; // However, other containers can also join it. - return fmt.Sprintf("_ses.%s", l.config.ContainerId), 0xffffffff, newperms + return "_ses." + l.config.ContainerId, 0xffffffff, newperms } func (l *linuxStandardInit) Init() error { @@ -185,7 +185,7 @@ func (l *linuxStandardInit) Init() error { // user process. We open it through /proc/self/fd/$fd, because the fd that // was given to us was an O_PATH fd to the fifo itself. Linux allows us to // re-open an O_PATH fd through /proc. - fd, err := unix.Open(fmt.Sprintf("/proc/self/fd/%d", l.fifoFd), unix.O_WRONLY|unix.O_CLOEXEC, 0) + fd, err := unix.Open("/proc/self/fd/"+strconv.Itoa(l.fifoFd), unix.O_WRONLY|unix.O_CLOEXEC, 0) if err != nil { return newSystemErrorWithCause(err, "open exec fifo") } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go index 0deb22d1f94..02ff06ea9cc 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/state_linux.go @@ -38,7 +38,8 @@ type containerState interface { } func destroy(c *linuxContainer) error { - if !c.config.Namespaces.Contains(configs.NEWPID) { + if !c.config.Namespaces.Contains(configs.NEWPID) || + c.config.Namespaces.PathOf(configs.NEWPID) != "" { if err := signalAllProcesses(c.cgroupManager, unix.SIGKILL); err != nil { logrus.Warn(err) } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go b/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go index 79232a43715..b73cf70b434 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go @@ -71,16 +71,6 @@ func Stat(pid int) (stat Stat_t, err error) { return parseStat(string(bytes)) } -// GetProcessStartTime is deprecated. Use Stat(pid) and -// Stat_t.StartTime instead. -func GetProcessStartTime(pid int) (string, error) { - stat, err := Stat(pid) - if err != nil { - return "", err - } - return fmt.Sprintf("%d", stat.StartTime), nil -} - func parseStat(data string) (stat Stat_t, err error) { // From proc(5), field 2 could contain space and is inside `(` and `)`. // The following is an example: diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go index 65cd40e9287..f19333e61eb 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go @@ -3,8 +3,8 @@ package user import ( - "fmt" "os/user" + "strconv" ) func lookupUser(username string) (User, error) { @@ -16,7 +16,7 @@ func lookupUser(username string) (User, error) { } func lookupUid(uid int) (User, error) { - u, err := user.LookupId(fmt.Sprintf("%d", uid)) + u, err := user.LookupId(strconv.Itoa(uid)) if err != nil { return User{}, err } @@ -32,7 +32,7 @@ func lookupGroup(groupname string) (Group, error) { } func lookupGid(gid int) (Group, error) { - g, err := user.LookupGroupId(fmt.Sprintf("%d", gid)) + g, err := user.LookupGroupId(strconv.Itoa(gid)) if err != nil { return Group{}, err } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go index 4b89dad7376..a533bf5e668 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go @@ -466,7 +466,7 @@ func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, err // we asked for a group but didn't find it. let's check to see // if we wanted a numeric group if !found { - gid, err := strconv.Atoi(ag) + gid, err := strconv.ParseInt(ag, 10, 64) if err != nil { return nil, fmt.Errorf("Unable to find group %s", ag) } @@ -474,7 +474,7 @@ func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, err if gid < minId || gid > maxId { return nil, ErrRange } - gidMap[gid] = struct{}{} + gidMap[int(gid)] = struct{}{} } } gids := []int{} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go b/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go index 40ccfaa1a01..1b72b7a1c1b 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go @@ -1,6 +1,7 @@ package utils import ( + "encoding/binary" "encoding/json" "io" "os" @@ -15,6 +16,20 @@ const ( exitSignalOffset = 128 ) +// NativeEndian is the native byte order of the host system. +var NativeEndian binary.ByteOrder + +func init() { + // Copied from . + i := uint32(1) + b := (*[4]byte)(unsafe.Pointer(&i)) + if b[0] == 1 { + NativeEndian = binary.LittleEndian + } else { + NativeEndian = binary.BigEndian + } +} + // ResolveRootfs ensures that the current working directory is // not a symlink and returns the absolute path to the rootfs func ResolveRootfs(uncleanRootfs string) (string, error) { @@ -106,7 +121,3 @@ func Annotations(labels []string) (bundle string, userAnnotations map[string]str } return } - -func GetIntSize() int { - return int(unsafe.Sizeof(1)) -} diff --git a/vendor/github.com/opencontainers/runc/types/events.go b/vendor/github.com/opencontainers/runc/types/events.go index 6f9a12f1596..81bde829da5 100644 --- a/vendor/github.com/opencontainers/runc/types/events.go +++ b/vendor/github.com/opencontainers/runc/types/events.go @@ -12,6 +12,7 @@ type Event struct { // stats is the runc specific stats structure for stability when encoding and decoding stats. type Stats struct { CPU Cpu `json:"cpu"` + CPUSet CPUSet `json:"cpuset"` Memory Memory `json:"memory"` Pids Pids `json:"pids"` Blkio Blkio `json:"blkio"` @@ -70,6 +71,20 @@ type Cpu struct { Throttling Throttling `json:"throttling,omitempty"` } +type CPUSet struct { + CPUs []uint16 `json:"cpus,omitempty"` + CPUExclusive uint64 `json:"cpu_exclusive"` + Mems []uint16 `json:"mems,omitempty"` + MemHardwall uint64 `json:"mem_hardwall"` + MemExclusive uint64 `json:"mem_exclusive"` + MemoryMigrate uint64 `json:"memory_migrate"` + MemorySpreadPage uint64 `json:"memory_spread_page"` + MemorySpreadSlab uint64 `json:"memory_spread_slab"` + MemoryPressure uint64 `json:"memory_pressure"` + SchedLoadBalance uint64 `json:"sched_load_balance"` + SchedRelaxDomainLevel int64 `json:"sched_relax_domain_level"` +} + type MemoryEntry struct { Limit uint64 `json:"limit"` Usage uint64 `json:"usage,omitempty"` diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go index 3dc9efd23e6..5fceeb63533 100644 --- a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go +++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go @@ -60,7 +60,7 @@ type Process struct { SelinuxLabel string `json:"selinuxLabel,omitempty" platform:"linux"` } -// LinuxCapabilities specifies the whitelist of capabilities that are kept for a process. +// LinuxCapabilities specifies the list of allowed capabilities that are kept for a process. // http://man7.org/linux/man-pages/man7/capabilities.7.html type LinuxCapabilities struct { // Bounding is the set of capabilities checked by the kernel. @@ -354,7 +354,7 @@ type LinuxRdma struct { // LinuxResources has container runtime resource constraints type LinuxResources struct { - // Devices configures the device whitelist. + // Devices configures the device allowlist. Devices []LinuxDeviceCgroup `json:"devices,omitempty"` // Memory restriction configuration Memory *LinuxMemory `json:"memory,omitempty"` @@ -372,6 +372,8 @@ type LinuxResources struct { // Limits are a set of key value pairs that define RDMA resource limits, // where the key is device name and value is resource limits. Rdma map[string]LinuxRdma `json:"rdma,omitempty"` + // Unified resources. + Unified map[string]string `json:"unified,omitempty"` } // LinuxDevice represents the mknod information for a Linux special device file @@ -392,7 +394,8 @@ type LinuxDevice struct { GID *uint32 `json:"gid,omitempty"` } -// LinuxDeviceCgroup represents a device rule for the whitelist controller +// LinuxDeviceCgroup represents a device rule for the devices specified to +// the device controller type LinuxDeviceCgroup struct { // Allow or deny Allow bool `json:"allow"` @@ -628,6 +631,7 @@ const ( ArchS390X Arch = "SCMP_ARCH_S390X" ArchPARISC Arch = "SCMP_ARCH_PARISC" ArchPARISC64 Arch = "SCMP_ARCH_PARISC64" + ArchRISCV64 Arch = "SCMP_ARCH_RISCV64" ) // LinuxSeccompAction taken upon Seccomp rule match diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/doc.go b/vendor/github.com/opencontainers/selinux/go-selinux/doc.go index 79a8e6446db..9c9cbd120aa 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/doc.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/doc.go @@ -5,9 +5,6 @@ This package uses a selinux build tag to enable the selinux functionality. This allows non-linux and linux users who do not have selinux support to still use tools that rely on this library. -To compile with full selinux support use the -tags=selinux option in your build -and test commands. - Usage: import "github.com/opencontainers/selinux/go-selinux" diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go similarity index 98% rename from vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go rename to vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go index 10ac15a8524..43945551172 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go @@ -1,5 +1,3 @@ -// +build selinux,linux - package label import ( @@ -27,14 +25,14 @@ var ErrIncompatibleLabel = errors.New("Bad SELinux option z and Z can not be use // the container. A list of options can be passed into this function to alter // the labels. The labels returned will include a random MCS String, that is // guaranteed to be unique. -func InitLabels(options []string) (plabel string, mlabel string, Err error) { +func InitLabels(options []string) (plabel string, mlabel string, retErr error) { if !selinux.GetEnabled() { return "", "", nil } processLabel, mountLabel := selinux.ContainerLabels() if processLabel != "" { defer func() { - if Err != nil { + if retErr != nil { selinux.ReleaseLabel(mountLabel) } }() @@ -57,7 +55,6 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) { con := strings.SplitN(opt, ":", 2) if !validOptions[con[0]] { return "", "", errors.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0]) - } if con[0] == "filetype" { mcon["type"] = con[1] diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go index a7d2d5e342b..02d206239c7 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go @@ -1,4 +1,4 @@ -// +build !selinux !linux +// +build !linux package label diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go index 50760dc93e7..d9119908b78 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go @@ -30,6 +30,11 @@ var ( // ErrLevelSyntax is returned when a sensitivity or category do not have correct syntax in a level ErrLevelSyntax = errors.New("invalid level syntax") + // ErrContextMissing is returned if a requested context is not found in a file. + ErrContextMissing = errors.New("context does not have a match") + // ErrVerifierNil is returned when a context verifier function is nil. + ErrVerifierNil = errors.New("verifier function is nil") + // CategoryRange allows the upper bound on the category range to be adjusted CategoryRange = DefaultCategoryRange ) @@ -63,8 +68,12 @@ func FileLabel(fpath string) (string, error) { return fileLabel(fpath) } -// SetFSCreateLabel tells kernel the label to create all file system objects -// created by this task. Setting label="" to return to default. +// SetFSCreateLabel tells the kernel what label to use for all file system objects +// created by this task. +// Set the label to an empty string to return to the default label. Calls to SetFSCreateLabel +// should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until file system +// objects created by this task are finished to guarantee another goroutine does not migrate +// to the current thread before execution is complete. func SetFSCreateLabel(label string) error { return setFSCreateLabel(label) } @@ -113,19 +122,27 @@ func CalculateGlbLub(sourceRange, targetRange string) (string, error) { } // SetExecLabel sets the SELinux label that the kernel will use for any programs -// that are executed by the current process thread, or an error. +// that are executed by the current process thread, or an error. Calls to SetExecLabel +// should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until execution +// of the program is finished to guarantee another goroutine does not migrate to the current +// thread before execution is complete. func SetExecLabel(label string) error { return setExecLabel(label) } // SetTaskLabel sets the SELinux label for the current thread, or an error. -// This requires the dyntransition permission. +// This requires the dyntransition permission. Calls to SetTaskLabel should +// be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() to guarantee +// the current thread does not run in a new mislabeled thread. func SetTaskLabel(label string) error { return setTaskLabel(label) } // SetSocketLabel takes a process label and tells the kernel to assign the -// label to the next socket that gets created +// label to the next socket that gets created. Calls to SetSocketLabel +// should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until +// the the socket is created to guarantee another goroutine does not migrate +// to the current thread before execution is complete. func SetSocketLabel(label string) error { return setSocketLabel(label) } @@ -141,7 +158,10 @@ func PeerLabel(fd uintptr) (string, error) { } // SetKeyLabel takes a process label and tells the kernel to assign the -// label to the next kernel keyring that gets created +// label to the next kernel keyring that gets created. Calls to SetKeyLabel +// should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until +// the kernel keyring is created to guarantee another goroutine does not migrate +// to the current thread before execution is complete. func SetKeyLabel(label string) error { return setKeyLabel(label) } @@ -247,3 +267,12 @@ func DupSecOpt(src string) ([]string, error) { func DisableSecOpt() []string { return disableSecOpt() } + +// GetDefaultContextWithLevel gets a single context for the specified SELinux user +// identity that is reachable from the specified scon context. The context is based +// on the per-user /etc/selinux/{SELINUXTYPE}/contexts/users/ if it exists, +// and falls back to the global /etc/selinux/{SELINUXTYPE}/contexts/default_contexts +// file. +func GetDefaultContextWithLevel(user, level, scon string) (string, error) { + return getDefaultContextWithLevel(user, level, scon) +} diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go index d6b0d49db65..5bfcc049026 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go @@ -1,5 +1,3 @@ -// +build selinux,linux - package selinux import ( @@ -28,6 +26,8 @@ const ( minSensLen = 2 contextFile = "/usr/share/containers/selinux/contexts" selinuxDir = "/etc/selinux/" + selinuxUsersDir = "contexts/users" + defaultContexts = "contexts/default_contexts" selinuxConfig = selinuxDir + "config" selinuxfsMount = "/sys/fs/selinux" selinuxTypeTag = "SELINUXTYPE" @@ -35,6 +35,8 @@ const ( xattrNameSelinux = "security.selinux" ) +var policyRoot = filepath.Join(selinuxDir, readConfig(selinuxTypeTag)) + type selinuxState struct { enabledSet bool enabled bool @@ -54,6 +56,13 @@ type mlsRange struct { high *level } +type defaultSECtx struct { + user, level, scon string + userRdr, defaultRdr io.Reader + + verifier func(string) error +} + type levelItem byte const ( @@ -111,7 +120,7 @@ func verifySELinuxfsMount(mnt string) bool { if err == nil { break } - if err == unix.EAGAIN { + if err == unix.EAGAIN || err == unix.EINTR { continue } return false @@ -205,28 +214,16 @@ func getEnabled() bool { } func readConfig(target string) string { - var ( - val, key string - bufin *bufio.Reader - ) - in, err := os.Open(selinuxConfig) if err != nil { return "" } defer in.Close() - bufin = bufio.NewReader(in) + scanner := bufio.NewScanner(in) - for done := false; !done; { - var line string - if line, err = bufin.ReadString('\n'); err != nil { - if err != io.EOF { - return "" - } - done = true - } - line = strings.TrimSpace(line) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) if len(line) == 0 { // Skip blank lines continue @@ -236,7 +233,7 @@ func readConfig(target string) string { continue } if groups := assignRegex.FindStringSubmatch(line); groups != nil { - key, val = strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2]) + key, val := strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2]) if key == target { return strings.Trim(val, "\"") } @@ -245,15 +242,17 @@ func readConfig(target string) string { return "" } -func getSELinuxPolicyRoot() string { - return filepath.Join(selinuxDir, readConfig(selinuxTypeTag)) -} - func isProcHandle(fh *os.File) error { var buf unix.Statfs_t - err := unix.Fstatfs(int(fh.Fd()), &buf) - if err != nil { - return errors.Wrapf(err, "statfs(%q) failed", fh.Name()) + + for { + err := unix.Fstatfs(int(fh.Fd()), &buf) + if err == nil { + break + } + if err != unix.EINTR { + return errors.Wrapf(err, "statfs(%q) failed", fh.Name()) + } } if buf.Type != unix.PROC_SUPER_MAGIC { return errors.Errorf("file %q is not on procfs", fh.Name()) @@ -307,9 +306,16 @@ func setFileLabel(fpath string, label string) error { if fpath == "" { return ErrEmptyPath } - if err := unix.Lsetxattr(fpath, xattrNameSelinux, []byte(label), 0); err != nil { - return errors.Wrapf(err, "failed to set file label on %s", fpath) + for { + err := unix.Lsetxattr(fpath, xattrNameSelinux, []byte(label), 0) + if err == nil { + break + } + if err != unix.EINTR { + return errors.Wrapf(err, "failed to set file label on %s", fpath) + } } + return nil } @@ -751,7 +757,7 @@ func reserveLabel(label string) { if len(label) != 0 { con := strings.SplitN(label, ":", 4) if len(con) > 3 { - mcsAdd(con[3]) + _ = mcsAdd(con[3]) } } } @@ -828,11 +834,11 @@ func intToMcs(id int, catRange uint32) string { } for ORD > TIER { - ORD = ORD - TIER + ORD -= TIER TIER-- } TIER = SETSIZE - TIER - ORD = ORD + TIER + ORD += TIER return fmt.Sprintf("s0:c%d,c%d", TIER, ORD) } @@ -844,16 +850,14 @@ func uniqMcs(catRange uint32) string { ) for { - binary.Read(rand.Reader, binary.LittleEndian, &n) + _ = binary.Read(rand.Reader, binary.LittleEndian, &n) c1 = n % catRange - binary.Read(rand.Reader, binary.LittleEndian, &n) + _ = binary.Read(rand.Reader, binary.LittleEndian, &n) c2 = n % catRange if c1 == c2 { continue - } else { - if c1 > c2 { - c1, c2 = c2, c1 - } + } else if c1 > c2 { + c1, c2 = c2, c1 } mcs = fmt.Sprintf("s0:c%d,c%d", c1, c2) if err := mcsAdd(mcs); err != nil { @@ -884,18 +888,13 @@ func openContextFile() (*os.File, error) { if f, err := os.Open(contextFile); err == nil { return f, nil } - lxcPath := filepath.Join(getSELinuxPolicyRoot(), "/contexts/lxc_contexts") + lxcPath := filepath.Join(policyRoot, "/contexts/lxc_contexts") return os.Open(lxcPath) } var labels = loadLabels() func loadLabels() map[string]string { - var ( - val, key string - bufin *bufio.Reader - ) - labels := make(map[string]string) in, err := openContextFile() if err != nil { @@ -903,18 +902,10 @@ func loadLabels() map[string]string { } defer in.Close() - bufin = bufio.NewReader(in) + scanner := bufio.NewScanner(in) - for done := false; !done; { - var line string - if line, err = bufin.ReadString('\n'); err != nil { - if err == io.EOF { - done = true - } else { - break - } - } - line = strings.TrimSpace(line) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) if len(line) == 0 { // Skip blank lines continue @@ -924,7 +915,7 @@ func loadLabels() map[string]string { continue } if groups := assignRegex.FindStringSubmatch(line); groups != nil { - key, val = strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2]) + key, val := strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2]) labels[key] = strings.Trim(val, "\"") } } @@ -1015,7 +1006,7 @@ func copyLevel(src, dest string) (string, error) { return "", err } mcsDelete(tcon["level"]) - mcsAdd(scon["level"]) + _ = mcsAdd(scon["level"]) tcon["level"] = scon["level"] return tcon.Get(), nil } @@ -1095,3 +1086,124 @@ func dupSecOpt(src string) ([]string, error) { func disableSecOpt() []string { return []string{"disable"} } + +// findUserInContext scans the reader for a valid SELinux context +// match that is verified with the verifier. Invalid contexts are +// skipped. It returns a matched context or an empty string if no +// match is found. If a scanner error occurs, it is returned. +func findUserInContext(context Context, r io.Reader, verifier func(string) error) (string, error) { + fromRole := context["role"] + fromType := context["type"] + scanner := bufio.NewScanner(r) + + for scanner.Scan() { + fromConns := strings.Fields(scanner.Text()) + if len(fromConns) == 0 { + // Skip blank lines + continue + } + + line := fromConns[0] + + if line[0] == ';' || line[0] == '#' { + // Skip comments + continue + } + + // user context files contexts are formatted as + // role_r:type_t:s0 where the user is missing. + lineArr := strings.SplitN(line, ":", 4) + // skip context with typo, or role and type do not match + if len(lineArr) != 3 || + lineArr[0] != fromRole || + lineArr[1] != fromType { + continue + } + + for _, cc := range fromConns[1:] { + toConns := strings.SplitN(cc, ":", 4) + if len(toConns) != 3 { + continue + } + + context["role"] = toConns[0] + context["type"] = toConns[1] + + outConn := context.get() + if err := verifier(outConn); err != nil { + continue + } + + return outConn, nil + } + } + + if err := scanner.Err(); err != nil { + return "", errors.Wrap(err, "failed to scan for context") + } + + return "", nil +} + +func getDefaultContextFromReaders(c *defaultSECtx) (string, error) { + if c.verifier == nil { + return "", ErrVerifierNil + } + + context, err := newContext(c.scon) + if err != nil { + return "", errors.Wrapf(err, "failed to create label for %s", c.scon) + } + + // set so the verifier validates the matched context with the provided user and level. + context["user"] = c.user + context["level"] = c.level + + conn, err := findUserInContext(context, c.userRdr, c.verifier) + if err != nil { + return "", err + } + + if conn != "" { + return conn, nil + } + + conn, err = findUserInContext(context, c.defaultRdr, c.verifier) + if err != nil { + return "", err + } + + if conn != "" { + return conn, nil + } + + return "", errors.Wrapf(ErrContextMissing, "context not found: %q", c.scon) +} + +func getDefaultContextWithLevel(user, level, scon string) (string, error) { + userPath := filepath.Join(policyRoot, selinuxUsersDir, user) + defaultPath := filepath.Join(policyRoot, defaultContexts) + + fu, err := os.Open(userPath) + if err != nil { + return "", err + } + defer fu.Close() + + fd, err := os.Open(defaultPath) + if err != nil { + return "", err + } + defer fd.Close() + + c := defaultSECtx{ + user: user, + level: level, + scon: scon, + userRdr: fu, + defaultRdr: fd, + verifier: securityCheckContext, + } + + return getDefaultContextFromReaders(&c) +} diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go index c526b210f9c..70b7b7c8519 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go @@ -1,4 +1,4 @@ -// +build !selinux !linux +// +build !linux package selinux @@ -146,3 +146,7 @@ func dupSecOpt(src string) ([]string, error) { func disableSecOpt() []string { return []string{"disable"} } + +func getDefaultContextWithLevel(user, level, scon string) (string, error) { + return "", nil +} diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go deleted file mode 100644 index de5c80ef3a9..00000000000 --- a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build selinux,linux - -package selinux - -import ( - "golang.org/x/sys/unix" -) - -// Returns a []byte slice if the xattr is set and nil otherwise -// Requires path and its attribute as arguments -func lgetxattr(path string, attr string) ([]byte, error) { - // Start with a 128 length byte array - dest := make([]byte, 128) - sz, errno := unix.Lgetxattr(path, attr, dest) - for errno == unix.ERANGE { - // Buffer too small, use zero-sized buffer to get the actual size - sz, errno = unix.Lgetxattr(path, attr, []byte{}) - if errno != nil { - return nil, errno - } - - dest = make([]byte, sz) - sz, errno = unix.Lgetxattr(path, attr, dest) - } - if errno != nil { - return nil, errno - } - - return dest[:sz], nil -} diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go new file mode 100644 index 00000000000..117c255be20 --- /dev/null +++ b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go @@ -0,0 +1,38 @@ +package selinux + +import ( + "golang.org/x/sys/unix" +) + +// lgetxattr returns a []byte slice containing the value of +// an extended attribute attr set for path. +func lgetxattr(path, attr string) ([]byte, error) { + // Start with a 128 length byte array + dest := make([]byte, 128) + sz, errno := doLgetxattr(path, attr, dest) + for errno == unix.ERANGE { + // Buffer too small, use zero-sized buffer to get the actual size + sz, errno = doLgetxattr(path, attr, []byte{}) + if errno != nil { + return nil, errno + } + + dest = make([]byte, sz) + sz, errno = doLgetxattr(path, attr, dest) + } + if errno != nil { + return nil, errno + } + + return dest[:sz], nil +} + +// doLgetxattr is a wrapper that retries on EINTR +func doLgetxattr(path, attr string, dest []byte) (int, error) { + for { + sz, err := unix.Lgetxattr(path, attr, dest) + if err != unix.EINTR { + return sz, err + } + } +} diff --git a/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go b/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go index 63fde18429a..437b12b3e28 100644 --- a/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go +++ b/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go @@ -20,17 +20,16 @@ type WalkFunc = filepath.WalkFunc // // Note that this implementation only supports primitive error handling: // -// * no errors are ever passed to WalkFn +// - no errors are ever passed to WalkFn; // -// * once a walkFn returns any error, all further processing stops -// and the error is returned to the caller of Walk; +// - once a walkFn returns any error, all further processing stops +// and the error is returned to the caller of Walk; // -// * filepath.SkipDir is not supported; -// -// * if more than one walkFn instance will return an error, only one -// of such errors will be propagated and returned by Walk, others -// will be silently discarded. +// - filepath.SkipDir is not supported; // +// - if more than one walkFn instance will return an error, only one +// of such errors will be propagated and returned by Walk, others +// will be silently discarded. func Walk(root string, walkFn WalkFunc) error { return WalkN(root, walkFn, runtime.NumCPU()*2) } @@ -38,6 +37,8 @@ func Walk(root string, walkFn WalkFunc) error { // WalkN is a wrapper for filepath.Walk which can call multiple walkFn // in parallel, allowing to handle each item concurrently. A maximum of // num walkFn will be called at any one time. +// +// Please see Walk documentation for caveats of using this function. func WalkN(root string, walkFn WalkFunc, num int) error { // make sure limit is sensible if num < 1 { diff --git a/vendor/github.com/sirupsen/logrus/.gitignore b/vendor/github.com/sirupsen/logrus/.gitignore index 6b7d7d1e8b9..1fb13abebe7 100644 --- a/vendor/github.com/sirupsen/logrus/.gitignore +++ b/vendor/github.com/sirupsen/logrus/.gitignore @@ -1,2 +1,4 @@ logrus vendor + +.idea/ diff --git a/vendor/github.com/sirupsen/logrus/buffer_pool.go b/vendor/github.com/sirupsen/logrus/buffer_pool.go new file mode 100644 index 00000000000..4545dec07d8 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/buffer_pool.go @@ -0,0 +1,52 @@ +package logrus + +import ( + "bytes" + "sync" +) + +var ( + bufferPool BufferPool +) + +type BufferPool interface { + Put(*bytes.Buffer) + Get() *bytes.Buffer +} + +type defaultPool struct { + pool *sync.Pool +} + +func (p *defaultPool) Put(buf *bytes.Buffer) { + p.pool.Put(buf) +} + +func (p *defaultPool) Get() *bytes.Buffer { + return p.pool.Get().(*bytes.Buffer) +} + +func getBuffer() *bytes.Buffer { + return bufferPool.Get() +} + +func putBuffer(buf *bytes.Buffer) { + buf.Reset() + bufferPool.Put(buf) +} + +// SetBufferPool allows to replace the default logrus buffer pool +// to better meets the specific needs of an application. +func SetBufferPool(bp BufferPool) { + bufferPool = bp +} + +func init() { + SetBufferPool(&defaultPool{ + pool: &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, + }, + }) +} diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go index f6e062a3466..5a5cbfe7c89 100644 --- a/vendor/github.com/sirupsen/logrus/entry.go +++ b/vendor/github.com/sirupsen/logrus/entry.go @@ -13,7 +13,6 @@ import ( ) var ( - bufferPool *sync.Pool // qualified package name, cached at first use logrusPackage string @@ -31,12 +30,6 @@ const ( ) func init() { - bufferPool = &sync.Pool{ - New: func() interface{} { - return new(bytes.Buffer) - }, - } - // start at the bottom of the stack before the package-name cache is primed minimumCallerDepth = 1 } @@ -243,9 +236,12 @@ func (entry Entry) log(level Level, msg string) { entry.fireHooks() - buffer = bufferPool.Get().(*bytes.Buffer) + buffer = getBuffer() + defer func() { + entry.Buffer = nil + putBuffer(buffer) + }() buffer.Reset() - defer bufferPool.Put(buffer) entry.Buffer = buffer entry.write() diff --git a/vendor/github.com/sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go index 42b04f6c809..017c30ce678 100644 --- a/vendor/github.com/sirupsen/logrus/exported.go +++ b/vendor/github.com/sirupsen/logrus/exported.go @@ -134,6 +134,51 @@ func Fatal(args ...interface{}) { std.Fatal(args...) } +// TraceFn logs a message from a func at level Trace on the standard logger. +func TraceFn(fn LogFunction) { + std.TraceFn(fn) +} + +// DebugFn logs a message from a func at level Debug on the standard logger. +func DebugFn(fn LogFunction) { + std.DebugFn(fn) +} + +// PrintFn logs a message from a func at level Info on the standard logger. +func PrintFn(fn LogFunction) { + std.PrintFn(fn) +} + +// InfoFn logs a message from a func at level Info on the standard logger. +func InfoFn(fn LogFunction) { + std.InfoFn(fn) +} + +// WarnFn logs a message from a func at level Warn on the standard logger. +func WarnFn(fn LogFunction) { + std.WarnFn(fn) +} + +// WarningFn logs a message from a func at level Warn on the standard logger. +func WarningFn(fn LogFunction) { + std.WarningFn(fn) +} + +// ErrorFn logs a message from a func at level Error on the standard logger. +func ErrorFn(fn LogFunction) { + std.ErrorFn(fn) +} + +// PanicFn logs a message from a func at level Panic on the standard logger. +func PanicFn(fn LogFunction) { + std.PanicFn(fn) +} + +// FatalFn logs a message from a func at level Fatal on the standard logger then the process will exit with status set to 1. +func FatalFn(fn LogFunction) { + std.FatalFn(fn) +} + // Tracef logs a message at level Trace on the standard logger. func Tracef(format string, args ...interface{}) { std.Tracef(format, args...) diff --git a/vendor/github.com/sirupsen/logrus/go.mod b/vendor/github.com/sirupsen/logrus/go.mod index d41329679f8..b3919d5eabf 100644 --- a/vendor/github.com/sirupsen/logrus/go.mod +++ b/vendor/github.com/sirupsen/logrus/go.mod @@ -2,10 +2,9 @@ module github.com/sirupsen/logrus require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/konsorten/go-windows-terminal-sequences v1.0.3 github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/testify v1.2.2 - golang.org/x/sys v0.0.0-20190422165155-953cdadca894 + golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 ) go 1.13 diff --git a/vendor/github.com/sirupsen/logrus/go.sum b/vendor/github.com/sirupsen/logrus/go.sum index 49c690f2383..1edc143bed0 100644 --- a/vendor/github.com/sirupsen/logrus/go.sum +++ b/vendor/github.com/sirupsen/logrus/go.sum @@ -1,12 +1,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/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/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 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/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go index 6fdda748e4d..dbf627c9754 100644 --- a/vendor/github.com/sirupsen/logrus/logger.go +++ b/vendor/github.com/sirupsen/logrus/logger.go @@ -9,6 +9,11 @@ import ( "time" ) +// LogFunction For big messages, it can be more efficient to pass a function +// and only call it if the log level is actually enables rather than +// generating the log message and then checking if the level is enabled +type LogFunction func()[]interface{} + type Logger struct { // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a // file, or leave it default which is `os.Stderr`. You can also set this to @@ -70,7 +75,7 @@ func (mw *MutexWrap) Disable() { // // var log = &logrus.Logger{ // Out: os.Stderr, -// Formatter: new(logrus.JSONFormatter), +// Formatter: new(logrus.TextFormatter), // Hooks: make(logrus.LevelHooks), // Level: logrus.DebugLevel, // } @@ -195,6 +200,14 @@ func (logger *Logger) Log(level Level, args ...interface{}) { } } +func (logger *Logger) LogFn(level Level, fn LogFunction) { + if logger.IsLevelEnabled(level) { + entry := logger.newEntry() + entry.Log(level, fn()...) + logger.releaseEntry(entry) + } +} + func (logger *Logger) Trace(args ...interface{}) { logger.Log(TraceLevel, args...) } @@ -234,6 +247,45 @@ func (logger *Logger) Panic(args ...interface{}) { logger.Log(PanicLevel, args...) } +func (logger *Logger) TraceFn(fn LogFunction) { + logger.LogFn(TraceLevel, fn) +} + +func (logger *Logger) DebugFn(fn LogFunction) { + logger.LogFn(DebugLevel, fn) +} + +func (logger *Logger) InfoFn(fn LogFunction) { + logger.LogFn(InfoLevel, fn) +} + +func (logger *Logger) PrintFn(fn LogFunction) { + entry := logger.newEntry() + entry.Print(fn()...) + logger.releaseEntry(entry) +} + +func (logger *Logger) WarnFn(fn LogFunction) { + logger.LogFn(WarnLevel, fn) +} + +func (logger *Logger) WarningFn(fn LogFunction) { + logger.WarnFn(fn) +} + +func (logger *Logger) ErrorFn(fn LogFunction) { + logger.LogFn(ErrorLevel, fn) +} + +func (logger *Logger) FatalFn(fn LogFunction) { + logger.LogFn(FatalLevel, fn) + logger.Exit(1) +} + +func (logger *Logger) PanicFn(fn LogFunction) { + logger.LogFn(PanicLevel, fn) +} + func (logger *Logger) Logln(level Level, args ...interface{}) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go index 572889db216..2879eb50ea6 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go @@ -5,30 +5,23 @@ package logrus import ( "io" "os" - "syscall" - sequences "github.com/konsorten/go-windows-terminal-sequences" + "golang.org/x/sys/windows" ) -func initTerminal(w io.Writer) { - switch v := w.(type) { - case *os.File: - sequences.EnableVirtualTerminalProcessing(syscall.Handle(v.Fd()), true) - } -} - func checkIfTerminal(w io.Writer) bool { - var ret bool switch v := w.(type) { case *os.File: + handle := windows.Handle(v.Fd()) var mode uint32 - err := syscall.GetConsoleMode(syscall.Handle(v.Fd()), &mode) - ret = (err == nil) - default: - ret = false + if err := windows.GetConsoleMode(handle, &mode); err != nil { + return false + } + mode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING + if err := windows.SetConsoleMode(handle, mode); err != nil { + return false + } + return true } - if ret { - initTerminal(w) - } - return ret + return false } diff --git a/vendor/github.com/syndtr/gocapability/capability/enum.go b/vendor/github.com/syndtr/gocapability/capability/enum.go index 693817317bd..ad10785314d 100644 --- a/vendor/github.com/syndtr/gocapability/capability/enum.go +++ b/vendor/github.com/syndtr/gocapability/capability/enum.go @@ -41,7 +41,9 @@ const ( //go:generate go run enumgen/gen.go type Cap int -// POSIX-draft defined capabilities. +// POSIX-draft defined capabilities and Linux extensions. +// +// Defined in https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h const ( // In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this // overrides the restriction of changing file ownership and group @@ -187,6 +189,7 @@ const ( // arbitrary SCSI commands // Allow setting encryption key on loopback filesystem // Allow setting zone reclaim policy + // Allow everything under CAP_BPF and CAP_PERFMON for backward compatibility CAP_SYS_ADMIN = Cap(21) // Allow use of reboot() @@ -211,6 +214,7 @@ const ( // Allow more than 64hz interrupts from the real-time clock // Override max number of consoles on console allocation // Override max number of keymaps + // Control memory reclaim behavior CAP_SYS_RESOURCE = Cap(24) // Allow manipulation of system clock @@ -256,8 +260,45 @@ const ( // Allow preventing system suspends CAP_BLOCK_SUSPEND = Cap(36) - // Allow reading audit messages from the kernel + // Allow reading the audit log via multicast netlink socket CAP_AUDIT_READ = Cap(37) + + // Allow system performance and observability privileged operations + // using perf_events, i915_perf and other kernel subsystems + CAP_PERFMON = Cap(38) + + // CAP_BPF allows the following BPF operations: + // - Creating all types of BPF maps + // - Advanced verifier features + // - Indirect variable access + // - Bounded loops + // - BPF to BPF function calls + // - Scalar precision tracking + // - Larger complexity limits + // - Dead code elimination + // - And potentially other features + // - Loading BPF Type Format (BTF) data + // - Retrieve xlated and JITed code of BPF programs + // - Use bpf_spin_lock() helper + // + // CAP_PERFMON relaxes the verifier checks further: + // - BPF progs can use of pointer-to-integer conversions + // - speculation attack hardening measures are bypassed + // - bpf_probe_read to read arbitrary kernel memory is allowed + // - bpf_trace_printk to print kernel memory is allowed + // + // CAP_SYS_ADMIN is required to use bpf_probe_write_user. + // + // CAP_SYS_ADMIN is required to iterate system wide loaded + // programs, maps, links, BTFs and convert their IDs to file descriptors. + // + // CAP_PERFMON and CAP_BPF are required to load tracing programs. + // CAP_NET_ADMIN and CAP_BPF are required to load networking programs. + CAP_BPF = Cap(39) + + // Allow checkpoint/restore related operations. + // Introduced in kernel 5.9 + CAP_CHECKPOINT_RESTORE = Cap(40) ) var ( diff --git a/vendor/github.com/syndtr/gocapability/capability/enum_gen.go b/vendor/github.com/syndtr/gocapability/capability/enum_gen.go index b9e6d2d5e1e..2ff9bf4d887 100644 --- a/vendor/github.com/syndtr/gocapability/capability/enum_gen.go +++ b/vendor/github.com/syndtr/gocapability/capability/enum_gen.go @@ -80,6 +80,12 @@ func (c Cap) String() string { return "block_suspend" case CAP_AUDIT_READ: return "audit_read" + case CAP_PERFMON: + return "perfmon" + case CAP_BPF: + return "bpf" + case CAP_CHECKPOINT_RESTORE: + return "checkpoint_restore" } return "unknown" } @@ -125,5 +131,8 @@ func List() []Cap { CAP_WAKE_ALARM, CAP_BLOCK_SUSPEND, CAP_AUDIT_READ, + CAP_PERFMON, + CAP_BPF, + CAP_CHECKPOINT_RESTORE, } } diff --git a/vendor/github.com/willf/bitset/Makefile b/vendor/github.com/willf/bitset/Makefile deleted file mode 100644 index db8377106f6..00000000000 --- a/vendor/github.com/willf/bitset/Makefile +++ /dev/null @@ -1,191 +0,0 @@ -# MAKEFILE -# -# @author Nicola Asuni -# @link https://github.com/willf/bitset -# ------------------------------------------------------------------------------ - -# List special make targets that are not associated with files -.PHONY: help all test format fmtcheck vet lint coverage cyclo ineffassign misspell structcheck varcheck errcheck gosimple astscan qa deps clean nuke - -# Use bash as shell (Note: Ubuntu now uses dash which doesn't support PIPESTATUS). -SHELL=/bin/bash - -# CVS path (path to the parent dir containing the project) -CVSPATH=github.com/willf - -# Project owner -OWNER=willf - -# Project vendor -VENDOR=willf - -# Project name -PROJECT=bitset - -# Project version -VERSION=$(shell cat VERSION) - -# Name of RPM or DEB package -PKGNAME=${VENDOR}-${PROJECT} - -# Current directory -CURRENTDIR=$(shell pwd) - -# GO lang path -ifneq ($(GOPATH),) - ifeq ($(findstring $(GOPATH),$(CURRENTDIR)),) - # the defined GOPATH is not valid - GOPATH= - endif -endif -ifeq ($(GOPATH),) - # extract the GOPATH - GOPATH=$(firstword $(subst /src/, ,$(CURRENTDIR))) -endif - -# --- MAKE TARGETS --- - -# Display general help about this command -help: - @echo "" - @echo "$(PROJECT) Makefile." - @echo "GOPATH=$(GOPATH)" - @echo "The following commands are available:" - @echo "" - @echo " make qa : Run all the tests" - @echo " make test : Run the unit tests" - @echo "" - @echo " make format : Format the source code" - @echo " make fmtcheck : Check if the source code has been formatted" - @echo " make vet : Check for suspicious constructs" - @echo " make lint : Check for style errors" - @echo " make coverage : Generate the coverage report" - @echo " make cyclo : Generate the cyclomatic complexity report" - @echo " make ineffassign : Detect ineffectual assignments" - @echo " make misspell : Detect commonly misspelled words in source files" - @echo " make structcheck : Find unused struct fields" - @echo " make varcheck : Find unused global variables and constants" - @echo " make errcheck : Check that error return values are used" - @echo " make gosimple : Suggest code simplifications" - @echo " make astscan : GO AST scanner" - @echo "" - @echo " make docs : Generate source code documentation" - @echo "" - @echo " make deps : Get the dependencies" - @echo " make clean : Remove any build artifact" - @echo " make nuke : Deletes any intermediate file" - @echo "" - -# Alias for help target -all: help - -# Run the unit tests -test: - @mkdir -p target/test - @mkdir -p target/report - GOPATH=$(GOPATH) \ - go test \ - -covermode=atomic \ - -bench=. \ - -race \ - -cpuprofile=target/report/cpu.out \ - -memprofile=target/report/mem.out \ - -mutexprofile=target/report/mutex.out \ - -coverprofile=target/report/coverage.out \ - -v ./... | \ - tee >(PATH=$(GOPATH)/bin:$(PATH) go-junit-report > target/test/report.xml); \ - test $${PIPESTATUS[0]} -eq 0 - -# Format the source code -format: - @find . -type f -name "*.go" -exec gofmt -s -w {} \; - -# Check if the source code has been formatted -fmtcheck: - @mkdir -p target - @find . -type f -name "*.go" -exec gofmt -s -d {} \; | tee target/format.diff - @test ! -s target/format.diff || { echo "ERROR: the source code has not been formatted - please use 'make format' or 'gofmt'"; exit 1; } - -# Check for syntax errors -vet: - GOPATH=$(GOPATH) go vet . - -# Check for style errors -lint: - GOPATH=$(GOPATH) PATH=$(GOPATH)/bin:$(PATH) golint . - -# Generate the coverage report -coverage: - @mkdir -p target/report - GOPATH=$(GOPATH) \ - go tool cover -html=target/report/coverage.out -o target/report/coverage.html - -# Report cyclomatic complexity -cyclo: - @mkdir -p target/report - GOPATH=$(GOPATH) gocyclo -avg ./ | tee target/report/cyclo.txt ; test $${PIPESTATUS[0]} -eq 0 - -# Detect ineffectual assignments -ineffassign: - @mkdir -p target/report - GOPATH=$(GOPATH) ineffassign ./ | tee target/report/ineffassign.txt ; test $${PIPESTATUS[0]} -eq 0 - -# Detect commonly misspelled words in source files -misspell: - @mkdir -p target/report - GOPATH=$(GOPATH) misspell -error ./ | tee target/report/misspell.txt ; test $${PIPESTATUS[0]} -eq 0 - -# Find unused struct fields -structcheck: - @mkdir -p target/report - GOPATH=$(GOPATH) structcheck -a ./ | tee target/report/structcheck.txt - -# Find unused global variables and constants -varcheck: - @mkdir -p target/report - GOPATH=$(GOPATH) varcheck -e ./ | tee target/report/varcheck.txt - -# Check that error return values are used -errcheck: - @mkdir -p target/report - GOPATH=$(GOPATH) errcheck ./ | tee target/report/errcheck.txt - -# AST scanner -astscan: - @mkdir -p target/report - GOPATH=$(GOPATH) gosec . | tee target/report/astscan.txt ; test $${PIPESTATUS[0]} -eq 0 || true - -# Generate source docs -docs: - @mkdir -p target/docs - nohup sh -c 'GOPATH=$(GOPATH) godoc -http=127.0.0.1:6060' > target/godoc_server.log 2>&1 & - wget --directory-prefix=target/docs/ --execute robots=off --retry-connrefused --recursive --no-parent --adjust-extension --page-requisites --convert-links http://127.0.0.1:6060/pkg/github.com/${VENDOR}/${PROJECT}/ ; kill -9 `lsof -ti :6060` - @echo ''${PKGNAME}' Documentation ...' > target/docs/index.html - -# Alias to run all quality-assurance checks -qa: fmtcheck test vet lint coverage cyclo ineffassign misspell structcheck varcheck errcheck gosimple astscan - -# --- INSTALL --- - -# Get the dependencies -deps: - GOPATH=$(GOPATH) go get ./... - GOPATH=$(GOPATH) go get golang.org/x/lint/golint - GOPATH=$(GOPATH) go get github.com/jstemmer/go-junit-report - GOPATH=$(GOPATH) go get github.com/axw/gocov/gocov - GOPATH=$(GOPATH) go get github.com/fzipp/gocyclo - GOPATH=$(GOPATH) go get github.com/gordonklaus/ineffassign - GOPATH=$(GOPATH) go get github.com/client9/misspell/cmd/misspell - GOPATH=$(GOPATH) go get github.com/opennota/check/cmd/structcheck - GOPATH=$(GOPATH) go get github.com/opennota/check/cmd/varcheck - GOPATH=$(GOPATH) go get github.com/kisielk/errcheck - GOPATH=$(GOPATH) go get github.com/securego/gosec/cmd/gosec/... - -# Remove any build artifact -clean: - GOPATH=$(GOPATH) go clean ./... - -# Deletes any intermediate file -nuke: - rm -rf ./target - GOPATH=$(GOPATH) go clean -i ./... diff --git a/vendor/github.com/willf/bitset/README.md b/vendor/github.com/willf/bitset/README.md index 6c62b20c6c8..50338e71dfd 100644 --- a/vendor/github.com/willf/bitset/README.md +++ b/vendor/github.com/willf/bitset/README.md @@ -2,10 +2,10 @@ *Go language library to map between non-negative integers and boolean values* -[![Master Build Status](https://secure.travis-ci.org/willf/bitset.png?branch=master)](https://travis-ci.org/willf/bitset?branch=master) +[![Test](https://github.com/willf/bitset/workflows/Test/badge.svg)](https://github.com/willf/bitset/actions?query=workflow%3ATest) [![Master Coverage Status](https://coveralls.io/repos/willf/bitset/badge.svg?branch=master&service=github)](https://coveralls.io/github/willf/bitset?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/willf/bitset)](https://goreportcard.com/report/github.com/willf/bitset) -[![GoDoc](https://godoc.org/github.com/willf/bitset?status.svg)](http://godoc.org/github.com/willf/bitset) +[![PkgGoDev](https://pkg.go.dev/badge/github.com/willf/bitset?tab=doc)](https://pkg.go.dev/github.com/willf/bitset?tab=doc) ## Description @@ -63,8 +63,11 @@ func main() { As an alternative to BitSets, one should check out the 'big' package, which provides a (less set-theoretical) view of bitsets. -Godoc documentation is at: https://godoc.org/github.com/willf/bitset +Package documentation is at: https://pkg.go.dev/github.com/willf/bitset?tab=doc +## Memory Usage + +The memory usage of a bitset using N bits is at least N/8 bytes. The number of bits in a bitset is at least as large as one plus the greatest bit index you have accessed. Thus it is possible to run out of memory while using a bitset. If you have lots of bits, you might prefer compressed bitsets, like the [Roaring bitmaps](http://roaringbitmap.org) and its [Go implementation](https://github.com/RoaringBitmap/roaring). ## Implementation Note @@ -82,15 +85,10 @@ go get github.com/willf/bitset If you wish to contribute to this project, please branch and issue a pull request against master ("[GitHub Flow](https://guides.github.com/introduction/flow/)") -This project include a Makefile that allows you to test and build the project with simple commands. -To see all available options: -```bash -make help -``` - ## Running all tests -Before committing the code, please check if it passes all tests using (note: this will install some dependencies): +Before committing the code, please check if it passes tests, has adequate coverage, etc. ```bash -make qa +go test +go test -cover ``` diff --git a/vendor/github.com/willf/bitset/bitset.go b/vendor/github.com/willf/bitset/bitset.go index 22e5d42e5d6..21e889da2e0 100644 --- a/vendor/github.com/willf/bitset/bitset.go +++ b/vendor/github.com/willf/bitset/bitset.go @@ -138,6 +138,9 @@ func (b *BitSet) Len() uint { // extendSetMaybe adds additional words to incorporate new bits if needed func (b *BitSet) extendSetMaybe(i uint) { if i >= b.length { // if we need more bits, make 'em + if i >= Cap() { + panic("You are exceeding the capacity") + } nsize := wordsNeeded(i + 1) if b.set == nil { b.set = make([]uint64, nsize) @@ -160,7 +163,12 @@ func (b *BitSet) Test(i uint) bool { return b.set[i>>log2WordSize]&(1<<(i&(wordSize-1))) != 0 } -// Set bit i to 1 +// Set bit i to 1, the capacity of the bitset is automatically +// increased accordingly. +// If i>= Cap(), this function will panic. +// Warning: using a very large value for 'i' +// may lead to a memory shortage and a panic: the caller is responsible +// for providing sensible parameters in line with their memory capacity. func (b *BitSet) Set(i uint) *BitSet { b.extendSetMaybe(i) b.set[i>>log2WordSize] |= 1 << (i & (wordSize - 1)) @@ -176,7 +184,11 @@ func (b *BitSet) Clear(i uint) *BitSet { return b } -// SetTo sets bit i to value +// SetTo sets bit i to value. +// If i>= Cap(), this function will panic. +// Warning: using a very large value for 'i' +// may lead to a memory shortage and a panic: the caller is responsible +// for providing sensible parameters in line with their memory capacity. func (b *BitSet) SetTo(i uint, value bool) *BitSet { if value { return b.Set(i) @@ -184,7 +196,11 @@ func (b *BitSet) SetTo(i uint, value bool) *BitSet { return b.Clear(i) } -// Flip bit at i +// Flip bit at i. +// If i>= Cap(), this function will panic. +// Warning: using a very large value for 'i' +// may lead to a memory shortage and a panic: the caller is responsible +// for providing sensible parameters in line with their memory capacity. func (b *BitSet) Flip(i uint) *BitSet { if i >= b.length { return b.Set(i) @@ -193,26 +209,51 @@ func (b *BitSet) Flip(i uint) *BitSet { return b } -// Shrink shrinks BitSet to desired length in bits. It clears all bits > length -// and reduces the size and length of the set. +// Shrink shrinks BitSet so that the provided value is the last possible +// set value. It clears all bits > the provided index and reduces the size +// and length of the set. +// +// Note that the parameter value is not the new length in bits: it is the +// maximal value that can be stored in the bitset after the function call. +// The new length in bits is the parameter value + 1. Thus it is not possible +// to use this function to set the length to 0, the minimal value of the length +// after this function call is 1. // // A new slice is allocated to store the new bits, so you may see an increase in // memory usage until the GC runs. Normally this should not be a problem, but if you // have an extremely large BitSet its important to understand that the old BitSet will // remain in memory until the GC frees it. -func (b *BitSet) Shrink(length uint) *BitSet { - idx := wordsNeeded(length + 1) +func (b *BitSet) Shrink(lastbitindex uint) *BitSet { + length := lastbitindex + 1 + idx := wordsNeeded(length) if idx > len(b.set) { return b } shrunk := make([]uint64, idx) copy(shrunk, b.set[:idx]) b.set = shrunk - b.length = length + 1 - b.set[idx-1] &= (allBits >> (uint64(64) - uint64(length&(wordSize-1)) - 1)) + b.length = length + b.set[idx-1] &= (allBits >> (uint64(64) - uint64(length&(wordSize-1)))) return b } +// Compact shrinks BitSet to so that we preserve all set bits, while minimizing +// memory usage. Compact calls Shrink. +func (b *BitSet) Compact() *BitSet { + idx := len(b.set) - 1 + for ; idx >= 0 && b.set[idx] == 0; idx-- { + } + newlength := uint((idx + 1) << log2WordSize) + if newlength >= b.length { + return b // nothing to do + } + if newlength > 0 { + return b.Shrink(newlength - 1) + } + // We preserve one word + return b.Shrink(63) +} + // InsertAt takes an index which indicates where a bit should be // inserted. Then it shifts all the bits in the set to the left by 1, starting // from the given index position, and sets the index position to 0. @@ -323,6 +364,9 @@ func (b *BitSet) DeleteAt(i uint) *BitSet { // including possibly the current index // along with an error code (true = valid, false = no set bit found) // for i,e := v.NextSet(0); e; i,e = v.NextSet(i + 1) {...} +// +// Users concerned with performance may want to use NextSetMany to +// retrieve several values at once. func (b *BitSet) NextSet(i uint) (uint, bool) { x := int(i >> log2WordSize) if x >= len(b.set) { @@ -358,6 +402,14 @@ func (b *BitSet) NextSet(i uint) (uint, bool) { // j += 1 // } // +// +// It is possible to retrieve all set bits as follow: +// +// indices := make([]uint, bitmap.Count()) +// bitmap.NextSetMany(0, indices) +// +// However if bitmap.Count() is large, it might be preferable to +// use several calls to NextSetMany, for performance reasons. func (b *BitSet) NextSetMany(i uint, buffer []uint) (uint, []uint) { myanswer := buffer capacity := cap(buffer) @@ -809,7 +861,7 @@ func (b *BitSet) ReadFrom(stream io.Reader) (int64, error) { newset := New(uint(length)) if uint64(newset.length) != length { - return 0, errors.New("Unmarshalling error: type mismatch") + return 0, errors.New("unmarshalling error: type mismatch") } // Read remaining bytes as set diff --git a/vendor/github.com/willf/bitset/go.mod b/vendor/github.com/willf/bitset/go.mod new file mode 100644 index 00000000000..583ecab78f7 --- /dev/null +++ b/vendor/github.com/willf/bitset/go.mod @@ -0,0 +1,3 @@ +module github.com/willf/bitset + +go 1.14 diff --git a/vendor/github.com/willf/bitset/go.sum b/vendor/github.com/willf/bitset/go.sum new file mode 100644 index 00000000000..e69de29bb2d diff --git a/vendor/modules.txt b/vendor/modules.txt index 6088f460a72..f01c1bc6e8f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -212,9 +212,9 @@ github.com/checkpoint-restore/go-criu/v4/rpc # github.com/chzyer/logex => github.com/chzyer/logex v1.1.10 # github.com/chzyer/readline => github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e # github.com/chzyer/test => github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 -# github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775 => github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775 +# github.com/cilium/ebpf v0.2.0 => github.com/cilium/ebpf v0.2.0 github.com/cilium/ebpf -# github.com/cilium/ebpf => github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775 +# github.com/cilium/ebpf => github.com/cilium/ebpf v0.2.0 github.com/cilium/ebpf/asm github.com/cilium/ebpf/internal github.com/cilium/ebpf/internal/btf @@ -231,11 +231,11 @@ github.com/container-storage-interface/spec/lib/go/csi # github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 => github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 # github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 github.com/containerd/cgroups/stats/v1 -# github.com/containerd/console v1.0.0 => github.com/containerd/console v1.0.0 +# github.com/containerd/console v1.0.1 => github.com/containerd/console v1.0.1 github.com/containerd/console -# github.com/containerd/console => github.com/containerd/console v1.0.0 -# github.com/containerd/containerd v1.4.1 => github.com/containerd/containerd v1.4.1 -# github.com/containerd/containerd => github.com/containerd/containerd v1.4.1 +# github.com/containerd/console => github.com/containerd/console v1.0.1 +# github.com/containerd/containerd v1.4.4 => github.com/containerd/containerd v1.4.4 +# github.com/containerd/containerd => github.com/containerd/containerd v1.4.4 github.com/containerd/containerd/api/services/containers/v1 github.com/containerd/containerd/api/services/tasks/v1 github.com/containerd/containerd/api/services/version/v1 @@ -244,8 +244,10 @@ github.com/containerd/containerd/api/types/task github.com/containerd/containerd/containers github.com/containerd/containerd/errdefs github.com/containerd/containerd/identifiers +github.com/containerd/containerd/log github.com/containerd/containerd/namespaces github.com/containerd/containerd/pkg/dialer +github.com/containerd/containerd/platforms # github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc # github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 # github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3 @@ -295,7 +297,7 @@ github.com/coreos/pkg/dlopen ## explicit # github.com/cpuguy83/go-md2man/v2 => github.com/cpuguy83/go-md2man/v2 v2.0.0 github.com/cpuguy83/go-md2man/v2/md2man -# github.com/creack/pty => github.com/creack/pty v1.1.9 +# github.com/creack/pty => github.com/creack/pty v1.1.11 # github.com/cyphar/filepath-securejoin v0.2.2 => github.com/cyphar/filepath-securejoin v0.2.2 github.com/cyphar/filepath-securejoin # github.com/cyphar/filepath-securejoin => github.com/cyphar/filepath-securejoin v0.2.2 @@ -316,9 +318,9 @@ github.com/dgrijalva/jwt-go github.com/docker/distribution/digestset github.com/docker/distribution/reference github.com/docker/distribution/registry/api/errcode -# github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible => github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible +# github.com/docker/docker v20.10.2+incompatible => github.com/docker/docker v20.10.2+incompatible ## explicit -# github.com/docker/docker => github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible +# github.com/docker/docker => github.com/docker/docker v20.10.2+incompatible github.com/docker/docker/api github.com/docker/docker/api/types github.com/docker/docker/api/types/blkiodev @@ -339,8 +341,6 @@ github.com/docker/docker/client github.com/docker/docker/errdefs github.com/docker/docker/pkg/jsonmessage github.com/docker/docker/pkg/stdcopy -github.com/docker/docker/pkg/term -github.com/docker/docker/pkg/term/windows # github.com/docker/go-connections v0.4.0 => github.com/docker/go-connections v0.4.0 ## explicit # github.com/docker/go-connections => github.com/docker/go-connections v0.4.0 @@ -496,9 +496,9 @@ github.com/golang/protobuf/ptypes/wrappers # github.com/google/btree v1.0.0 => github.com/google/btree v1.0.0 github.com/google/btree # github.com/google/btree => github.com/google/btree v1.0.0 -# github.com/google/cadvisor v0.38.8 => github.com/google/cadvisor v0.38.8 +# github.com/google/cadvisor v0.39.0 => github.com/google/cadvisor v0.39.0 ## explicit -# github.com/google/cadvisor => github.com/google/cadvisor v0.38.8 +# github.com/google/cadvisor => github.com/google/cadvisor v0.39.0 github.com/google/cadvisor/accelerators github.com/google/cadvisor/cache/memory github.com/google/cadvisor/client/v2 @@ -710,9 +710,7 @@ github.com/karrick/godirwalk # github.com/kisielk/errcheck => github.com/kisielk/errcheck v1.5.0 # github.com/kisielk/gotool => github.com/kisielk/gotool v1.0.0 # github.com/klauspost/cpuid => github.com/klauspost/cpuid v1.2.0 -# github.com/konsorten/go-windows-terminal-sequences v1.0.3 => github.com/konsorten/go-windows-terminal-sequences v1.0.3 -github.com/konsorten/go-windows-terminal-sequences -# github.com/konsorten/go-windows-terminal-sequences => github.com/konsorten/go-windows-terminal-sequences v1.0.3 +# github.com/konsorten/go-windows-terminal-sequences => github.com/konsorten/go-windows-terminal-sequences v1.0.2 # github.com/kr/logfmt => github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 # github.com/kr/pretty => github.com/kr/pretty v0.2.0 # github.com/kr/text => github.com/kr/text v0.2.0 @@ -787,12 +785,12 @@ github.com/moby/ipvs github.com/moby/spdystream # github.com/moby/spdystream => github.com/moby/spdystream v0.2.0 github.com/moby/spdystream/spdy -# github.com/moby/sys/mountinfo v0.1.3 => github.com/moby/sys/mountinfo v0.1.3 +# github.com/moby/sys/mountinfo v0.4.0 => github.com/moby/sys/mountinfo v0.4.0 github.com/moby/sys/mountinfo -# github.com/moby/sys/mountinfo => github.com/moby/sys/mountinfo v0.1.3 -# github.com/moby/term v0.0.0-20200312100748-672ec06f55cd => github.com/moby/term v0.0.0-20200312100748-672ec06f55cd +# github.com/moby/sys/mountinfo => github.com/moby/sys/mountinfo v0.4.0 +# github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 => github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 github.com/moby/term -# github.com/moby/term => github.com/moby/term v0.0.0-20200312100748-672ec06f55cd +# github.com/moby/term => github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 github.com/moby/term/windows # github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd => github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd github.com/modern-go/concurrent @@ -810,10 +808,10 @@ github.com/monochromegane/go-gitignore # github.com/morikuni/aec v1.0.0 => github.com/morikuni/aec v1.0.0 github.com/morikuni/aec # github.com/morikuni/aec => github.com/morikuni/aec v1.0.0 -# github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976 => github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976 +# github.com/mrunalp/fileutils v0.5.0 => github.com/mrunalp/fileutils v0.5.0 ## explicit github.com/mrunalp/fileutils -# github.com/mrunalp/fileutils => github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976 +# github.com/mrunalp/fileutils => github.com/mrunalp/fileutils v0.5.0 # github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 => github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 ## explicit github.com/munnerz/goautoneg @@ -883,11 +881,12 @@ github.com/opencontainers/go-digest # github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.1 github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 -# github.com/opencontainers/runc v1.0.0-rc92 => github.com/opencontainers/runc v1.0.0-rc92 +# github.com/opencontainers/runc v1.0.0-rc93 => github.com/opencontainers/runc v1.0.0-rc93 ## explicit -# github.com/opencontainers/runc => github.com/opencontainers/runc v1.0.0-rc92 +# github.com/opencontainers/runc => github.com/opencontainers/runc v1.0.0-rc93 github.com/opencontainers/runc/libcontainer github.com/opencontainers/runc/libcontainer/apparmor +github.com/opencontainers/runc/libcontainer/capabilities github.com/opencontainers/runc/libcontainer/cgroups github.com/opencontainers/runc/libcontainer/cgroups/devices github.com/opencontainers/runc/libcontainer/cgroups/ebpf @@ -898,21 +897,23 @@ github.com/opencontainers/runc/libcontainer/cgroups/fscommon github.com/opencontainers/runc/libcontainer/cgroups/systemd github.com/opencontainers/runc/libcontainer/configs github.com/opencontainers/runc/libcontainer/configs/validate +github.com/opencontainers/runc/libcontainer/devices github.com/opencontainers/runc/libcontainer/intelrdt github.com/opencontainers/runc/libcontainer/keys github.com/opencontainers/runc/libcontainer/logs github.com/opencontainers/runc/libcontainer/seccomp +github.com/opencontainers/runc/libcontainer/seccomp/patchbpf github.com/opencontainers/runc/libcontainer/stacktrace github.com/opencontainers/runc/libcontainer/system github.com/opencontainers/runc/libcontainer/user github.com/opencontainers/runc/libcontainer/utils github.com/opencontainers/runc/types -# github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6 => github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6 -# github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6 +# github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d => github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d +# github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d github.com/opencontainers/runtime-spec/specs-go -# github.com/opencontainers/selinux v1.6.0 => github.com/opencontainers/selinux v1.6.0 +# github.com/opencontainers/selinux v1.8.0 => github.com/opencontainers/selinux v1.8.0 ## explicit -# github.com/opencontainers/selinux => github.com/opencontainers/selinux v1.6.0 +# github.com/opencontainers/selinux => github.com/opencontainers/selinux v1.8.0 github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label github.com/opencontainers/selinux/pkg/pwalk @@ -990,9 +991,9 @@ github.com/seccomp/libseccomp-golang # github.com/shurcooL/sanitized_anchor_name v1.0.0 => github.com/shurcooL/sanitized_anchor_name v1.0.0 github.com/shurcooL/sanitized_anchor_name # github.com/shurcooL/sanitized_anchor_name => github.com/shurcooL/sanitized_anchor_name v1.0.0 -# github.com/sirupsen/logrus v1.6.0 => github.com/sirupsen/logrus v1.6.0 +# github.com/sirupsen/logrus v1.7.0 => github.com/sirupsen/logrus v1.7.0 github.com/sirupsen/logrus -# github.com/sirupsen/logrus => github.com/sirupsen/logrus v1.6.0 +# github.com/sirupsen/logrus => github.com/sirupsen/logrus v1.7.0 # github.com/smartystreets/assertions => github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d # github.com/smartystreets/goconvey => github.com/smartystreets/goconvey v1.6.4 # github.com/soheilhy/cmux v0.1.4 => github.com/soheilhy/cmux v0.1.4 @@ -1042,8 +1043,8 @@ github.com/stretchr/testify/require # github.com/subosito/gotenv v1.2.0 => github.com/subosito/gotenv v1.2.0 github.com/subosito/gotenv # github.com/subosito/gotenv => github.com/subosito/gotenv v1.2.0 -# github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 => github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 -# github.com/syndtr/gocapability => github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 +# github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 => github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 +# github.com/syndtr/gocapability => github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 github.com/syndtr/gocapability/capability # github.com/thecodeteam/goscaleio v0.1.0 => github.com/thecodeteam/goscaleio v0.1.0 ## explicit @@ -1103,9 +1104,9 @@ github.com/vmware/govmomi/vim25/progress github.com/vmware/govmomi/vim25/soap github.com/vmware/govmomi/vim25/types github.com/vmware/govmomi/vim25/xml -# github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243 => github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243 +# github.com/willf/bitset v1.1.11 => github.com/willf/bitset v1.1.11 github.com/willf/bitset -# github.com/willf/bitset => github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243 +# github.com/willf/bitset => github.com/willf/bitset v1.1.11 # github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 => github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 github.com/xiang90/probing # github.com/xiang90/probing => github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 @@ -1574,7 +1575,7 @@ gopkg.in/yaml.v2 gopkg.in/yaml.v3 # gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c # gotest.tools => gotest.tools v2.2.0+incompatible -# gotest.tools/v3 => gotest.tools/v3 v3.0.2 +# gotest.tools/v3 => gotest.tools/v3 v3.0.3 # honnef.co/go/tools => honnef.co/go/tools v0.0.1-2020.1.3 # k8s.io/api v0.0.0 => ./staging/src/k8s.io/api ## explicit