diff --git a/daemon/daemon.go b/daemon/daemon.go index d5e0f3fec3..198423140b 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -65,6 +65,7 @@ import ( "golang.org/x/sync/singleflight" "google.golang.org/grpc" "google.golang.org/grpc/backoff" + "google.golang.org/grpc/credentials/insecure" ) // ContainersNamespace is the name of the namespace used for users containers @@ -885,7 +886,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S // It is not harm to add WithBlock for containerd connection. grpc.WithBlock(), - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithConnectParams(connParams), grpc.WithContextDialer(dialer.ContextDialer), diff --git a/vendor.mod b/vendor.mod index 90cbde3099..8ee1ce2229 100644 --- a/vendor.mod +++ b/vendor.mod @@ -18,7 +18,7 @@ require ( github.com/bsphere/le_go v0.0.0-20170215134836-7a984a84b549 github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5 github.com/containerd/cgroups v1.0.3 - github.com/containerd/containerd v1.5.10 + github.com/containerd/containerd v1.6.1 github.com/containerd/continuity v0.2.2 github.com/containerd/fifo v1.0.0 github.com/containerd/typeurl v1.0.2 @@ -74,15 +74,15 @@ require ( github.com/tchap/go-patricia v2.3.0+incompatible github.com/tonistiigi/fsutil v0.0.0-20220115021204-b19f7f9cb274 github.com/vbatts/tar-split v0.11.2 - github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852 + github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5 github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f go.etcd.io/bbolt v1.3.6 - golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 + golang.org/x/net v0.0.0-20211216030914-fe4d6282115f golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa - google.golang.org/grpc v1.40.0 + google.golang.org/grpc v1.43.0 gotest.tools/v3 v3.1.0 ) @@ -127,8 +127,8 @@ require ( github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee // indirect github.com/philhofer/fwd v1.0.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.10.0 // indirect - github.com/prometheus/procfs v0.6.0 // indirect + github.com/prometheus/common v0.30.0 // indirect + github.com/prometheus/procfs v0.7.3 // indirect github.com/rexray/gocsi v1.2.2 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/tinylib/msgp v1.1.0 // indirect diff --git a/vendor.sum b/vendor.sum index 86763c4a39..c3fc7395bb 100644 --- a/vendor.sum +++ b/vendor.sum @@ -44,19 +44,24 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 code.cloudfoundry.org/clock v1.0.0 h1:kFXWQM4bxYvdBw2X8BbBeXwQNgfoWv1vqAk2ZZyBN2o= code.cloudfoundry.org/clock v1.0.0/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -79,6 +84,7 @@ github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg3 github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= +github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= github.com/Microsoft/hcsshim v0.9.2 h1:wB06W5aYFfUB3IvootYAY2WnOmIdgPGfqSI6tufQNnY= @@ -86,6 +92,7 @@ github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfy github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -100,7 +107,9 @@ github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A= github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= +github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20150106224455-eb0af217e5e9 h1:j0r1R47jEcPk5M3GY3tFbv7q5J6j0Ppler3q4Guh6C0= @@ -127,10 +136,12 @@ github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR github.com/bsphere/le_go v0.0.0-20170215134836-7a984a84b549 h1:QJJnIXZ34OUK5JfWlq1l3n0SfO9g1amiLFIcTECgpq0= github.com/bsphere/le_go v0.0.0-20170215134836-7a984a84b549/go.mod h1:313oBJKClgRD/+t59eUnrfG7/xHXZJd7v+SjCacDm4Q= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI= @@ -158,7 +169,11 @@ github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5/go.mod h1:yMWuSON github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5 h1:xD/lrqdvwsc+O2bjSSi3YqY73Ke3LAiSCx49aCesA0E= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= @@ -209,8 +224,9 @@ github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoT github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= -github.com/containerd/containerd v1.5.10 h1:3cQ2uRVCkJVcx5VombsE7105Gl9Wrl7ORAO3+4+ogf4= -github.com/containerd/containerd v1.5.10/go.mod h1:fvQqCfadDGga5HZyn3j4+dx56qj2I9YwBrlSdalvJYQ= +github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= +github.com/containerd/containerd v1.6.1 h1:oa2uY0/0G+JX4X7hpGCYvkp9FjUancz56kSNnb1sG3o= +github.com/containerd/containerd v1.6.1/go.mod h1:1nJz5xCZPusx6jJU8Frfct988y0NpumIq9ODB0kLtoE= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -230,6 +246,8 @@ github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O1 github.com/containerd/fuse-overlayfs-snapshotter v1.0.2/go.mod h1:nRZceC8a7dRm3Ao6cJAwuJWPFiBPaibHiFntRUnzhwU= github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= +github.com/containerd/go-cni v1.1.0/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= +github.com/containerd/go-cni v1.1.3/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= @@ -240,6 +258,7 @@ github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA= github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= +github.com/containerd/imgcrypt v1.1.3/go.mod h1:/TPA1GIDXMzbj01yd8pIbQiLdQxed5ue1wb8bP7PQu4= github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= @@ -266,16 +285,20 @@ github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNR github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y= github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= +github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE= github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= +github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -355,9 +378,12 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e h1:P10tZmVD2XclAaT9l7OduMH1OLFzTa1wUuUqHZnEdI0= github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e/go.mod h1:2H9hjfbpSMHwY503FclkV/lZTBh2YlOmLLSda12uL8c= github.com/fluent/fluent-logger-golang v1.9.0 h1:zUdY44CHX2oIUc7VTNZc+4m+ORuO/mldQDA7czhWXEg= @@ -381,22 +407,34 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= @@ -474,6 +512,7 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -501,6 +540,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= +github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -564,9 +605,11 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee h1:PAXLXk1heNZ5yokbMBpVLZQxo43wCZxRwl00mX+dd44= github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= +github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= github.com/jaguilar/vt100 v0.0.0-20150826170717-2703a27b14ea/go.mod h1:QMdK4dGB3YhEW2BmA1wgGpPYI3HZy/5gD705PXKUVSg= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -575,16 +618,20 @@ github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeY github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -615,6 +662,7 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -622,6 +670,7 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= @@ -646,6 +695,7 @@ 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/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7sxOougM= github.com/moby/sys/mount v0.3.1 h1:RX1K0x95oR8j5P1YefKDt7tE1C2kCCixV0H8Aza3GaI= github.com/moby/sys/mount v0.3.1/go.mod h1:6IZknFQiqjLpwuYJD5Zk0qYEuJiws36M88MIXnZHya0= @@ -654,6 +704,7 @@ github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2J github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/mountinfo v0.6.0 h1:gUDhXQx58YNrpHlK4nSL+7y2pxFZkUcXqzFDKWdC0Oo= github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI= github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= @@ -661,24 +712,27 @@ github.com/moby/sys/symlink v0.2.0 h1:tk1rOM+Ljp0nFmfOIBtlV3rTDlWOwFRhjEeAhZB0nZ github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= +github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 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.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -689,8 +743,11 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= @@ -698,8 +755,10 @@ github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU= +github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -708,6 +767,7 @@ 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.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= @@ -740,6 +800,7 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.9.1/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -764,8 +825,10 @@ github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2 github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu/Ug= +github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI= github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -775,7 +838,9 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -818,6 +883,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/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= @@ -891,15 +957,22 @@ go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/api/v3 v3.5.2/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/pkg/v3 v3.5.2 h1:4hzqQ6hIb3blLyQ8usCU4h3NghkqcsohEQ3o3VetYxE= go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.etcd.io/etcd/client/v2 v2.305.2/go.mod h1:2D7ZejHVMIfog1221iLSYlQRzrtECw3kz4I4VAQm3qI= +go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= go.etcd.io/etcd/client/v3 v3.5.2/go.mod h1:kOOaWFFgHygyT0WlSmL8TJiXmMysO/nNUlEsSsN6W4o= +go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= go.etcd.io/etcd/pkg/v3 v3.5.2 h1:YZUojdoPhOyl5QILYnR8LTUbbNefu/sV4ma+ZMr2tto= go.etcd.io/etcd/pkg/v3 v3.5.2/go.mod h1:zsXz+9D/kijzRiG/UnFGDTyHKcVp0orwiO8iMLAi+k0= +go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= go.etcd.io/etcd/raft/v3 v3.5.2 h1:uCC37qOXqBvKqTGHGyhASsaCsnTuJugl1GvneJNwHWo= go.etcd.io/etcd/raft/v3 v3.5.2/go.mod h1:G6pCP1sFgbjod7/KnEHY0vHUViqxjkdt6AiKsD0GRr8= +go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= go.etcd.io/etcd/server/v3 v3.5.2 h1:B6ytJvS4Fmt8nkjzS2/8POf4tuPhFMluE0lWd4dx/7U= go.etcd.io/etcd/server/v3 v3.5.2/go.mod h1:mlG8znIEz4N/28GABrohZCBM11FqgGVQcpbcyJgh0j0= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= @@ -907,15 +980,25 @@ go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= +go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= +go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= +go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= @@ -942,7 +1025,9 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211202192323-5770296d904e h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8= golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1013,6 +1098,7 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -1028,10 +1114,14 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1111,8 +1201,10 @@ golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1129,6 +1221,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1140,19 +1233,27 @@ golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1170,6 +1271,7 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M= golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1231,6 +1333,7 @@ golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4X golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= @@ -1311,6 +1414,7 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1324,6 +1428,7 @@ google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaE google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -1352,8 +1457,10 @@ google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM= +google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1374,8 +1481,9 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -1400,6 +1508,7 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= @@ -1417,33 +1526,46 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= +k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= +k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= +k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= +k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= +k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y= k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= +k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI= k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= +k8s.io/cri-api v0.23.1/go.mod h1:REJE3PSU0h/LOV1APBrupxrEJqnoxZC8KWzkBUHwrK4= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= labix.org/v2/mgo v0.0.0-20140701140051-000000000287 h1:L0cnkNl4TfAXzvdrqsYEmxOHOCv2p5I3taaReO8BWFs= labix.org/v2/mgo v0.0.0-20140701140051-000000000287/go.mod h1:Lg7AYkt1uXJoR9oeSZ3W/8IXLdvOfIITgZnommstyz4= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= @@ -1451,8 +1573,10 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/vendor/github.com/containerd/containerd/.golangci.yml b/vendor/github.com/containerd/containerd/.golangci.yml index 4eba7d8d19..4bf84599d7 100644 --- a/vendor/github.com/containerd/containerd/.golangci.yml +++ b/vendor/github.com/containerd/containerd/.golangci.yml @@ -19,7 +19,7 @@ issues: - EXC0002 run: - timeout: 3m + timeout: 8m skip-dirs: - api - design diff --git a/vendor/github.com/containerd/containerd/.mailmap b/vendor/github.com/containerd/containerd/.mailmap index b6ce97230b..83bb03cd00 100644 --- a/vendor/github.com/containerd/containerd/.mailmap +++ b/vendor/github.com/containerd/containerd/.mailmap @@ -29,13 +29,17 @@ Eric Ernst Eric Ren Eric Ren Eric Ren +Fabiano FidĂȘncio Fahed Dorgaa Frank Yang Fupan Li Fupan Li +Fupan Li +Furkan TĂŒrkal Georgia Panoutsakopoulou Guangming Wang Haiyan Meng +haoyun Harry Zhang Hu Shuai Hu Shuai @@ -53,15 +57,18 @@ John Howard John Howard Lorenz Brun Luc Perkins +Jiajun Jiang Julien Balestra Jun Lin Chen <1913688+mc256@users.noreply.github.com> Justin Cormack Justin Terry Justin Terry +Kante Kenfe-MickaĂ«l Laventure Kevin Kern Kevin Parsons Kevin Xu +Kitt Hsu Kohei Tokunaga Krasi Georgiev Lantao Liu @@ -69,6 +76,7 @@ Lantao Liu Li Yuxuan Lifubang Lu Jingxiao +Maksym Pavlenko <865334+mxpv@users.noreply.github.com> Maksym Pavlenko Maksym Pavlenko Mario Hros @@ -79,6 +87,9 @@ Michael Crosby Michael Katsoulis Mike Brown Mohammad Asif Siddiqui +Ng Yang +Ning Li +ningmingxiao Nishchay Kumar Oliver Stenbom Phil Estes @@ -104,16 +115,20 @@ Stephen J Day Sudeesh John Su Fei Su Xiaolin +Takumasa Sakao Ted Yu TĂ”nis Tiigi Wade Lee Wade Lee Wade Lee <21621232@zju.edu.cn> wanglei +wanglei +wangzhan Wei Fu Wei Fu Xiaodong Zhang Xuean Yan +Yang Yang Yue Zhang Yuxing Liu Zhang Wei @@ -124,4 +139,5 @@ Zhiyu Li <404977848@qq.com> Zhongming Chang Zhoulin Xie Zhoulin Xie <42261994+JoeWrightss@users.noreply.github.com> +zounengren ćŒ æœ‡ diff --git a/vendor/github.com/containerd/containerd/ADOPTERS.md b/vendor/github.com/containerd/containerd/ADOPTERS.md index 4d70cca639..bbf99e7dd5 100644 --- a/vendor/github.com/containerd/containerd/ADOPTERS.md +++ b/vendor/github.com/containerd/containerd/ADOPTERS.md @@ -12,10 +12,14 @@ including the Balena project listed below. **_[IBM Cloud Private (ICP)](https://www.ibm.com/cloud/private)_** - IBM's on-premises cloud offering has containerd as a "tech preview" CRI runtime for the Kubernetes offered within this product for the past two releases, and plans to fully migrate to containerd in a future release. -**_[Google Cloud Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine/)_** - offers containerd as the CRI runtime in **beta** for recent versions of Kubernetes. +**_[Google Cloud Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine/)_** - containerd has been offered in GKE since version 1.14 and has been the default runtime since version 1.19. It is also the only supported runtime for GKE Autopilot from the launch. [More details](https://cloud.google.com/kubernetes-engine/docs/concepts/using-containerd) **_[AWS Fargate](https://aws.amazon.com/fargate)_** - uses containerd + Firecracker (noted below) as the runtime and isolation technology for containers run in the Fargate platform. Fargate is a serverless, container-native compute offering from Amazon Web Services. +**_[Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/)_** - EKS optionally offers containerd as a CRI runtime starting with Kubernetes version 1.21. In Kubernetes 1.22 the default CRI runtime will be containerd. + +**_[Bottlerocket](https://aws.amazon.com/bottlerocket/)_** - Bottlerocket is a Linux distribution from Amazon Web Services purpose-built for containers using containerd as the core system runtime. + **_Cloud Foundry_** - The [Guardian container manager](https://github.com/cloudfoundry/guardian) for CF has been using OCI runC directly with additional code from CF managing the container image and filesystem interactions, but have recently migrated to use containerd as a replacement for the extra code they had written around runC. **_Alibaba's PouchContainer_** - The Alibaba [PouchContainer](https://github.com/alibaba/pouch) project uses containerd as its runtime for a cloud native offering that has unique isolation and image distribution capabilities. @@ -32,7 +36,7 @@ including the Balena project listed below. **_BuildKit_** - The Moby project's [BuildKit](https://github.com/moby/buildkit) can use either runC or containerd as build execution backends for building container images. BuildKit support has also been built into the Docker engine in recent releases, making BuildKit provide the backend to the `docker build` command. -**_Azure acs-engine_** - Microsoft Azure's [acs-engine](https://github.com/Azure/acs-engine) open source project has customizable deployment of Kubernetes clusters, where containerd is a selectable container runtime. At some point in the future Azure's AKS service will default to use containerd as the CRI runtime for deployed Kubernetes clusters. +**_[Azure Kubernetes Service (AKS)](https://azure.microsoft.com/services/kubernetes-service)_** - Microsoft's managed Kubernetes offering uses containerd for Linux nodes running v1.19 or greater. Containerd for Windows nodes is currently in public preview. [More Details](https://docs.microsoft.com/azure/aks/cluster-configuration#container-runtime-configuration) **_Amazon Firecracker_** - The AWS [Firecracker VMM project](http://firecracker-microvm.io/) has extended containerd with a new snapshotter and v2 shim to allow containerd to drive virtualized container processes via their VMM implementation. More details on their containerd integration are available in [their GitHub project](https://github.com/firecracker-microvm/firecracker-containerd). @@ -42,6 +46,12 @@ including the Balena project listed below. **_Inclavare Containers_** - [Inclavare Containers](https://github.com/alibaba/inclavare-containers) is an innovation of container runtime with the novel approach for launching protected containers in hardware-assisted Trusted Execution Environment (TEE) technology, aka Enclave, which can prevent the untrusted entity, such as Cloud Service Provider (CSP), from accessing the sensitive and confidential assets in use. +**_VMware TKG_** - [Tanzu Kubernetes Grid](https://tanzu.vmware.com/kubernetes-grid) VMware's Multicloud Kubernetes offering uses containerd as the default CRI runtime. + +**_VMware TCE_** - [Tanzu Community Edition](https://github.com/vmware-tanzu/community-edition) VMware's fully-featured, easy to manage, Kubernetes platform for learners and users. It is a freely available, community supported, and open source distribution of VMware Tanzu. It uses containerd as the default CRI runtime. + +**_[Talos Linux](https://www.talos.dev/)_** - Talos Linux is Linux designed for Kubernetes – secure, immutable, and minimal. Talos Linux is using containerd as the core system runtime and CRI implementation. + **_Other Projects_** - While the above list provides a cross-section of well known uses of containerd, the simplicity and clear API layer for containerd has inspired many smaller projects around providing simple container management platforms. Several examples of building higher layer functionality on top of the containerd base have come from various containerd community participants: - Michael Crosby's [boss](https://github.com/crosbymichael/boss) project, - Evan Hazlett's [stellar](https://github.com/ehazlett/stellar) project, diff --git a/vendor/github.com/containerd/containerd/BUILDING.md b/vendor/github.com/containerd/containerd/BUILDING.md index b50c780f2c..5310924ce8 100644 --- a/vendor/github.com/containerd/containerd/BUILDING.md +++ b/vendor/github.com/containerd/containerd/BUILDING.md @@ -15,7 +15,7 @@ This doc includes: To build the `containerd` daemon, and the `ctr` simple test client, the following build system dependencies are required: * Go 1.13.x or above except 1.14.x -* Protoc 3.x compiler and headers (download at the [Google protobuf releases page](https://github.com/google/protobuf/releases)) +* Protoc 3.x compiler and headers (download at the [Google protobuf releases page](https://github.com/protocolbuffers/protobuf/releases)) * Btrfs headers and libraries for your distribution. Note that building the btrfs driver can be disabled via the build tag `no_btrfs`, removing this dependency. ## Build the development environment @@ -32,9 +32,9 @@ git clone https://github.com/containerd/containerd For proper results, install the `protoc` release into `/usr/local` on your build system. For example, the following commands will download and install the 3.11.4 release for a 64-bit Linux host: -``` -$ wget -c https://github.com/google/protobuf/releases/download/v3.11.4/protoc-3.11.4-linux-x86_64.zip -$ sudo unzip protoc-3.11.4-linux-x86_64.zip -d /usr/local +```sh +wget -c https://github.com/protocolbuffers/protobuf/releases/download/v3.11.4/protoc-3.11.4-linux-x86_64.zip +sudo unzip protoc-3.11.4-linux-x86_64.zip -d /usr/local ``` `containerd` uses [Btrfs](https://en.wikipedia.org/wiki/Btrfs) it means that you @@ -46,38 +46,20 @@ need to satisfy these dependencies in your system: At this point you are ready to build `containerd` yourself! -## Build runc +## Runc -`runc` is the default container runtime used by `containerd` and is required to -run containerd. While it is okay to download a runc binary and install that on +Runc is the default container runtime used by `containerd` and is required to +run containerd. While it is okay to download a `runc` binary and install that on the system, sometimes it is necessary to build runc directly when working with -container runtime development. You can skip this step if you already have the -correct version of `runc` installed. - -`runc` requires `libseccomp`. You may need to install the missing dependencies: - -* CentOS/Fedora: `yum install libseccomp libseccomp-devel` -* Debian/Ubuntu: `apt-get install libseccomp libseccomp-dev` - - -For the quick and dirty installation, you can use the following: - -``` -git clone https://github.com/opencontainers/runc -cd runc -make -sudo make install -``` - -Make sure to follow the guidelines for versioning in [RUNC.md](/docs/RUNC.md) for the -best results. +container runtime development. Make sure to follow the guidelines for versioning +in [RUNC.md](/docs/RUNC.md) for the best results. ## Build containerd `containerd` uses `make` to create a repeatable build flow. It means that you can run: -``` +```sh cd containerd make ``` @@ -86,22 +68,44 @@ This is going to build all the project binaries in the `./bin/` directory. You can move them in your global path, `/usr/local/bin` with: -```sudo +```sh sudo make install ``` +The install prefix can be changed by passing the `PREFIX` variable (defaults +to `/usr/local`). + +Note: if you set one of these vars, set them to the same values on all make stages +(build as well as install). + +If you want to prepend an additional prefix on actual installation (eg. packaging or chroot install), +you can pass it via `DESTDIR` variable: + +```sh +sudo make install DESTDIR=/tmp/install-x973234/ +``` + +The above command installs the `containerd` binary to `/tmp/install-x973234/usr/local/bin/containerd` + +The current `DESTDIR` convention is supported since containerd v1.6. +Older releases was using `DESTDIR` for a different purpose that is similar to `PREFIX`. + + When making any changes to the gRPC API, you can use the installed `protoc` compiler to regenerate the API generated code packages with: -```sudo +```sh make generate ``` > *Note*: Several build tags are currently available: -> * `no_btrfs`: A build tag disables building the btrfs snapshot driver. > * `no_cri`: A build tag disables building Kubernetes [CRI](http://blog.kubernetes.io/2016/12/container-runtime-interface-cri-in-kubernetes.html) support into containerd. > See [here](https://github.com/containerd/cri-containerd#build-tags) for build tags of CRI plugin. -> * `no_devmapper`: A build tag disables building the device mapper snapshot driver. +> * snapshotters (alphabetical order) +> * `no_aufs`: A build tag disables building the aufs snapshot driver. +> * `no_btrfs`: A build tag disables building the Btrfs snapshot driver. +> * `no_devmapper`: A build tag disables building the device mapper snapshot driver. +> * `no_zfs`: A build tag disables building the ZFS snapshot driver. > > For example, adding `BUILDTAGS=no_btrfs` to your environment before calling the **binaries** > Makefile target will disable the btrfs driver within the containerd Go build. @@ -117,7 +121,7 @@ Please refer to [RUNC.md](/docs/RUNC.md) for the currently supported version of You can build static binaries by providing a few variables to `make`: -```sudo +```sh make EXTRA_FLAGS="-buildmode pie" \ EXTRA_LDFLAGS='-linkmode external -extldflags "-fno-PIC -static"' \ BUILDTAGS="netgo osusergo static_build" @@ -131,12 +135,12 @@ make EXTRA_FLAGS="-buildmode pie" \ The following instructions assume you are at the parent directory of containerd source directory. -## Build containerd +## Build containerd in a container You can build `containerd` via a Linux-based Docker container. You can build an image from this `Dockerfile`: -``` +```dockerfile FROM golang RUN apt-get update && \ @@ -158,10 +162,11 @@ This mounts `containerd` repository You are now ready to [build](#build-containerd): ```sh - make && make install +make && make install ``` -## Build containerd and runc +## Build containerd and runc in a container + To have complete core container runtime, you will need both `containerd` and `runc`. It is possible to build both of these via Docker container. You can use `git` to checkout `runc`: @@ -177,7 +182,6 @@ FROM golang RUN apt-get update && \ apt-get install -y libbtrfs-dev libseccomp-dev - ``` In our Docker container we will build `runc` build, which includes @@ -246,6 +250,7 @@ go test -v -run . -test.root ``` Example output from directly running `go test` to execute the `TestContainerList` test: + ```sh sudo go test -v -run "TestContainerList" . -test.root INFO[0000] running tests against containerd revision=f2ae8a020a985a8d9862c9eb5ab66902c2888361 version=v1.0.0-beta.2-49-gf2ae8a0 @@ -255,6 +260,10 @@ PASS ok github.com/containerd/containerd 4.778s ``` +> *Note*: in order to run `sudo go` you need to +> - either keep user PATH environment variable. ex: `sudo "PATH=$PATH" env go test ` +> - or use `go test -exec` ex: `go test -exec sudo -v -run "TestTarWithXattr" ./archive/ -test.root` + ## Additional tools ### containerd-stress diff --git a/vendor/github.com/containerd/containerd/Makefile b/vendor/github.com/containerd/containerd/Makefile index ef7b7606ed..5791d8fa22 100644 --- a/vendor/github.com/containerd/containerd/Makefile +++ b/vendor/github.com/containerd/containerd/Makefile @@ -15,16 +15,22 @@ # Go command to use for build GO ?= go +INSTALL ?= install # Root directory of the project (absolute path). ROOTDIR=$(dir $(abspath $(lastword $(MAKEFILE_LIST)))) # Base path used to install. -DESTDIR ?= /usr/local +# The files will be installed under `$(DESTDIR)/$(PREFIX)`. +# The convention of `DESTDIR` was changed in containerd v1.6. +PREFIX ?= /usr/local +DATADIR ?= $(PREFIX)/share +MANDIR ?= $(DATADIR)/man + TEST_IMAGE_LIST ?= # Used to populate variables in version package. -VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always) +VERSION ?= $(shell git describe --match 'v[0-9]*' --dirty='.m' --always) REVISION=$(shell git rev-parse HEAD)$(shell if ! git diff --no-ext-diff --quiet --exit-code; then echo .m; fi) PACKAGE=github.com/containerd/containerd SHIM_CGO_ENABLED ?= 0 @@ -68,7 +74,7 @@ endif WHALE = "đŸ‡©" ONI = "đŸ‘č" -RELEASE=containerd-$(VERSION:v%=%).${GOOS}-${GOARCH} +RELEASE=containerd-$(VERSION:v%=%)-${GOOS}-${GOARCH} CRIRELEASE=cri-containerd-$(VERSION:v%=%)-${GOOS}-${GOARCH} CRICNIRELEASE=cri-containerd-cni-$(VERSION:v%=%)-${GOOS}-${GOARCH} @@ -83,12 +89,14 @@ ifdef BUILDTAGS endif GO_BUILDTAGS ?= GO_BUILDTAGS += ${DEBUG_TAGS} -GO_TAGS=$(if $(GO_BUILDTAGS),-tags "$(GO_BUILDTAGS)",) +GO_TAGS=$(if $(GO_BUILDTAGS),-tags "$(strip $(GO_BUILDTAGS))",) GO_LDFLAGS=-ldflags '-X $(PKG)/version.Version=$(VERSION) -X $(PKG)/version.Revision=$(REVISION) -X $(PKG)/version.Package=$(PACKAGE) $(EXTRA_LDFLAGS)' SHIM_GO_LDFLAGS=-ldflags '-X $(PKG)/version.Version=$(VERSION) -X $(PKG)/version.Revision=$(REVISION) -X $(PKG)/version.Package=$(PACKAGE) -extldflags "-static" $(EXTRA_LDFLAGS)' # Project packages. PACKAGES=$(shell $(GO) list ${GO_TAGS} ./... | grep -v /vendor/ | grep -v /integration) +API_PACKAGES=$(shell (cd api && $(GO) list ${GO_TAGS} ./... | grep -v /vendor/ | grep -v /integration)) +NON_API_PACKAGES=$(shell $(GO) list ${GO_TAGS} ./... | grep -v /vendor/ | grep -v /integration | grep -v "containerd/api") TEST_REQUIRES_ROOT_PACKAGES=$(filter \ ${PACKAGES}, \ $(shell \ @@ -133,6 +141,9 @@ CRIDIR=$(OUTPUTDIR)/cri .PHONY: clean all AUTHORS build binaries test integration generate protos checkprotos coverage ci check help install uninstall vendor release mandir install-man genman install-cri-deps cri-release cri-cni-release cri-integration install-deps bin/cri-integration.test .DEFAULT: default +# Forcibly set the default goal to all, in case an include above brought in a rule definition. +.DEFAULT_GOAL := all + all: binaries check: proto-fmt ## run all linters @@ -150,7 +161,13 @@ generate: protos protos: bin/protoc-gen-gogoctrd ## generate protobuf @echo "$(WHALE) $@" - @PATH="${ROOTDIR}/bin:${PATH}" protobuild --quiet ${PACKAGES} + @find . -path ./vendor -prune -false -o -name '*.pb.go' | xargs rm + $(eval TMPDIR := $(shell mktemp -d)) + @mv ${ROOTDIR}/vendor ${TMPDIR} + @(cd ${ROOTDIR}/api && PATH="${ROOTDIR}/bin:${PATH}" protobuild --quiet ${API_PACKAGES}) + @(PATH="${ROOTDIR}/bin:${PATH}" protobuild --quiet ${NON_API_PACKAGES}) + @mv ${TMPDIR}/vendor ${ROOTDIR} + @rm -rf ${TMPDIR} check-protos: protos ## check if protobufs needs to be generated again @echo "$(WHALE) $@" @@ -194,7 +211,7 @@ bin/cri-integration.test: cri-integration: binaries bin/cri-integration.test ## run cri integration tests @echo "$(WHALE) $@" - @./script/test/cri-integration.sh + @bash -x ./script/test/cri-integration.sh @rm -rf bin/cri-integration.test benchmark: ## run benchmarks tests @@ -213,16 +230,16 @@ bin/%: cmd/% FORCE $(call BUILD_BINARY) bin/containerd-shim: cmd/containerd-shim FORCE # set !cgo and omit pie for a static shim build: https://github.com/golang/go/issues/17789#issuecomment-258542220 - @echo "$(WHALE) bin/containerd-shim" - @CGO_ENABLED=${SHIM_CGO_ENABLED} $(GO) build ${GO_BUILD_FLAGS} -o bin/containerd-shim ${SHIM_GO_LDFLAGS} ${GO_TAGS} ./cmd/containerd-shim + @echo "$(WHALE) $@" + @CGO_ENABLED=${SHIM_CGO_ENABLED} $(GO) build ${GO_BUILD_FLAGS} -o $@ ${SHIM_GO_LDFLAGS} ${GO_TAGS} ./cmd/containerd-shim bin/containerd-shim-runc-v1: cmd/containerd-shim-runc-v1 FORCE # set !cgo and omit pie for a static shim build: https://github.com/golang/go/issues/17789#issuecomment-258542220 - @echo "$(WHALE) bin/containerd-shim-runc-v1" - @CGO_ENABLED=${SHIM_CGO_ENABLED} $(GO) build ${GO_BUILD_FLAGS} -o bin/containerd-shim-runc-v1 ${SHIM_GO_LDFLAGS} ${GO_TAGS} ./cmd/containerd-shim-runc-v1 + @echo "$(WHALE) $@" + @CGO_ENABLED=${SHIM_CGO_ENABLED} $(GO) build ${GO_BUILD_FLAGS} -o $@ ${SHIM_GO_LDFLAGS} ${GO_TAGS} ./cmd/containerd-shim-runc-v1 bin/containerd-shim-runc-v2: cmd/containerd-shim-runc-v2 FORCE # set !cgo and omit pie for a static shim build: https://github.com/golang/go/issues/17789#issuecomment-258542220 - @echo "$(WHALE) bin/containerd-shim-runc-v2" - @CGO_ENABLED=${SHIM_CGO_ENABLED} $(GO) build ${GO_BUILD_FLAGS} -o bin/containerd-shim-runc-v2 ${SHIM_GO_LDFLAGS} ${GO_TAGS} ./cmd/containerd-shim-runc-v2 + @echo "$(WHALE) $@" + @CGO_ENABLED=${SHIM_CGO_ENABLED} $(GO) build ${GO_BUILD_FLAGS} -o $@ ${SHIM_GO_LDFLAGS} ${GO_TAGS} ./cmd/containerd-shim-runc-v2 binaries: $(BINARIES) ## build binaries @echo "$(WHALE) $@" @@ -238,30 +255,31 @@ genman: man/containerd.8 man/ctr.8 man/containerd.8: FORCE @echo "$(WHALE) $@" - $(GO) run cmd/gen-manpages/main.go $(@F) $(@D) + $(GO) run -mod=readonly ${GO_TAGS} cmd/gen-manpages/main.go $(@F) $(@D) man/ctr.8: FORCE @echo "$(WHALE) $@" - $(GO) run cmd/gen-manpages/main.go $(@F) $(@D) + $(GO) run -mod=readonly ${GO_TAGS} cmd/gen-manpages/main.go $(@F) $(@D) man/%: docs/man/%.md FORCE @echo "$(WHALE) $@" go-md2man -in "$<" -out "$@" define installmanpage -mkdir -p $(DESTDIR)/man/man$(2); -gzip -c $(1) >$(DESTDIR)/man/man$(2)/$(3).gz; +$(INSTALL) -d $(DESTDIR)$(MANDIR)/man$(2); +gzip -c $(1) >$(DESTDIR)$(MANDIR)/man$(2)/$(3).gz; endef -install-man: +install-man: man @echo "$(WHALE) $@" $(foreach manpage,$(addprefix man/,$(MANPAGES)), $(call installmanpage,$(manpage),$(subst .,,$(suffix $(manpage))),$(notdir $(manpage)))) + releases/$(RELEASE).tar.gz: $(BINARIES) @echo "$(WHALE) $@" @rm -rf releases/$(RELEASE) releases/$(RELEASE).tar.gz - @install -d releases/$(RELEASE)/bin - @install $(BINARIES) releases/$(RELEASE)/bin + @$(INSTALL) -d releases/$(RELEASE)/bin + @$(INSTALL) $(BINARIES) releases/$(RELEASE)/bin @tar -czf releases/$(RELEASE).tar.gz -C releases/$(RELEASE) bin @rm -rf releases/$(RELEASE) @@ -272,18 +290,18 @@ release: releases/$(RELEASE).tar.gz # install of cri deps into release output directory ifeq ($(GOOS),windows) install-cri-deps: $(BINARIES) - mkdir -p $(CRIDIR) + $(INSTALL) -d $(CRIDIR) DESTDIR=$(CRIDIR) script/setup/install-cni-windows cp bin/* $(CRIDIR) else install-cri-deps: $(BINARIES) @rm -rf ${CRIDIR} - @install -d ${CRIDIR}/usr/local/bin - @install -D -m 755 bin/* ${CRIDIR}/usr/local/bin - @install -d ${CRIDIR}/opt/containerd/cluster + @$(INSTALL) -d ${CRIDIR}/usr/local/bin + @$(INSTALL) -D -m 755 bin/* ${CRIDIR}/usr/local/bin + @$(INSTALL) -d ${CRIDIR}/opt/containerd/cluster @cp -r contrib/gce ${CRIDIR}/opt/containerd/cluster/ - @install -d ${CRIDIR}/etc/systemd/system - @install -m 644 containerd.service ${CRIDIR}/etc/systemd/system + @$(INSTALL) -d ${CRIDIR}/etc/systemd/system + @$(INSTALL) -m 644 containerd.service ${CRIDIR}/etc/systemd/system echo "CONTAINERD_VERSION: '$(VERSION:v%=%)'" | tee ${CRIDIR}/opt/containerd/cluster/version DESTDIR=$(CRIDIR) script/setup/install-runc @@ -291,8 +309,8 @@ install-cri-deps: $(BINARIES) DESTDIR=$(CRIDIR) script/setup/install-critools DESTDIR=$(CRIDIR) script/setup/install-imgcrypt - @install -d $(CRIDIR)/bin - @install $(BINARIES) $(CRIDIR)/bin + @$(INSTALL) -d $(CRIDIR)/bin + @$(INSTALL) $(BINARIES) $(CRIDIR)/bin endif ifeq ($(GOOS),windows) @@ -345,12 +363,12 @@ clean-test: ## clean up debris from previously failed tests install: ## install binaries @echo "$(WHALE) $@ $(BINARIES)" - @mkdir -p $(DESTDIR)/bin - @install $(BINARIES) $(DESTDIR)/bin + @$(INSTALL) -d $(DESTDIR)$(PREFIX)/bin + @$(INSTALL) $(BINARIES) $(DESTDIR)$(PREFIX)/bin uninstall: @echo "$(WHALE) $@" - @rm -f $(addprefix $(DESTDIR)/bin/,$(notdir $(BINARIES))) + @rm -f $(addprefix $(DESTDIR)$(PREFIX)/bin/,$(notdir $(BINARIES))) ifeq ($(GOOS),windows) install-deps: @@ -394,10 +412,23 @@ root-coverage: ## generate coverage profiles for unit tests that require root fi; \ done ) -vendor: ## vendor +vendor: ## ensure all the go.mod/go.sum files are up-to-date including vendor/ directory @echo "$(WHALE) $@" @$(GO) mod tidy @$(GO) mod vendor + @$(GO) mod verify + @(cd ${ROOTDIR}/integration/client && ${GO} mod tidy) + +verify-vendor: ## verify if all the go.mod/go.sum files are up-to-date + @echo "$(WHALE) $@" + $(eval TMPDIR := $(shell mktemp -d)) + @cp -R ${ROOTDIR} ${TMPDIR} + @(cd ${TMPDIR}/containerd && ${GO} mod tidy) + @(cd ${TMPDIR}/containerd/integration/client && ${GO} mod tidy) + @diff -r -u -q ${ROOTDIR} ${TMPDIR}/containerd + @rm -rf ${TMPDIR} + @${ROOTDIR}/script/verify-go-modules.sh integration/client + help: ## this help @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | sort diff --git a/vendor/github.com/containerd/containerd/Makefile.linux b/vendor/github.com/containerd/containerd/Makefile.linux index c3385313d6..aba7b149f8 100644 --- a/vendor/github.com/containerd/containerd/Makefile.linux +++ b/vendor/github.com/containerd/containerd/Makefile.linux @@ -20,7 +20,7 @@ COMMANDS += containerd-shim containerd-shim-runc-v1 containerd-shim-runc-v2 # check GOOS for cross compile builds ifeq ($(GOOS),linux) - ifneq ($(GOARCH),$(filter $(GOARCH),mips mipsle mips64 mips64le ppc64 riscv64)) + ifneq ($(GOARCH),$(filter $(GOARCH),mips mipsle mips64 mips64le ppc64)) GO_GCFLAGS += -buildmode=pie endif endif diff --git a/vendor/github.com/containerd/containerd/Makefile.windows b/vendor/github.com/containerd/containerd/Makefile.windows index 56164e4247..6e62a87cf8 100644 --- a/vendor/github.com/containerd/containerd/Makefile.windows +++ b/vendor/github.com/containerd/containerd/Makefile.windows @@ -22,7 +22,11 @@ ifeq ($(GOARCH),amd64) TESTFLAGS_RACE= -race endif -BINARIES:=$(addsuffix .exe,$(BINARIES)) +WINDOWS_SHIM=bin/containerd-shim-runhcs-v1.exe +BINARIES := $(addsuffix .exe,$(BINARIES)) $(WINDOWS_SHIM) + +$(WINDOWS_SHIM): script/setup/install-runhcs-shim go.mod + DESTDIR=$(CURDIR)/bin $< bin/%.exe: cmd/% FORCE $(BUILD_BINARY) diff --git a/vendor/github.com/containerd/containerd/Protobuild.toml b/vendor/github.com/containerd/containerd/Protobuild.toml index d88fcd68d4..ccc4e79cf0 100644 --- a/vendor/github.com/containerd/containerd/Protobuild.toml +++ b/vendor/github.com/containerd/containerd/Protobuild.toml @@ -31,28 +31,11 @@ plugins = ["grpc", "fieldpath"] "google/protobuf/duration.proto" = "github.com/gogo/protobuf/types" "google/rpc/status.proto" = "github.com/gogo/googleapis/google/rpc" -[[overrides]] -prefixes = ["github.com/containerd/containerd/api/events"] -plugins = ["fieldpath"] # disable grpc for this package - -[[overrides]] -prefixes = ["github.com/containerd/containerd/api/services/ttrpc/events/v1"] -plugins = ["ttrpc", "fieldpath"] - [[overrides]] # enable ttrpc and disable fieldpath and grpc for the shim prefixes = ["github.com/containerd/containerd/runtime/v1/shim/v1", "github.com/containerd/containerd/runtime/v2/task"] plugins = ["ttrpc"] -# Aggregrate the API descriptors to lock down API changes. -[[descriptors]] -prefix = "github.com/containerd/containerd/api" -target = "api/next.pb.txt" -ignore_files = [ - "google/protobuf/descriptor.proto", - "gogoproto/gogo.proto" -] - # Lock down runc config [[descriptors]] prefix = "github.com/containerd/containerd/runtime/linux/runctypes" diff --git a/vendor/github.com/containerd/containerd/README.md b/vendor/github.com/containerd/containerd/README.md index 1ecec1ff04..f876079abb 100644 --- a/vendor/github.com/containerd/containerd/README.md +++ b/vendor/github.com/containerd/containerd/README.md @@ -1,9 +1,9 @@ -![containerd banner](https://raw.githubusercontent.com/cncf/artwork/master/projects/containerd/horizontal/color/containerd-horizontal-color.png) +![containerd banner light mode](https://raw.githubusercontent.com/cncf/artwork/master/projects/containerd/horizontal/color/containerd-horizontal-color.png#gh-light-mode-only) +![containerd banner dark mode](https://raw.githubusercontent.com/cncf/artwork/master/projects/containerd/horizontal/white/containerd-horizontal-white.png#gh-dark-mode-only) [![PkgGoDev](https://pkg.go.dev/badge/github.com/containerd/containerd)](https://pkg.go.dev/github.com/containerd/containerd) [![Build Status](https://github.com/containerd/containerd/workflows/CI/badge.svg)](https://github.com/containerd/containerd/actions?query=workflow%3ACI) [![Nightlies](https://github.com/containerd/containerd/workflows/Nightly/badge.svg)](https://github.com/containerd/containerd/actions?query=workflow%3ANightly) -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fcontainerd%2Fcontainerd.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fcontainerd%2Fcontainerd?ref=badge_shield) [![Go Report Card](https://goreportcard.com/badge/github.com/containerd/containerd)](https://goreportcard.com/report/github.com/containerd/containerd) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1271/badge)](https://bestpractices.coreinfrastructure.org/projects/1271) @@ -21,7 +21,7 @@ We are a large inclusive OSS project that is welcoming help of any kind shape or * Documentation help is needed to make the product easier to consume and extend. * We need OSS community outreach / organizing help to get the word out; manage and create messaging and educational content; and to help with social media, community forums/groups, and google groups. -* We are actively inviting new [security advisors](https://github.com/containerd/project/blob/master/GOVERNANCE.md#security-advisors) to join the team. +* We are actively inviting new [security advisors](https://github.com/containerd/project/blob/main/GOVERNANCE.md#security-advisors) to join the team. * New sub-projects are being created, core and non-core that could use additional development help. * Each of the [containerd projects](https://github.com/containerd) has a list of issues currently being worked on or that need help resolving. - If the issue has not already been assigned to someone, or has not made recent progress and you are interested, please inquire. @@ -41,7 +41,7 @@ If you are interested in trying out containerd see our example at [Getting Start ## Nightly builds There are nightly builds available for download [here](https://github.com/containerd/containerd/actions?query=workflow%3ANightly). -Binaries are generated from `master` branch every night for `Linux` and `Windows`. +Binaries are generated from `main` branch every night for `Linux` and `Windows`. Please be aware: nightly builds might have critical bugs, it's not recommended for use in production and no support provided. @@ -68,6 +68,14 @@ your system. See more details in [Checkpoint and Restore](#checkpoint-and-restor Build requirements for developers are listed in [BUILDING](BUILDING.md). + +## Supported Registries + +Any registry which is compliant with the [OCI Distribution Specification](https://github.com/opencontainers/distribution-spec) +is supported by containerd. + +For configuring registries, see [registry host configuration documentation](docs/hosts.md) + ## Features ### Client @@ -77,8 +85,11 @@ containerd offers a full client package to help you integrate containerd into yo ```go import ( + "context" + "github.com/containerd/containerd" "github.com/containerd/containerd/cio" + "github.com/containerd/containerd/namespaces" ) @@ -269,7 +280,7 @@ loaded for the user's shell environment. `cri` is a native plugin of containerd. Since containerd 1.1, the cri plugin is built into the release binaries and enabled by default. > **Note:** As of containerd 1.5, the `cri` plugin is merged into the containerd/containerd repo. For example, the source code previously stored under [`containerd/cri/pkg`](https://github.com/containerd/cri/tree/release/1.4/pkg) -was moved to [`containerd/containerd/pkg/cri` package](https://github.com/containerd/containerd/tree/master/pkg/cri). +was moved to [`containerd/containerd/pkg/cri` package](https://github.com/containerd/containerd/tree/main/pkg/cri). The `cri` plugin has reached GA status, representing that it is: * Feature complete @@ -289,7 +300,7 @@ A Kubernetes incubator project, [cri-tools](https://github.com/kubernetes-sigs/c * [CRI Plugin Testing Guide](./docs/cri/testing.md) * [Debugging Pods, Containers, and Images with `crictl`](./docs/cri/crictl.md) * [Configuring `cri` Plugins](./docs/cri/config.md) -* [Configuring containerd](https://github.com/containerd/containerd/blob/master/docs/man/containerd-config.8.md) +* [Configuring containerd](https://github.com/containerd/containerd/blob/main/docs/man/containerd-config.8.md) ### Communication @@ -315,14 +326,14 @@ copy of the license, titled CC-BY-4.0, at http://creativecommons.org/licenses/by ## Project details -**containerd** is the primary open source project within the broader containerd GitHub repository. +**containerd** is the primary open source project within the broader containerd GitHub organization. However, all projects within the repo have common maintainership, governance, and contributing guidelines which are stored in a `project` repository commonly for all containerd projects. Please find all these core project documents, including the: - * [Project governance](https://github.com/containerd/project/blob/master/GOVERNANCE.md), - * [Maintainers](https://github.com/containerd/project/blob/master/MAINTAINERS), - * and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md) + * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), + * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS), + * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) information in our [`containerd/project`](https://github.com/containerd/project) repository. diff --git a/vendor/github.com/containerd/containerd/RELEASES.md b/vendor/github.com/containerd/containerd/RELEASES.md index 3fda9964aa..24762487c8 100644 --- a/vendor/github.com/containerd/containerd/RELEASES.md +++ b/vendor/github.com/containerd/containerd/RELEASES.md @@ -27,7 +27,7 @@ considered "pre-releases". ### Major and Minor Releases -Major and minor releases of containerd will be made from master. Releases of +Major and minor releases of containerd will be made from main. Releases of containerd will be marked with GPG signed tags and announced at https://github.com/containerd/containerd/releases. The tag will be of the format `v..` and should be made with the command `git tag @@ -43,7 +43,7 @@ done against that branch. Pre-releases, such as alphas, betas and release candidates will be conducted from their source branch. For major and minor releases, these releases will be -done from master. For patch releases, these pre-releases should be done within +done from main. For patch releases, these pre-releases should be done within the corresponding release branch. While pre-releases are done to assist in the stabilization process, no @@ -89,7 +89,7 @@ whichever is longer. Additionally, releases may have an extended security suppor period after the end of the active period to accept security backports. This timeframe will be decided by maintainers before the end of the active status. -The current state is available in the following table: +The current state is available in the following tables: | Release | Status | Start | End of Life | |---------|-------------|------------------|-------------------| @@ -100,12 +100,27 @@ The current state is available in the following table: | [1.1](https://github.com/containerd/containerd/releases/tag/v1.1.8) | End of Life | April 23, 2018 | October 23, 2019 | | [1.2](https://github.com/containerd/containerd/releases/tag/v1.2.13) | End of Life | October 24, 2018 | October 15, 2020 | | [1.3](https://github.com/containerd/containerd/releases/tag/v1.3.10) | End of Life | September 26, 2019 | March 4, 2021 | -| [1.4](https://github.com/containerd/containerd/releases/tag/v1.4.4) | Active | August 17, 2020 | max(August 17, 2021, release of 1.5.0 + 6 months) | -| [1.5](https://github.com/containerd/containerd/milestone/30) | Next | TBD | max(TBD+1 year, release of 1.6.0 + 6 months) | +| [1.4](https://github.com/containerd/containerd/releases/tag/v1.4.12) | Extended | August 17, 2020 | March 3, 2022 (Extended) | +| [1.5](https://github.com/containerd/containerd/releases/tag/v1.5.9) | Active | May 3, 2021 | October 28, 2022 | +| [1.6](https://github.com/containerd/containerd/releases/tag/v1.6.0) | Active | February 15, 2022 | max(February 15, 2023 or release of 1.7.0 + 6 months) | +| [1.7](https://github.com/containerd/containerd/milestone/42) | Next | TBD | TBD | Note that branches and release from before 1.0 may not follow these rules. -This table should be updated as part of the release preparation process. +| CRI-Containerd Version | Containerd Version | Kubernetes Version | CRI Version | +|------------------------|--------------------|--------------------|--------------| +| v1.0.0-alpha.x | | 1.7, 1.8 | v1alpha1 | +| v1.0.0-beta.x | | 1.9 | v1alpha1 | +| End-Of-Life | v1.1 (End-Of-Life) | 1.10+ | v1alpha2 | +| | v1.2 (End-Of-Life) | 1.10+ | v1alpha2 | +| | v1.3 (End-Of-Life) | 1.12+ | v1alpha2 | +| | v1.4 | 1.19+ | v1alpha2 | +| | v1.5 | 1.20+ | v1alpha2 | +| | v1.6 | 1.23+ | v1, v1alpha2 | + +**Note:** The support table above specifies the Kubernetes Version that was supported at time of release of the containerd - cri integration and Kubernetes only supports n-3 minor release versions. + +These tables should be updated as part of the release preparation process. ### Backporting @@ -115,11 +130,11 @@ will be features for the next _minor_ or _major_ release. For the most part, this process is straightforward and we are here to help make it as smooth as possible. -If there are important fixes that need to be backported, please let use know in +If there are important fixes that need to be backported, please let us know in one of three ways: 1. Open an issue. -2. Open a PR with cherry-picked change from master. +2. Open a PR with cherry-picked change from main. 3. Open a PR with a ported fix. __If you are reporting a security issue, please reach out discreetly at security@containerd.io__. @@ -127,10 +142,10 @@ Remember that backported PRs must follow the versioning guidelines from this doc Any release that is "active" can accept backports. Opening a backport PR is fairly straightforward. The steps differ depending on whether you are pulling -a fix from master or need to draft a new commit specific to a particular +a fix from main or need to draft a new commit specific to a particular branch. -To cherry pick a straightforward commit from master, simply use the cherry pick +To cherry pick a straightforward commit from main, simply use the cherry pick process: 1. Pick the branch to which you want backported, usually in the format @@ -154,7 +169,7 @@ process: ``` Make sure to replace `stevvooe` with whatever fork you are using to open - the PR. When you open the PR, make sure to switch `master` with whatever + the PR. When you open the PR, make sure to switch `main` with whatever release branch you are targeting with the fix. Make sure the PR title has `[]` prefixed. e.g.: @@ -162,11 +177,11 @@ process: [release/1.4] Fix foo in bar ``` -If there is no existing fix in master, you should first fix the bug in master, +If there is no existing fix in main, you should first fix the bug in main, or ask us a maintainer or contributor to do it via an issue. Once that PR is completed, open a PR using the process above. -Only when the bug is not seen in master and must be made for the specific +Only when the bug is not seen in main and must be made for the specific release branch should you open a PR with new code. ## Public API Stability @@ -177,12 +192,12 @@ containerd versions: | Component | Status | Stabilized Version | Links | |------------------|----------|--------------------|---------------| -| GRPC API | Stable | 1.0 | [api/](api) | +| GRPC API | Stable | 1.0 | [gRPC API](#grpc-api) | | Metrics API | Stable | 1.0 | - | | Runtime Shim API | Stable | 1.2 | - | -| Daemon Config | Stable | 1.0 | - | +| Daemon Config | Stable | 1.0 | - | +| CRI GRPC API | Stable | 1.6 (_CRI v1_) | [cri-api](https://github.com/kubernetes/cri-api/tree/master/pkg/apis/runtime/v1) | | Go client API | Unstable | _future_ | [godoc](https://godoc.org/github.com/containerd/containerd) | -| CRI GRPC API | Unstable | v1alpha2 _current_ | [cri-api](https://github.com/kubernetes/cri-api/tree/master/pkg/apis/runtime/v1alpha2) | | `ctr` tool | Unstable | Out of scope | - | From the version stated in the above table, that component must adhere to the @@ -201,7 +216,7 @@ version jump. To ensure compatibility, we have collected the entire GRPC API symbol set into a single file. At each _minor_ release of containerd, we will move the current `next.pb.txt` file to a file named for the minor version, such as `1.0.pb.txt`, -enumerating the support services and messages. See [api/](api) for details. +enumerating the support services and messages. Note that new services may be added in _minor_ releases. New service methods and new fields on messages may be added if they are optional. @@ -321,9 +336,10 @@ against total impact. The deprecated features are shown in the following table: -| Component | Deprecation release | Target release for removal | Recommendation | -|----------------------------------------------------------------------|---------------------|----------------------------|-------------------------------| -| Runtime V1 API and implementation (`io.containerd.runtime.v1.linux`) | containerd v1.4 | containerd v2.0 | Use `io.containerd.runc.v2` | -| Runc V1 implementation of Runtime V2 (`io.containerd.runc.v1`) | containerd v1.4 | containerd v2.0 | Use `io.containerd.runc.v2` | -| config.toml `version = 1` | containerd v1.5 | containerd v2.0 | Use config.toml `version = 2` | -| Built-in `aufs` snapshotter | containerd v1.5 | containerd v2.0 | Use `overlayfs` snapshotter | +| Component | Deprecation release | Target release for removal | Recommendation | +|----------------------------------------------------------------------|---------------------|----------------------------|-----------------------------------| +| Runtime V1 API and implementation (`io.containerd.runtime.v1.linux`) | containerd v1.4 | containerd v2.0 | Use `io.containerd.runc.v2` | +| Runc V1 implementation of Runtime V2 (`io.containerd.runc.v1`) | containerd v1.4 | containerd v2.0 | Use `io.containerd.runc.v2` | +| config.toml `version = 1` | containerd v1.5 | containerd v2.0 | Use config.toml `version = 2` | +| Built-in `aufs` snapshotter | containerd v1.5 | containerd v2.0 | Use `overlayfs` snapshotter | +| `cri-containerd-*.tar.gz` release bundles | containerd v1.6 | containerd v2.0 | Use `containerd-*.tar.gz` bundles | diff --git a/vendor/github.com/containerd/containerd/Vagrantfile b/vendor/github.com/containerd/containerd/Vagrantfile index e294fe111f..16feb48a1a 100644 --- a/vendor/github.com/containerd/containerd/Vagrantfile +++ b/vendor/github.com/containerd/containerd/Vagrantfile @@ -17,7 +17,7 @@ # Vagrantfile for cgroup2 and SELinux Vagrant.configure("2") do |config| - config.vm.box = "fedora/34-cloud-base" + config.vm.box = "fedora/35-cloud-base" memory = 4096 cpus = 2 config.vm.provider :virtualbox do |v| @@ -77,7 +77,7 @@ Vagrant.configure("2") do |config| config.vm.provision "install-golang", type: "shell", run: "once" do |sh| sh.upload_path = "/tmp/vagrant-install-golang" sh.env = { - 'GO_VERSION': ENV['GO_VERSION'] || "1.16.14", + 'GO_VERSION': ENV['GO_VERSION'] || "1.17.7", } sh.inline = <<~SHELL #!/usr/bin/env bash @@ -257,4 +257,31 @@ EOF SHELL end + # Rootless Podman is used for testing CRI-in-UserNS + # (We could use rootless nerdctl, but we are using Podman here because it is available in dnf) + config.vm.provision "install-rootless-podman", type: "shell", run: "never" do |sh| + sh.upload_path = "/tmp/vagrant-install-rootless-podman" + sh.inline = <<~SHELL + #!/usr/bin/env bash + set -eux -o pipefail + # Delegate cgroup v2 controllers to rootless + mkdir -p /etc/systemd/system/user@.service.d + cat > /etc/systemd/system/user@.service.d/delegate.conf << EOF +[Service] +Delegate=yes +EOF + systemctl daemon-reload + # Install Podman + dnf install -y podman + # Configure Podman to resolve `golang` to `docker.io/library/golang` + mkdir -p /etc/containers + cat > /etc/containers/registries.conf < 0 { + i -= len(m.RuntimePath) + copy(dAtA[i:], m.RuntimePath) + i = encodeVarintTasks(dAtA, i, uint64(len(m.RuntimePath))) + i-- + dAtA[i] = 0x52 + } if m.Options != nil { { size, err := m.Options.MarshalToSizedBuffer(dAtA[:i]) @@ -3198,6 +3208,10 @@ func (m *CreateTaskRequest) Size() (n int) { l = m.Options.Size() n += 1 + l + sovTasks(uint64(l)) } + l = len(m.RuntimePath) + if l > 0 { + n += 1 + l + sovTasks(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -3747,6 +3761,7 @@ func (this *CreateTaskRequest) String() string { `Terminal:` + fmt.Sprintf("%v", this.Terminal) + `,`, `Checkpoint:` + strings.Replace(fmt.Sprintf("%v", this.Checkpoint), "Descriptor", "types.Descriptor", 1) + `,`, `Options:` + strings.Replace(fmt.Sprintf("%v", this.Options), "Any", "types1.Any", 1) + `,`, + `RuntimePath:` + fmt.Sprintf("%v", this.RuntimePath) + `,`, `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, `}`, }, "") @@ -4385,6 +4400,38 @@ func (m *CreateTaskRequest) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RuntimePath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTasks + } + 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 ErrInvalidLengthTasks + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTasks + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RuntimePath = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTasks(dAtA[iNdEx:]) diff --git a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.proto b/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.proto index 2fe72c64f8..6299c76026 100644 --- a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.proto +++ b/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.proto @@ -88,6 +88,8 @@ message CreateTaskRequest { containerd.types.Descriptor checkpoint = 8; google.protobuf.Any options = 9; + + string runtime_path = 10; } message CreateTaskResponse { diff --git a/vendor/github.com/containerd/containerd/api/services/version/v1/doc.go b/vendor/github.com/containerd/containerd/api/services/version/v1/doc.go new file mode 100644 index 0000000000..c5c0b85ddb --- /dev/null +++ b/vendor/github.com/containerd/containerd/api/services/version/v1/doc.go @@ -0,0 +1,18 @@ +/* + 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 version defines the version service. +package version diff --git a/vendor/github.com/containerd/containerd/api/types/task/doc.go b/vendor/github.com/containerd/containerd/api/types/task/doc.go new file mode 100644 index 0000000000..e10c7a4699 --- /dev/null +++ b/vendor/github.com/containerd/containerd/api/types/task/doc.go @@ -0,0 +1,18 @@ +/* + 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 task defines the task service. +package task diff --git a/vendor/github.com/containerd/containerd/archive/compression/compression.go b/vendor/github.com/containerd/containerd/archive/compression/compression.go index a883e4d58c..ceceb21f56 100644 --- a/vendor/github.com/containerd/containerd/archive/compression/compression.go +++ b/vendor/github.com/containerd/containerd/archive/compression/compression.go @@ -21,15 +21,16 @@ import ( "bytes" "compress/gzip" "context" + "encoding/binary" "fmt" "io" "os" - "os/exec" "strconv" "sync" "github.com/containerd/containerd/log" "github.com/klauspost/compress/zstd" + exec "golang.org/x/sys/execabs" ) type ( @@ -125,17 +126,52 @@ func (r *bufferedReader) Peek(n int) ([]byte, error) { return r.buf.Peek(n) } +const ( + zstdMagicSkippableStart = 0x184D2A50 + zstdMagicSkippableMask = 0xFFFFFFF0 +) + +var ( + gzipMagic = []byte{0x1F, 0x8B, 0x08} + zstdMagic = []byte{0x28, 0xb5, 0x2f, 0xfd} +) + +type matcher = func([]byte) bool + +func magicNumberMatcher(m []byte) matcher { + return func(source []byte) bool { + return bytes.HasPrefix(source, m) + } +} + +// zstdMatcher detects zstd compression algorithm. +// There are two frame formats defined by Zstandard: Zstandard frames and Skippable frames. +// See https://tools.ietf.org/id/draft-kucherawy-dispatch-zstd-00.html#rfc.section.2 for more details. +func zstdMatcher() matcher { + return func(source []byte) bool { + if bytes.HasPrefix(source, zstdMagic) { + // Zstandard frame + return true + } + // skippable frame + if len(source) < 8 { + return false + } + // magic number from 0x184D2A50 to 0x184D2A5F. + if binary.LittleEndian.Uint32(source[:4])&zstdMagicSkippableMask == zstdMagicSkippableStart { + return true + } + return false + } +} + // DetectCompression detects the compression algorithm of the source. func DetectCompression(source []byte) Compression { - for compression, m := range map[Compression][]byte{ - Gzip: {0x1F, 0x8B, 0x08}, - Zstd: {0x28, 0xb5, 0x2f, 0xfd}, + for compression, fn := range map[Compression]matcher{ + Gzip: magicNumberMatcher(gzipMagic), + Zstd: zstdMatcher(), } { - if len(source) < len(m) { - // Len too short - continue - } - if bytes.Equal(m, source[:len(m)]) { + if fn(source) { return compression } } diff --git a/vendor/github.com/containerd/containerd/archive/tar.go b/vendor/github.com/containerd/containerd/archive/tar.go index 78a287317f..62341d5e12 100644 --- a/vendor/github.com/containerd/containerd/archive/tar.go +++ b/vendor/github.com/containerd/containerd/archive/tar.go @@ -19,6 +19,8 @@ package archive import ( "archive/tar" "context" + "errors" + "fmt" "io" "os" "path/filepath" @@ -30,7 +32,6 @@ import ( "github.com/containerd/containerd/log" "github.com/containerd/continuity/fs" - "github.com/pkg/errors" ) var bufPool = &sync.Pool{ @@ -48,12 +49,15 @@ var errInvalidArchive = errors.New("invalid archive") // Produces a tar using OCI style file markers for deletions. Deleted // files will be prepended with the prefix ".wh.". This style is // based off AUFS whiteouts. -// See https://github.com/opencontainers/image-spec/blob/master/layer.md +// See https://github.com/opencontainers/image-spec/blob/main/layer.md func Diff(ctx context.Context, a, b string) io.ReadCloser { r, w := io.Pipe() go func() { err := WriteDiff(ctx, w, a, b) + if err != nil { + log.G(ctx).WithError(err).Debugf("write diff failed") + } if err = w.CloseWithError(err); err != nil { log.G(ctx).WithError(err).Debugf("closing tar pipe failed") } @@ -68,12 +72,12 @@ func Diff(ctx context.Context, a, b string) io.ReadCloser { // Produces a tar using OCI style file markers for deletions. Deleted // files will be prepended with the prefix ".wh.". This style is // based off AUFS whiteouts. -// See https://github.com/opencontainers/image-spec/blob/master/layer.md +// See https://github.com/opencontainers/image-spec/blob/main/layer.md func WriteDiff(ctx context.Context, w io.Writer, a, b string, opts ...WriteDiffOpt) error { var options WriteDiffOptions for _, opt := range opts { if err := opt(&options); err != nil { - return errors.Wrap(err, "failed to apply option") + return fmt.Errorf("failed to apply option: %w", err) } } if options.writeDiffFunc == nil { @@ -89,12 +93,12 @@ func WriteDiff(ctx context.Context, w io.Writer, a, b string, opts ...WriteDiffO // Produces a tar using OCI style file markers for deletions. Deleted // files will be prepended with the prefix ".wh.". This style is // based off AUFS whiteouts. -// See https://github.com/opencontainers/image-spec/blob/master/layer.md +// See https://github.com/opencontainers/image-spec/blob/main/layer.md func writeDiffNaive(ctx context.Context, w io.Writer, a, b string, _ WriteDiffOptions) error { - cw := newChangeWriter(w, b) + cw := NewChangeWriter(w, b) err := fs.Changes(ctx, a, b, cw.HandleChange) if err != nil { - return errors.Wrap(err, "failed to create diff tar stream") + return fmt.Errorf("failed to create diff tar stream: %w", err) } return cw.Close() } @@ -102,7 +106,7 @@ func writeDiffNaive(ctx context.Context, w io.Writer, a, b string, _ WriteDiffOp const ( // whiteoutPrefix prefix means file is a whiteout. If this is followed by a // filename this means that file has been removed from the base layer. - // See https://github.com/opencontainers/image-spec/blob/master/layer.md#whiteouts + // See https://github.com/opencontainers/image-spec/blob/main/layer.md#whiteouts whiteoutPrefix = ".wh." // whiteoutMetaPrefix prefix means whiteout has a special meaning and is not @@ -118,14 +122,14 @@ const ( ) // Apply applies a tar stream of an OCI style diff tar. -// See https://github.com/opencontainers/image-spec/blob/master/layer.md#applying-changesets +// See https://github.com/opencontainers/image-spec/blob/main/layer.md#applying-changesets func Apply(ctx context.Context, root string, r io.Reader, opts ...ApplyOpt) (int64, error) { root = filepath.Clean(root) var options ApplyOptions for _, opt := range opts { if err := opt(&options); err != nil { - return 0, errors.Wrap(err, "failed to apply option") + return 0, fmt.Errorf("failed to apply option: %w", err) } } if options.Filter == nil { @@ -140,7 +144,7 @@ func Apply(ctx context.Context, root string, r io.Reader, opts ...ApplyOpt) (int // applyNaive applies a tar stream of an OCI style diff tar to a directory // applying each file as either a whole file or whiteout. -// See https://github.com/opencontainers/image-spec/blob/master/layer.md#applying-changesets +// See https://github.com/opencontainers/image-spec/blob/main/layer.md#applying-changesets func applyNaive(ctx context.Context, root string, r io.Reader, options ApplyOptions) (size int64, err error) { var ( dirs []*tar.Header @@ -233,7 +237,7 @@ func applyNaive(ctx context.Context, root string, r io.Reader, options ApplyOpti ppath, base := filepath.Split(hdr.Name) ppath, err = fs.RootPath(root, ppath) if err != nil { - return 0, errors.Wrap(err, "failed to get root path") + return 0, fmt.Errorf("failed to get root path: %w", err) } // Join to root before joining to parent path to ensure relative links are @@ -263,7 +267,7 @@ func applyNaive(ctx context.Context, root string, r io.Reader, options ApplyOpti } writeFile, err := convertWhiteout(hdr, path) if err != nil { - return 0, errors.Wrapf(err, "failed to convert whiteout file %q", hdr.Name) + return 0, fmt.Errorf("failed to convert whiteout file %q: %w", hdr.Name, err) } if !writeFile { continue @@ -370,7 +374,7 @@ func createTarFile(ctx context.Context, path, extractDir string, hdr *tar.Header return nil default: - return errors.Errorf("unhandled tar header type %d\n", hdr.Typeflag) + return fmt.Errorf("unhandled tar header type %d", hdr.Typeflag) } // Lchown is not supported on Windows. @@ -461,7 +465,17 @@ func mkparent(ctx context.Context, path, root string, parents []string) error { return nil } -type changeWriter struct { +// ChangeWriter provides tar stream from filesystem change information. +// The privided tar stream is styled as an OCI layer. Change information +// (add/modify/delete/unmodified) for each file needs to be passed to this +// writer through HandleChange method. +// +// This should be used combining with continuity's diff computing functionality +// (e.g. `fs.Change` of github.com/containerd/continuity/fs). +// +// See also https://github.com/opencontainers/image-spec/blob/main/layer.md for details +// about OCI layers +type ChangeWriter struct { tw *tar.Writer source string whiteoutT time.Time @@ -470,8 +484,11 @@ type changeWriter struct { addedDirs map[string]struct{} } -func newChangeWriter(w io.Writer, source string) *changeWriter { - return &changeWriter{ +// NewChangeWriter returns ChangeWriter that writes tar stream of the source directory +// to the privided writer. Change information (add/modify/delete/unmodified) for each +// file needs to be passed through HandleChange method. +func NewChangeWriter(w io.Writer, source string) *ChangeWriter { + return &ChangeWriter{ tw: tar.NewWriter(w), source: source, whiteoutT: time.Now(), @@ -481,7 +498,10 @@ func newChangeWriter(w io.Writer, source string) *changeWriter { } } -func (cw *changeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, err error) error { +// HandleChange receives filesystem change information and reflect that information to +// the result tar stream. This function implements `fs.ChangeFunc` of continuity +// (github.com/containerd/continuity/fs) and should be used with that package. +func (cw *ChangeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, err error) error { if err != nil { return err } @@ -501,7 +521,7 @@ func (cw *changeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, e return err } if err := cw.tw.WriteHeader(hdr); err != nil { - return errors.Wrap(err, "failed to write whiteout header") + return fmt.Errorf("failed to write whiteout header: %w", err) } } else { var ( @@ -536,12 +556,12 @@ func (cw *changeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, e if strings.HasPrefix(name, string(filepath.Separator)) { name, err = filepath.Rel(string(filepath.Separator), name) if err != nil { - return errors.Wrap(err, "failed to make path relative") + return fmt.Errorf("failed to make path relative: %w", err) } } name, err = tarName(name) if err != nil { - return errors.Wrap(err, "cannot canonicalize path") + return fmt.Errorf("cannot canonicalize path: %w", err) } // suffix with '/' for directories if f.IsDir() && !strings.HasSuffix(name, "/") { @@ -550,7 +570,7 @@ func (cw *changeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, e hdr.Name = name if err := setHeaderForSpecialDevice(hdr, name, f); err != nil { - return errors.Wrap(err, "failed to set device headers") + return fmt.Errorf("failed to set device headers: %w", err) } // additionalLinks stores file names which must be linked to @@ -578,8 +598,8 @@ func (cw *changeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, e } if capability, err := getxattr(source, "security.capability"); err != nil { - return errors.Wrap(err, "failed to get capabilities xattr") - } else if capability != nil { + return fmt.Errorf("failed to get capabilities xattr: %w", err) + } else if len(capability) > 0 { if hdr.PAXRecords == nil { hdr.PAXRecords = map[string]string{} } @@ -590,19 +610,19 @@ func (cw *changeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, e return err } if err := cw.tw.WriteHeader(hdr); err != nil { - return errors.Wrap(err, "failed to write file header") + return fmt.Errorf("failed to write file header: %w", err) } if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 { file, err := open(source) if err != nil { - return errors.Wrapf(err, "failed to open path: %v", source) + return fmt.Errorf("failed to open path: %v: %w", source, err) } defer file.Close() n, err := copyBuffered(context.TODO(), cw.tw, file) if err != nil { - return errors.Wrap(err, "failed to copy") + return fmt.Errorf("failed to copy: %w", err) } if n != hdr.Size { return errors.New("short write copying file") @@ -621,7 +641,7 @@ func (cw *changeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, e return err } if err := cw.tw.WriteHeader(hdr); err != nil { - return errors.Wrap(err, "failed to write file header") + return fmt.Errorf("failed to write file header: %w", err) } } } @@ -629,14 +649,15 @@ func (cw *changeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, e return nil } -func (cw *changeWriter) Close() error { +// Close closes this writer. +func (cw *ChangeWriter) Close() error { if err := cw.tw.Close(); err != nil { - return errors.Wrap(err, "failed to close tar writer") + return fmt.Errorf("failed to close tar writer: %w", err) } return nil } -func (cw *changeWriter) includeParents(hdr *tar.Header) error { +func (cw *ChangeWriter) includeParents(hdr *tar.Header) error { if cw.addedDirs == nil { return nil } @@ -744,7 +765,7 @@ func validateWhiteout(path string) error { dir += string(filepath.Separator) } if !strings.HasPrefix(originalPath, dir) { - return errors.Wrapf(errInvalidArchive, "invalid whiteout name: %v", base) + return fmt.Errorf("invalid whiteout name: %v: %w", base, errInvalidArchive) } } return nil diff --git a/vendor/github.com/containerd/containerd/archive/tar_freebsd.go b/vendor/github.com/containerd/containerd/archive/tar_freebsd.go index ce4dffd6dd..fb5abff0ec 100644 --- a/vendor/github.com/containerd/containerd/archive/tar_freebsd.go +++ b/vendor/github.com/containerd/containerd/archive/tar_freebsd.go @@ -1,5 +1,3 @@ -// +build freebsd - /* Copyright The containerd Authors. diff --git a/vendor/github.com/containerd/containerd/archive/tar_mostunix.go b/vendor/github.com/containerd/containerd/archive/tar_mostunix.go index 9cd1f0fa8f..d2d970356c 100644 --- a/vendor/github.com/containerd/containerd/archive/tar_mostunix.go +++ b/vendor/github.com/containerd/containerd/archive/tar_mostunix.go @@ -1,3 +1,4 @@ +//go:build !windows && !freebsd // +build !windows,!freebsd /* diff --git a/vendor/github.com/containerd/containerd/archive/tar_opts_linux.go b/vendor/github.com/containerd/containerd/archive/tar_opts_linux.go index 38ef9e9bc7..f88d826e49 100644 --- a/vendor/github.com/containerd/containerd/archive/tar_opts_linux.go +++ b/vendor/github.com/containerd/containerd/archive/tar_opts_linux.go @@ -1,5 +1,3 @@ -// +build linux - /* Copyright The containerd Authors. diff --git a/vendor/github.com/containerd/containerd/archive/tar_opts_windows.go b/vendor/github.com/containerd/containerd/archive/tar_opts_windows.go index d3b8f4fb93..0ba3cd0822 100644 --- a/vendor/github.com/containerd/containerd/archive/tar_opts_windows.go +++ b/vendor/github.com/containerd/containerd/archive/tar_opts_windows.go @@ -1,5 +1,3 @@ -// +build windows - /* Copyright The containerd Authors. @@ -26,7 +24,7 @@ import ( ) // applyWindowsLayer applies a tar stream of an OCI style diff tar of a Windows layer -// See https://github.com/opencontainers/image-spec/blob/master/layer.md#applying-changesets +// See https://github.com/opencontainers/image-spec/blob/main/layer.md#applying-changesets func applyWindowsLayer(ctx context.Context, root string, r io.Reader, options ApplyOptions) (size int64, err error) { return ociwclayer.ImportLayerFromTar(ctx, r, root, options.Parents) } @@ -47,7 +45,7 @@ func AsWindowsContainerLayer() ApplyOpt { // Produces a tar using OCI style file markers for deletions. Deleted // files will be prepended with the prefix ".wh.". This style is // based off AUFS whiteouts. -// See https://github.com/opencontainers/image-spec/blob/master/layer.md +// See https://github.com/opencontainers/image-spec/blob/main/layer.md func writeDiffWindowsLayers(ctx context.Context, w io.Writer, _, layer string, options WriteDiffOptions) error { return ociwclayer.ExportLayerToTar(ctx, w, layer, options.ParentLayers) } diff --git a/vendor/github.com/containerd/containerd/archive/tar_unix.go b/vendor/github.com/containerd/containerd/archive/tar_unix.go index cd2be74a08..2f3a3a392e 100644 --- a/vendor/github.com/containerd/containerd/archive/tar_unix.go +++ b/vendor/github.com/containerd/containerd/archive/tar_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows /* @@ -20,14 +21,16 @@ package archive import ( "archive/tar" + "errors" + "fmt" "os" + "runtime" "strings" "syscall" "github.com/containerd/containerd/pkg/userns" "github.com/containerd/continuity/fs" "github.com/containerd/continuity/sysx" - "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -40,6 +43,20 @@ func chmodTarEntry(perm os.FileMode) os.FileMode { } func setHeaderForSpecialDevice(hdr *tar.Header, name string, fi os.FileInfo) error { + // Devmajor and Devminor are only needed for special devices. + + // In FreeBSD, RDev for regular files is -1 (unless overridden by FS): + // https://cgit.freebsd.org/src/tree/sys/kern/vfs_default.c?h=stable/13#n1531 + // (NODEV is -1: https://cgit.freebsd.org/src/tree/sys/sys/param.h?h=stable/13#n241). + + // ZFS in particular does not override the default: + // https://cgit.freebsd.org/src/tree/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c?h=stable/13#n2027 + + // Since `Stat_t.Rdev` is uint64, the cast turns -1 into (2^64 - 1). + // Such large values cannot be encoded in a tar header. + if runtime.GOOS == "freebsd" && hdr.Typeflag != tar.TypeBlock && hdr.Typeflag != tar.TypeChar { + return nil + } s, ok := fi.Sys().(*syscall.Stat_t) if !ok { return errors.New("unsupported stat type") @@ -69,6 +86,7 @@ func openFile(name string, flag int, perm os.FileMode) (*os.File, error) { } // Call chmod to avoid permission mask if err := os.Chmod(name, perm); err != nil { + f.Close() return nil, err } return f, err @@ -122,7 +140,7 @@ func getxattr(path, attr string) ([]byte, error) { func setxattr(path, key, value string) error { // Do not set trusted attributes if strings.HasPrefix(key, "trusted.") { - return errors.Wrap(unix.ENOTSUP, "admin attributes from archive not supported") + return fmt.Errorf("admin attributes from archive not supported: %w", unix.ENOTSUP) } return unix.Lsetxattr(path, key, []byte(value), 0) } @@ -142,12 +160,12 @@ func copyDirInfo(fi os.FileInfo, path string) error { } } if err != nil { - return errors.Wrapf(err, "failed to chown %s", path) + return fmt.Errorf("failed to chown %s: %w", path, err) } } if err := os.Chmod(path, fi.Mode()); err != nil { - return errors.Wrapf(err, "failed to chmod %s", path) + return fmt.Errorf("failed to chmod %s: %w", path, err) } timespec := []unix.Timespec{ @@ -155,7 +173,7 @@ func copyDirInfo(fi os.FileInfo, path string) error { unix.NsecToTimespec(syscall.TimespecToNsec(fs.StatMtime(st))), } if err := unix.UtimesNanoAt(unix.AT_FDCWD, path, timespec, unix.AT_SYMLINK_NOFOLLOW); err != nil { - return errors.Wrapf(err, "failed to utime %s", path) + return fmt.Errorf("failed to utime %s: %w", path, err) } return nil @@ -167,7 +185,7 @@ func copyUpXAttrs(dst, src string) error { if err == unix.ENOTSUP || err == sysx.ENODATA { return nil } - return errors.Wrapf(err, "failed to list xattrs on %s", src) + return fmt.Errorf("failed to list xattrs on %s: %w", src, err) } for _, xattr := range xattrKeys { // Do not copy up trusted attributes @@ -179,10 +197,10 @@ func copyUpXAttrs(dst, src string) error { if err == unix.ENOTSUP || err == sysx.ENODATA { continue } - return errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src) + return fmt.Errorf("failed to get xattr %q on %s: %w", xattr, src, err) } if err := lsetxattrCreate(dst, xattr, data); err != nil { - return errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst) + return fmt.Errorf("failed to set xattr %q on %s: %w", xattr, dst, err) } } diff --git a/vendor/github.com/containerd/containerd/archive/tar_windows.go b/vendor/github.com/containerd/containerd/archive/tar_windows.go index 3184070ac5..4b71c1e307 100644 --- a/vendor/github.com/containerd/containerd/archive/tar_windows.go +++ b/vendor/github.com/containerd/containerd/archive/tar_windows.go @@ -1,5 +1,3 @@ -// +build windows - /* Copyright The containerd Authors. @@ -20,12 +18,12 @@ package archive import ( "archive/tar" + "errors" "fmt" "os" "strings" "github.com/containerd/containerd/sys" - "github.com/pkg/errors" ) // tarName returns platform-specific filepath @@ -114,7 +112,7 @@ func setxattr(path, key, value string) error { func copyDirInfo(fi os.FileInfo, path string) error { if err := os.Chmod(path, fi.Mode()); err != nil { - return errors.Wrapf(err, "failed to chmod %s", path) + return fmt.Errorf("failed to chmod %s: %w", path, err) } return nil } diff --git a/vendor/github.com/containerd/containerd/archive/time_unix.go b/vendor/github.com/containerd/containerd/archive/time_unix.go index e05ca719c2..043e374538 100644 --- a/vendor/github.com/containerd/containerd/archive/time_unix.go +++ b/vendor/github.com/containerd/containerd/archive/time_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows /* @@ -19,11 +20,10 @@ package archive import ( + "fmt" "time" "golang.org/x/sys/unix" - - "github.com/pkg/errors" ) func chtimes(path string, atime, mtime time.Time) error { @@ -32,7 +32,7 @@ func chtimes(path string, atime, mtime time.Time) error { utimes[1] = unix.NsecToTimespec(mtime.UnixNano()) if err := unix.UtimesNanoAt(unix.AT_FDCWD, path, utimes[0:], unix.AT_SYMLINK_NOFOLLOW); err != nil { - return errors.Wrapf(err, "failed call to UtimesNanoAt for %s", path) + return fmt.Errorf("failed call to UtimesNanoAt for %s: %w", path, err) } return nil diff --git a/vendor/github.com/containerd/containerd/cio/io_unix.go b/vendor/github.com/containerd/containerd/cio/io_unix.go index 8b600673fe..5606cc88a9 100644 --- a/vendor/github.com/containerd/containerd/cio/io_unix.go +++ b/vendor/github.com/containerd/containerd/cio/io_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows /* @@ -20,15 +21,14 @@ package cio import ( "context" + "fmt" "io" - "io/ioutil" "os" "path/filepath" "sync" "syscall" "github.com/containerd/fifo" - "github.com/pkg/errors" ) // NewFIFOSetInDir returns a new FIFOSet with paths in a temporary directory under root @@ -38,7 +38,7 @@ func NewFIFOSetInDir(root, id string, terminal bool) (*FIFOSet, error) { return nil, err } } - dir, err := ioutil.TempDir(root, "") + dir, err := os.MkdirTemp(root, "") if err != nil { return nil, err } @@ -112,7 +112,7 @@ func openFifos(ctx context.Context, fifos *FIFOSet) (f pipes, retErr error) { if fifos.Stdin != "" { if f.Stdin, retErr = fifo.OpenFifo(ctx, fifos.Stdin, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); retErr != nil { - return f, errors.Wrapf(retErr, "failed to open stdin fifo") + return f, fmt.Errorf("failed to open stdin fifo: %w", retErr) } defer func() { if retErr != nil && f.Stdin != nil { @@ -122,7 +122,7 @@ func openFifos(ctx context.Context, fifos *FIFOSet) (f pipes, retErr error) { } if fifos.Stdout != "" { if f.Stdout, retErr = fifo.OpenFifo(ctx, fifos.Stdout, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); retErr != nil { - return f, errors.Wrapf(retErr, "failed to open stdout fifo") + return f, fmt.Errorf("failed to open stdout fifo: %w", retErr) } defer func() { if retErr != nil && f.Stdout != nil { @@ -132,7 +132,7 @@ func openFifos(ctx context.Context, fifos *FIFOSet) (f pipes, retErr error) { } if !fifos.Terminal && fifos.Stderr != "" { if f.Stderr, retErr = fifo.OpenFifo(ctx, fifos.Stderr, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); retErr != nil { - return f, errors.Wrapf(retErr, "failed to open stderr fifo") + return f, fmt.Errorf("failed to open stderr fifo: %w", retErr) } } return f, nil diff --git a/vendor/github.com/containerd/containerd/cio/io_windows.go b/vendor/github.com/containerd/containerd/cio/io_windows.go index ded475788f..f3d736a6d4 100644 --- a/vendor/github.com/containerd/containerd/cio/io_windows.go +++ b/vendor/github.com/containerd/containerd/cio/io_windows.go @@ -23,7 +23,6 @@ import ( winio "github.com/Microsoft/go-winio" "github.com/containerd/containerd/log" - "github.com/pkg/errors" ) const pipeRoot = `\\.\pipe` @@ -54,7 +53,7 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (_ *cio, retErr error) { if fifos.Stdin != "" { l, err := winio.ListenPipe(fifos.Stdin, nil) if err != nil { - return nil, errors.Wrapf(err, "failed to create stdin pipe %s", fifos.Stdin) + return nil, fmt.Errorf("failed to create stdin pipe %s: %w", fifos.Stdin, err) } cios.closers = append(cios.closers, l) @@ -77,7 +76,7 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (_ *cio, retErr error) { if fifos.Stdout != "" { l, err := winio.ListenPipe(fifos.Stdout, nil) if err != nil { - return nil, errors.Wrapf(err, "failed to create stdout pipe %s", fifos.Stdout) + return nil, fmt.Errorf("failed to create stdout pipe %s: %w", fifos.Stdout, err) } cios.closers = append(cios.closers, l) @@ -100,7 +99,7 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (_ *cio, retErr error) { if fifos.Stderr != "" { l, err := winio.ListenPipe(fifos.Stderr, nil) if err != nil { - return nil, errors.Wrapf(err, "failed to create stderr pipe %s", fifos.Stderr) + return nil, fmt.Errorf("failed to create stderr pipe %s: %w", fifos.Stderr, err) } cios.closers = append(cios.closers, l) diff --git a/vendor/github.com/containerd/containerd/client.go b/vendor/github.com/containerd/containerd/client.go index ace9bf6d14..1c2202e1ec 100644 --- a/vendor/github.com/containerd/containerd/client.go +++ b/vendor/github.com/containerd/containerd/client.go @@ -21,7 +21,6 @@ import ( "context" "encoding/json" "fmt" - "net/http" "runtime" "strconv" "strings" @@ -62,10 +61,10 @@ import ( ptypes "github.com/gogo/protobuf/types" ocispec "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" "golang.org/x/sync/semaphore" "google.golang.org/grpc" "google.golang.org/grpc/backoff" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/health/grpc_health_v1" ) @@ -119,31 +118,33 @@ func New(address string, opts ...ClientOpt) (*Client, error) { } gopts := []grpc.DialOption{ grpc.WithBlock(), - grpc.WithInsecure(), + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.FailOnNonTempDialError(true), grpc.WithConnectParams(connParams), grpc.WithContextDialer(dialer.ContextDialer), - - // TODO(stevvooe): We may need to allow configuration of this on the client. - grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)), - grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)), + grpc.WithReturnConnectionError(), } if len(copts.dialOptions) > 0 { gopts = copts.dialOptions } + gopts = append(gopts, grpc.WithDefaultCallOptions( + grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize), + grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize))) + if len(copts.callOptions) > 0 { + gopts = append(gopts, grpc.WithDefaultCallOptions(copts.callOptions...)) + } if copts.defaultns != "" { unary, stream := newNSInterceptors(copts.defaultns) - gopts = append(gopts, - grpc.WithUnaryInterceptor(unary), - grpc.WithStreamInterceptor(stream), - ) + gopts = append(gopts, grpc.WithChainUnaryInterceptor(unary)) + gopts = append(gopts, grpc.WithChainStreamInterceptor(stream)) } + connector := func() (*grpc.ClientConn, error) { ctx, cancel := context.WithTimeout(context.Background(), copts.timeout) defer cancel() conn, err := grpc.DialContext(ctx, dialer.DialAddress(address), gopts...) if err != nil { - return nil, errors.Wrapf(err, "failed to dial %q", address) + return nil, fmt.Errorf("failed to dial %q: %w", address, err) } return conn, nil } @@ -154,7 +155,7 @@ func New(address string, opts ...ClientOpt) (*Client, error) { c.conn, c.connector = conn, connector } if copts.services == nil && c.conn == nil { - return nil, errors.Wrap(errdefs.ErrUnavailable, "no grpc connection or services is available") + return nil, fmt.Errorf("no grpc connection or services is available: %w", errdefs.ErrUnavailable) } // check namespace labels for default runtime @@ -214,7 +215,7 @@ type Client struct { // Reconnect re-establishes the GRPC connection to the containerd daemon func (c *Client) Reconnect() error { if c.connector == nil { - return errors.Wrap(errdefs.ErrUnavailable, "unable to reconnect to containerd, no connector available") + return fmt.Errorf("unable to reconnect to containerd, no connector available: %w", errdefs.ErrUnavailable) } c.connMu.Lock() defer c.connMu.Unlock() @@ -242,7 +243,7 @@ func (c *Client) IsServing(ctx context.Context) (bool, error) { c.connMu.Lock() if c.conn == nil { c.connMu.Unlock() - return false, errors.Wrap(errdefs.ErrUnavailable, "no grpc connection available") + return false, fmt.Errorf("no grpc connection available: %w", errdefs.ErrUnavailable) } c.connMu.Unlock() r, err := c.HealthService().Check(ctx, &grpc_health_v1.HealthCheckRequest{}, grpc.WaitForReady(true)) @@ -265,8 +266,8 @@ func (c *Client) Containers(ctx context.Context, filters ...string) ([]Container return out, nil } -// NewContainer will create a new container in container with the provided id -// the id must be unique within the namespace +// NewContainer will create a new container with the provided id. +// The id must be unique within the namespace. func (c *Client) NewContainer(ctx context.Context, id string, opts ...NewContainerOpts) (Container, error) { ctx, done, err := c.WithLease(ctx) if err != nil { @@ -369,9 +370,7 @@ type RemoteContext struct { func defaultRemoteContext() *RemoteContext { return &RemoteContext{ - Resolver: docker.NewResolver(docker.ResolverOptions{ - Client: http.DefaultClient, - }), + Resolver: docker.NewResolver(docker.ResolverOptions{}), } } @@ -386,7 +385,7 @@ func (c *Client) Fetch(ctx context.Context, ref string, opts ...RemoteOpt) (imag } if fetchCtx.Unpack { - return images.Image{}, errors.Wrap(errdefs.ErrNotImplemented, "unpack on fetch not supported, try pull") + return images.Image{}, fmt.Errorf("unpack on fetch not supported, try pull: %w", errdefs.ErrNotImplemented) } if fetchCtx.PlatformMatcher == nil { @@ -397,7 +396,7 @@ func (c *Client) Fetch(ctx context.Context, ref string, opts ...RemoteOpt) (imag for _, s := range fetchCtx.Platforms { p, err := platforms.Parse(s) if err != nil { - return images.Image{}, errors.Wrapf(err, "invalid platform %s", s) + return images.Image{}, fmt.Errorf("invalid platform %s: %w", s, err) } ps = append(ps, p) } @@ -433,7 +432,7 @@ func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, for _, platform := range pushCtx.Platforms { p, err := platforms.Parse(platform) if err != nil { - return errors.Wrapf(err, "invalid platform %s", platform) + return fmt.Errorf("invalid platform %s: %w", platform, err) } ps = append(ps, p) } @@ -716,7 +715,7 @@ func (c *Client) Version(ctx context.Context) (Version, error) { c.connMu.Lock() if c.conn == nil { c.connMu.Unlock() - return Version{}, errors.Wrap(errdefs.ErrUnavailable, "no grpc connection available") + return Version{}, fmt.Errorf("no grpc connection available: %w", errdefs.ErrUnavailable) } c.connMu.Unlock() response, err := c.VersionService().Version(ctx, &ptypes.Empty{}) @@ -739,7 +738,7 @@ func (c *Client) Server(ctx context.Context) (ServerInfo, error) { c.connMu.Lock() if c.conn == nil { c.connMu.Unlock() - return ServerInfo{}, errors.Wrap(errdefs.ErrUnavailable, "no grpc connection available") + return ServerInfo{}, fmt.Errorf("no grpc connection available: %w", errdefs.ErrUnavailable) } c.connMu.Unlock() @@ -777,7 +776,7 @@ func (c *Client) getSnapshotter(ctx context.Context, name string) (snapshots.Sna s := c.SnapshotService(name) if s == nil { - return nil, errors.Wrapf(errdefs.ErrNotFound, "snapshotter %s was not found", name) + return nil, fmt.Errorf("snapshotter %s was not found: %w", name, errdefs.ErrNotFound) } return s, nil diff --git a/vendor/github.com/containerd/containerd/client_opts.go b/vendor/github.com/containerd/containerd/client_opts.go index 44feaa30ab..2ef7575d8a 100644 --- a/vendor/github.com/containerd/containerd/client_opts.go +++ b/vendor/github.com/containerd/containerd/client_opts.go @@ -34,6 +34,7 @@ type clientOpts struct { defaultPlatform platforms.MatchComparer services *services dialOptions []grpc.DialOption + callOptions []grpc.CallOption timeout time.Duration } @@ -75,6 +76,14 @@ func WithDialOpts(opts []grpc.DialOption) ClientOpt { } } +// WithCallOpts allows grpc.CallOptions to be set on the connection +func WithCallOpts(opts []grpc.CallOption) ClientOpt { + return func(c *clientOpts) error { + c.callOptions = opts + return nil + } +} + // WithServices sets services used by the client. func WithServices(opts ...ServicesOpt) ClientOpt { return func(c *clientOpts) error { diff --git a/vendor/github.com/containerd/containerd/container.go b/vendor/github.com/containerd/containerd/container.go index d5da55e518..7d8d674c89 100644 --- a/vendor/github.com/containerd/containerd/container.go +++ b/vendor/github.com/containerd/containerd/container.go @@ -19,6 +19,7 @@ package containerd import ( "context" "encoding/json" + "fmt" "os" "path/filepath" "strings" @@ -38,7 +39,6 @@ import ( ver "github.com/opencontainers/image-spec/specs-go" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/selinux/go-selinux/label" - "github.com/pkg/errors" ) const ( @@ -173,7 +173,7 @@ func (c *container) Spec(ctx context.Context) (*oci.Spec, error) { // an error is returned if the container has running tasks func (c *container) Delete(ctx context.Context, opts ...DeleteOpts) error { if _, err := c.loadTask(ctx, nil); err == nil { - return errors.Wrapf(errdefs.ErrFailedPrecondition, "cannot delete running task %v", c.id) + return fmt.Errorf("cannot delete running task %v: %w", c.id, errdefs.ErrFailedPrecondition) } r, err := c.get(ctx) if err != nil { @@ -198,11 +198,11 @@ func (c *container) Image(ctx context.Context) (Image, error) { return nil, err } if r.Image == "" { - return nil, errors.Wrap(errdefs.ErrNotFound, "container not created from an image") + return nil, fmt.Errorf("container not created from an image: %w", errdefs.ErrNotFound) } i, err := c.client.ImageService().Get(ctx, r.Image) if err != nil { - return nil, errors.Wrapf(err, "failed to get image %s for container", r.Image) + return nil, fmt.Errorf("failed to get image %s for container: %w", r.Image, err) } return NewImage(c.client, i), nil } @@ -232,7 +232,7 @@ func (c *container) NewTask(ctx context.Context, ioCreate cio.Creator, opts ...N } if r.SnapshotKey != "" { if r.Snapshotter == "" { - return nil, errors.Wrapf(errdefs.ErrInvalidArgument, "unable to resolve rootfs mounts without snapshotter on container") + return nil, fmt.Errorf("unable to resolve rootfs mounts without snapshotter on container: %w", errdefs.ErrInvalidArgument) } // get the rootfs from the snapshotter and add it to the request @@ -391,7 +391,7 @@ func (c *container) loadTask(ctx context.Context, ioAttach cio.Attach) (Task, er if err != nil { err = errdefs.FromGRPC(err) if errdefs.IsNotFound(err) { - return nil, errors.Wrapf(err, "no running task found") + return nil, fmt.Errorf("no running task found: %w", err) } return nil, err } diff --git a/vendor/github.com/containerd/containerd/container_checkpoint_opts.go b/vendor/github.com/containerd/containerd/container_checkpoint_opts.go index 510863681c..a64ef618ba 100644 --- a/vendor/github.com/containerd/containerd/container_checkpoint_opts.go +++ b/vendor/github.com/containerd/containerd/container_checkpoint_opts.go @@ -19,6 +19,7 @@ package containerd import ( "bytes" "context" + "errors" "fmt" "runtime" @@ -31,7 +32,6 @@ import ( "github.com/containerd/containerd/runtime/v2/runc/options" "github.com/containerd/typeurl" imagespec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) var ( diff --git a/vendor/github.com/containerd/containerd/container_opts.go b/vendor/github.com/containerd/containerd/container_opts.go index 024d6e10b6..4d630ea6c9 100644 --- a/vendor/github.com/containerd/containerd/container_opts.go +++ b/vendor/github.com/containerd/containerd/container_opts.go @@ -19,6 +19,7 @@ package containerd import ( "context" "encoding/json" + "errors" "fmt" "github.com/containerd/containerd/containers" @@ -31,7 +32,6 @@ import ( "github.com/gogo/protobuf/types" "github.com/opencontainers/image-spec/identity" v1 "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) // DeleteOpts allows the caller to set options for the deletion of a container @@ -227,7 +227,7 @@ func WithNewSnapshot(id string, i Image, opts ...snapshots.Opt) NewContainerOpts func WithSnapshotCleanup(ctx context.Context, client *Client, c containers.Container) error { if c.SnapshotKey != "" { if c.Snapshotter == "" { - return errors.Wrapf(errdefs.ErrInvalidArgument, "container.Snapshotter must be set to cleanup rootfs snapshot") + return fmt.Errorf("container.Snapshotter must be set to cleanup rootfs snapshot: %w", errdefs.ErrInvalidArgument) } s, err := client.getSnapshotter(ctx, c.Snapshotter) if err != nil { @@ -276,15 +276,15 @@ func WithNewSnapshotView(id string, i Image, opts ...snapshots.Opt) NewContainer func WithContainerExtension(name string, extension interface{}) NewContainerOpts { return func(ctx context.Context, client *Client, c *containers.Container) error { if name == "" { - return errors.Wrapf(errdefs.ErrInvalidArgument, "extension key must not be zero-length") + return fmt.Errorf("extension key must not be zero-length: %w", errdefs.ErrInvalidArgument) } any, err := typeurl.MarshalAny(extension) if err != nil { if errors.Is(err, typeurl.ErrNotFound) { - return errors.Wrapf(err, "extension %q is not registered with the typeurl package, see `typeurl.Register`", name) + return fmt.Errorf("extension %q is not registered with the typeurl package, see `typeurl.Register`: %w", name, err) } - return errors.Wrap(err, "error marshalling extension") + return fmt.Errorf("error marshalling extension: %w", err) } if c.Extensions == nil { diff --git a/vendor/github.com/containerd/containerd/container_opts_unix.go b/vendor/github.com/containerd/containerd/container_opts_unix.go index b109a10ecb..b6fc37db92 100644 --- a/vendor/github.com/containerd/containerd/container_opts_unix.go +++ b/vendor/github.com/containerd/containerd/container_opts_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows /* diff --git a/vendor/github.com/containerd/containerd/container_restore_opts.go b/vendor/github.com/containerd/containerd/container_restore_opts.go index fb60e8de9d..bdc8650cda 100644 --- a/vendor/github.com/containerd/containerd/container_restore_opts.go +++ b/vendor/github.com/containerd/containerd/container_restore_opts.go @@ -18,6 +18,8 @@ package containerd import ( "context" + "errors" + "fmt" "github.com/containerd/containerd/containers" "github.com/containerd/containerd/content" @@ -26,7 +28,6 @@ import ( ptypes "github.com/gogo/protobuf/types" "github.com/opencontainers/image-spec/identity" imagespec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) var ( @@ -46,7 +47,7 @@ func WithRestoreImage(ctx context.Context, id string, client *Client, checkpoint return func(ctx context.Context, client *Client, c *containers.Container) error { name, ok := index.Annotations[checkpointImageNameLabel] if !ok || name == "" { - return ErrRuntimeNameNotFoundInIndex + return ErrImageNameNotFoundInIndex } snapshotter, ok := index.Annotations[checkpointSnapshotterNameLabel] if !ok || name == "" { @@ -92,7 +93,7 @@ func WithRestoreRuntime(ctx context.Context, id string, client *Client, checkpoi store := client.ContentStore() data, err := content.ReadBlob(ctx, store, *m) if err != nil { - return errors.Wrap(err, "unable to read checkpoint runtime") + return fmt.Errorf("unable to read checkpoint runtime: %w", err) } if err := proto.Unmarshal(data, &options); err != nil { return err @@ -117,7 +118,7 @@ func WithRestoreSpec(ctx context.Context, id string, client *Client, checkpoint store := client.ContentStore() data, err := content.ReadBlob(ctx, store, *m) if err != nil { - return errors.Wrap(err, "unable to read checkpoint config") + return fmt.Errorf("unable to read checkpoint config: %w", err) } var any ptypes.Any if err := proto.Unmarshal(data, &any); err != nil { diff --git a/vendor/github.com/containerd/containerd/content/helpers.go b/vendor/github.com/containerd/containerd/content/helpers.go index 00fae1fc80..3ec1ffce00 100644 --- a/vendor/github.com/containerd/containerd/content/helpers.go +++ b/vendor/github.com/containerd/containerd/content/helpers.go @@ -18,8 +18,9 @@ package content import ( "context" + "errors" + "fmt" "io" - "io/ioutil" "math/rand" "sync" "time" @@ -27,7 +28,6 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) var bufPool = sync.Pool{ @@ -77,7 +77,7 @@ func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, desc o cw, err := OpenWriter(ctx, cs, WithRef(ref), WithDescriptor(desc)) if err != nil { if !errdefs.IsAlreadyExists(err) { - return errors.Wrap(err, "failed to open writer") + return fmt.Errorf("failed to open writer: %w", err) } return nil // all ready present @@ -134,28 +134,28 @@ func OpenWriter(ctx context.Context, cs Ingester, opts ...WriterOpt) (Writer, er func Copy(ctx context.Context, cw Writer, r io.Reader, size int64, expected digest.Digest, opts ...Opt) error { ws, err := cw.Status() if err != nil { - return errors.Wrap(err, "failed to get status") + return fmt.Errorf("failed to get status: %w", err) } if ws.Offset > 0 { r, err = seekReader(r, ws.Offset, size) if err != nil { - return errors.Wrapf(err, "unable to resume write to %v", ws.Ref) + return fmt.Errorf("unable to resume write to %v: %w", ws.Ref, err) } } copied, err := copyWithBuffer(cw, r) if err != nil { - return errors.Wrap(err, "failed to copy") + return fmt.Errorf("failed to copy: %w", err) } if size != 0 && copied < size-ws.Offset { // Short writes would return its own error, this indicates a read failure - return errors.Wrapf(io.ErrUnexpectedEOF, "failed to read expected number of bytes") + return fmt.Errorf("failed to read expected number of bytes: %w", io.ErrUnexpectedEOF) } if err := cw.Commit(ctx, size, expected, opts...); err != nil { if !errdefs.IsAlreadyExists(err) { - return errors.Wrapf(err, "failed commit on ref %q", ws.Ref) + return fmt.Errorf("failed commit on ref %q: %w", ws.Ref, err) } } @@ -172,11 +172,11 @@ func CopyReaderAt(cw Writer, ra ReaderAt, n int64) error { copied, err := copyWithBuffer(cw, io.NewSectionReader(ra, ws.Offset, n)) if err != nil { - return errors.Wrap(err, "failed to copy") + return fmt.Errorf("failed to copy: %w", err) } if copied < n { // Short writes would return its own error, this indicates a read failure - return errors.Wrap(io.ErrUnexpectedEOF, "failed to read expected number of bytes") + return fmt.Errorf("failed to read expected number of bytes: %w", io.ErrUnexpectedEOF) } return nil } @@ -190,13 +190,13 @@ func CopyReaderAt(cw Writer, ra ReaderAt, n int64) error { func CopyReader(cw Writer, r io.Reader) (int64, error) { ws, err := cw.Status() if err != nil { - return 0, errors.Wrap(err, "failed to get status") + return 0, fmt.Errorf("failed to get status: %w", err) } if ws.Offset > 0 { r, err = seekReader(r, ws.Offset, 0) if err != nil { - return 0, errors.Wrapf(err, "unable to resume write to %v", ws.Ref) + return 0, fmt.Errorf("unable to resume write to %v: %w", ws.Ref, err) } } @@ -212,7 +212,10 @@ func seekReader(r io.Reader, offset, size int64) (io.Reader, error) { if ok { nn, err := seeker.Seek(offset, io.SeekStart) if nn != offset { - return nil, errors.Wrapf(err, "failed to seek to offset %v", offset) + if err == nil { + err = fmt.Errorf("unexpected seek location without seek error") + } + return nil, fmt.Errorf("failed to seek to offset %v: %w", offset, err) } if err != nil { @@ -230,12 +233,12 @@ func seekReader(r io.Reader, offset, size int64) (io.Reader, error) { } // well then, let's just discard up to the offset - n, err := copyWithBuffer(ioutil.Discard, io.LimitReader(r, offset)) + n, err := copyWithBuffer(io.Discard, io.LimitReader(r, offset)) if err != nil { - return nil, errors.Wrap(err, "failed to discard to offset") + return nil, fmt.Errorf("failed to discard to offset: %w", err) } if n != offset { - return nil, errors.Errorf("unable to discard to offset") + return nil, errors.New("unable to discard to offset") } return r, nil diff --git a/vendor/github.com/containerd/containerd/content/local/locks.go b/vendor/github.com/containerd/containerd/content/local/locks.go index d1d2d564df..1e59f39b30 100644 --- a/vendor/github.com/containerd/containerd/content/local/locks.go +++ b/vendor/github.com/containerd/containerd/content/local/locks.go @@ -17,11 +17,11 @@ package local import ( + "fmt" "sync" "time" "github.com/containerd/containerd/errdefs" - "github.com/pkg/errors" ) // Handles locking references @@ -41,7 +41,13 @@ func tryLock(ref string) error { defer locksMu.Unlock() if v, ok := locks[ref]; ok { - return errors.Wrapf(errdefs.ErrUnavailable, "ref %s locked since %s", ref, v.since) + // Returning the duration may help developers distinguish dead locks (long duration) from + // lock contentions (short duration). + now := time.Now() + return fmt.Errorf( + "ref %s locked for %s (since %s): %w", ref, now.Sub(v.since), v.since, + errdefs.ErrUnavailable, + ) } locks[ref] = &lock{time.Now()} diff --git a/vendor/github.com/containerd/containerd/content/local/readerat.go b/vendor/github.com/containerd/containerd/content/local/readerat.go index 5d3ae03903..a83c171bbd 100644 --- a/vendor/github.com/containerd/containerd/content/local/readerat.go +++ b/vendor/github.com/containerd/containerd/content/local/readerat.go @@ -17,10 +17,9 @@ package local import ( + "fmt" "os" - "github.com/pkg/errors" - "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" ) @@ -40,7 +39,7 @@ func OpenReader(p string) (content.ReaderAt, error) { return nil, err } - return nil, errors.Wrap(errdefs.ErrNotFound, "blob not found") + return nil, fmt.Errorf("blob not found: %w", errdefs.ErrNotFound) } fp, err := os.Open(p) @@ -49,7 +48,7 @@ func OpenReader(p string) (content.ReaderAt, error) { return nil, err } - return nil, errors.Wrap(errdefs.ErrNotFound, "blob not found") + return nil, fmt.Errorf("blob not found: %w", errdefs.ErrNotFound) } return sizeReaderAt{size: fi.Size(), fp: fp}, nil diff --git a/vendor/github.com/containerd/containerd/content/local/store.go b/vendor/github.com/containerd/containerd/content/local/store.go index 314d913673..457bbcd0eb 100644 --- a/vendor/github.com/containerd/containerd/content/local/store.go +++ b/vendor/github.com/containerd/containerd/content/local/store.go @@ -20,7 +20,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "math/rand" "os" "path/filepath" @@ -37,7 +36,6 @@ import ( digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) var bufPool = sync.Pool{ @@ -94,13 +92,13 @@ func NewLabeledStore(root string, ls LabelStore) (content.Store, error) { func (s *store) Info(ctx context.Context, dgst digest.Digest) (content.Info, error) { p, err := s.blobPath(dgst) if err != nil { - return content.Info{}, errors.Wrapf(err, "calculating blob info path") + return content.Info{}, fmt.Errorf("calculating blob info path: %w", err) } fi, err := os.Stat(p) if err != nil { if os.IsNotExist(err) { - err = errors.Wrapf(errdefs.ErrNotFound, "content %v", dgst) + err = fmt.Errorf("content %v: %w", dgst, errdefs.ErrNotFound) } return content.Info{}, err @@ -129,12 +127,12 @@ func (s *store) info(dgst digest.Digest, fi os.FileInfo, labels map[string]strin func (s *store) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.ReaderAt, error) { p, err := s.blobPath(desc.Digest) if err != nil { - return nil, errors.Wrapf(err, "calculating blob path for ReaderAt") + return nil, fmt.Errorf("calculating blob path for ReaderAt: %w", err) } reader, err := OpenReader(p) if err != nil { - return nil, errors.Wrapf(err, "blob %s expected at %s", desc.Digest, p) + return nil, fmt.Errorf("blob %s expected at %s: %w", desc.Digest, p, err) } return reader, nil @@ -147,7 +145,7 @@ func (s *store) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content. func (s *store) Delete(ctx context.Context, dgst digest.Digest) error { bp, err := s.blobPath(dgst) if err != nil { - return errors.Wrapf(err, "calculating blob path for delete") + return fmt.Errorf("calculating blob path for delete: %w", err) } if err := os.RemoveAll(bp); err != nil { @@ -155,7 +153,7 @@ func (s *store) Delete(ctx context.Context, dgst digest.Digest) error { return err } - return errors.Wrapf(errdefs.ErrNotFound, "content %v", dgst) + return fmt.Errorf("content %v: %w", dgst, errdefs.ErrNotFound) } return nil @@ -163,18 +161,18 @@ func (s *store) Delete(ctx context.Context, dgst digest.Digest) error { func (s *store) Update(ctx context.Context, info content.Info, fieldpaths ...string) (content.Info, error) { if s.ls == nil { - return content.Info{}, errors.Wrapf(errdefs.ErrFailedPrecondition, "update not supported on immutable content store") + return content.Info{}, fmt.Errorf("update not supported on immutable content store: %w", errdefs.ErrFailedPrecondition) } p, err := s.blobPath(info.Digest) if err != nil { - return content.Info{}, errors.Wrapf(err, "calculating blob path for update") + return content.Info{}, fmt.Errorf("calculating blob path for update: %w", err) } fi, err := os.Stat(p) if err != nil { if os.IsNotExist(err) { - err = errors.Wrapf(errdefs.ErrNotFound, "content %v", info.Digest) + err = fmt.Errorf("content %v: %w", info.Digest, errdefs.ErrNotFound) } return content.Info{}, err @@ -201,7 +199,7 @@ func (s *store) Update(ctx context.Context, info content.Info, fieldpaths ...str all = true labels = info.Labels default: - return content.Info{}, errors.Wrapf(errdefs.ErrInvalidArgument, "cannot update %q field on content info %q", path, info.Digest) + return content.Info{}, fmt.Errorf("cannot update %q field on content info %q: %w", path, info.Digest, errdefs.ErrInvalidArgument) } } } else { @@ -378,7 +376,7 @@ func (s *store) status(ingestPath string) (content.Status, error) { fi, err := os.Stat(dp) if err != nil { if os.IsNotExist(err) { - err = errors.Wrap(errdefs.ErrNotFound, err.Error()) + err = fmt.Errorf("%s: %w", err.Error(), errdefs.ErrNotFound) } return content.Status{}, err } @@ -386,19 +384,19 @@ func (s *store) status(ingestPath string) (content.Status, error) { ref, err := readFileString(filepath.Join(ingestPath, "ref")) if err != nil { if os.IsNotExist(err) { - err = errors.Wrap(errdefs.ErrNotFound, err.Error()) + err = fmt.Errorf("%s: %w", err.Error(), errdefs.ErrNotFound) } return content.Status{}, err } startedAt, err := readFileTimestamp(filepath.Join(ingestPath, "startedat")) if err != nil { - return content.Status{}, errors.Wrapf(err, "could not read startedat") + return content.Status{}, fmt.Errorf("could not read startedat: %w", err) } updatedAt, err := readFileTimestamp(filepath.Join(ingestPath, "updatedat")) if err != nil { - return content.Status{}, errors.Wrapf(err, "could not read updatedat") + return content.Status{}, fmt.Errorf("could not read updatedat: %w", err) } // because we don't write updatedat on every write, the mod time may @@ -461,7 +459,7 @@ func (s *store) Writer(ctx context.Context, opts ...content.WriterOpt) (content. // TODO(AkihiroSuda): we could create a random string or one calculated based on the context // https://github.com/containerd/containerd/issues/2129#issuecomment-380255019 if wOpts.Ref == "" { - return nil, errors.Wrap(errdefs.ErrInvalidArgument, "ref must not be empty") + return nil, fmt.Errorf("ref must not be empty: %w", errdefs.ErrInvalidArgument) } var lockErr error for count := uint64(0); count < 10; count++ { @@ -495,16 +493,16 @@ func (s *store) resumeStatus(ref string, total int64, digester digest.Digester) path, _, data := s.ingestPaths(ref) status, err := s.status(path) if err != nil { - return status, errors.Wrap(err, "failed reading status of resume write") + return status, fmt.Errorf("failed reading status of resume write: %w", err) } if ref != status.Ref { // NOTE(stevvooe): This is fairly catastrophic. Either we have some // layout corruption or a hash collision for the ref key. - return status, errors.Errorf("ref key does not match: %v != %v", ref, status.Ref) + return status, fmt.Errorf("ref key does not match: %v != %v", ref, status.Ref) } if total > 0 && status.Total > 0 && total != status.Total { - return status, errors.Errorf("provided total differs from status: %v != %v", total, status.Total) + return status, fmt.Errorf("provided total differs from status: %v != %v", total, status.Total) } // TODO(stevvooe): slow slow slow!!, send to goroutine or use resumable hashes @@ -528,10 +526,10 @@ func (s *store) writer(ctx context.Context, ref string, total int64, expected di if expected != "" { p, err := s.blobPath(expected) if err != nil { - return nil, errors.Wrap(err, "calculating expected blob path for writer") + return nil, fmt.Errorf("calculating expected blob path for writer: %w", err) } if _, err := os.Stat(p); err == nil { - return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v", expected) + return nil, fmt.Errorf("content %v: %w", expected, errdefs.ErrAlreadyExists) } } @@ -568,7 +566,7 @@ func (s *store) writer(ctx context.Context, ref string, total int64, expected di // the ingest is new, we need to setup the target location. // write the ref to a file for later use - if err := ioutil.WriteFile(refp, []byte(ref), 0666); err != nil { + if err := os.WriteFile(refp, []byte(ref), 0666); err != nil { return nil, err } @@ -581,7 +579,7 @@ func (s *store) writer(ctx context.Context, ref string, total int64, expected di } if total > 0 { - if err := ioutil.WriteFile(filepath.Join(path, "total"), []byte(fmt.Sprint(total)), 0666); err != nil { + if err := os.WriteFile(filepath.Join(path, "total"), []byte(fmt.Sprint(total)), 0666); err != nil { return nil, err } } @@ -589,11 +587,12 @@ func (s *store) writer(ctx context.Context, ref string, total int64, expected di fp, err := os.OpenFile(data, os.O_WRONLY|os.O_CREATE, 0666) if err != nil { - return nil, errors.Wrap(err, "failed to open data file") + return nil, fmt.Errorf("failed to open data file: %w", err) } if _, err := fp.Seek(offset, io.SeekStart); err != nil { - return nil, errors.Wrap(err, "could not seek to current write offset") + fp.Close() + return nil, fmt.Errorf("could not seek to current write offset: %w", err) } return &writer{ @@ -615,7 +614,7 @@ func (s *store) Abort(ctx context.Context, ref string) error { root := s.ingestRoot(ref) if err := os.RemoveAll(root); err != nil { if os.IsNotExist(err) { - return errors.Wrapf(errdefs.ErrNotFound, "ingest ref %q", ref) + return fmt.Errorf("ingest ref %q: %w", ref, errdefs.ErrNotFound) } return err @@ -626,7 +625,7 @@ func (s *store) Abort(ctx context.Context, ref string) error { func (s *store) blobPath(dgst digest.Digest) (string, error) { if err := dgst.Validate(); err != nil { - return "", errors.Wrapf(errdefs.ErrInvalidArgument, "cannot calculate blob path from invalid digest: %v", err) + return "", fmt.Errorf("cannot calculate blob path from invalid digest: %v: %w", err, errdefs.ErrInvalidArgument) } return filepath.Join(s.root, "blobs", dgst.Algorithm().String(), dgst.Hex()), nil @@ -656,23 +655,23 @@ func (s *store) ingestPaths(ref string) (string, string, string) { } func readFileString(path string) (string, error) { - p, err := ioutil.ReadFile(path) + p, err := os.ReadFile(path) return string(p), err } // readFileTimestamp reads a file with just a timestamp present. func readFileTimestamp(p string) (time.Time, error) { - b, err := ioutil.ReadFile(p) + b, err := os.ReadFile(p) if err != nil { if os.IsNotExist(err) { - err = errors.Wrap(errdefs.ErrNotFound, err.Error()) + err = fmt.Errorf("%s: %w", err.Error(), errdefs.ErrNotFound) } return time.Time{}, err } var t time.Time if err := t.UnmarshalText(b); err != nil { - return time.Time{}, errors.Wrapf(err, "could not parse timestamp file %v", p) + return time.Time{}, fmt.Errorf("could not parse timestamp file %v: %w", p, err) } return t, nil @@ -683,19 +682,23 @@ func writeTimestampFile(p string, t time.Time) error { if err != nil { return err } - return atomicWrite(p, b, 0666) + return writeToCompletion(p, b, 0666) } -func atomicWrite(path string, data []byte, mode os.FileMode) error { +func writeToCompletion(path string, data []byte, mode os.FileMode) error { tmp := fmt.Sprintf("%s.tmp", path) f, err := os.OpenFile(tmp, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_SYNC, mode) if err != nil { - return errors.Wrap(err, "create tmp file") + return fmt.Errorf("create tmp file: %w", err) } _, err = f.Write(data) f.Close() if err != nil { - return errors.Wrap(err, "write atomic data") + return fmt.Errorf("write tmp file: %w", err) } - return os.Rename(tmp, path) + err = os.Rename(tmp, path) + if err != nil { + return fmt.Errorf("rename tmp file: %w", err) + } + return nil } diff --git a/vendor/github.com/containerd/containerd/content/local/store_bsd.go b/vendor/github.com/containerd/containerd/content/local/store_bsd.go index da149a2fda..42fddd3411 100644 --- a/vendor/github.com/containerd/containerd/content/local/store_bsd.go +++ b/vendor/github.com/containerd/containerd/content/local/store_bsd.go @@ -1,3 +1,4 @@ +//go:build darwin || freebsd || netbsd // +build darwin freebsd netbsd /* @@ -26,7 +27,7 @@ import ( func getATime(fi os.FileInfo) time.Time { if st, ok := fi.Sys().(*syscall.Stat_t); ok { - return time.Unix(int64(st.Atimespec.Sec), int64(st.Atimespec.Nsec)) //nolint: unconvert // int64 conversions ensure the line compiles for 32-bit systems as well. + return time.Unix(st.Atimespec.Unix()) } return fi.ModTime() diff --git a/vendor/github.com/containerd/containerd/content/local/store_openbsd.go b/vendor/github.com/containerd/containerd/content/local/store_openbsd.go index f34f0dad2b..2b58b617b9 100644 --- a/vendor/github.com/containerd/containerd/content/local/store_openbsd.go +++ b/vendor/github.com/containerd/containerd/content/local/store_openbsd.go @@ -1,3 +1,4 @@ +//go:build openbsd // +build openbsd /* @@ -26,7 +27,7 @@ import ( func getATime(fi os.FileInfo) time.Time { if st, ok := fi.Sys().(*syscall.Stat_t); ok { - return time.Unix(int64(st.Atim.Sec), int64(st.Atim.Nsec)) //nolint: unconvert // int64 conversions ensure the line compiles for 32-bit systems as well. + return time.Unix(st.Atim.Unix()) } return fi.ModTime() diff --git a/vendor/github.com/containerd/containerd/content/local/store_unix.go b/vendor/github.com/containerd/containerd/content/local/store_unix.go index 69a74bab0e..efa2eb9430 100644 --- a/vendor/github.com/containerd/containerd/content/local/store_unix.go +++ b/vendor/github.com/containerd/containerd/content/local/store_unix.go @@ -1,3 +1,4 @@ +//go:build linux || solaris // +build linux solaris /* @@ -26,7 +27,7 @@ import ( func getATime(fi os.FileInfo) time.Time { if st, ok := fi.Sys().(*syscall.Stat_t); ok { - return time.Unix(int64(st.Atim.Sec), int64(st.Atim.Nsec)) //nolint: unconvert // int64 conversions ensure the line compiles for 32-bit systems as well. + return time.Unix(st.Atim.Unix()) } return fi.ModTime() diff --git a/vendor/github.com/containerd/containerd/content/local/writer.go b/vendor/github.com/containerd/containerd/content/local/writer.go index 0a11f4d912..b187e524cb 100644 --- a/vendor/github.com/containerd/containerd/content/local/writer.go +++ b/vendor/github.com/containerd/containerd/content/local/writer.go @@ -18,6 +18,8 @@ package local import ( "context" + "errors" + "fmt" "io" "os" "path/filepath" @@ -28,7 +30,6 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" "github.com/opencontainers/go-digest" - "github.com/pkg/errors" ) // writer represents a write transaction against the blob store. @@ -88,30 +89,30 @@ func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest, w.fp = nil if fp == nil { - return errors.Wrap(errdefs.ErrFailedPrecondition, "cannot commit on closed writer") + return fmt.Errorf("cannot commit on closed writer: %w", errdefs.ErrFailedPrecondition) } if err := fp.Sync(); err != nil { fp.Close() - return errors.Wrap(err, "sync failed") + return fmt.Errorf("sync failed: %w", err) } fi, err := fp.Stat() closeErr := fp.Close() if err != nil { - return errors.Wrap(err, "stat on ingest file failed") + return fmt.Errorf("stat on ingest file failed: %w", err) } if closeErr != nil { - return errors.Wrap(err, "failed to close ingest file") + return fmt.Errorf("failed to close ingest file: %w", closeErr) } if size > 0 && size != fi.Size() { - return errors.Wrapf(errdefs.ErrFailedPrecondition, "unexpected commit size %d, expected %d", fi.Size(), size) + return fmt.Errorf("unexpected commit size %d, expected %d: %w", fi.Size(), size, errdefs.ErrFailedPrecondition) } dgst := w.digester.Digest() if expected != "" && expected != dgst { - return errors.Wrapf(errdefs.ErrFailedPrecondition, "unexpected commit digest %s, expected %s", dgst, expected) + return fmt.Errorf("unexpected commit digest %s, expected %s: %w", dgst, expected, errdefs.ErrFailedPrecondition) } var ( @@ -127,9 +128,9 @@ func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest, if _, err := os.Stat(target); err == nil { // collision with the target file! if err := os.RemoveAll(w.path); err != nil { - log.G(ctx).WithField("ref", w.ref).WithField("path", w.path).Errorf("failed to remove ingest directory") + log.G(ctx).WithField("ref", w.ref).WithField("path", w.path).Error("failed to remove ingest directory") } - return errors.Wrapf(errdefs.ErrAlreadyExists, "content %v", dgst) + return fmt.Errorf("content %v: %w", dgst, errdefs.ErrAlreadyExists) } if err := os.Rename(ingest, target); err != nil { @@ -142,17 +143,17 @@ func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest, commitTime := time.Now() if err := os.Chtimes(target, commitTime, commitTime); err != nil { - log.G(ctx).WithField("digest", dgst).Errorf("failed to change file time to commit time") + log.G(ctx).WithField("digest", dgst).Error("failed to change file time to commit time") } // clean up!! if err := os.RemoveAll(w.path); err != nil { - log.G(ctx).WithField("ref", w.ref).WithField("path", w.path).Errorf("failed to remove ingest directory") + log.G(ctx).WithField("ref", w.ref).WithField("path", w.path).Error("failed to remove ingest directory") } if w.s.ls != nil && base.Labels != nil { if err := w.s.ls.Set(dgst, base.Labels); err != nil { - log.G(ctx).WithField("digest", dgst).Errorf("failed to set labels") + log.G(ctx).WithField("digest", dgst).Error("failed to set labels") } } @@ -165,7 +166,7 @@ func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest, // NOTE: Windows does not support this operation if runtime.GOOS != "windows" { if err := os.Chmod(target, (fi.Mode()&os.ModePerm)&^0333); err != nil { - log.G(ctx).WithField("ref", w.ref).Errorf("failed to make readonly") + log.G(ctx).WithField("ref", w.ref).Error("failed to make readonly") } } diff --git a/vendor/github.com/containerd/containerd/content/proxy/content_writer.go b/vendor/github.com/containerd/containerd/content/proxy/content_writer.go index 8423335988..ffc0f50ea1 100644 --- a/vendor/github.com/containerd/containerd/content/proxy/content_writer.go +++ b/vendor/github.com/containerd/containerd/content/proxy/content_writer.go @@ -18,13 +18,13 @@ package proxy import ( "context" + "fmt" "io" contentapi "github.com/containerd/containerd/api/services/content/v1" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" digest "github.com/opencontainers/go-digest" - "github.com/pkg/errors" ) type remoteWriter struct { @@ -57,7 +57,7 @@ func (rw *remoteWriter) Status() (content.Status, error) { Action: contentapi.WriteActionStat, }) if err != nil { - return content.Status{}, errors.Wrap(errdefs.FromGRPC(err), "error getting writer status") + return content.Status{}, fmt.Errorf("error getting writer status: %w", errdefs.FromGRPC(err)) } return content.Status{ @@ -82,7 +82,7 @@ func (rw *remoteWriter) Write(p []byte) (n int, err error) { Data: p, }) if err != nil { - return 0, errors.Wrap(errdefs.FromGRPC(err), "failed to send write") + return 0, fmt.Errorf("failed to send write: %w", errdefs.FromGRPC(err)) } n = int(resp.Offset - offset) @@ -119,15 +119,15 @@ func (rw *remoteWriter) Commit(ctx context.Context, size int64, expected digest. Labels: base.Labels, }) if err != nil { - return errors.Wrap(errdefs.FromGRPC(err), "commit failed") + return fmt.Errorf("commit failed: %w", errdefs.FromGRPC(err)) } if size != 0 && resp.Offset != size { - return errors.Errorf("unexpected size: %v != %v", resp.Offset, size) + return fmt.Errorf("unexpected size: %v != %v", resp.Offset, size) } if expected != "" && resp.Digest != expected { - return errors.Errorf("unexpected digest: %v != %v", resp.Digest, expected) + return fmt.Errorf("unexpected digest: %v != %v", resp.Digest, expected) } rw.digest = resp.Digest diff --git a/vendor/github.com/containerd/containerd/contrib/nvidia/nvidia.go b/vendor/github.com/containerd/containerd/contrib/nvidia/nvidia.go index 6a351771ff..a808dd166c 100644 --- a/vendor/github.com/containerd/containerd/contrib/nvidia/nvidia.go +++ b/vendor/github.com/containerd/containerd/contrib/nvidia/nvidia.go @@ -20,13 +20,13 @@ import ( "context" "fmt" "os" - "os/exec" "strconv" "strings" "github.com/containerd/containerd/containers" "github.com/containerd/containerd/oci" specs "github.com/opencontainers/runtime-spec/specs-go" + exec "golang.org/x/sys/execabs" ) // NvidiaCLI is the path to the Nvidia helper binary @@ -111,6 +111,7 @@ type config struct { LDConfig string Requirements []string OCIHookPath string + NoCgroups bool } func (c *config) args() []string { @@ -137,6 +138,9 @@ func (c *config) args() []string { for _, r := range c.Requirements { args = append(args, fmt.Sprintf("--require=%s", r)) } + if c.NoCgroups { + args = append(args, "--no-cgroups") + } args = append(args, "--pid={{pid}}", "{{rootfs}}") return args } @@ -209,3 +213,9 @@ func WithLookupOCIHookPath(name string) Opts { return nil } } + +// WithNoCgroups passes --no-cgroups option to nvidia-container-cli. +func WithNoCgroups(c *config) error { + c.NoCgroups = true + return nil +} diff --git a/vendor/github.com/containerd/containerd/defaults/defaults_darwin.go b/vendor/github.com/containerd/containerd/defaults/defaults_darwin.go new file mode 100644 index 0000000000..1391884cde --- /dev/null +++ b/vendor/github.com/containerd/containerd/defaults/defaults_darwin.go @@ -0,0 +1,37 @@ +/* + 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 defaults + +const ( + // DefaultRootDir is the default location used by containerd to store + // persistent data + DefaultRootDir = "/var/lib/containerd" + // DefaultStateDir is the default location used by containerd to store + // transient data + DefaultStateDir = "/var/run/containerd" + // DefaultAddress is the default unix socket address + DefaultAddress = "/var/run/containerd/containerd.sock" + // DefaultDebugAddress is the default unix socket address for pprof data + DefaultDebugAddress = "/var/run/containerd/debug.sock" + // DefaultFIFODir is the default location used by client-side cio library + // to store FIFOs. + DefaultFIFODir = "/var/run/containerd/fifo" + // DefaultRuntime would be a multiple of choices, thus empty + DefaultRuntime = "" + // DefaultConfigDir is the default location for config files. + DefaultConfigDir = "/etc/containerd" +) diff --git a/vendor/github.com/containerd/containerd/defaults/defaults_unix.go b/vendor/github.com/containerd/containerd/defaults/defaults_unix.go index 6b69cd06b9..8e2619a381 100644 --- a/vendor/github.com/containerd/containerd/defaults/defaults_unix.go +++ b/vendor/github.com/containerd/containerd/defaults/defaults_unix.go @@ -1,4 +1,5 @@ -// +build !windows +//go:build !windows && !darwin +// +build !windows,!darwin /* Copyright The containerd Authors. diff --git a/vendor/github.com/containerd/containerd/defaults/defaults_windows.go b/vendor/github.com/containerd/containerd/defaults/defaults_windows.go index a80700075f..9f4bed8b07 100644 --- a/vendor/github.com/containerd/containerd/defaults/defaults_windows.go +++ b/vendor/github.com/containerd/containerd/defaults/defaults_windows.go @@ -1,5 +1,3 @@ -// +build windows - /* Copyright The containerd Authors. diff --git a/vendor/github.com/containerd/containerd/diff/diff.go b/vendor/github.com/containerd/containerd/diff/diff.go index 17aab616e5..235d6377c4 100644 --- a/vendor/github.com/containerd/containerd/diff/diff.go +++ b/vendor/github.com/containerd/containerd/diff/diff.go @@ -18,6 +18,7 @@ package diff import ( "context" + "io" "github.com/containerd/containerd/mount" "github.com/gogo/protobuf/types" @@ -37,6 +38,12 @@ type Config struct { // Labels are the labels to apply to the generated content Labels map[string]string + + // Compressor is a function to compress the diff stream + // instead of the default gzip compressor. Differ passes + // the MediaType of the target diff content to the compressor. + // When using this config, MediaType must be specified as well. + Compressor func(dest io.Writer, mediaType string) (io.WriteCloser, error) } // Opt is used to configure a diff operation @@ -71,6 +78,14 @@ type Applier interface { Apply(ctx context.Context, desc ocispec.Descriptor, mount []mount.Mount, opts ...ApplyOpt) (ocispec.Descriptor, error) } +// WithCompressor sets the function to be used to compress the diff stream. +func WithCompressor(f func(dest io.Writer, mediaType string) (io.WriteCloser, error)) Opt { + return func(c *Config) error { + c.Compressor = f + return nil + } +} + // WithMediaType sets the media type to use for creating the diff, without // specifying the differ will choose a default. func WithMediaType(m string) Opt { diff --git a/vendor/github.com/containerd/containerd/diff/stream.go b/vendor/github.com/containerd/containerd/diff/stream.go index 655f9ce838..44e35fcc81 100644 --- a/vendor/github.com/containerd/containerd/diff/stream.go +++ b/vendor/github.com/containerd/containerd/diff/stream.go @@ -18,6 +18,7 @@ package diff import ( "context" + "errors" "io" "os" @@ -25,7 +26,6 @@ import ( "github.com/containerd/containerd/images" "github.com/gogo/protobuf/types" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) var ( diff --git a/vendor/github.com/containerd/containerd/diff/stream_unix.go b/vendor/github.com/containerd/containerd/diff/stream_unix.go index d79fd71544..6622c331ee 100644 --- a/vendor/github.com/containerd/containerd/diff/stream_unix.go +++ b/vendor/github.com/containerd/containerd/diff/stream_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows /* @@ -21,15 +22,15 @@ package diff import ( "bytes" "context" + "errors" "fmt" "io" "os" - "os/exec" "sync" "github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/types" - "github.com/pkg/errors" + exec "golang.org/x/sys/execabs" ) // NewBinaryProcessor returns a binary processor for use with processing content streams diff --git a/vendor/github.com/containerd/containerd/diff/stream_windows.go b/vendor/github.com/containerd/containerd/diff/stream_windows.go index 19dcbacf5d..c0bf03b94a 100644 --- a/vendor/github.com/containerd/containerd/diff/stream_windows.go +++ b/vendor/github.com/containerd/containerd/diff/stream_windows.go @@ -1,5 +1,3 @@ -// +build windows - /* Copyright The containerd Authors. @@ -21,19 +19,18 @@ package diff import ( "bytes" "context" + "errors" "fmt" "io" - "io/ioutil" "os" - "os/exec" "path/filepath" "sync" winio "github.com/Microsoft/go-winio" "github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/types" - "github.com/pkg/errors" "github.com/sirupsen/logrus" + exec "golang.org/x/sys/execabs" ) const processorPipe = "STREAM_PROCESSOR_PIPE" @@ -157,7 +154,7 @@ func (c *binaryProcessor) Close() error { } func getUiqPath() (string, error) { - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") if err != nil { return "", err } diff --git a/vendor/github.com/containerd/containerd/errdefs/errors.go b/vendor/github.com/containerd/containerd/errdefs/errors.go index 05a35228ca..8762255970 100644 --- a/vendor/github.com/containerd/containerd/errdefs/errors.go +++ b/vendor/github.com/containerd/containerd/errdefs/errors.go @@ -17,7 +17,7 @@ // Package errdefs defines the common errors used throughout containerd // packages. // -// Use with errors.Wrap and error.Wrapf to add context to an error. +// Use with fmt.Errorf to add context to an error. // // To detect an error class, use the IsXXX functions to tell whether an error // is of a certain type. @@ -28,8 +28,7 @@ package errdefs import ( "context" - - "github.com/pkg/errors" + "errors" ) // Definitions of common error types used throughout containerd. All containerd diff --git a/vendor/github.com/containerd/containerd/errdefs/grpc.go b/vendor/github.com/containerd/containerd/errdefs/grpc.go index 209f63bd0f..7a9b33e05a 100644 --- a/vendor/github.com/containerd/containerd/errdefs/grpc.go +++ b/vendor/github.com/containerd/containerd/errdefs/grpc.go @@ -18,9 +18,9 @@ package errdefs import ( "context" + "fmt" "strings" - "github.com/pkg/errors" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -68,9 +68,9 @@ func ToGRPC(err error) error { // ToGRPCf maps the error to grpc error codes, assembling the formatting string // and combining it with the target error string. // -// This is equivalent to errors.ToGRPC(errors.Wrapf(err, format, args...)) +// This is equivalent to errdefs.ToGRPC(fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), err)) func ToGRPCf(err error, format string, args ...interface{}) error { - return ToGRPC(errors.Wrapf(err, format, args...)) + return ToGRPC(fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), err)) } // FromGRPC returns the underlying error from a grpc service based on the grpc error code @@ -104,9 +104,9 @@ func FromGRPC(err error) error { msg := rebaseMessage(cls, err) if msg != "" { - err = errors.Wrap(cls, msg) + err = fmt.Errorf("%s: %w", msg, cls) } else { - err = errors.WithStack(cls) + err = cls } return err diff --git a/vendor/github.com/containerd/containerd/events/exchange/exchange.go b/vendor/github.com/containerd/containerd/events/exchange/exchange.go index eb27bf29b3..a1f385d7ab 100644 --- a/vendor/github.com/containerd/containerd/events/exchange/exchange.go +++ b/vendor/github.com/containerd/containerd/events/exchange/exchange.go @@ -18,6 +18,7 @@ package exchange import ( "context" + "fmt" "strings" "time" @@ -30,7 +31,6 @@ import ( "github.com/containerd/typeurl" goevents "github.com/docker/go-events" "github.com/gogo/protobuf/types" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -88,10 +88,10 @@ func (e *Exchange) Publish(ctx context.Context, topic string, event events.Event namespace, err = namespaces.NamespaceRequired(ctx) if err != nil { - return errors.Wrapf(err, "failed publishing event") + return fmt.Errorf("failed publishing event: %w", err) } if err := validateTopic(topic); err != nil { - return errors.Wrapf(err, "envelope topic %q", topic) + return fmt.Errorf("envelope topic %q: %w", topic, err) } encoded, err = typeurl.MarshalAny(event) @@ -150,7 +150,7 @@ func (e *Exchange) Subscribe(ctx context.Context, fs ...string) (ch <-chan *even if len(fs) > 0 { filter, err := filters.ParseAll(fs...) if err != nil { - errq <- errors.Wrapf(err, "failed parsing subscription filters") + errq <- fmt.Errorf("failed parsing subscription filters: %w", err) closeAll() return } @@ -175,7 +175,7 @@ func (e *Exchange) Subscribe(ctx context.Context, fs ...string) (ch <-chan *even // TODO(stevvooe): For the most part, we are well protected // from this condition. Both Forward and Publish protect // from this. - err = errors.Errorf("invalid envelope encountered %#v; please file a bug", ev) + err = fmt.Errorf("invalid envelope encountered %#v; please file a bug", ev) break } @@ -203,21 +203,21 @@ func (e *Exchange) Subscribe(ctx context.Context, fs ...string) (ch <-chan *even func validateTopic(topic string) error { if topic == "" { - return errors.Wrap(errdefs.ErrInvalidArgument, "must not be empty") + return fmt.Errorf("must not be empty: %w", errdefs.ErrInvalidArgument) } if topic[0] != '/' { - return errors.Wrapf(errdefs.ErrInvalidArgument, "must start with '/'") + return fmt.Errorf("must start with '/': %w", errdefs.ErrInvalidArgument) } if len(topic) == 1 { - return errors.Wrapf(errdefs.ErrInvalidArgument, "must have at least one component") + return fmt.Errorf("must have at least one component: %w", errdefs.ErrInvalidArgument) } components := strings.Split(topic[1:], "/") for _, component := range components { if err := identifiers.Validate(component); err != nil { - return errors.Wrapf(err, "failed validation on component %q", component) + return fmt.Errorf("failed validation on component %q: %w", component, err) } } @@ -226,15 +226,15 @@ func validateTopic(topic string) error { func validateEnvelope(envelope *events.Envelope) error { if err := identifiers.Validate(envelope.Namespace); err != nil { - return errors.Wrapf(err, "event envelope has invalid namespace") + return fmt.Errorf("event envelope has invalid namespace: %w", err) } if err := validateTopic(envelope.Topic); err != nil { - return errors.Wrapf(err, "envelope topic %q", envelope.Topic) + return fmt.Errorf("envelope topic %q: %w", envelope.Topic, err) } if envelope.Timestamp.IsZero() { - return errors.Wrapf(errdefs.ErrInvalidArgument, "timestamp must be set on forwarded event") + return fmt.Errorf("timestamp must be set on forwarded event: %w", errdefs.ErrInvalidArgument) } return nil diff --git a/vendor/github.com/containerd/containerd/filters/parser.go b/vendor/github.com/containerd/containerd/filters/parser.go index 0825d668ca..49182d7b7b 100644 --- a/vendor/github.com/containerd/containerd/filters/parser.go +++ b/vendor/github.com/containerd/containerd/filters/parser.go @@ -21,7 +21,6 @@ import ( "io" "github.com/containerd/containerd/errdefs" - "github.com/pkg/errors" ) /* @@ -71,7 +70,7 @@ func ParseAll(ss ...string) (Filter, error) { for _, s := range ss { f, err := Parse(s) if err != nil { - return nil, errors.Wrap(errdefs.ErrInvalidArgument, err.Error()) + return nil, fmt.Errorf("%s: %w", err.Error(), errdefs.ErrInvalidArgument) } fs = append(fs, f) @@ -90,7 +89,7 @@ func (p *parser) parse() (Filter, error) { ss, err := p.selectors() if err != nil { - return nil, errors.Wrap(err, "filters") + return nil, fmt.Errorf("filters: %w", err) } return ss, nil @@ -284,9 +283,9 @@ func (pe parseError) Error() string { } func (p *parser) mkerr(pos int, format string, args ...interface{}) error { - return errors.Wrap(parseError{ + return fmt.Errorf("parse error: %w", parseError{ input: p.input, pos: pos, msg: fmt.Sprintf(format, args...), - }, "parse error") + }) } diff --git a/vendor/github.com/containerd/containerd/filters/quote.go b/vendor/github.com/containerd/containerd/filters/quote.go index 2d64e23a30..b76aab9b4a 100644 --- a/vendor/github.com/containerd/containerd/filters/quote.go +++ b/vendor/github.com/containerd/containerd/filters/quote.go @@ -17,9 +17,8 @@ package filters import ( + "errors" "unicode/utf8" - - "github.com/pkg/errors" ) // NOTE(stevvooe): Most of this code in this file is copied from the stdlib diff --git a/vendor/github.com/containerd/containerd/gc/gc.go b/vendor/github.com/containerd/containerd/gc/gc.go index 4f71cb305c..079a6eae97 100644 --- a/vendor/github.com/containerd/containerd/gc/gc.go +++ b/vendor/github.com/containerd/containerd/gc/gc.go @@ -59,6 +59,8 @@ type Stats interface { // // We can probably use this to inform a design for incremental GC by injecting // callbacks to the set modification algorithms. +// +// https://en.wikipedia.org/wiki/Tracing_garbage_collection#Tri-color_marking func Tricolor(roots []Node, refs func(ref Node) ([]Node, error)) (map[Node]struct{}, error) { var ( grays []Node // maintain a gray "stack" diff --git a/vendor/github.com/containerd/containerd/identifiers/validate.go b/vendor/github.com/containerd/containerd/identifiers/validate.go index f52317b491..cbd3a52ba9 100644 --- a/vendor/github.com/containerd/containerd/identifiers/validate.go +++ b/vendor/github.com/containerd/containerd/identifiers/validate.go @@ -25,10 +25,10 @@ package identifiers import ( + "fmt" "regexp" "github.com/containerd/containerd/errdefs" - "github.com/pkg/errors" ) const ( @@ -51,15 +51,15 @@ var ( // In general identifiers that pass this validation should be safe for use as filesystem path components. func Validate(s string) error { if len(s) == 0 { - return errors.Wrapf(errdefs.ErrInvalidArgument, "identifier must not be empty") + return fmt.Errorf("identifier must not be empty: %w", errdefs.ErrInvalidArgument) } if len(s) > maxLength { - return errors.Wrapf(errdefs.ErrInvalidArgument, "identifier %q greater than maximum length (%d characters)", s, maxLength) + return fmt.Errorf("identifier %q greater than maximum length (%d characters): %w", s, maxLength, errdefs.ErrInvalidArgument) } if !identifierRe.MatchString(s) { - return errors.Wrapf(errdefs.ErrInvalidArgument, "identifier %q must match %v", s, identifierRe) + return fmt.Errorf("identifier %q must match %v: %w", s, identifierRe, errdefs.ErrInvalidArgument) } return nil } diff --git a/vendor/github.com/containerd/containerd/image.go b/vendor/github.com/containerd/containerd/image.go index f35f0edcaa..216b3adb1e 100644 --- a/vendor/github.com/containerd/containerd/image.go +++ b/vendor/github.com/containerd/containerd/image.go @@ -19,6 +19,7 @@ package containerd import ( "context" "encoding/json" + "errors" "fmt" "strings" "sync/atomic" @@ -33,7 +34,6 @@ import ( "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/identity" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "golang.org/x/sync/semaphore" ) @@ -61,6 +61,8 @@ type Image interface { ContentStore() content.Store // Metadata returns the underlying image metadata Metadata() images.Image + // Platform returns the platform match comparer. Can be nil. + Platform() platforms.MatchComparer } type usageOptions struct { @@ -397,10 +399,10 @@ func (i *image) getLayers(ctx context.Context, platform platforms.MatchComparer, cs := i.ContentStore() diffIDs, err := i.i.RootFS(ctx, cs, platform) if err != nil { - return nil, errors.Wrap(err, "failed to resolve rootfs") + return nil, fmt.Errorf("failed to resolve rootfs: %w", err) } if len(diffIDs) != len(manifest.Layers) { - return nil, errors.Errorf("mismatched image rootfs and manifest layers") + return nil, errors.New("mismatched image rootfs and manifest layers") } layers := make([]rootfs.Layer, len(diffIDs)) for i := range diffIDs { @@ -448,3 +450,7 @@ func (i *image) checkSnapshotterSupport(ctx context.Context, snapshotterName str func (i *image) ContentStore() content.Store { return i.client.ContentStore() } + +func (i *image) Platform() platforms.MatchComparer { + return i.platform +} diff --git a/vendor/github.com/containerd/containerd/images/archive/exporter.go b/vendor/github.com/containerd/containerd/images/archive/exporter.go index 7801b2552c..549474644b 100644 --- a/vendor/github.com/containerd/containerd/images/archive/exporter.go +++ b/vendor/github.com/containerd/containerd/images/archive/exporter.go @@ -20,6 +20,7 @@ import ( "archive/tar" "context" "encoding/json" + "fmt" "io" "path" "sort" @@ -31,7 +32,6 @@ import ( digest "github.com/opencontainers/go-digest" ocispecs "github.com/opencontainers/image-spec/specs-go" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) type exportOptions struct { @@ -230,7 +230,7 @@ func Export(ctx context.Context, store content.Provider, writer io.Writer, opts manifest: manifests[0], } } else if eo.platform != nil { - return errors.Wrap(errdefs.ErrNotFound, "no manifest found for platform") + return fmt.Errorf("no manifest found for platform: %w", errdefs.ErrNotFound) } } resolvedIndex[desc.Digest] = d @@ -243,14 +243,14 @@ func Export(ctx context.Context, store content.Provider, writer io.Writer, opts } default: - return errors.Wrap(errdefs.ErrInvalidArgument, "only manifests may be exported") + return fmt.Errorf("only manifests may be exported: %w", errdefs.ErrInvalidArgument) } } if len(dManifests) > 0 { tr, err := manifestsRecord(ctx, store, dManifests) if err != nil { - return errors.Wrap(err, "unable to create manifests file") + return fmt.Errorf("unable to create manifests file: %w", err) } records = append(records, tr) @@ -316,7 +316,7 @@ func blobRecord(cs content.Provider, desc ocispec.Descriptor, opts *blobRecordOp CopyTo: func(ctx context.Context, w io.Writer) (int64, error) { r, err := cs.ReaderAt(ctx, desc) if err != nil { - return 0, errors.Wrap(err, "failed to get reader") + return 0, fmt.Errorf("failed to get reader: %w", err) } defer r.Close() @@ -325,10 +325,10 @@ func blobRecord(cs content.Provider, desc ocispec.Descriptor, opts *blobRecordOp n, err := io.Copy(io.MultiWriter(w, dgstr.Hash()), content.NewReader(r)) if err != nil { - return 0, errors.Wrap(err, "failed to copy to tar") + return 0, fmt.Errorf("failed to copy to tar: %w", err) } if dgstr.Digest() != desc.Digest { - return 0, errors.Errorf("unexpected digest %s copied", dgstr.Digest()) + return 0, fmt.Errorf("unexpected digest %s copied", dgstr.Digest()) } return n, nil }, @@ -424,7 +424,7 @@ func manifestsRecord(ctx context.Context, store content.Provider, manifests map[ return tarRecord{}, err } if err := manifest.Config.Digest.Validate(); err != nil { - return tarRecord{}, errors.Wrapf(err, "invalid manifest %q", m.manifest.Digest) + return tarRecord{}, fmt.Errorf("invalid manifest %q: %w", m.manifest.Digest, err) } dgst := manifest.Config.Digest @@ -491,10 +491,10 @@ func writeTar(ctx context.Context, tw *tar.Writer, recordsWithEmpty []tarRecord) return err } if n != record.Header.Size { - return errors.Errorf("unexpected copy size for %s", record.Header.Name) + return fmt.Errorf("unexpected copy size for %s", record.Header.Name) } } else if record.Header.Size > 0 { - return errors.Errorf("no content to write to record with non-zero size for %s", record.Header.Name) + return fmt.Errorf("no content to write to record with non-zero size for %s", record.Header.Name) } } return nil diff --git a/vendor/github.com/containerd/containerd/images/archive/importer.go b/vendor/github.com/containerd/containerd/images/archive/importer.go index 2d046589f8..c531049508 100644 --- a/vendor/github.com/containerd/containerd/images/archive/importer.go +++ b/vendor/github.com/containerd/containerd/images/archive/importer.go @@ -22,9 +22,9 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io" - "io/ioutil" "path" "github.com/containerd/containerd/archive/compression" @@ -32,10 +32,10 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/log" + "github.com/containerd/containerd/platforms" digest "github.com/opencontainers/go-digest" specs "github.com/opencontainers/image-spec/specs-go" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) type importOpts struct { @@ -104,16 +104,16 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader, opt hdrName := path.Clean(hdr.Name) if hdrName == ocispec.ImageLayoutFile { if err = onUntarJSON(tr, &ociLayout); err != nil { - return ocispec.Descriptor{}, errors.Wrapf(err, "untar oci layout %q", hdr.Name) + return ocispec.Descriptor{}, fmt.Errorf("untar oci layout %q: %w", hdr.Name, err) } } else if hdrName == "manifest.json" { if err = onUntarJSON(tr, &mfsts); err != nil { - return ocispec.Descriptor{}, errors.Wrapf(err, "untar manifest %q", hdr.Name) + return ocispec.Descriptor{}, fmt.Errorf("untar manifest %q: %w", hdr.Name, err) } } else { dgst, err := onUntarBlob(ctx, tr, store, hdr.Size, "tar-"+hdrName) if err != nil { - return ocispec.Descriptor{}, errors.Wrapf(err, "failed to ingest %q", hdr.Name) + return ocispec.Descriptor{}, fmt.Errorf("failed to ingest %q: %w", hdr.Name, err) } blobs[hdrName] = ocispec.Descriptor{ @@ -128,12 +128,12 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader, opt // as Docker v1.1 or v1.2. if ociLayout.Version != "" { if ociLayout.Version != ocispec.ImageLayoutVersion { - return ocispec.Descriptor{}, errors.Errorf("unsupported OCI version %s", ociLayout.Version) + return ocispec.Descriptor{}, fmt.Errorf("unsupported OCI version %s", ociLayout.Version) } idx, ok := blobs["index.json"] if !ok { - return ocispec.Descriptor{}, errors.Errorf("missing index.json in OCI layout %s", ocispec.ImageLayoutVersion) + return ocispec.Descriptor{}, fmt.Errorf("missing index.json in OCI layout %s", ocispec.ImageLayoutVersion) } idx.MediaType = ocispec.MediaTypeImageIndex @@ -141,13 +141,13 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader, opt } if mfsts == nil { - return ocispec.Descriptor{}, errors.Errorf("unrecognized image format") + return ocispec.Descriptor{}, errors.New("unrecognized image format") } for name, linkname := range symlinks { desc, ok := blobs[linkname] if !ok { - return ocispec.Descriptor{}, errors.Errorf("no target for symlink layer from %q to %q", name, linkname) + return ocispec.Descriptor{}, fmt.Errorf("no target for symlink layer from %q to %q", name, linkname) } blobs[name] = desc } @@ -160,13 +160,13 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader, opt for _, mfst := range mfsts { config, ok := blobs[mfst.Config] if !ok { - return ocispec.Descriptor{}, errors.Errorf("image config %q not found", mfst.Config) + return ocispec.Descriptor{}, fmt.Errorf("image config %q not found", mfst.Config) } config.MediaType = images.MediaTypeDockerSchema2Config layers, err := resolveLayers(ctx, store, mfst.Layers, blobs, iopts.compress) if err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to resolve layers") + return ocispec.Descriptor{}, fmt.Errorf("failed to resolve layers: %w", err) } manifest := struct { @@ -183,18 +183,28 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader, opt desc, err := writeManifest(ctx, store, manifest, manifest.MediaType) if err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "write docker manifest") + return ocispec.Descriptor{}, fmt.Errorf("write docker manifest: %w", err) } - platforms, err := images.Platforms(ctx, store, desc) + imgPlatforms, err := images.Platforms(ctx, store, desc) if err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "unable to resolve platform") + return ocispec.Descriptor{}, fmt.Errorf("unable to resolve platform: %w", err) } - if len(platforms) > 0 { + if len(imgPlatforms) > 0 { // Only one platform can be resolved from non-index manifest, // The platform can only come from the config included above, // if the config has no platform it can be safely omitted. - desc.Platform = &platforms[0] + desc.Platform = &imgPlatforms[0] + + // If the image we've just imported is a Windows image without the OSVersion set, + // we could just assume it matches this host's OS Version. Without this, the + // children labels might not be set on the image content, leading to it being + // garbage collected, breaking the image. + // See: https://github.com/containerd/containerd/issues/5690 + if desc.Platform.OS == "windows" && desc.Platform.OSVersion == "" { + platform := platforms.DefaultSpec() + desc.Platform.OSVersion = platform.OSVersion + } } if len(mfst.RepoTags) == 0 { @@ -223,7 +233,7 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader, opt } func onUntarJSON(r io.Reader, j interface{}) error { - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err != nil { return err } @@ -247,7 +257,7 @@ func resolveLayers(ctx context.Context, store content.Store, layerFiles []string for i, f := range layerFiles { desc, ok := blobs[f] if !ok { - return nil, errors.Errorf("layer %q not found", f) + return nil, fmt.Errorf("layer %q not found", f) } layers[i] = desc descs[desc.Digest] = &layers[i] @@ -259,15 +269,19 @@ func resolveLayers(ctx context.Context, store content.Store, layerFiles []string if ok { desc := descs[digest.Digest(dgst)] if desc != nil { - desc.MediaType = images.MediaTypeDockerSchema2LayerGzip desc.Digest = info.Digest desc.Size = info.Size + mediaType, err := detectLayerMediaType(ctx, store, *desc) + if err != nil { + return fmt.Errorf("failed to detect media type of layer: %w", err) + } + desc.MediaType = mediaType } } return nil }, filters...) if err != nil { - return nil, errors.Wrap(err, "failure checking for compressed blobs") + return nil, fmt.Errorf("failure checking for compressed blobs: %w", err) } for i, desc := range layers { @@ -277,11 +291,12 @@ func resolveLayers(ctx context.Context, store content.Store, layerFiles []string // Open blob, resolve media type ra, err := store.ReaderAt(ctx, desc) if err != nil { - return nil, errors.Wrapf(err, "failed to open %q (%s)", layerFiles[i], desc.Digest) + return nil, fmt.Errorf("failed to open %q (%s): %w", layerFiles[i], desc.Digest, err) } s, err := compression.DecompressStream(content.NewReader(ra)) if err != nil { - return nil, errors.Wrapf(err, "failed to detect compression for %q", layerFiles[i]) + ra.Close() + return nil, fmt.Errorf("failed to detect compression for %q: %w", layerFiles[i], err) } if s.GetCompression() == compression.Uncompressed { if compress { @@ -292,6 +307,7 @@ func resolveLayers(ctx context.Context, store content.Store, layerFiles []string layers[i], err = compressBlob(ctx, store, s, ref, content.WithLabels(labels)) if err != nil { s.Close() + ra.Close() return nil, err } layers[i].MediaType = images.MediaTypeDockerSchema2LayerGzip @@ -302,7 +318,7 @@ func resolveLayers(ctx context.Context, store content.Store, layerFiles []string layers[i].MediaType = images.MediaTypeDockerSchema2LayerGzip } s.Close() - + ra.Close() } return layers, nil } @@ -310,7 +326,7 @@ func resolveLayers(ctx context.Context, store content.Store, layerFiles []string func compressBlob(ctx context.Context, cs content.Store, r io.Reader, ref string, opts ...content.Opt) (desc ocispec.Descriptor, err error) { w, err := content.OpenWriter(ctx, cs, content.WithRef(ref)) if err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to open writer") + return ocispec.Descriptor{}, fmt.Errorf("failed to open writer: %w", err) } defer func() { @@ -320,7 +336,7 @@ func compressBlob(ctx context.Context, cs content.Store, r io.Reader, ref string } }() if err := w.Truncate(0); err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to truncate writer") + return ocispec.Descriptor{}, fmt.Errorf("failed to truncate writer: %w", err) } cw, err := compression.CompressStream(w, compression.Gzip) @@ -337,7 +353,7 @@ func compressBlob(ctx context.Context, cs content.Store, r io.Reader, ref string cst, err := w.Status() if err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to get writer status") + return ocispec.Descriptor{}, fmt.Errorf("failed to get writer status: %w", err) } desc.Digest = w.Digest() @@ -345,7 +361,7 @@ func compressBlob(ctx context.Context, cs content.Store, r io.Reader, ref string if err := w.Commit(ctx, desc.Size, desc.Digest, opts...); err != nil { if !errdefs.IsAlreadyExists(err) { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to commit") + return ocispec.Descriptor{}, fmt.Errorf("failed to commit: %w", err) } } @@ -369,3 +385,29 @@ func writeManifest(ctx context.Context, cs content.Ingester, manifest interface{ return desc, nil } + +func detectLayerMediaType(ctx context.Context, store content.Store, desc ocispec.Descriptor) (string, error) { + var mediaType string + // need to parse existing blob to use the proper media type + bytes := make([]byte, 10) + ra, err := store.ReaderAt(ctx, desc) + if err != nil { + return "", fmt.Errorf("failed to read content store to detect layer media type: %w", err) + } + defer ra.Close() + _, err = ra.ReadAt(bytes, 0) + if err != nil && err != io.EOF { + return "", fmt.Errorf("failed to read header bytes from layer to detect media type: %w", err) + } + if err == io.EOF { + // in the case of an empty layer then the media type should be uncompressed + return images.MediaTypeDockerSchema2Layer, nil + } + switch c := compression.DetectCompression(bytes); c { + case compression.Uncompressed: + mediaType = images.MediaTypeDockerSchema2Layer + default: + mediaType = images.MediaTypeDockerSchema2LayerGzip + } + return mediaType, nil +} diff --git a/vendor/github.com/containerd/containerd/images/archive/reference.go b/vendor/github.com/containerd/containerd/images/archive/reference.go index ce9fe98f91..ba19b111f1 100644 --- a/vendor/github.com/containerd/containerd/images/archive/reference.go +++ b/vendor/github.com/containerd/containerd/images/archive/reference.go @@ -17,12 +17,12 @@ package archive import ( + "fmt" "strings" "github.com/containerd/containerd/reference" distref "github.com/containerd/containerd/reference/docker" "github.com/opencontainers/go-digest" - "github.com/pkg/errors" ) // FilterRefPrefix restricts references to having the given image @@ -72,7 +72,7 @@ func normalizeReference(ref string) (string, error) { // TODO: Replace this function to not depend on reference package normalized, err := distref.ParseDockerRef(ref) if err != nil { - return "", errors.Wrapf(err, "normalize image ref %q", ref) + return "", fmt.Errorf("normalize image ref %q: %w", ref, err) } return normalized.String(), nil @@ -81,7 +81,7 @@ func normalizeReference(ref string) (string, error) { func familiarizeReference(ref string) (string, error) { named, err := distref.ParseNormalizedNamed(ref) if err != nil { - return "", errors.Wrapf(err, "failed to parse %q", ref) + return "", fmt.Errorf("failed to parse %q: %w", ref, err) } named = distref.TagNameOnly(named) diff --git a/vendor/github.com/containerd/containerd/images/handlers.go b/vendor/github.com/containerd/containerd/images/handlers.go index 05a9017bc2..077d88e787 100644 --- a/vendor/github.com/containerd/containerd/images/handlers.go +++ b/vendor/github.com/containerd/containerd/images/handlers.go @@ -18,6 +18,7 @@ package images import ( "context" + "errors" "fmt" "sort" @@ -25,7 +26,6 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/platforms" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "golang.org/x/sync/errgroup" "golang.org/x/sync/semaphore" ) @@ -33,13 +33,17 @@ import ( var ( // ErrSkipDesc is used to skip processing of a descriptor and // its descendants. - ErrSkipDesc = fmt.Errorf("skip descriptor") + ErrSkipDesc = errors.New("skip descriptor") // ErrStopHandler is used to signify that the descriptor // has been handled and should not be handled further. // This applies only to a single descriptor in a handler // chain and does not apply to descendant descriptors. - ErrStopHandler = fmt.Errorf("stop handler") + ErrStopHandler = errors.New("stop handler") + + // ErrEmptyWalk is used when the WalkNotEmpty handlers return no + // children (e.g.: they were filtered out). + ErrEmptyWalk = errors.New("image might be filtered out") ) // Handler handles image manifests @@ -99,6 +103,36 @@ func Walk(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) err } } } + return nil +} + +// WalkNotEmpty works the same way Walk does, with the exception that it ensures that +// some children are still found by Walking the descriptors (for example, not all of +// them have been filtered out by one of the handlers). If there are no children, +// then an ErrEmptyWalk error is returned. +func WalkNotEmpty(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) error { + isEmpty := true + var notEmptyHandler HandlerFunc = func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { + children, err := handler.Handle(ctx, desc) + if err != nil { + return children, err + } + + if len(children) > 0 { + isEmpty = false + } + + return children, nil + } + + err := Walk(ctx, notEmptyHandler, descs...) + if err != nil { + return err + } + + if isEmpty { + return ErrEmptyWalk + } return nil } @@ -274,7 +308,7 @@ func LimitManifests(f HandlerFunc, m platforms.MatchComparer, n int) HandlerFunc if n > 0 { if len(children) == 0 { - return children, errors.Wrap(errdefs.ErrNotFound, "no match for platform in manifest") + return children, fmt.Errorf("no match for platform in manifest: %w", errdefs.ErrNotFound) } if len(children) > n { children = children[:n] diff --git a/vendor/github.com/containerd/containerd/images/image.go b/vendor/github.com/containerd/containerd/images/image.go index 2e5cd61c9a..d45afe482c 100644 --- a/vendor/github.com/containerd/containerd/images/image.go +++ b/vendor/github.com/containerd/containerd/images/image.go @@ -29,7 +29,6 @@ import ( "github.com/containerd/containerd/platforms" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) // Image provides the model for how containerd views container images. @@ -115,7 +114,7 @@ func (image *Image) Size(ctx context.Context, provider content.Provider, platfor var size int64 return size, Walk(ctx, Handlers(HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { if desc.Size < 0 { - return nil, errors.Errorf("invalid size %v in %v (%v)", desc.Size, desc.Digest, desc.MediaType) + return nil, fmt.Errorf("invalid size %v in %v (%v)", desc.Size, desc.Digest, desc.MediaType) } size += desc.Size return nil, nil @@ -156,7 +155,7 @@ func Manifest(ctx context.Context, provider content.Provider, image ocispec.Desc } if err := validateMediaType(p, desc.MediaType); err != nil { - return nil, errors.Wrapf(err, "manifest: invalid desc %s", desc.Digest) + return nil, fmt.Errorf("manifest: invalid desc %s: %w", desc.Digest, err) } var manifest ocispec.Manifest @@ -200,7 +199,7 @@ func Manifest(ctx context.Context, provider content.Provider, image ocispec.Desc } if err := validateMediaType(p, desc.MediaType); err != nil { - return nil, errors.Wrapf(err, "manifest: invalid desc %s", desc.Digest) + return nil, fmt.Errorf("manifest: invalid desc %s: %w", desc.Digest, err) } var idx ocispec.Index @@ -236,15 +235,15 @@ func Manifest(ctx context.Context, provider content.Provider, image ocispec.Desc } return descs, nil } - return nil, errors.Wrapf(errdefs.ErrNotFound, "unexpected media type %v for %v", desc.MediaType, desc.Digest) + return nil, fmt.Errorf("unexpected media type %v for %v: %w", desc.MediaType, desc.Digest, errdefs.ErrNotFound) }), image); err != nil { return ocispec.Manifest{}, err } if len(m) == 0 { - err := errors.Wrapf(errdefs.ErrNotFound, "manifest %v", image.Digest) + err := fmt.Errorf("manifest %v: %w", image.Digest, errdefs.ErrNotFound) if wasIndex { - err = errors.Wrapf(errdefs.ErrNotFound, "no match for platform in manifest %v", image.Digest) + err = fmt.Errorf("no match for platform in manifest %v: %w", image.Digest, errdefs.ErrNotFound) } return ocispec.Manifest{}, err } @@ -309,7 +308,7 @@ func Check(ctx context.Context, provider content.Provider, image ocispec.Descrip return false, []ocispec.Descriptor{image}, nil, []ocispec.Descriptor{image}, nil } - return false, nil, nil, nil, errors.Wrapf(err, "failed to check image %v", image.Digest) + return false, nil, nil, nil, fmt.Errorf("failed to check image %v: %w", image.Digest, err) } // TODO(stevvooe): It is possible that referenced conponents could have @@ -324,7 +323,7 @@ func Check(ctx context.Context, provider content.Provider, image ocispec.Descrip missing = append(missing, desc) continue } else { - return false, nil, nil, nil, errors.Wrapf(err, "failed to check image %v", desc.Digest) + return false, nil, nil, nil, fmt.Errorf("failed to check image %v: %w", desc.Digest, err) } } ra.Close() @@ -346,7 +345,7 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr } if err := validateMediaType(p, desc.MediaType); err != nil { - return nil, errors.Wrapf(err, "children: invalid desc %s", desc.Digest) + return nil, fmt.Errorf("children: invalid desc %s: %w", desc.Digest, err) } // TODO(stevvooe): We just assume oci manifest, for now. There may be @@ -365,7 +364,7 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr } if err := validateMediaType(p, desc.MediaType); err != nil { - return nil, errors.Wrapf(err, "children: invalid desc %s", desc.Digest) + return nil, fmt.Errorf("children: invalid desc %s: %w", desc.Digest, err) } var index ocispec.Index diff --git a/vendor/github.com/containerd/containerd/images/mediatypes.go b/vendor/github.com/containerd/containerd/images/mediatypes.go index 785d71291e..671e160e15 100644 --- a/vendor/github.com/containerd/containerd/images/mediatypes.go +++ b/vendor/github.com/containerd/containerd/images/mediatypes.go @@ -18,12 +18,12 @@ package images import ( "context" + "fmt" "sort" "strings" "github.com/containerd/containerd/errdefs" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) // mediatype definitions for image components handled in containerd. @@ -87,7 +87,7 @@ func DiffCompression(ctx context.Context, mediaType string) (string, error) { } return "", nil default: - return "", errors.Wrapf(errdefs.ErrNotImplemented, "unrecognised mediatype %s", mediaType) + return "", fmt.Errorf("unrecognised mediatype %s: %w", mediaType, errdefs.ErrNotImplemented) } } diff --git a/vendor/github.com/containerd/containerd/import.go b/vendor/github.com/containerd/containerd/import.go index 6080161f84..8936d88eff 100644 --- a/vendor/github.com/containerd/containerd/import.go +++ b/vendor/github.com/containerd/containerd/import.go @@ -31,11 +31,13 @@ import ( ) type importOpts struct { - indexName string - imageRefT func(string) string - dgstRefT func(digest.Digest) string - allPlatforms bool - compress bool + indexName string + imageRefT func(string) string + dgstRefT func(digest.Digest) string + skipDgstRef func(string) bool + allPlatforms bool + platformMatcher platforms.MatchComparer + compress bool } // ImportOpt allows the caller to specify import specific options @@ -59,6 +61,17 @@ func WithDigestRef(f func(digest.Digest) string) ImportOpt { } } +// WithSkipDigestRef is used to specify when to skip applying +// WithDigestRef. The callback receives an image reference (or an empty +// string if not specified in the image). When the callback returns true, +// the skip occurs. +func WithSkipDigestRef(f func(string) bool) ImportOpt { + return func(c *importOpts) error { + c.skipDgstRef = f + return nil + } +} + // WithIndexName creates a tag pointing to the imported index func WithIndexName(name string) ImportOpt { return func(c *importOpts) error { @@ -75,6 +88,14 @@ func WithAllPlatforms(allPlatforms bool) ImportOpt { } } +// WithImportPlatform is used to import content for specific platform. +func WithImportPlatform(platformMacher platforms.MatchComparer) ImportOpt { + return func(c *importOpts) error { + c.platformMatcher = platformMacher + return nil + } +} + // WithImportCompression compresses uncompressed layers on import. // This is used for import formats which do not include the manifest. func WithImportCompression() ImportOpt { @@ -123,9 +144,11 @@ func (c *Client) Import(ctx context.Context, reader io.Reader, opts ...ImportOpt Target: index, }) } - var platformMatcher = platforms.All - if !iopts.allPlatforms { - platformMatcher = c.platform + var platformMatcher = c.platform + if iopts.allPlatforms { + platformMatcher = platforms.All + } else if iopts.platformMatcher != nil { + platformMatcher = iopts.platformMatcher } var handler images.HandlerFunc = func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { @@ -152,6 +175,11 @@ func (c *Client) Import(ctx context.Context, reader io.Reader, opts ...ImportOpt Target: m, }) } + if iopts.skipDgstRef != nil { + if iopts.skipDgstRef(name) { + continue + } + } if iopts.dgstRefT != nil { ref := iopts.dgstRefT(m.Digest) if ref != "" { @@ -168,7 +196,7 @@ func (c *Client) Import(ctx context.Context, reader io.Reader, opts ...ImportOpt handler = images.FilterPlatforms(handler, platformMatcher) handler = images.SetChildrenLabels(cs, handler) - if err := images.Walk(ctx, handler, index); err != nil { + if err := images.WalkNotEmpty(ctx, handler, index); err != nil { return nil, err } diff --git a/vendor/github.com/containerd/containerd/install.go b/vendor/github.com/containerd/containerd/install.go index 7a8311c832..16cff08d24 100644 --- a/vendor/github.com/containerd/containerd/install.go +++ b/vendor/github.com/containerd/containerd/install.go @@ -19,6 +19,8 @@ package containerd import ( "archive/tar" "context" + "errors" + "fmt" "os" "path/filepath" "runtime" @@ -28,7 +30,6 @@ import ( "github.com/containerd/containerd/archive/compression" "github.com/containerd/containerd/content" "github.com/containerd/containerd/images" - "github.com/pkg/errors" ) // Install a binary image into the opt service @@ -66,6 +67,7 @@ func (c *Client) Install(ctx context.Context, image Image, opts ...InstallOpts) cr := content.NewReader(ra) r, err := compression.DecompressStream(cr) if err != nil { + ra.Close() return err } if _, err := archive.Apply(ctx, path, r, archive.WithFilter(func(hdr *tar.Header) (bool, error) { @@ -81,15 +83,17 @@ func (c *Client) Install(ctx context.Context, image Image, opts ...InstallOpts) } if result && !config.Replace { if _, err := os.Lstat(filepath.Join(path, hdr.Name)); err == nil { - return false, errors.Errorf("cannot replace %s in %s", hdr.Name, path) + return false, fmt.Errorf("cannot replace %s in %s", hdr.Name, path) } } return result, nil })); err != nil { r.Close() + ra.Close() return err } r.Close() + ra.Close() } return nil } diff --git a/vendor/github.com/containerd/containerd/labels/validate.go b/vendor/github.com/containerd/containerd/labels/validate.go index 0de461663a..1fd527adb3 100644 --- a/vendor/github.com/containerd/containerd/labels/validate.go +++ b/vendor/github.com/containerd/containerd/labels/validate.go @@ -17,8 +17,9 @@ package labels import ( + "fmt" + "github.com/containerd/containerd/errdefs" - "github.com/pkg/errors" ) const ( @@ -31,7 +32,7 @@ func Validate(k, v string) error { if len(k) > 10 { k = k[:10] } - return errors.Wrapf(errdefs.ErrInvalidArgument, "label key and value greater than maximum size (%d bytes), key: %s", maxSize, k) + return fmt.Errorf("label key and value greater than maximum size (%d bytes), key: %s: %w", maxSize, k, errdefs.ErrInvalidArgument) } return nil } diff --git a/vendor/github.com/containerd/containerd/log/context.go b/vendor/github.com/containerd/containerd/log/context.go index 37b6a7d1c8..0db9562b82 100644 --- a/vendor/github.com/containerd/containerd/log/context.go +++ b/vendor/github.com/containerd/containerd/log/context.go @@ -52,7 +52,8 @@ const ( // 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) + e := logger.WithContext(ctx) + return context.WithValue(ctx, loggerKey{}, e) } // GetLogger retrieves the current logger from the context. If no logger is @@ -61,7 +62,7 @@ func GetLogger(ctx context.Context) *logrus.Entry { logger := ctx.Value(loggerKey{}) if logger == nil { - return L + return L.WithContext(ctx) } return logger.(*logrus.Entry) diff --git a/vendor/github.com/containerd/containerd/metadata/bolt.go b/vendor/github.com/containerd/containerd/metadata/bolt.go index 6ea4608663..9edfab565b 100644 --- a/vendor/github.com/containerd/containerd/metadata/bolt.go +++ b/vendor/github.com/containerd/containerd/metadata/bolt.go @@ -18,8 +18,8 @@ package metadata import ( "context" + "fmt" - "github.com/pkg/errors" bolt "go.etcd.io/bbolt" ) @@ -55,7 +55,7 @@ func update(ctx context.Context, db transactor, fn func(*bolt.Tx) error) error { if !ok { return db.Update(fn) } else if !tx.Writable() { - return errors.Wrap(bolt.ErrTxNotWritable, "unable to use transaction from context") + return fmt.Errorf("unable to use transaction from context: %w", bolt.ErrTxNotWritable) } return fn(tx) } diff --git a/vendor/github.com/containerd/containerd/metadata/boltutil/helpers.go b/vendor/github.com/containerd/containerd/metadata/boltutil/helpers.go index 6995917c92..4722a52269 100644 --- a/vendor/github.com/containerd/containerd/metadata/boltutil/helpers.go +++ b/vendor/github.com/containerd/containerd/metadata/boltutil/helpers.go @@ -17,11 +17,11 @@ package boltutil import ( + "fmt" "time" "github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/types" - "github.com/pkg/errors" bolt "go.etcd.io/bbolt" ) @@ -99,7 +99,7 @@ func writeMap(bkt *bolt.Bucket, bucketName []byte, labels map[string]string) err } if err := lbkt.Put([]byte(k), []byte(v)); err != nil { - return errors.Wrapf(err, "failed to set label %q=%q", k, v) + return fmt.Errorf("failed to set label %q=%q: %w", k, v, err) } } @@ -228,7 +228,7 @@ func ReadAny(bkt *bolt.Bucket, name []byte) (*types.Any, error) { out := types.Any{} if err := proto.Unmarshal(bytes, &out); err != nil { - return nil, errors.Wrap(err, "failed to unmarshal any") + return nil, fmt.Errorf("failed to unmarshal any: %w", err) } return &out, nil diff --git a/vendor/github.com/containerd/containerd/metadata/buckets.go b/vendor/github.com/containerd/containerd/metadata/buckets.go index fa947fb250..d23be84fea 100644 --- a/vendor/github.com/containerd/containerd/metadata/buckets.go +++ b/vendor/github.com/containerd/containerd/metadata/buckets.go @@ -15,7 +15,7 @@ */ // Package metadata stores all labels and object specific metadata by namespace. -// This package also contains the main garbage collection logic for cleaning up +// This package also contains the main garbage collection logic for cleaning up // resources consistently and atomically. Resources used by backends will be // tracked in the metadata store to be exposed to consumers of this package. // diff --git a/vendor/github.com/containerd/containerd/metadata/containers.go b/vendor/github.com/containerd/containerd/metadata/containers.go index 26e86d8583..97002e5886 100644 --- a/vendor/github.com/containerd/containerd/metadata/containers.go +++ b/vendor/github.com/containerd/containerd/metadata/containers.go @@ -18,6 +18,7 @@ package metadata import ( "context" + "fmt" "strings" "sync/atomic" "time" @@ -31,7 +32,6 @@ import ( "github.com/containerd/containerd/namespaces" "github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/types" - "github.com/pkg/errors" bolt "go.etcd.io/bbolt" ) @@ -57,11 +57,11 @@ func (s *containerStore) Get(ctx context.Context, id string) (containers.Contain if err := view(ctx, s.db, func(tx *bolt.Tx) error { bkt := getContainerBucket(tx, namespace, id) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "container %q in namespace %q", id, namespace) + return fmt.Errorf("container %q in namespace %q: %w", id, namespace, errdefs.ErrNotFound) } if err := readContainer(&container, bkt); err != nil { - return errors.Wrapf(err, "failed to read container %q", id) + return fmt.Errorf("failed to read container %q: %w", id, err) } return nil @@ -80,7 +80,7 @@ func (s *containerStore) List(ctx context.Context, fs ...string) ([]containers.C filter, err := filters.ParseAll(fs...) if err != nil { - return nil, errors.Wrap(errdefs.ErrInvalidArgument, err.Error()) + return nil, fmt.Errorf("%s: %w", err.Error(), errdefs.ErrInvalidArgument) } var m []containers.Container @@ -99,7 +99,7 @@ func (s *containerStore) List(ctx context.Context, fs ...string) ([]containers.C container := containers.Container{ID: string(k)} if err := readContainer(&container, cbkt); err != nil { - return errors.Wrapf(err, "failed to read container %q", string(k)) + return fmt.Errorf("failed to read container %q: %w", string(k), err) } if filter.Match(adaptContainer(container)) { @@ -121,7 +121,7 @@ func (s *containerStore) Create(ctx context.Context, container containers.Contai } if err := validateContainer(&container); err != nil { - return containers.Container{}, errors.Wrap(err, "create container failed validation") + return containers.Container{}, fmt.Errorf("create container failed validation: %w", err) } if err := update(ctx, s.db, func(tx *bolt.Tx) error { @@ -133,7 +133,7 @@ func (s *containerStore) Create(ctx context.Context, container containers.Contai cbkt, err := bkt.CreateBucket([]byte(container.ID)) if err != nil { if err == bolt.ErrBucketExists { - err = errors.Wrapf(errdefs.ErrAlreadyExists, "container %q", container.ID) + err = fmt.Errorf("container %q: %w", container.ID, errdefs.ErrAlreadyExists) } return err } @@ -141,7 +141,7 @@ func (s *containerStore) Create(ctx context.Context, container containers.Contai container.CreatedAt = time.Now().UTC() container.UpdatedAt = container.CreatedAt if err := writeContainer(cbkt, &container); err != nil { - return errors.Wrapf(err, "failed to write container %q", container.ID) + return fmt.Errorf("failed to write container %q: %w", container.ID, err) } return nil @@ -159,23 +159,23 @@ func (s *containerStore) Update(ctx context.Context, container containers.Contai } if container.ID == "" { - return containers.Container{}, errors.Wrapf(errdefs.ErrInvalidArgument, "must specify a container id") + return containers.Container{}, fmt.Errorf("must specify a container id: %w", errdefs.ErrInvalidArgument) } var updated containers.Container if err := update(ctx, s.db, func(tx *bolt.Tx) error { bkt := getContainersBucket(tx, namespace) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "cannot update container %q in namespace %q", container.ID, namespace) + return fmt.Errorf("cannot update container %q in namespace %q: %w", container.ID, namespace, errdefs.ErrNotFound) } cbkt := bkt.Bucket([]byte(container.ID)) if cbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "container %q", container.ID) + return fmt.Errorf("container %q: %w", container.ID, errdefs.ErrNotFound) } if err := readContainer(&updated, cbkt); err != nil { - return errors.Wrapf(err, "failed to read container %q", container.ID) + return fmt.Errorf("failed to read container %q: %w", container.ID, err) } createdat := updated.CreatedAt updated.ID = container.ID @@ -188,11 +188,11 @@ func (s *containerStore) Update(ctx context.Context, container containers.Contai // are provided. This allows these fields to become mutable in the // future. if updated.Snapshotter != container.Snapshotter { - return errors.Wrapf(errdefs.ErrInvalidArgument, "container.Snapshotter field is immutable") + return fmt.Errorf("container.Snapshotter field is immutable: %w", errdefs.ErrInvalidArgument) } if updated.Runtime.Name != container.Runtime.Name { - return errors.Wrapf(errdefs.ErrInvalidArgument, "container.Runtime.Name field is immutable") + return fmt.Errorf("container.Runtime.Name field is immutable: %w", errdefs.ErrInvalidArgument) } } @@ -230,18 +230,18 @@ func (s *containerStore) Update(ctx context.Context, container containers.Contai case "snapshotkey": updated.SnapshotKey = container.SnapshotKey default: - return errors.Wrapf(errdefs.ErrInvalidArgument, "cannot update %q field on %q", path, container.ID) + return fmt.Errorf("cannot update %q field on %q: %w", path, container.ID, errdefs.ErrInvalidArgument) } } if err := validateContainer(&updated); err != nil { - return errors.Wrap(err, "update failed validation") + return fmt.Errorf("update failed validation: %w", err) } updated.CreatedAt = createdat updated.UpdatedAt = time.Now().UTC() if err := writeContainer(cbkt, &updated); err != nil { - return errors.Wrapf(err, "failed to write container %q", container.ID) + return fmt.Errorf("failed to write container %q: %w", container.ID, err) } return nil @@ -261,12 +261,12 @@ func (s *containerStore) Delete(ctx context.Context, id string) error { return update(ctx, s.db, func(tx *bolt.Tx) error { bkt := getContainersBucket(tx, namespace) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "cannot delete container %q in namespace %q", id, namespace) + return fmt.Errorf("cannot delete container %q in namespace %q: %w", id, namespace, errdefs.ErrNotFound) } if err := bkt.DeleteBucket([]byte(id)); err != nil { if err == bolt.ErrBucketNotFound { - err = errors.Wrapf(errdefs.ErrNotFound, "container %v", id) + err = fmt.Errorf("container %v: %w", id, errdefs.ErrNotFound) } return err } @@ -279,32 +279,32 @@ func (s *containerStore) Delete(ctx context.Context, id string) error { func validateContainer(container *containers.Container) error { if err := identifiers.Validate(container.ID); err != nil { - return errors.Wrap(err, "container.ID") + return fmt.Errorf("container.ID: %w", err) } for k := range container.Extensions { if k == "" { - return errors.Wrapf(errdefs.ErrInvalidArgument, "container.Extension keys must not be zero-length") + return fmt.Errorf("container.Extension keys must not be zero-length: %w", errdefs.ErrInvalidArgument) } } // image has no validation for k, v := range container.Labels { if err := labels.Validate(k, v); err != nil { - return errors.Wrapf(err, "containers.Labels") + return fmt.Errorf("containers.Labels: %w", err) } } if container.Runtime.Name == "" { - return errors.Wrapf(errdefs.ErrInvalidArgument, "container.Runtime.Name must be set") + return fmt.Errorf("container.Runtime.Name must be set: %w", errdefs.ErrInvalidArgument) } if container.Spec == nil { - return errors.Wrapf(errdefs.ErrInvalidArgument, "container.Spec must be set") + return fmt.Errorf("container.Spec must be set: %w", errdefs.ErrInvalidArgument) } if container.SnapshotKey != "" && container.Snapshotter == "" { - return errors.Wrapf(errdefs.ErrInvalidArgument, "container.Snapshotter must be set if container.SnapshotKey is set") + return fmt.Errorf("container.Snapshotter must be set if container.SnapshotKey is set: %w", errdefs.ErrInvalidArgument) } return nil diff --git a/vendor/github.com/containerd/containerd/metadata/content.go b/vendor/github.com/containerd/containerd/metadata/content.go index ee68ccfe1e..66d0ee263e 100644 --- a/vendor/github.com/containerd/containerd/metadata/content.go +++ b/vendor/github.com/containerd/containerd/metadata/content.go @@ -19,6 +19,7 @@ package metadata import ( "context" "encoding/binary" + "fmt" "strings" "sync" "sync/atomic" @@ -33,7 +34,6 @@ import ( "github.com/containerd/containerd/namespaces" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" bolt "go.etcd.io/bbolt" ) @@ -77,7 +77,7 @@ func (cs *contentStore) Info(ctx context.Context, dgst digest.Digest) (content.I if err := view(ctx, cs.db, func(tx *bolt.Tx) error { bkt := getBlobBucket(tx, ns, dgst) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "content digest %v", dgst) + return fmt.Errorf("content digest %v: %w", dgst, errdefs.ErrNotFound) } info.Digest = dgst @@ -104,11 +104,11 @@ func (cs *contentStore) Update(ctx context.Context, info content.Info, fieldpath if err := update(ctx, cs.db, func(tx *bolt.Tx) error { bkt := getBlobBucket(tx, ns, info.Digest) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "content digest %v", info.Digest) + return fmt.Errorf("content digest %v: %w", info.Digest, errdefs.ErrNotFound) } if err := readInfo(&updated, bkt); err != nil { - return errors.Wrapf(err, "info %q", info.Digest) + return fmt.Errorf("info %q: %w", info.Digest, err) } if len(fieldpaths) > 0 { @@ -127,7 +127,7 @@ func (cs *contentStore) Update(ctx context.Context, info content.Info, fieldpath case "labels": updated.Labels = info.Labels default: - return errors.Wrapf(errdefs.ErrInvalidArgument, "cannot update %q field on content info %q", path, info.Digest) + return fmt.Errorf("cannot update %q field on content info %q: %w", path, info.Digest, errdefs.ErrInvalidArgument) } } } else { @@ -211,7 +211,7 @@ func (cs *contentStore) Delete(ctx context.Context, dgst digest.Digest) error { return update(ctx, cs.db, func(tx *bolt.Tx) error { bkt := getBlobBucket(tx, ns, dgst) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "content digest %v", dgst) + return fmt.Errorf("content digest %v: %w", dgst, errdefs.ErrNotFound) } if err := getBlobsBucket(tx, ns).DeleteBucket([]byte(dgst.String())); err != nil { @@ -300,7 +300,7 @@ func (cs *contentStore) Status(ctx context.Context, ref string) (content.Status, if err := view(ctx, cs.db, func(tx *bolt.Tx) error { bref = getRef(tx, ns, ref) if bref == "" { - return errors.Wrapf(errdefs.ErrNotFound, "reference %v", ref) + return fmt.Errorf("reference %v: %w", ref, errdefs.ErrNotFound) } return nil @@ -328,15 +328,15 @@ func (cs *contentStore) Abort(ctx context.Context, ref string) error { return update(ctx, cs.db, func(tx *bolt.Tx) error { ibkt := getIngestsBucket(tx, ns) if ibkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "reference %v", ref) + return fmt.Errorf("reference %v: %w", ref, errdefs.ErrNotFound) } bkt := ibkt.Bucket([]byte(ref)) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "reference %v", ref) + return fmt.Errorf("reference %v: %w", ref, errdefs.ErrNotFound) } bref := string(bkt.Get(bucketKeyRef)) if bref == "" { - return errors.Wrapf(errdefs.ErrNotFound, "reference %v", ref) + return fmt.Errorf("reference %v: %w", ref, errdefs.ErrNotFound) } expected := string(bkt.Get(bucketKeyExpected)) if err := ibkt.DeleteBucket([]byte(ref)); err != nil { @@ -367,7 +367,7 @@ func (cs *contentStore) Writer(ctx context.Context, opts ...content.WriterOpt) ( // TODO(AkihiroSuda): we could create a random string or one calculated based on the context // https://github.com/containerd/containerd/issues/2129#issuecomment-380255019 if wOpts.Ref == "" { - return nil, errors.Wrap(errdefs.ErrInvalidArgument, "ref must not be empty") + return nil, fmt.Errorf("ref must not be empty: %w", errdefs.ErrInvalidArgument) } ns, err := namespaces.NamespaceRequired(ctx) if err != nil { @@ -390,7 +390,7 @@ func (cs *contentStore) Writer(ctx context.Context, opts ...content.WriterOpt) ( // Add content to lease to prevent other reference removals // from effecting this object during a provided lease if err := addContentLease(ctx, tx, wOpts.Desc.Digest); err != nil { - return errors.Wrap(err, "unable to lease content") + return fmt.Errorf("unable to lease content: %w", err) } // Return error outside of transaction to ensure // commit succeeds with the lease. @@ -466,7 +466,7 @@ func (cs *contentStore) Writer(ctx context.Context, opts ...content.WriterOpt) ( return nil, err } if exists { - return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v", wOpts.Desc.Digest) + return nil, fmt.Errorf("content %v: %w", wOpts.Desc.Digest, errdefs.ErrAlreadyExists) } return &namespacedWriter{ @@ -619,10 +619,10 @@ func (nw *namespacedWriter) commit(ctx context.Context, tx *bolt.Tx, size int64, var actual digest.Digest if nw.w == nil { if size != 0 && size != nw.desc.Size { - return "", errors.Wrapf(errdefs.ErrFailedPrecondition, "%q failed size validation: %v != %v", nw.ref, nw.desc.Size, size) + return "", fmt.Errorf("%q failed size validation: %v != %v: %w", nw.ref, nw.desc.Size, size, errdefs.ErrFailedPrecondition) } if expected != "" && expected != nw.desc.Digest { - return "", errors.Wrapf(errdefs.ErrFailedPrecondition, "%q unexpected digest", nw.ref) + return "", fmt.Errorf("%q unexpected digest: %w", nw.ref, errdefs.ErrFailedPrecondition) } size = nw.desc.Size actual = nw.desc.Digest @@ -634,7 +634,7 @@ func (nw *namespacedWriter) commit(ctx context.Context, tx *bolt.Tx, size int64, } if size != 0 && size != status.Offset { nw.w.Close() - return "", errors.Wrapf(errdefs.ErrFailedPrecondition, "%q failed size validation: %v != %v", nw.ref, status.Offset, size) + return "", fmt.Errorf("%q failed size validation: %v != %v: %w", nw.ref, status.Offset, size, errdefs.ErrFailedPrecondition) } size = status.Offset @@ -647,7 +647,7 @@ func (nw *namespacedWriter) commit(ctx context.Context, tx *bolt.Tx, size int64, bkt, err := createBlobBucket(tx, nw.namespace, actual) if err != nil { if err == bolt.ErrBucketExists { - return actual, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v", actual) + return actual, fmt.Errorf("content %v: %w", actual, errdefs.ErrAlreadyExists) } return "", err } @@ -700,7 +700,7 @@ func (cs *contentStore) checkAccess(ctx context.Context, dgst digest.Digest) err return view(ctx, cs.db, func(tx *bolt.Tx) error { bkt := getBlobBucket(tx, ns, dgst) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "content digest %v", dgst) + return fmt.Errorf("content digest %v: %w", dgst, errdefs.ErrNotFound) } return nil }) @@ -709,7 +709,7 @@ func (cs *contentStore) checkAccess(ctx context.Context, dgst digest.Digest) err func validateInfo(info *content.Info) error { for k, v := range info.Labels { if err := labels.Validate(k, v); err != nil { - return errors.Wrapf(err, "info.Labels") + return fmt.Errorf("info.Labels: %w", err) } } @@ -740,7 +740,7 @@ func writeInfo(info *content.Info, bkt *bolt.Bucket) error { } if err := boltutil.WriteLabels(bkt, info.Labels); err != nil { - return errors.Wrapf(err, "writing labels for info %v", info.Digest) + return fmt.Errorf("writing labels for info %v: %w", info.Digest, err) } // Write size @@ -772,6 +772,7 @@ func writeExpireAt(expire time.Time, bkt *bolt.Bucket) error { return bkt.Put(bucketKeyExpireAt, expireAt) } +// garbageCollect removes all contents that are no longer used. func (cs *contentStore) garbageCollect(ctx context.Context) (d time.Duration, err error) { cs.l.Lock() t1 := time.Now() diff --git a/vendor/github.com/containerd/containerd/metadata/db.go b/vendor/github.com/containerd/containerd/metadata/db.go index 40d045f05d..2d9cbf31a6 100644 --- a/vendor/github.com/containerd/containerd/metadata/db.go +++ b/vendor/github.com/containerd/containerd/metadata/db.go @@ -19,6 +19,8 @@ package metadata import ( "context" "encoding/binary" + "errors" + "fmt" "strings" "sync" "sync/atomic" @@ -28,7 +30,6 @@ import ( "github.com/containerd/containerd/gc" "github.com/containerd/containerd/log" "github.com/containerd/containerd/snapshots" - "github.com/pkg/errors" bolt "go.etcd.io/bbolt" ) @@ -181,7 +182,7 @@ func (m *DB) Init(ctx context.Context) error { for _, m := range updates { t0 := time.Now() if err := m.migrate(tx); err != nil { - return errors.Wrapf(err, "failed to migrate to %s.%d", m.schema, m.version) + return fmt.Errorf("failed to migrate to %s.%d: %w", m.schema, m.version, err) } log.G(ctx).WithField("d", time.Since(t0)).Debugf("finished database migration to %s.%d", m.schema, m.version) } @@ -276,7 +277,7 @@ func (s GCStats) Elapsed() time.Duration { return s.MetaD } -// GarbageCollect starts garbage collection +// GarbageCollect removes resources (snapshots, contents, ...) that are no longer used. func (m *DB) GarbageCollect(ctx context.Context) (gc.Stats, error) { m.wlock.Lock() t1 := time.Now() @@ -307,7 +308,7 @@ func (m *DB) GarbageCollect(ctx context.Context) (gc.Stats, error) { } if err := scanAll(ctx, tx, rm); err != nil { - return errors.Wrap(err, "failed to scan and remove") + return fmt.Errorf("failed to scan and remove: %w", err) } return nil @@ -362,6 +363,7 @@ func (m *DB) GarbageCollect(ctx context.Context) (gc.Stats, error) { return stats, err } +// getMarked returns all resources that are used. func (m *DB) getMarked(ctx context.Context) (map[gc.Node]struct{}, error) { var marked map[gc.Node]struct{} if err := m.db.View(func(tx *bolt.Tx) error { diff --git a/vendor/github.com/containerd/containerd/metadata/gc.go b/vendor/github.com/containerd/containerd/metadata/gc.go index afe16c9222..60bf410a6d 100644 --- a/vendor/github.com/containerd/containerd/metadata/gc.go +++ b/vendor/github.com/containerd/containerd/metadata/gc.go @@ -25,7 +25,6 @@ import ( "github.com/containerd/containerd/gc" "github.com/containerd/containerd/log" - "github.com/pkg/errors" bolt "go.etcd.io/bbolt" ) @@ -59,6 +58,8 @@ var ( labelGCFlat = []byte("containerd.io/gc.flat") ) +// scanRoots sends the given channel "root" resources that are certainly used. +// The caller could look the references of the resources to find all resources that are used. func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error { v1bkt := tx.Bucket(bucketKeyVersion) if v1bkt == nil { @@ -277,6 +278,7 @@ func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error { return cerr } +// references finds the resources that are reachable from the given node. func references(ctx context.Context, tx *bolt.Tx, node gc.Node, fn func(gc.Node)) error { switch node.Type { case ResourceContent: @@ -290,7 +292,7 @@ func references(ctx context.Context, tx *bolt.Tx, node gc.Node, fn func(gc.Node) case ResourceSnapshot, resourceSnapshotFlat: parts := strings.SplitN(node.Key, "/", 2) if len(parts) != 2 { - return errors.Errorf("invalid snapshot gc key %s", node.Key) + return fmt.Errorf("invalid snapshot gc key %s", node.Key) } ss := parts[0] name := parts[1] @@ -329,6 +331,7 @@ func references(ctx context.Context, tx *bolt.Tx, node gc.Node, fn func(gc.Node) return nil } +// scanAll finds all resources regardless whether the resources are used or not. func scanAll(ctx context.Context, tx *bolt.Tx, fn func(ctx context.Context, n gc.Node) error) error { v1bkt := tx.Bucket(bucketKeyVersion) if v1bkt == nil { @@ -409,6 +412,7 @@ func scanAll(ctx context.Context, tx *bolt.Tx, fn func(ctx context.Context, n gc return nil } +// remove all buckets for the given node. func remove(ctx context.Context, tx *bolt.Tx, node gc.Node) error { v1bkt := tx.Bucket(bucketKeyVersion) if v1bkt == nil { @@ -435,7 +439,7 @@ func remove(ctx context.Context, tx *bolt.Tx, node gc.Node) error { if sbkt != nil { parts := strings.SplitN(node.Key, "/", 2) if len(parts) != 2 { - return errors.Errorf("invalid snapshot gc key %s", node.Key) + return fmt.Errorf("invalid snapshot gc key %s", node.Key) } ssbkt := sbkt.Bucket([]byte(parts[0])) if ssbkt != nil { diff --git a/vendor/github.com/containerd/containerd/metadata/images.go b/vendor/github.com/containerd/containerd/metadata/images.go index cace4e1801..8355b712ef 100644 --- a/vendor/github.com/containerd/containerd/metadata/images.go +++ b/vendor/github.com/containerd/containerd/metadata/images.go @@ -19,6 +19,7 @@ package metadata import ( "context" "encoding/binary" + "errors" "fmt" "strings" "sync/atomic" @@ -32,7 +33,6 @@ import ( "github.com/containerd/containerd/namespaces" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" bolt "go.etcd.io/bbolt" ) @@ -56,17 +56,17 @@ func (s *imageStore) Get(ctx context.Context, name string) (images.Image, error) if err := view(ctx, s.db, func(tx *bolt.Tx) error { bkt := getImagesBucket(tx, namespace) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "image %q", name) + return fmt.Errorf("image %q: %w", name, errdefs.ErrNotFound) } ibkt := bkt.Bucket([]byte(name)) if ibkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "image %q", name) + return fmt.Errorf("image %q: %w", name, errdefs.ErrNotFound) } image.Name = name if err := readImage(&image, ibkt); err != nil { - return errors.Wrapf(err, "image %q", name) + return fmt.Errorf("image %q: %w", name, err) } return nil @@ -85,7 +85,7 @@ func (s *imageStore) List(ctx context.Context, fs ...string) ([]images.Image, er filter, err := filters.ParseAll(fs...) if err != nil { - return nil, errors.Wrap(errdefs.ErrInvalidArgument, err.Error()) + return nil, fmt.Errorf("%s: %w", err.Error(), errdefs.ErrInvalidArgument) } var m []images.Image @@ -141,7 +141,7 @@ func (s *imageStore) Create(ctx context.Context, image images.Image) (images.Ima return err } - return errors.Wrapf(errdefs.ErrAlreadyExists, "image %q", image.Name) + return fmt.Errorf("image %q: %w", image.Name, errdefs.ErrAlreadyExists) } image.CreatedAt = time.Now().UTC() @@ -161,7 +161,7 @@ func (s *imageStore) Update(ctx context.Context, image images.Image, fieldpaths } if image.Name == "" { - return images.Image{}, errors.Wrapf(errdefs.ErrInvalidArgument, "image name is required for update") + return images.Image{}, fmt.Errorf("image name is required for update: %w", errdefs.ErrInvalidArgument) } var updated images.Image @@ -174,11 +174,11 @@ func (s *imageStore) Update(ctx context.Context, image images.Image, fieldpaths ibkt := bkt.Bucket([]byte(image.Name)) if ibkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "image %q", image.Name) + return fmt.Errorf("image %q: %w", image.Name, errdefs.ErrNotFound) } if err := readImage(&updated, ibkt); err != nil { - return errors.Wrapf(err, "image %q", image.Name) + return fmt.Errorf("image %q: %w", image.Name, err) } createdat := updated.CreatedAt updated.Name = image.Name @@ -216,7 +216,7 @@ func (s *imageStore) Update(ctx context.Context, image images.Image, fieldpaths case "annotations": updated.Target.Annotations = image.Target.Annotations default: - return errors.Wrapf(errdefs.ErrInvalidArgument, "cannot update %q field on image %q", path, image.Name) + return fmt.Errorf("cannot update %q field on image %q: %w", path, image.Name, errdefs.ErrInvalidArgument) } } } else { @@ -247,12 +247,12 @@ func (s *imageStore) Delete(ctx context.Context, name string, opts ...images.Del return update(ctx, s.db, func(tx *bolt.Tx) error { bkt := getImagesBucket(tx, namespace) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "image %q", name) + return fmt.Errorf("image %q: %w", name, errdefs.ErrNotFound) } if err = bkt.DeleteBucket([]byte(name)); err != nil { if err == bolt.ErrBucketNotFound { - err = errors.Wrapf(errdefs.ErrNotFound, "image %q", name) + err = fmt.Errorf("image %q: %w", name, errdefs.ErrNotFound) } return err } @@ -265,12 +265,12 @@ func (s *imageStore) Delete(ctx context.Context, name string, opts ...images.Del func validateImage(image *images.Image) error { if image.Name == "" { - return errors.Wrapf(errdefs.ErrInvalidArgument, "image name must not be empty") + return fmt.Errorf("image name must not be empty: %w", errdefs.ErrInvalidArgument) } for k, v := range image.Labels { if err := labels.Validate(k, v); err != nil { - return errors.Wrapf(err, "image.Labels") + return fmt.Errorf("image.Labels: %w", err) } } @@ -281,15 +281,15 @@ func validateTarget(target *ocispec.Descriptor) error { // NOTE(stevvooe): Only validate fields we actually store. if err := target.Digest.Validate(); err != nil { - return errors.Wrapf(errdefs.ErrInvalidArgument, "Target.Digest %q invalid: %v", target.Digest, err) + return fmt.Errorf("Target.Digest %q invalid: %v: %w", target.Digest, err, errdefs.ErrInvalidArgument) } if target.Size <= 0 { - return errors.Wrapf(errdefs.ErrInvalidArgument, "Target.Size must be greater than zero") + return fmt.Errorf("Target.Size must be greater than zero: %w", errdefs.ErrInvalidArgument) } if target.MediaType == "" { - return errors.Wrapf(errdefs.ErrInvalidArgument, "Target.MediaType must be set") + return fmt.Errorf("Target.MediaType must be set: %w", errdefs.ErrInvalidArgument) } return nil @@ -341,11 +341,11 @@ func writeImage(bkt *bolt.Bucket, image *images.Image) error { } if err := boltutil.WriteLabels(bkt, image.Labels); err != nil { - return errors.Wrapf(err, "writing labels for image %v", image.Name) + return fmt.Errorf("writing labels for image %v: %w", image.Name, err) } if err := boltutil.WriteAnnotations(bkt, image.Target.Annotations); err != nil { - return errors.Wrapf(err, "writing Annotations for image %v", image.Name) + return fmt.Errorf("writing Annotations for image %v: %w", image.Name, err) } // write the target bucket diff --git a/vendor/github.com/containerd/containerd/metadata/leases.go b/vendor/github.com/containerd/containerd/metadata/leases.go index 60da06b0f0..03fa75af34 100644 --- a/vendor/github.com/containerd/containerd/metadata/leases.go +++ b/vendor/github.com/containerd/containerd/metadata/leases.go @@ -18,6 +18,7 @@ package metadata import ( "context" + "errors" "fmt" "strings" "sync/atomic" @@ -29,26 +30,25 @@ import ( "github.com/containerd/containerd/metadata/boltutil" "github.com/containerd/containerd/namespaces" digest "github.com/opencontainers/go-digest" - "github.com/pkg/errors" bolt "go.etcd.io/bbolt" ) -// LeaseManager manages the create/delete lifecycle of leases +// leaseManager manages the create/delete lifecycle of leases // and also returns existing leases -type LeaseManager struct { +type leaseManager struct { db *DB } // NewLeaseManager creates a new lease manager for managing leases using // the provided database transaction. -func NewLeaseManager(db *DB) *LeaseManager { - return &LeaseManager{ +func NewLeaseManager(db *DB) leases.Manager { + return &leaseManager{ db: db, } } // Create creates a new lease using the provided lease -func (lm *LeaseManager) Create(ctx context.Context, opts ...leases.Opt) (leases.Lease, error) { +func (lm *leaseManager) Create(ctx context.Context, opts ...leases.Opt) (leases.Lease, error) { var l leases.Lease for _, opt := range opts { if err := opt(&l); err != nil { @@ -75,7 +75,7 @@ func (lm *LeaseManager) Create(ctx context.Context, opts ...leases.Opt) (leases. if err == bolt.ErrBucketExists { err = errdefs.ErrAlreadyExists } - return errors.Wrapf(err, "lease %q", l.ID) + return fmt.Errorf("lease %q: %w", l.ID, err) } t := time.Now().UTC() @@ -102,7 +102,7 @@ func (lm *LeaseManager) Create(ctx context.Context, opts ...leases.Opt) (leases. } // Delete deletes the lease with the provided lease ID -func (lm *LeaseManager) Delete(ctx context.Context, lease leases.Lease, _ ...leases.DeleteOpt) error { +func (lm *leaseManager) Delete(ctx context.Context, lease leases.Lease, _ ...leases.DeleteOpt) error { namespace, err := namespaces.NamespaceRequired(ctx) if err != nil { return err @@ -111,11 +111,11 @@ func (lm *LeaseManager) Delete(ctx context.Context, lease leases.Lease, _ ...lea return update(ctx, lm.db, func(tx *bolt.Tx) error { topbkt := getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases) if topbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "lease %q", lease.ID) + return fmt.Errorf("lease %q: %w", lease.ID, errdefs.ErrNotFound) } if err := topbkt.DeleteBucket([]byte(lease.ID)); err != nil { if err == bolt.ErrBucketNotFound { - err = errors.Wrapf(errdefs.ErrNotFound, "lease %q", lease.ID) + err = fmt.Errorf("lease %q: %w", lease.ID, errdefs.ErrNotFound) } return err } @@ -127,7 +127,7 @@ func (lm *LeaseManager) Delete(ctx context.Context, lease leases.Lease, _ ...lea } // List lists all active leases -func (lm *LeaseManager) List(ctx context.Context, fs ...string) ([]leases.Lease, error) { +func (lm *leaseManager) List(ctx context.Context, fs ...string) ([]leases.Lease, error) { namespace, err := namespaces.NamespaceRequired(ctx) if err != nil { return nil, err @@ -135,7 +135,7 @@ func (lm *LeaseManager) List(ctx context.Context, fs ...string) ([]leases.Lease, filter, err := filters.ParseAll(fs...) if err != nil { - return nil, errors.Wrap(errdefs.ErrInvalidArgument, err.Error()) + return nil, fmt.Errorf("%s: %w", err.Error(), errdefs.ErrInvalidArgument) } var ll []leases.Lease @@ -183,7 +183,7 @@ func (lm *LeaseManager) List(ctx context.Context, fs ...string) ([]leases.Lease, } // AddResource references the resource by the provided lease. -func (lm *LeaseManager) AddResource(ctx context.Context, lease leases.Lease, r leases.Resource) error { +func (lm *leaseManager) AddResource(ctx context.Context, lease leases.Lease, r leases.Resource) error { namespace, err := namespaces.NamespaceRequired(ctx) if err != nil { return err @@ -192,7 +192,7 @@ func (lm *LeaseManager) AddResource(ctx context.Context, lease leases.Lease, r l return update(ctx, lm.db, func(tx *bolt.Tx) error { topbkt := getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases, []byte(lease.ID)) if topbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "lease %q", lease.ID) + return fmt.Errorf("lease %q: %w", lease.ID, errdefs.ErrNotFound) } keys, ref, err := parseLeaseResource(r) @@ -212,7 +212,7 @@ func (lm *LeaseManager) AddResource(ctx context.Context, lease leases.Lease, r l } // DeleteResource dereferences the resource by the provided lease. -func (lm *LeaseManager) DeleteResource(ctx context.Context, lease leases.Lease, r leases.Resource) error { +func (lm *leaseManager) DeleteResource(ctx context.Context, lease leases.Lease, r leases.Resource) error { namespace, err := namespaces.NamespaceRequired(ctx) if err != nil { return err @@ -221,7 +221,7 @@ func (lm *LeaseManager) DeleteResource(ctx context.Context, lease leases.Lease, return update(ctx, lm.db, func(tx *bolt.Tx) error { topbkt := getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases, []byte(lease.ID)) if topbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "lease %q", lease.ID) + return fmt.Errorf("lease %q: %w", lease.ID, errdefs.ErrNotFound) } keys, ref, err := parseLeaseResource(r) @@ -250,7 +250,7 @@ func (lm *LeaseManager) DeleteResource(ctx context.Context, lease leases.Lease, } // ListResources lists all the resources referenced by the lease. -func (lm *LeaseManager) ListResources(ctx context.Context, lease leases.Lease) ([]leases.Resource, error) { +func (lm *leaseManager) ListResources(ctx context.Context, lease leases.Lease) ([]leases.Resource, error) { namespace, err := namespaces.NamespaceRequired(ctx) if err != nil { return nil, err @@ -262,7 +262,7 @@ func (lm *LeaseManager) ListResources(ctx context.Context, lease leases.Lease) ( topbkt := getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases, []byte(lease.ID)) if topbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "lease %q", lease.ID) + return fmt.Errorf("lease %q: %w", lease.ID, errdefs.ErrNotFound) } // content resources @@ -333,7 +333,7 @@ func addSnapshotLease(ctx context.Context, tx *bolt.Tx, snapshotter, key string) bkt := getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases, []byte(lid)) if bkt == nil { - return errors.Wrap(errdefs.ErrNotFound, "lease does not exist") + return fmt.Errorf("lease does not exist: %w", errdefs.ErrNotFound) } bkt, err := bkt.CreateBucketIfNotExists(bucketKeyObjectSnapshots) @@ -382,7 +382,7 @@ func addContentLease(ctx context.Context, tx *bolt.Tx, dgst digest.Digest) error bkt := getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases, []byte(lid)) if bkt == nil { - return errors.Wrap(errdefs.ErrNotFound, "lease does not exist") + return fmt.Errorf("lease does not exist: %w", errdefs.ErrNotFound) } bkt, err := bkt.CreateBucketIfNotExists(bucketKeyObjectContent) @@ -426,7 +426,7 @@ func addIngestLease(ctx context.Context, tx *bolt.Tx, ref string) (bool, error) bkt := getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases, []byte(lid)) if bkt == nil { - return false, errors.Wrap(errdefs.ErrNotFound, "lease does not exist") + return false, fmt.Errorf("lease does not exist: %w", errdefs.ErrNotFound) } bkt, err := bkt.CreateBucketIfNotExists(bucketKeyObjectIngests) @@ -473,22 +473,22 @@ func parseLeaseResource(r leases.Resource) ([]string, string, error) { string(bucketKeyObjectIngests): if len(keys) != 1 { - return nil, "", errors.Wrapf(errdefs.ErrInvalidArgument, "invalid resource type %s", typ) + return nil, "", fmt.Errorf("invalid resource type %s: %w", typ, errdefs.ErrInvalidArgument) } if k == string(bucketKeyObjectContent) { dgst, err := digest.Parse(ref) if err != nil { - return nil, "", errors.Wrapf(errdefs.ErrInvalidArgument, "invalid content resource id %s: %v", ref, err) + return nil, "", fmt.Errorf("invalid content resource id %s: %v: %w", ref, err, errdefs.ErrInvalidArgument) } ref = dgst.String() } case string(bucketKeyObjectSnapshots): if len(keys) != 2 { - return nil, "", errors.Wrapf(errdefs.ErrInvalidArgument, "invalid snapshot resource type %s", typ) + return nil, "", fmt.Errorf("invalid snapshot resource type %s: %w", typ, errdefs.ErrInvalidArgument) } default: - return nil, "", errors.Wrapf(errdefs.ErrNotImplemented, "resource type %s not supported yet", typ) + return nil, "", fmt.Errorf("resource type %s not supported yet: %w", typ, errdefs.ErrNotImplemented) } return keys, ref, nil diff --git a/vendor/github.com/containerd/containerd/metadata/namespaces.go b/vendor/github.com/containerd/containerd/metadata/namespaces.go index 165c09fcac..84eb83f273 100644 --- a/vendor/github.com/containerd/containerd/metadata/namespaces.go +++ b/vendor/github.com/containerd/containerd/metadata/namespaces.go @@ -18,13 +18,13 @@ package metadata import ( "context" + "fmt" "strings" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/identifiers" l "github.com/containerd/containerd/labels" "github.com/containerd/containerd/namespaces" - "github.com/pkg/errors" bolt "go.etcd.io/bbolt" ) @@ -49,7 +49,7 @@ func (s *namespaceStore) Create(ctx context.Context, namespace string, labels ma for k, v := range labels { if err := l.Validate(k, v); err != nil { - return errors.Wrapf(err, "namespace.Labels") + return fmt.Errorf("namespace.Labels: %w", err) } } @@ -57,7 +57,7 @@ func (s *namespaceStore) Create(ctx context.Context, namespace string, labels ma bkt, err := topbkt.CreateBucket([]byte(namespace)) if err != nil { if err == bolt.ErrBucketExists { - return errors.Wrapf(errdefs.ErrAlreadyExists, "namespace %q", namespace) + return fmt.Errorf("namespace %q: %w", namespace, errdefs.ErrAlreadyExists) } return err @@ -97,7 +97,7 @@ func (s *namespaceStore) Labels(ctx context.Context, namespace string) (map[stri func (s *namespaceStore) SetLabel(ctx context.Context, namespace, key, value string) error { if err := l.Validate(key, value); err != nil { - return errors.Wrapf(err, "namespace.Labels") + return fmt.Errorf("namespace.Labels: %w", err) } return withNamespacesLabelsBucket(s.tx, namespace, func(bkt *bolt.Bucket) error { @@ -147,16 +147,16 @@ func (s *namespaceStore) Delete(ctx context.Context, namespace string, opts ...n } if len(types) > 0 { - return errors.Wrapf( - errdefs.ErrFailedPrecondition, - "namespace %q must be empty, but it still has %s", + return fmt.Errorf( + "namespace %q must be empty, but it still has %s: %w", namespace, strings.Join(types, ", "), + errdefs.ErrFailedPrecondition, ) } if err := bkt.DeleteBucket([]byte(namespace)); err != nil { if err == bolt.ErrBucketNotFound { - return errors.Wrapf(errdefs.ErrNotFound, "namespace %q", namespace) + return fmt.Errorf("namespace %q: %w", namespace, errdefs.ErrNotFound) } return err @@ -184,7 +184,7 @@ func (s *namespaceStore) listNs(namespace string) ([]string, error) { if err := snbkt.ForEach(func(k, v []byte) error { if v == nil { if !isBucketEmpty(snbkt.Bucket(k)) { - out = append(out, "snapshot-"+string(k)) + out = append(out, fmt.Sprintf("snapshots on %q snapshotter", k)) } } return nil diff --git a/vendor/github.com/containerd/containerd/metadata/snapshot.go b/vendor/github.com/containerd/containerd/metadata/snapshot.go index 389aeda45e..348602093a 100644 --- a/vendor/github.com/containerd/containerd/metadata/snapshot.go +++ b/vendor/github.com/containerd/containerd/metadata/snapshot.go @@ -32,7 +32,6 @@ import ( "github.com/containerd/containerd/mount" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/snapshots" - "github.com/pkg/errors" bolt "go.etcd.io/bbolt" ) @@ -88,7 +87,7 @@ func (s *snapshotter) resolveKey(ctx context.Context, key string) (string, error if err := view(ctx, s.db, func(tx *bolt.Tx) error { id = getKey(tx, ns, s.name, key) if id == "" { - return errors.Wrapf(errdefs.ErrNotFound, "snapshot %v does not exist", key) + return fmt.Errorf("snapshot %v does not exist: %w", key, errdefs.ErrNotFound) } return nil }); err != nil { @@ -113,18 +112,18 @@ func (s *snapshotter) Stat(ctx context.Context, key string) (snapshots.Info, err if err := view(ctx, s.db, func(tx *bolt.Tx) error { bkt := getSnapshotterBucket(tx, ns, s.name) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "snapshot %v does not exist", key) + return fmt.Errorf("snapshot %v does not exist: %w", key, errdefs.ErrNotFound) } sbkt := bkt.Bucket([]byte(key)) if sbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "snapshot %v does not exist", key) + return fmt.Errorf("snapshot %v does not exist: %w", key, errdefs.ErrNotFound) } local.Labels, err = boltutil.ReadLabels(sbkt) if err != nil { - return errors.Wrap(err, "failed to read labels") + return fmt.Errorf("failed to read labels: %w", err) } if err := boltutil.ReadTimestamps(sbkt, &local.Created, &local.Updated); err != nil { - return errors.Wrap(err, "failed to read timestamps") + return fmt.Errorf("failed to read timestamps: %w", err) } bkey = string(sbkt.Get(bucketKeyName)) local.Parent = string(sbkt.Get(bucketKeyParent)) @@ -152,7 +151,7 @@ func (s *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpath } if info.Name == "" { - return snapshots.Info{}, errors.Wrap(errdefs.ErrInvalidArgument, "") + return snapshots.Info{}, errdefs.ErrInvalidArgument } var ( @@ -165,19 +164,19 @@ func (s *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpath if err := update(ctx, s.db, func(tx *bolt.Tx) error { bkt := getSnapshotterBucket(tx, ns, s.name) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "snapshot %v does not exist", info.Name) + return fmt.Errorf("snapshot %v does not exist: %w", info.Name, errdefs.ErrNotFound) } sbkt := bkt.Bucket([]byte(info.Name)) if sbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "snapshot %v does not exist", info.Name) + return fmt.Errorf("snapshot %v does not exist: %w", info.Name, errdefs.ErrNotFound) } local.Labels, err = boltutil.ReadLabels(sbkt) if err != nil { - return errors.Wrap(err, "failed to read labels") + return fmt.Errorf("failed to read labels: %w", err) } if err := boltutil.ReadTimestamps(sbkt, &local.Created, &local.Updated); err != nil { - return errors.Wrap(err, "failed to read timestamps") + return fmt.Errorf("failed to read timestamps: %w", err) } // Handle field updates @@ -197,7 +196,7 @@ func (s *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpath case "labels": local.Labels = info.Labels default: - return errors.Wrapf(errdefs.ErrInvalidArgument, "cannot update %q field on snapshot %q", path, info.Name) + return fmt.Errorf("cannot update %q field on snapshot %q: %w", path, info.Name, errdefs.ErrInvalidArgument) } } } else { @@ -209,10 +208,10 @@ func (s *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpath local.Updated = time.Now().UTC() if err := boltutil.WriteTimestamps(sbkt, local.Created, local.Updated); err != nil { - return errors.Wrap(err, "failed to read timestamps") + return fmt.Errorf("failed to read timestamps: %w", err) } if err := boltutil.WriteLabels(sbkt, local.Labels); err != nil { - return errors.Wrap(err, "failed to read labels") + return fmt.Errorf("failed to read labels: %w", err) } bkey = string(sbkt.Get(bucketKeyName)) local.Parent = string(sbkt.Get(bucketKeyParent)) @@ -319,18 +318,18 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re // Check if target exists, if so, return already exists if target != "" { if tbkt := bkt.Bucket([]byte(target)); tbkt != nil { - return errors.Wrapf(errdefs.ErrAlreadyExists, "target snapshot %q", target) + return fmt.Errorf("target snapshot %q: %w", target, errdefs.ErrAlreadyExists) } } if bbkt := bkt.Bucket([]byte(key)); bbkt != nil { - return errors.Wrapf(errdefs.ErrAlreadyExists, "snapshot %q", key) + return fmt.Errorf("snapshot %q: %w", key, errdefs.ErrAlreadyExists) } if parent != "" { pbkt := bkt.Bucket([]byte(parent)) if pbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "parent snapshot %v does not exist", parent) + return fmt.Errorf("parent snapshot %v does not exist: %w", parent, errdefs.ErrNotFound) } bparent = string(pbkt.Get(bucketKeyName)) } @@ -378,11 +377,11 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re return nil }, filter); err != nil { - return nil, errors.Wrap(err, "failed walking backend snapshots") + return nil, fmt.Errorf("failed walking backend snapshots: %w", err) } if tinfo == nil { - return nil, errors.Wrapf(errdefs.ErrNotFound, "target snapshot %q in backend", target) + return nil, fmt.Errorf("target snapshot %q in backend: %w", target, errdefs.ErrNotFound) } key = target @@ -401,12 +400,12 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re } // Propagate this error after the final update - rerr = errors.Wrapf(errdefs.ErrAlreadyExists, "target snapshot %q from snapshotter", target) + rerr = fmt.Errorf("target snapshot %q from snapshotter: %w", target, errdefs.ErrAlreadyExists) } else { // This condition is unexpected as the key provided is expected // to be new and unique, return as unknown response from backend // to avoid confusing callers handling already exists. - return nil, errors.Wrapf(errdefs.ErrUnknown, "unexpected error from snapshotter: %v", err) + return nil, fmt.Errorf("unexpected error from snapshotter: %v: %w", err, errdefs.ErrUnknown) } } else if err != nil { return nil, err @@ -420,7 +419,7 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re if txerr := update(ctx, s.db, func(tx *bolt.Tx) error { bkt := getSnapshotterBucket(tx, ns, s.name) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "can not find snapshotter %q", s.name) + return fmt.Errorf("can not find snapshotter %q: %w", s.name, errdefs.ErrNotFound) } if err := addSnapshotLease(ctx, tx, s.name, key); err != nil { @@ -433,7 +432,7 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re return err } if rerr == nil { - rerr = errors.Wrapf(errdefs.ErrAlreadyExists, "snapshot %q", key) + rerr = fmt.Errorf("snapshot %q: %w", key, errdefs.ErrAlreadyExists) } return nil } @@ -441,7 +440,7 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re if parent != "" { pbkt := bkt.Bucket([]byte(parent)) if pbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "parent snapshot %v does not exist", parent) + return fmt.Errorf("parent snapshot %v does not exist: %w", parent, errdefs.ErrNotFound) } // Ensure the backend's parent matches the metadata store's parent @@ -451,7 +450,7 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re // uniqueness of the reference relationships, the metadata store // can only error out to prevent inconsistent data. if bparent != string(pbkt.Get(bucketKeyName)) { - return errors.Wrapf(errdefs.ErrInvalidArgument, "mismatched parent %s from target %s", parent, target) + return fmt.Errorf("mismatched parent %s from target %s: %w", parent, target, errdefs.ErrInvalidArgument) } cbkt, err := pbkt.CreateBucketIfNotExists(bucketKeyChildren) @@ -516,14 +515,14 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap if err := update(ctx, s.db, func(tx *bolt.Tx) error { bkt := getSnapshotterBucket(tx, ns, s.name) if bkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, - "can not find snapshotter %q", s.name) + return fmt.Errorf("can not find snapshotter %q: %w", + s.name, errdefs.ErrNotFound) } bbkt, err := bkt.CreateBucket([]byte(name)) if err != nil { if err == bolt.ErrBucketExists { - err = errors.Wrapf(errdefs.ErrAlreadyExists, "snapshot %q", name) + err = fmt.Errorf("snapshot %q: %w", name, errdefs.ErrAlreadyExists) } return err } @@ -533,7 +532,7 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap obkt := bkt.Bucket([]byte(key)) if obkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "snapshot %v does not exist", key) + return fmt.Errorf("snapshot %v does not exist: %w", key, errdefs.ErrNotFound) } bkey := string(obkt.Get(bucketKeyName)) @@ -553,7 +552,7 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap if len(parent) > 0 { pbkt := bkt.Bucket(parent) if pbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "parent snapshot %v does not exist", string(parent)) + return fmt.Errorf("parent snapshot %v does not exist: %w", string(parent), errdefs.ErrNotFound) } cbkt, err := pbkt.CreateBucketIfNotExists(bucketKeyChildren) @@ -639,13 +638,13 @@ func (s *snapshotter) Remove(ctx context.Context, key string) error { sbkt = bkt.Bucket([]byte(key)) } if sbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "snapshot %v does not exist", key) + return fmt.Errorf("snapshot %v does not exist: %w", key, errdefs.ErrNotFound) } cbkt := sbkt.Bucket(bucketKeyChildren) if cbkt != nil { if child, _ := cbkt.Cursor().First(); child != nil { - return errors.Wrap(errdefs.ErrFailedPrecondition, "cannot remove snapshot with child") + return fmt.Errorf("cannot remove snapshot with child: %w", errdefs.ErrFailedPrecondition) } } @@ -653,12 +652,12 @@ func (s *snapshotter) Remove(ctx context.Context, key string) error { if len(parent) > 0 { pbkt := bkt.Bucket(parent) if pbkt == nil { - return errors.Wrapf(errdefs.ErrNotFound, "parent snapshot %v does not exist", string(parent)) + return fmt.Errorf("parent snapshot %v does not exist: %w", string(parent), errdefs.ErrNotFound) } cbkt := pbkt.Bucket(bucketKeyChildren) if cbkt != nil { if err := cbkt.Delete([]byte(key)); err != nil { - return errors.Wrap(err, "failed to remove child link") + return fmt.Errorf("failed to remove child link: %w", err) } } } @@ -784,13 +783,14 @@ func (s *snapshotter) Walk(ctx context.Context, fn snapshots.WalkFunc, fs ...str func validateSnapshot(info *snapshots.Info) error { for k, v := range info.Labels { if err := labels.Validate(k, v); err != nil { - return errors.Wrapf(err, "info.Labels") + return fmt.Errorf("info.Labels: %w", err) } } return nil } +// garbageCollect removes all snapshots that are no longer used. func (s *snapshotter) garbageCollect(ctx context.Context) (d time.Duration, err error) { s.l.Lock() t1 := time.Now() diff --git a/vendor/github.com/containerd/containerd/sys/mount_linux.go b/vendor/github.com/containerd/containerd/mount/fmountat_linux.go similarity index 90% rename from vendor/github.com/containerd/containerd/sys/mount_linux.go rename to vendor/github.com/containerd/containerd/mount/fmountat_linux.go index a21045529a..850a92acf6 100644 --- a/vendor/github.com/containerd/containerd/sys/mount_linux.go +++ b/vendor/github.com/containerd/containerd/mount/fmountat_linux.go @@ -14,20 +14,20 @@ limitations under the License. */ -package sys +package mount import ( + "fmt" "runtime" "syscall" "unsafe" "github.com/containerd/containerd/log" - "github.com/pkg/errors" "golang.org/x/sys/unix" ) -// FMountat performs mount from the provided directory. -func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data string) error { +// fMountat performs mount from the provided directory. +func fMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data string) error { var ( sourceP, targetP, fstypeP, dataP *byte pid uintptr @@ -62,7 +62,7 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data var pipefds [2]int if err := syscall.Pipe2(pipefds[:], syscall.O_CLOEXEC); err != nil { - return errors.Wrap(err, "failed to open pipe") + return fmt.Errorf("failed to open pipe: %w", err) } defer func() { @@ -82,7 +82,7 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data ) if errno != 0 { - return errors.Wrap(errno, "failed to fork thread") + return fmt.Errorf("failed to fork thread: %w", errno) } defer func() { @@ -101,11 +101,11 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data uintptr(unsafe.Pointer(&status)), unsafe.Sizeof(status)) if errno != 0 { - return errors.Wrap(errno, "failed to read pipe") + return fmt.Errorf("failed to read pipe: %w", errno) } if status != 0 { - return errors.Wrap(status, "failed to mount") + return fmt.Errorf("failed to mount: %w", status) } return nil diff --git a/vendor/github.com/containerd/containerd/mount/lookup_unix.go b/vendor/github.com/containerd/containerd/mount/lookup_unix.go index a2d51ce584..44881750b2 100644 --- a/vendor/github.com/containerd/containerd/mount/lookup_unix.go +++ b/vendor/github.com/containerd/containerd/mount/lookup_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows /* @@ -19,10 +20,10 @@ package mount import ( + "fmt" "path/filepath" "github.com/moby/sys/mountinfo" - "github.com/pkg/errors" ) // Lookup returns the mount info corresponds to the path. @@ -31,10 +32,10 @@ func Lookup(dir string) (Info, error) { m, err := mountinfo.GetMounts(mountinfo.ParentsFilter(dir)) if err != nil { - return Info{}, errors.Wrapf(err, "failed to find the mount info for %q", dir) + return Info{}, fmt.Errorf("failed to find the mount info for %q: %w", dir, err) } if len(m) == 0 { - return Info{}, errors.Errorf("failed to find the mount info for %q", dir) + return Info{}, fmt.Errorf("failed to find the mount info for %q", dir) } // find the longest matching mount point diff --git a/vendor/github.com/containerd/containerd/mount/lookup_unsupported.go b/vendor/github.com/containerd/containerd/mount/lookup_unsupported.go index 46ec66a904..2e954b1ae5 100644 --- a/vendor/github.com/containerd/containerd/mount/lookup_unsupported.go +++ b/vendor/github.com/containerd/containerd/mount/lookup_unsupported.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows /* diff --git a/vendor/github.com/containerd/containerd/mount/losetup_linux.go b/vendor/github.com/containerd/containerd/mount/losetup_linux.go index e99e962f12..9a68017901 100644 --- a/vendor/github.com/containerd/containerd/mount/losetup_linux.go +++ b/vendor/github.com/containerd/containerd/mount/losetup_linux.go @@ -17,6 +17,7 @@ package mount import ( + "errors" "fmt" "math/rand" "os" @@ -25,7 +26,6 @@ import ( "time" "unsafe" - "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -59,12 +59,12 @@ func ioctl(fd, req, args uintptr) (uintptr, uintptr, error) { func getFreeLoopDev() (uint32, error) { ctrl, err := os.OpenFile(loopControlPath, os.O_RDWR, 0) if err != nil { - return 0, errors.Errorf("could not open %v: %v", loopControlPath, err) + return 0, fmt.Errorf("could not open %v: %v", loopControlPath, err) } defer ctrl.Close() num, _, err := ioctl(ctrl.Fd(), unix.LOOP_CTL_GET_FREE, 0) if err != nil { - return 0, errors.Wrap(err, "could not get free loop device") + return 0, fmt.Errorf("could not get free loop device: %w", err) } return uint32(num), nil } @@ -81,13 +81,13 @@ func setupLoopDev(backingFile, loopDev string, param LoopParams) (_ *os.File, re back, err := os.OpenFile(backingFile, flags, 0) if err != nil { - return nil, errors.Wrapf(err, "could not open backing file: %s", backingFile) + return nil, fmt.Errorf("could not open backing file: %s: %w", backingFile, err) } defer back.Close() loop, err := os.OpenFile(loopDev, flags, 0) if err != nil { - return nil, errors.Wrapf(err, "could not open loop device: %s", loopDev) + return nil, fmt.Errorf("could not open loop device: %s: %w", loopDev, err) } defer func() { if retErr != nil { @@ -97,7 +97,7 @@ func setupLoopDev(backingFile, loopDev string, param LoopParams) (_ *os.File, re // 2. Set FD if _, _, err = ioctl(loop.Fd(), unix.LOOP_SET_FD, back.Fd()); err != nil { - return nil, errors.Wrapf(err, "could not set loop fd for device: %s", loopDev) + return nil, fmt.Errorf("could not set loop fd for device: %s: %w", loopDev, err) } // 3. Set Info @@ -131,7 +131,7 @@ func setupLoopDev(backingFile, loopDev string, param LoopParams) (_ *os.File, re } _, _, _ = ioctl(loop.Fd(), unix.LOOP_CLR_FD, 0) - return nil, errors.Errorf("failed to set loop device info: %v", err) + return nil, fmt.Errorf("failed to set loop device info: %v", err) } // setupLoop looks for (and possibly creates) a free loop device, and @@ -200,7 +200,7 @@ func AttachLoopDevice(backingFile string) (string, error) { func DetachLoopDevice(devices ...string) error { for _, dev := range devices { if err := removeLoop(dev); err != nil { - return errors.Wrapf(err, "failed to remove loop device: %s", dev) + return fmt.Errorf("failed to remove loop device: %s: %w", dev, err) } } diff --git a/vendor/github.com/containerd/containerd/mount/mount_freebsd.go b/vendor/github.com/containerd/containerd/mount/mount_freebsd.go index d52450013c..3711383c61 100644 --- a/vendor/github.com/containerd/containerd/mount/mount_freebsd.go +++ b/vendor/github.com/containerd/containerd/mount/mount_freebsd.go @@ -1,5 +1,3 @@ -// +build freebsd - /* Copyright The containerd Authors. @@ -19,11 +17,12 @@ package mount import ( + "errors" + "fmt" "os" - "os/exec" "time" - "github.com/pkg/errors" + exec "golang.org/x/sys/execabs" "golang.org/x/sys/unix" ) @@ -66,7 +65,7 @@ func (m *Mount) mountWithHelper(target string) error { return nil } if !errors.Is(err, unix.ECHILD) { - return errors.Wrapf(err, "mount [%v] failed: %q", args, string(out)) + return fmt.Errorf("mount [%v] failed: %q: %w", args, string(out), err) } // We got ECHILD, we are not sure whether the mount was successful. // If the mount ID has changed, we are sure we got some new mount, but still not sure it is fully completed. @@ -79,7 +78,7 @@ func (m *Mount) mountWithHelper(target string) error { _ = unmount(target, 0) } } - return errors.Errorf("mount [%v] failed with ECHILD (retired %d times)", args, retriesOnECHILD) + return fmt.Errorf("mount [%v] failed with ECHILD (retired %d times)", args, retriesOnECHILD) } // Unmount the provided mount path with the flags @@ -103,7 +102,7 @@ func unmount(target string, flags int) error { } return nil } - return errors.Wrapf(unix.EBUSY, "failed to unmount target %s", target) + return fmt.Errorf("failed to unmount target %s: %w", target, unix.EBUSY) } // UnmountAll repeatedly unmounts the given mount point until there diff --git a/vendor/github.com/containerd/containerd/mount/mount_linux.go b/vendor/github.com/containerd/containerd/mount/mount_linux.go index 3f05ebc891..a69f65c2dd 100644 --- a/vendor/github.com/containerd/containerd/mount/mount_linux.go +++ b/vendor/github.com/containerd/containerd/mount/mount_linux.go @@ -17,15 +17,14 @@ package mount import ( + "errors" "fmt" "os" - "os/exec" "path" "strings" "time" - "github.com/containerd/containerd/sys" - "github.com/pkg/errors" + exec "golang.org/x/sys/execabs" "golang.org/x/sys/unix" ) @@ -64,7 +63,7 @@ func (m *Mount) Mount(target string) (err error) { flags, data, losetup := parseMountOptions(options) if len(data) > pagesize { - return errors.Errorf("mount options is too long") + return errors.New("mount options is too long") } // propagation types. @@ -164,7 +163,7 @@ func unmount(target string, flags int) error { } return nil } - return errors.Wrapf(unix.EBUSY, "failed to unmount target %s", target) + return fmt.Errorf("failed to unmount target %s: %w", target, unix.EBUSY) } // UnmountAll repeatedly unmounts the given mount point until there @@ -366,19 +365,22 @@ func mountAt(chdir string, source, target, fstype string, flags uintptr, data st f, err := os.Open(chdir) if err != nil { - return errors.Wrap(err, "failed to mountat") + return fmt.Errorf("failed to mountat: %w", err) } defer f.Close() fs, err := f.Stat() if err != nil { - return errors.Wrap(err, "failed to mountat") + return fmt.Errorf("failed to mountat: %w", err) } if !fs.IsDir() { - return errors.Wrap(errors.Errorf("%s is not dir", chdir), "failed to mountat") + return fmt.Errorf("failed to mountat: %s is not dir", chdir) } - return errors.Wrap(sys.FMountat(f.Fd(), source, target, fstype, flags, data), "failed to mountat") + if err := fMountat(f.Fd(), source, target, fstype, flags, data); err != nil { + return fmt.Errorf("failed to mountat: %w", err) + } + return nil } func (m *Mount) mountWithHelper(helperBinary, typePrefix, target string) error { @@ -407,7 +409,7 @@ func (m *Mount) mountWithHelper(helperBinary, typePrefix, target string) error { return nil } if !errors.Is(err, unix.ECHILD) { - return errors.Wrapf(err, "mount helper [%s %v] failed: %q", helperBinary, args, string(out)) + return fmt.Errorf("mount helper [%s %v] failed: %q: %w", helperBinary, args, string(out), err) } // We got ECHILD, we are not sure whether the mount was successful. // If the mount ID has changed, we are sure we got some new mount, but still not sure it is fully completed. @@ -420,5 +422,5 @@ func (m *Mount) mountWithHelper(helperBinary, typePrefix, target string) error { _ = unmount(target, 0) } } - return errors.Errorf("mount helper [%s %v] failed with ECHILD (retired %d times)", helperBinary, args, retriesOnECHILD) + return fmt.Errorf("mount helper [%s %v] failed with ECHILD (retired %d times)", helperBinary, args, retriesOnECHILD) } diff --git a/vendor/github.com/containerd/containerd/mount/mount_unix.go b/vendor/github.com/containerd/containerd/mount/mount_unix.go index ecf569d9c4..795bb4bfe1 100644 --- a/vendor/github.com/containerd/containerd/mount/mount_unix.go +++ b/vendor/github.com/containerd/containerd/mount/mount_unix.go @@ -1,3 +1,4 @@ +//go:build darwin || openbsd // +build darwin openbsd /* @@ -18,7 +19,7 @@ package mount -import "github.com/pkg/errors" +import "errors" var ( // ErrNotImplementOnUnix is returned for methods that are not implemented diff --git a/vendor/github.com/containerd/containerd/mount/mount_windows.go b/vendor/github.com/containerd/containerd/mount/mount_windows.go index 5de25c4e0a..87fed8268e 100644 --- a/vendor/github.com/containerd/containerd/mount/mount_windows.go +++ b/vendor/github.com/containerd/containerd/mount/mount_windows.go @@ -18,11 +18,13 @@ package mount import ( "encoding/json" + "errors" + "fmt" + "os" "path/filepath" "strings" "github.com/Microsoft/hcsshim" - "github.com/pkg/errors" ) var ( @@ -33,7 +35,7 @@ var ( // Mount to the provided target func (m *Mount) Mount(target string) error { if m.Type != "windows-layer" { - return errors.Errorf("invalid windows mount type: '%s'", m.Type) + return fmt.Errorf("invalid windows mount type: '%s'", m.Type) } home, layerID := filepath.Split(m.Source) @@ -48,16 +50,22 @@ func (m *Mount) Mount(target string) error { } if err = hcsshim.ActivateLayer(di, layerID); err != nil { - return errors.Wrapf(err, "failed to activate layer %s", m.Source) + return fmt.Errorf("failed to activate layer %s: %w", m.Source, err) } - defer func() { - if err != nil { - hcsshim.DeactivateLayer(di, layerID) - } - }() if err = hcsshim.PrepareLayer(di, layerID, parentLayerPaths); err != nil { - return errors.Wrapf(err, "failed to prepare layer %s", m.Source) + return fmt.Errorf("failed to prepare layer %s: %w", m.Source, err) + } + + // We can link the layer mount path to the given target. It is an UNC path, and it needs + // a trailing backslash. + mountPath, err := hcsshim.GetLayerMountPath(di, layerID) + if err != nil { + return fmt.Errorf("failed to get layer mount path for %s: %w", m.Source, err) + } + mountPath = mountPath + `\` + if err = os.Symlink(mountPath, target); err != nil { + return fmt.Errorf("failed to link mount to taget %s: %w", target, err) } return nil } @@ -73,7 +81,7 @@ func (m *Mount) GetParentPaths() ([]string, error) { if strings.HasPrefix(option, ParentLayerPathsFlag) { err := json.Unmarshal([]byte(option[len(ParentLayerPathsFlag):]), &parentLayerPaths) if err != nil { - return nil, errors.Wrap(err, "failed to unmarshal parent layer paths from mount") + return nil, fmt.Errorf("failed to unmarshal parent layer paths from mount: %w", err) } } } @@ -90,10 +98,10 @@ func Unmount(mount string, flags int) error { ) if err := hcsshim.UnprepareLayer(di, layerID); err != nil { - return errors.Wrapf(err, "failed to unprepare layer %s", mount) + return fmt.Errorf("failed to unprepare layer %s: %w", mount, err) } if err := hcsshim.DeactivateLayer(di, layerID); err != nil { - return errors.Wrapf(err, "failed to deactivate layer %s", mount) + return fmt.Errorf("failed to deactivate layer %s: %w", mount, err) } return nil diff --git a/vendor/github.com/containerd/containerd/sys/subprocess_unsafe_linux.go b/vendor/github.com/containerd/containerd/mount/subprocess_unsafe_linux.go similarity index 98% rename from vendor/github.com/containerd/containerd/sys/subprocess_unsafe_linux.go rename to vendor/github.com/containerd/containerd/mount/subprocess_unsafe_linux.go index 6e40a9c7d7..c7cb0c0343 100644 --- a/vendor/github.com/containerd/containerd/sys/subprocess_unsafe_linux.go +++ b/vendor/github.com/containerd/containerd/mount/subprocess_unsafe_linux.go @@ -14,7 +14,7 @@ limitations under the License. */ -package sys +package mount import ( _ "unsafe" // required for go:linkname. diff --git a/vendor/github.com/containerd/containerd/sys/subprocess_unsafe_linux.s b/vendor/github.com/containerd/containerd/mount/subprocess_unsafe_linux.s similarity index 100% rename from vendor/github.com/containerd/containerd/sys/subprocess_unsafe_linux.s rename to vendor/github.com/containerd/containerd/mount/subprocess_unsafe_linux.s diff --git a/vendor/github.com/containerd/containerd/mount/temp.go b/vendor/github.com/containerd/containerd/mount/temp.go index 9dc4010fee..13eedaf035 100644 --- a/vendor/github.com/containerd/containerd/mount/temp.go +++ b/vendor/github.com/containerd/containerd/mount/temp.go @@ -18,11 +18,10 @@ package mount import ( "context" - "io/ioutil" + "fmt" "os" "github.com/containerd/containerd/log" - "github.com/pkg/errors" ) var tempMountLocation = getTempDir() @@ -31,9 +30,9 @@ var tempMountLocation = getTempDir() // The mounts are valid during the call to the f. // Finally we will unmount and remove the temp dir regardless of the result of f. func WithTempMount(ctx context.Context, mounts []Mount, f func(root string) error) (err error) { - root, uerr := ioutil.TempDir(tempMountLocation, "containerd-mount") + root, uerr := os.MkdirTemp(tempMountLocation, "containerd-mount") if uerr != nil { - return errors.Wrapf(uerr, "failed to create temp dir") + return fmt.Errorf("failed to create temp dir: %w", uerr) } // We use Remove here instead of RemoveAll. // The RemoveAll will delete the temp dir and all children it contains. @@ -44,25 +43,28 @@ func WithTempMount(ctx context.Context, mounts []Mount, f func(root string) erro // For details, please refer to #1868 #1785. defer func() { if uerr = os.Remove(root); uerr != nil { - log.G(ctx).WithError(uerr).WithField("dir", root).Errorf("failed to remove mount temp dir") + log.G(ctx).WithError(uerr).WithField("dir", root).Error("failed to remove mount temp dir") } }() // We should do defer first, if not we will not do Unmount when only a part of Mounts are failed. defer func() { if uerr = UnmountAll(root, 0); uerr != nil { - uerr = errors.Wrapf(uerr, "failed to unmount %s", root) + uerr = fmt.Errorf("failed to unmount %s: %w", root, uerr) if err == nil { err = uerr } else { - err = errors.Wrap(err, uerr.Error()) + err = fmt.Errorf("%s: %w", uerr.Error(), err) } } }() if uerr = All(mounts, root); uerr != nil { - return errors.Wrapf(uerr, "failed to mount %s", root) + return fmt.Errorf("failed to mount %s: %w", root, uerr) } - return errors.Wrapf(f(root), "mount callback failed on %s", root) + if err := f(root); err != nil { + return fmt.Errorf("mount callback failed on %s: %w", root, err) + } + return nil } func getTempDir() string { diff --git a/vendor/github.com/containerd/containerd/mount/temp_unix.go b/vendor/github.com/containerd/containerd/mount/temp_unix.go index ed190b8f9d..e969700818 100644 --- a/vendor/github.com/containerd/containerd/mount/temp_unix.go +++ b/vendor/github.com/containerd/containerd/mount/temp_unix.go @@ -1,4 +1,5 @@ -// +build !windows +//go:build !windows && !darwin +// +build !windows,!darwin /* Copyright The containerd Authors. diff --git a/vendor/github.com/containerd/containerd/mount/temp_unsupported.go b/vendor/github.com/containerd/containerd/mount/temp_unsupported.go index 942be4128a..feec90a76f 100644 --- a/vendor/github.com/containerd/containerd/mount/temp_unsupported.go +++ b/vendor/github.com/containerd/containerd/mount/temp_unsupported.go @@ -1,4 +1,5 @@ -// +build windows +//go:build windows || darwin +// +build windows darwin /* Copyright The containerd Authors. diff --git a/vendor/github.com/containerd/containerd/namespaces/context.go b/vendor/github.com/containerd/containerd/namespaces/context.go index b53c9012c1..e5e23fe430 100644 --- a/vendor/github.com/containerd/containerd/namespaces/context.go +++ b/vendor/github.com/containerd/containerd/namespaces/context.go @@ -18,11 +18,11 @@ package namespaces import ( "context" + "fmt" "os" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/identifiers" - "github.com/pkg/errors" ) const ( @@ -69,10 +69,10 @@ func Namespace(ctx context.Context) (string, bool) { func NamespaceRequired(ctx context.Context) (string, error) { namespace, ok := Namespace(ctx) if !ok || namespace == "" { - return "", errors.Wrapf(errdefs.ErrFailedPrecondition, "namespace is required") + return "", fmt.Errorf("namespace is required: %w", errdefs.ErrFailedPrecondition) } if err := identifiers.Validate(namespace); err != nil { - return "", errors.Wrap(err, "namespace validation") + return "", fmt.Errorf("namespace validation: %w", err) } return namespace, nil } diff --git a/vendor/github.com/containerd/containerd/oci/mounts.go b/vendor/github.com/containerd/containerd/oci/mounts.go new file mode 100644 index 0000000000..83dd0d0b10 --- /dev/null +++ b/vendor/github.com/containerd/containerd/oci/mounts.go @@ -0,0 +1,71 @@ +//go:build !freebsd +// +build !freebsd + +/* + 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 oci + +import ( + specs "github.com/opencontainers/runtime-spec/specs-go" +) + +func defaultMounts() []specs.Mount { + return []specs.Mount{ + { + Destination: "/proc", + Type: "proc", + Source: "proc", + Options: []string{"nosuid", "noexec", "nodev"}, + }, + { + Destination: "/dev", + Type: "tmpfs", + Source: "tmpfs", + Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"}, + }, + { + Destination: "/dev/pts", + Type: "devpts", + Source: "devpts", + Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"}, + }, + { + Destination: "/dev/shm", + Type: "tmpfs", + Source: "shm", + Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"}, + }, + { + Destination: "/dev/mqueue", + Type: "mqueue", + Source: "mqueue", + Options: []string{"nosuid", "noexec", "nodev"}, + }, + { + Destination: "/sys", + Type: "sysfs", + Source: "sysfs", + Options: []string{"nosuid", "noexec", "nodev", "ro"}, + }, + { + Destination: "/run", + Type: "tmpfs", + Source: "tmpfs", + Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"}, + }, + } +} diff --git a/vendor/github.com/containerd/containerd/sys/stat_unix.go b/vendor/github.com/containerd/containerd/oci/mounts_freebsd.go similarity index 52% rename from vendor/github.com/containerd/containerd/sys/stat_unix.go rename to vendor/github.com/containerd/containerd/oci/mounts_freebsd.go index 21a666dff8..42b9d7affd 100644 --- a/vendor/github.com/containerd/containerd/sys/stat_unix.go +++ b/vendor/github.com/containerd/containerd/oci/mounts_freebsd.go @@ -1,5 +1,3 @@ -// +build linux solaris - /* Copyright The containerd Authors. @@ -16,29 +14,25 @@ limitations under the License. */ -package sys +package oci import ( - "syscall" - "time" + specs "github.com/opencontainers/runtime-spec/specs-go" ) -// StatAtime returns the Atim -func StatAtime(st *syscall.Stat_t) syscall.Timespec { - return st.Atim -} - -// StatCtime returns the Ctim -func StatCtime(st *syscall.Stat_t) syscall.Timespec { - return st.Ctim -} - -// StatMtime returns the Mtim -func StatMtime(st *syscall.Stat_t) syscall.Timespec { - return st.Mtim -} - -// StatATimeAsTime returns st.Atim as a time.Time -func StatATimeAsTime(st *syscall.Stat_t) time.Time { - return time.Unix(int64(st.Atim.Sec), int64(st.Atim.Nsec)) // nolint: unconvert +func defaultMounts() []specs.Mount { + return []specs.Mount{ + { + Destination: "/dev", + Type: "devfs", + Source: "devfs", + Options: []string{"ruleset=4"}, + }, + { + Destination: "/dev/fd", + Type: "fdescfs", + Source: "fdescfs", + Options: []string{}, + }, + } } diff --git a/vendor/github.com/containerd/containerd/oci/spec.go b/vendor/github.com/containerd/containerd/oci/spec.go index 035bb7e7d8..34d7662309 100644 --- a/vendor/github.com/containerd/containerd/oci/spec.go +++ b/vendor/github.com/containerd/containerd/oci/spec.go @@ -161,50 +161,6 @@ func populateDefaultUnixSpec(ctx context.Context, s *Spec, id string) error { }, }, }, - Mounts: []specs.Mount{ - { - Destination: "/proc", - Type: "proc", - Source: "proc", - Options: []string{"nosuid", "noexec", "nodev"}, - }, - { - Destination: "/dev", - Type: "tmpfs", - Source: "tmpfs", - Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"}, - }, - { - Destination: "/dev/pts", - Type: "devpts", - Source: "devpts", - Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"}, - }, - { - Destination: "/dev/shm", - Type: "tmpfs", - Source: "shm", - Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"}, - }, - { - Destination: "/dev/mqueue", - Type: "mqueue", - Source: "mqueue", - Options: []string{"nosuid", "noexec", "nodev"}, - }, - { - Destination: "/sys", - Type: "sysfs", - Source: "sysfs", - Options: []string{"nosuid", "noexec", "nodev", "ro"}, - }, - { - Destination: "/run", - Type: "tmpfs", - Source: "tmpfs", - Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"}, - }, - }, Linux: &specs.Linux{ MaskedPaths: []string{ "/proc/acpi", @@ -237,6 +193,7 @@ func populateDefaultUnixSpec(ctx context.Context, s *Spec, id string) error { Namespaces: defaultUnixNamespaces(), }, } + s.Mounts = defaultMounts() return nil } diff --git a/vendor/github.com/containerd/containerd/oci/spec_opts.go b/vendor/github.com/containerd/containerd/oci/spec_opts.go index 4199a85d93..9b0cfc3f17 100644 --- a/vendor/github.com/containerd/containerd/oci/spec_opts.go +++ b/vendor/github.com/containerd/containerd/oci/spec_opts.go @@ -20,10 +20,11 @@ import ( "bufio" "context" "encoding/json" + "errors" "fmt" - "io/ioutil" "os" "path/filepath" + "runtime" "strconv" "strings" @@ -36,8 +37,7 @@ import ( "github.com/containerd/continuity/fs" v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/runc/libcontainer/user" - specs "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" + "github.com/opencontainers/runtime-spec/specs-go" ) // SpecOpts sets spec specific information to a newly generated OCI spec @@ -138,7 +138,7 @@ func WithSpecFromBytes(p []byte) SpecOpts { return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error { *s = Spec{} // make sure spec is cleared. if err := json.Unmarshal(p, s); err != nil { - return errors.Wrapf(err, "decoding spec config file failed, current supported OCI runtime-spec : v%s", specs.Version) + return fmt.Errorf("decoding spec config file failed, current supported OCI runtime-spec : v%s: %w", specs.Version, err) } return nil } @@ -147,9 +147,9 @@ func WithSpecFromBytes(p []byte) SpecOpts { // WithSpecFromFile loads the specification from the provided filename. func WithSpecFromFile(filename string) SpecOpts { return func(ctx context.Context, c Client, container *containers.Container, s *Spec) error { - p, err := ioutil.ReadFile(filename) + p, err := os.ReadFile(filename) if err != nil { - return errors.Wrap(err, "cannot load spec config file") + return fmt.Errorf("cannot load spec config file: %w", err) } return WithSpecFromBytes(p)(ctx, c, container, s) } @@ -522,6 +522,18 @@ func WithNamespacedCgroup() SpecOpts { func WithUser(userstr string) SpecOpts { return func(ctx context.Context, client Client, c *containers.Container, s *Spec) error { setProcess(s) + + // For LCOW it's a bit harder to confirm that the user actually exists on the host as a rootfs isn't + // mounted on the host and shared into the guest, but rather the rootfs is constructed entirely in the + // guest itself. To accommodate this, a spot to place the user string provided by a client as-is is needed. + // The `Username` field on the runtime spec is marked by Platform as only for Windows, and in this case it + // *is* being set on a Windows host at least, but will be used as a temporary holding spot until the guest + // can use the string to perform these same operations to grab the uid:gid inside. + if s.Windows != nil && s.Linux != nil { + s.Process.User.Username = userstr + return nil + } + parts := strings.Split(userstr, ":") switch len(parts) { case 1: @@ -618,7 +630,7 @@ func WithUserID(uid uint32) SpecOpts { setProcess(s) if c.Snapshotter == "" && c.SnapshotKey == "" { if !isRootfsAbs(s.Root.Path) { - return errors.Errorf("rootfs absolute path is required") + return errors.New("rootfs absolute path is required") } user, err := UserFromPath(s.Root.Path, func(u user.User) bool { return u.Uid == int(uid) @@ -635,10 +647,10 @@ func WithUserID(uid uint32) SpecOpts { } if c.Snapshotter == "" { - return errors.Errorf("no snapshotter set for container") + return errors.New("no snapshotter set for container") } if c.SnapshotKey == "" { - return errors.Errorf("rootfs snapshot not created for container") + return errors.New("rootfs snapshot not created for container") } snapshotter := client.SnapshotService(c.Snapshotter) mounts, err := snapshotter.Mounts(ctx, c.SnapshotKey) @@ -667,14 +679,16 @@ func WithUserID(uid uint32) SpecOpts { // WithUsername sets the correct UID and GID for the container // based on the image's /etc/passwd contents. If /etc/passwd // does not exist, or the username is not found in /etc/passwd, -// it returns error. +// it returns error. On Windows this sets the username as provided, +// the operating system will validate the user when going to run +// the container. func WithUsername(username string) SpecOpts { return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) { setProcess(s) if s.Linux != nil { if c.Snapshotter == "" && c.SnapshotKey == "" { if !isRootfsAbs(s.Root.Path) { - return errors.Errorf("rootfs absolute path is required") + return errors.New("rootfs absolute path is required") } user, err := UserFromPath(s.Root.Path, func(u user.User) bool { return u.Name == username @@ -686,10 +700,10 @@ func WithUsername(username string) SpecOpts { return nil } if c.Snapshotter == "" { - return errors.Errorf("no snapshotter set for container") + return errors.New("no snapshotter set for container") } if c.SnapshotKey == "" { - return errors.Errorf("rootfs snapshot not created for container") + return errors.New("rootfs snapshot not created for container") } snapshotter := client.SnapshotService(c.Snapshotter) mounts, err := snapshotter.Mounts(ctx, c.SnapshotKey) @@ -722,8 +736,8 @@ func WithUsername(username string) SpecOpts { // The passed in user can be either a uid or a username. func WithAdditionalGIDs(userstr string) SpecOpts { return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) { - // For LCOW additional GID's not supported - if s.Windows != nil { + // For LCOW or on Darwin additional GID's not supported + if s.Windows != nil || runtime.GOOS == "darwin" { return nil } setProcess(s) @@ -767,15 +781,15 @@ func WithAdditionalGIDs(userstr string) SpecOpts { } if c.Snapshotter == "" && c.SnapshotKey == "" { if !isRootfsAbs(s.Root.Path) { - return errors.Errorf("rootfs absolute path is required") + return errors.New("rootfs absolute path is required") } return setAdditionalGids(s.Root.Path) } if c.Snapshotter == "" { - return errors.Errorf("no snapshotter set for container") + return errors.New("no snapshotter set for container") } if c.SnapshotKey == "" { - return errors.Errorf("rootfs snapshot not created for container") + return errors.New("rootfs snapshot not created for container") } snapshotter := client.SnapshotService(c.Snapshotter) mounts, err := snapshotter.Mounts(ctx, c.SnapshotKey) @@ -1208,7 +1222,7 @@ func WithLinuxDevice(path, permissions string) SpecOpts { setLinux(s) setResources(s) - dev, err := deviceFromPath(path) + dev, err := DeviceFromPath(path) if err != nil { return err } @@ -1256,16 +1270,16 @@ var ErrNoShmMount = errors.New("no /dev/shm mount specified") // // The size value is specified in kb, kilobytes. func WithDevShmSize(kb int64) SpecOpts { - return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error { - for _, m := range s.Mounts { - if m.Source == "shm" && m.Type == "tmpfs" { - for i, o := range m.Options { - if strings.HasPrefix(o, "size=") { - m.Options[i] = fmt.Sprintf("size=%dk", kb) - return nil + return func(ctx context.Context, _ Client, _ *containers.Container, s *Spec) error { + for i, m := range s.Mounts { + if filepath.Clean(m.Destination) == "/dev/shm" && m.Source == "shm" && m.Type == "tmpfs" { + for i := 0; i < len(m.Options); i++ { + if strings.HasPrefix(m.Options[i], "size=") { + m.Options = append(m.Options[:i], m.Options[i+1:]...) + i-- } } - m.Options = append(m.Options, fmt.Sprintf("size=%dk", kb)) + s.Mounts[i].Options = append(m.Options, fmt.Sprintf("size=%dk", kb)) return nil } } diff --git a/vendor/github.com/containerd/containerd/oci/spec_opts_linux.go b/vendor/github.com/containerd/containerd/oci/spec_opts_linux.go index ae8c0a7d8f..4d8841ee11 100644 --- a/vendor/github.com/containerd/containerd/oci/spec_opts_linux.go +++ b/vendor/github.com/containerd/containerd/oci/spec_opts_linux.go @@ -1,5 +1,3 @@ -// +build linux - /* Copyright The containerd Authors. @@ -143,3 +141,15 @@ var WithAllKnownCapabilities = func(ctx context.Context, client Client, c *conta func WithoutRunMount(ctx context.Context, client Client, c *containers.Container, s *Spec) error { return WithoutMounts("/run")(ctx, client, c, s) } + +// WithRdt sets the container's RDT parameters +func WithRdt(closID, l3CacheSchema, memBwSchema string) SpecOpts { + return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error { + s.Linux.IntelRdt = &specs.LinuxIntelRdt{ + ClosID: closID, + L3CacheSchema: l3CacheSchema, + MemBwSchema: memBwSchema, + } + return nil + } +} diff --git a/vendor/github.com/containerd/containerd/oci/spec_opts_nonlinux.go b/vendor/github.com/containerd/containerd/oci/spec_opts_nonlinux.go index 77a1636387..c990fc6349 100644 --- a/vendor/github.com/containerd/containerd/oci/spec_opts_nonlinux.go +++ b/vendor/github.com/containerd/containerd/oci/spec_opts_nonlinux.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux /* @@ -20,6 +21,7 @@ package oci import ( "context" + "errors" "github.com/containerd/containerd/containers" ) @@ -36,3 +38,18 @@ var WithAllCurrentCapabilities = func(ctx context.Context, client Client, c *con var WithAllKnownCapabilities = func(ctx context.Context, client Client, c *containers.Container, s *Spec) error { return WithCapabilities(nil)(ctx, client, c, s) } + +// WithCPUShares sets the container's cpu shares +//nolint: deadcode, unused +func WithCPUShares(shares uint64) SpecOpts { + return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error { + return nil + } +} + +// WithRdt sets the container's RDT parameters +func WithRdt(closID, l3CacheSchema, memBwSchema string) SpecOpts { + return func(_ context.Context, _ Client, _ *containers.Container, _ *Spec) error { + return errors.New("RDT not supported") + } +} diff --git a/vendor/github.com/containerd/containerd/oci/spec_opts_unix.go b/vendor/github.com/containerd/containerd/oci/spec_opts_unix.go index 80a5223567..9d03091aa8 100644 --- a/vendor/github.com/containerd/containerd/oci/spec_opts_unix.go +++ b/vendor/github.com/containerd/containerd/oci/spec_opts_unix.go @@ -1,3 +1,4 @@ +//go:build !linux && !windows // +build !linux,!windows /* @@ -36,7 +37,7 @@ func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Sp return nil } -// WithDevices recursively adds devices from the passed in path and associated cgroup rules for that device. +// WithDevices recursively adds devices from the passed in path. // If devicePath is a dir it traverses the dir to add all devices in that dir. // If devicePath is not a dir, it attempts to add the single device. func WithDevices(devicePath, containerPath, permissions string) SpecOpts { diff --git a/vendor/github.com/containerd/containerd/oci/spec_opts_windows.go b/vendor/github.com/containerd/containerd/oci/spec_opts_windows.go index 126a89ec83..5502257a48 100644 --- a/vendor/github.com/containerd/containerd/oci/spec_opts_windows.go +++ b/vendor/github.com/containerd/containerd/oci/spec_opts_windows.go @@ -1,5 +1,3 @@ -// +build windows - /* Copyright The containerd Authors. @@ -20,10 +18,10 @@ package oci import ( "context" + "errors" "github.com/containerd/containerd/containers" specs "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" ) // WithWindowsCPUCount sets the `Windows.Resources.CPU.Count` section to the @@ -74,6 +72,20 @@ func WithHostDevices(_ context.Context, _ Client, _ *containers.Container, s *Sp return nil } -func deviceFromPath(path string) (*specs.LinuxDevice, error) { +func DeviceFromPath(path string) (*specs.LinuxDevice, error) { return nil, errors.New("device from path not supported on Windows") } + +// WithWindowsNetworkNamespace sets the network namespace for a Windows container. +func WithWindowsNetworkNamespace(ns string) SpecOpts { + return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error { + if s.Windows == nil { + s.Windows = &specs.Windows{} + } + if s.Windows.Network == nil { + s.Windows.Network = &specs.WindowsNetwork{} + } + s.Windows.Network.NetworkNamespace = ns + return nil + } +} diff --git a/vendor/github.com/containerd/containerd/oci/utils_unix.go b/vendor/github.com/containerd/containerd/oci/utils_unix.go index 108cacf5b8..db75b0bade 100644 --- a/vendor/github.com/containerd/containerd/oci/utils_unix.go +++ b/vendor/github.com/containerd/containerd/oci/utils_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows /* @@ -19,16 +20,25 @@ package oci import ( - "io/ioutil" + "errors" + "fmt" "os" "path/filepath" + "github.com/containerd/containerd/pkg/userns" specs "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" "golang.org/x/sys/unix" ) -var errNotADevice = errors.New("not a device node") +// ErrNotADevice denotes that a file is not a valid linux device. +var ErrNotADevice = errors.New("not a device node") + +// Testing dependencies +var ( + osReadDir = os.ReadDir + usernsRunningInUserNS = userns.RunningInUserNS + overrideDeviceFromPath func(path string) error +) // HostDevices returns all devices that can be found under /dev directory. func HostDevices() ([]specs.LinuxDevice, error) { @@ -38,11 +48,11 @@ func HostDevices() ([]specs.LinuxDevice, error) { func getDevices(path, containerPath string) ([]specs.LinuxDevice, error) { stat, err := os.Stat(path) if err != nil { - return nil, errors.Wrap(err, "error stating device path") + return nil, fmt.Errorf("error stating device path: %w", err) } if !stat.IsDir() { - dev, err := deviceFromPath(path) + dev, err := DeviceFromPath(path) if err != nil { return nil, err } @@ -52,7 +62,7 @@ func getDevices(path, containerPath string) ([]specs.LinuxDevice, error) { return []specs.LinuxDevice{*dev}, nil } - files, err := ioutil.ReadDir(path) + files, err := osReadDir(path) if err != nil { return nil, err } @@ -72,6 +82,12 @@ func getDevices(path, containerPath string) ([]specs.LinuxDevice, error) { } sub, err := getDevices(filepath.Join(path, f.Name()), cp) if err != nil { + if errors.Is(err, os.ErrPermission) && usernsRunningInUserNS() { + // ignore the "permission denied" error if running in userns. + // This allows rootless containers to use devices that are + // accessible, ignoring devices / subdirectories that are not. + continue + } return nil, err } @@ -80,26 +96,52 @@ func getDevices(path, containerPath string) ([]specs.LinuxDevice, error) { } case f.Name() == "console": continue - } - device, err := deviceFromPath(filepath.Join(path, f.Name())) - if err != nil { - if err == errNotADevice { + default: + device, err := DeviceFromPath(filepath.Join(path, f.Name())) + if err != nil { + if err == ErrNotADevice { + continue + } + if os.IsNotExist(err) { + continue + } + if errors.Is(err, os.ErrPermission) && usernsRunningInUserNS() { + // ignore the "permission denied" error if running in userns. + // This allows rootless containers to use devices that are + // accessible, ignoring devices that are not. + continue + } + return nil, err + } + if device.Type == fifoDevice { continue } - if os.IsNotExist(err) { - continue + if containerPath != "" { + device.Path = filepath.Join(containerPath, filepath.Base(f.Name())) } - return nil, err + out = append(out, *device) } - if containerPath != "" { - device.Path = filepath.Join(containerPath, filepath.Base(f.Name())) - } - out = append(out, *device) } return out, nil } -func deviceFromPath(path string) (*specs.LinuxDevice, error) { +// TODO consider adding these consts to the OCI runtime-spec. +const ( + wildcardDevice = "a" //nolint // currently unused, but should be included when upstreaming to OCI runtime-spec. + blockDevice = "b" + charDevice = "c" // or "u" + fifoDevice = "p" +) + +// DeviceFromPath takes the path to a device to look up the information about a +// linux device and returns that information as a LinuxDevice struct. +func DeviceFromPath(path string) (*specs.LinuxDevice, error) { + if overrideDeviceFromPath != nil { + if err := overrideDeviceFromPath(path); err != nil { + return nil, err + } + } + var stat unix.Stat_t if err := unix.Lstat(path, &stat); err != nil { return nil, err @@ -110,19 +152,21 @@ func deviceFromPath(path string) (*specs.LinuxDevice, error) { major = unix.Major(devNumber) minor = unix.Minor(devNumber) ) - if major == 0 { - return nil, errNotADevice - } var ( devType string mode = stat.Mode ) - switch { - case mode&unix.S_IFBLK == unix.S_IFBLK: - devType = "b" - case mode&unix.S_IFCHR == unix.S_IFCHR: - devType = "c" + + 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 } fm := os.FileMode(mode &^ unix.S_IFMT) return &specs.LinuxDevice{ diff --git a/vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_linux.go b/vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_linux.go index ee3858583e..ab54df8eab 100644 --- a/vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_linux.go +++ b/vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_linux.go @@ -1,5 +1,3 @@ -// +build linux - /* Copyright The containerd Authors. @@ -19,7 +17,6 @@ package apparmor import ( - "io/ioutil" "os" "sync" ) @@ -36,12 +33,10 @@ var ( // check for apparmor_parser to be present, or if we're running docker-in-docker. func hostSupports() bool { checkAppArmor.Do(func() { - // see https://github.com/docker/docker/commit/de191e86321f7d3136ff42ff75826b8107399497 + // see https://github.com/opencontainers/runc/blob/0d49470392206f40eaab3b2190a57fe7bb3df458/libcontainer/apparmor/apparmor_linux.go 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") - appArmorSupported = err == nil && len(buf) > 1 && buf[0] == 'Y' - } + buf, err := os.ReadFile("/sys/module/apparmor/parameters/enabled") + appArmorSupported = err == nil && len(buf) > 1 && buf[0] == 'Y' } }) return appArmorSupported diff --git a/vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_unsupported.go b/vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_unsupported.go index 428d36424d..833170338e 100644 --- a/vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_unsupported.go +++ b/vendor/github.com/containerd/containerd/pkg/apparmor/apparmor_unsupported.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux /* diff --git a/vendor/github.com/containerd/containerd/pkg/cap/cap_linux.go b/vendor/github.com/containerd/containerd/pkg/cap/cap_linux.go index 35772a4d85..26212573dc 100644 --- a/vendor/github.com/containerd/containerd/pkg/cap/cap_linux.go +++ b/vendor/github.com/containerd/containerd/pkg/cap/cap_linux.go @@ -19,12 +19,11 @@ package cap import ( "bufio" + "fmt" "io" "os" "strconv" "strings" - - "github.com/pkg/errors" ) // FromNumber returns a cap string like "CAP_SYS_ADMIN" @@ -91,7 +90,7 @@ func ParseProcPIDStatus(r io.Reader) (map[Type]uint64, error) { case "CapInh", "CapPrm", "CapEff", "CapBnd", "CapAmb": ui64, err := strconv.ParseUint(v, 16, 64) if err != nil { - return nil, errors.Errorf("failed to parse line %q", line) + return nil, fmt.Errorf("failed to parse line %q", line) } switch k { case "CapInh": @@ -117,9 +116,6 @@ func ParseProcPIDStatus(r io.Reader) (map[Type]uint64, error) { // the current process. // // The result is like []string{"CAP_SYS_ADMIN", ...}. -// -// The result does not contain caps that are not recognized by -// the "github.com/syndtr/gocapability" library. func Current() ([]string, error) { f, err := os.Open("/proc/self/status") if err != nil { diff --git a/vendor/github.com/containerd/containerd/pkg/dialer/dialer.go b/vendor/github.com/containerd/containerd/pkg/dialer/dialer.go index aa604baab9..74c303b944 100644 --- a/vendor/github.com/containerd/containerd/pkg/dialer/dialer.go +++ b/vendor/github.com/containerd/containerd/pkg/dialer/dialer.go @@ -18,10 +18,9 @@ package dialer import ( "context" + "fmt" "net" "time" - - "github.com/pkg/errors" ) type dialResult struct { @@ -74,6 +73,6 @@ func timeoutDialer(address string, timeout time.Duration) (net.Conn, error) { dr.c.Close() } }() - return nil, errors.Errorf("dial %s: timeout", address) + return nil, fmt.Errorf("dial %s: timeout", address) } } diff --git a/vendor/github.com/containerd/containerd/pkg/dialer/dialer_unix.go b/vendor/github.com/containerd/containerd/pkg/dialer/dialer_unix.go index e7d1958339..b4304ffbf1 100644 --- a/vendor/github.com/containerd/containerd/pkg/dialer/dialer_unix.go +++ b/vendor/github.com/containerd/containerd/pkg/dialer/dialer_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows /* diff --git a/vendor/github.com/containerd/containerd/pkg/seccomp/seccomp_unsupported.go b/vendor/github.com/containerd/containerd/pkg/seccomp/seccomp_unsupported.go index 87b133426c..4458c1c702 100644 --- a/vendor/github.com/containerd/containerd/pkg/seccomp/seccomp_unsupported.go +++ b/vendor/github.com/containerd/containerd/pkg/seccomp/seccomp_unsupported.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux /* diff --git a/vendor/github.com/containerd/containerd/pkg/userns/userns_unsupported.go b/vendor/github.com/containerd/containerd/pkg/userns/userns_unsupported.go index aab756fd2a..4f8d7dd2d5 100644 --- a/vendor/github.com/containerd/containerd/pkg/userns/userns_unsupported.go +++ b/vendor/github.com/containerd/containerd/pkg/userns/userns_unsupported.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux /* diff --git a/vendor/github.com/containerd/containerd/platforms/compare.go b/vendor/github.com/containerd/containerd/platforms/compare.go index c7657e1869..3913ef6637 100644 --- a/vendor/github.com/containerd/containerd/platforms/compare.go +++ b/vendor/github.com/containerd/containerd/platforms/compare.go @@ -38,12 +38,22 @@ func platformVector(platform specs.Platform) []specs.Platform { switch platform.Architecture { case "amd64": + if amd64Version, err := strconv.Atoi(strings.TrimPrefix(platform.Variant, "v")); err == nil && amd64Version > 1 { + for amd64Version--; amd64Version >= 1; amd64Version-- { + vector = append(vector, specs.Platform{ + Architecture: platform.Architecture, + OS: platform.OS, + OSVersion: platform.OSVersion, + OSFeatures: platform.OSFeatures, + Variant: "v" + strconv.Itoa(amd64Version), + }) + } + } vector = append(vector, specs.Platform{ Architecture: "386", OS: platform.OS, OSVersion: platform.OSVersion, OSFeatures: platform.OSFeatures, - Variant: platform.Variant, }) case "arm": if armVersion, err := strconv.Atoi(strings.TrimPrefix(platform.Variant, "v")); err == nil && armVersion > 5 { diff --git a/vendor/github.com/containerd/containerd/platforms/cpuinfo.go b/vendor/github.com/containerd/containerd/platforms/cpuinfo.go index 4a7177e313..046e0356d1 100644 --- a/vendor/github.com/containerd/containerd/platforms/cpuinfo.go +++ b/vendor/github.com/containerd/containerd/platforms/cpuinfo.go @@ -18,6 +18,7 @@ package platforms import ( "bufio" + "fmt" "os" "runtime" "strings" @@ -25,7 +26,6 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" - "github.com/pkg/errors" ) // Present the ARM instruction set architecture, eg: v7, v8 @@ -48,7 +48,7 @@ func cpuVariant() string { // 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) + return "", fmt.Errorf("getCPUInfo for OS %s: %w", runtime.GOOS, errdefs.ErrNotImplemented) } cpuinfo, err := os.Open("/proc/cpuinfo") @@ -75,7 +75,7 @@ func getCPUInfo(pattern string) (info string, err error) { return "", err } - return "", errors.Wrapf(errdefs.ErrNotFound, "getCPUInfo for pattern: %s", pattern) + return "", fmt.Errorf("getCPUInfo for pattern: %s: %w", pattern, errdefs.ErrNotFound) } func getCPUVariant() string { diff --git a/vendor/github.com/containerd/containerd/platforms/database.go b/vendor/github.com/containerd/containerd/platforms/database.go index 6ede94061e..dbe9957ca9 100644 --- a/vendor/github.com/containerd/containerd/platforms/database.go +++ b/vendor/github.com/containerd/containerd/platforms/database.go @@ -38,7 +38,7 @@ func isLinuxOS(os string) bool { // 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": + case "aix", "android", "darwin", "dragonfly", "freebsd", "hurd", "illumos", "ios", "js", "linux", "nacl", "netbsd", "openbsd", "plan9", "solaris", "windows", "zos": return true } return false @@ -60,7 +60,7 @@ func isArmArch(arch string) bool { // 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": + case "386", "amd64", "amd64p32", "arm", "armbe", "arm64", "arm64be", "ppc64", "ppc64le", "loong64", "mips", "mipsle", "mips64", "mips64le", "mips64p32", "mips64p32le", "ppc", "riscv", "riscv64", "s390", "s390x", "sparc", "sparc64", "wasm": return true } return false @@ -86,9 +86,11 @@ func normalizeArch(arch, variant string) (string, string) { case "i386": arch = "386" variant = "" - case "x86_64", "x86-64": + case "x86_64", "x86-64", "amd64": arch = "amd64" - variant = "" + if variant == "v1" { + variant = "" + } case "aarch64", "arm64": arch = "arm64" switch variant { diff --git a/vendor/github.com/containerd/containerd/platforms/defaults.go b/vendor/github.com/containerd/containerd/platforms/defaults.go index cb77fbc9f7..cfa3ff34a1 100644 --- a/vendor/github.com/containerd/containerd/platforms/defaults.go +++ b/vendor/github.com/containerd/containerd/platforms/defaults.go @@ -16,27 +16,11 @@ 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(), - } -} - // DefaultStrict returns strict form of Default. func DefaultStrict() MatchComparer { return OnlyStrict(DefaultSpec()) diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_darwin.go b/vendor/github.com/containerd/containerd/platforms/defaults_darwin.go new file mode 100644 index 0000000000..e249fe48d3 --- /dev/null +++ b/vendor/github.com/containerd/containerd/platforms/defaults_darwin.go @@ -0,0 +1,45 @@ +//go:build darwin +// +build darwin + +/* + 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" +) + +// 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(), + } +} + +// Default returns the default matcher for the platform. +func Default() MatchComparer { + return Ordered(DefaultSpec(), specs.Platform{ + // darwin runtime also supports Linux binary via runu/LKL + OS: "linux", + Architecture: runtime.GOARCH, + }) +} diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_unix.go b/vendor/github.com/containerd/containerd/platforms/defaults_unix.go index e8a7d5ffa0..49690f1b3e 100644 --- a/vendor/github.com/containerd/containerd/platforms/defaults_unix.go +++ b/vendor/github.com/containerd/containerd/platforms/defaults_unix.go @@ -1,4 +1,5 @@ -// +build !windows +//go:build !windows && !darwin +// +build !windows,!darwin /* Copyright The containerd Authors. @@ -18,6 +19,22 @@ package platforms +import ( + "runtime" + + specs "github.com/opencontainers/image-spec/specs-go/v1" +) + +// 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(), + } +} + // 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 index 0c380e3b7c..c1aaf72ca8 100644 --- a/vendor/github.com/containerd/containerd/platforms/defaults_windows.go +++ b/vendor/github.com/containerd/containerd/platforms/defaults_windows.go @@ -1,5 +1,3 @@ -// +build windows - /* Copyright The containerd Authors. @@ -29,6 +27,18 @@ import ( "golang.org/x/sys/windows" ) +// DefaultSpec returns the current platform's default platform specification. +func DefaultSpec() specs.Platform { + major, minor, build := windows.RtlGetNtVersionNumbers() + return specs.Platform{ + OS: runtime.GOOS, + Architecture: runtime.GOARCH, + OSVersion: fmt.Sprintf("%d.%d.%d", major, minor, build), + // The Variant field will be empty if arch != ARM. + Variant: cpuVariant(), + } +} + type matchComparer struct { defaults Matcher osVersionPrefix string diff --git a/vendor/github.com/containerd/containerd/platforms/platforms.go b/vendor/github.com/containerd/containerd/platforms/platforms.go index 088bdea050..8f955d036d 100644 --- a/vendor/github.com/containerd/containerd/platforms/platforms.go +++ b/vendor/github.com/containerd/containerd/platforms/platforms.go @@ -107,6 +107,8 @@ package platforms import ( + "fmt" + "path" "regexp" "runtime" "strconv" @@ -114,7 +116,6 @@ import ( "github.com/containerd/containerd/errdefs" specs "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) var ( @@ -166,14 +167,14 @@ func (m *matcher) String() string { 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) + return specs.Platform{}, fmt.Errorf("%q: wildcards not yet supported: %w", specifier, errdefs.ErrInvalidArgument) } 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()) + return specs.Platform{}, fmt.Errorf("%q is an invalid component of %q: platform specifier component must match %q: %w", part, specifier, specifierRe.String(), errdefs.ErrInvalidArgument) } } @@ -205,7 +206,7 @@ func Parse(specifier string) (specs.Platform, error) { return p, nil } - return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q: unknown operating system or architecture", specifier) + return specs.Platform{}, fmt.Errorf("%q: unknown operating system or architecture: %w", specifier, errdefs.ErrInvalidArgument) 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. @@ -227,7 +228,7 @@ func Parse(specifier string) (specs.Platform, error) { return p, nil } - return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q: cannot parse platform specifier", specifier) + return specs.Platform{}, fmt.Errorf("%q: cannot parse platform specifier: %w", specifier, errdefs.ErrInvalidArgument) } // MustParse is like Parses but panics if the specifier cannot be parsed. @@ -246,20 +247,7 @@ func Format(platform specs.Platform) string { 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, "/") + return path.Join(platform.OS, platform.Architecture, platform.Variant) } // Normalize validates and translate the platform to the canonical value. @@ -269,10 +257,5 @@ func joinNotEmpty(s ...string) string { 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/containerd/containerd/plugin/context.go b/vendor/github.com/containerd/containerd/plugin/context.go index 75b7366fca..dcb533c8a7 100644 --- a/vendor/github.com/containerd/containerd/plugin/context.go +++ b/vendor/github.com/containerd/containerd/plugin/context.go @@ -18,15 +18,15 @@ package plugin import ( "context" + "fmt" "path/filepath" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/events/exchange" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) -// InitContext is used for plugin inititalization +// InitContext is used for plugin initialization type InitContext struct { Context context.Context Root string @@ -34,7 +34,9 @@ type InitContext struct { Config interface{} Address string TTRPCAddress string - Events *exchange.Exchange + + // deprecated: will be removed in 2.0, use plugin.EventType + Events *exchange.Exchange Meta *Meta // plugins can fill in metadata at init. @@ -115,7 +117,7 @@ func (ps *Set) Add(p *Plugin) error { } else if _, idok := byID[p.Registration.ID]; !idok { byID[p.Registration.ID] = p } else { - return errors.Wrapf(errdefs.ErrAlreadyExists, "plugin %v already initialized", p.Registration.URI()) + return fmt.Errorf("plugin %v already initialized: %w", p.Registration.URI(), errdefs.ErrAlreadyExists) } ps.ordered = append(ps.ordered, p) @@ -127,19 +129,42 @@ func (ps *Set) Get(t Type) (interface{}, error) { for _, v := range ps.byTypeAndID[t] { return v.Instance() } - return nil, errors.Wrapf(errdefs.ErrNotFound, "no plugins registered for %s", t) + return nil, fmt.Errorf("no plugins registered for %s: %w", t, errdefs.ErrNotFound) +} + +// GetAll returns all initialized plugins +func (ps *Set) GetAll() []*Plugin { + return ps.ordered +} + +// Plugins returns plugin set +func (i *InitContext) Plugins() *Set { + return i.plugins } // GetAll plugins in the set func (i *InitContext) GetAll() []*Plugin { - return i.plugins.ordered + return i.plugins.GetAll() +} + +// GetByID returns the plugin of the given type and ID +func (i *InitContext) GetByID(t Type, id string) (interface{}, error) { + ps, err := i.GetByType(t) + if err != nil { + return nil, err + } + p, ok := ps[id] + if !ok { + return nil, fmt.Errorf("no %s plugins with id %s: %w", t, id, errdefs.ErrNotFound) + } + return p.Instance() } // GetByType returns all plugins with the specific type. func (i *InitContext) GetByType(t Type) (map[string]*Plugin, error) { p, ok := i.plugins.byTypeAndID[t] if !ok { - return nil, errors.Wrapf(errdefs.ErrNotFound, "no plugins registered for %s", t) + return nil, fmt.Errorf("no plugins registered for %s: %w", t, errdefs.ErrNotFound) } return p, nil diff --git a/vendor/github.com/containerd/containerd/plugin/plugin.go b/vendor/github.com/containerd/containerd/plugin/plugin.go index 2674edeb1b..eb38c12715 100644 --- a/vendor/github.com/containerd/containerd/plugin/plugin.go +++ b/vendor/github.com/containerd/containerd/plugin/plugin.go @@ -17,12 +17,9 @@ package plugin import ( + "errors" "fmt" "sync" - - "github.com/containerd/ttrpc" - "github.com/pkg/errors" - "google.golang.org/grpc" ) var ( @@ -63,6 +60,8 @@ const ( ServicePlugin Type = "io.containerd.service.v1" // GRPCPlugin implements a grpc service GRPCPlugin Type = "io.containerd.grpc.v1" + // TTRPCPlugin implements a ttrpc shim service + TTRPCPlugin Type = "io.containerd.ttrpc.v1" // SnapshotPlugin implements a snapshotter SnapshotPlugin Type = "io.containerd.snapshotter.v1" // TaskMonitorPlugin implements a task monitor @@ -75,6 +74,10 @@ const ( ContentPlugin Type = "io.containerd.content.v1" // GCPlugin implements garbage collection policy GCPlugin Type = "io.containerd.gc.v1" + // EventPlugin implements event handling + EventPlugin Type = "io.containerd.event.v1" + // TracingProcessorPlugin implements a open telemetry span processor + TracingProcessorPlugin Type = "io.containerd.tracing.processor.v1" ) const ( @@ -122,21 +125,6 @@ func (r *Registration) URI() string { return fmt.Sprintf("%s.%s", r.Type, r.ID) } -// Service allows GRPC services to be registered with the underlying server -type Service interface { - Register(*grpc.Server) error -} - -// TTRPCService allows TTRPC services to be registered with the underlying server -type TTRPCService interface { - RegisterTTRPC(*ttrpc.Server) error -} - -// TCPService allows GRPC services to be registered with the underlying tcp server -type TCPService interface { - RegisterTCP(*grpc.Server) error -} - var register = struct { sync.RWMutex r []*Registration @@ -171,15 +159,11 @@ func Register(r *Registration) { panic(err) } - var last bool for _, requires := range r.Requires { - if requires == "*" { - last = true + if requires == "*" && len(r.Requires) != 1 { + panic(ErrInvalidRequires) } } - if last && len(r.Requires) != 1 { - panic(ErrInvalidRequires) - } register.r = append(register.r, r) } @@ -187,7 +171,7 @@ func Register(r *Registration) { func checkUnique(r *Registration) error { for _, registered := range register.r { if r.URI() == registered.URI() { - return errors.Wrap(ErrIDRegistered, r.URI()) + return fmt.Errorf("%s: %w", r.URI(), ErrIDRegistered) } } return nil diff --git a/vendor/github.com/containerd/containerd/plugin/plugin_go18.go b/vendor/github.com/containerd/containerd/plugin/plugin_go18.go index 927fe61965..0df0669d29 100644 --- a/vendor/github.com/containerd/containerd/plugin/plugin_go18.go +++ b/vendor/github.com/containerd/containerd/plugin/plugin_go18.go @@ -1,3 +1,4 @@ +//go:build go1.8 && !windows && amd64 && !static_build && !gccgo // +build go1.8,!windows,amd64,!static_build,!gccgo /* diff --git a/vendor/github.com/containerd/containerd/plugin/plugin_other.go b/vendor/github.com/containerd/containerd/plugin/plugin_other.go index 0c5e14165c..a2883bbbad 100644 --- a/vendor/github.com/containerd/containerd/plugin/plugin_other.go +++ b/vendor/github.com/containerd/containerd/plugin/plugin_other.go @@ -1,3 +1,4 @@ +//go:build !go1.8 || windows || !amd64 || static_build || gccgo // +build !go1.8 windows !amd64 static_build gccgo /* diff --git a/vendor/github.com/containerd/containerd/process.go b/vendor/github.com/containerd/containerd/process.go index 5b302569ba..42d0da60e1 100644 --- a/vendor/github.com/containerd/containerd/process.go +++ b/vendor/github.com/containerd/containerd/process.go @@ -18,6 +18,7 @@ package containerd import ( "context" + "fmt" "strings" "syscall" "time" @@ -25,7 +26,6 @@ import ( "github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/cio" "github.com/containerd/containerd/errdefs" - "github.com/pkg/errors" ) // Process represents a system process @@ -210,7 +210,7 @@ func (p *process) Delete(ctx context.Context, opts ...ProcessDeleteOpts) (*ExitS } switch status.Status { case Running, Paused, Pausing: - return nil, errors.Wrapf(errdefs.ErrFailedPrecondition, "process must be stopped before deletion") + return nil, fmt.Errorf("current process state: %s, process must be stopped before deletion: %w", status.Status, errdefs.ErrFailedPrecondition) } r, err := p.task.client.TaskService().DeleteProcess(ctx, &tasks.DeleteProcessRequest{ ContainerID: p.task.id, diff --git a/vendor/github.com/containerd/containerd/pull.go b/vendor/github.com/containerd/containerd/pull.go index 36365513f6..92f7719b1f 100644 --- a/vendor/github.com/containerd/containerd/pull.go +++ b/vendor/github.com/containerd/containerd/pull.go @@ -18,6 +18,8 @@ package containerd import ( "context" + "errors" + "fmt" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" @@ -26,7 +28,6 @@ import ( "github.com/containerd/containerd/remotes/docker" "github.com/containerd/containerd/remotes/docker/schema1" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "golang.org/x/sync/errgroup" "golang.org/x/sync/semaphore" ) @@ -49,7 +50,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima } else { p, err := platforms.Parse(pullCtx.Platforms[0]) if err != nil { - return nil, errors.Wrapf(err, "invalid platform %s", pullCtx.Platforms[0]) + return nil, fmt.Errorf("invalid platform %s: %w", pullCtx.Platforms[0], err) } pullCtx.PlatformMatcher = platforms.Only(p) @@ -70,13 +71,13 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima // unpacker only supports schema 2 image, for schema 1 this is noop. u, err := c.newUnpacker(ctx, pullCtx) if err != nil { - return nil, errors.Wrap(err, "create unpacker") + return nil, fmt.Errorf("create unpacker: %w", err) } unpackWrapper, unpackEg = u.handlerWrapper(ctx, pullCtx, &unpacks) defer func() { if err := unpackEg.Wait(); err != nil { if retErr == nil { - retErr = errors.Wrap(err, "unpack") + retErr = fmt.Errorf("unpack: %w", err) } } }() @@ -117,7 +118,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima // Try to unpack is none is done previously. // This is at least required for schema 1 image. if err := i.Unpack(ctx, pullCtx.Snapshotter, pullCtx.UnpackOpts...); err != nil { - return nil, errors.Wrapf(err, "failed to unpack image on snapshotter %s", pullCtx.Snapshotter) + return nil, fmt.Errorf("failed to unpack image on snapshotter %s: %w", pullCtx.Snapshotter, err) } } } @@ -129,12 +130,12 @@ func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, lim store := c.ContentStore() name, desc, err := rCtx.Resolver.Resolve(ctx, ref) if err != nil { - return images.Image{}, errors.Wrapf(err, "failed to resolve reference %q", ref) + return images.Image{}, fmt.Errorf("failed to resolve reference %q: %w", ref, err) } fetcher, err := rCtx.Resolver.Fetcher(ctx, name) if err != nil { - return images.Image{}, errors.Wrapf(err, "failed to get fetcher for %q", name) + return images.Image{}, fmt.Errorf("failed to get fetcher for %q: %w", name, err) } var ( diff --git a/vendor/github.com/containerd/containerd/reference/docker/reference.go b/vendor/github.com/containerd/containerd/reference/docker/reference.go index 0998639b03..6fa97dfdca 100644 --- a/vendor/github.com/containerd/containerd/reference/docker/reference.go +++ b/vendor/github.com/containerd/containerd/reference/docker/reference.go @@ -338,11 +338,13 @@ func WithDigest(name Named, digest digest.Digest) (Canonical, error) { // TrimNamed removes any tag or digest from the named reference. func TrimNamed(ref Named) Named { - domain, path := SplitHostname(ref) - return repository{ - domain: domain, - path: path, + repo := repository{} + if r, ok := ref.(namedRepository); ok { + repo.domain, repo.path = r.Domain(), r.Path() + } else { + repo.domain, repo.path = splitDomain(ref.Name()) } + return repo } func getBestReferenceType(ref reference) Reference { diff --git a/vendor/github.com/containerd/containerd/remotes/docker/auth/fetch.go b/vendor/github.com/containerd/containerd/remotes/docker/auth/fetch.go index 8b0a87e755..c259873d2a 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/auth/fetch.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/auth/fetch.go @@ -19,6 +19,8 @@ package auth import ( "context" "encoding/json" + "errors" + "fmt" "net/http" "net/url" "strings" @@ -27,7 +29,6 @@ import ( "github.com/containerd/containerd/log" remoteserrors "github.com/containerd/containerd/remotes/errors" "github.com/containerd/containerd/version" - "github.com/pkg/errors" "golang.org/x/net/context/ctxhttp" ) @@ -46,7 +47,7 @@ func GenerateTokenOptions(ctx context.Context, host, username, secret string, c realmURL, err := url.Parse(realm) if err != nil { - return TokenOptions{}, errors.Wrap(err, "invalid token auth challenge realm") + return TokenOptions{}, fmt.Errorf("invalid token auth challenge realm: %w", err) } to := TokenOptions{ @@ -58,7 +59,7 @@ func GenerateTokenOptions(ctx context.Context, host, username, secret string, c scope, ok := c.Parameters["scope"] if ok { - to.Scopes = append(to.Scopes, scope) + to.Scopes = append(to.Scopes, strings.Split(scope, " ")...) } else { log.G(ctx).WithField("host", host).Debug("no scope specified for token auth challenge") } @@ -73,6 +74,15 @@ type TokenOptions struct { Scopes []string Username string Secret string + + // FetchRefreshToken enables fetching a refresh token (aka "identity token", "offline token") along with the bearer token. + // + // For HTTP GET mode (FetchToken), FetchRefreshToken sets `offline_token=true` in the request. + // https://docs.docker.com/registry/spec/auth/token/#requesting-a-token + // + // For HTTP POST mode (FetchTokenWithOAuth), FetchRefreshToken sets `access_type=offline` in the request. + // https://docs.docker.com/registry/spec/auth/oauth/#getting-a-token + FetchRefreshToken bool } // OAuthTokenResponse is response from fetching token with a OAuth POST request @@ -101,6 +111,9 @@ func FetchTokenWithOAuth(ctx context.Context, client *http.Client, headers http. form.Set("username", to.Username) form.Set("password", to.Secret) } + if to.FetchRefreshToken { + form.Set("access_type", "offline") + } req, err := http.NewRequest("POST", to.Realm, strings.NewReader(form.Encode())) if err != nil { @@ -121,18 +134,18 @@ func FetchTokenWithOAuth(ctx context.Context, client *http.Client, headers http. defer resp.Body.Close() if resp.StatusCode < 200 || resp.StatusCode >= 400 { - return nil, errors.WithStack(remoteserrors.NewUnexpectedStatusErr(resp)) + return nil, remoteserrors.NewUnexpectedStatusErr(resp) } decoder := json.NewDecoder(resp.Body) var tr OAuthTokenResponse if err = decoder.Decode(&tr); err != nil { - return nil, errors.Wrap(err, "unable to decode token response") + return nil, fmt.Errorf("unable to decode token response: %w", err) } if tr.AccessToken == "" { - return nil, errors.WithStack(ErrNoToken) + return nil, ErrNoToken } return &tr, nil @@ -175,6 +188,10 @@ func FetchToken(ctx context.Context, client *http.Client, headers http.Header, t req.SetBasicAuth(to.Username, to.Secret) } + if to.FetchRefreshToken { + reqParams.Add("offline_token", "true") + } + req.URL.RawQuery = reqParams.Encode() resp, err := ctxhttp.Do(ctx, client, req) @@ -184,14 +201,14 @@ func FetchToken(ctx context.Context, client *http.Client, headers http.Header, t defer resp.Body.Close() if resp.StatusCode < 200 || resp.StatusCode >= 400 { - return nil, errors.WithStack(remoteserrors.NewUnexpectedStatusErr(resp)) + return nil, remoteserrors.NewUnexpectedStatusErr(resp) } decoder := json.NewDecoder(resp.Body) var tr FetchTokenResponse if err = decoder.Decode(&tr); err != nil { - return nil, errors.Wrap(err, "unable to decode token response") + return nil, fmt.Errorf("unable to decode token response: %w", err) } // `access_token` is equivalent to `token` and if both are specified @@ -202,7 +219,7 @@ func FetchToken(ctx context.Context, client *http.Client, headers http.Header, t } if tr.Token == "" { - return nil, errors.WithStack(ErrNoToken) + return nil, ErrNoToken } return &tr, nil diff --git a/vendor/github.com/containerd/containerd/remotes/docker/authorizer.go b/vendor/github.com/containerd/containerd/remotes/docker/authorizer.go index 67e4aea8da..eaa0e5dbdb 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/authorizer.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/authorizer.go @@ -19,6 +19,7 @@ package docker import ( "context" "encoding/base64" + "errors" "fmt" "net/http" "strings" @@ -28,7 +29,6 @@ import ( "github.com/containerd/containerd/log" "github.com/containerd/containerd/remotes/docker/auth" remoteerrors "github.com/containerd/containerd/remotes/errors" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -37,10 +37,12 @@ type dockerAuthorizer struct { client *http.Client header http.Header - mu sync.Mutex + mu sync.RWMutex // indexed by host name handlers map[string]*authHandler + + onFetchRefreshToken OnFetchRefreshToken } // NewAuthorizer creates a Docker authorizer using the provided function to @@ -51,9 +53,10 @@ func NewAuthorizer(client *http.Client, f func(string) (string, string, error)) } type authorizerConfig struct { - credentials func(string) (string, string, error) - client *http.Client - header http.Header + credentials func(string) (string, string, error) + client *http.Client + header http.Header + onFetchRefreshToken OnFetchRefreshToken } // AuthorizerOpt configures an authorizer @@ -80,6 +83,16 @@ func WithAuthHeader(hdr http.Header) AuthorizerOpt { } } +// OnFetchRefreshToken is called on fetching request token. +type OnFetchRefreshToken func(ctx context.Context, refreshToken string, req *http.Request) + +// WithFetchRefreshToken enables fetching "refresh token" (aka "identity token", "offline token"). +func WithFetchRefreshToken(f OnFetchRefreshToken) AuthorizerOpt { + return func(opt *authorizerConfig) { + opt.onFetchRefreshToken = f + } +} + // NewDockerAuthorizer creates an authorizer using Docker's registry // authentication spec. // See https://docs.docker.com/registry/spec/auth/ @@ -94,10 +107,11 @@ func NewDockerAuthorizer(opts ...AuthorizerOpt) Authorizer { } return &dockerAuthorizer{ - credentials: ao.credentials, - client: ao.client, - header: ao.header, - handlers: make(map[string]*authHandler), + credentials: ao.credentials, + client: ao.client, + header: ao.header, + handlers: make(map[string]*authHandler), + onFetchRefreshToken: ao.onFetchRefreshToken, } } @@ -109,12 +123,21 @@ func (a *dockerAuthorizer) Authorize(ctx context.Context, req *http.Request) err return nil } - auth, err := ah.authorize(ctx) + auth, refreshToken, err := ah.authorize(ctx) if err != nil { return err } req.Header.Set("Authorization", auth) + + if refreshToken != "" { + a.mu.RLock() + onFetchRefreshToken := a.onFetchRefreshToken + a.mu.RUnlock() + if onFetchRefreshToken != nil { + onFetchRefreshToken(ctx, refreshToken, req) + } + } return nil } @@ -161,6 +184,7 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R if err != nil { return err } + common.FetchRefreshToken = a.onFetchRefreshToken != nil a.handlers[host] = newAuthHandler(a.client, a.header, c.Scheme, common) return nil @@ -181,14 +205,15 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R } } } - return errors.Wrap(errdefs.ErrNotImplemented, "failed to find supported auth scheme") + return fmt.Errorf("failed to find supported auth scheme: %w", errdefs.ErrNotImplemented) } // authResult is used to control limit rate. type authResult struct { sync.WaitGroup - token string - err error + token string + refreshToken string + err error } // authHandler is used to handle auth request per registry server. @@ -220,29 +245,29 @@ func newAuthHandler(client *http.Client, hdr http.Header, scheme auth.Authentica } } -func (ah *authHandler) authorize(ctx context.Context) (string, error) { +func (ah *authHandler) authorize(ctx context.Context) (string, string, error) { switch ah.scheme { case auth.BasicAuth: return ah.doBasicAuth(ctx) case auth.BearerAuth: return ah.doBearerAuth(ctx) default: - return "", errors.Wrapf(errdefs.ErrNotImplemented, "failed to find supported auth scheme: %s", string(ah.scheme)) + return "", "", fmt.Errorf("failed to find supported auth scheme: %s: %w", string(ah.scheme), errdefs.ErrNotImplemented) } } -func (ah *authHandler) doBasicAuth(ctx context.Context) (string, error) { +func (ah *authHandler) doBasicAuth(ctx context.Context) (string, string, error) { username, secret := ah.common.Username, ah.common.Secret if username == "" || secret == "" { - return "", fmt.Errorf("failed to handle basic auth because missing username or secret") + return "", "", fmt.Errorf("failed to handle basic auth because missing username or secret") } auth := base64.StdEncoding.EncodeToString([]byte(username + ":" + secret)) - return fmt.Sprintf("Basic %s", auth), nil + return fmt.Sprintf("Basic %s", auth), "", nil } -func (ah *authHandler) doBearerAuth(ctx context.Context) (token string, err error) { +func (ah *authHandler) doBearerAuth(ctx context.Context) (token, refreshToken string, err error) { // copy common tokenOptions to := ah.common @@ -255,7 +280,7 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (token string, err erro if r, exist := ah.scopedTokens[scoped]; exist { ah.Unlock() r.Wait() - return r.token, r.err + return r.token, r.refreshToken, r.err } // only one fetch token job @@ -266,14 +291,16 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (token string, err erro defer func() { token = fmt.Sprintf("Bearer %s", token) - r.token, r.err = token, err + r.token, r.refreshToken, r.err = token, refreshToken, err r.Done() }() // fetch token for the resource scope if to.Secret != "" { defer func() { - err = errors.Wrap(err, "failed to fetch oauth token") + if err != nil { + err = fmt.Errorf("failed to fetch oauth token: %w", err) + } }() // credential information is provided, use oauth POST endpoint // TODO: Allow setting client_id @@ -284,28 +311,29 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (token string, err erro // Registries without support for POST may return 404 for POST /v2/token. // As of September 2017, GCR is known to return 404. // As of February 2018, JFrog Artifactory is known to return 401. - if (errStatus.StatusCode == 405 && to.Username != "") || errStatus.StatusCode == 404 || errStatus.StatusCode == 401 { + // As of January 2022, ACR is known to return 400. + if (errStatus.StatusCode == 405 && to.Username != "") || errStatus.StatusCode == 404 || errStatus.StatusCode == 401 || errStatus.StatusCode == 400 { resp, err := auth.FetchToken(ctx, ah.client, ah.header, to) if err != nil { - return "", err + return "", "", err } - return resp.Token, nil + return resp.Token, resp.RefreshToken, nil } log.G(ctx).WithFields(logrus.Fields{ "status": errStatus.Status, "body": string(errStatus.Body), }).Debugf("token request failed") } - return "", err + return "", "", err } - return resp.AccessToken, nil + return resp.AccessToken, resp.RefreshToken, nil } // do request anonymously resp, err := auth.FetchToken(ctx, ah.client, ah.header, to) if err != nil { - return "", errors.Wrap(err, "failed to fetch anonymous token") + return "", "", fmt.Errorf("failed to fetch anonymous token: %w", err) } - return resp.Token, nil + return resp.Token, resp.RefreshToken, nil } func invalidAuthorization(c auth.Challenge, responses []*http.Response) error { @@ -319,7 +347,7 @@ func invalidAuthorization(c auth.Challenge, responses []*http.Response) error { return nil } - return errors.Wrapf(ErrInvalidAuthorization, "server message: %s", errStr) + return fmt.Errorf("server message: %s: %w", errStr, ErrInvalidAuthorization) } func sameRequest(r1, r2 *http.Request) bool { diff --git a/vendor/github.com/containerd/containerd/remotes/docker/converter.go b/vendor/github.com/containerd/containerd/remotes/docker/converter.go index 43e6b372c1..d7dca0d364 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/converter.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/converter.go @@ -28,7 +28,6 @@ import ( "github.com/containerd/containerd/remotes" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) // LegacyConfigMediaType should be replaced by OCI image spec. @@ -52,12 +51,12 @@ func ConvertManifest(ctx context.Context, store content.Store, desc ocispec.Desc // read manifest data mb, err := content.ReadBlob(ctx, store, desc) if err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to read index data") + return ocispec.Descriptor{}, fmt.Errorf("failed to read index data: %w", err) } var manifest ocispec.Manifest if err := json.Unmarshal(mb, &manifest); err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to unmarshal data into manifest") + return ocispec.Descriptor{}, fmt.Errorf("failed to unmarshal data into manifest: %w", err) } // check config media type @@ -68,7 +67,7 @@ func ConvertManifest(ctx context.Context, store content.Store, desc ocispec.Desc manifest.Config.MediaType = images.MediaTypeDockerSchema2Config data, err := json.MarshalIndent(manifest, "", " ") if err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal manifest") + return ocispec.Descriptor{}, fmt.Errorf("failed to marshal manifest: %w", err) } // update manifest with gc labels @@ -82,7 +81,7 @@ func ConvertManifest(ctx context.Context, store content.Store, desc ocispec.Desc ref := remotes.MakeRefKey(ctx, desc) if err := content.WriteBlob(ctx, store, ref, bytes.NewReader(data), desc, content.WithLabels(labels)); err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to update content") + return ocispec.Descriptor{}, fmt.Errorf("failed to update content: %w", err) } return desc, nil } diff --git a/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go b/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go index 4b2c10e9a3..11a75356e8 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go @@ -19,9 +19,9 @@ package docker import ( "context" "encoding/json" + "errors" "fmt" "io" - "io/ioutil" "net/http" "net/url" "strings" @@ -30,7 +30,6 @@ import ( "github.com/containerd/containerd/images" "github.com/containerd/containerd/log" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) type dockerFetcher struct { @@ -42,7 +41,7 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R hosts := r.filterHosts(HostCapabilityPull) if len(hosts) == 0 { - return nil, errors.Wrap(errdefs.ErrNotFound, "no pull hosts") + return nil, fmt.Errorf("no pull hosts: %w", errdefs.ErrNotFound) } ctx, err := ContextWithRepositoryScope(ctx, r.refspec, false) @@ -142,9 +141,9 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R } if errdefs.IsNotFound(firstErr) { - firstErr = errors.Wrapf(errdefs.ErrNotFound, - "could not fetch content descriptor %v (%v) from remote", - desc.Digest, desc.MediaType) + firstErr = fmt.Errorf("could not fetch content descriptor %v (%v) from remote: %w", + desc.Digest, desc.MediaType, errdefs.ErrNotFound, + ) } return nil, firstErr @@ -179,19 +178,19 @@ func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string, // implementation. if resp.StatusCode == http.StatusNotFound { - return nil, errors.Wrapf(errdefs.ErrNotFound, "content at %v not found", req.String()) + return nil, fmt.Errorf("content at %v not found: %w", req.String(), errdefs.ErrNotFound) } var registryErr Errors if err := json.NewDecoder(resp.Body).Decode(®istryErr); err != nil || registryErr.Len() < 1 { - return nil, errors.Errorf("unexpected status code %v: %v", req.String(), resp.Status) + return nil, fmt.Errorf("unexpected status code %v: %v", req.String(), resp.Status) } - return nil, errors.Errorf("unexpected status code %v: %s - Server message: %s", req.String(), resp.Status, registryErr.Error()) + return nil, fmt.Errorf("unexpected status code %v: %s - Server message: %s", req.String(), resp.Status, registryErr.Error()) } if offset > 0 { cr := resp.Header.Get("content-range") if cr != "" { if !strings.HasPrefix(cr, fmt.Sprintf("bytes %d-", offset)) { - return nil, errors.Errorf("unhandled content range in response: %v", cr) + return nil, fmt.Errorf("unhandled content range in response: %v", cr) } } else { @@ -201,12 +200,12 @@ func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string, // Discard up to offset // Could use buffer pool here but this case should be rare - n, err := io.Copy(ioutil.Discard, io.LimitReader(resp.Body, offset)) + n, err := io.Copy(io.Discard, io.LimitReader(resp.Body, offset)) if err != nil { - return nil, errors.Wrap(err, "failed to discard to offset") + return nil, fmt.Errorf("failed to discard to offset: %w", err) } if n != offset { - return nil, errors.Errorf("unable to discard to offset") + return nil, errors.New("unable to discard to offset") } } diff --git a/vendor/github.com/containerd/containerd/remotes/docker/httpreadseeker.go b/vendor/github.com/containerd/containerd/remotes/docker/httpreadseeker.go index 58c866bcde..9a827ef04c 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/httpreadseeker.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/httpreadseeker.go @@ -18,12 +18,11 @@ package docker import ( "bytes" + "fmt" "io" - "io/ioutil" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" - "github.com/pkg/errors" ) const maxRetry = 3 @@ -70,7 +69,7 @@ func (hrs *httpReadSeeker) Read(p []byte) (n int, err error) { } if hrs.rc != nil { if clsErr := hrs.rc.Close(); clsErr != nil { - log.L.WithError(clsErr).Errorf("httpReadSeeker: failed to close ReadCloser") + log.L.WithError(clsErr).Error("httpReadSeeker: failed to close ReadCloser") } hrs.rc = nil } @@ -95,7 +94,7 @@ func (hrs *httpReadSeeker) Close() error { func (hrs *httpReadSeeker) Seek(offset int64, whence int) (int64, error) { if hrs.closed { - return 0, errors.Wrap(errdefs.ErrUnavailable, "Fetcher.Seek: closed") + return 0, fmt.Errorf("Fetcher.Seek: closed: %w", errdefs.ErrUnavailable) } abs := hrs.offset @@ -106,21 +105,21 @@ func (hrs *httpReadSeeker) Seek(offset int64, whence int) (int64, error) { abs += offset case io.SeekEnd: if hrs.size == -1 { - return 0, errors.Wrap(errdefs.ErrUnavailable, "Fetcher.Seek: unknown size, cannot seek from end") + return 0, fmt.Errorf("Fetcher.Seek: unknown size, cannot seek from end: %w", errdefs.ErrUnavailable) } abs = hrs.size + offset default: - return 0, errors.Wrap(errdefs.ErrInvalidArgument, "Fetcher.Seek: invalid whence") + return 0, fmt.Errorf("Fetcher.Seek: invalid whence: %w", errdefs.ErrInvalidArgument) } if abs < 0 { - return 0, errors.Wrapf(errdefs.ErrInvalidArgument, "Fetcher.Seek: negative offset") + return 0, fmt.Errorf("Fetcher.Seek: negative offset: %w", errdefs.ErrInvalidArgument) } if abs != hrs.offset { if hrs.rc != nil { if err := hrs.rc.Close(); err != nil { - log.L.WithError(err).Errorf("Fetcher.Seek: failed to close ReadCloser") + log.L.WithError(err).Error("Fetcher.Seek: failed to close ReadCloser") } hrs.rc = nil @@ -141,17 +140,17 @@ func (hrs *httpReadSeeker) reader() (io.Reader, error) { // only try to reopen the body request if we are seeking to a value // less than the actual size. if hrs.open == nil { - return nil, errors.Wrapf(errdefs.ErrNotImplemented, "cannot open") + return nil, fmt.Errorf("cannot open: %w", errdefs.ErrNotImplemented) } rc, err := hrs.open(hrs.offset) if err != nil { - return nil, errors.Wrapf(err, "httpReadSeeker: failed open") + return nil, fmt.Errorf("httpReadSeeker: failed open: %w", err) } if hrs.rc != nil { if err := hrs.rc.Close(); err != nil { - log.L.WithError(err).Errorf("httpReadSeeker: failed to close ReadCloser") + log.L.WithError(err).Error("httpReadSeeker: failed to close ReadCloser") } } hrs.rc = rc @@ -162,7 +161,7 @@ func (hrs *httpReadSeeker) reader() (io.Reader, error) { // as the length is already satisfied but we just return the empty // reader instead. - hrs.rc = ioutil.NopCloser(bytes.NewReader([]byte{})) + hrs.rc = io.NopCloser(bytes.NewReader([]byte{})) } return hrs.rc, nil diff --git a/vendor/github.com/containerd/containerd/remotes/docker/pusher.go b/vendor/github.com/containerd/containerd/remotes/docker/pusher.go index 97ed66a6ab..c786ad2158 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/pusher.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/pusher.go @@ -18,8 +18,9 @@ package docker import ( "context" + "errors" + "fmt" "io" - "io/ioutil" "net/http" "net/url" "strings" @@ -33,7 +34,6 @@ import ( remoteserrors "github.com/containerd/containerd/remotes/errors" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) type dockerPusher struct { @@ -56,7 +56,7 @@ func (p dockerPusher) Writer(ctx context.Context, opts ...content.WriterOpt) (co } } if wOpts.Ref == "" { - return nil, errors.Wrap(errdefs.ErrInvalidArgument, "ref must not be empty") + return nil, fmt.Errorf("ref must not be empty: %w", errdefs.ErrInvalidArgument) } return p.push(ctx, wOpts.Desc, wOpts.Ref, true) } @@ -77,22 +77,22 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str status, err := p.tracker.GetStatus(ref) if err == nil { if status.Committed && status.Offset == status.Total { - return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "ref %v", ref) + return nil, fmt.Errorf("ref %v: %w", ref, errdefs.ErrAlreadyExists) } - if unavailableOnFail { + if unavailableOnFail && status.ErrClosed == nil { // Another push of this ref is happening elsewhere. The rest of function // will continue only when `errdefs.IsNotFound(err) == true` (i.e. there // is no actively-tracked ref already). - return nil, errors.Wrap(errdefs.ErrUnavailable, "push is on-going") + return nil, fmt.Errorf("push is on-going: %w", errdefs.ErrUnavailable) } // TODO: Handle incomplete status } else if !errdefs.IsNotFound(err) { - return nil, errors.Wrap(err, "failed to get status") + return nil, fmt.Errorf("failed to get status: %w", err) } hosts := p.filterHosts(HostCapabilityPush) if len(hosts) == 0 { - return nil, errors.Wrap(errdefs.ErrNotFound, "no push hosts") + return nil, fmt.Errorf("no push hosts: %w", errdefs.ErrNotFound) } var ( @@ -144,7 +144,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str }, }) resp.Body.Close() - return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest) + return nil, fmt.Errorf("content %v on remote: %w", desc.Digest, errdefs.ErrAlreadyExists) } } else if resp.StatusCode != http.StatusNotFound { err := remoteserrors.NewUnexpectedStatusErr(resp) @@ -206,7 +206,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str Offset: desc.Size, }, }) - return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest) + return nil, fmt.Errorf("content %v on remote: %w", desc.Digest, errdefs.ErrAlreadyExists) default: err := remoteserrors.NewUnexpectedStatusErr(resp) log.G(ctx).WithField("resp", resp).WithField("body", string(err.(remoteserrors.ErrUnexpectedStatus).Body)).Debug("unexpected response") @@ -222,7 +222,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str if strings.HasPrefix(location, "/") { lurl, err = url.Parse(lhost.Scheme + "://" + lhost.Host + location) if err != nil { - return nil, errors.Wrapf(err, "unable to parse location %v", location) + return nil, fmt.Errorf("unable to parse location %v: %w", location, err) } } else { if !strings.Contains(location, "://") { @@ -230,7 +230,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str } lurl, err = url.Parse(location) if err != nil { - return nil, errors.Wrapf(err, "unable to parse location %v", location) + return nil, fmt.Errorf("unable to parse location %v: %w", location, err) } if lurl.Host != lhost.Host || lhost.Scheme != lurl.Scheme { @@ -263,7 +263,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str pr, pw := io.Pipe() respC := make(chan response, 1) - body := ioutil.NopCloser(pr) + body := io.NopCloser(pr) req.body = func() (io.ReadCloser, error) { if body == nil { @@ -355,6 +355,12 @@ func (pw *pushWriter) Write(p []byte) (n int, err error) { } func (pw *pushWriter) Close() error { + status, err := pw.tracker.GetStatus(pw.ref) + if err == nil && !status.Committed { + // Closing an incomplete writer. Record this as an error so that following write can retry it. + status.ErrClosed = errors.New("closed incomplete writer") + pw.tracker.SetStatus(pw.ref, status) + } return pw.pipe.Close() } @@ -375,7 +381,7 @@ func (pw *pushWriter) Digest() digest.Digest { func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error { // Check whether read has already thrown an error if _, err := pw.pipe.Write([]byte{}); err != nil && err != io.ErrClosedPipe { - return errors.Wrap(err, "pipe error before commit") + return fmt.Errorf("pipe error before commit: %w", err) } if err := pw.pipe.Close(); err != nil { @@ -398,11 +404,11 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di status, err := pw.tracker.GetStatus(pw.ref) if err != nil { - return errors.Wrap(err, "failed to get status") + return fmt.Errorf("failed to get status: %w", err) } if size > 0 && size != status.Offset { - return errors.Errorf("unexpected size %d, expected %d", status.Offset, size) + return fmt.Errorf("unexpected size %d, expected %d", status.Offset, size) } if expected == "" { @@ -411,11 +417,11 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di actual, err := digest.Parse(resp.Header.Get("Docker-Content-Digest")) if err != nil { - return errors.Wrap(err, "invalid content digest in response") + return fmt.Errorf("invalid content digest in response: %w", err) } if actual != expected { - return errors.Errorf("got digest %s, expected %s", actual, expected) + return fmt.Errorf("got digest %s, expected %s", actual, expected) } status.Committed = true diff --git a/vendor/github.com/containerd/containerd/remotes/docker/registry.go b/vendor/github.com/containerd/containerd/remotes/docker/registry.go index 1e77d4c86c..98cafcd069 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/registry.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/registry.go @@ -17,10 +17,9 @@ package docker import ( + "errors" "net" "net/http" - - "github.com/pkg/errors" ) // HostCapabilities represent the capabilities of the registry diff --git a/vendor/github.com/containerd/containerd/remotes/docker/resolver.go b/vendor/github.com/containerd/containerd/remotes/docker/resolver.go index 1be9e1d05c..9bbbc26222 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/resolver.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/resolver.go @@ -18,9 +18,9 @@ package docker import ( "context" + "errors" "fmt" "io" - "io/ioutil" "net/http" "net/url" "path" @@ -35,7 +35,6 @@ import ( "github.com/containerd/containerd/version" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/net/context/ctxhttp" ) @@ -255,7 +254,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp hosts := base.filterHosts(caps) if len(hosts) == 0 { - return "", ocispec.Descriptor{}, errors.Wrap(errdefs.ErrNotFound, "no resolve hosts") + return "", ocispec.Descriptor{}, fmt.Errorf("no resolve hosts: %w", errdefs.ErrNotFound) } ctx, err = ContextWithRepositoryScope(ctx, refspec, false) @@ -280,7 +279,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp resp, err := req.doWithRetries(ctx, nil) if err != nil { if errors.Is(err, ErrInvalidAuthorization) { - err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization") + err = fmt.Errorf("pull access denied, repository does not exist or may require authorization: %w", err) } // Store the error for referencing later if firstErr == nil { @@ -299,11 +298,11 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp if resp.StatusCode > 399 { // Set firstErr when encountering the first non-404 status code. if firstErr == nil { - firstErr = errors.Errorf("pulling from host %s failed with status code %v: %v", host.Host, u, resp.Status) + firstErr = fmt.Errorf("pulling from host %s failed with status code %v: %v", host.Host, u, resp.Status) } continue // try another host } - return "", ocispec.Descriptor{}, errors.Errorf("pulling from host %s failed with unexpected status code %v: %v", host.Host, u, resp.Status) + return "", ocispec.Descriptor{}, fmt.Errorf("pulling from host %s failed with unexpected status code %v: %v", host.Host, u, resp.Status) } size := resp.ContentLength contentType := getManifestMediaType(resp) @@ -319,7 +318,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp if dgstHeader != "" && size != -1 { if err := dgstHeader.Validate(); err != nil { - return "", ocispec.Descriptor{}, errors.Wrapf(err, "%q in header not a valid digest", dgstHeader) + return "", ocispec.Descriptor{}, fmt.Errorf("%q in header not a valid digest: %w", dgstHeader, err) } dgst = dgstHeader } @@ -359,7 +358,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp return "", ocispec.Descriptor{}, err } } - } else if _, err := io.Copy(ioutil.Discard, &bodyReader); err != nil { + } else if _, err := io.Copy(io.Discard, &bodyReader); err != nil { return "", ocispec.Descriptor{}, err } size = bodyReader.bytesRead @@ -367,7 +366,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp // Prevent resolving to excessively large manifests if size > MaxManifestSize { if firstErr == nil { - firstErr = errors.Wrapf(errdefs.ErrNotFound, "rejecting %d byte manifest for %s", size, ref) + firstErr = fmt.Errorf("rejecting %d byte manifest for %s: %w", size, ref, errdefs.ErrNotFound) } continue } @@ -388,7 +387,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp // means that either no registries were given or each registry returned 404. if firstErr == nil { - firstErr = errors.Wrap(errdefs.ErrNotFound, ref) + firstErr = fmt.Errorf("%s: %w", ref, errdefs.ErrNotFound) } return "", ocispec.Descriptor{}, firstErr @@ -548,7 +547,7 @@ func (r *request) do(ctx context.Context) (*http.Response, error) { ctx = log.WithLogger(ctx, log.G(ctx).WithField("url", u)) log.G(ctx).WithFields(requestFields(req)).Debug("do request") if err := r.authorize(ctx, req); err != nil { - return nil, errors.Wrap(err, "failed to authorize") + return nil, fmt.Errorf("failed to authorize: %w", err) } var client = &http.Client{} @@ -560,13 +559,16 @@ func (r *request) do(ctx context.Context) (*http.Response, error) { if len(via) >= 10 { return errors.New("stopped after 10 redirects") } - return errors.Wrap(r.authorize(ctx, req), "failed to authorize redirect") + if err := r.authorize(ctx, req); err != nil { + return fmt.Errorf("failed to authorize redirect: %w", err) + } + return nil } } resp, err := ctxhttp.Do(ctx, client, req) if err != nil { - return nil, errors.Wrap(err, "failed to do request") + return nil, fmt.Errorf("failed to do request: %w", err) } log.G(ctx).WithFields(responseFields(resp)).Debug("fetch response received") return resp, nil diff --git a/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go b/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go index f15a9acf3e..efa4e8d6ee 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go @@ -21,16 +21,14 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "io" - "io/ioutil" "strconv" "strings" "sync" "time" - "golang.org/x/sync/errgroup" - "github.com/containerd/containerd/archive/compression" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" @@ -40,7 +38,7 @@ import ( digest "github.com/opencontainers/go-digest" specs "github.com/opencontainers/image-spec/specs-go" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" + "golang.org/x/sync/errgroup" ) const ( @@ -159,12 +157,12 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De history, diffIDs, err := c.schema1ManifestHistory() if err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "schema 1 conversion failed") + return ocispec.Descriptor{}, fmt.Errorf("schema 1 conversion failed: %w", err) } var img ocispec.Image if err := json.Unmarshal([]byte(c.pulledManifest.History[0].V1Compatibility), &img); err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to unmarshal image from schema 1 history") + return ocispec.Descriptor{}, fmt.Errorf("failed to unmarshal image from schema 1 history: %w", err) } img.History = history @@ -175,7 +173,7 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De b, err := json.MarshalIndent(img, "", " ") if err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal image") + return ocispec.Descriptor{}, fmt.Errorf("failed to marshal image: %w", err) } config := ocispec.Descriptor{ @@ -199,7 +197,7 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De mb, err := json.MarshalIndent(manifest, "", " ") if err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal image") + return ocispec.Descriptor{}, fmt.Errorf("failed to marshal image: %w", err) } desc := ocispec.Descriptor{ @@ -216,12 +214,12 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De ref := remotes.MakeRefKey(ctx, desc) if err := content.WriteBlob(ctx, c.contentStore, ref, bytes.NewReader(mb), desc, content.WithLabels(labels)); err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to write image manifest") + return ocispec.Descriptor{}, fmt.Errorf("failed to write image manifest: %w", err) } ref = remotes.MakeRefKey(ctx, config) if err := content.WriteBlob(ctx, c.contentStore, ref, bytes.NewReader(b), config); err != nil { - return ocispec.Descriptor{}, errors.Wrap(err, "failed to write image config") + return ocispec.Descriptor{}, fmt.Errorf("failed to write image config: %w", err) } return desc, nil @@ -230,7 +228,7 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De // ReadStripSignature reads in a schema1 manifest and returns a byte array // with the "signatures" field stripped func ReadStripSignature(schema1Blob io.Reader) ([]byte, error) { - b, err := ioutil.ReadAll(io.LimitReader(schema1Blob, manifestSizeLimit)) // limit to 8MB + b, err := io.ReadAll(io.LimitReader(schema1Blob, manifestSizeLimit)) // limit to 8MB if err != nil { return nil, err } @@ -350,7 +348,7 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro if desc.Size == -1 { info, err := c.contentStore.Info(ctx, desc.Digest) if err != nil { - return errors.Wrap(err, "failed to get blob info") + return fmt.Errorf("failed to get blob info: %w", err) } desc.Size = info.Size } @@ -371,7 +369,7 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro } if _, err := c.contentStore.Update(ctx, cinfo, "labels.containerd.io/uncompressed", fmt.Sprintf("labels.%s", labelDockerSchema1EmptyLayer)); err != nil { - return errors.Wrap(err, "failed to update uncompressed label") + return fmt.Errorf("failed to update uncompressed label: %w", err) } c.mu.Lock() @@ -385,7 +383,7 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro func (c *Converter) reuseLabelBlobState(ctx context.Context, desc ocispec.Descriptor) (bool, error) { cinfo, err := c.contentStore.Info(ctx, desc.Digest) if err != nil { - return false, errors.Wrap(err, "failed to get blob info") + return false, fmt.Errorf("failed to get blob info: %w", err) } desc.Size = cinfo.Size @@ -442,7 +440,7 @@ func (c *Converter) schema1ManifestHistory() ([]ocispec.History, []digest.Digest for i := range m.History { var h v1History if err := json.Unmarshal([]byte(m.History[i].V1Compatibility), &h); err != nil { - return nil, nil, errors.Wrap(err, "failed to unmarshal history") + return nil, nil, fmt.Errorf("failed to unmarshal history: %w", err) } blobSum := m.FSLayers[i].BlobSum @@ -554,7 +552,7 @@ func stripSignature(b []byte) ([]byte, error) { } pb, err := joseBase64UrlDecode(sig.Signatures[0].Protected) if err != nil { - return nil, errors.Wrapf(err, "could not decode %s", sig.Signatures[0].Protected) + return nil, fmt.Errorf("could not decode %s: %w", sig.Signatures[0].Protected, err) } var protected protectedBlock @@ -568,7 +566,7 @@ func stripSignature(b []byte) ([]byte, error) { tail, err := joseBase64UrlDecode(protected.Tail) if err != nil { - return nil, errors.Wrap(err, "invalid tail base 64 value") + return nil, fmt.Errorf("invalid tail base 64 value: %w", err) } return append(b[:protected.Length], tail...), nil diff --git a/vendor/github.com/containerd/containerd/remotes/docker/scope.go b/vendor/github.com/containerd/containerd/remotes/docker/scope.go index fe57f023d3..95b4810ab9 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/scope.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/scope.go @@ -74,7 +74,7 @@ func ContextWithAppendPullRepositoryScope(ctx context.Context, repo string) cont // GetTokenScopes returns deduplicated and sorted scopes from ctx.Value(tokenScopesKey{}) and common scopes. func GetTokenScopes(ctx context.Context, common []string) []string { - var scopes []string + scopes := []string{} if x := ctx.Value(tokenScopesKey{}); x != nil { scopes = append(scopes, x.([]string)...) } @@ -82,6 +82,10 @@ func GetTokenScopes(ctx context.Context, common []string) []string { scopes = append(scopes, common...) sort.Strings(scopes) + if len(scopes) == 0 { + return scopes + } + l := 0 for idx := 1; idx < len(scopes); idx++ { // Note: this comparison is unaware of the scope grammar (https://docs.docker.com/registry/spec/auth/scope/) diff --git a/vendor/github.com/containerd/containerd/remotes/docker/status.go b/vendor/github.com/containerd/containerd/remotes/docker/status.go index 9751edac7f..1f7b278aef 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/status.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/status.go @@ -17,12 +17,12 @@ package docker import ( + "fmt" "sync" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/moby/locker" - "github.com/pkg/errors" ) // Status of a content operation @@ -31,6 +31,9 @@ type Status struct { Committed bool + // ErrClosed contains error encountered on close. + ErrClosed error + // UploadUUID is used by the Docker registry to reference blob uploads UploadUUID string } @@ -67,7 +70,7 @@ func (t *memoryStatusTracker) GetStatus(ref string) (Status, error) { defer t.m.Unlock() status, ok := t.statuses[ref] if !ok { - return Status{}, errors.Wrapf(errdefs.ErrNotFound, "status for ref %v", ref) + return Status{}, fmt.Errorf("status for ref %v: %w", ref, errdefs.ErrNotFound) } return status, nil } diff --git a/vendor/github.com/containerd/containerd/remotes/errors/errors.go b/vendor/github.com/containerd/containerd/remotes/errors/errors.go index 519dbac105..67ccb23df6 100644 --- a/vendor/github.com/containerd/containerd/remotes/errors/errors.go +++ b/vendor/github.com/containerd/containerd/remotes/errors/errors.go @@ -19,7 +19,6 @@ package errors import ( "fmt" "io" - "io/ioutil" "net/http" ) @@ -41,7 +40,7 @@ func (e ErrUnexpectedStatus) Error() string { func NewUnexpectedStatusErr(resp *http.Response) error { var b []byte if resp.Body != nil { - b, _ = ioutil.ReadAll(io.LimitReader(resp.Body, 64000)) // 64KB + b, _ = io.ReadAll(io.LimitReader(resp.Body, 64000)) // 64KB } err := ErrUnexpectedStatus{ Body: b, diff --git a/vendor/github.com/containerd/containerd/remotes/handlers.go b/vendor/github.com/containerd/containerd/remotes/handlers.go index 8f79c608e6..8bcafb22a0 100644 --- a/vendor/github.com/containerd/containerd/remotes/handlers.go +++ b/vendor/github.com/containerd/containerd/remotes/handlers.go @@ -18,6 +18,7 @@ package remotes import ( "context" + "errors" "fmt" "io" "strings" @@ -29,7 +30,6 @@ import ( "github.com/containerd/containerd/log" "github.com/containerd/containerd/platforms" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sync/semaphore" ) @@ -127,13 +127,13 @@ func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc // most likely a poorly configured registry/web front end which responded with no // Content-Length header; unable (not to mention useless) to commit a 0-length entry // into the content store. Error out here otherwise the error sent back is confusing - return errors.Wrapf(errdefs.ErrInvalidArgument, "unable to fetch descriptor (%s) which reports content size of zero", desc.Digest) + return fmt.Errorf("unable to fetch descriptor (%s) which reports content size of zero: %w", desc.Digest, errdefs.ErrInvalidArgument) } if ws.Offset == desc.Size { // If writer is already complete, commit and return err := cw.Commit(ctx, desc.Size, desc.Digest) if err != nil && !errdefs.IsAlreadyExists(err) { - return errors.Wrapf(err, "failed commit on ref %q", ws.Ref) + return fmt.Errorf("failed commit on ref %q: %w", ws.Ref, err) } return nil } @@ -243,8 +243,8 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, st // as a marker for this problem if (manifestStack[i].MediaType == ocispec.MediaTypeImageIndex || manifestStack[i].MediaType == images.MediaTypeDockerSchema2ManifestList) && - errors.Cause(err) != nil && strings.Contains(errors.Cause(err).Error(), "400 Bad Request") { - return errors.Wrap(err, "manifest list/index references to blobs and/or manifests are missing in your target registry") + errors.Unwrap(err) != nil && strings.Contains(errors.Unwrap(err).Error(), "400 Bad Request") { + return fmt.Errorf("manifest list/index references to blobs and/or manifests are missing in your target registry: %w", err) } return err } @@ -253,6 +253,43 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, st return nil } +// SkipNonDistributableBlobs returns a handler that skips blobs that have a media type that is "non-distributeable". +// An example of this kind of content would be a Windows base layer, which is not supposed to be redistributed. +// +// This is based on the media type of the content: +// - application/vnd.oci.image.layer.nondistributable +// - application/vnd.docker.image.rootfs.foreign +func SkipNonDistributableBlobs(f images.HandlerFunc) images.HandlerFunc { + return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { + if images.IsNonDistributable(desc.MediaType) { + log.G(ctx).WithField("digest", desc.Digest).WithField("mediatype", desc.MediaType).Debug("Skipping non-distributable blob") + return nil, images.ErrSkipDesc + } + + if images.IsLayerType(desc.MediaType) { + return nil, nil + } + + children, err := f(ctx, desc) + if err != nil { + return nil, err + } + if len(children) == 0 { + return nil, nil + } + + out := make([]ocispec.Descriptor, 0, len(children)) + for _, child := range children { + if !images.IsNonDistributable(child.MediaType) { + out = append(out, child) + } else { + log.G(ctx).WithField("digest", child.Digest).WithField("mediatype", child.MediaType).Debug("Skipping non-distributable blob") + } + } + return out, nil + } +} + // FilterManifestByPlatformHandler allows Handler to handle non-target // platform's manifest and configuration data. func FilterManifestByPlatformHandler(f images.HandlerFunc, m platforms.Matcher) images.HandlerFunc { diff --git a/vendor/github.com/containerd/containerd/rootfs/apply.go b/vendor/github.com/containerd/containerd/rootfs/apply.go index f1ca624bf9..b3f388e641 100644 --- a/vendor/github.com/containerd/containerd/rootfs/apply.go +++ b/vendor/github.com/containerd/containerd/rootfs/apply.go @@ -31,7 +31,6 @@ import ( "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/identity" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) // Layer represents the descriptors for a layer diff. These descriptions @@ -68,7 +67,7 @@ func ApplyLayersWithOpts(ctx context.Context, layers []Layer, sn snapshots.Snaps _, err := sn.Stat(ctx, chainID.String()) if err != nil { if !errdefs.IsNotFound(err) { - return "", errors.Wrapf(err, "failed to stat snapshot %s", chainID) + return "", fmt.Errorf("failed to stat snapshot %s: %w", chainID, err) } if err := applyLayers(ctx, layers, chain, sn, a, nil, applyOpts); err != nil && !errdefs.IsAlreadyExists(err) { @@ -96,7 +95,7 @@ func ApplyLayerWithOpts(ctx context.Context, layer Layer, chain []digest.Digest, ) if _, err := sn.Stat(ctx, chainID); err != nil { if !errdefs.IsNotFound(err) { - return false, errors.Wrapf(err, "failed to stat snapshot %s", chainID) + return false, fmt.Errorf("failed to stat snapshot %s: %w", chainID, err) } if err := applyLayers(ctx, []Layer{layer}, append(chain, layer.Diff.Digest), sn, a, opts, applyOpts); err != nil { @@ -143,7 +142,7 @@ func applyLayers(ctx context.Context, layers []Layer, chain []digest.Digest, sn } // Already exists should have the caller retry - return errors.Wrapf(err, "failed to prepare extraction snapshot %q", key) + return fmt.Errorf("failed to prepare extraction snapshot %q: %w", key, err) } break @@ -162,16 +161,16 @@ func applyLayers(ctx context.Context, layers []Layer, chain []digest.Digest, sn diff, err = a.Apply(ctx, layer.Blob, mounts, applyOpts...) if err != nil { - err = errors.Wrapf(err, "failed to extract layer %s", layer.Diff.Digest) + err = fmt.Errorf("failed to extract layer %s: %w", layer.Diff.Digest, err) return err } if diff.Digest != layer.Diff.Digest { - err = errors.Errorf("wrong diff id calculated on extraction %q", diff.Digest) + err = fmt.Errorf("wrong diff id calculated on extraction %q", diff.Digest) return err } if err = sn.Commit(ctx, chainID.String(), key, opts...); err != nil { - err = errors.Wrapf(err, "failed to commit snapshot %s", key) + err = fmt.Errorf("failed to commit snapshot %s: %w", key, err) return err } diff --git a/vendor/github.com/containerd/containerd/rootfs/init.go b/vendor/github.com/containerd/containerd/rootfs/init.go index 9316b9ddae..02d13bfc36 100644 --- a/vendor/github.com/containerd/containerd/rootfs/init.go +++ b/vendor/github.com/containerd/containerd/rootfs/init.go @@ -18,15 +18,14 @@ package rootfs import ( "context" + "errors" "fmt" - "io/ioutil" "os" "github.com/containerd/containerd/log" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/snapshots" digest "github.com/opencontainers/go-digest" - "github.com/pkg/errors" ) var ( @@ -45,7 +44,7 @@ type Mounter interface { func InitRootFS(ctx context.Context, name string, parent digest.Digest, readonly bool, snapshotter snapshots.Snapshotter, mounter Mounter) ([]mount.Mount, error) { _, err := snapshotter.Stat(ctx, name) if err == nil { - return nil, errors.Errorf("rootfs already exists") + return nil, errors.New("rootfs already exists") } // TODO: ensure not exist error once added to snapshot package @@ -75,7 +74,7 @@ func createInitLayer(ctx context.Context, parent, initName string, initFn func(s // TODO: ensure not exist error once added to snapshot package // Create tempdir - td, err := ioutil.TempDir(os.Getenv("XDG_RUNTIME_DIR"), "create-init-") + td, err := os.MkdirTemp(os.Getenv("XDG_RUNTIME_DIR"), "create-init-") if err != nil { return "", err } diff --git a/vendor/github.com/containerd/containerd/rootfs/init_other.go b/vendor/github.com/containerd/containerd/rootfs/init_other.go index 261121085d..d8e38d4c78 100644 --- a/vendor/github.com/containerd/containerd/rootfs/init_other.go +++ b/vendor/github.com/containerd/containerd/rootfs/init_other.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux /* diff --git a/vendor/github.com/containerd/containerd/services.go b/vendor/github.com/containerd/containerd/services.go index d8fced5591..e780e6ccfe 100644 --- a/vendor/github.com/containerd/containerd/services.go +++ b/vendor/github.com/containerd/containerd/services.go @@ -55,13 +55,20 @@ func WithContentStore(contentStore content.Store) ServicesOpt { } } -// WithImageService sets the image service. -func WithImageService(imageService imagesapi.ImagesClient) ServicesOpt { +// WithImageClient sets the image service to use using an images client. +func WithImageClient(imageService imagesapi.ImagesClient) ServicesOpt { return func(s *services) { s.imageStore = NewImageStoreFromClient(imageService) } } +// WithImageStore sets the image store. +func WithImageStore(imageStore images.Store) ServicesOpt { + return func(s *services) { + s.imageStore = imageStore + } +} + // WithSnapshotters sets the snapshotters. func WithSnapshotters(snapshotters map[string]snapshots.Snapshotter) ServicesOpt { return func(s *services) { @@ -72,27 +79,41 @@ func WithSnapshotters(snapshotters map[string]snapshots.Snapshotter) ServicesOpt } } -// WithContainerService sets the container service. -func WithContainerService(containerService containersapi.ContainersClient) ServicesOpt { +// WithContainerClient sets the container service to use using a containers client. +func WithContainerClient(containerService containersapi.ContainersClient) ServicesOpt { return func(s *services) { s.containerStore = NewRemoteContainerStore(containerService) } } -// WithTaskService sets the task service. -func WithTaskService(taskService tasks.TasksClient) ServicesOpt { +// WithContainerStore sets the container store. +func WithContainerStore(containerStore containers.Store) ServicesOpt { + return func(s *services) { + s.containerStore = containerStore + } +} + +// WithTaskClient sets the task service to use from a tasks client. +func WithTaskClient(taskService tasks.TasksClient) ServicesOpt { return func(s *services) { s.taskService = taskService } } -// WithDiffService sets the diff service. -func WithDiffService(diffService diff.DiffClient) ServicesOpt { +// WithDiffClient sets the diff service to use from a diff client. +func WithDiffClient(diffService diff.DiffClient) ServicesOpt { return func(s *services) { s.diffService = NewDiffServiceFromClient(diffService) } } +// WithDiffService sets the diff store. +func WithDiffService(diffService DiffService) ServicesOpt { + return func(s *services) { + s.diffService = diffService + } +} + // WithEventService sets the event service. func WithEventService(eventService EventService) ServicesOpt { return func(s *services) { @@ -100,13 +121,20 @@ func WithEventService(eventService EventService) ServicesOpt { } } -// WithNamespaceService sets the namespace service. -func WithNamespaceService(namespaceService namespacesapi.NamespacesClient) ServicesOpt { +// WithNamespaceClient sets the namespace service using a namespaces client. +func WithNamespaceClient(namespaceService namespacesapi.NamespacesClient) ServicesOpt { return func(s *services) { s.namespaceStore = NewNamespaceStoreFromClient(namespaceService) } } +// WithNamespaceService sets the namespace service. +func WithNamespaceService(namespaceService namespaces.Store) ServicesOpt { + return func(s *services) { + s.namespaceStore = namespaceService + } +} + // WithLeasesService sets the lease service. func WithLeasesService(leasesService leases.Manager) ServicesOpt { return func(s *services) { @@ -114,9 +142,16 @@ func WithLeasesService(leasesService leases.Manager) ServicesOpt { } } -// WithIntrospectionService sets the introspection service. -func WithIntrospectionService(in introspectionapi.IntrospectionClient) ServicesOpt { +// WithIntrospectionClient sets the introspection service using an introspection client. +func WithIntrospectionClient(in introspectionapi.IntrospectionClient) ServicesOpt { return func(s *services) { s.introspectionService = introspection.NewIntrospectionServiceFromClient(in) } } + +// WithIntrospectionService sets the introspection service. +func WithIntrospectionService(in introspection.Service) ServicesOpt { + return func(s *services) { + s.introspectionService = in + } +} diff --git a/vendor/github.com/containerd/containerd/services/content/contentserver/contentserver.go b/vendor/github.com/containerd/containerd/services/content/contentserver/contentserver.go index 7b6efdb3a5..eb5855a476 100644 --- a/vendor/github.com/containerd/containerd/services/content/contentserver/contentserver.go +++ b/vendor/github.com/containerd/containerd/services/content/contentserver/contentserver.go @@ -18,6 +18,7 @@ package contentserver import ( "context" + "fmt" "io" "sync" @@ -28,7 +29,6 @@ import ( ptypes "github.com/gogo/protobuf/types" digest "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -383,7 +383,7 @@ func (s *service) Write(session api.Content_WriteServer) (err error) { if req.Offset == 0 && ws.Offset > 0 { if err := wr.Truncate(req.Offset); err != nil { - return errors.Wrapf(err, "truncate failed") + return fmt.Errorf("truncate failed: %w", err) } msg.Offset = req.Offset } @@ -423,6 +423,10 @@ func (s *service) Write(session api.Content_WriteServer) (err error) { return err } + if req.Action == api.WriteActionCommit { + return nil + } + req, err = session.Recv() if err != nil { if err == io.EOF { diff --git a/vendor/github.com/containerd/containerd/services/introspection/local.go b/vendor/github.com/containerd/containerd/services/introspection/local.go index 988f1e834b..47388e4371 100644 --- a/vendor/github.com/containerd/containerd/services/introspection/local.go +++ b/vendor/github.com/containerd/containerd/services/introspection/local.go @@ -18,7 +18,6 @@ package introspection import ( context "context" - "io/ioutil" "os" "path/filepath" "sync" @@ -42,12 +41,9 @@ func init() { ID: services.IntrospectionService, Requires: []plugin.Type{}, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - // this service works by using the plugin context up till the point - // this service is initialized. Since we require this service last, - // it should provide the full set of plugins. - pluginsPB := pluginsToPB(ic.GetAll()) + // this service fetches all plugins through the plugin set of the plugin context return &Local{ - plugins: pluginsPB, + plugins: ic.Plugins(), root: ic.Root, }, nil }, @@ -56,19 +52,19 @@ func init() { // Local is a local implementation of the introspection service type Local struct { - mu sync.Mutex - plugins []api.Plugin - root string + mu sync.Mutex + root string + plugins *plugin.Set + pluginCache []api.Plugin } var _ = (api.IntrospectionClient)(&Local{}) // UpdateLocal updates the local introspection service -func (l *Local) UpdateLocal(root string, plugins []api.Plugin) { +func (l *Local) UpdateLocal(root string) { l.mu.Lock() defer l.mu.Unlock() l.root = root - l.plugins = plugins } // Plugins returns the locally defined plugins @@ -96,7 +92,11 @@ func (l *Local) Plugins(ctx context.Context, req *api.PluginsRequest, _ ...grpc. func (l *Local) getPlugins() []api.Plugin { l.mu.Lock() defer l.mu.Unlock() - return l.plugins + plugins := l.plugins.GetAll() + if l.pluginCache == nil || len(plugins) != len(l.pluginCache) { + l.pluginCache = pluginsToPB(plugins) + } + return l.pluginCache } // Server returns the local server information @@ -114,7 +114,7 @@ func (l *Local) getUUID() (string, error) { l.mu.Lock() defer l.mu.Unlock() - data, err := ioutil.ReadFile(l.uuidPath()) + data, err := os.ReadFile(l.uuidPath()) if err != nil { if os.IsNotExist(err) { return l.generateUUID() @@ -138,7 +138,7 @@ func (l *Local) generateUUID() (string, error) { return "", err } uu := u.String() - if err := ioutil.WriteFile(path, []byte(uu), 0666); err != nil { + if err := os.WriteFile(path, []byte(uu), 0666); err != nil { return "", err } return uu, nil diff --git a/vendor/github.com/containerd/containerd/services/introspection/service.go b/vendor/github.com/containerd/containerd/services/introspection/service.go index b8c54afc02..c11b8dc1ce 100644 --- a/vendor/github.com/containerd/containerd/services/introspection/service.go +++ b/vendor/github.com/containerd/containerd/services/introspection/service.go @@ -18,12 +18,12 @@ package introspection import ( context "context" + "errors" api "github.com/containerd/containerd/api/services/introspection/v1" "github.com/containerd/containerd/plugin" "github.com/containerd/containerd/services" ptypes "github.com/gogo/protobuf/types" - "github.com/pkg/errors" "google.golang.org/grpc" ) @@ -31,11 +31,8 @@ func init() { plugin.Register(&plugin.Registration{ Type: plugin.GRPCPlugin, ID: "introspection", - Requires: []plugin.Type{"*"}, + Requires: []plugin.Type{plugin.ServicePlugin}, InitFn: func(ic *plugin.InitContext) (interface{}, error) { - // this service works by using the plugin context up till the point - // this service is initialized. Since we require this service last, - // it should provide the full set of plugins. plugins, err := ic.GetByType(plugin.ServicePlugin) if err != nil { return nil, err @@ -50,13 +47,11 @@ func init() { return nil, err } - allPluginsPB := pluginsToPB(ic.GetAll()) - localClient, ok := i.(*Local) if !ok { - return nil, errors.Errorf("Could not create a local client for introspection service") + return nil, errors.New("Could not create a local client for introspection service") } - localClient.UpdateLocal(ic.Root, allPluginsPB) + localClient.UpdateLocal(ic.Root) return &server{ local: localClient, diff --git a/vendor/github.com/containerd/containerd/services/server/config/config.go b/vendor/github.com/containerd/containerd/services/server/config/config.go index 6aafe36a5d..49175c9a0b 100644 --- a/vendor/github.com/containerd/containerd/services/server/config/config.go +++ b/vendor/github.com/containerd/containerd/services/server/config/config.go @@ -17,12 +17,12 @@ package config import ( + "fmt" "path/filepath" "strings" "github.com/imdario/mergo" "github.com/pelletier/go-toml" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/containerd/containerd/errdefs" @@ -39,6 +39,8 @@ type Config struct { Root string `toml:"root"` // State is the path to a directory where containerd will store transient data State string `toml:"state"` + // TempDir is the path to a directory where to place containerd temporary files + TempDir string `toml:"temp"` // PluginDir is the directory for dynamic plugins to be stored PluginDir string `toml:"plugin_dir"` // GRPC configuration settings @@ -67,7 +69,7 @@ type Config struct { Timeouts map[string]string `toml:"timeouts"` // Imports are additional file path list to config files that can overwrite main config file fields Imports []string `toml:"imports"` - + // StreamProcessors configuration StreamProcessors map[string]StreamProcessor `toml:"stream_processors"` } @@ -102,17 +104,17 @@ func (c *Config) ValidateV2() error { } for _, p := range c.DisabledPlugins { if len(strings.Split(p, ".")) < 4 { - return errors.Errorf("invalid disabled plugin URI %q expect io.containerd.x.vx", p) + return fmt.Errorf("invalid disabled plugin URI %q expect io.containerd.x.vx", p) } } for _, p := range c.RequiredPlugins { if len(strings.Split(p, ".")) < 4 { - return errors.Errorf("invalid required plugin URI %q expect io.containerd.x.vx", p) + return fmt.Errorf("invalid required plugin URI %q expect io.containerd.x.vx", p) } } for p := range c.Plugins { if len(strings.Split(p, ".")) < 4 { - return errors.Errorf("invalid plugin key URI %q expect io.containerd.x.vx", p) + return fmt.Errorf("invalid plugin key URI %q expect io.containerd.x.vx", p) } } return nil @@ -122,6 +124,7 @@ func (c *Config) ValidateV2() error { type GRPCConfig struct { Address string `toml:"address"` TCPAddress string `toml:"tcp_address"` + TCPTLSCA string `toml:"tcp_tls_ca"` TCPTLSCert string `toml:"tcp_tls_cert"` TCPTLSKey string `toml:"tcp_tls_key"` UID int `toml:"uid"` @@ -198,7 +201,7 @@ func (bc *BoltConfig) Validate() error { case SharingPolicyShared, SharingPolicyIsolated: return nil default: - return errors.Wrapf(errdefs.ErrInvalidArgument, "unknown policy: %s", bc.ContentSharingPolicy) + return fmt.Errorf("unknown policy: %s: %w", bc.ContentSharingPolicy, errdefs.ErrInvalidArgument) } } @@ -221,7 +224,7 @@ func (c *Config) Decode(p *plugin.Registration) (interface{}, error) { // LoadConfig loads the containerd server config from the provided path func LoadConfig(path string, out *Config) error { if out == nil { - return errors.Wrapf(errdefs.ErrInvalidArgument, "argument out must not be nil") + return fmt.Errorf("argument out must not be nil: %w", errdefs.ErrInvalidArgument) } var ( @@ -263,7 +266,7 @@ func LoadConfig(path string, out *Config) error { err := out.ValidateV2() if err != nil { - return errors.Wrapf(err, "failed to load TOML from %s", path) + return fmt.Errorf("failed to load TOML from %s: %w", path, err) } return nil } @@ -274,11 +277,11 @@ func loadConfigFile(path string) (*Config, error) { file, err := toml.LoadFile(path) if err != nil { - return nil, errors.Wrapf(err, "failed to load TOML: %s", path) + return nil, fmt.Errorf("failed to load TOML: %s: %w", path, err) } if err := file.Unmarshal(config); err != nil { - return nil, errors.Wrap(err, "failed to unmarshal TOML") + return nil, fmt.Errorf("failed to unmarshal TOML: %w", err) } return config, nil diff --git a/vendor/github.com/containerd/containerd/signals.go b/vendor/github.com/containerd/containerd/signals.go index ca64ecd021..9d81eed876 100644 --- a/vendor/github.com/containerd/containerd/signals.go +++ b/vendor/github.com/containerd/containerd/signals.go @@ -24,6 +24,7 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/images" + "github.com/moby/sys/signal" v1 "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -40,7 +41,7 @@ func GetStopSignal(ctx context.Context, container Container, defaultSignal sysca } if stopSignal, ok := labels[StopSignalLabel]; ok { - return ParseSignal(stopSignal) + return signal.ParseSignal(stopSignal) } return defaultSignal, nil @@ -48,7 +49,7 @@ func GetStopSignal(ctx context.Context, container Container, defaultSignal sysca // GetOCIStopSignal retrieves the stop signal specified in the OCI image config func GetOCIStopSignal(ctx context.Context, image Image, defaultSignal string) (string, error) { - _, err := ParseSignal(defaultSignal) + _, err := signal.ParseSignal(defaultSignal) if err != nil { return "", err } @@ -81,3 +82,12 @@ func GetOCIStopSignal(ctx context.Context, image Image, defaultSignal string) (s return config.StopSignal, nil } + +// ParseSignal parses a given string into a syscall.Signal +// the rawSignal can be a string with "SIG" prefix, +// or a signal number in string format. +// +// Deprecated: Use github.com/moby/sys/signal instead. +func ParseSignal(rawSignal string) (syscall.Signal, error) { + return signal.ParseSignal(rawSignal) +} diff --git a/vendor/github.com/containerd/containerd/signals_unix.go b/vendor/github.com/containerd/containerd/signals_unix.go deleted file mode 100644 index 14916a9ff3..0000000000 --- a/vendor/github.com/containerd/containerd/signals_unix.go +++ /dev/null @@ -1,43 +0,0 @@ -// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris - -/* - 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 containerd - -import ( - "fmt" - "strconv" - "strings" - "syscall" - - "golang.org/x/sys/unix" -) - -// ParseSignal parses a given string into a syscall.Signal -// the rawSignal can be a string with "SIG" prefix, -// or a signal number in string format. -func ParseSignal(rawSignal string) (syscall.Signal, error) { - s, err := strconv.Atoi(rawSignal) - if err == nil { - return syscall.Signal(s), nil - } - signal := unix.SignalNum(strings.ToUpper(rawSignal)) - if signal == 0 { - return -1, fmt.Errorf("unknown signal %q", rawSignal) - } - return signal, nil -} diff --git a/vendor/github.com/containerd/containerd/signals_windows.go b/vendor/github.com/containerd/containerd/signals_windows.go deleted file mode 100644 index 0018e191ed..0000000000 --- a/vendor/github.com/containerd/containerd/signals_windows.go +++ /dev/null @@ -1,63 +0,0 @@ -/* - 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 containerd - -import ( - "fmt" - "strconv" - "strings" - "syscall" - - "golang.org/x/sys/windows" -) - -var signalMap = map[string]syscall.Signal{ - "HUP": syscall.Signal(windows.SIGHUP), - "INT": syscall.Signal(windows.SIGINT), - "QUIT": syscall.Signal(windows.SIGQUIT), - "SIGILL": syscall.Signal(windows.SIGILL), - "TRAP": syscall.Signal(windows.SIGTRAP), - "ABRT": syscall.Signal(windows.SIGABRT), - "BUS": syscall.Signal(windows.SIGBUS), - "FPE": syscall.Signal(windows.SIGFPE), - "KILL": syscall.Signal(windows.SIGKILL), - "SEGV": syscall.Signal(windows.SIGSEGV), - "PIPE": syscall.Signal(windows.SIGPIPE), - "ALRM": syscall.Signal(windows.SIGALRM), - "TERM": syscall.Signal(windows.SIGTERM), -} - -// ParseSignal parses a given string into a syscall.Signal -// the rawSignal can be a string with "SIG" prefix, -// or a signal number in string format. -func ParseSignal(rawSignal string) (syscall.Signal, error) { - s, err := strconv.Atoi(rawSignal) - if err == nil { - sig := syscall.Signal(s) - for _, msig := range signalMap { - if sig == msig { - return sig, nil - } - } - return -1, fmt.Errorf("unknown signal %q", rawSignal) - } - signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")] - if !ok { - return -1, fmt.Errorf("unknown signal %q", rawSignal) - } - return signal, nil -} diff --git a/vendor/github.com/containerd/containerd/snapshotter_default_unix.go b/vendor/github.com/containerd/containerd/snapshotter_default_unix.go index eb001c7d38..dcba4792cc 100644 --- a/vendor/github.com/containerd/containerd/snapshotter_default_unix.go +++ b/vendor/github.com/containerd/containerd/snapshotter_default_unix.go @@ -1,3 +1,4 @@ +//go:build darwin || freebsd || solaris // +build darwin freebsd solaris /* diff --git a/vendor/github.com/containerd/containerd/snapshotter_opts_unix.go b/vendor/github.com/containerd/containerd/snapshotter_opts_unix.go index 1964379d49..2a2c829f01 100644 --- a/vendor/github.com/containerd/containerd/snapshotter_opts_unix.go +++ b/vendor/github.com/containerd/containerd/snapshotter_opts_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows /* diff --git a/vendor/github.com/containerd/containerd/sys/epoll.go b/vendor/github.com/containerd/containerd/sys/epoll.go index 28d6c2cabc..73a57013ff 100644 --- a/vendor/github.com/containerd/containerd/sys/epoll.go +++ b/vendor/github.com/containerd/containerd/sys/epoll.go @@ -1,3 +1,4 @@ +//go:build linux // +build linux /* diff --git a/vendor/github.com/containerd/containerd/sys/fds.go b/vendor/github.com/containerd/containerd/sys/fds.go index db3cf702f4..a71a9cd7e9 100644 --- a/vendor/github.com/containerd/containerd/sys/fds.go +++ b/vendor/github.com/containerd/containerd/sys/fds.go @@ -1,3 +1,4 @@ +//go:build !windows && !darwin // +build !windows,!darwin /* @@ -19,14 +20,14 @@ package sys import ( - "io/ioutil" + "os" "path/filepath" "strconv" ) // GetOpenFds returns the number of open fds for the process provided by pid func GetOpenFds(pid int) (int, error) { - dirs, err := ioutil.ReadDir(filepath.Join("/proc", strconv.Itoa(pid), "fd")) + dirs, err := os.ReadDir(filepath.Join("/proc", strconv.Itoa(pid), "fd")) if err != nil { return -1, err } diff --git a/vendor/github.com/containerd/containerd/sys/filesys_unix.go b/vendor/github.com/containerd/containerd/sys/filesys_unix.go index d8329af9fb..805a7a736f 100644 --- a/vendor/github.com/containerd/containerd/sys/filesys_unix.go +++ b/vendor/github.com/containerd/containerd/sys/filesys_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows /* diff --git a/vendor/github.com/containerd/containerd/sys/filesys_windows.go b/vendor/github.com/containerd/containerd/sys/filesys_windows.go index a9198ef399..87ebacc200 100644 --- a/vendor/github.com/containerd/containerd/sys/filesys_windows.go +++ b/vendor/github.com/containerd/containerd/sys/filesys_windows.go @@ -1,5 +1,3 @@ -// +build windows - /* Copyright The containerd Authors. @@ -19,6 +17,7 @@ package sys import ( + "fmt" "os" "path/filepath" "regexp" @@ -29,7 +28,6 @@ import ( "unsafe" "github.com/Microsoft/hcsshim" - "github.com/pkg/errors" "golang.org/x/sys/windows" ) @@ -270,7 +268,7 @@ func ForceRemoveAll(path string) error { snapshotDir := filepath.Join(path, snapshotPlugin, "snapshots") if stat, err := os.Stat(snapshotDir); err == nil && stat.IsDir() { if err := cleanupWCOWLayers(snapshotDir); err != nil { - return errors.Wrapf(err, "failed to cleanup WCOW layers in %s", snapshotDir) + return fmt.Errorf("failed to cleanup WCOW layers in %s: %w", snapshotDir, err) } } @@ -280,12 +278,22 @@ func ForceRemoveAll(path string) error { func cleanupWCOWLayers(root string) error { // See snapshots/windows/windows.go getSnapshotDir() var layerNums []int + var rmLayerNums []int if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if path != root && info.IsDir() { - if layerNum, err := strconv.Atoi(filepath.Base(path)); err == nil { - layerNums = append(layerNums, layerNum) + name := filepath.Base(path) + if strings.HasPrefix(name, "rm-") { + layerNum, err := strconv.Atoi(strings.TrimPrefix(name, "rm-")) + if err != nil { + return err + } + rmLayerNums = append(rmLayerNums, layerNum) } else { - return err + layerNum, err := strconv.Atoi(name) + if err != nil { + return err + } + layerNums = append(layerNums, layerNum) } return filepath.SkipDir } @@ -295,8 +303,14 @@ func cleanupWCOWLayers(root string) error { return err } - sort.Sort(sort.Reverse(sort.IntSlice(layerNums))) + sort.Sort(sort.Reverse(sort.IntSlice(rmLayerNums))) + for _, rmLayerNum := range rmLayerNums { + if err := cleanupWCOWLayer(filepath.Join(root, "rm-"+strconv.Itoa(rmLayerNum))); err != nil { + return err + } + } + sort.Sort(sort.Reverse(sort.IntSlice(layerNums))) for _, layerNum := range layerNums { if err := cleanupWCOWLayer(filepath.Join(root, strconv.Itoa(layerNum))); err != nil { return err @@ -311,19 +325,20 @@ func cleanupWCOWLayer(layerPath string) error { HomeDir: filepath.Dir(layerPath), } - // ERROR_DEV_NOT_EXIST is returned if the layer is not currently prepared. + // ERROR_DEV_NOT_EXIST is returned if the layer is not currently prepared or activated. + // ERROR_FLT_INSTANCE_NOT_FOUND is returned if the layer is currently activated but not prepared. if err := hcsshim.UnprepareLayer(info, filepath.Base(layerPath)); err != nil { - if hcserror, ok := err.(*hcsshim.HcsError); !ok || hcserror.Err != windows.ERROR_DEV_NOT_EXIST { - return errors.Wrapf(err, "failed to unprepare %s", layerPath) + if hcserror, ok := err.(*hcsshim.HcsError); !ok || (hcserror.Err != windows.ERROR_DEV_NOT_EXIST && hcserror.Err != syscall.Errno(windows.ERROR_FLT_INSTANCE_NOT_FOUND)) { + return fmt.Errorf("failed to unprepare %s: %w", layerPath, err) } } if err := hcsshim.DeactivateLayer(info, filepath.Base(layerPath)); err != nil { - return errors.Wrapf(err, "failed to deactivate %s", layerPath) + return fmt.Errorf("failed to deactivate %s: %w", layerPath, err) } if err := hcsshim.DestroyLayer(info, filepath.Base(layerPath)); err != nil { - return errors.Wrapf(err, "failed to destroy %s", layerPath) + return fmt.Errorf("failed to destroy %s: %w", layerPath, err) } return nil diff --git a/vendor/github.com/containerd/containerd/sys/oom_linux.go b/vendor/github.com/containerd/containerd/sys/oom_linux.go index 82a347c6f7..bb2a3eafb4 100644 --- a/vendor/github.com/containerd/containerd/sys/oom_linux.go +++ b/vendor/github.com/containerd/containerd/sys/oom_linux.go @@ -18,7 +18,6 @@ package sys import ( "fmt" - "io/ioutil" "os" "strconv" "strings" @@ -69,7 +68,7 @@ func SetOOMScore(pid, score int) error { // no oom score is set, or a sore is set to 0. func GetOOMScoreAdj(pid int) (int, error) { path := fmt.Sprintf("/proc/%d/oom_score_adj", pid) - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return 0, err } diff --git a/vendor/github.com/containerd/containerd/sys/oom_unsupported.go b/vendor/github.com/containerd/containerd/sys/oom_unsupported.go index f5d7e9786b..fa0db5a10e 100644 --- a/vendor/github.com/containerd/containerd/sys/oom_unsupported.go +++ b/vendor/github.com/containerd/containerd/sys/oom_unsupported.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux /* diff --git a/vendor/github.com/containerd/containerd/sys/socket_unix.go b/vendor/github.com/containerd/containerd/sys/socket_unix.go index b67cc1fa3a..367e19cad8 100644 --- a/vendor/github.com/containerd/containerd/sys/socket_unix.go +++ b/vendor/github.com/containerd/containerd/sys/socket_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows /* @@ -19,11 +20,11 @@ package sys import ( + "fmt" "net" "os" "path/filepath" - "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -31,7 +32,7 @@ import ( func CreateUnixSocket(path string) (net.Listener, error) { // BSDs have a 104 limit if len(path) > 104 { - return nil, errors.Errorf("%q: unix socket path too long (> 104)", path) + return nil, fmt.Errorf("%q: unix socket path too long (> 104)", path) } if err := os.MkdirAll(filepath.Dir(path), 0660); err != nil { return nil, err diff --git a/vendor/github.com/containerd/containerd/sys/socket_windows.go b/vendor/github.com/containerd/containerd/sys/socket_windows.go index 3ee7679b49..1ae12bc511 100644 --- a/vendor/github.com/containerd/containerd/sys/socket_windows.go +++ b/vendor/github.com/containerd/containerd/sys/socket_windows.go @@ -1,5 +1,3 @@ -// +build windows - /* Copyright The containerd Authors. diff --git a/vendor/github.com/containerd/containerd/sys/stat_bsd.go b/vendor/github.com/containerd/containerd/sys/stat_bsd.go deleted file mode 100644 index 4f03cd6cb0..0000000000 --- a/vendor/github.com/containerd/containerd/sys/stat_bsd.go +++ /dev/null @@ -1,44 +0,0 @@ -// +build darwin freebsd netbsd - -/* - 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 sys - -import ( - "syscall" - "time" -) - -// StatAtime returns the access time from a stat struct -func StatAtime(st *syscall.Stat_t) syscall.Timespec { - return st.Atimespec -} - -// StatCtime returns the created time from a stat struct -func StatCtime(st *syscall.Stat_t) syscall.Timespec { - return st.Ctimespec -} - -// StatMtime returns the modified time from a stat struct -func StatMtime(st *syscall.Stat_t) syscall.Timespec { - return st.Mtimespec -} - -// StatATimeAsTime returns the access time as a time.Time -func StatATimeAsTime(st *syscall.Stat_t) time.Time { - return time.Unix(int64(st.Atimespec.Sec), int64(st.Atimespec.Nsec)) // nolint: unconvert -} diff --git a/vendor/github.com/containerd/containerd/sys/stat_openbsd.go b/vendor/github.com/containerd/containerd/sys/stat_openbsd.go deleted file mode 100644 index ec3b9df69a..0000000000 --- a/vendor/github.com/containerd/containerd/sys/stat_openbsd.go +++ /dev/null @@ -1,45 +0,0 @@ -// +build openbsd - -/* - 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 sys - -import ( - "syscall" - "time" -) - -// StatAtime returns the Atim -func StatAtime(st *syscall.Stat_t) syscall.Timespec { - return st.Atim -} - -// StatCtime returns the Ctim -func StatCtime(st *syscall.Stat_t) syscall.Timespec { - return st.Ctim -} - -// StatMtime returns the Mtim -func StatMtime(st *syscall.Stat_t) syscall.Timespec { - return st.Mtim -} - -// StatATimeAsTime returns st.Atim as a time.Time -func StatATimeAsTime(st *syscall.Stat_t) time.Time { - // The int64 conversions ensure the line compiles for 32-bit systems as well. - return time.Unix(int64(st.Atim.Sec), int64(st.Atim.Nsec)) // nolint: unconvert -} diff --git a/vendor/github.com/containerd/containerd/task.go b/vendor/github.com/containerd/containerd/task.go index 4e23fb8616..692d92c1d2 100644 --- a/vendor/github.com/containerd/containerd/task.go +++ b/vendor/github.com/containerd/containerd/task.go @@ -20,6 +20,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io" goruntime "runtime" @@ -46,7 +47,6 @@ import ( is "github.com/opencontainers/image-spec/specs-go" v1 "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" ) // UnknownExitStatus is returned when containerd is unable to @@ -312,7 +312,7 @@ func (t *task) Delete(ctx context.Context, opts ...ProcessDeleteOpts) (*ExitStat } fallthrough default: - return nil, errors.Wrapf(errdefs.ErrFailedPrecondition, "task must be stopped before deletion: %s", status.Status) + return nil, fmt.Errorf("task must be stopped before deletion: %s: %w", status.Status, errdefs.ErrFailedPrecondition) } if t.io != nil { t.io.Close() @@ -334,7 +334,7 @@ func (t *task) Delete(ctx context.Context, opts ...ProcessDeleteOpts) (*ExitStat func (t *task) Exec(ctx context.Context, id string, spec *specs.Process, ioCreate cio.Creator) (_ Process, err error) { if id == "" { - return nil, errors.Wrapf(errdefs.ErrInvalidArgument, "exec id must not be empty") + return nil, fmt.Errorf("exec id must not be empty: %w", errdefs.ErrInvalidArgument) } i, err := ioCreate(id) if err != nil { @@ -555,7 +555,7 @@ func (t *task) LoadProcess(ctx context.Context, id string, ioAttach cio.Attach) if err != nil { err = errdefs.FromGRPC(err) if errdefs.IsNotFound(err) { - return nil, errors.Wrapf(err, "no running process found") + return nil, fmt.Errorf("no running process found: %w", err) } return nil, err } diff --git a/vendor/github.com/containerd/containerd/task_opts.go b/vendor/github.com/containerd/containerd/task_opts.go index e8d99eb512..56f3cbad60 100644 --- a/vendor/github.com/containerd/containerd/task_opts.go +++ b/vendor/github.com/containerd/containerd/task_opts.go @@ -19,6 +19,7 @@ package containerd import ( "context" "encoding/json" + "errors" "fmt" "syscall" @@ -31,7 +32,6 @@ import ( "github.com/containerd/containerd/runtime/v2/runc/options" imagespec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" ) // NewTaskOpts allows the caller to set options on a new task @@ -45,6 +45,15 @@ func WithRootFS(mounts []mount.Mount) NewTaskOpts { } } +// WithRuntimePath will force task service to use a custom path to the runtime binary +// instead of resolving it from runtime name. +func WithRuntimePath(absRuntimePath string) NewTaskOpts { + return func(ctx context.Context, client *Client, info *TaskInfo) error { + info.runtime = absRuntimePath + return nil + } +} + // WithTaskCheckpoint allows a task to be created with live runtime and memory data from a // previous checkpoint. Additional software such as CRIU may be required to // restore a task from a checkpoint @@ -158,7 +167,17 @@ func WithProcessKill(ctx context.Context, p Process) error { return err } if err := p.Kill(ctx, syscall.SIGKILL, WithKillAll); err != nil { - if errdefs.IsFailedPrecondition(err) || errdefs.IsNotFound(err) { + // Kill might still return an IsNotFound error, even if it actually + // killed the process. + if errdefs.IsNotFound(err) { + select { + case <-ctx.Done(): + return ctx.Err() + case <-s: + return nil + } + } + if errdefs.IsFailedPrecondition(err) { return nil } return err diff --git a/vendor/github.com/containerd/containerd/task_opts_unix.go b/vendor/github.com/containerd/containerd/task_opts_unix.go index a710b358fc..1d5983b629 100644 --- a/vendor/github.com/containerd/containerd/task_opts_unix.go +++ b/vendor/github.com/containerd/containerd/task_opts_unix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows /* @@ -20,10 +21,10 @@ package containerd import ( "context" + "errors" "github.com/containerd/containerd/runtime/linux/runctypes" "github.com/containerd/containerd/runtime/v2/runc/options" - "github.com/pkg/errors" ) // WithNoNewKeyring causes tasks not to be created with a new keyring for secret storage. diff --git a/vendor/github.com/containerd/containerd/unpacker.go b/vendor/github.com/containerd/containerd/unpacker.go index 76f5d7b0c4..719345a1c2 100644 --- a/vendor/github.com/containerd/containerd/unpacker.go +++ b/vendor/github.com/containerd/containerd/unpacker.go @@ -20,6 +20,7 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "math/rand" "sync" @@ -36,7 +37,6 @@ import ( "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/identity" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" "golang.org/x/sync/semaphore" @@ -65,11 +65,16 @@ func (c *Client) newUnpacker(ctx context.Context, rCtx *RemoteContext) (*unpacke return nil, err } } + var limiter *semaphore.Weighted + if rCtx.MaxConcurrentDownloads > 0 { + limiter = semaphore.NewWeighted(int64(rCtx.MaxConcurrentDownloads)) + } return &unpacker{ updateCh: make(chan ocispec.Descriptor, 128), snapshotter: snapshotter, config: config, c: c, + limiter: limiter, }, nil } @@ -87,18 +92,18 @@ func (u *unpacker) unpack( var i ocispec.Image if err := json.Unmarshal(p, &i); err != nil { - return errors.Wrap(err, "unmarshal image config") + return fmt.Errorf("unmarshal image config: %w", err) } diffIDs := i.RootFS.DiffIDs if len(layers) != len(diffIDs) { - return errors.Errorf("number of layers and diffIDs don't match: %d != %d", len(layers), len(diffIDs)) + return fmt.Errorf("number of layers and diffIDs don't match: %d != %d", len(layers), len(diffIDs)) } if u.config.CheckPlatformSupported { imgPlatform := platforms.Normalize(ocispec.Platform{OS: i.OS, Architecture: i.Architecture}) snapshotterPlatformMatcher, err := u.c.GetSnapshotterSupportedPlatforms(ctx, u.snapshotter) if err != nil { - return errors.Wrapf(err, "failed to find supported platforms for snapshotter %s", u.snapshotter) + return fmt.Errorf("failed to find supported platforms for snapshotter %s: %w", u.snapshotter, err) } if !snapshotterPlatformMatcher.Match(imgPlatform) { return fmt.Errorf("snapshotter %s does not support platform %s for image %s", u.snapshotter, imgPlatform, config.Digest) @@ -132,7 +137,7 @@ EachLayer: // no need to handle continue } else if !errdefs.IsNotFound(err) { - return errors.Wrapf(err, "failed to stat snapshot %s", chainID) + return fmt.Errorf("failed to stat snapshot %s: %w", chainID, err) } // inherits annotations which are provided as snapshot labels. @@ -156,7 +161,7 @@ EachLayer: if errdefs.IsAlreadyExists(err) { if _, err := sn.Stat(ctx, chainID); err != nil { if !errdefs.IsNotFound(err) { - return errors.Wrapf(err, "failed to stat snapshot %s", chainID) + return fmt.Errorf("failed to stat snapshot %s: %w", chainID, err) } // Try again, this should be rare, log it log.G(ctx).WithField("key", key).WithField("chainid", chainID).Debug("extraction snapshot already exists, chain id not found") @@ -165,14 +170,14 @@ EachLayer: continue EachLayer } } else { - return errors.Wrapf(err, "failed to prepare extraction snapshot %q", key) + return fmt.Errorf("failed to prepare extraction snapshot %q: %w", key, err) } } else { break } } if err != nil { - return errors.Wrap(err, "unable to prepare extraction snapshot") + return fmt.Errorf("unable to prepare extraction snapshot: %w", err) } // Abort the snapshot if commit does not happen @@ -212,11 +217,11 @@ EachLayer: diff, err := a.Apply(ctx, desc, mounts, u.config.ApplyOpts...) if err != nil { abort() - return errors.Wrapf(err, "failed to extract layer %s", diffIDs[i]) + return fmt.Errorf("failed to extract layer %s: %w", diffIDs[i], err) } if diff.Digest != diffIDs[i] { abort() - return errors.Errorf("wrong diff id calculated on extraction %q", diffIDs[i]) + return fmt.Errorf("wrong diff id calculated on extraction %q", diffIDs[i]) } if err = sn.Commit(ctx, chainID, key, opts...); err != nil { @@ -224,7 +229,7 @@ EachLayer: if errdefs.IsAlreadyExists(err) { continue } - return errors.Wrapf(err, "failed to commit snapshot %s", key) + return fmt.Errorf("failed to commit snapshot %s: %w", key, err) } // Set the uncompressed label after the uncompressed diff --git a/vendor/github.com/containerd/containerd/version/version.go b/vendor/github.com/containerd/containerd/version/version.go index 73857aef8d..a92784ef81 100644 --- a/vendor/github.com/containerd/containerd/version/version.go +++ b/vendor/github.com/containerd/containerd/version/version.go @@ -23,7 +23,7 @@ var ( Package = "github.com/containerd/containerd" // Version holds the complete version number. Filled in at linking time. - Version = "1.5.10+unknown" + Version = "1.6.1+unknown" // Revision is filled with the VCS (e.g. git) revision being used to build // the program at linking time. diff --git a/vendor/github.com/prometheus/common/expfmt/decode.go b/vendor/github.com/prometheus/common/expfmt/decode.go index c092723e84..7657f841d6 100644 --- a/vendor/github.com/prometheus/common/expfmt/decode.go +++ b/vendor/github.com/prometheus/common/expfmt/decode.go @@ -164,7 +164,7 @@ func (sd *SampleDecoder) Decode(s *model.Vector) error { } // ExtractSamples builds a slice of samples from the provided metric -// families. If an error occurrs during sample extraction, it continues to +// families. If an error occurs during sample extraction, it continues to // extract from the remaining metric families. The returned error is the last // error that has occurred. func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) (model.Vector, error) { diff --git a/vendor/github.com/prometheus/common/expfmt/encode.go b/vendor/github.com/prometheus/common/expfmt/encode.go index bd4e347454..64dc0eb40c 100644 --- a/vendor/github.com/prometheus/common/expfmt/encode.go +++ b/vendor/github.com/prometheus/common/expfmt/encode.go @@ -18,7 +18,7 @@ import ( "io" "net/http" - "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/proto" //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/matttproud/golang_protobuf_extensions/pbutil" "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" diff --git a/vendor/github.com/prometheus/common/expfmt/text_parse.go b/vendor/github.com/prometheus/common/expfmt/text_parse.go index 342e5940d0..84be0643ec 100644 --- a/vendor/github.com/prometheus/common/expfmt/text_parse.go +++ b/vendor/github.com/prometheus/common/expfmt/text_parse.go @@ -24,7 +24,7 @@ import ( dto "github.com/prometheus/client_model/go" - "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/proto" //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/prometheus/common/model" ) @@ -299,6 +299,17 @@ func (p *TextParser) startLabelName() stateFn { p.parseError(fmt.Sprintf("expected '=' after label name, found %q", p.currentByte)) return nil } + // Check for duplicate label names. + labels := make(map[string]struct{}) + for _, l := range p.currentMetric.Label { + lName := l.GetName() + if _, exists := labels[lName]; !exists { + labels[lName] = struct{}{} + } else { + p.parseError(fmt.Sprintf("duplicate label names for metric %q", p.currentMF.GetName())) + return nil + } + } return p.startLabelValue } diff --git a/vendor/github.com/prometheus/common/model/fnv.go b/vendor/github.com/prometheus/common/model/fnv.go index 038fc1c900..367afecd30 100644 --- a/vendor/github.com/prometheus/common/model/fnv.go +++ b/vendor/github.com/prometheus/common/model/fnv.go @@ -20,7 +20,7 @@ const ( prime64 = 1099511628211 ) -// hashNew initializies a new fnv64a hash value. +// hashNew initializes a new fnv64a hash value. func hashNew() uint64 { return offset64 } diff --git a/vendor/github.com/prometheus/common/model/labels.go b/vendor/github.com/prometheus/common/model/labels.go index 41051a01a3..ef89563354 100644 --- a/vendor/github.com/prometheus/common/model/labels.go +++ b/vendor/github.com/prometheus/common/model/labels.go @@ -45,6 +45,14 @@ const ( // scrape a target. MetricsPathLabel = "__metrics_path__" + // ScrapeIntervalLabel is the name of the label that holds the scrape interval + // used to scrape a target. + ScrapeIntervalLabel = "__scrape_interval__" + + // ScrapeTimeoutLabel is the name of the label that holds the scrape + // timeout used to scrape a target. + ScrapeTimeoutLabel = "__scrape_timeout__" + // ReservedLabelPrefix is a prefix which is not legal in user-supplied // label names. ReservedLabelPrefix = "__" diff --git a/vendor/github.com/prometheus/common/model/time.go b/vendor/github.com/prometheus/common/model/time.go index 490a0240c1..7f67b16e42 100644 --- a/vendor/github.com/prometheus/common/model/time.go +++ b/vendor/github.com/prometheus/common/model/time.go @@ -14,6 +14,8 @@ package model import ( + "encoding/json" + "errors" "fmt" "math" "regexp" @@ -181,77 +183,118 @@ func (d *Duration) Type() string { return "duration" } -var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$") +var durationRE = regexp.MustCompile("^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$") // ParseDuration parses a string into a time.Duration, assuming that a year // always has 365d, a week always has 7d, and a day always has 24h. func ParseDuration(durationStr string) (Duration, error) { - // Allow 0 without a unit. - if durationStr == "0" { + switch durationStr { + case "0": + // Allow 0 without a unit. return 0, nil + case "": + return 0, fmt.Errorf("empty duration string") } matches := durationRE.FindStringSubmatch(durationStr) - if len(matches) != 3 { + if matches == nil { return 0, fmt.Errorf("not a valid duration string: %q", durationStr) } - var ( - n, _ = strconv.Atoi(matches[1]) - dur = time.Duration(n) * time.Millisecond - ) - switch unit := matches[2]; unit { - case "y": - dur *= 1000 * 60 * 60 * 24 * 365 - case "w": - dur *= 1000 * 60 * 60 * 24 * 7 - case "d": - dur *= 1000 * 60 * 60 * 24 - case "h": - dur *= 1000 * 60 * 60 - case "m": - dur *= 1000 * 60 - case "s": - dur *= 1000 - case "ms": - // Value already correct - default: - return 0, fmt.Errorf("invalid time unit in duration string: %q", unit) + var dur time.Duration + + // Parse the match at pos `pos` in the regex and use `mult` to turn that + // into ms, then add that value to the total parsed duration. + var overflowErr error + m := func(pos int, mult time.Duration) { + if matches[pos] == "" { + return + } + n, _ := strconv.Atoi(matches[pos]) + + // Check if the provided duration overflows time.Duration (> ~ 290years). + if n > int((1<<63-1)/mult/time.Millisecond) { + overflowErr = errors.New("duration out of range") + } + d := time.Duration(n) * time.Millisecond + dur += d * mult + + if dur < 0 { + overflowErr = errors.New("duration out of range") + } } - return Duration(dur), nil + + m(2, 1000*60*60*24*365) // y + m(4, 1000*60*60*24*7) // w + m(6, 1000*60*60*24) // d + m(8, 1000*60*60) // h + m(10, 1000*60) // m + m(12, 1000) // s + m(14, 1) // ms + + return Duration(dur), overflowErr } func (d Duration) String() string { var ( - ms = int64(time.Duration(d) / time.Millisecond) - unit = "ms" + ms = int64(time.Duration(d) / time.Millisecond) + r = "" ) if ms == 0 { return "0s" } - factors := map[string]int64{ - "y": 1000 * 60 * 60 * 24 * 365, - "w": 1000 * 60 * 60 * 24 * 7, - "d": 1000 * 60 * 60 * 24, - "h": 1000 * 60 * 60, - "m": 1000 * 60, - "s": 1000, - "ms": 1, + + f := func(unit string, mult int64, exact bool) { + if exact && ms%mult != 0 { + return + } + if v := ms / mult; v > 0 { + r += fmt.Sprintf("%d%s", v, unit) + ms -= v * mult + } } - switch int64(0) { - case ms % factors["y"]: - unit = "y" - case ms % factors["w"]: - unit = "w" - case ms % factors["d"]: - unit = "d" - case ms % factors["h"]: - unit = "h" - case ms % factors["m"]: - unit = "m" - case ms % factors["s"]: - unit = "s" + // Only format years and weeks if the remainder is zero, as it is often + // easier to read 90d than 12w6d. + f("y", 1000*60*60*24*365, true) + f("w", 1000*60*60*24*7, true) + + f("d", 1000*60*60*24, false) + f("h", 1000*60*60, false) + f("m", 1000*60, false) + f("s", 1000, false) + f("ms", 1, false) + + return r +} + +// MarshalJSON implements the json.Marshaler interface. +func (d Duration) MarshalJSON() ([]byte, error) { + return json.Marshal(d.String()) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (d *Duration) UnmarshalJSON(bytes []byte) error { + var s string + if err := json.Unmarshal(bytes, &s); err != nil { + return err } - return fmt.Sprintf("%v%v", ms/factors[unit], unit) + dur, err := ParseDuration(s) + if err != nil { + return err + } + *d = dur + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (d *Duration) MarshalText() ([]byte, error) { + return []byte(d.String()), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (d *Duration) UnmarshalText(text []byte) error { + var err error + *d, err = ParseDuration(string(text)) + return err } // MarshalYAML implements the yaml.Marshaler interface. diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index c67e9b7f55..e644d9b2f3 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -719,7 +719,15 @@ func (sc *serverConn) canonicalHeader(v string) string { sc.canonHeader = make(map[string]string) } cv = http.CanonicalHeaderKey(v) - sc.canonHeader[v] = cv + // maxCachedCanonicalHeaders is an arbitrarily-chosen limit on the number of + // entries in the canonHeader cache. This should be larger than the number + // of unique, uncommon header keys likely to be sent by the peer, while not + // so high as to permit unreasonable memory usage if the peer sends an unbounded + // number of unique header keys. + const maxCachedCanonicalHeaders = 32 + if len(sc.canonHeader) < maxCachedCanonicalHeaders { + sc.canonHeader[v] = cv + } return cv } diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index b5e2ac64d4..f135b0f751 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -1124,36 +1124,49 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { } } + handleResponseHeaders := func() (*http.Response, error) { + res := cs.res + if res.StatusCode > 299 { + // On error or status code 3xx, 4xx, 5xx, etc abort any + // ongoing write, assuming that the server doesn't care + // about our request body. If the server replied with 1xx or + // 2xx, however, then assume the server DOES potentially + // want our body (e.g. full-duplex streaming: + // golang.org/issue/13444). If it turns out the server + // doesn't, they'll RST_STREAM us soon enough. This is a + // heuristic to avoid adding knobs to Transport. Hopefully + // we can keep it. + cs.abortRequestBodyWrite() + } + res.Request = req + res.TLS = cc.tlsState + if res.Body == noBody && actualContentLength(req) == 0 { + // If there isn't a request or response body still being + // written, then wait for the stream to be closed before + // RoundTrip returns. + if err := waitDone(); err != nil { + return nil, err + } + } + return res, nil + } + for { select { case <-cs.respHeaderRecv: - res := cs.res - if res.StatusCode > 299 { - // On error or status code 3xx, 4xx, 5xx, etc abort any - // ongoing write, assuming that the server doesn't care - // about our request body. If the server replied with 1xx or - // 2xx, however, then assume the server DOES potentially - // want our body (e.g. full-duplex streaming: - // golang.org/issue/13444). If it turns out the server - // doesn't, they'll RST_STREAM us soon enough. This is a - // heuristic to avoid adding knobs to Transport. Hopefully - // we can keep it. - cs.abortRequestBodyWrite() - } - res.Request = req - res.TLS = cc.tlsState - if res.Body == noBody && actualContentLength(req) == 0 { - // If there isn't a request or response body still being - // written, then wait for the stream to be closed before - // RoundTrip returns. - if err := waitDone(); err != nil { - return nil, err - } - } - return res, nil + return handleResponseHeaders() case <-cs.abort: - waitDone() - return nil, cs.abortErr + select { + case <-cs.respHeaderRecv: + // If both cs.respHeaderRecv and cs.abort are signaling, + // pick respHeaderRecv. The server probably wrote the + // response and immediately reset the stream. + // golang.org/issue/49645 + return handleResponseHeaders() + default: + waitDone() + return nil, cs.abortErr + } case <-ctx.Done(): err := ctx.Err() cs.abortStream(err) @@ -1239,12 +1252,12 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { } continueTimeout := cc.t.expectContinueTimeout() - if continueTimeout != 0 && - !httpguts.HeaderValuesContainsToken( - req.Header["Expect"], - "100-continue") { - continueTimeout = 0 - cs.on100 = make(chan struct{}, 1) + if continueTimeout != 0 { + if !httpguts.HeaderValuesContainsToken(req.Header["Expect"], "100-continue") { + continueTimeout = 0 + } else { + cs.on100 = make(chan struct{}, 1) + } } // Past this point (where we send request headers), it is possible for @@ -1313,6 +1326,7 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) { case <-respHeaderTimer: return errTimeout case <-respHeaderRecv: + respHeaderRecv = nil respHeaderTimer = nil // keep waiting for END_STREAM case <-cs.abort: return cs.abortErr diff --git a/vendor/golang.org/x/net/http2/writesched.go b/vendor/golang.org/x/net/http2/writesched.go index f24d2b1e7d..c7cd001739 100644 --- a/vendor/golang.org/x/net/http2/writesched.go +++ b/vendor/golang.org/x/net/http2/writesched.go @@ -32,7 +32,8 @@ type WriteScheduler interface { // Pop dequeues the next frame to write. Returns false if no frames can // be written. Frames with a given wr.StreamID() are Pop'd in the same - // order they are Push'd. No frames should be discarded except by CloseStream. + // order they are Push'd, except RST_STREAM frames. No frames should be + // discarded except by CloseStream. Pop() (wr FrameWriteRequest, ok bool) } @@ -52,6 +53,7 @@ type FrameWriteRequest struct { // stream is the stream on which this frame will be written. // nil for non-stream frames like PING and SETTINGS. + // nil for RST_STREAM streams, which use the StreamError.StreamID field instead. stream *stream // done, if non-nil, must be a buffered channel with space for diff --git a/vendor/golang.org/x/net/http2/writesched_random.go b/vendor/golang.org/x/net/http2/writesched_random.go index 9a7b9e581c..f2e55e05ce 100644 --- a/vendor/golang.org/x/net/http2/writesched_random.go +++ b/vendor/golang.org/x/net/http2/writesched_random.go @@ -45,11 +45,11 @@ func (ws *randomWriteScheduler) AdjustStream(streamID uint32, priority PriorityP } func (ws *randomWriteScheduler) Push(wr FrameWriteRequest) { - id := wr.StreamID() - if id == 0 { + if wr.isControl() { ws.zero.push(wr) return } + id := wr.StreamID() q, ok := ws.sq[id] if !ok { q = ws.queuePool.get() @@ -59,7 +59,7 @@ func (ws *randomWriteScheduler) Push(wr FrameWriteRequest) { } func (ws *randomWriteScheduler) Pop() (FrameWriteRequest, bool) { - // Control frames first. + // Control and RST_STREAM frames first. if !ws.zero.empty() { return ws.zero.shift(), true } diff --git a/vendor/golang.org/x/net/internal/socket/sys_bsd.go b/vendor/golang.org/x/net/internal/socket/sys_bsd.go index b6cd77088d..b258879d44 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_bsd.go +++ b/vendor/golang.org/x/net/internal/socket/sys_bsd.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build aix || darwin || dragonfly || freebsd || openbsd -// +build aix darwin dragonfly freebsd openbsd +//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris +// +build aix darwin dragonfly freebsd openbsd solaris package socket diff --git a/vendor/golang.org/x/net/internal/socket/sys_linkname.go b/vendor/golang.org/x/net/internal/socket/sys_linkname.go deleted file mode 100644 index 21734af4b8..0000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linkname.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || (go1.12 && darwin) -// +build aix go1.12,darwin - -package socket - -import ( - "syscall" - "unsafe" -) - -//go:linkname syscall_getsockopt syscall.getsockopt -func syscall_getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *uint32) error - -func getsockopt(s uintptr, level, name int, b []byte) (int, error) { - l := uint32(len(b)) - err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l) - return int(l), err -} - -//go:linkname syscall_setsockopt syscall.setsockopt -func syscall_setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) error - -func setsockopt(s uintptr, level, name int, b []byte) error { - return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b))) -} - -//go:linkname syscall_recvmsg syscall.recvmsg -func syscall_recvmsg(s int, msg *syscall.Msghdr, flags int) (n int, err error) - -func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - return syscall_recvmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags) -} - -//go:linkname syscall_sendmsg syscall.sendmsg -func syscall_sendmsg(s int, msg *syscall.Msghdr, flags int) (n int, err error) - -func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { - return syscall_sendmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags) -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_386.go b/vendor/golang.org/x/net/internal/socket/sys_linux_386.go index 651215321b..c877ef23ae 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_386.go +++ b/vendor/golang.org/x/net/internal/socket/sys_linux_386.go @@ -10,38 +10,13 @@ import ( ) const ( - sysSETSOCKOPT = 0xe - sysGETSOCKOPT = 0xf - sysSENDMSG = 0x10 - sysRECVMSG = 0x11 - sysRECVMMSG = 0x13 - sysSENDMMSG = 0x14 + sysRECVMMSG = 0x13 + sysSENDMMSG = 0x14 ) func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno) func rawsocketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno) -func getsockopt(s uintptr, level, name int, b []byte) (int, error) { - l := uint32(len(b)) - _, errno := socketcall(sysGETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0) - return int(l), errnoErr(errno) -} - -func setsockopt(s uintptr, level, name int, b []byte) error { - _, errno := socketcall(sysSETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0) - return errnoErr(errno) -} - -func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - n, errno := socketcall(sysRECVMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags), 0, 0, 0) - return int(n), errnoErr(errno) -} - -func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { - n, errno := socketcall(sysSENDMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags), 0, 0, 0) - return int(n), errnoErr(errno) -} - func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { n, errno := socketcall(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0) return int(n), errnoErr(errno) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go b/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go index 651215321b..c877ef23ae 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go +++ b/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go @@ -10,38 +10,13 @@ import ( ) const ( - sysSETSOCKOPT = 0xe - sysGETSOCKOPT = 0xf - sysSENDMSG = 0x10 - sysRECVMSG = 0x11 - sysRECVMMSG = 0x13 - sysSENDMMSG = 0x14 + sysRECVMMSG = 0x13 + sysSENDMMSG = 0x14 ) func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno) func rawsocketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno) -func getsockopt(s uintptr, level, name int, b []byte) (int, error) { - l := uint32(len(b)) - _, errno := socketcall(sysGETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0) - return int(l), errnoErr(errno) -} - -func setsockopt(s uintptr, level, name int, b []byte) error { - _, errno := socketcall(sysSETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0) - return errnoErr(errno) -} - -func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - n, errno := socketcall(sysRECVMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags), 0, 0, 0) - return int(n), errnoErr(errno) -} - -func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { - n, errno := socketcall(sysSENDMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags), 0, 0, 0) - return int(n), errnoErr(errno) -} - func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { n, errno := socketcall(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0) return int(n), errnoErr(errno) diff --git a/vendor/golang.org/x/net/internal/socket/sys_solaris.go b/vendor/golang.org/x/net/internal/socket/sys_solaris.go deleted file mode 100644 index e79ca95183..0000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_solaris.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -import ( - "syscall" - "unsafe" -) - -//go:cgo_import_dynamic libc___xnet_getsockopt __xnet_getsockopt "libsocket.so" -//go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so" -//go:cgo_import_dynamic libc___xnet_recvmsg __xnet_recvmsg "libsocket.so" -//go:cgo_import_dynamic libc___xnet_sendmsg __xnet_sendmsg "libsocket.so" - -//go:linkname procGetsockopt libc___xnet_getsockopt -//go:linkname procSetsockopt libc_setsockopt -//go:linkname procRecvmsg libc___xnet_recvmsg -//go:linkname procSendmsg libc___xnet_sendmsg - -var ( - procGetsockopt uintptr - procSetsockopt uintptr - procRecvmsg uintptr - procSendmsg uintptr -) - -func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (uintptr, uintptr, syscall.Errno) -func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (uintptr, uintptr, syscall.Errno) - -func getsockopt(s uintptr, level, name int, b []byte) (int, error) { - l := uint32(len(b)) - _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procGetsockopt)), 5, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0) - return int(l), errnoErr(errno) -} - -func setsockopt(s uintptr, level, name int, b []byte) error { - _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procSetsockopt)), 5, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0) - return errnoErr(errno) -} - -func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - n, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procRecvmsg)), 3, s, uintptr(unsafe.Pointer(h)), uintptr(flags), 0, 0, 0) - return int(n), errnoErr(errno) -} - -func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { - n, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procSendmsg)), 3, s, uintptr(unsafe.Pointer(h)), uintptr(flags), 0, 0, 0) - return int(n), errnoErr(errno) -} - -func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errNotImplemented -} - -func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errNotImplemented -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_solaris_amd64.s b/vendor/golang.org/x/net/internal/socket/sys_solaris_amd64.s deleted file mode 100644 index a18ac5ed75..0000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_solaris_amd64.s +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "textflag.h" - -TEXT ·sysvicall6(SB),NOSPLIT,$0-88 - JMP syscall·sysvicall6(SB) - -TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88 - JMP syscall·rawSysvicall6(SB) diff --git a/vendor/golang.org/x/net/internal/socket/sys_unix.go b/vendor/golang.org/x/net/internal/socket/sys_unix.go index c98ebae548..d203e2984c 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_unix.go +++ b/vendor/golang.org/x/net/internal/socket/sys_unix.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build dragonfly || freebsd || (linux && !s390x && !386) || netbsd || openbsd -// +build dragonfly freebsd linux,!s390x,!386 netbsd openbsd +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris package socket @@ -12,23 +12,32 @@ import ( "unsafe" ) +//go:linkname syscall_getsockopt syscall.getsockopt +func syscall_getsockopt(s, level, name int, val unsafe.Pointer, vallen *uint32) error + +//go:linkname syscall_setsockopt syscall.setsockopt +func syscall_setsockopt(s, level, name int, val unsafe.Pointer, vallen uintptr) error + +//go:linkname syscall_recvmsg syscall.recvmsg +func syscall_recvmsg(s int, msg *syscall.Msghdr, flags int) (int, error) + +//go:linkname syscall_sendmsg syscall.sendmsg +func syscall_sendmsg(s int, msg *syscall.Msghdr, flags int) (int, error) + func getsockopt(s uintptr, level, name int, b []byte) (int, error) { l := uint32(len(b)) - _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0) - return int(l), errnoErr(errno) + err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l) + return int(l), err } func setsockopt(s uintptr, level, name int, b []byte) error { - _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0) - return errnoErr(errno) + return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b))) } func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - n, _, errno := syscall.Syscall(syscall.SYS_RECVMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags)) - return int(n), errnoErr(errno) + return syscall_recvmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags) } func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { - n, _, errno := syscall.Syscall(syscall.SYS_SENDMSG, s, uintptr(unsafe.Pointer(h)), uintptr(flags)) - return int(n), errnoErr(errno) + return syscall_sendmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags) } diff --git a/vendor/google.golang.org/grpc/MAINTAINERS.md b/vendor/google.golang.org/grpc/MAINTAINERS.md index 093c82b3af..c6672c0a3e 100644 --- a/vendor/google.golang.org/grpc/MAINTAINERS.md +++ b/vendor/google.golang.org/grpc/MAINTAINERS.md @@ -8,17 +8,18 @@ See [CONTRIBUTING.md](https://github.com/grpc/grpc-community/blob/master/CONTRIB for general contribution guidelines. ## Maintainers (in alphabetical order) -- [canguler](https://github.com/canguler), Google LLC + - [cesarghali](https://github.com/cesarghali), Google LLC - [dfawley](https://github.com/dfawley), Google LLC - [easwars](https://github.com/easwars), Google LLC -- [jadekler](https://github.com/jadekler), Google LLC - [menghanl](https://github.com/menghanl), Google LLC - [srini100](https://github.com/srini100), Google LLC ## Emeritus Maintainers (in alphabetical order) - [adelez](https://github.com/adelez), Google LLC +- [canguler](https://github.com/canguler), Google LLC - [iamqizhao](https://github.com/iamqizhao), Google LLC +- [jadekler](https://github.com/jadekler), Google LLC - [jtattermusch](https://github.com/jtattermusch), Google LLC - [lyuxuan](https://github.com/lyuxuan), Google LLC - [makmukhi](https://github.com/makmukhi), Google LLC diff --git a/vendor/google.golang.org/grpc/Makefile b/vendor/google.golang.org/grpc/Makefile index 1f0722f162..1f8960922b 100644 --- a/vendor/google.golang.org/grpc/Makefile +++ b/vendor/google.golang.org/grpc/Makefile @@ -41,8 +41,6 @@ vetdeps: clean \ proto \ test \ - testappengine \ - testappenginedeps \ testrace \ vet \ vetdeps diff --git a/vendor/google.golang.org/grpc/NOTICE.txt b/vendor/google.golang.org/grpc/NOTICE.txt new file mode 100644 index 0000000000..530197749e --- /dev/null +++ b/vendor/google.golang.org/grpc/NOTICE.txt @@ -0,0 +1,13 @@ +Copyright 2014 gRPC 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. diff --git a/vendor/google.golang.org/grpc/attributes/attributes.go b/vendor/google.golang.org/grpc/attributes/attributes.go index 3220d87be4..6ff2792ee4 100644 --- a/vendor/google.golang.org/grpc/attributes/attributes.go +++ b/vendor/google.golang.org/grpc/attributes/attributes.go @@ -25,55 +25,75 @@ // later release. package attributes -import "fmt" - // Attributes is an immutable struct for storing and retrieving generic // key/value pairs. Keys must be hashable, and users should define their own -// types for keys. +// types for keys. Values should not be modified after they are added to an +// Attributes or if they were received from one. If values implement 'Equal(o +// interface{}) bool', it will be called by (*Attributes).Equal to determine +// whether two values with the same key should be considered equal. type Attributes struct { m map[interface{}]interface{} } -// New returns a new Attributes containing all key/value pairs in kvs. If the -// same key appears multiple times, the last value overwrites all previous -// values for that key. Panics if len(kvs) is not even. -func New(kvs ...interface{}) *Attributes { - if len(kvs)%2 != 0 { - panic(fmt.Sprintf("attributes.New called with unexpected input: len(kvs) = %v", len(kvs))) - } - a := &Attributes{m: make(map[interface{}]interface{}, len(kvs)/2)} - for i := 0; i < len(kvs)/2; i++ { - a.m[kvs[i*2]] = kvs[i*2+1] - } - return a +// New returns a new Attributes containing the key/value pair. +func New(key, value interface{}) *Attributes { + return &Attributes{m: map[interface{}]interface{}{key: value}} } -// WithValues returns a new Attributes containing all key/value pairs in a and -// kvs. Panics if len(kvs) is not even. If the same key appears multiple -// times, the last value overwrites all previous values for that key. To -// remove an existing key, use a nil value. -func (a *Attributes) WithValues(kvs ...interface{}) *Attributes { +// WithValue returns a new Attributes containing the previous keys and values +// and the new key/value pair. If the same key appears multiple times, the +// last value overwrites all previous values for that key. To remove an +// existing key, use a nil value. value should not be modified later. +func (a *Attributes) WithValue(key, value interface{}) *Attributes { if a == nil { - return New(kvs...) + return New(key, value) } - if len(kvs)%2 != 0 { - panic(fmt.Sprintf("attributes.New called with unexpected input: len(kvs) = %v", len(kvs))) - } - n := &Attributes{m: make(map[interface{}]interface{}, len(a.m)+len(kvs)/2)} + n := &Attributes{m: make(map[interface{}]interface{}, len(a.m)+1)} for k, v := range a.m { n.m[k] = v } - for i := 0; i < len(kvs)/2; i++ { - n.m[kvs[i*2]] = kvs[i*2+1] - } + n.m[key] = value return n } // Value returns the value associated with these attributes for key, or nil if -// no value is associated with key. +// no value is associated with key. The returned value should not be modified. func (a *Attributes) Value(key interface{}) interface{} { if a == nil { return nil } return a.m[key] } + +// Equal returns whether a and o are equivalent. If 'Equal(o interface{}) +// bool' is implemented for a value in the attributes, it is called to +// determine if the value matches the one stored in the other attributes. If +// Equal is not implemented, standard equality is used to determine if the two +// values are equal. +func (a *Attributes) Equal(o *Attributes) bool { + if a == nil && o == nil { + return true + } + if a == nil || o == nil { + return false + } + if len(a.m) != len(o.m) { + return false + } + for k, v := range a.m { + ov, ok := o.m[k] + if !ok { + // o missing element of a + return false + } + if eq, ok := v.(interface{ Equal(o interface{}) bool }); ok { + if !eq.Equal(ov) { + return false + } + } else if v != ov { + // Fallback to a standard equality check if Value is unimplemented. + return false + } + } + return true +} diff --git a/vendor/google.golang.org/grpc/balancer/balancer.go b/vendor/google.golang.org/grpc/balancer/balancer.go index ab531f4c0b..bcc6f5451c 100644 --- a/vendor/google.golang.org/grpc/balancer/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/balancer.go @@ -75,24 +75,26 @@ func Get(name string) Builder { return nil } -// SubConn represents a gRPC sub connection. -// Each sub connection contains a list of addresses. gRPC will -// try to connect to them (in sequence), and stop trying the -// remainder once one connection is successful. +// A SubConn represents a single connection to a gRPC backend service. // -// The reconnect backoff will be applied on the list, not a single address. -// For example, try_on_all_addresses -> backoff -> try_on_all_addresses. +// Each SubConn contains a list of addresses. // -// All SubConns start in IDLE, and will not try to connect. To trigger -// the connecting, Balancers must call Connect. -// When the connection encounters an error, it will reconnect immediately. -// When the connection becomes IDLE, it will not reconnect unless Connect is -// called. +// All SubConns start in IDLE, and will not try to connect. To trigger the +// connecting, Balancers must call Connect. If a connection re-enters IDLE, +// Balancers must call Connect again to trigger a new connection attempt. // -// This interface is to be implemented by gRPC. Users should not need a -// brand new implementation of this interface. For the situations like -// testing, the new implementation should embed this interface. This allows -// gRPC to add new methods to this interface. +// gRPC will try to connect to the addresses in sequence, and stop trying the +// remainder once the first connection is successful. If an attempt to connect +// to all addresses encounters an error, the SubConn will enter +// TRANSIENT_FAILURE for a backoff period, and then transition to IDLE. +// +// Once established, if a connection is lost, the SubConn will transition +// directly to IDLE. +// +// This interface is to be implemented by gRPC. Users should not need their own +// implementation of this interface. For situations like testing, any +// implementations should embed this interface. This allows gRPC to add new +// methods to this interface. type SubConn interface { // UpdateAddresses updates the addresses used in this SubConn. // gRPC checks if currently-connected address is still in the new list. @@ -172,25 +174,32 @@ type ClientConn interface { // BuildOptions contains additional information for Build. type BuildOptions struct { - // DialCreds is the transport credential the Balancer implementation can - // use to dial to a remote load balancer server. The Balancer implementations - // can ignore this if it does not need to talk to another party securely. + // DialCreds is the transport credentials to use when communicating with a + // remote load balancer server. Balancer implementations which do not + // communicate with a remote load balancer server can ignore this field. DialCreds credentials.TransportCredentials - // CredsBundle is the credentials bundle that the Balancer can use. + // CredsBundle is the credentials bundle to use when communicating with a + // remote load balancer server. Balancer implementations which do not + // communicate with a remote load balancer server can ignore this field. CredsBundle credentials.Bundle - // Dialer is the custom dialer the Balancer implementation can use to dial - // to a remote load balancer server. The Balancer implementations - // can ignore this if it doesn't need to talk to remote balancer. + // Dialer is the custom dialer to use when communicating with a remote load + // balancer server. Balancer implementations which do not communicate with a + // remote load balancer server can ignore this field. Dialer func(context.Context, string) (net.Conn, error) - // ChannelzParentID is the entity parent's channelz unique identification number. + // Authority is the server name to use as part of the authentication + // handshake when communicating with a remote load balancer server. Balancer + // implementations which do not communicate with a remote load balancer + // server can ignore this field. + Authority string + // ChannelzParentID is the parent ClientConn's channelz ID. ChannelzParentID int64 // CustomUserAgent is the custom user agent set on the parent ClientConn. // The balancer should set the same custom user agent if it creates a // ClientConn. CustomUserAgent string - // Target contains the parsed address info of the dial target. It is the same resolver.Target as - // passed to the resolver. - // See the documentation for the resolver.Target type for details about what it contains. + // Target contains the parsed address info of the dial target. It is the + // same resolver.Target as passed to the resolver. See the documentation for + // the resolver.Target type for details about what it contains. Target resolver.Target } @@ -326,6 +335,20 @@ type Balancer interface { Close() } +// ExitIdler is an optional interface for balancers to implement. If +// implemented, ExitIdle will be called when ClientConn.Connect is called, if +// the ClientConn is idle. If unimplemented, ClientConn.Connect will cause +// all SubConns to connect. +// +// Notice: it will be required for all balancers to implement this in a future +// release. +type ExitIdler interface { + // ExitIdle instructs the LB policy to reconnect to backends / exit the + // IDLE state, if appropriate and possible. Note that SubConns that enter + // the IDLE state will not reconnect until SubConn.Connect is called. + ExitIdle() +} + // SubConnState describes the state of a SubConn. type SubConnState struct { // ConnectivityState is the connectivity state of the SubConn. @@ -353,8 +376,10 @@ var ErrBadResolverState = errors.New("bad resolver state") // // It's not thread safe. type ConnectivityStateEvaluator struct { - numReady uint64 // Number of addrConns in ready state. - numConnecting uint64 // Number of addrConns in connecting state. + numReady uint64 // Number of addrConns in ready state. + numConnecting uint64 // Number of addrConns in connecting state. + numTransientFailure uint64 // Number of addrConns in transient failure state. + numIdle uint64 // Number of addrConns in idle state. } // RecordTransition records state change happening in subConn and based on that @@ -362,9 +387,11 @@ type ConnectivityStateEvaluator struct { // // - If at least one SubConn in Ready, the aggregated state is Ready; // - Else if at least one SubConn in Connecting, the aggregated state is Connecting; -// - Else the aggregated state is TransientFailure. +// - Else if at least one SubConn is TransientFailure, the aggregated state is Transient Failure; +// - Else if at least one SubConn is Idle, the aggregated state is Idle; +// - Else there are no subconns and the aggregated state is Transient Failure // -// Idle and Shutdown are not considered. +// Shutdown is not considered. func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState connectivity.State) connectivity.State { // Update counters. for idx, state := range []connectivity.State{oldState, newState} { @@ -374,6 +401,10 @@ func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState conne cse.numReady += updateVal case connectivity.Connecting: cse.numConnecting += updateVal + case connectivity.TransientFailure: + cse.numTransientFailure += updateVal + case connectivity.Idle: + cse.numIdle += updateVal } } @@ -384,5 +415,11 @@ func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState conne if cse.numConnecting > 0 { return connectivity.Connecting } + if cse.numTransientFailure > 0 { + return connectivity.TransientFailure + } + if cse.numIdle > 0 { + return connectivity.Idle + } return connectivity.TransientFailure } diff --git a/vendor/google.golang.org/grpc/balancer/base/balancer.go b/vendor/google.golang.org/grpc/balancer/base/balancer.go index c883efa0bb..a67074a3ad 100644 --- a/vendor/google.golang.org/grpc/balancer/base/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/base/balancer.go @@ -22,7 +22,6 @@ import ( "errors" "fmt" - "google.golang.org/grpc/attributes" "google.golang.org/grpc/balancer" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/grpclog" @@ -42,7 +41,7 @@ func (bb *baseBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) cc: cc, pickerBuilder: bb.pickerBuilder, - subConns: make(map[resolver.Address]subConnInfo), + subConns: resolver.NewAddressMap(), scStates: make(map[balancer.SubConn]connectivity.State), csEvltr: &balancer.ConnectivityStateEvaluator{}, config: bb.config, @@ -58,11 +57,6 @@ func (bb *baseBuilder) Name() string { return bb.name } -type subConnInfo struct { - subConn balancer.SubConn - attrs *attributes.Attributes -} - type baseBalancer struct { cc balancer.ClientConn pickerBuilder PickerBuilder @@ -70,7 +64,7 @@ type baseBalancer struct { csEvltr *balancer.ConnectivityStateEvaluator state connectivity.State - subConns map[resolver.Address]subConnInfo // `attributes` is stripped from the keys of this map (the addresses) + subConns *resolver.AddressMap scStates map[balancer.SubConn]connectivity.State picker balancer.Picker config Config @@ -81,7 +75,7 @@ type baseBalancer struct { func (b *baseBalancer) ResolverError(err error) { b.resolverErr = err - if len(b.subConns) == 0 { + if b.subConns.Len() == 0 { b.state = connectivity.TransientFailure } @@ -105,52 +99,29 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error { // Successful resolution; clear resolver error and ensure we return nil. b.resolverErr = nil // addrsSet is the set converted from addrs, it's used for quick lookup of an address. - addrsSet := make(map[resolver.Address]struct{}) + addrsSet := resolver.NewAddressMap() for _, a := range s.ResolverState.Addresses { - // Strip attributes from addresses before using them as map keys. So - // that when two addresses only differ in attributes pointers (but with - // the same attribute content), they are considered the same address. - // - // Note that this doesn't handle the case where the attribute content is - // different. So if users want to set different attributes to create - // duplicate connections to the same backend, it doesn't work. This is - // fine for now, because duplicate is done by setting Metadata today. - // - // TODO: read attributes to handle duplicate connections. - aNoAttrs := a - aNoAttrs.Attributes = nil - addrsSet[aNoAttrs] = struct{}{} - if scInfo, ok := b.subConns[aNoAttrs]; !ok { + addrsSet.Set(a, nil) + if _, ok := b.subConns.Get(a); !ok { // a is a new address (not existing in b.subConns). - // - // When creating SubConn, the original address with attributes is - // passed through. So that connection configurations in attributes - // (like creds) will be used. sc, err := b.cc.NewSubConn([]resolver.Address{a}, balancer.NewSubConnOptions{HealthCheckEnabled: b.config.HealthCheck}) if err != nil { logger.Warningf("base.baseBalancer: failed to create new SubConn: %v", err) continue } - b.subConns[aNoAttrs] = subConnInfo{subConn: sc, attrs: a.Attributes} + b.subConns.Set(a, sc) b.scStates[sc] = connectivity.Idle + b.csEvltr.RecordTransition(connectivity.Shutdown, connectivity.Idle) sc.Connect() - } else { - // Always update the subconn's address in case the attributes - // changed. - // - // The SubConn does a reflect.DeepEqual of the new and old - // addresses. So this is a noop if the current address is the same - // as the old one (including attributes). - scInfo.attrs = a.Attributes - b.subConns[aNoAttrs] = scInfo - b.cc.UpdateAddresses(scInfo.subConn, []resolver.Address{a}) } } - for a, scInfo := range b.subConns { + for _, a := range b.subConns.Keys() { + sci, _ := b.subConns.Get(a) + sc := sci.(balancer.SubConn) // a was removed by resolver. - if _, ok := addrsSet[a]; !ok { - b.cc.RemoveSubConn(scInfo.subConn) - delete(b.subConns, a) + if _, ok := addrsSet.Get(a); !ok { + b.cc.RemoveSubConn(sc) + b.subConns.Delete(a) // Keep the state of this sc in b.scStates until sc's state becomes Shutdown. // The entry will be deleted in UpdateSubConnState. } @@ -192,10 +163,11 @@ func (b *baseBalancer) regeneratePicker() { readySCs := make(map[balancer.SubConn]SubConnInfo) // Filter out all ready SCs from full subConn map. - for addr, scInfo := range b.subConns { - if st, ok := b.scStates[scInfo.subConn]; ok && st == connectivity.Ready { - addr.Attributes = scInfo.attrs - readySCs[scInfo.subConn] = SubConnInfo{Address: addr} + for _, addr := range b.subConns.Keys() { + sci, _ := b.subConns.Get(addr) + sc := sci.(balancer.SubConn) + if st, ok := b.scStates[sc]; ok && st == connectivity.Ready { + readySCs[sc] = SubConnInfo{Address: addr} } } b.picker = b.pickerBuilder.Build(PickerBuildInfo{ReadySCs: readySCs}) @@ -213,10 +185,14 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su } return } - if oldS == connectivity.TransientFailure && s == connectivity.Connecting { - // Once a subconn enters TRANSIENT_FAILURE, ignore subsequent + if oldS == connectivity.TransientFailure && + (s == connectivity.Connecting || s == connectivity.Idle) { + // Once a subconn enters TRANSIENT_FAILURE, ignore subsequent IDLE or // CONNECTING transitions to prevent the aggregated state from being // always CONNECTING when many backends exist but are all down. + if s == connectivity.Idle { + sc.Connect() + } return } b.scStates[sc] = s @@ -242,7 +218,6 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su b.state == connectivity.TransientFailure { b.regeneratePicker() } - b.cc.UpdateState(balancer.State{ConnectivityState: b.state, Picker: b.picker}) } @@ -251,6 +226,11 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su func (b *baseBalancer) Close() { } +// ExitIdle is a nop because the base balancer attempts to stay connected to +// all SubConns at all times. +func (b *baseBalancer) ExitIdle() { +} + // NewErrPicker returns a Picker that always returns err on Pick(). func NewErrPicker(err error) balancer.Picker { return &errPicker{err: err} diff --git a/vendor/google.golang.org/grpc/balancer/grpclb/grpclb.go b/vendor/google.golang.org/grpc/balancer/grpclb/grpclb.go index 49d11d0d2e..fe423af182 100644 --- a/vendor/google.golang.org/grpc/balancer/grpclb/grpclb.go +++ b/vendor/google.golang.org/grpc/balancer/grpclb/grpclb.go @@ -135,6 +135,7 @@ func (b *lbBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) bal lb := &lbBalancer{ cc: newLBCacheClientConn(cc), + dialTarget: opt.Target.Endpoint, target: opt.Target.Endpoint, opt: opt, fallbackTimeout: b.fallbackTimeout, @@ -164,9 +165,10 @@ func (b *lbBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) bal } type lbBalancer struct { - cc *lbCacheClientConn - target string - opt balancer.BuildOptions + cc *lbCacheClientConn + dialTarget string // user's dial target + target string // same as dialTarget unless overridden in service config + opt balancer.BuildOptions usePickFirst bool @@ -398,6 +400,30 @@ func (lb *lbBalancer) handleServiceConfig(gc *grpclbServiceConfig) { lb.mu.Lock() defer lb.mu.Unlock() + // grpclb uses the user's dial target to populate the `Name` field of the + // `InitialLoadBalanceRequest` message sent to the remote balancer. But when + // grpclb is used a child policy in the context of RLS, we want the `Name` + // field to be populated with the value received from the RLS server. To + // support this use case, an optional "target_name" field has been added to + // the grpclb LB policy's config. If specified, it overrides the name of + // the target to be sent to the remote balancer; if not, the target to be + // sent to the balancer will continue to be obtained from the target URI + // passed to the gRPC client channel. Whenever that target to be sent to the + // balancer is updated, we need to restart the stream to the balancer as + // this target is sent in the first message on the stream. + if gc != nil { + target := lb.dialTarget + if gc.TargetName != "" { + target = gc.TargetName + } + if target != lb.target { + lb.target = target + if lb.ccRemoteLB != nil { + lb.ccRemoteLB.cancelRemoteBalancerCall() + } + } + } + newUsePickFirst := childIsPickFirst(gc) if lb.usePickFirst == newUsePickFirst { return @@ -488,3 +514,5 @@ func (lb *lbBalancer) Close() { } lb.cc.close() } + +func (lb *lbBalancer) ExitIdle() {} diff --git a/vendor/google.golang.org/grpc/balancer/grpclb/grpclb_config.go b/vendor/google.golang.org/grpc/balancer/grpclb/grpclb_config.go index aac3719631..b4e23dee01 100644 --- a/vendor/google.golang.org/grpc/balancer/grpclb/grpclb_config.go +++ b/vendor/google.golang.org/grpc/balancer/grpclb/grpclb_config.go @@ -34,6 +34,7 @@ const ( type grpclbServiceConfig struct { serviceconfig.LoadBalancingConfig ChildPolicy *[]map[string]json.RawMessage + TargetName string } func (b *lbBuilder) ParseConfig(lbConfig json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { diff --git a/vendor/google.golang.org/grpc/balancer/grpclb/grpclb_remote_balancer.go b/vendor/google.golang.org/grpc/balancer/grpclb/grpclb_remote_balancer.go index 5ac8d86bd5..330df4baa2 100644 --- a/vendor/google.golang.org/grpc/balancer/grpclb/grpclb_remote_balancer.go +++ b/vendor/google.golang.org/grpc/balancer/grpclb/grpclb_remote_balancer.go @@ -135,11 +135,19 @@ func (lb *lbBalancer) refreshSubConns(backendAddrs []resolver.Address, fallback } if lb.usePickFirst { - var sc balancer.SubConn - for _, sc = range lb.subConns { + var ( + scKey resolver.Address + sc balancer.SubConn + ) + for scKey, sc = range lb.subConns { break } if sc != nil { + if len(backendAddrs) == 0 { + lb.cc.cc.RemoveSubConn(sc) + delete(lb.subConns, scKey) + return + } lb.cc.cc.UpdateAddresses(sc, backendAddrs) sc.Connect() return @@ -206,6 +214,9 @@ type remoteBalancerCCWrapper struct { backoff backoff.Strategy done chan struct{} + streamMu sync.Mutex + streamCancel func() + // waitgroup to wait for all goroutines to exit. wg sync.WaitGroup } @@ -319,10 +330,8 @@ func (ccw *remoteBalancerCCWrapper) sendLoadReport(s *balanceLoadClientStream, i } } -func (ccw *remoteBalancerCCWrapper) callRemoteBalancer() (backoff bool, _ error) { +func (ccw *remoteBalancerCCWrapper) callRemoteBalancer(ctx context.Context) (backoff bool, _ error) { lbClient := &loadBalancerClient{cc: ccw.cc} - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() stream, err := lbClient.BalanceLoad(ctx, grpc.WaitForReady(true)) if err != nil { return true, fmt.Errorf("grpclb: failed to perform RPC to the remote balancer %v", err) @@ -362,11 +371,43 @@ func (ccw *remoteBalancerCCWrapper) callRemoteBalancer() (backoff bool, _ error) return false, ccw.readServerList(stream) } +// cancelRemoteBalancerCall cancels the context used by the stream to the remote +// balancer. watchRemoteBalancer() takes care of restarting this call after the +// stream fails. +func (ccw *remoteBalancerCCWrapper) cancelRemoteBalancerCall() { + ccw.streamMu.Lock() + if ccw.streamCancel != nil { + ccw.streamCancel() + ccw.streamCancel = nil + } + ccw.streamMu.Unlock() +} + func (ccw *remoteBalancerCCWrapper) watchRemoteBalancer() { - defer ccw.wg.Done() + defer func() { + ccw.wg.Done() + ccw.streamMu.Lock() + if ccw.streamCancel != nil { + // This is to make sure that we don't leak the context when we are + // directly returning from inside of the below `for` loop. + ccw.streamCancel() + ccw.streamCancel = nil + } + ccw.streamMu.Unlock() + }() + var retryCount int + var ctx context.Context for { - doBackoff, err := ccw.callRemoteBalancer() + ccw.streamMu.Lock() + if ccw.streamCancel != nil { + ccw.streamCancel() + ccw.streamCancel = nil + } + ctx, ccw.streamCancel = context.WithCancel(context.Background()) + ccw.streamMu.Unlock() + + doBackoff, err := ccw.callRemoteBalancer(ctx) select { case <-ccw.done: return diff --git a/vendor/google.golang.org/grpc/balancer/grpclb/state/state.go b/vendor/google.golang.org/grpc/balancer/grpclb/state/state.go index a24264a34f..4ecfa1c215 100644 --- a/vendor/google.golang.org/grpc/balancer/grpclb/state/state.go +++ b/vendor/google.golang.org/grpc/balancer/grpclb/state/state.go @@ -39,7 +39,7 @@ type State struct { // Set returns a copy of the provided state with attributes containing s. s's // data should not be mutated after calling Set. func Set(state resolver.State, s *State) resolver.State { - state.Attributes = state.Attributes.WithValues(key, s) + state.Attributes = state.Attributes.WithValue(key, s) return state } diff --git a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go index 43c2a15373..274eb2f858 100644 --- a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go +++ b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go @@ -47,11 +47,11 @@ func init() { type rrPickerBuilder struct{} func (*rrPickerBuilder) Build(info base.PickerBuildInfo) balancer.Picker { - logger.Infof("roundrobinPicker: newPicker called with info: %v", info) + logger.Infof("roundrobinPicker: Build called with info: %v", info) if len(info.ReadySCs) == 0 { return base.NewErrPicker(balancer.ErrNoSubConnAvailable) } - var scs []balancer.SubConn + scs := make([]balancer.SubConn, 0, len(info.ReadySCs)) for sc := range info.ReadySCs { scs = append(scs, sc) } diff --git a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go index dd83979639..f4ea617468 100644 --- a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go +++ b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go @@ -37,15 +37,20 @@ type scStateUpdate struct { err error } +// exitIdle contains no data and is just a signal sent on the updateCh in +// ccBalancerWrapper to instruct the balancer to exit idle. +type exitIdle struct{} + // ccBalancerWrapper is a wrapper on top of cc for balancers. // It implements balancer.ClientConn interface. type ccBalancerWrapper struct { - cc *ClientConn - balancerMu sync.Mutex // synchronizes calls to the balancer - balancer balancer.Balancer - updateCh *buffer.Unbounded - closed *grpcsync.Event - done *grpcsync.Event + cc *ClientConn + balancerMu sync.Mutex // synchronizes calls to the balancer + balancer balancer.Balancer + hasExitIdle bool + updateCh *buffer.Unbounded + closed *grpcsync.Event + done *grpcsync.Event mu sync.Mutex subConns map[*acBalancerWrapper]struct{} @@ -61,6 +66,7 @@ func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.Bui } go ccb.watcher() ccb.balancer = b.Build(ccb, bopts) + _, ccb.hasExitIdle = ccb.balancer.(balancer.ExitIdler) return ccb } @@ -86,6 +92,17 @@ func (ccb *ccBalancerWrapper) watcher() { ccb.cc.removeAddrConn(u.getAddrConn(), errConnDrain) } ccb.mu.Unlock() + case exitIdle: + if ccb.cc.GetState() == connectivity.Idle { + if ei, ok := ccb.balancer.(balancer.ExitIdler); ok { + // We already checked that the balancer implements + // ExitIdle before pushing the event to updateCh, but + // check conditionally again as defensive programming. + ccb.balancerMu.Lock() + ei.ExitIdle() + ccb.balancerMu.Unlock() + } + } default: logger.Errorf("ccBalancerWrapper.watcher: unknown update %+v, type %T", t, t) } @@ -118,6 +135,14 @@ func (ccb *ccBalancerWrapper) close() { <-ccb.done.Done() } +func (ccb *ccBalancerWrapper) exitIdle() bool { + if !ccb.hasExitIdle { + return false + } + ccb.updateCh.Put(exitIdle{}) + return true +} + func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s connectivity.State, err error) { // When updating addresses for a SubConn, if the address in use is not in // the new addresses, the old ac will be tearDown() and a new ac will be @@ -144,8 +169,8 @@ func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnStat func (ccb *ccBalancerWrapper) resolverError(err error) { ccb.balancerMu.Lock() + defer ccb.balancerMu.Unlock() ccb.balancer.ResolverError(err) - ccb.balancerMu.Unlock() } func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) { @@ -239,17 +264,17 @@ func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { return } - ac, err := cc.newAddrConn(addrs, opts) + newAC, err := cc.newAddrConn(addrs, opts) if err != nil { channelz.Warningf(logger, acbw.ac.channelzID, "acBalancerWrapper: UpdateAddresses: failed to newAddrConn: %v", err) return } - acbw.ac = ac - ac.mu.Lock() - ac.acbw = acbw - ac.mu.Unlock() + acbw.ac = newAC + newAC.mu.Lock() + newAC.acbw = acbw + newAC.mu.Unlock() if acState != connectivity.Idle { - ac.connect() + go newAC.connect() } } } @@ -257,7 +282,7 @@ func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { func (acbw *acBalancerWrapper) Connect() { acbw.mu.Lock() defer acbw.mu.Unlock() - acbw.ac.connect() + go acbw.ac.connect() } func (acbw *acBalancerWrapper) getAddrConn() *addrConn { diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index b2bccfed13..28f09dc870 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -23,6 +23,7 @@ import ( "errors" "fmt" "math" + "net/url" "reflect" "strings" "sync" @@ -37,7 +38,6 @@ import ( "google.golang.org/grpc/internal/backoff" "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/grpcsync" - "google.golang.org/grpc/internal/grpcutil" iresolver "google.golang.org/grpc/internal/resolver" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" @@ -83,13 +83,13 @@ var ( // errTransportCredsAndBundle indicates that creds bundle is used together // with other individual Transport Credentials. errTransportCredsAndBundle = errors.New("grpc: credentials.Bundle may not be used with individual TransportCredentials") - // errTransportCredentialsMissing indicates that users want to transmit security - // information (e.g., OAuth2 token) which requires secure connection on an insecure - // connection. + // errNoTransportCredsInBundle indicated that the configured creds bundle + // returned a transport credentials which was nil. + errNoTransportCredsInBundle = errors.New("grpc: credentials.Bundle must return non-nil transport credentials") + // errTransportCredentialsMissing indicates that users want to transmit + // security information (e.g., OAuth2 token) which requires secure + // connection on an insecure connection. errTransportCredentialsMissing = errors.New("grpc: the credentials require transport level security (use grpc.WithTransportCredentials() to set)") - // errCredentialsConflict indicates that grpc.WithTransportCredentials() - // and grpc.WithInsecure() are both called for a connection. - errCredentialsConflict = errors.New("grpc: transport credentials are set for an insecure connection (grpc.WithTransportCredentials() and grpc.WithInsecure() are both called)") ) const ( @@ -177,17 +177,20 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * cc.csMgr.channelzID = cc.channelzID } - if !cc.dopts.insecure { - if cc.dopts.copts.TransportCredentials == nil && cc.dopts.copts.CredsBundle == nil { - return nil, errNoTransportSecurity - } - if cc.dopts.copts.TransportCredentials != nil && cc.dopts.copts.CredsBundle != nil { - return nil, errTransportCredsAndBundle - } - } else { - if cc.dopts.copts.TransportCredentials != nil || cc.dopts.copts.CredsBundle != nil { - return nil, errCredentialsConflict - } + if cc.dopts.copts.TransportCredentials == nil && cc.dopts.copts.CredsBundle == nil { + return nil, errNoTransportSecurity + } + if cc.dopts.copts.TransportCredentials != nil && cc.dopts.copts.CredsBundle != nil { + return nil, errTransportCredsAndBundle + } + if cc.dopts.copts.CredsBundle != nil && cc.dopts.copts.CredsBundle.TransportCredentials() == nil { + return nil, errNoTransportCredsInBundle + } + transportCreds := cc.dopts.copts.TransportCredentials + if transportCreds == nil { + transportCreds = cc.dopts.copts.CredsBundle.TransportCredentials() + } + if transportCreds.Info().SecurityProtocol == "insecure" { for _, cd := range cc.dopts.copts.PerRPCCredentials { if cd.RequireTransportSecurity() { return nil, errTransportCredentialsMissing @@ -248,38 +251,15 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * } // Determine the resolver to use. - cc.parsedTarget = grpcutil.ParseTarget(cc.target, cc.dopts.copts.Dialer != nil) - channelz.Infof(logger, cc.channelzID, "parsed scheme: %q", cc.parsedTarget.Scheme) - resolverBuilder := cc.getResolver(cc.parsedTarget.Scheme) - if resolverBuilder == nil { - // If resolver builder is still nil, the parsed target's scheme is - // not registered. Fallback to default resolver and set Endpoint to - // the original target. - channelz.Infof(logger, cc.channelzID, "scheme %q not registered, fallback to default scheme", cc.parsedTarget.Scheme) - cc.parsedTarget = resolver.Target{ - Scheme: resolver.GetDefaultScheme(), - Endpoint: target, - } - resolverBuilder = cc.getResolver(cc.parsedTarget.Scheme) - if resolverBuilder == nil { - return nil, fmt.Errorf("could not get resolver for default scheme: %q", cc.parsedTarget.Scheme) - } + resolverBuilder, err := cc.parseTargetAndFindResolver() + if err != nil { + return nil, err } - - creds := cc.dopts.copts.TransportCredentials - if creds != nil && creds.Info().ServerName != "" { - cc.authority = creds.Info().ServerName - } else if cc.dopts.insecure && cc.dopts.authority != "" { - cc.authority = cc.dopts.authority - } else if strings.HasPrefix(cc.target, "unix:") || strings.HasPrefix(cc.target, "unix-abstract:") { - cc.authority = "localhost" - } else if strings.HasPrefix(cc.parsedTarget.Endpoint, ":") { - cc.authority = "localhost" + cc.parsedTarget.Endpoint - } else { - // Use endpoint from "scheme://authority/endpoint" as the default - // authority for ClientConn. - cc.authority = cc.parsedTarget.Endpoint + cc.authority, err = determineAuthority(cc.parsedTarget.Endpoint, cc.target, cc.dopts) + if err != nil { + return nil, err } + channelz.Infof(logger, cc.channelzID, "Channel authority set to %q", cc.authority) if cc.dopts.scChan != nil && !scSet { // Blocking wait for the initial service config. @@ -305,6 +285,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * DialCreds: credsClone, CredsBundle: cc.dopts.copts.CredsBundle, Dialer: cc.dopts.copts.Dialer, + Authority: cc.authority, CustomUserAgent: cc.dopts.copts.UserAgent, ChannelzParentID: cc.channelzID, Target: cc.parsedTarget, @@ -322,6 +303,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * // A blocking dial blocks until the clientConn is ready. if cc.dopts.block { for { + cc.Connect() s := cc.GetState() if s == connectivity.Ready { break @@ -539,12 +521,31 @@ func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState connec // // Experimental // -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. +// Notice: This API is EXPERIMENTAL and may be changed or removed in a later +// release. func (cc *ClientConn) GetState() connectivity.State { return cc.csMgr.getState() } +// Connect causes all subchannels in the ClientConn to attempt to connect if +// the channel is idle. Does not wait for the connection attempts to begin +// before returning. +// +// Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a later +// release. +func (cc *ClientConn) Connect() { + cc.mu.Lock() + defer cc.mu.Unlock() + if cc.balancerWrapper != nil && cc.balancerWrapper.exitIdle() { + return + } + for ac := range cc.conns { + go ac.connect() + } +} + func (cc *ClientConn) scWatcher() { for { select { @@ -632,7 +633,10 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error { } var ret error - if cc.dopts.disableServiceConfig || s.ServiceConfig == nil { + if cc.dopts.disableServiceConfig { + channelz.Infof(logger, cc.channelzID, "ignoring service config from resolver (%v) and applying the default because service config is disabled", s.ServiceConfig) + cc.maybeApplyDefaultServiceConfig(s.Addresses) + } else if s.ServiceConfig == nil { cc.maybeApplyDefaultServiceConfig(s.Addresses) // TODO: do we need to apply a failing LB policy if there is no // default, per the error handling design? @@ -845,8 +849,7 @@ func (ac *addrConn) connect() error { ac.updateConnectivityState(connectivity.Connecting, nil) ac.mu.Unlock() - // Start a goroutine connecting to the server asynchronously. - go ac.resetTransport() + ac.resetTransport() return nil } @@ -883,6 +886,7 @@ func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool { // ac.state is Ready, try to find the connected address. var curAddrFound bool for _, a := range addrs { + a.ServerName = ac.cc.getServerName(a) if reflect.DeepEqual(ac.curAddr, a) { curAddrFound = true break @@ -896,6 +900,26 @@ func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool { return curAddrFound } +// getServerName determines the serverName to be used in the connection +// handshake. The default value for the serverName is the authority on the +// ClientConn, which either comes from the user's dial target or through an +// authority override specified using the WithAuthority dial option. Name +// resolvers can specify a per-address override for the serverName through the +// resolver.Address.ServerName field which is used only if the WithAuthority +// dial option was not used. The rationale is that per-address authority +// overrides specified by the name resolver can represent a security risk, while +// an override specified by the user is more dependable since they probably know +// what they are doing. +func (cc *ClientConn) getServerName(addr resolver.Address) string { + if cc.dopts.authority != "" { + return cc.dopts.authority + } + if addr.ServerName != "" { + return addr.ServerName + } + return cc.authority +} + func getMethodConfig(sc *ServiceConfig, method string) MethodConfig { if sc == nil { return MethodConfig{} @@ -1135,112 +1159,86 @@ func (ac *addrConn) adjustParams(r transport.GoAwayReason) { } func (ac *addrConn) resetTransport() { - for i := 0; ; i++ { - if i > 0 { - ac.cc.resolveNow(resolver.ResolveNowOptions{}) - } - - ac.mu.Lock() - if ac.state == connectivity.Shutdown { - ac.mu.Unlock() - return - } - - addrs := ac.addrs - backoffFor := ac.dopts.bs.Backoff(ac.backoffIdx) - // This will be the duration that dial gets to finish. - dialDuration := minConnectTimeout - if ac.dopts.minConnectTimeout != nil { - dialDuration = ac.dopts.minConnectTimeout() - } - - if dialDuration < backoffFor { - // Give dial more time as we keep failing to connect. - dialDuration = backoffFor - } - // We can potentially spend all the time trying the first address, and - // if the server accepts the connection and then hangs, the following - // addresses will never be tried. - // - // The spec doesn't mention what should be done for multiple addresses. - // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md#proposed-backoff-algorithm - connectDeadline := time.Now().Add(dialDuration) - - ac.updateConnectivityState(connectivity.Connecting, nil) - ac.transport = nil + ac.mu.Lock() + if ac.state == connectivity.Shutdown { ac.mu.Unlock() - - newTr, addr, reconnect, err := ac.tryAllAddrs(addrs, connectDeadline) - if err != nil { - // After exhausting all addresses, the addrConn enters - // TRANSIENT_FAILURE. - ac.mu.Lock() - if ac.state == connectivity.Shutdown { - ac.mu.Unlock() - return - } - ac.updateConnectivityState(connectivity.TransientFailure, err) - - // Backoff. - b := ac.resetBackoff - ac.mu.Unlock() - - timer := time.NewTimer(backoffFor) - select { - case <-timer.C: - ac.mu.Lock() - ac.backoffIdx++ - ac.mu.Unlock() - case <-b: - timer.Stop() - case <-ac.ctx.Done(): - timer.Stop() - return - } - continue - } - - ac.mu.Lock() - if ac.state == connectivity.Shutdown { - ac.mu.Unlock() - newTr.Close(fmt.Errorf("reached connectivity state: SHUTDOWN")) - return - } - ac.curAddr = addr - ac.transport = newTr - ac.backoffIdx = 0 - - hctx, hcancel := context.WithCancel(ac.ctx) - ac.startHealthCheck(hctx) - ac.mu.Unlock() - - // Block until the created transport is down. And when this happens, - // we restart from the top of the addr list. - <-reconnect.Done() - hcancel() - // restart connecting - the top of the loop will set state to - // CONNECTING. This is against the current connectivity semantics doc, - // however it allows for graceful behavior for RPCs not yet dispatched - // - unfortunate timing would otherwise lead to the RPC failing even - // though the TRANSIENT_FAILURE state (called for by the doc) would be - // instantaneous. - // - // Ideally we should transition to Idle here and block until there is - // RPC activity that leads to the balancer requesting a reconnect of - // the associated SubConn. + return } + + addrs := ac.addrs + backoffFor := ac.dopts.bs.Backoff(ac.backoffIdx) + // This will be the duration that dial gets to finish. + dialDuration := minConnectTimeout + if ac.dopts.minConnectTimeout != nil { + dialDuration = ac.dopts.minConnectTimeout() + } + + if dialDuration < backoffFor { + // Give dial more time as we keep failing to connect. + dialDuration = backoffFor + } + // We can potentially spend all the time trying the first address, and + // if the server accepts the connection and then hangs, the following + // addresses will never be tried. + // + // The spec doesn't mention what should be done for multiple addresses. + // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md#proposed-backoff-algorithm + connectDeadline := time.Now().Add(dialDuration) + + ac.updateConnectivityState(connectivity.Connecting, nil) + ac.mu.Unlock() + + if err := ac.tryAllAddrs(addrs, connectDeadline); err != nil { + ac.cc.resolveNow(resolver.ResolveNowOptions{}) + // After exhausting all addresses, the addrConn enters + // TRANSIENT_FAILURE. + ac.mu.Lock() + if ac.state == connectivity.Shutdown { + ac.mu.Unlock() + return + } + ac.updateConnectivityState(connectivity.TransientFailure, err) + + // Backoff. + b := ac.resetBackoff + ac.mu.Unlock() + + timer := time.NewTimer(backoffFor) + select { + case <-timer.C: + ac.mu.Lock() + ac.backoffIdx++ + ac.mu.Unlock() + case <-b: + timer.Stop() + case <-ac.ctx.Done(): + timer.Stop() + return + } + + ac.mu.Lock() + if ac.state != connectivity.Shutdown { + ac.updateConnectivityState(connectivity.Idle, err) + } + ac.mu.Unlock() + return + } + // Success; reset backoff. + ac.mu.Lock() + ac.backoffIdx = 0 + ac.mu.Unlock() } -// tryAllAddrs tries to creates a connection to the addresses, and stop when at the -// first successful one. It returns the transport, the address and a Event in -// the successful case. The Event fires when the returned transport disconnects. -func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.Time) (transport.ClientTransport, resolver.Address, *grpcsync.Event, error) { +// tryAllAddrs tries to creates a connection to the addresses, and stop when at +// the first successful one. It returns an error if no address was successfully +// connected, or updates ac appropriately with the new transport. +func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.Time) error { var firstConnErr error for _, addr := range addrs { ac.mu.Lock() if ac.state == connectivity.Shutdown { ac.mu.Unlock() - return nil, resolver.Address{}, nil, errConnClosing + return errConnClosing } ac.cc.mu.RLock() @@ -1255,9 +1253,9 @@ func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.T channelz.Infof(logger, ac.channelzID, "Subchannel picks a new address %q to connect", addr.Addr) - newTr, reconnect, err := ac.createTransport(addr, copts, connectDeadline) + err := ac.createTransport(addr, copts, connectDeadline) if err == nil { - return newTr, addr, reconnect, nil + return nil } if firstConnErr == nil { firstConnErr = err @@ -1266,57 +1264,50 @@ func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.T } // Couldn't connect to any address. - return nil, resolver.Address{}, nil, firstConnErr + return firstConnErr } -// createTransport creates a connection to addr. It returns the transport and a -// Event in the successful case. The Event fires when the returned transport -// disconnects. -func (ac *addrConn) createTransport(addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time) (transport.ClientTransport, *grpcsync.Event, error) { - prefaceReceived := make(chan struct{}) - onCloseCalled := make(chan struct{}) - reconnect := grpcsync.NewEvent() +// createTransport creates a connection to addr. It returns an error if the +// address was not successfully connected, or updates ac appropriately with the +// new transport. +func (ac *addrConn) createTransport(addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time) error { + // TODO: Delete prefaceReceived and move the logic to wait for it into the + // transport. + prefaceReceived := grpcsync.NewEvent() + connClosed := grpcsync.NewEvent() - // addr.ServerName takes precedent over ClientConn authority, if present. - if addr.ServerName == "" { - addr.ServerName = ac.cc.authority - } - - once := sync.Once{} - onGoAway := func(r transport.GoAwayReason) { - ac.mu.Lock() - ac.adjustParams(r) - once.Do(func() { - if ac.state == connectivity.Ready { - // Prevent this SubConn from being used for new RPCs by setting its - // state to Connecting. - // - // TODO: this should be Idle when grpc-go properly supports it. - ac.updateConnectivityState(connectivity.Connecting, nil) - } - }) - ac.mu.Unlock() - reconnect.Fire() - } + addr.ServerName = ac.cc.getServerName(addr) + hctx, hcancel := context.WithCancel(ac.ctx) + hcStarted := false // protected by ac.mu onClose := func() { ac.mu.Lock() - once.Do(func() { - if ac.state == connectivity.Ready { - // Prevent this SubConn from being used for new RPCs by setting its - // state to Connecting. - // - // TODO: this should be Idle when grpc-go properly supports it. - ac.updateConnectivityState(connectivity.Connecting, nil) - } - }) - ac.mu.Unlock() - close(onCloseCalled) - reconnect.Fire() + defer ac.mu.Unlock() + defer connClosed.Fire() + if !hcStarted || hctx.Err() != nil { + // We didn't start the health check or set the state to READY, so + // no need to do anything else here. + // + // OR, we have already cancelled the health check context, meaning + // we have already called onClose once for this transport. In this + // case it would be dangerous to clear the transport and update the + // state, since there may be a new transport in this addrConn. + return + } + hcancel() + ac.transport = nil + // Refresh the name resolver + ac.cc.resolveNow(resolver.ResolveNowOptions{}) + if ac.state != connectivity.Shutdown { + ac.updateConnectivityState(connectivity.Idle, nil) + } } - onPrefaceReceipt := func() { - close(prefaceReceived) + onGoAway := func(r transport.GoAwayReason) { + ac.mu.Lock() + ac.adjustParams(r) + ac.mu.Unlock() + onClose() } connectCtx, cancel := context.WithDeadline(ac.ctx, connectDeadline) @@ -1325,27 +1316,67 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne copts.ChannelzParentID = ac.channelzID } - newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, onPrefaceReceipt, onGoAway, onClose) + newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, func() { prefaceReceived.Fire() }, onGoAway, onClose) if err != nil { // newTr is either nil, or closed. - channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v. Err: %v. Reconnecting...", addr, err) - return nil, nil, err + channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v. Err: %v", addr, err) + return err } select { - case <-time.After(time.Until(connectDeadline)): + case <-connectCtx.Done(): // We didn't get the preface in time. - newTr.Close(fmt.Errorf("failed to receive server preface within timeout")) - channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v: didn't receive server preface in time. Reconnecting...", addr) - return nil, nil, errors.New("timed out waiting for server handshake") - case <-prefaceReceived: + // The error we pass to Close() is immaterial since there are no open + // streams at this point, so no trailers with error details will be sent + // out. We just need to pass a non-nil error. + newTr.Close(transport.ErrConnClosing) + if connectCtx.Err() == context.DeadlineExceeded { + err := errors.New("failed to receive server preface within timeout") + channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v: %v", addr, err) + return err + } + return nil + case <-prefaceReceived.Done(): // We got the preface - huzzah! things are good. - case <-onCloseCalled: - // The transport has already closed - noop. - return nil, nil, errors.New("connection closed") - // TODO(deklerk) this should bail on ac.ctx.Done(). Add a test and fix. + ac.mu.Lock() + defer ac.mu.Unlock() + if connClosed.HasFired() { + // onClose called first; go idle but do nothing else. + if ac.state != connectivity.Shutdown { + ac.updateConnectivityState(connectivity.Idle, nil) + } + return nil + } + if ac.state == connectivity.Shutdown { + // This can happen if the subConn was removed while in `Connecting` + // state. tearDown() would have set the state to `Shutdown`, but + // would not have closed the transport since ac.transport would not + // been set at that point. + // + // We run this in a goroutine because newTr.Close() calls onClose() + // inline, which requires locking ac.mu. + // + // The error we pass to Close() is immaterial since there are no open + // streams at this point, so no trailers with error details will be sent + // out. We just need to pass a non-nil error. + go newTr.Close(transport.ErrConnClosing) + return nil + } + ac.curAddr = addr + ac.transport = newTr + hcStarted = true + ac.startHealthCheck(hctx) // Will set state to READY if appropriate. + return nil + case <-connClosed.Done(): + // The transport has already closed. If we received the preface, too, + // this is not an error. + select { + case <-prefaceReceived.Done(): + return nil + default: + return errors.New("connection closed before server preface received") + } } - return newTr, reconnect, nil } // startHealthCheck starts the health checking stream (RPC) to watch the health @@ -1587,3 +1618,114 @@ func (cc *ClientConn) connectionError() error { defer cc.lceMu.Unlock() return cc.lastConnectionError } + +func (cc *ClientConn) parseTargetAndFindResolver() (resolver.Builder, error) { + channelz.Infof(logger, cc.channelzID, "original dial target is: %q", cc.target) + + var rb resolver.Builder + parsedTarget, err := parseTarget(cc.target) + if err != nil { + channelz.Infof(logger, cc.channelzID, "dial target %q parse failed: %v", cc.target, err) + } else { + channelz.Infof(logger, cc.channelzID, "parsed dial target is: %+v", parsedTarget) + rb = cc.getResolver(parsedTarget.Scheme) + if rb != nil { + cc.parsedTarget = parsedTarget + return rb, nil + } + } + + // We are here because the user's dial target did not contain a scheme or + // specified an unregistered scheme. We should fallback to the default + // scheme, except when a custom dialer is specified in which case, we should + // always use passthrough scheme. + defScheme := resolver.GetDefaultScheme() + channelz.Infof(logger, cc.channelzID, "fallback to scheme %q", defScheme) + canonicalTarget := defScheme + ":///" + cc.target + + parsedTarget, err = parseTarget(canonicalTarget) + if err != nil { + channelz.Infof(logger, cc.channelzID, "dial target %q parse failed: %v", canonicalTarget, err) + return nil, err + } + channelz.Infof(logger, cc.channelzID, "parsed dial target is: %+v", parsedTarget) + rb = cc.getResolver(parsedTarget.Scheme) + if rb == nil { + return nil, fmt.Errorf("could not get resolver for default scheme: %q", parsedTarget.Scheme) + } + cc.parsedTarget = parsedTarget + return rb, nil +} + +// parseTarget uses RFC 3986 semantics to parse the given target into a +// resolver.Target struct containing scheme, authority and endpoint. Query +// params are stripped from the endpoint. +func parseTarget(target string) (resolver.Target, error) { + u, err := url.Parse(target) + if err != nil { + return resolver.Target{}, err + } + // For targets of the form "[scheme]://[authority]/endpoint, the endpoint + // value returned from url.Parse() contains a leading "/". Although this is + // in accordance with RFC 3986, we do not want to break existing resolver + // implementations which expect the endpoint without the leading "/". So, we + // end up stripping the leading "/" here. But this will result in an + // incorrect parsing for something like "unix:///path/to/socket". Since we + // own the "unix" resolver, we can workaround in the unix resolver by using + // the `URL` field instead of the `Endpoint` field. + endpoint := u.Path + if endpoint == "" { + endpoint = u.Opaque + } + endpoint = strings.TrimPrefix(endpoint, "/") + return resolver.Target{ + Scheme: u.Scheme, + Authority: u.Host, + Endpoint: endpoint, + URL: *u, + }, nil +} + +// Determine channel authority. The order of precedence is as follows: +// - user specified authority override using `WithAuthority` dial option +// - creds' notion of server name for the authentication handshake +// - endpoint from dial target of the form "scheme://[authority]/endpoint" +func determineAuthority(endpoint, target string, dopts dialOptions) (string, error) { + // Historically, we had two options for users to specify the serverName or + // authority for a channel. One was through the transport credentials + // (either in its constructor, or through the OverrideServerName() method). + // The other option (for cases where WithInsecure() dial option was used) + // was to use the WithAuthority() dial option. + // + // A few things have changed since: + // - `insecure` package with an implementation of the `TransportCredentials` + // interface for the insecure case + // - WithAuthority() dial option support for secure credentials + authorityFromCreds := "" + if creds := dopts.copts.TransportCredentials; creds != nil && creds.Info().ServerName != "" { + authorityFromCreds = creds.Info().ServerName + } + authorityFromDialOption := dopts.authority + if (authorityFromCreds != "" && authorityFromDialOption != "") && authorityFromCreds != authorityFromDialOption { + return "", fmt.Errorf("ClientConn's authority from transport creds %q and dial option %q don't match", authorityFromCreds, authorityFromDialOption) + } + + switch { + case authorityFromDialOption != "": + return authorityFromDialOption, nil + case authorityFromCreds != "": + return authorityFromCreds, nil + case strings.HasPrefix(target, "unix:") || strings.HasPrefix(target, "unix-abstract:"): + // TODO: remove when the unix resolver implements optional interface to + // return channel authority. + return "localhost", nil + case strings.HasPrefix(endpoint, ":"): + return "localhost" + endpoint, nil + default: + // TODO: Define an optional interface on the resolver builder to return + // the channel authority given the user's dial target. For resolvers + // which don't implement this interface, we will use the endpoint from + // "scheme://authority/endpoint" as the default authority. + return endpoint, nil + } +} diff --git a/vendor/google.golang.org/grpc/connectivity/connectivity.go b/vendor/google.golang.org/grpc/connectivity/connectivity.go index 0101562615..4a89926422 100644 --- a/vendor/google.golang.org/grpc/connectivity/connectivity.go +++ b/vendor/google.golang.org/grpc/connectivity/connectivity.go @@ -18,7 +18,6 @@ // Package connectivity defines connectivity semantics. // For details, see https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md. -// All APIs in this package are experimental. package connectivity import ( @@ -45,7 +44,7 @@ func (s State) String() string { return "SHUTDOWN" default: logger.Errorf("unknown connectivity state: %d", s) - return "Invalid-State" + return "INVALID_STATE" } } @@ -61,3 +60,35 @@ const ( // Shutdown indicates the ClientConn has started shutting down. Shutdown ) + +// ServingMode indicates the current mode of operation of the server. +// +// Only xDS enabled gRPC servers currently report their serving mode. +type ServingMode int + +const ( + // ServingModeStarting indicates that the server is starting up. + ServingModeStarting ServingMode = iota + // ServingModeServing indicates that the server contains all required + // configuration and is serving RPCs. + ServingModeServing + // ServingModeNotServing indicates that the server is not accepting new + // connections. Existing connections will be closed gracefully, allowing + // in-progress RPCs to complete. A server enters this mode when it does not + // contain the required configuration to serve RPCs. + ServingModeNotServing +) + +func (s ServingMode) String() string { + switch s { + case ServingModeStarting: + return "STARTING" + case ServingModeServing: + return "SERVING" + case ServingModeNotServing: + return "NOT_SERVING" + default: + logger.Errorf("unknown serving mode: %d", s) + return "INVALID_MODE" + } +} diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index 7eee7e4ec1..96ff1877e7 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -140,6 +140,11 @@ type TransportCredentials interface { // Additionally, ClientHandshakeInfo data will be available via the context // passed to this call. // + // The second argument to this method is the `:authority` header value used + // while creating new streams on this connection after authentication + // succeeds. Implementations must use this as the server name during the + // authentication handshake. + // // If the returned net.Conn is closed, it MUST close the net.Conn provided. ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error) // ServerHandshake does the authentication handshake for servers. It returns @@ -153,9 +158,13 @@ type TransportCredentials interface { Info() ProtocolInfo // Clone makes a copy of this TransportCredentials. Clone() TransportCredentials - // OverrideServerName overrides the server name used to verify the hostname on the returned certificates from the server. - // gRPC internals also use it to override the virtual hosting name if it is set. - // It must be called before dialing. Currently, this is only used by grpclb. + // OverrideServerName specifies the value used for the following: + // - verifying the hostname on the returned certificates + // - as SNI in the client's handshake to support virtual hosting + // - as the value for `:authority` header at stream creation time + // + // Deprecated: use grpc.WithAuthority instead. Will be supported + // throughout 1.x. OverrideServerName(string) error } @@ -169,8 +178,18 @@ type TransportCredentials interface { // // This API is experimental. type Bundle interface { + // TransportCredentials returns the transport credentials from the Bundle. + // + // Implementations must return non-nil transport credentials. If transport + // security is not needed by the Bundle, implementations may choose to + // return insecure.NewCredentials(). TransportCredentials() TransportCredentials + + // PerRPCCredentials returns the per-RPC credentials from the Bundle. + // + // May be nil if per-RPC credentials are not needed. PerRPCCredentials() PerRPCCredentials + // NewWithMode should make a copy of Bundle, and switch mode. Modifying the // existing Bundle may cause races. // diff --git a/vendor/google.golang.org/grpc/credentials/go12.go b/vendor/google.golang.org/grpc/credentials/go12.go deleted file mode 100644 index ccbf35b331..0000000000 --- a/vendor/google.golang.org/grpc/credentials/go12.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build go1.12 - -/* - * - * Copyright 2019 gRPC 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 credentials - -import "crypto/tls" - -// This init function adds cipher suite constants only defined in Go 1.12. -func init() { - cipherSuiteLookup[tls.TLS_AES_128_GCM_SHA256] = "TLS_AES_128_GCM_SHA256" - cipherSuiteLookup[tls.TLS_AES_256_GCM_SHA384] = "TLS_AES_256_GCM_SHA384" - cipherSuiteLookup[tls.TLS_CHACHA20_POLY1305_SHA256] = "TLS_CHACHA20_POLY1305_SHA256" -} diff --git a/vendor/google.golang.org/grpc/credentials/google/google.go b/vendor/google.golang.org/grpc/credentials/google/google.go index 265d193c7c..63625a4b68 100644 --- a/vendor/google.golang.org/grpc/credentials/google/google.go +++ b/vendor/google.golang.org/grpc/credentials/google/google.go @@ -35,27 +35,40 @@ const tokenRequestTimeout = 30 * time.Second var logger = grpclog.Component("credentials") +// DefaultCredentialsOptions constructs options to build DefaultCredentials. +type DefaultCredentialsOptions struct { + // PerRPCCreds is a per RPC credentials that is passed to a bundle. + PerRPCCreds credentials.PerRPCCredentials +} + +// NewDefaultCredentialsWithOptions returns a credentials bundle that is +// configured to work with google services. +// +// This API is experimental. +func NewDefaultCredentialsWithOptions(opts DefaultCredentialsOptions) credentials.Bundle { + if opts.PerRPCCreds == nil { + ctx, cancel := context.WithTimeout(context.Background(), tokenRequestTimeout) + defer cancel() + var err error + opts.PerRPCCreds, err = oauth.NewApplicationDefault(ctx) + if err != nil { + logger.Warningf("NewDefaultCredentialsWithOptions: failed to create application oauth: %v", err) + } + } + c := &creds{opts: opts} + bundle, err := c.NewWithMode(internal.CredsBundleModeFallback) + if err != nil { + logger.Warningf("NewDefaultCredentialsWithOptions: failed to create new creds: %v", err) + } + return bundle +} + // NewDefaultCredentials returns a credentials bundle that is configured to work // with google services. // // This API is experimental. func NewDefaultCredentials() credentials.Bundle { - c := &creds{ - newPerRPCCreds: func() credentials.PerRPCCredentials { - ctx, cancel := context.WithTimeout(context.Background(), tokenRequestTimeout) - defer cancel() - perRPCCreds, err := oauth.NewApplicationDefault(ctx) - if err != nil { - logger.Warningf("google default creds: failed to create application oauth: %v", err) - } - return perRPCCreds - }, - } - bundle, err := c.NewWithMode(internal.CredsBundleModeFallback) - if err != nil { - logger.Warningf("google default creds: failed to create new creds: %v", err) - } - return bundle + return NewDefaultCredentialsWithOptions(DefaultCredentialsOptions{}) } // NewComputeEngineCredentials returns a credentials bundle that is configured to work @@ -64,28 +77,21 @@ func NewDefaultCredentials() credentials.Bundle { // // This API is experimental. func NewComputeEngineCredentials() credentials.Bundle { - c := &creds{ - newPerRPCCreds: func() credentials.PerRPCCredentials { - return oauth.NewComputeEngine() - }, - } - bundle, err := c.NewWithMode(internal.CredsBundleModeFallback) - if err != nil { - logger.Warningf("compute engine creds: failed to create new creds: %v", err) - } - return bundle + return NewDefaultCredentialsWithOptions(DefaultCredentialsOptions{ + PerRPCCreds: oauth.NewComputeEngine(), + }) } // creds implements credentials.Bundle. type creds struct { + opts DefaultCredentialsOptions + // Supported modes are defined in internal/internal.go. mode string - // The transport credentials associated with this bundle. + // The active transport credentials associated with this bundle. transportCreds credentials.TransportCredentials - // The per RPC credentials associated with this bundle. + // The active per RPC credentials associated with this bundle. perRPCCreds credentials.PerRPCCredentials - // Creates new per RPC credentials - newPerRPCCreds func() credentials.PerRPCCredentials } func (c *creds) TransportCredentials() credentials.TransportCredentials { @@ -112,8 +118,8 @@ var ( // existing Bundle may cause races. func (c *creds) NewWithMode(mode string) (credentials.Bundle, error) { newCreds := &creds{ - mode: mode, - newPerRPCCreds: c.newPerRPCCreds, + opts: c.opts, + mode: mode, } // Create transport credentials. @@ -129,7 +135,7 @@ func (c *creds) NewWithMode(mode string) (credentials.Bundle, error) { } if mode == internal.CredsBundleModeFallback || mode == internal.CredsBundleModeBackendFromBalancer { - newCreds.perRPCCreds = newCreds.newPerRPCCreds() + newCreds.perRPCCreds = newCreds.opts.PerRPCCreds } return newCreds, nil diff --git a/vendor/google.golang.org/grpc/credentials/google/xds.go b/vendor/google.golang.org/grpc/credentials/google/xds.go index 588c685e25..b8c2e8f920 100644 --- a/vendor/google.golang.org/grpc/credentials/google/xds.go +++ b/vendor/google.golang.org/grpc/credentials/google/xds.go @@ -21,18 +21,19 @@ package google import ( "context" "net" + "strings" "google.golang.org/grpc/credentials" "google.golang.org/grpc/internal" ) -const cfeClusterName = "google-cfe" +const cfeClusterNamePrefix = "google_cfe_" // clusterTransportCreds is a combo of TLS + ALTS. // // On the client, ClientHandshake picks TLS or ALTS based on address attributes. // - if attributes has cluster name -// - if cluster name is "google_cfe", use TLS +// - if cluster name has prefix "google_cfe_", use TLS // - otherwise, use ALTS // - else, do TLS // @@ -55,7 +56,7 @@ func (c *clusterTransportCreds) ClientHandshake(ctx context.Context, authority s return c.tls.ClientHandshake(ctx, authority, rawConn) } cn, ok := internal.GetXDSHandshakeClusterName(chi.Attributes) - if !ok || cn == cfeClusterName { + if !ok || strings.HasPrefix(cn, cfeClusterNamePrefix) { return c.tls.ClientHandshake(ctx, authority, rawConn) } // If attributes have cluster name, and cluster name is not cfe, it's a diff --git a/vendor/google.golang.org/grpc/credentials/insecure/insecure.go b/vendor/google.golang.org/grpc/credentials/insecure/insecure.go new file mode 100644 index 0000000000..22a8f996a6 --- /dev/null +++ b/vendor/google.golang.org/grpc/credentials/insecure/insecure.go @@ -0,0 +1,77 @@ +/* + * + * Copyright 2020 gRPC 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 insecure provides an implementation of the +// credentials.TransportCredentials interface which disables transport security. +// +// Experimental +// +// Notice: This package is EXPERIMENTAL and may be changed or removed in a +// later release. +package insecure + +import ( + "context" + "net" + + "google.golang.org/grpc/credentials" +) + +// NewCredentials returns a credentials which disables transport security. +// +// Note that using this credentials with per-RPC credentials which require +// transport security is incompatible and will cause grpc.Dial() to fail. +func NewCredentials() credentials.TransportCredentials { + return insecureTC{} +} + +// insecureTC implements the insecure transport credentials. The handshake +// methods simply return the passed in net.Conn and set the security level to +// NoSecurity. +type insecureTC struct{} + +func (insecureTC) ClientHandshake(ctx context.Context, _ string, conn net.Conn) (net.Conn, credentials.AuthInfo, error) { + return conn, info{credentials.CommonAuthInfo{SecurityLevel: credentials.NoSecurity}}, nil +} + +func (insecureTC) ServerHandshake(conn net.Conn) (net.Conn, credentials.AuthInfo, error) { + return conn, info{credentials.CommonAuthInfo{SecurityLevel: credentials.NoSecurity}}, nil +} + +func (insecureTC) Info() credentials.ProtocolInfo { + return credentials.ProtocolInfo{SecurityProtocol: "insecure"} +} + +func (insecureTC) Clone() credentials.TransportCredentials { + return insecureTC{} +} + +func (insecureTC) OverrideServerName(string) error { + return nil +} + +// info contains the auth information for an insecure connection. +// It implements the AuthInfo interface. +type info struct { + credentials.CommonAuthInfo +} + +// AuthType returns the type of info as a string. +func (info) AuthType() string { + return "insecure" +} diff --git a/vendor/google.golang.org/grpc/credentials/oauth/oauth.go b/vendor/google.golang.org/grpc/credentials/oauth/oauth.go index 852ae375cf..c748fd21ce 100644 --- a/vendor/google.golang.org/grpc/credentials/oauth/oauth.go +++ b/vendor/google.golang.org/grpc/credentials/oauth/oauth.go @@ -23,6 +23,7 @@ import ( "context" "fmt" "io/ioutil" + "net/url" "sync" "golang.org/x/oauth2" @@ -56,6 +57,16 @@ func (ts TokenSource) RequireTransportSecurity() bool { return true } +// removeServiceNameFromJWTURI removes RPC service name from URI. +func removeServiceNameFromJWTURI(uri string) (string, error) { + parsed, err := url.Parse(uri) + if err != nil { + return "", err + } + parsed.Path = "/" + return parsed.String(), nil +} + type jwtAccess struct { jsonKey []byte } @@ -75,9 +86,15 @@ func NewJWTAccessFromKey(jsonKey []byte) (credentials.PerRPCCredentials, error) } func (j jwtAccess) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { + // Remove RPC service name from URI that will be used as audience + // in a self-signed JWT token. It follows https://google.aip.dev/auth/4111. + aud, err := removeServiceNameFromJWTURI(uri[0]) + if err != nil { + return nil, err + } // TODO: the returned TokenSource is reusable. Store it in a sync.Map, with // uri as the key, to avoid recreating for every RPC. - ts, err := google.JWTAccessTokenSourceFromJSON(j.jsonKey, uri[0]) + ts, err := google.JWTAccessTokenSourceFromJSON(j.jsonKey, aud) if err != nil { return nil, err } diff --git a/vendor/google.golang.org/grpc/credentials/tls.go b/vendor/google.golang.org/grpc/credentials/tls.go index 8ee7124f22..784822d056 100644 --- a/vendor/google.golang.org/grpc/credentials/tls.go +++ b/vendor/google.golang.org/grpc/credentials/tls.go @@ -230,4 +230,7 @@ var cipherSuiteLookup = map[uint16]string{ tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + tls.TLS_AES_128_GCM_SHA256: "TLS_AES_128_GCM_SHA256", + tls.TLS_AES_256_GCM_SHA384: "TLS_AES_256_GCM_SHA384", + tls.TLS_CHACHA20_POLY1305_SHA256: "TLS_CHACHA20_POLY1305_SHA256", } diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go index 7a497237bb..063f1e903c 100644 --- a/vendor/google.golang.org/grpc/dialoptions.go +++ b/vendor/google.golang.org/grpc/dialoptions.go @@ -27,9 +27,9 @@ import ( "google.golang.org/grpc/backoff" "google.golang.org/grpc/balancer" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/internal" internalbackoff "google.golang.org/grpc/internal/backoff" - "google.golang.org/grpc/internal/envconfig" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/resolver" @@ -50,7 +50,6 @@ type dialOptions struct { bs internalbackoff.Strategy block bool returnLastError bool - insecure bool timeout time.Duration scChan <-chan ServiceConfig authority string @@ -228,18 +227,14 @@ func WithServiceConfig(c <-chan ServiceConfig) DialOption { }) } -// WithConnectParams configures the dialer to use the provided ConnectParams. +// WithConnectParams configures the ClientConn to use the provided ConnectParams +// for creating and maintaining connections to servers. // // The backoff configuration specified as part of the ConnectParams overrides // all defaults specified in // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. Consider // using the backoff.DefaultConfig as a base, in cases where you want to // override only a subset of the backoff configuration. -// -// Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. func WithConnectParams(p ConnectParams) DialOption { return newFuncDialOption(func(o *dialOptions) { o.bs = internalbackoff.Exponential{Config: p.Backoff} @@ -303,11 +298,17 @@ func WithReturnConnectionError() DialOption { } // WithInsecure returns a DialOption which disables transport security for this -// ClientConn. Note that transport security is required unless WithInsecure is -// set. +// ClientConn. Under the hood, it uses insecure.NewCredentials(). +// +// Note that using this DialOption with per-RPC credentials (through +// WithCredentialsBundle or WithPerRPCCredentials) which require transport +// security is incompatible and will cause grpc.Dial() to fail. +// +// Deprecated: use insecure.NewCredentials() instead. +// Will be supported throughout 1.x. func WithInsecure() DialOption { return newFuncDialOption(func(o *dialOptions) { - o.insecure = true + o.copts.TransportCredentials = insecure.NewCredentials() }) } @@ -482,8 +483,7 @@ func WithChainStreamInterceptor(interceptors ...StreamClientInterceptor) DialOpt } // WithAuthority returns a DialOption that specifies the value to be used as the -// :authority pseudo-header. This value only works with WithInsecure and has no -// effect if TransportCredentials are present. +// :authority pseudo-header and as the server name in authentication handshake. func WithAuthority(a string) DialOption { return newFuncDialOption(func(o *dialOptions) { o.authority = a @@ -519,14 +519,16 @@ func WithDisableServiceConfig() DialOption { // WithDefaultServiceConfig returns a DialOption that configures the default // service config, which will be used in cases where: // -// 1. WithDisableServiceConfig is also used. -// 2. Resolver does not return a service config or if the resolver returns an -// invalid service config. +// 1. WithDisableServiceConfig is also used, or // -// Experimental +// 2. The name resolver does not provide a service config or provides an +// invalid service config. // -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. +// The parameter s is the JSON representation of the default service config. +// For more information about service configs, see: +// https://github.com/grpc/grpc/blob/master/doc/service_config.md +// For a simple example of usage, see: +// examples/features/load_balancing/client/main.go func WithDefaultServiceConfig(s string) DialOption { return newFuncDialOption(func(o *dialOptions) { o.defaultServiceConfigRawJSON = &s @@ -538,14 +540,8 @@ func WithDefaultServiceConfig(s string) DialOption { // will happen automatically if no data is written to the wire or if the RPC is // unprocessed by the remote server. // -// Retry support is currently disabled by default, but will be enabled by -// default in the future. Until then, it may be enabled by setting the -// environment variable "GRPC_GO_RETRY" to "on". -// -// Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. +// Retry support is currently enabled by default, but may be disabled by +// setting the environment variable "GRPC_GO_RETRY" to "off". func WithDisableRetry() DialOption { return newFuncDialOption(func(o *dialOptions) { o.disableRetry = true @@ -585,7 +581,6 @@ func withHealthCheckFunc(f internal.HealthChecker) DialOption { func defaultDialOptions() dialOptions { return dialOptions{ - disableRetry: !envconfig.Retry, healthCheckFunc: internal.HealthCheckFunc, copts: transport.ConnectOptions{ WriteBufferSize: defaultWriteBufSize, diff --git a/vendor/google.golang.org/grpc/grpclog/loggerv2.go b/vendor/google.golang.org/grpc/grpclog/loggerv2.go index 4ee33171e0..34098bb8eb 100644 --- a/vendor/google.golang.org/grpc/grpclog/loggerv2.go +++ b/vendor/google.golang.org/grpc/grpclog/loggerv2.go @@ -19,11 +19,14 @@ package grpclog import ( + "encoding/json" + "fmt" "io" "io/ioutil" "log" "os" "strconv" + "strings" "google.golang.org/grpc/internal/grpclog" ) @@ -95,8 +98,9 @@ var severityName = []string{ // loggerT is the default logger used by grpclog. type loggerT struct { - m []*log.Logger - v int + m []*log.Logger + v int + jsonFormat bool } // NewLoggerV2 creates a loggerV2 with the provided writers. @@ -105,19 +109,32 @@ type loggerT struct { // Warning logs will be written to warningW and infoW. // Info logs will be written to infoW. func NewLoggerV2(infoW, warningW, errorW io.Writer) LoggerV2 { - return NewLoggerV2WithVerbosity(infoW, warningW, errorW, 0) + return newLoggerV2WithConfig(infoW, warningW, errorW, loggerV2Config{}) } // NewLoggerV2WithVerbosity creates a loggerV2 with the provided writers and // verbosity level. func NewLoggerV2WithVerbosity(infoW, warningW, errorW io.Writer, v int) LoggerV2 { + return newLoggerV2WithConfig(infoW, warningW, errorW, loggerV2Config{verbose: v}) +} + +type loggerV2Config struct { + verbose int + jsonFormat bool +} + +func newLoggerV2WithConfig(infoW, warningW, errorW io.Writer, c loggerV2Config) LoggerV2 { var m []*log.Logger - m = append(m, log.New(infoW, severityName[infoLog]+": ", log.LstdFlags)) - m = append(m, log.New(io.MultiWriter(infoW, warningW), severityName[warningLog]+": ", log.LstdFlags)) + flag := log.LstdFlags + if c.jsonFormat { + flag = 0 + } + m = append(m, log.New(infoW, "", flag)) + m = append(m, log.New(io.MultiWriter(infoW, warningW), "", flag)) ew := io.MultiWriter(infoW, warningW, errorW) // ew will be used for error and fatal. - m = append(m, log.New(ew, severityName[errorLog]+": ", log.LstdFlags)) - m = append(m, log.New(ew, severityName[fatalLog]+": ", log.LstdFlags)) - return &loggerT{m: m, v: v} + m = append(m, log.New(ew, "", flag)) + m = append(m, log.New(ew, "", flag)) + return &loggerT{m: m, v: c.verbose, jsonFormat: c.jsonFormat} } // newLoggerV2 creates a loggerV2 to be used as default logger. @@ -142,58 +159,79 @@ func newLoggerV2() LoggerV2 { if vl, err := strconv.Atoi(vLevel); err == nil { v = vl } - return NewLoggerV2WithVerbosity(infoW, warningW, errorW, v) + + jsonFormat := strings.EqualFold(os.Getenv("GRPC_GO_LOG_FORMATTER"), "json") + + return newLoggerV2WithConfig(infoW, warningW, errorW, loggerV2Config{ + verbose: v, + jsonFormat: jsonFormat, + }) +} + +func (g *loggerT) output(severity int, s string) { + sevStr := severityName[severity] + if !g.jsonFormat { + g.m[severity].Output(2, fmt.Sprintf("%v: %v", sevStr, s)) + return + } + // TODO: we can also include the logging component, but that needs more + // (API) changes. + b, _ := json.Marshal(map[string]string{ + "severity": sevStr, + "message": s, + }) + g.m[severity].Output(2, string(b)) } func (g *loggerT) Info(args ...interface{}) { - g.m[infoLog].Print(args...) + g.output(infoLog, fmt.Sprint(args...)) } func (g *loggerT) Infoln(args ...interface{}) { - g.m[infoLog].Println(args...) + g.output(infoLog, fmt.Sprintln(args...)) } func (g *loggerT) Infof(format string, args ...interface{}) { - g.m[infoLog].Printf(format, args...) + g.output(infoLog, fmt.Sprintf(format, args...)) } func (g *loggerT) Warning(args ...interface{}) { - g.m[warningLog].Print(args...) + g.output(warningLog, fmt.Sprint(args...)) } func (g *loggerT) Warningln(args ...interface{}) { - g.m[warningLog].Println(args...) + g.output(warningLog, fmt.Sprintln(args...)) } func (g *loggerT) Warningf(format string, args ...interface{}) { - g.m[warningLog].Printf(format, args...) + g.output(warningLog, fmt.Sprintf(format, args...)) } func (g *loggerT) Error(args ...interface{}) { - g.m[errorLog].Print(args...) + g.output(errorLog, fmt.Sprint(args...)) } func (g *loggerT) Errorln(args ...interface{}) { - g.m[errorLog].Println(args...) + g.output(errorLog, fmt.Sprintln(args...)) } func (g *loggerT) Errorf(format string, args ...interface{}) { - g.m[errorLog].Printf(format, args...) + g.output(errorLog, fmt.Sprintf(format, args...)) } func (g *loggerT) Fatal(args ...interface{}) { - g.m[fatalLog].Fatal(args...) - // No need to call os.Exit() again because log.Logger.Fatal() calls os.Exit(). + g.output(fatalLog, fmt.Sprint(args...)) + os.Exit(1) } func (g *loggerT) Fatalln(args ...interface{}) { - g.m[fatalLog].Fatalln(args...) - // No need to call os.Exit() again because log.Logger.Fatal() calls os.Exit(). + g.output(fatalLog, fmt.Sprintln(args...)) + os.Exit(1) } func (g *loggerT) Fatalf(format string, args ...interface{}) { - g.m[fatalLog].Fatalf(format, args...) - // No need to call os.Exit() again because log.Logger.Fatal() calls os.Exit(). + g.output(fatalLog, fmt.Sprintf(format, args...)) + os.Exit(1) } func (g *loggerT) V(l int) bool { diff --git a/vendor/google.golang.org/grpc/install_gae.sh b/vendor/google.golang.org/grpc/install_gae.sh deleted file mode 100644 index 15ff9facdd..0000000000 --- a/vendor/google.golang.org/grpc/install_gae.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -TMP=$(mktemp -d /tmp/sdk.XXX) \ -&& curl -o $TMP.zip "https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.68.zip" \ -&& unzip -q $TMP.zip -d $TMP \ -&& export PATH="$PATH:$TMP/go_appengine" \ No newline at end of file diff --git a/vendor/google.golang.org/grpc/internal/channelz/funcs.go b/vendor/google.golang.org/grpc/internal/channelz/funcs.go index f731413930..cd1807543e 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/funcs.go +++ b/vendor/google.golang.org/grpc/internal/channelz/funcs.go @@ -204,9 +204,9 @@ func RegisterChannel(c Channel, pid int64, ref string) int64 { trace: &channelTrace{createdTime: time.Now(), events: make([]*TraceEvent, 0, getMaxTraceEntry())}, } if pid == 0 { - db.get().addChannel(id, cn, true, pid, ref) + db.get().addChannel(id, cn, true, pid) } else { - db.get().addChannel(id, cn, false, pid, ref) + db.get().addChannel(id, cn, false, pid) } return id } @@ -228,7 +228,7 @@ func RegisterSubChannel(c Channel, pid int64, ref string) int64 { pid: pid, trace: &channelTrace{createdTime: time.Now(), events: make([]*TraceEvent, 0, getMaxTraceEntry())}, } - db.get().addSubChannel(id, sc, pid, ref) + db.get().addSubChannel(id, sc, pid) return id } @@ -258,7 +258,7 @@ func RegisterListenSocket(s Socket, pid int64, ref string) int64 { } id := idGen.genID() ls := &listenSocket{refName: ref, s: s, id: id, pid: pid} - db.get().addListenSocket(id, ls, pid, ref) + db.get().addListenSocket(id, ls, pid) return id } @@ -273,11 +273,11 @@ func RegisterNormalSocket(s Socket, pid int64, ref string) int64 { } id := idGen.genID() ns := &normalSocket{refName: ref, s: s, id: id, pid: pid} - db.get().addNormalSocket(id, ns, pid, ref) + db.get().addNormalSocket(id, ns, pid) return id } -// RemoveEntry removes an entry with unique channelz trakcing id to be id from +// RemoveEntry removes an entry with unique channelz tracking id to be id from // channelz database. func RemoveEntry(id int64) { db.get().removeEntry(id) @@ -333,7 +333,7 @@ func (c *channelMap) addServer(id int64, s *server) { c.mu.Unlock() } -func (c *channelMap) addChannel(id int64, cn *channel, isTopChannel bool, pid int64, ref string) { +func (c *channelMap) addChannel(id int64, cn *channel, isTopChannel bool, pid int64) { c.mu.Lock() cn.cm = c cn.trace.cm = c @@ -346,7 +346,7 @@ func (c *channelMap) addChannel(id int64, cn *channel, isTopChannel bool, pid in c.mu.Unlock() } -func (c *channelMap) addSubChannel(id int64, sc *subChannel, pid int64, ref string) { +func (c *channelMap) addSubChannel(id int64, sc *subChannel, pid int64) { c.mu.Lock() sc.cm = c sc.trace.cm = c @@ -355,7 +355,7 @@ func (c *channelMap) addSubChannel(id int64, sc *subChannel, pid int64, ref stri c.mu.Unlock() } -func (c *channelMap) addListenSocket(id int64, ls *listenSocket, pid int64, ref string) { +func (c *channelMap) addListenSocket(id int64, ls *listenSocket, pid int64) { c.mu.Lock() ls.cm = c c.listenSockets[id] = ls @@ -363,7 +363,7 @@ func (c *channelMap) addListenSocket(id int64, ls *listenSocket, pid int64, ref c.mu.Unlock() } -func (c *channelMap) addNormalSocket(id int64, ns *normalSocket, pid int64, ref string) { +func (c *channelMap) addNormalSocket(id int64, ns *normalSocket, pid int64) { c.mu.Lock() ns.cm = c c.normalSockets[id] = ns @@ -630,7 +630,7 @@ func (c *channelMap) GetServerSockets(id int64, startID int64, maxResults int64) if count == 0 { end = true } - var s []*SocketMetric + s := make([]*SocketMetric, 0, len(sks)) for _, ns := range sks { sm := &SocketMetric{} sm.SocketData = ns.s.ChannelzMetric() diff --git a/vendor/google.golang.org/grpc/internal/channelz/types_linux.go b/vendor/google.golang.org/grpc/internal/channelz/types_linux.go index 692dd61817..1b1c4cce34 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/types_linux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/types_linux.go @@ -1,5 +1,3 @@ -// +build !appengine - /* * * Copyright 2018 gRPC authors. diff --git a/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go b/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go index 19c2fc521d..8b06eed1ab 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go @@ -1,4 +1,5 @@ -// +build !linux appengine +//go:build !linux +// +build !linux /* * @@ -37,6 +38,6 @@ type SocketOptionData struct { // Windows OS doesn't support Socket Option func (s *SocketOptionData) Getsockopt(fd uintptr) { once.Do(func() { - logger.Warning("Channelz: socket options are not supported on non-linux os and appengine.") + logger.Warning("Channelz: socket options are not supported on non-linux environments") }) } diff --git a/vendor/google.golang.org/grpc/internal/channelz/util_linux.go b/vendor/google.golang.org/grpc/internal/channelz/util_linux.go index fdf409d55d..8d194e44e1 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/util_linux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/util_linux.go @@ -1,5 +1,3 @@ -// +build linux,!appengine - /* * * Copyright 2018 gRPC authors. diff --git a/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go b/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go index 8864a08111..837ddc4024 100644 --- a/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go +++ b/vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go @@ -1,4 +1,5 @@ -// +build !linux appengine +//go:build !linux +// +build !linux /* * diff --git a/vendor/google.golang.org/grpc/internal/credentials/spiffe.go b/vendor/google.golang.org/grpc/internal/credentials/spiffe.go index be70b6cdfc..25ade62305 100644 --- a/vendor/google.golang.org/grpc/internal/credentials/spiffe.go +++ b/vendor/google.golang.org/grpc/internal/credentials/spiffe.go @@ -1,5 +1,3 @@ -// +build !appengine - /* * * Copyright 2020 gRPC authors. diff --git a/vendor/google.golang.org/grpc/internal/credentials/spiffe_appengine.go b/vendor/google.golang.org/grpc/internal/credentials/spiffe_appengine.go deleted file mode 100644 index af6f577197..0000000000 --- a/vendor/google.golang.org/grpc/internal/credentials/spiffe_appengine.go +++ /dev/null @@ -1,31 +0,0 @@ -// +build appengine - -/* - * - * Copyright 2020 gRPC 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 credentials - -import ( - "crypto/tls" - "net/url" -) - -// SPIFFEIDFromState is a no-op for appengine builds. -func SPIFFEIDFromState(state tls.ConnectionState) *url.URL { - return nil -} diff --git a/vendor/google.golang.org/grpc/internal/credentials/syscallconn.go b/vendor/google.golang.org/grpc/internal/credentials/syscallconn.go index f499a614c2..2919632d65 100644 --- a/vendor/google.golang.org/grpc/internal/credentials/syscallconn.go +++ b/vendor/google.golang.org/grpc/internal/credentials/syscallconn.go @@ -1,5 +1,3 @@ -// +build !appengine - /* * * Copyright 2018 gRPC authors. diff --git a/vendor/google.golang.org/grpc/internal/credentials/util.go b/vendor/google.golang.org/grpc/internal/credentials/util.go index 55664fa46b..f792fd22ca 100644 --- a/vendor/google.golang.org/grpc/internal/credentials/util.go +++ b/vendor/google.golang.org/grpc/internal/credentials/util.go @@ -18,7 +18,9 @@ package credentials -import "crypto/tls" +import ( + "crypto/tls" +) const alpnProtoStrH2 = "h2" diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index 73931a94bc..6f02725431 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -26,13 +26,10 @@ import ( const ( prefix = "GRPC_GO_" - retryStr = prefix + "RETRY" txtErrIgnoreStr = prefix + "IGNORE_TXT_ERRORS" ) var ( - // Retry is set if retry is explicitly enabled via "GRPC_GO_RETRY=on". - Retry = strings.EqualFold(os.Getenv(retryStr), "on") // TXTErrIgnore is set if TXT errors should be ignored ("GRPC_GO_IGNORE_TXT_ERRORS" is not "false"). TXTErrIgnore = !strings.EqualFold(os.Getenv(txtErrIgnoreStr), "false") ) diff --git a/vendor/google.golang.org/grpc/internal/envconfig/xds.go b/vendor/google.golang.org/grpc/internal/envconfig/xds.go new file mode 100644 index 0000000000..93522d716d --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/envconfig/xds.go @@ -0,0 +1,90 @@ +/* + * + * Copyright 2020 gRPC 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 envconfig + +import ( + "os" + "strings" +) + +const ( + // XDSBootstrapFileNameEnv is the env variable to set bootstrap file name. + // Do not use this and read from env directly. Its value is read and kept in + // variable BootstrapFileName. + // + // When both bootstrap FileName and FileContent are set, FileName is used. + XDSBootstrapFileNameEnv = "GRPC_XDS_BOOTSTRAP" + // XDSBootstrapFileContentEnv is the env variable to set bootstrapp file + // content. Do not use this and read from env directly. Its value is read + // and kept in variable BootstrapFileName. + // + // When both bootstrap FileName and FileContent are set, FileName is used. + XDSBootstrapFileContentEnv = "GRPC_XDS_BOOTSTRAP_CONFIG" + + ringHashSupportEnv = "GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH" + clientSideSecuritySupportEnv = "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" + aggregateAndDNSSupportEnv = "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER" + rbacSupportEnv = "GRPC_XDS_EXPERIMENTAL_RBAC" + federationEnv = "GRPC_EXPERIMENTAL_XDS_FEDERATION" + + c2pResolverTestOnlyTrafficDirectorURIEnv = "GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI" +) + +var ( + // XDSBootstrapFileName holds the name of the file which contains xDS + // bootstrap configuration. Users can specify the location of the bootstrap + // file by setting the environment variable "GRPC_XDS_BOOTSTRAP". + // + // When both bootstrap FileName and FileContent are set, FileName is used. + XDSBootstrapFileName = os.Getenv(XDSBootstrapFileNameEnv) + // XDSBootstrapFileContent holds the content of the xDS bootstrap + // configuration. Users can specify the bootstrap config by setting the + // environment variable "GRPC_XDS_BOOTSTRAP_CONFIG". + // + // When both bootstrap FileName and FileContent are set, FileName is used. + XDSBootstrapFileContent = os.Getenv(XDSBootstrapFileContentEnv) + // XDSRingHash indicates whether ring hash support is enabled, which can be + // disabled by setting the environment variable + // "GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH" to "false". + XDSRingHash = !strings.EqualFold(os.Getenv(ringHashSupportEnv), "false") + // XDSClientSideSecurity is used to control processing of security + // configuration on the client-side. + // + // Note that there is no env var protection for the server-side because we + // have a brand new API on the server-side and users explicitly need to use + // the new API to get security integration on the server. + XDSClientSideSecurity = !strings.EqualFold(os.Getenv(clientSideSecuritySupportEnv), "false") + // XDSAggregateAndDNS indicates whether processing of aggregated cluster + // and DNS cluster is enabled, which can be enabled by setting the + // environment variable + // "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER" to + // "true". + XDSAggregateAndDNS = strings.EqualFold(os.Getenv(aggregateAndDNSSupportEnv), "true") + + // XDSRBAC indicates whether xDS configured RBAC HTTP Filter is enabled, + // which can be disabled by setting the environment variable + // "GRPC_XDS_EXPERIMENTAL_RBAC" to "false". + XDSRBAC = !strings.EqualFold(os.Getenv(rbacSupportEnv), "false") + + // XDSFederation indicates whether federation support is enabled. + XDSFederation = strings.EqualFold(os.Getenv(federationEnv), "true") + + // C2PResolverTestOnlyTrafficDirectorURI is the TD URI for testing. + C2PResolverTestOnlyTrafficDirectorURI = os.Getenv(c2pResolverTestOnlyTrafficDirectorURIEnv) +) diff --git a/vendor/google.golang.org/grpc/internal/credentials/syscallconn_appengine.go b/vendor/google.golang.org/grpc/internal/grpcutil/grpcutil.go similarity index 72% rename from vendor/google.golang.org/grpc/internal/credentials/syscallconn_appengine.go rename to vendor/google.golang.org/grpc/internal/grpcutil/grpcutil.go index a6144cd661..e2f948e8f4 100644 --- a/vendor/google.golang.org/grpc/internal/credentials/syscallconn_appengine.go +++ b/vendor/google.golang.org/grpc/internal/grpcutil/grpcutil.go @@ -1,8 +1,6 @@ -// +build appengine - /* * - * Copyright 2018 gRPC authors. + * Copyright 2021 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,13 +16,5 @@ * */ -package credentials - -import ( - "net" -) - -// WrapSyscallConn returns newConn on appengine. -func WrapSyscallConn(rawConn, newConn net.Conn) net.Conn { - return newConn -} +// Package grpcutil provides utility functions used across the gRPC codebase. +package grpcutil diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/go113.go b/vendor/google.golang.org/grpc/internal/grpcutil/regex.go similarity index 66% rename from vendor/google.golang.org/grpc/internal/resolver/dns/go113.go rename to vendor/google.golang.org/grpc/internal/grpcutil/regex.go index 8783a8cf82..2810a8ba2f 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/dns/go113.go +++ b/vendor/google.golang.org/grpc/internal/grpcutil/regex.go @@ -1,8 +1,6 @@ -// +build go1.13 - /* * - * Copyright 2019 gRPC authors. + * Copyright 2021 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,16 +16,13 @@ * */ -package dns +package grpcutil -import "net" +import "regexp" -func init() { - filterError = func(err error) error { - if dnsErr, ok := err.(*net.DNSError); ok && dnsErr.IsNotFound { - // The name does not exist; not an error. - return nil - } - return err - } +// FullMatchWithRegex returns whether the full string matches the regex provided. +func FullMatchWithRegex(re *regexp.Regexp, string string) bool { + re.Longest() + rem := re.FindString(string) + return len(rem) == len(string) } diff --git a/vendor/google.golang.org/grpc/internal/grpcutil/target.go b/vendor/google.golang.org/grpc/internal/grpcutil/target.go deleted file mode 100644 index 8833021da0..0000000000 --- a/vendor/google.golang.org/grpc/internal/grpcutil/target.go +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * Copyright 2020 gRPC 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 grpcutil provides a bunch of utility functions to be used across the -// gRPC codebase. -package grpcutil - -import ( - "strings" - - "google.golang.org/grpc/resolver" -) - -// split2 returns the values from strings.SplitN(s, sep, 2). -// If sep is not found, it returns ("", "", false) instead. -func split2(s, sep string) (string, string, bool) { - spl := strings.SplitN(s, sep, 2) - if len(spl) < 2 { - return "", "", false - } - return spl[0], spl[1], true -} - -// ParseTarget splits target into a resolver.Target struct containing scheme, -// authority and endpoint. skipUnixColonParsing indicates that the parse should -// not parse "unix:[path]" cases. This should be true in cases where a custom -// dialer is present, to prevent a behavior change. -// -// If target is not a valid scheme://authority/endpoint as specified in -// https://github.com/grpc/grpc/blob/master/doc/naming.md, -// it returns {Endpoint: target}. -func ParseTarget(target string, skipUnixColonParsing bool) (ret resolver.Target) { - var ok bool - if strings.HasPrefix(target, "unix-abstract:") { - if strings.HasPrefix(target, "unix-abstract://") { - // Maybe, with Authority specified, try to parse it - var remain string - ret.Scheme, remain, _ = split2(target, "://") - ret.Authority, ret.Endpoint, ok = split2(remain, "/") - if !ok { - // No Authority, add the "//" back - ret.Endpoint = "//" + remain - } else { - // Found Authority, add the "/" back - ret.Endpoint = "/" + ret.Endpoint - } - } else { - // Without Authority specified, split target on ":" - ret.Scheme, ret.Endpoint, _ = split2(target, ":") - } - return ret - } - ret.Scheme, ret.Endpoint, ok = split2(target, "://") - if !ok { - if strings.HasPrefix(target, "unix:") && !skipUnixColonParsing { - // Handle the "unix:[local/path]" and "unix:[/absolute/path]" cases, - // because splitting on :// only handles the - // "unix://[/absolute/path]" case. Only handle if the dialer is nil, - // to avoid a behavior change with custom dialers. - return resolver.Target{Scheme: "unix", Endpoint: target[len("unix:"):]} - } - return resolver.Target{Endpoint: target} - } - ret.Authority, ret.Endpoint, ok = split2(ret.Endpoint, "/") - if !ok { - return resolver.Target{Endpoint: target} - } - if ret.Scheme == "unix" { - // Add the "/" back in the unix case, so the unix resolver receives the - // actual endpoint in the "unix://[/absolute/path]" case. - ret.Endpoint = "/" + ret.Endpoint - } - return ret -} diff --git a/vendor/google.golang.org/grpc/internal/metadata/metadata.go b/vendor/google.golang.org/grpc/internal/metadata/metadata.go index 302262613a..b8733dbf34 100644 --- a/vendor/google.golang.org/grpc/internal/metadata/metadata.go +++ b/vendor/google.golang.org/grpc/internal/metadata/metadata.go @@ -30,14 +30,38 @@ type mdKeyType string const mdKey = mdKeyType("grpc.internal.address.metadata") +type mdValue metadata.MD + +func (m mdValue) Equal(o interface{}) bool { + om, ok := o.(mdValue) + if !ok { + return false + } + if len(m) != len(om) { + return false + } + for k, v := range m { + ov := om[k] + if len(ov) != len(v) { + return false + } + for i, ve := range v { + if ov[i] != ve { + return false + } + } + } + return true +} + // Get returns the metadata of addr. func Get(addr resolver.Address) metadata.MD { attrs := addr.Attributes if attrs == nil { return nil } - md, _ := attrs.Value(mdKey).(metadata.MD) - return md + md, _ := attrs.Value(mdKey).(mdValue) + return metadata.MD(md) } // Set sets (overrides) the metadata in addr. @@ -45,6 +69,6 @@ func Get(addr resolver.Address) metadata.MD { // When a SubConn is created with this address, the RPCs sent on it will all // have this metadata. func Set(addr resolver.Address, md metadata.MD) resolver.Address { - addr.Attributes = addr.Attributes.WithValues(mdKey, md) + addr.Attributes = addr.Attributes.WithValue(mdKey, mdValue(md)) return addr } diff --git a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go index 5e7f36703d..c7a18a948a 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go +++ b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go @@ -117,9 +117,12 @@ type ClientInterceptor interface { NewStream(ctx context.Context, ri RPCInfo, done func(), newStream func(ctx context.Context, done func()) (ClientStream, error)) (ClientStream, error) } -// ServerInterceptor is unimplementable; do not use. +// ServerInterceptor is an interceptor for incoming RPC's on gRPC server side. type ServerInterceptor interface { - notDefined() + // AllowRPC checks if an incoming RPC is allowed to proceed based on + // information about connection RPC was received on, and HTTP Headers. This + // information will be piped into context. + AllowRPC(ctx context.Context) error // TODO: Make this a real interceptor for filters such as rate limiting. } type csKeyType string @@ -129,7 +132,7 @@ const csKey = csKeyType("grpc.internal.resolver.configSelector") // SetConfigSelector sets the config selector in state and returns the new // state. func SetConfigSelector(state resolver.State, cs ConfigSelector) resolver.State { - state.Attributes = state.Attributes.WithValues(csKey, cs) + state.Attributes = state.Attributes.WithValue(csKey, cs) return state } diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go index 03825bbe7b..75301c5149 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go @@ -277,18 +277,13 @@ func (d *dnsResolver) lookupSRV() ([]resolver.Address, error) { return newAddrs, nil } -var filterError = func(err error) error { +func handleDNSError(err error, lookupType string) error { if dnsErr, ok := err.(*net.DNSError); ok && !dnsErr.IsTimeout && !dnsErr.IsTemporary { // Timeouts and temporary errors should be communicated to gRPC to // attempt another DNS query (with backoff). Other errors should be // suppressed (they may represent the absence of a TXT record). return nil } - return err -} - -func handleDNSError(err error, lookupType string) error { - err = filterError(err) if err != nil { err = fmt.Errorf("dns: %v record lookup error: %v", lookupType, err) logger.Info(err) @@ -323,12 +318,12 @@ func (d *dnsResolver) lookupTXT() *serviceconfig.ParseResult { } func (d *dnsResolver) lookupHost() ([]resolver.Address, error) { - var newAddrs []resolver.Address addrs, err := d.resolver.LookupHost(d.ctx, d.host) if err != nil { err = handleDNSError(err, "A") return nil, err } + newAddrs := make([]resolver.Address, 0, len(addrs)) for _, a := range addrs { ip, ok := formatIP(a) if !ok { diff --git a/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go b/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go index 0d5a811ddf..20852e59df 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go +++ b/vendor/google.golang.org/grpc/internal/resolver/unix/unix.go @@ -37,7 +37,17 @@ func (b *builder) Build(target resolver.Target, cc resolver.ClientConn, _ resolv if target.Authority != "" { return nil, fmt.Errorf("invalid (non-empty) authority: %v", target.Authority) } - addr := resolver.Address{Addr: target.Endpoint} + + // gRPC was parsing the dial target manually before PR #4817, and we + // switched to using url.Parse() in that PR. To avoid breaking existing + // resolver implementations we ended up stripping the leading "/" from the + // endpoint. This obviously does not work for the "unix" scheme. Hence we + // end up using the parsed URL instead. + endpoint := target.URL.Path + if endpoint == "" { + endpoint = target.URL.Opaque + } + addr := resolver.Address{Addr: endpoint} if b.scheme == unixAbstractScheme { // prepend "\x00" to address for unix-abstract addr.Addr = "\x00" + addr.Addr diff --git a/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go b/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go index c0634d152c..badbdbf597 100644 --- a/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go +++ b/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go @@ -78,6 +78,7 @@ func (bc *BalancerConfig) UnmarshalJSON(b []byte) error { return err } + var names []string for i, lbcfg := range ir { if len(lbcfg) != 1 { return fmt.Errorf("invalid loadBalancingConfig: entry %v does not contain exactly 1 policy/config pair: %q", i, lbcfg) @@ -92,6 +93,7 @@ func (bc *BalancerConfig) UnmarshalJSON(b []byte) error { for name, jsonCfg = range lbcfg { } + names = append(names, name) builder := balancer.Get(name) if builder == nil { // If the balancer is not registered, move on to the next config. @@ -120,7 +122,7 @@ func (bc *BalancerConfig) UnmarshalJSON(b []byte) error { // return. This means we had a loadBalancingConfig slice but did not // encounter a registered policy. The config is considered invalid in this // case. - return fmt.Errorf("invalid loadBalancingConfig: no supported policies found") + return fmt.Errorf("invalid loadBalancingConfig: no supported policies found in %v", names) } // MethodConfig defines the configuration recommended by the service providers for a diff --git a/vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go b/vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go index 4b2964f2a1..b3a72276de 100644 --- a/vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go +++ b/vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go @@ -1,5 +1,3 @@ -// +build !appengine - /* * * Copyright 2018 gRPC authors. diff --git a/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go b/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go index 7913ef1dbf..999f52cd75 100644 --- a/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go +++ b/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go @@ -1,4 +1,5 @@ -// +build !linux appengine +//go:build !linux +// +build !linux /* * @@ -35,41 +36,41 @@ var logger = grpclog.Component("core") func log() { once.Do(func() { - logger.Info("CPU time info is unavailable on non-linux or appengine environment.") + logger.Info("CPU time info is unavailable on non-linux environments.") }) } -// GetCPUTime returns the how much CPU time has passed since the start of this process. -// It always returns 0 under non-linux or appengine environment. +// GetCPUTime returns the how much CPU time has passed since the start of this +// process. It always returns 0 under non-linux environments. func GetCPUTime() int64 { log() return 0 } -// Rusage is an empty struct under non-linux or appengine environment. +// Rusage is an empty struct under non-linux environments. type Rusage struct{} -// GetRusage is a no-op function under non-linux or appengine environment. +// GetRusage is a no-op function under non-linux environments. func GetRusage() *Rusage { log() return nil } // CPUTimeDiff returns the differences of user CPU time and system CPU time used -// between two Rusage structs. It a no-op function for non-linux or appengine environment. +// between two Rusage structs. It a no-op function for non-linux environments. func CPUTimeDiff(first *Rusage, latest *Rusage) (float64, float64) { log() return 0, 0 } -// SetTCPUserTimeout is a no-op function under non-linux or appengine environments +// SetTCPUserTimeout is a no-op function under non-linux environments. func SetTCPUserTimeout(conn net.Conn, timeout time.Duration) error { log() return nil } -// GetTCPUserTimeout is a no-op function under non-linux or appengine environments -// a negative return value indicates the operation is not supported +// GetTCPUserTimeout is a no-op function under non-linux environments. +// A negative return value indicates the operation is not supported func GetTCPUserTimeout(conn net.Conn) (int, error) { log() return -1, nil diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go index 45532f8aea..8394d252df 100644 --- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go +++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -133,6 +133,7 @@ type cleanupStream struct { func (c *cleanupStream) isTransportResponseFrame() bool { return c.rst } // Results in a RST_STREAM type earlyAbortStream struct { + httpStatus uint32 streamID uint32 contentSubtype string status *status.Status @@ -771,9 +772,12 @@ func (l *loopyWriter) earlyAbortStreamHandler(eas *earlyAbortStream) error { if l.side == clientSide { return errors.New("earlyAbortStream not handled on client") } - + // In case the caller forgets to set the http status, default to 200. + if eas.httpStatus == 0 { + eas.httpStatus = 200 + } headerFields := []hpack.HeaderField{ - {Name: ":status", Value: "200"}, + {Name: ":status", Value: strconv.Itoa(int(eas.httpStatus))}, {Name: "content-type", Value: grpcutil.ContentType(eas.contentSubtype)}, {Name: "grpc-status", Value: strconv.Itoa(int(eas.status.Code()))}, {Name: "grpc-message", Value: encodeGrpcMessage(eas.status.Message())}, diff --git a/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go b/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go index f262edd8ec..97198c5158 100644 --- a/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go +++ b/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go @@ -136,12 +136,10 @@ type inFlow struct { // newLimit updates the inflow window to a new value n. // It assumes that n is always greater than the old limit. -func (f *inFlow) newLimit(n uint32) uint32 { +func (f *inFlow) newLimit(n uint32) { f.mu.Lock() - d := n - f.limit f.limit = n f.mu.Unlock() - return d } func (f *inFlow) maybeAdjust(n uint32) uint32 { diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index 0cd6da1e73..f0c72d3371 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -25,6 +25,7 @@ import ( "math" "net" "net/http" + "path/filepath" "strconv" "strings" "sync" @@ -146,13 +147,20 @@ func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error address := addr.Addr networkType, ok := networktype.Get(addr) if fn != nil { + // Special handling for unix scheme with custom dialer. Back in the day, + // we did not have a unix resolver and therefore targets with a unix + // scheme would end up using the passthrough resolver. So, user's used a + // custom dialer in this case and expected the original dial target to + // be passed to the custom dialer. Now, we have a unix resolver. But if + // a custom dialer is specified, we want to retain the old behavior in + // terms of the address being passed to the custom dialer. if networkType == "unix" && !strings.HasPrefix(address, "\x00") { - // For backward compatibility, if the user dialed "unix:///path", - // the passthrough resolver would be used and the user's custom - // dialer would see "unix:///path". Since the unix resolver is used - // and the address is now "/path", prepend "unix://" so the user's - // custom dialer sees the same address. - return fn(ctx, "unix://"+address) + // Supported unix targets are either "unix://absolute-path" or + // "unix:relative-path". + if filepath.IsAbs(address) { + return fn(ctx, "unix://"+address) + } + return fn(ctx, "unix:"+address) } return fn(ctx, address) } @@ -193,6 +201,12 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts } }() + // gRPC, resolver, balancer etc. can specify arbitrary data in the + // Attributes field of resolver.Address, which is shoved into connectCtx + // and passed to the dialer and credential handshaker. This makes it possible for + // address specific arbitrary data to reach custom dialers and credential handshakers. + connectCtx = icredentials.NewClientHandshakeInfoContext(connectCtx, credentials.ClientHandshakeInfo{Attributes: addr.Attributes}) + conn, err := dial(connectCtx, opts.Dialer, addr, opts.UseProxy, opts.UserAgent) if err != nil { if opts.FailOnNonTempDialError { @@ -237,11 +251,6 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts } } if transportCreds != nil { - // gRPC, resolver, balancer etc. can specify arbitrary data in the - // Attributes field of resolver.Address, which is shoved into connectCtx - // and passed to the credential handshaker. This makes it possible for - // address specific arbitrary data to reach the credential handshaker. - connectCtx = icredentials.NewClientHandshakeInfoContext(connectCtx, credentials.ClientHandshakeInfo{Attributes: addr.Attributes}) rawConn := conn // Pull the deadline from the connectCtx, which will be used for // timeouts in the authentication protocol handshake. Can ignore the @@ -579,7 +588,7 @@ func (t *http2Client) getTrAuthData(ctx context.Context, audience string) (map[s return nil, err } - return nil, status.Errorf(codes.Unauthenticated, "transport: %v", err) + return nil, status.Errorf(codes.Unauthenticated, "transport: per-RPC creds failed due to error: %v", err) } for k, v := range data { // Capital header names are illegal in HTTP/2. @@ -616,12 +625,22 @@ func (t *http2Client) getCallAuthData(ctx context.Context, audience string, call return callAuthData, nil } -// NewStreamError wraps an error and reports additional information. +// NewStreamError wraps an error and reports additional information. Typically +// NewStream errors result in transparent retry, as they mean nothing went onto +// the wire. However, there are two notable exceptions: +// +// 1. If the stream headers violate the max header list size allowed by the +// server. In this case there is no reason to retry at all, as it is +// assumed the RPC would continue to fail on subsequent attempts. +// 2. If the credentials errored when requesting their headers. In this case, +// it's possible a retry can fix the problem, but indefinitely transparently +// retrying is not appropriate as it is likely the credentials, if they can +// eventually succeed, would need I/O to do so. type NewStreamError struct { Err error - DoNotRetry bool - PerformedIO bool + DoNotRetry bool + DoNotTransparentRetry bool } func (e NewStreamError) Error() string { @@ -631,24 +650,10 @@ func (e NewStreamError) Error() string { // NewStream creates a stream and registers it into the transport as "active" // streams. All non-nil errors returned will be *NewStreamError. func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Stream, err error) { - defer func() { - if err != nil { - nse, ok := err.(*NewStreamError) - if !ok { - nse = &NewStreamError{Err: err} - } - if len(t.perRPCCreds) > 0 || callHdr.Creds != nil { - // We may have performed I/O in the per-RPC creds callback, so do not - // allow transparent retry. - nse.PerformedIO = true - } - err = nse - } - }() ctx = peer.NewContext(ctx, t.getPeer()) headerFields, err := t.createHeaderFields(ctx, callHdr) if err != nil { - return nil, err + return nil, &NewStreamError{Err: err, DoNotTransparentRetry: true} } s := t.newStream(ctx, callHdr) cleanup := func(err error) { @@ -748,7 +753,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea return true }, hdr) if err != nil { - return nil, err + return nil, &NewStreamError{Err: err} } if success { break @@ -759,12 +764,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea firstTry = false select { case <-ch: - case <-s.ctx.Done(): - return nil, ContextErr(s.ctx.Err()) + case <-ctx.Done(): + return nil, &NewStreamError{Err: ContextErr(ctx.Err())} case <-t.goAway: - return nil, errStreamDrain + return nil, &NewStreamError{Err: errStreamDrain} case <-t.ctx.Done(): - return nil, ErrConnClosing + return nil, &NewStreamError{Err: ErrConnClosing} } } if t.statsHandler != nil { @@ -1077,7 +1082,7 @@ func (t *http2Client) handleData(f *http2.DataFrame) { } // The server has closed the stream without sending trailers. Record that // the read direction is closed, and set the status appropriately. - if f.FrameHeader.Flags.Has(http2.FlagDataEndStream) { + if f.StreamEnded() { t.closeStream(s, io.EOF, false, http2.ErrCodeNo, status.New(codes.Internal, "server closed the stream without sending trailers"), nil, true) } } @@ -1407,26 +1412,6 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { } isHeader := false - defer func() { - if t.statsHandler != nil { - if isHeader { - inHeader := &stats.InHeader{ - Client: true, - WireLength: int(frame.Header().Length), - Header: s.header.Copy(), - Compression: s.recvCompress, - } - t.statsHandler.HandleRPC(s.ctx, inHeader) - } else { - inTrailer := &stats.InTrailer{ - Client: true, - WireLength: int(frame.Header().Length), - Trailer: s.trailer.Copy(), - } - t.statsHandler.HandleRPC(s.ctx, inTrailer) - } - } - }() // If headerChan hasn't been closed yet if atomic.CompareAndSwapUint32(&s.headerChanClosed, 0, 1) { @@ -1448,6 +1433,25 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { close(s.headerChan) } + if t.statsHandler != nil { + if isHeader { + inHeader := &stats.InHeader{ + Client: true, + WireLength: int(frame.Header().Length), + Header: metadata.MD(mdata).Copy(), + Compression: s.recvCompress, + } + t.statsHandler.HandleRPC(s.ctx, inHeader) + } else { + inTrailer := &stats.InTrailer{ + Client: true, + WireLength: int(frame.Header().Length), + Trailer: metadata.MD(mdata).Copy(), + } + t.statsHandler.HandleRPC(s.ctx, inTrailer) + } + } + if !endStream { return } @@ -1553,7 +1557,7 @@ func minTime(a, b time.Duration) time.Duration { return b } -// keepalive running in a separate goroutune makes sure the connection is alive by sending pings. +// keepalive running in a separate goroutine makes sure the connection is alive by sending pings. func (t *http2Client) keepalive() { p := &ping{data: [8]byte{}} // True iff a ping has been sent, and no data has been received since then. diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index e3799d50aa..2c6eaf0e59 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -73,7 +73,6 @@ type http2Server struct { writerDone chan struct{} // sync point to enable testing. remoteAddr net.Addr localAddr net.Addr - maxStreamID uint32 // max stream ID ever seen authInfo credentials.AuthInfo // auth info about the connection inTapHandle tap.ServerInHandle framer *framer @@ -123,16 +122,37 @@ type http2Server struct { bufferPool *bufferPool connectionID uint64 + + // maxStreamMu guards the maximum stream ID + // This lock may not be taken if mu is already held. + maxStreamMu sync.Mutex + maxStreamID uint32 // max stream ID ever seen } // NewServerTransport creates a http2 transport with conn and configuration // options from config. // // It returns a non-nil transport and a nil error on success. On failure, it -// returns a non-nil transport and a nil-error. For a special case where the +// returns a nil transport and a non-nil error. For a special case where the // underlying conn gets closed before the client preface could be read, it // returns a nil transport and a nil error. func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, err error) { + var authInfo credentials.AuthInfo + rawConn := conn + if config.Credentials != nil { + var err error + conn, authInfo, err = config.Credentials.ServerHandshake(rawConn) + if err != nil { + // ErrConnDispatched means that the connection was dispatched away + // from gRPC; those connections should be left open. io.EOF means + // the connection was closed before handshaking completed, which can + // happen naturally from probers. Return these errors directly. + if err == credentials.ErrConnDispatched || err == io.EOF { + return nil, err + } + return nil, connectionErrorf(false, err, "ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err) + } + } writeBufSize := config.WriteBufferSize readBufSize := config.ReadBufferSize maxHeaderListSize := defaultServerMaxHeaderListSize @@ -215,14 +235,15 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, if kep.MinTime == 0 { kep.MinTime = defaultKeepalivePolicyMinTime } + done := make(chan struct{}) t := &http2Server{ - ctx: context.Background(), + ctx: setConnection(context.Background(), rawConn), done: done, conn: conn, remoteAddr: conn.RemoteAddr(), localAddr: conn.LocalAddr(), - authInfo: config.AuthInfo, + authInfo: authInfo, framer: framer, readerDone: make(chan struct{}), writerDone: make(chan struct{}), @@ -273,10 +294,11 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, if _, err := io.ReadFull(t.conn, preface); err != nil { // In deployments where a gRPC server runs behind a cloud load balancer // which performs regular TCP level health checks, the connection is - // closed immediately by the latter. Skipping the error here will help - // reduce log clutter. + // closed immediately by the latter. Returning io.EOF here allows the + // grpc server implementation to recognize this scenario and suppress + // logging to reduce spam. if err == io.EOF { - return nil, nil + return nil, io.EOF } return nil, connectionErrorf(false, err, "transport: http2Server.HandleStreams failed to receive the preface from client: %v", err) } @@ -316,6 +338,10 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, // operateHeader takes action on the decoded headers. func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) (fatal bool) { + // Acquire max stream ID lock for entire duration + t.maxStreamMu.Lock() + defer t.maxStreamMu.Unlock() + streamID := frame.Header().StreamID // frame.Truncated is set to true when framer detects that the current header @@ -330,6 +356,15 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( return false } + if streamID%2 != 1 || streamID <= t.maxStreamID { + // illegal gRPC stream id. + if logger.V(logLevel) { + logger.Errorf("transport: http2Server.HandleStreams received an illegal stream id: %v", streamID) + } + return true + } + t.maxStreamID = streamID + buf := newRecvBuffer() s := &Stream{ id: streamID, @@ -337,7 +372,6 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( buf: buf, fc: &inFlow{limit: uint32(t.initialWindowSize)}, } - var ( // If a gRPC Response-Headers has already been received, then it means // that the peer is speaking gRPC and we are in gRPC mode. @@ -373,6 +407,13 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( if timeout, err = decodeTimeout(hf.Value); err != nil { headerError = true } + // "Transports must consider requests containing the Connection header + // as malformed." - A41 + case "connection": + if logger.V(logLevel) { + logger.Errorf("transport: http2Server.operateHeaders parsed a :connection header which makes a request malformed as per the HTTP/2 spec") + } + headerError = true default: if isReservedHeader(hf.Name) && !isWhitelistedHeader(hf.Name) { break @@ -387,6 +428,25 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( } } + // "If multiple Host headers or multiple :authority headers are present, the + // request must be rejected with an HTTP status code 400 as required by Host + // validation in RFC 7230 §5.4, gRPC status code INTERNAL, or RST_STREAM + // with HTTP/2 error code PROTOCOL_ERROR." - A41. Since this is a HTTP/2 + // error, this takes precedence over a client not speaking gRPC. + if len(mdata[":authority"]) > 1 || len(mdata["host"]) > 1 { + errMsg := fmt.Sprintf("num values of :authority: %v, num values of host: %v, both must only have 1 value as per HTTP/2 spec", len(mdata[":authority"]), len(mdata["host"])) + if logger.V(logLevel) { + logger.Errorf("transport: %v", errMsg) + } + t.controlBuf.put(&earlyAbortStream{ + httpStatus: 400, + streamID: streamID, + contentSubtype: s.contentSubtype, + status: status.New(codes.Internal, errMsg), + }) + return false + } + if !isGRPC || headerError { t.controlBuf.put(&cleanupStream{ streamID: streamID, @@ -397,6 +457,19 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( return false } + // "If :authority is missing, Host must be renamed to :authority." - A41 + if len(mdata[":authority"]) == 0 { + // No-op if host isn't present, no eventual :authority header is a valid + // RPC. + if host, ok := mdata["host"]; ok { + mdata[":authority"] = host + delete(mdata, "host") + } + } else { + // "If :authority is present, Host must be discarded" - A41 + delete(mdata, "host") + } + if frame.StreamEnded() { // s is just created by the caller. No lock needed. s.state = streamReadDone @@ -441,16 +514,6 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( s.cancel() return false } - if streamID%2 != 1 || streamID <= t.maxStreamID { - t.mu.Unlock() - // illegal gRPC stream id. - if logger.V(logLevel) { - logger.Errorf("transport: http2Server.HandleStreams received an illegal stream id: %v", streamID) - } - s.cancel() - return true - } - t.maxStreamID = streamID if httpMethod != http.MethodPost { t.mu.Unlock() if logger.V(logLevel) { @@ -477,6 +540,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( stat = status.New(codes.PermissionDenied, err.Error()) } t.controlBuf.put(&earlyAbortStream{ + httpStatus: 200, streamID: s.id, contentSubtype: s.contentSubtype, status: stat, @@ -717,7 +781,7 @@ func (t *http2Server) handleData(f *http2.DataFrame) { s.write(recvMsg{buffer: buffer}) } } - if f.Header().Flags.Has(http2.FlagDataEndStream) { + if f.StreamEnded() { // Received the end of stream from the client. s.compareAndSwapState(streamActive, streamReadDone) s.write(recvMsg{err: io.EOF}) @@ -1235,20 +1299,23 @@ var goAwayPing = &ping{data: [8]byte{1, 6, 1, 8, 0, 3, 3, 9}} // Handles outgoing GoAway and returns true if loopy needs to put itself // in draining mode. func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { + t.maxStreamMu.Lock() t.mu.Lock() if t.state == closing { // TODO(mmukhi): This seems unnecessary. t.mu.Unlock() + t.maxStreamMu.Unlock() // The transport is closing. return false, ErrConnClosing } - sid := t.maxStreamID if !g.headsUp { // Stop accepting more streams now. t.state = draining + sid := t.maxStreamID if len(t.activeStreams) == 0 { g.closeConn = true } t.mu.Unlock() + t.maxStreamMu.Unlock() if err := t.framer.fr.WriteGoAway(sid, g.code, g.debugData); err != nil { return false, err } @@ -1261,6 +1328,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { return true, nil } t.mu.Unlock() + t.maxStreamMu.Unlock() // For a graceful close, send out a GoAway with stream ID of MaxUInt32, // Follow that with a ping and wait for the ack to come back or a timer // to expire. During this time accept new streams since they might have @@ -1345,3 +1413,18 @@ func getJitter(v time.Duration) time.Duration { j := grpcrand.Int63n(2*r) - r return time.Duration(j) } + +type connectionKey struct{} + +// GetConnection gets the connection from the context. +func GetConnection(ctx context.Context) net.Conn { + conn, _ := ctx.Value(connectionKey{}).(net.Conn) + return conn +} + +// SetConnection adds the connection to the context to be able to get +// information about the destination ip and port for an incoming RPC. This also +// allows any unary or streaming interceptors to see the connection. +func setConnection(ctx context.Context, conn net.Conn) context.Context { + return context.WithValue(ctx, connectionKey{}, conn) +} diff --git a/vendor/google.golang.org/grpc/internal/transport/networktype/networktype.go b/vendor/google.golang.org/grpc/internal/transport/networktype/networktype.go index 7bb53cff10..c11b527827 100644 --- a/vendor/google.golang.org/grpc/internal/transport/networktype/networktype.go +++ b/vendor/google.golang.org/grpc/internal/transport/networktype/networktype.go @@ -31,7 +31,7 @@ const key = keyType("grpc.internal.transport.networktype") // Set returns a copy of the provided address with attributes containing networkType. func Set(address resolver.Address, networkType string) resolver.Address { - address.Attributes = address.Attributes.WithValues(key, networkType) + address.Attributes = address.Attributes.WithValue(key, networkType) return address } diff --git a/vendor/google.golang.org/grpc/internal/transport/proxy.go b/vendor/google.golang.org/grpc/internal/transport/proxy.go index a662bf39a6..4159619878 100644 --- a/vendor/google.golang.org/grpc/internal/transport/proxy.go +++ b/vendor/google.golang.org/grpc/internal/transport/proxy.go @@ -37,7 +37,7 @@ var ( httpProxyFromEnvironment = http.ProxyFromEnvironment ) -func mapAddress(ctx context.Context, address string) (*url.URL, error) { +func mapAddress(address string) (*url.URL, error) { req := &http.Request{ URL: &url.URL{ Scheme: "https", @@ -114,7 +114,7 @@ func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, backendAddr stri // connection. func proxyDial(ctx context.Context, addr string, grpcUA string) (conn net.Conn, err error) { newAddr := addr - proxyURL, err := mapAddress(ctx, addr) + proxyURL, err := mapAddress(addr) if err != nil { return nil, err } diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index 1419812645..d3bf65b2bd 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -30,6 +30,7 @@ import ( "net" "sync" "sync/atomic" + "time" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -518,7 +519,8 @@ const ( // ServerConfig consists of all the configurations to establish a server transport. type ServerConfig struct { MaxStreams uint32 - AuthInfo credentials.AuthInfo + ConnectionTimeout time.Duration + Credentials credentials.TransportCredentials InTapHandle tap.ServerInHandle StatsHandler stats.Handler KeepaliveParams keepalive.ServerParameters diff --git a/vendor/google.golang.org/grpc/internal/xds_handshake_cluster.go b/vendor/google.golang.org/grpc/internal/xds_handshake_cluster.go index 3677c3f04f..e8b492774d 100644 --- a/vendor/google.golang.org/grpc/internal/xds_handshake_cluster.go +++ b/vendor/google.golang.org/grpc/internal/xds_handshake_cluster.go @@ -28,7 +28,7 @@ type handshakeClusterNameKey struct{} // SetXDSHandshakeClusterName returns a copy of addr in which the Attributes field // is updated with the cluster name. func SetXDSHandshakeClusterName(addr resolver.Address, clusterName string) resolver.Address { - addr.Attributes = addr.Attributes.WithValues(handshakeClusterNameKey{}, clusterName) + addr.Attributes = addr.Attributes.WithValue(handshakeClusterNameKey{}, clusterName) return addr } diff --git a/vendor/google.golang.org/grpc/picker_wrapper.go b/vendor/google.golang.org/grpc/picker_wrapper.go index 0878ada9db..e8367cb899 100644 --- a/vendor/google.golang.org/grpc/picker_wrapper.go +++ b/vendor/google.golang.org/grpc/picker_wrapper.go @@ -144,7 +144,7 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. acw, ok := pickResult.SubConn.(*acBalancerWrapper) if !ok { - logger.Error("subconn returned from pick is not *acBalancerWrapper") + logger.Errorf("subconn returned from pick is type %T, not *acBalancerWrapper", pickResult.SubConn) continue } if t := acw.getAddrConn().getReadyTransport(); t != nil { diff --git a/vendor/google.golang.org/grpc/pickfirst.go b/vendor/google.golang.org/grpc/pickfirst.go index b858c2a5e6..5168b62b07 100644 --- a/vendor/google.golang.org/grpc/pickfirst.go +++ b/vendor/google.golang.org/grpc/pickfirst.go @@ -107,10 +107,12 @@ func (b *pickfirstBalancer) UpdateSubConnState(sc balancer.SubConn, s balancer.S } switch s.ConnectivityState { - case connectivity.Ready, connectivity.Idle: + case connectivity.Ready: b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &picker{result: balancer.PickResult{SubConn: sc}}}) case connectivity.Connecting: b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &picker{err: balancer.ErrNoSubConnAvailable}}) + case connectivity.Idle: + b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &idlePicker{sc: sc}}) case connectivity.TransientFailure: b.cc.UpdateState(balancer.State{ ConnectivityState: s.ConnectivityState, @@ -122,6 +124,12 @@ func (b *pickfirstBalancer) UpdateSubConnState(sc balancer.SubConn, s balancer.S func (b *pickfirstBalancer) Close() { } +func (b *pickfirstBalancer) ExitIdle() { + if b.sc != nil && b.state == connectivity.Idle { + b.sc.Connect() + } +} + type picker struct { result balancer.PickResult err error @@ -131,6 +139,17 @@ func (p *picker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { return p.result, p.err } +// idlePicker is used when the SubConn is IDLE and kicks the SubConn into +// CONNECTING when Pick is called. +type idlePicker struct { + sc balancer.SubConn +} + +func (i *idlePicker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { + i.sc.Connect() + return balancer.PickResult{}, balancer.ErrNoSubConnAvailable +} + func init() { balancer.Register(newPickfirstBuilder()) } diff --git a/vendor/google.golang.org/grpc/regenerate.sh b/vendor/google.golang.org/grpc/regenerate.sh index dfd3226a1d..a0a71aae96 100644 --- a/vendor/google.golang.org/grpc/regenerate.sh +++ b/vendor/google.golang.org/grpc/regenerate.sh @@ -102,8 +102,8 @@ done # The go_package option in grpc/lookup/v1/rls.proto doesn't match the # current location. Move it into the right place. -mkdir -p ${WORKDIR}/out/google.golang.org/grpc/balancer/rls/internal/proto/grpc_lookup_v1 -mv ${WORKDIR}/out/google.golang.org/grpc/lookup/grpc_lookup_v1/* ${WORKDIR}/out/google.golang.org/grpc/balancer/rls/internal/proto/grpc_lookup_v1 +mkdir -p ${WORKDIR}/out/google.golang.org/grpc/internal/proto/grpc_lookup_v1 +mv ${WORKDIR}/out/google.golang.org/grpc/lookup/grpc_lookup_v1/* ${WORKDIR}/out/google.golang.org/grpc/internal/proto/grpc_lookup_v1 # grpc_testingv3/testv3.pb.go is not re-generated because it was # intentionally generated by an older version of protoc-gen-go. diff --git a/vendor/google.golang.org/grpc/resolver/map.go b/vendor/google.golang.org/grpc/resolver/map.go new file mode 100644 index 0000000000..e87ecd0eeb --- /dev/null +++ b/vendor/google.golang.org/grpc/resolver/map.go @@ -0,0 +1,109 @@ +/* + * + * Copyright 2021 gRPC 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 resolver + +type addressMapEntry struct { + addr Address + value interface{} +} + +// AddressMap is a map of addresses to arbitrary values taking into account +// Attributes. BalancerAttributes are ignored, as are Metadata and Type. +// Multiple accesses may not be performed concurrently. Must be created via +// NewAddressMap; do not construct directly. +type AddressMap struct { + m map[string]addressMapEntryList +} + +type addressMapEntryList []*addressMapEntry + +// NewAddressMap creates a new AddressMap. +func NewAddressMap() *AddressMap { + return &AddressMap{m: make(map[string]addressMapEntryList)} +} + +// find returns the index of addr in the addressMapEntry slice, or -1 if not +// present. +func (l addressMapEntryList) find(addr Address) int { + if len(l) == 0 { + return -1 + } + for i, entry := range l { + if entry.addr.ServerName == addr.ServerName && + entry.addr.Attributes.Equal(addr.Attributes) { + return i + } + } + return -1 +} + +// Get returns the value for the address in the map, if present. +func (a *AddressMap) Get(addr Address) (value interface{}, ok bool) { + entryList := a.m[addr.Addr] + if entry := entryList.find(addr); entry != -1 { + return entryList[entry].value, true + } + return nil, false +} + +// Set updates or adds the value to the address in the map. +func (a *AddressMap) Set(addr Address, value interface{}) { + entryList := a.m[addr.Addr] + if entry := entryList.find(addr); entry != -1 { + a.m[addr.Addr][entry].value = value + return + } + a.m[addr.Addr] = append(a.m[addr.Addr], &addressMapEntry{addr: addr, value: value}) +} + +// Delete removes addr from the map. +func (a *AddressMap) Delete(addr Address) { + entryList := a.m[addr.Addr] + entry := entryList.find(addr) + if entry == -1 { + return + } + if len(entryList) == 1 { + entryList = nil + } else { + copy(entryList[entry:], entryList[entry+1:]) + entryList = entryList[:len(entryList)-1] + } + a.m[addr.Addr] = entryList +} + +// Len returns the number of entries in the map. +func (a *AddressMap) Len() int { + ret := 0 + for _, entryList := range a.m { + ret += len(entryList) + } + return ret +} + +// Keys returns a slice of all current map keys. +func (a *AddressMap) Keys() []Address { + ret := make([]Address, 0, a.Len()) + for _, entryList := range a.m { + for _, entry := range entryList { + ret = append(ret, entry.addr) + } + } + return ret +} diff --git a/vendor/google.golang.org/grpc/resolver/resolver.go b/vendor/google.golang.org/grpc/resolver/resolver.go index 6a9d234a59..e28b680260 100644 --- a/vendor/google.golang.org/grpc/resolver/resolver.go +++ b/vendor/google.golang.org/grpc/resolver/resolver.go @@ -23,6 +23,7 @@ package resolver import ( "context" "net" + "net/url" "google.golang.org/grpc/attributes" "google.golang.org/grpc/credentials" @@ -116,9 +117,14 @@ type Address struct { ServerName string // Attributes contains arbitrary data about this address intended for - // consumption by the load balancing policy. + // consumption by the SubConn. Attributes *attributes.Attributes + // BalancerAttributes contains arbitrary data about this address intended + // for consumption by the LB policy. These attribes do not affect SubConn + // creation, connection establishment, handshaking, etc. + BalancerAttributes *attributes.Attributes + // Type is the type of this address. // // Deprecated: use Attributes instead. @@ -131,6 +137,15 @@ type Address struct { Metadata interface{} } +// Equal returns whether a and o are identical. Metadata is compared directly, +// not with any recursive introspection. +func (a *Address) Equal(o Address) bool { + return a.Addr == o.Addr && a.ServerName == o.ServerName && + a.Attributes.Equal(o.Attributes) && + a.BalancerAttributes.Equal(o.BalancerAttributes) && + a.Type == o.Type && a.Metadata == o.Metadata +} + // BuildOptions includes additional information for the builder to create // the resolver. type BuildOptions struct { @@ -204,25 +219,36 @@ type ClientConn interface { // Target represents a target for gRPC, as specified in: // https://github.com/grpc/grpc/blob/master/doc/naming.md. -// It is parsed from the target string that gets passed into Dial or DialContext by the user. And -// grpc passes it to the resolver and the balancer. +// It is parsed from the target string that gets passed into Dial or DialContext +// by the user. And gRPC passes it to the resolver and the balancer. // -// If the target follows the naming spec, and the parsed scheme is registered with grpc, we will -// parse the target string according to the spec. e.g. "dns://some_authority/foo.bar" will be parsed -// into &Target{Scheme: "dns", Authority: "some_authority", Endpoint: "foo.bar"} +// If the target follows the naming spec, and the parsed scheme is registered +// with gRPC, we will parse the target string according to the spec. If the +// target does not contain a scheme or if the parsed scheme is not registered +// (i.e. no corresponding resolver available to resolve the endpoint), we will +// apply the default scheme, and will attempt to reparse it. // -// If the target does not contain a scheme, we will apply the default scheme, and set the Target to -// be the full target string. e.g. "foo.bar" will be parsed into -// &Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "foo.bar"}. +// Examples: // -// If the parsed scheme is not registered (i.e. no corresponding resolver available to resolve the -// endpoint), we set the Scheme to be the default scheme, and set the Endpoint to be the full target -// string. e.g. target string "unknown_scheme://authority/endpoint" will be parsed into -// &Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "unknown_scheme://authority/endpoint"}. +// - "dns://some_authority/foo.bar" +// Target{Scheme: "dns", Authority: "some_authority", Endpoint: "foo.bar"} +// - "foo.bar" +// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "foo.bar"} +// - "unknown_scheme://authority/endpoint" +// Target{Scheme: resolver.GetDefaultScheme(), Endpoint: "unknown_scheme://authority/endpoint"} type Target struct { - Scheme string + // Deprecated: use URL.Scheme instead. + Scheme string + // Deprecated: use URL.Host instead. Authority string - Endpoint string + // Deprecated: use URL.Path or URL.Opaque instead. The latter is set when + // the former is empty. + Endpoint string + // URL contains the parsed dial target with an optional default scheme added + // to it if the original dial target contained no scheme or contained an + // unregistered scheme. Any query params specified in the original dial + // target can be accessed from here. + URL url.URL } // Builder creates a resolver that will be used to watch name resolution updates. diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index 87987a2e65..5d407b004b 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -712,13 +712,11 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei if err != nil { return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err) } - } else { - size = len(d) - } - if size > maxReceiveMessageSize { - // TODO: Revisit the error code. Currently keep it consistent with java - // implementation. - return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", size, maxReceiveMessageSize) + if size > maxReceiveMessageSize { + // TODO: Revisit the error code. Currently keep it consistent with java + // implementation. + return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize) + } } return d, nil } diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index 0251f48daf..eadf9e05fd 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -710,13 +710,6 @@ func (s *Server) GetServiceInfo() map[string]ServiceInfo { // the server being stopped. var ErrServerStopped = errors.New("grpc: the server has been stopped") -func (s *Server) useTransportAuthenticator(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { - if s.opts.creds == nil { - return rawConn, nil, nil - } - return s.opts.creds.ServerHandshake(rawConn) -} - type listenSocket struct { net.Listener channelzID int64 @@ -839,35 +832,14 @@ func (s *Server) handleRawConn(lisAddr string, rawConn net.Conn) { return } rawConn.SetDeadline(time.Now().Add(s.opts.connectionTimeout)) - conn, authInfo, err := s.useTransportAuthenticator(rawConn) - if err != nil { - // ErrConnDispatched means that the connection was dispatched away from - // gRPC; those connections should be left open. - if err != credentials.ErrConnDispatched { - // In deployments where a gRPC server runs behind a cloud load - // balancer which performs regular TCP level health checks, the - // connection is closed immediately by the latter. Skipping the - // error here will help reduce log clutter. - if err != io.EOF { - s.mu.Lock() - s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err) - s.mu.Unlock() - channelz.Warningf(logger, s.channelzID, "grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err) - } - rawConn.Close() - } - rawConn.SetDeadline(time.Time{}) - return - } // Finish handshaking (HTTP2) - st := s.newHTTP2Transport(conn, authInfo) + st := s.newHTTP2Transport(rawConn) + rawConn.SetDeadline(time.Time{}) if st == nil { - conn.Close() return } - rawConn.SetDeadline(time.Time{}) if !s.addConn(lisAddr, st) { return } @@ -888,10 +860,11 @@ func (s *Server) drainServerTransports(addr string) { // newHTTP2Transport sets up a http/2 transport (using the // gRPC http2 server transport in transport/http2_server.go). -func (s *Server) newHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) transport.ServerTransport { +func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport { config := &transport.ServerConfig{ MaxStreams: s.opts.maxConcurrentStreams, - AuthInfo: authInfo, + ConnectionTimeout: s.opts.connectionTimeout, + Credentials: s.opts.creds, InTapHandle: s.opts.inTapHandle, StatsHandler: s.opts.statsHandler, KeepaliveParams: s.opts.keepaliveParams, @@ -909,8 +882,15 @@ func (s *Server) newHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) tr s.mu.Lock() s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err) s.mu.Unlock() - c.Close() - channelz.Warning(logger, s.channelzID, "grpc: Server.Serve failed to create ServerTransport: ", err) + // ErrConnDispatched means that the connection was dispatched away from + // gRPC; those connections should be left open. + if err != credentials.ErrConnDispatched { + // Don't log on ErrConnDispatched and io.EOF to prevent log spam. + if err != io.EOF { + channelz.Warning(logger, s.channelzID, "grpc: Server.Serve failed to create ServerTransport: ", err) + } + c.Close() + } return nil } @@ -1124,16 +1104,21 @@ func chainUnaryServerInterceptors(s *Server) { func chainUnaryInterceptors(interceptors []UnaryServerInterceptor) UnaryServerInterceptor { return func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (interface{}, error) { - var i int - var next UnaryHandler - next = func(ctx context.Context, req interface{}) (interface{}, error) { - if i == len(interceptors)-1 { - return interceptors[i](ctx, req, info, handler) - } - i++ - return interceptors[i-1](ctx, req, info, next) + // the struct ensures the variables are allocated together, rather than separately, since we + // know they should be garbage collected together. This saves 1 allocation and decreases + // time/call by about 10% on the microbenchmark. + var state struct { + i int + next UnaryHandler } - return next(ctx, req) + state.next = func(ctx context.Context, req interface{}) (interface{}, error) { + if state.i == len(interceptors)-1 { + return interceptors[state.i](ctx, req, info, handler) + } + state.i++ + return interceptors[state.i-1](ctx, req, info, state.next) + } + return state.next(ctx, req) } } @@ -1409,16 +1394,21 @@ func chainStreamServerInterceptors(s *Server) { func chainStreamInterceptors(interceptors []StreamServerInterceptor) StreamServerInterceptor { return func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error { - var i int - var next StreamHandler - next = func(srv interface{}, ss ServerStream) error { - if i == len(interceptors)-1 { - return interceptors[i](srv, ss, info, handler) - } - i++ - return interceptors[i-1](srv, ss, info, next) + // the struct ensures the variables are allocated together, rather than separately, since we + // know they should be garbage collected together. This saves 1 allocation and decreases + // time/call by about 10% on the microbenchmark. + var state struct { + i int + next StreamHandler } - return next(srv, ss) + state.next = func(srv interface{}, ss ServerStream) error { + if state.i == len(interceptors)-1 { + return interceptors[state.i](srv, ss, info, handler) + } + state.i++ + return interceptors[state.i-1](srv, ss, info, state.next) + } + return state.next(srv, ss) } } diff --git a/vendor/google.golang.org/grpc/stats/stats.go b/vendor/google.golang.org/grpc/stats/stats.go index a5ebeeb693..0285dcc6a2 100644 --- a/vendor/google.golang.org/grpc/stats/stats.go +++ b/vendor/google.golang.org/grpc/stats/stats.go @@ -36,12 +36,12 @@ type RPCStats interface { IsClient() bool } -// Begin contains stats when an RPC begins. +// Begin contains stats when an RPC attempt begins. // FailFast is only valid if this Begin is from client side. type Begin struct { // Client is true if this Begin is from client side. Client bool - // BeginTime is the time when the RPC begins. + // BeginTime is the time when the RPC attempt begins. BeginTime time.Time // FailFast indicates if this RPC is failfast. FailFast bool @@ -49,6 +49,9 @@ type Begin struct { IsClientStream bool // IsServerStream indicates whether the RPC is a server streaming RPC. IsServerStream bool + // IsTransparentRetryAttempt indicates whether this attempt was initiated + // due to transparently retrying a previous attempt. + IsTransparentRetryAttempt bool } // IsClient indicates if the stats information is from client side. diff --git a/vendor/google.golang.org/grpc/status/status.go b/vendor/google.golang.org/grpc/status/status.go index 54d187186b..6d163b6e38 100644 --- a/vendor/google.golang.org/grpc/status/status.go +++ b/vendor/google.golang.org/grpc/status/status.go @@ -29,6 +29,7 @@ package status import ( "context" + "errors" "fmt" spb "google.golang.org/genproto/googleapis/rpc/status" @@ -73,11 +74,16 @@ func FromProto(s *spb.Status) *Status { return status.FromProto(s) } -// FromError returns a Status representing err if it was produced by this -// package or has a method `GRPCStatus() *Status`. -// If err is nil, a Status is returned with codes.OK and no message. -// Otherwise, ok is false and a Status is returned with codes.Unknown and -// the original error message. +// FromError returns a Status representation of err. +// +// - If err was produced by this package or implements the method `GRPCStatus() +// *Status`, the appropriate Status is returned. +// +// - If err is nil, a Status is returned with codes.OK and no message. +// +// - Otherwise, err is an error not compatible with this package. In this +// case, a Status is returned with codes.Unknown and err's Error() message, +// and ok is false. func FromError(err error) (s *Status, ok bool) { if err == nil { return nil, true @@ -112,18 +118,18 @@ func Code(err error) codes.Code { return codes.Unknown } -// FromContextError converts a context error into a Status. It returns a -// Status with codes.OK if err is nil, or a Status with codes.Unknown if err is -// non-nil and not a context error. +// FromContextError converts a context error or wrapped context error into a +// Status. It returns a Status with codes.OK if err is nil, or a Status with +// codes.Unknown if err is non-nil and not a context error. func FromContextError(err error) *Status { - switch err { - case nil: + if err == nil { return nil - case context.DeadlineExceeded: - return New(codes.DeadlineExceeded, err.Error()) - case context.Canceled: - return New(codes.Canceled, err.Error()) - default: - return New(codes.Unknown, err.Error()) } + if errors.Is(err, context.DeadlineExceeded) { + return New(codes.DeadlineExceeded, err.Error()) + } + if errors.Is(err, context.Canceled) { + return New(codes.Canceled, err.Error()) + } + return New(codes.Unknown, err.Error()) } diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index e224af12d2..625d47b34e 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -274,35 +274,6 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client if c.creds != nil { callHdr.Creds = c.creds } - var trInfo *traceInfo - if EnableTracing { - trInfo = &traceInfo{ - tr: trace.New("grpc.Sent."+methodFamily(method), method), - firstLine: firstLine{ - client: true, - }, - } - if deadline, ok := ctx.Deadline(); ok { - trInfo.firstLine.deadline = time.Until(deadline) - } - trInfo.tr.LazyLog(&trInfo.firstLine, false) - ctx = trace.NewContext(ctx, trInfo.tr) - } - ctx = newContextWithRPCInfo(ctx, c.failFast, c.codec, cp, comp) - sh := cc.dopts.copts.StatsHandler - var beginTime time.Time - if sh != nil { - ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: method, FailFast: c.failFast}) - beginTime = time.Now() - begin := &stats.Begin{ - Client: true, - BeginTime: beginTime, - FailFast: c.failFast, - IsClientStream: desc.ClientStreams, - IsServerStream: desc.ServerStreams, - } - sh.HandleRPC(ctx, begin) - } cs := &clientStream{ callHdr: callHdr, @@ -316,7 +287,6 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client cp: cp, comp: comp, cancel: cancel, - beginTime: beginTime, firstAttempt: true, onCommit: onCommit, } @@ -325,9 +295,7 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client } cs.binlog = binarylog.GetMethodLogger(method) - // Only this initial attempt has stats/tracing. - // TODO(dfawley): move to newAttempt when per-attempt stats are implemented. - if err := cs.newAttemptLocked(sh, trInfo); err != nil { + if err := cs.newAttemptLocked(false /* isTransparent */); err != nil { cs.finish(err) return nil, err } @@ -375,8 +343,43 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client // newAttemptLocked creates a new attempt with a transport. // If it succeeds, then it replaces clientStream's attempt with this new attempt. -func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo *traceInfo) (retErr error) { +func (cs *clientStream) newAttemptLocked(isTransparent bool) (retErr error) { + ctx := newContextWithRPCInfo(cs.ctx, cs.callInfo.failFast, cs.callInfo.codec, cs.cp, cs.comp) + method := cs.callHdr.Method + sh := cs.cc.dopts.copts.StatsHandler + var beginTime time.Time + if sh != nil { + ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: method, FailFast: cs.callInfo.failFast}) + beginTime = time.Now() + begin := &stats.Begin{ + Client: true, + BeginTime: beginTime, + FailFast: cs.callInfo.failFast, + IsClientStream: cs.desc.ClientStreams, + IsServerStream: cs.desc.ServerStreams, + IsTransparentRetryAttempt: isTransparent, + } + sh.HandleRPC(ctx, begin) + } + + var trInfo *traceInfo + if EnableTracing { + trInfo = &traceInfo{ + tr: trace.New("grpc.Sent."+methodFamily(method), method), + firstLine: firstLine{ + client: true, + }, + } + if deadline, ok := ctx.Deadline(); ok { + trInfo.firstLine.deadline = time.Until(deadline) + } + trInfo.tr.LazyLog(&trInfo.firstLine, false) + ctx = trace.NewContext(ctx, trInfo.tr) + } + newAttempt := &csAttempt{ + ctx: ctx, + beginTime: beginTime, cs: cs, dc: cs.cc.dopts.dc, statsHandler: sh, @@ -391,15 +394,14 @@ func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo *traceInfo) (r } }() - if err := cs.ctx.Err(); err != nil { + if err := ctx.Err(); err != nil { return toRPCErr(err) } - ctx := cs.ctx if cs.cc.parsedTarget.Scheme == "xds" { // Add extra metadata (metadata that will be added by transport) to context // so the balancer can see them. - ctx = grpcutil.WithExtraMetadata(cs.ctx, metadata.Pairs( + ctx = grpcutil.WithExtraMetadata(ctx, metadata.Pairs( "content-type", grpcutil.ContentType(cs.callHdr.ContentSubtype), )) } @@ -419,7 +421,7 @@ func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo *traceInfo) (r func (a *csAttempt) newStream() error { cs := a.cs cs.callHdr.PreviousAttempts = cs.numRetries - s, err := a.t.NewStream(cs.ctx, cs.callHdr) + s, err := a.t.NewStream(a.ctx, cs.callHdr) if err != nil { // Return without converting to an RPC error so retry code can // inspect. @@ -444,8 +446,7 @@ type clientStream struct { cancel context.CancelFunc // cancels all attempts - sentLast bool // sent an end stream - beginTime time.Time + sentLast bool // sent an end stream methodConfig *MethodConfig @@ -485,6 +486,7 @@ type clientStream struct { // csAttempt implements a single transport stream attempt within a // clientStream. type csAttempt struct { + ctx context.Context cs *clientStream t transport.ClientTransport s *transport.Stream @@ -503,6 +505,7 @@ type csAttempt struct { trInfo *traceInfo statsHandler stats.Handler + beginTime time.Time } func (cs *clientStream) commitAttemptLocked() { @@ -520,15 +523,16 @@ func (cs *clientStream) commitAttempt() { } // shouldRetry returns nil if the RPC should be retried; otherwise it returns -// the error that should be returned by the operation. -func (cs *clientStream) shouldRetry(err error) error { +// the error that should be returned by the operation. If the RPC should be +// retried, the bool indicates whether it is being retried transparently. +func (cs *clientStream) shouldRetry(err error) (bool, error) { if cs.attempt.s == nil { // Error from NewClientStream. nse, ok := err.(*transport.NewStreamError) if !ok { // Unexpected, but assume no I/O was performed and the RPC is not // fatal, so retry indefinitely. - return nil + return true, nil } // Unwrap and convert error. @@ -537,19 +541,19 @@ func (cs *clientStream) shouldRetry(err error) error { // Never retry DoNotRetry errors, which indicate the RPC should not be // retried due to max header list size violation, etc. if nse.DoNotRetry { - return err + return false, err } // In the event of a non-IO operation error from NewStream, we never // attempted to write anything to the wire, so we can retry // indefinitely. - if !nse.PerformedIO { - return nil + if !nse.DoNotTransparentRetry { + return true, nil } } if cs.finished || cs.committed { // RPC is finished or committed; cannot retry. - return err + return false, err } // Wait for the trailers. unprocessed := false @@ -559,17 +563,17 @@ func (cs *clientStream) shouldRetry(err error) error { } if cs.firstAttempt && unprocessed { // First attempt, stream unprocessed: transparently retry. - return nil + return true, nil } if cs.cc.dopts.disableRetry { - return err + return false, err } pushback := 0 hasPushback := false if cs.attempt.s != nil { if !cs.attempt.s.TrailersOnly() { - return err + return false, err } // TODO(retry): Move down if the spec changes to not check server pushback @@ -580,13 +584,13 @@ func (cs *clientStream) shouldRetry(err error) error { if pushback, e = strconv.Atoi(sps[0]); e != nil || pushback < 0 { channelz.Infof(logger, cs.cc.channelzID, "Server retry pushback specified to abort (%q).", sps[0]) cs.retryThrottler.throttle() // This counts as a failure for throttling. - return err + return false, err } hasPushback = true } else if len(sps) > 1 { channelz.Warningf(logger, cs.cc.channelzID, "Server retry pushback specified multiple values (%q); not retrying.", sps) cs.retryThrottler.throttle() // This counts as a failure for throttling. - return err + return false, err } } @@ -599,16 +603,16 @@ func (cs *clientStream) shouldRetry(err error) error { rp := cs.methodConfig.RetryPolicy if rp == nil || !rp.RetryableStatusCodes[code] { - return err + return false, err } // Note: the ordering here is important; we count this as a failure // only if the code matched a retryable code. if cs.retryThrottler.throttle() { - return err + return false, err } if cs.numRetries+1 >= rp.MaxAttempts { - return err + return false, err } var dur time.Duration @@ -631,10 +635,10 @@ func (cs *clientStream) shouldRetry(err error) error { select { case <-t.C: cs.numRetries++ - return nil + return false, nil case <-cs.ctx.Done(): t.Stop() - return status.FromContextError(cs.ctx.Err()).Err() + return false, status.FromContextError(cs.ctx.Err()).Err() } } @@ -642,12 +646,13 @@ func (cs *clientStream) shouldRetry(err error) error { func (cs *clientStream) retryLocked(lastErr error) error { for { cs.attempt.finish(toRPCErr(lastErr)) - if err := cs.shouldRetry(lastErr); err != nil { + isTransparent, err := cs.shouldRetry(lastErr) + if err != nil { cs.commitAttemptLocked() return err } cs.firstAttempt = false - if err := cs.newAttemptLocked(nil, nil); err != nil { + if err := cs.newAttemptLocked(isTransparent); err != nil { return err } if lastErr = cs.replayBufferLocked(); lastErr == nil { @@ -937,7 +942,7 @@ func (a *csAttempt) sendMsg(m interface{}, hdr, payld, data []byte) error { return io.EOF } if a.statsHandler != nil { - a.statsHandler.HandleRPC(cs.ctx, outPayload(true, m, data, payld, time.Now())) + a.statsHandler.HandleRPC(a.ctx, outPayload(true, m, data, payld, time.Now())) } if channelz.IsOn() { a.t.IncrMsgSent() @@ -985,7 +990,7 @@ func (a *csAttempt) recvMsg(m interface{}, payInfo *payloadInfo) (err error) { a.mu.Unlock() } if a.statsHandler != nil { - a.statsHandler.HandleRPC(cs.ctx, &stats.InPayload{ + a.statsHandler.HandleRPC(a.ctx, &stats.InPayload{ Client: true, RecvTime: time.Now(), Payload: m, @@ -1047,12 +1052,12 @@ func (a *csAttempt) finish(err error) { if a.statsHandler != nil { end := &stats.End{ Client: true, - BeginTime: a.cs.beginTime, + BeginTime: a.beginTime, EndTime: time.Now(), Trailer: tr, Error: err, } - a.statsHandler.HandleRPC(a.cs.ctx, end) + a.statsHandler.HandleRPC(a.ctx, end) } if a.trInfo != nil && a.trInfo.tr != nil { if err == nil { diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index e3510e10f1..8ef0958797 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.40.0" +const Version = "1.43.0" diff --git a/vendor/google.golang.org/grpc/vet.sh b/vendor/google.golang.org/grpc/vet.sh index 5eaa8b05d6..d923187a7b 100644 --- a/vendor/google.golang.org/grpc/vet.sh +++ b/vendor/google.golang.org/grpc/vet.sh @@ -89,10 +89,6 @@ not git grep "\(import \|^\s*\)\"github.com/golang/protobuf/ptypes/" -- "*.go" # - Ensure all xds proto imports are renamed to *pb or *grpc. git grep '"github.com/envoyproxy/go-control-plane/envoy' -- '*.go' ':(exclude)*.pb.go' | not grep -v 'pb "\|grpc "' -# - Check imports that are illegal in appengine (until Go 1.11). -# TODO: Remove when we drop Go 1.10 support -go list -f {{.Dir}} ./... | xargs go run test/go_vet/vet.go - misspell -error . # - Check that generated proto files are up to date. diff --git a/vendor/modules.txt b/vendor/modules.txt index ef5d1aca5c..dc5262c953 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -147,7 +147,7 @@ github.com/containerd/cgroups/v2/stats # github.com/containerd/console v1.0.3 ## explicit; go 1.13 github.com/containerd/console -# github.com/containerd/containerd v1.5.10 +# github.com/containerd/containerd v1.6.1 ## explicit; go 1.16 github.com/containerd/containerd github.com/containerd/containerd/api/events @@ -691,12 +691,12 @@ github.com/prometheus/client_golang/prometheus/promhttp # github.com/prometheus/client_model v0.2.0 ## explicit; go 1.9 github.com/prometheus/client_model/go -# github.com/prometheus/common v0.10.0 -## explicit; go 1.11 +# github.com/prometheus/common v0.30.0 +## explicit; go 1.13 github.com/prometheus/common/expfmt github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg github.com/prometheus/common/model -# github.com/prometheus/procfs v0.6.0 => github.com/prometheus/procfs v0.0.11 +# github.com/prometheus/procfs v0.7.3 => github.com/prometheus/procfs v0.0.11 ## explicit; go 1.12 github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs @@ -734,7 +734,7 @@ github.com/tonistiigi/units github.com/vbatts/tar-split/archive/tar github.com/vbatts/tar-split/tar/asm github.com/vbatts/tar-split/tar/storage -# github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852 => github.com/vishvananda/netlink v1.1.0 +# github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5 => github.com/vishvananda/netlink v1.1.0 ## explicit; go 1.12 github.com/vishvananda/netlink github.com/vishvananda/netlink/nl @@ -828,7 +828,7 @@ golang.org/x/lint/golint ## explicit; go 1.12 golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 +# golang.org/x/net v0.0.0-20211216030914-fe4d6282115f ## explicit; go 1.17 golang.org/x/net/bpf golang.org/x/net/context @@ -937,8 +937,8 @@ google.golang.org/genproto/googleapis/api/monitoredres google.golang.org/genproto/googleapis/logging/type google.golang.org/genproto/googleapis/logging/v2 google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.40.0 -## explicit; go 1.11 +# google.golang.org/grpc v1.43.0 +## explicit; go 1.14 google.golang.org/grpc google.golang.org/grpc/attributes google.golang.org/grpc/backoff @@ -960,6 +960,7 @@ google.golang.org/grpc/credentials/alts/internal/handshaker google.golang.org/grpc/credentials/alts/internal/handshaker/service google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp google.golang.org/grpc/credentials/google +google.golang.org/grpc/credentials/insecure google.golang.org/grpc/credentials/oauth google.golang.org/grpc/encoding google.golang.org/grpc/encoding/proto