vendor: update buildkit to 2f99651

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
pull/948/head
CrazyMax 3 years ago
parent 60a025b227
commit 307c94e5c7
No known key found for this signature in database
GPG Key ID: 3248E46B6BB8C7F7

@ -10,8 +10,8 @@ require (
github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e // indirect github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e // indirect
github.com/compose-spec/compose-go v1.0.8 github.com/compose-spec/compose-go v1.0.8
github.com/containerd/console v1.0.3 github.com/containerd/console v1.0.3
github.com/containerd/containerd v1.6.0-beta.3 github.com/containerd/containerd v1.6.0-rc.1
github.com/docker/cli v20.10.11+incompatible github.com/docker/cli v20.10.12+incompatible
github.com/docker/cli-docs-tool v0.3.0 github.com/docker/cli-docs-tool v0.3.0
github.com/docker/compose-on-kubernetes v0.4.19-0.20190128150448-356b2919c496 // indirect github.com/docker/compose-on-kubernetes v0.4.19-0.20190128150448-356b2919c496 // indirect
github.com/docker/distribution v2.7.1+incompatible github.com/docker/distribution v2.7.1+incompatible
@ -31,10 +31,10 @@ require (
github.com/jinzhu/gorm v1.9.2 // indirect github.com/jinzhu/gorm v1.9.2 // indirect
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a // indirect github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a // indirect
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
github.com/moby/buildkit v0.9.1-0.20211215010209-539be1708964 github.com/moby/buildkit v0.9.1-0.20220209015936-2f996517bcbd
github.com/morikuni/aec v1.0.0 github.com/morikuni/aec v1.0.0
github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283 github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5
github.com/pelletier/go-toml v1.9.4 github.com/pelletier/go-toml v1.9.4
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002
@ -44,21 +44,22 @@ require (
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/theupdateframework/notary v0.6.1 // indirect github.com/theupdateframework/notary v0.6.1 // indirect
github.com/zclconf/go-cty v1.10.0 github.com/zclconf/go-cty v1.10.0
go.opentelemetry.io/otel v1.2.0 go.opentelemetry.io/otel v1.3.0
go.opentelemetry.io/otel/trace v1.2.0 go.opentelemetry.io/otel/trace v1.3.0
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
google.golang.org/grpc v1.42.0 google.golang.org/grpc v1.44.0
gopkg.in/dancannon/gorethink.v3 v3.0.5 // indirect gopkg.in/dancannon/gorethink.v3 v3.0.5 // indirect
gopkg.in/fatih/pool.v2 v2.0.0 // indirect gopkg.in/fatih/pool.v2 v2.0.0 // indirect
gopkg.in/gorethink/gorethink.v3 v3.0.5 // indirect gopkg.in/gorethink/gorethink.v3 v3.0.5 // indirect
k8s.io/api v0.22.4 k8s.io/api v0.23.3
k8s.io/apimachinery v0.22.4 k8s.io/apimachinery v0.23.3
k8s.io/client-go v0.22.4 k8s.io/client-go v0.23.3
) )
replace ( replace (
github.com/docker/cli => github.com/docker/cli v20.10.3-0.20210702143511-f782d1355eff+incompatible github.com/docker/cli => github.com/docker/cli v20.10.3-0.20210702143511-f782d1355eff+incompatible
github.com/docker/docker => github.com/docker/docker v20.10.3-0.20211216190657-088afc99e4bf+incompatible github.com/docker/docker => github.com/docker/docker v20.10.3-0.20211216190657-088afc99e4bf+incompatible
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace => github.com/tonistiigi/opentelemetry-go-contrib/instrumentation/net/http/httptrace/otelhttptrace v0.0.0-20211026174723-2f82a1e0c997 k8s.io/api => k8s.io/api v0.22.4
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp => github.com/tonistiigi/opentelemetry-go-contrib/instrumentation/net/http/otelhttp v0.0.0-20211026174723-2f82a1e0c997 k8s.io/apimachinery => k8s.io/apimachinery v0.22.4
k8s.io/client-go => k8s.io/client-go v0.22.4
) )

230
go.sum

@ -14,7 +14,6 @@ cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxK
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
@ -80,17 +79,13 @@ github.com/Azure/go-autorest v14.1.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSW
github.com/Azure/go-autorest v14.2.0+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.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
github.com/Azure/go-autorest/autorest v0.10.2/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= github.com/Azure/go-autorest/autorest v0.10.2/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
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 v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
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/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM=
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw=
@ -100,14 +95,12 @@ github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSY
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
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/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc=
github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI=
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
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/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
@ -130,7 +123,6 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
@ -143,8 +135,9 @@ github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= 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.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
github.com/Microsoft/hcsshim v0.9.1 h1:VfDCj+QnY19ktX5TsH22JHcjaZ05RWQiwDbOyEg5ziM= github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg=
github.com/Microsoft/hcsshim v0.9.1/go.mod h1:Y/0uV2jUab5kBI7SQgl62at0AVX7uaruzADAVmxm3eM= github.com/Microsoft/hcsshim v0.9.2 h1:wB06W5aYFfUB3IvootYAY2WnOmIdgPGfqSI6tufQNnY=
github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/Microsoft/hcsshim/test v0.0.0-20200826032352-301c83a30e7c/go.mod h1:30A5igQ91GEmhYJF8TaRP79pMBOYynRsyOByfVV0dU4= github.com/Microsoft/hcsshim/test v0.0.0-20200826032352-301c83a30e7c/go.mod h1:30A5igQ91GEmhYJF8TaRP79pMBOYynRsyOByfVV0dU4=
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= 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/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
@ -192,6 +185,7 @@ github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJE
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
@ -246,18 +240,21 @@ github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMS
github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A=
github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY=
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 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-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@ -266,6 +263,7 @@ github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLI
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e h1:Qux+lbuMaRzkQyTdzgtz8MgzPtzmaPQy6DXmxpdxT3U= github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e h1:Qux+lbuMaRzkQyTdzgtz8MgzPtzmaPQy6DXmxpdxT3U=
github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
@ -320,18 +318,16 @@ github.com/containerd/containerd v1.4.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMX
github.com/containerd/containerd v1.4.1-0.20201117152358-0edc412565dc/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.4.1-0.20201117152358-0edc412565dc/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ= github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ=
github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU=
github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
github.com/containerd/containerd v1.6.0-beta.2.0.20211117185425-a776a27af54a/go.mod h1:0AwP8LDBKEIaCT48IETmHkY1+YX7c/ALcN1kkLGBLtk= github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s=
github.com/containerd/containerd v1.6.0-beta.3 h1:hcReMLP6dEydYjWytRKJB0TzHiZY3PZJMZd5vzWw5cM= github.com/containerd/containerd v1.6.0-rc.1 h1:bFSTay5ZHCSmAE/hzubBXX+eUpptHprbXi0QELuUk0Y=
github.com/containerd/containerd v1.6.0-beta.3/go.mod h1:EcsfYDRjW5oqSSRLCiPDI+6Swair1K2O3nPlL7F9UtA= github.com/containerd/containerd v1.6.0-rc.1/go.mod h1:jdeOXdXovU4bWF2Bd2hJjqpcOrrpSC1wmFCTtf6LD+A=
github.com/containerd/containerd/api v1.6.0-beta.1/go.mod h1:XDzkCoLyj2hn24f13Jcuq/U2bHb2LjJ2qWlklgL0Ofg=
github.com/containerd/containerd/api v1.6.0-beta.3 h1:+w8zh0hbn4cNIkAtt4v95dBylcwp1hEsFJ5lxbr8wgY=
github.com/containerd/containerd/api v1.6.0-beta.3/go.mod h1:fkctx1jj7m92mQDI6mIEXF+SH3tt2Rv/azUHqrOxYPc=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= 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-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
@ -339,9 +335,8 @@ github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cE
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
github.com/containerd/continuity v0.2.0/go.mod h1:wCYX+dRqZdImhGucXOqTQn05AhX6EUDaGEMUzTFFpLg= github.com/containerd/continuity v0.2.2 h1:QSqfxcn8c+12slxwu00AtzXrsami0MJb/MQs9lOLHLA=
github.com/containerd/continuity v0.2.1 h1:/EeEo2EtN3umhbbgCveyjifoMYg0pS+nMMEemaYw634= github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk=
github.com/containerd/continuity v0.2.1/go.mod h1:wCYX+dRqZdImhGucXOqTQn05AhX6EUDaGEMUzTFFpLg=
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
@ -352,7 +347,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/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.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.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk=
github.com/containerd/go-cni v1.1.1-0.20211026134925-aa8bf14323a5/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= github.com/containerd/go-cni v1.1.0/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA=
github.com/containerd/go-cni v1.1.1/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-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-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
@ -362,14 +358,14 @@ 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.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-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.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-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.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
github.com/containerd/stargz-snapshotter v0.0.0-20201027054423-3a04e4c2c116/go.mod h1:o59b3PCKVAf9jjiKtCc/9hLAd+5p/rfhBfm6aBcTEr4= github.com/containerd/stargz-snapshotter v0.0.0-20201027054423-3a04e4c2c116/go.mod h1:o59b3PCKVAf9jjiKtCc/9hLAd+5p/rfhBfm6aBcTEr4=
github.com/containerd/stargz-snapshotter v0.10.2-0.20211202025742-84f1bebf056d/go.mod h1:JvTcHWJAuDFJjGbzmTTRsxE6tV+2q85LzipJlhvUzts= github.com/containerd/stargz-snapshotter v0.11.0/go.mod h1:4uHVxcpajrdsb7lTjhQ9Aw2iYicB7szTSFu4YqDOpTo=
github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM= github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM=
github.com/containerd/stargz-snapshotter/estargz v0.10.1/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0= github.com/containerd/stargz-snapshotter/estargz v0.11.0/go.mod h1:/KsZXsJRllMbTKFfG0miFQWViQKdI9+9aSXs+HN0+ac=
github.com/containerd/stargz-snapshotter/estargz v0.10.2-0.20211202025742-84f1bebf056d/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
@ -397,6 +393,7 @@ github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNB
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= 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.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4=
github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= 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/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@ -425,6 +422,7 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
@ -477,14 +475,12 @@ github.com/docker/libnetwork v0.8.0-dev.2.0.20200917202933-d0951081b35f/go.mod h
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docker/libtrust v0.0.0-20150526203908-9cbd2a1374f4 h1:k8TfKGeAcDQFFQOGCQMRN04N4a9YrPlRMMKnzAuvM9Q= github.com/docker/libtrust v0.0.0-20150526203908-9cbd2a1374f4 h1:k8TfKGeAcDQFFQOGCQMRN04N4a9YrPlRMMKnzAuvM9Q=
github.com/docker/libtrust v0.0.0-20150526203908-9cbd2a1374f4/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/libtrust v0.0.0-20150526203908-9cbd2a1374f4/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484 h1:pEtiCjIXx3RvGjlUJuCNxNOw0MNblyR9Wi+vJGBFh+8= github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484 h1:pEtiCjIXx3RvGjlUJuCNxNOw0MNblyR9Wi+vJGBFh+8=
github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
@ -540,8 +536,14 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= 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.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.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
github.com/go-logr/logr v0.4.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 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs=
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 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= 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.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
@ -586,6 +588,7 @@ github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblf
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/flock v0.7.3 h1:I0EKY9l8HZCXTMYC4F80vwT6KNypV9uYKP3Alm/hjmQ= github.com/gofrs/flock v0.7.3 h1:I0EKY9l8HZCXTMYC4F80vwT6KNypV9uYKP3Alm/hjmQ=
github.com/gofrs/flock v0.7.3/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/flock v0.7.3/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
@ -695,8 +698,9 @@ github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwG
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.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 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
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 v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+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.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@ -775,11 +779,12 @@ github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok=
github.com/hanwen/go-fuse/v2 v2.0.3/go.mod h1:0EQM6aH2ctVpvZ6a+onrQ/vaykxh2GH7hy3e13vzTUY= github.com/hanwen/go-fuse/v2 v2.0.3/go.mod h1:0EQM6aH2ctVpvZ6a+onrQ/vaykxh2GH7hy3e13vzTUY=
github.com/hanwen/go-fuse/v2 v2.1.1-0.20210825171523-3ab5d95a30ae/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= github.com/hanwen/go-fuse/v2 v2.1.1-0.20220112183258-f57e95bda82d/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840 h1:kgvybwEeu0SXktbB2y3uLHX9lklLo+nzUwh59A3jzQc= github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840 h1:kgvybwEeu0SXktbB2y3uLHX9lklLo+nzUwh59A3jzQc=
github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840/go.mod h1:Abjk0jbRkDaNCzsRhOv2iDCofYpX1eVsjozoiK63qLA= github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840/go.mod h1:Abjk0jbRkDaNCzsRhOv2iDCofYpX1eVsjozoiK63qLA=
@ -824,6 +829,7 @@ 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/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 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 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-20191218070446-00ab2ac2db07/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg= github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg= 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 v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
@ -856,8 +862,9 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/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.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
github.com/json-iterator/go v1.1.11/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 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
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.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 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/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
@ -873,8 +880,8 @@ github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.14.2 h1:S0OHlFk/Gbon/yauFJ4FfJJF5V0fc5HbBTJazi28pRw=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@ -963,8 +970,8 @@ github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7p
github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/moby/buildkit v0.8.1/go.mod h1:/kyU1hKy/aYCuP39GZA9MaKioovHku57N6cqlKZIaiQ= github.com/moby/buildkit v0.8.1/go.mod h1:/kyU1hKy/aYCuP39GZA9MaKioovHku57N6cqlKZIaiQ=
github.com/moby/buildkit v0.9.1-0.20211215010209-539be1708964 h1:UVHoIeqUli4wJRK4he51g3e9ppwC8fu0GcdflKKfpBs= github.com/moby/buildkit v0.9.1-0.20220209015936-2f996517bcbd h1:rqNmMDatViLu3yzP/P20nw71dDLe0MKh7p+7LhFouWM=
github.com/moby/buildkit v0.9.1-0.20211215010209-539be1708964/go.mod h1:9qjv1ebiP/IFv49pXpJSRzG5zhXDqZV7XT518wIqs00= github.com/moby/buildkit v0.9.1-0.20220209015936-2f996517bcbd/go.mod h1:kLbnj6pNOawKdiMIdwbu87s1SIJxSAxG1mWLQfXrjzI=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= 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/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
@ -993,8 +1000,9 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/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-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
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 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
@ -1047,8 +1055,8 @@ 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/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.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.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283 h1:TVzvdjOalkJBNkbpPVMAr4KV9QRf2IjfxdyxwAK78Gs= github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5 h1:q37d91F6BO4Jp1UqWiun0dUFYaqv6WsKTLTCaWv+8LY=
github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc10/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc10/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
@ -1056,8 +1064,9 @@ github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc92/go.mod h1:X1zlU4p7wOlX4+WRCz+hvlRv8phdL7UqbYD+vQwNMmE= github.com/opencontainers/runc v1.0.0-rc92/go.mod h1:X1zlU4p7wOlX4+WRCz+hvlRv8phdL7UqbYD+vQwNMmE=
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg=
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runc v1.1.0 h1:O9+X96OcDjkmmZyfaG996kV7yq8HsoU2h1XRRQcefG8=
github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
@ -1109,8 +1118,9 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg=
github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@ -1126,8 +1136,10 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@ -1140,8 +1152,9 @@ github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
github.com/quasilyte/go-ruleguard v0.1.2-0.20200318202121-b00d7a75d3d8/go.mod h1:CGFX09Ci3pq9QZdj86B+VGIdNj4VyCo2iPOGS9esB/k= github.com/quasilyte/go-ruleguard v0.1.2-0.20200318202121-b00d7a75d3d8/go.mod h1:CGFX09Ci3pq9QZdj86B+VGIdNj4VyCo2iPOGS9esB/k=
@ -1169,6 +1182,7 @@ github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZ
github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83/go.mod h1:vvbZ2Ae7AzSq3/kywjUDxSNq2SJ27RxCz2un0H3ePqE= github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83/go.mod h1:vvbZ2Ae7AzSq3/kywjUDxSNq2SJ27RxCz2un0H3ePqE=
github.com/securego/gosec v0.0.0-20200401082031-e946c8c39989/go.mod h1:i9l/TNj+yDFh9SZXUTvspXTjbFXgZGP/UvhU1S65A4A= github.com/securego/gosec v0.0.0-20200401082031-e946c8c39989/go.mod h1:i9l/TNj+yDFh9SZXUTvspXTjbFXgZGP/UvhU1S65A4A=
github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME= github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME=
@ -1274,10 +1288,6 @@ github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85/go.mod h1:a7cilN
github.com/tonistiigi/fsutil v0.0.0-20211208180946-61a57076b9b0 h1:1s9pEdOzN6AuOsBXKpAoSVupUDsGx2v6Fee/hIto8Vg= github.com/tonistiigi/fsutil v0.0.0-20211208180946-61a57076b9b0 h1:1s9pEdOzN6AuOsBXKpAoSVupUDsGx2v6Fee/hIto8Vg=
github.com/tonistiigi/fsutil v0.0.0-20211208180946-61a57076b9b0/go.mod h1:oPAfvw32vlUJSjyDcQ3Bu0nb2ON2B+G0dtVN/SZNJiA= github.com/tonistiigi/fsutil v0.0.0-20211208180946-61a57076b9b0/go.mod h1:oPAfvw32vlUJSjyDcQ3Bu0nb2ON2B+G0dtVN/SZNJiA=
github.com/tonistiigi/go-actions-cache v0.0.0-20211202175116-9642704158ff/go.mod h1:qqvyZqkfwkoJuPU/bw61bItaoO0SJ8YSW0vSVRRvsRg= github.com/tonistiigi/go-actions-cache v0.0.0-20211202175116-9642704158ff/go.mod h1:qqvyZqkfwkoJuPU/bw61bItaoO0SJ8YSW0vSVRRvsRg=
github.com/tonistiigi/opentelemetry-go-contrib/instrumentation/net/http/httptrace/otelhttptrace v0.0.0-20211026174723-2f82a1e0c997 h1:4ZQ1aJo69twFu6BZBXYFDWy/jch1nk+VhpKh84ksoz4=
github.com/tonistiigi/opentelemetry-go-contrib/instrumentation/net/http/httptrace/otelhttptrace v0.0.0-20211026174723-2f82a1e0c997/go.mod h1:rU1ZQVaT9Yg2RUFvjYjuTtBd731QQbKOGcYK/QlcGe4=
github.com/tonistiigi/opentelemetry-go-contrib/instrumentation/net/http/otelhttp v0.0.0-20211026174723-2f82a1e0c997 h1:L8kP1W3WsC6tlCpYsrq/7foSVA4+Pscftua9FN5cvVw=
github.com/tonistiigi/opentelemetry-go-contrib/instrumentation/net/http/otelhttp v0.0.0-20211026174723-2f82a1e0c997/go.mod h1:7W3JSDYTtH3qKKHrS1fMiwLtK7iZFLPq1+7htfspX/E=
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0= github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0=
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk= github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk=
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f h1:DLpt6B5oaaS8jyXHa9VA4rrZloBVPVXeCtrOsrFauxc= github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f h1:DLpt6B5oaaS8jyXHa9VA4rrZloBVPVXeCtrOsrFauxc=
@ -1370,50 +1380,52 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0= go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0=
go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= 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.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.24.0/go.mod h1:O0cG0vP6TP3c323kh70JmeG1jN69Sn9Z5HxgmeASFWY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0 h1:Ky1MObd188aGbgb5OgNnwGuEEwI9MVIcc7rBW6zk5Ak=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.27.0 h1:TON1iU3Y5oIytGQHIejDYLam5uoSMsmA0UV9Yupb5gQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.27.0/go.mod h1:T/zQwBldOpoAEpE3HMbLnI8ydESZVz4ggw6Is4FF9LI= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.27.1-0.20211201163413-2bb24f926b80 h1:jofr8vPPRwgd1Z3dIpVmJ1TuYaYSHTUvOB+BngCpuKA=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.27.1-0.20211201163413-2bb24f926b80/go.mod h1:zCf+wGILpPxOvJY3ZbqPz1pa5phMScFXVhhwa6knQlg=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.28.1-0.20220111222512-7e31ebe04030 h1:UY7EGos9NAfUImvpQ1OnP5FCTKETWpHdiWLnZ6E3Rn0=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.28.1-0.20220111222512-7e31ebe04030/go.mod h1:Ihno+mNBfZlT0Qot3XyRTdZ/9U/Cg2Pfgj75DTdIfq4=
go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo=
go.opentelemetry.io/otel v1.0.0-RC3/go.mod h1:Ka5j3ua8tZs4Rkq4Ex3hwgBgOchyPVq5S6P2lz//nKQ=
go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU=
go.opentelemetry.io/otel v1.2.0 h1:YOQDvxO1FayUcT9MIhJhgMyNO1WqoduiyvQHzGN0kUQ=
go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I= go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I=
go.opentelemetry.io/otel/exporters/jaeger v1.0.1/go.mod h1:85Ym3qknJdIdfRzYS9Ofy9NeLi9gKPFzFDBEHCKpfXI= go.opentelemetry.io/otel v1.3.0 h1:APxLf0eiBwLl+SOXiJJCVYzA1OOJNyAoV8C5RNRyy7Y=
go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs=
go.opentelemetry.io/otel/exporters/jaeger v1.3.0/go.mod h1:KoYHi1BtkUPncGSRtCe/eh1ijsnePhSkxwzz07vU0Fc=
go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg= go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg=
go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1 h1:ofMbch7i29qIUf7VtF+r0HRF6ac0SBaPSziSsKp7wkk= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0 h1:R/OBkMoGgfy2fLhs2QhkCI1w4HLEQX92GCcJB6SSdNk=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw= 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/otlptracegrpc v1.0.1 h1:CFMFNoz+CGprjFAFy+RJFrfEe4GBia3RRm2a4fREvCA= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0 h1:giGm8w67Ja7amYNfYMdme7xSp2pIxThWopw8+QP51Yk=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1/go.mod h1:xOvWoTOrQjxjW61xtOmD/WKGRYb/P4NzRo3bs65U6Rk= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.0.1 h1:cL0lzRTwaR913f59F9AzWF3ky4W7nTOJUq9ESqS8OPg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0 h1:VQbUHoJqytHHSJ1OZodPH9tvZZSVzUHjPHpkO85sT6k=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.0.1/go.mod h1:QGQYgio16DMgAyFfC8TFlf4XUmAcSvuwzPjt7hoJEJg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY=
go.opentelemetry.io/otel/internal/metric v0.23.0/go.mod h1:z+RPiDJe30YnCrOhFGivwBS+DU1JU/PiLKkk4re2DNY= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0 h1:Ydage/P0fRrSPpZeCVxzjqGcI6iVmG2xb43+IR8cjqM=
go.opentelemetry.io/otel/internal/metric v0.24.0 h1:O5lFy6kAl0LMWBjzy3k//M8VjEaTDWL9DPJuqZmWIAA= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE=
go.opentelemetry.io/otel/internal/metric v0.24.0/go.mod h1:PSkQG+KuApZjBpC6ea6082ZrWUUy/w132tJ/LOU3TXk= go.opentelemetry.io/otel/internal/metric v0.26.0 h1:dlrvawyd/A+X8Jp0EBT4wWEe4k5avYaXsXrBr4dbfnY=
go.opentelemetry.io/otel/internal/metric v0.26.0/go.mod h1:CbBP6AxKynRs3QCbhklyLUtpfzbqCLiafV9oY2Zj1Jk=
go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU=
go.opentelemetry.io/otel/metric v0.23.0/go.mod h1:G/Nn9InyNnIv7J6YVkQfpc0JCfKBNJaERBGw08nqmVQ= go.opentelemetry.io/otel/metric v0.26.0 h1:VaPYBTvA13h/FsiWfxa3yZnZEm15BhStD8JZQSA773M=
go.opentelemetry.io/otel/metric v0.24.0 h1:Rg4UYHS6JKR1Sw1TxnI13z7q/0p/XAbgIqUTagvLJuU= go.opentelemetry.io/otel/metric v0.26.0/go.mod h1:c6YL0fhRo4YVoNs6GoByzUgBp36hBL523rECoZA5UWg=
go.opentelemetry.io/otel/metric v0.24.0/go.mod h1:tpMFnCD9t+BEGiWY2bWF5+AwjuAdM0lSowQ4SBA3/K4=
go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= 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 v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc=
go.opentelemetry.io/otel/sdk v1.0.1 h1:wXxFEWGo7XfXupPwVJvTBOaPBC9FEg0wB8hMNrKk+cA= go.opentelemetry.io/otel/sdk v1.3.0 h1:3278edCoH89MEJ0Ky8WQXVmDQv3FX4ZJ3Pp+9fJreAI=
go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI= 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/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/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 v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw=
go.opentelemetry.io/otel/trace v1.0.0-RC3/go.mod h1:VUt2TUYd8S2/ZRX09ZDFZQwn2RqfMB5MzO17jBojGxo=
go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
go.opentelemetry.io/otel/trace v1.0.1/go.mod h1:5g4i4fKLaX2BQpSBsxw8YYcgKpMMSW3x7ZTuYBr3sUk=
go.opentelemetry.io/otel/trace v1.2.0 h1:Ys3iqbqZhcf28hHzrm5WAquMkDHNZTUkw7KHbuNjej0=
go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0= go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0=
go.opentelemetry.io/otel/trace v1.3.0 h1:doy8Hzb1RJ+I3yFhtDmwNc7tIyw1tNMOIsyPzp1NOGY=
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.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.9.0 h1:C0g6TWmQYvjKRnljRULLWUVJGy8Uvu0NEL/5frY2/t4= go.opentelemetry.io/proto/otlp v0.11.0 h1:cLDgIBTf4lLOlztkhzAEdQsJ4Lj+i5Wc9k6Nn0K1VyU=
go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= 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.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.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
@ -1447,6 +1459,7 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= 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-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 h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8=
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 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= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1549,11 +1562,12 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 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-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/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-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/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-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -1570,8 +1584,10 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 h1:0Ja1LBD+yisY6RWM/BH7TJVXWsSjs2VwBSmvSX4HdBc=
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw=
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -1690,15 +1706,19 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20210616094352-59db8d763f22/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-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/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-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-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab h1:rfJ1bsoJQQIAoAxTxB7bme+vHrNkRw8CqfsYh9w54cw= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab/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-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/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-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1715,7 +1735,6 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1911,8 +1930,8 @@ google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= 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-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 h1:b9mVrqYfq3P4bCdaLg1qtBnPzUYgglsIdjZkL/fQVOE= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0=
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= 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= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
@ -1940,12 +1959,12 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 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.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg=
google.golang.org/grpc v1.44.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-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-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -2024,36 +2043,15 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.0.0-20180904230853-4e7be11eab3f/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
k8s.io/api v0.17.4/go.mod h1:5qxx6vjmwUVG2nHQTKGlLts8Tbok8PzHl4vHtVFuZCA=
k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw=
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.0/go.mod h1:0AoXXqst47OI/L0oGKq9DG61dvGRPXs7X4/B7KyjBCU=
k8s.io/api v0.22.4 h1:UvyHW0ezB2oIgHAxlYoo6UJQObYXU7awuNarwoHEOjw= k8s.io/api v0.22.4 h1:UvyHW0ezB2oIgHAxlYoo6UJQObYXU7awuNarwoHEOjw=
k8s.io/api v0.22.4/go.mod h1:Rgs+9gIGYC5laXQSZZ9JqT5NevNgoGiOdVWi1BAB3qk= k8s.io/api v0.22.4/go.mod h1:Rgs+9gIGYC5laXQSZZ9JqT5NevNgoGiOdVWi1BAB3qk=
k8s.io/apimachinery v0.0.0-20180904193909-def12e63c512/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
k8s.io/apimachinery v0.17.4/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g=
k8s.io/apimachinery v0.19.0/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA=
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.0/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
k8s.io/apimachinery v0.22.4 h1:9uwcvPpukBw/Ri0EUmWz+49cnFtaoiyEhQTK+xOe7Ck= k8s.io/apimachinery v0.22.4 h1:9uwcvPpukBw/Ri0EUmWz+49cnFtaoiyEhQTK+xOe7Ck=
k8s.io/apimachinery v0.22.4/go.mod h1:yU6oA6Gnax9RrxGzVvPFFJ+mpnW6PBSqp0sx0I0HHW0= k8s.io/apimachinery v0.22.4/go.mod h1:yU6oA6Gnax9RrxGzVvPFFJ+mpnW6PBSqp0sx0I0HHW0=
k8s.io/apiserver v0.17.4/go.mod h1:5ZDQ6Xr5MNBxyi3iUZXS84QOhZl+W7Oq2us/29c0j9I= k8s.io/apiserver v0.17.4/go.mod h1:5ZDQ6Xr5MNBxyi3iUZXS84QOhZl+W7Oq2us/29c0j9I=
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= 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.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
k8s.io/apiserver v0.22.0/go.mod h1:04kaIEzIQrTGJ5syLppQWvpkLJXQtJECHmae+ZGc/nc= k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ=
k8s.io/client-go v0.0.0-20180910083459-2cefa64ff137/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
k8s.io/client-go v0.17.4/go.mod h1:ouF6o5pz3is8qU0/qYL2RnoxOPqgfuidYLowytyLJmc=
k8s.io/client-go v0.19.0/go.mod h1:H9E/VT95blcFQnlyShFgnFT9ZnJOAceiUHM3MlRC+mU=
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.0/go.mod h1:GUjIuXR5PiEv/RVK5OODUsm6eZk7wtSWZSaSJbpFdGg=
k8s.io/client-go v0.22.4 h1:aAQ1Wk+I3bjCNk35YWUqbaueqrIonkfDPJSPDDe8Kfg= k8s.io/client-go v0.22.4 h1:aAQ1Wk+I3bjCNk35YWUqbaueqrIonkfDPJSPDDe8Kfg=
k8s.io/client-go v0.22.4/go.mod h1:Yzw4e5e7h1LNHA4uqnMVrpEpUs1hJOiuBsJKIlRCHDA= k8s.io/client-go v0.22.4/go.mod h1:Yzw4e5e7h1LNHA4uqnMVrpEpUs1hJOiuBsJKIlRCHDA=
k8s.io/cloud-provider v0.17.4/go.mod h1:XEjKDzfD+b9MTLXQFlDGkk6Ho8SGMpaU8Uugx/KNK9U= k8s.io/cloud-provider v0.17.4/go.mod h1:XEjKDzfD+b9MTLXQFlDGkk6Ho8SGMpaU8Uugx/KNK9U=
@ -2063,13 +2061,13 @@ k8s.io/component-base v0.17.4/go.mod h1:5BRqHMbbQPm2kKu35v3G+CpVq4K0RJKC7TRioF0I
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= 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.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
k8s.io/component-base v0.22.0/go.mod h1:SXj6Z+V6P6GsBhHZVbWCw9hFjUdUYnJerlhhPnYCBCg= 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.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.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.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=
k8s.io/cri-api v0.23.0-alpha.4/go.mod h1:qVxNSzR1gwLmZWK61jKRA5NhbyYrNoXUaZpQ7yOUYOQ= k8s.io/cri-api v0.23.1/go.mod h1:REJE3PSU0h/LOV1APBrupxrEJqnoxZC8KWzkBUHwrK4=
k8s.io/cri-api v0.24.0-alpha.0/go.mod h1:2edENu3/mkyW3c6fVPPPaVGEFbLRacJizBbSp7ZOLOo= k8s.io/cri-api v0.24.0-alpha.1/go.mod h1:2edENu3/mkyW3c6fVPPPaVGEFbLRacJizBbSp7ZOLOo=
k8s.io/csi-translation-lib v0.17.4/go.mod h1:CsxmjwxEI0tTNMzffIAcgR9lX4wOh6AKHdxQrT7L0oo= k8s.io/csi-translation-lib v0.17.4/go.mod h1:CsxmjwxEI0tTNMzffIAcgR9lX4wOh6AKHdxQrT7L0oo=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
@ -2083,21 +2081,19 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= 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.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.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw=
k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= 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-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/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kubernetes v1.11.10/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/kubernetes v1.11.10/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/legacy-cloud-providers v0.17.4/go.mod h1:FikRNoD64ECjkxO36gkDgJeiQWwyZTuBkhu+yxOc1Js= k8s.io/legacy-cloud-providers v0.17.4/go.mod h1:FikRNoD64ECjkxO36gkDgJeiQWwyZTuBkhu+yxOc1Js=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/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-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b h1:wxEMGetGMur3J1xuGLQY7GEQYg9bZxKn3tKo5k/eYcs= k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b h1:wxEMGetGMur3J1xuGLQY7GEQYg9bZxKn3tKo5k/eYcs=
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=

@ -1,8 +0,0 @@
language: go
go:
- "1.x"
- master
env:
- TAGS=""
- TAGS="-tags purego"
script: go test $TAGS -v ./...

@ -1,7 +1,7 @@
# xxhash # xxhash
[![GoDoc](https://godoc.org/github.com/cespare/xxhash?status.svg)](https://godoc.org/github.com/cespare/xxhash) [![Go Reference](https://pkg.go.dev/badge/github.com/cespare/xxhash/v2.svg)](https://pkg.go.dev/github.com/cespare/xxhash/v2)
[![Build Status](https://travis-ci.org/cespare/xxhash.svg?branch=master)](https://travis-ci.org/cespare/xxhash) [![Test](https://github.com/cespare/xxhash/actions/workflows/test.yml/badge.svg)](https://github.com/cespare/xxhash/actions/workflows/test.yml)
xxhash is a Go implementation of the 64-bit xxhash is a Go implementation of the 64-bit
[xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a [xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a
@ -64,4 +64,6 @@ $ go test -benchtime 10s -bench '/xxhash,direct,bytes'
- [InfluxDB](https://github.com/influxdata/influxdb) - [InfluxDB](https://github.com/influxdata/influxdb)
- [Prometheus](https://github.com/prometheus/prometheus) - [Prometheus](https://github.com/prometheus/prometheus)
- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics)
- [FreeCache](https://github.com/coocood/freecache) - [FreeCache](https://github.com/coocood/freecache)
- [FastCache](https://github.com/VictoriaMetrics/fastcache)

@ -193,7 +193,6 @@ func (d *Digest) UnmarshalBinary(b []byte) error {
b, d.v4 = consumeUint64(b) b, d.v4 = consumeUint64(b)
b, d.total = consumeUint64(b) b, d.total = consumeUint64(b)
copy(d.mem[:], b) copy(d.mem[:], b)
b = b[len(d.mem):]
d.n = int(d.total % uint64(len(d.mem))) d.n = int(d.total % uint64(len(d.mem)))
return nil return nil
} }

@ -6,7 +6,7 @@
// Register allocation: // Register allocation:
// AX h // AX h
// CX pointer to advance through b // SI pointer to advance through b
// DX n // DX n
// BX loop end // BX loop end
// R8 v1, k1 // R8 v1, k1
@ -16,39 +16,39 @@
// R12 tmp // R12 tmp
// R13 prime1v // R13 prime1v
// R14 prime2v // R14 prime2v
// R15 prime4v // DI prime4v
// round reads from and advances the buffer pointer in CX. // round reads from and advances the buffer pointer in SI.
// It assumes that R13 has prime1v and R14 has prime2v. // It assumes that R13 has prime1v and R14 has prime2v.
#define round(r) \ #define round(r) \
MOVQ (CX), R12 \ MOVQ (SI), R12 \
ADDQ $8, CX \ ADDQ $8, SI \
IMULQ R14, R12 \ IMULQ R14, R12 \
ADDQ R12, r \ ADDQ R12, r \
ROLQ $31, r \ ROLQ $31, r \
IMULQ R13, r IMULQ R13, r
// mergeRound applies a merge round on the two registers acc and val. // mergeRound applies a merge round on the two registers acc and val.
// It assumes that R13 has prime1v, R14 has prime2v, and R15 has prime4v. // It assumes that R13 has prime1v, R14 has prime2v, and DI has prime4v.
#define mergeRound(acc, val) \ #define mergeRound(acc, val) \
IMULQ R14, val \ IMULQ R14, val \
ROLQ $31, val \ ROLQ $31, val \
IMULQ R13, val \ IMULQ R13, val \
XORQ val, acc \ XORQ val, acc \
IMULQ R13, acc \ IMULQ R13, acc \
ADDQ R15, acc ADDQ DI, acc
// func Sum64(b []byte) uint64 // func Sum64(b []byte) uint64
TEXT ·Sum64(SB), NOSPLIT, $0-32 TEXT ·Sum64(SB), NOSPLIT, $0-32
// Load fixed primes. // Load fixed primes.
MOVQ ·prime1v(SB), R13 MOVQ ·prime1v(SB), R13
MOVQ ·prime2v(SB), R14 MOVQ ·prime2v(SB), R14
MOVQ ·prime4v(SB), R15 MOVQ ·prime4v(SB), DI
// Load slice. // Load slice.
MOVQ b_base+0(FP), CX MOVQ b_base+0(FP), SI
MOVQ b_len+8(FP), DX MOVQ b_len+8(FP), DX
LEAQ (CX)(DX*1), BX LEAQ (SI)(DX*1), BX
// The first loop limit will be len(b)-32. // The first loop limit will be len(b)-32.
SUBQ $32, BX SUBQ $32, BX
@ -65,14 +65,14 @@ TEXT ·Sum64(SB), NOSPLIT, $0-32
XORQ R11, R11 XORQ R11, R11
SUBQ R13, R11 SUBQ R13, R11
// Loop until CX > BX. // Loop until SI > BX.
blockLoop: blockLoop:
round(R8) round(R8)
round(R9) round(R9)
round(R10) round(R10)
round(R11) round(R11)
CMPQ CX, BX CMPQ SI, BX
JLE blockLoop JLE blockLoop
MOVQ R8, AX MOVQ R8, AX
@ -100,16 +100,16 @@ noBlocks:
afterBlocks: afterBlocks:
ADDQ DX, AX ADDQ DX, AX
// Right now BX has len(b)-32, and we want to loop until CX > len(b)-8. // Right now BX has len(b)-32, and we want to loop until SI > len(b)-8.
ADDQ $24, BX ADDQ $24, BX
CMPQ CX, BX CMPQ SI, BX
JG fourByte JG fourByte
wordLoop: wordLoop:
// Calculate k1. // Calculate k1.
MOVQ (CX), R8 MOVQ (SI), R8
ADDQ $8, CX ADDQ $8, SI
IMULQ R14, R8 IMULQ R14, R8
ROLQ $31, R8 ROLQ $31, R8
IMULQ R13, R8 IMULQ R13, R8
@ -117,18 +117,18 @@ wordLoop:
XORQ R8, AX XORQ R8, AX
ROLQ $27, AX ROLQ $27, AX
IMULQ R13, AX IMULQ R13, AX
ADDQ R15, AX ADDQ DI, AX
CMPQ CX, BX CMPQ SI, BX
JLE wordLoop JLE wordLoop
fourByte: fourByte:
ADDQ $4, BX ADDQ $4, BX
CMPQ CX, BX CMPQ SI, BX
JG singles JG singles
MOVL (CX), R8 MOVL (SI), R8
ADDQ $4, CX ADDQ $4, SI
IMULQ R13, R8 IMULQ R13, R8
XORQ R8, AX XORQ R8, AX
@ -138,19 +138,19 @@ fourByte:
singles: singles:
ADDQ $4, BX ADDQ $4, BX
CMPQ CX, BX CMPQ SI, BX
JGE finalize JGE finalize
singlesLoop: singlesLoop:
MOVBQZX (CX), R12 MOVBQZX (SI), R12
ADDQ $1, CX ADDQ $1, SI
IMULQ ·prime5v(SB), R12 IMULQ ·prime5v(SB), R12
XORQ R12, AX XORQ R12, AX
ROLQ $11, AX ROLQ $11, AX
IMULQ R13, AX IMULQ R13, AX
CMPQ CX, BX CMPQ SI, BX
JL singlesLoop JL singlesLoop
finalize: finalize:
@ -179,9 +179,9 @@ TEXT ·writeBlocks(SB), NOSPLIT, $0-40
MOVQ ·prime2v(SB), R14 MOVQ ·prime2v(SB), R14
// Load slice. // Load slice.
MOVQ b_base+8(FP), CX MOVQ b_base+8(FP), SI
MOVQ b_len+16(FP), DX MOVQ b_len+16(FP), DX
LEAQ (CX)(DX*1), BX LEAQ (SI)(DX*1), BX
SUBQ $32, BX SUBQ $32, BX
// Load vN from d. // Load vN from d.
@ -199,7 +199,7 @@ blockLoop:
round(R10) round(R10)
round(R11) round(R11)
CMPQ CX, BX CMPQ SI, BX
JLE blockLoop JLE blockLoop
// Copy vN back to d. // Copy vN back to d.
@ -208,8 +208,8 @@ blockLoop:
MOVQ R10, 16(AX) MOVQ R10, 16(AX)
MOVQ R11, 24(AX) MOVQ R11, 24(AX)
// The number of bytes written is CX minus the old base pointer. // The number of bytes written is SI minus the old base pointer.
SUBQ b_base+8(FP), CX SUBQ b_base+8(FP), SI
MOVQ CX, ret+32(FP) MOVQ SI, ret+32(FP)
RET RET

@ -6,41 +6,52 @@
package xxhash package xxhash
import ( import (
"reflect"
"unsafe" "unsafe"
) )
// Notes: // In the future it's possible that compiler optimizations will make these
// XxxString functions unnecessary by realizing that calls such as
// Sum64([]byte(s)) don't need to copy s. See https://golang.org/issue/2205.
// If that happens, even if we keep these functions they can be replaced with
// the trivial safe code.
// NOTE: The usual way of doing an unsafe string-to-[]byte conversion is:
// //
// See https://groups.google.com/d/msg/golang-nuts/dcjzJy-bSpw/tcZYBzQqAQAJ // var b []byte
// for some discussion about these unsafe conversions. // bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
// bh.Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data
// bh.Len = len(s)
// bh.Cap = len(s)
// //
// In the future it's possible that compiler optimizations will make these // Unfortunately, as of Go 1.15.3 the inliner's cost model assigns a high enough
// unsafe operations unnecessary: https://golang.org/issue/2205. // weight to this sequence of expressions that any function that uses it will
// not be inlined. Instead, the functions below use a different unsafe
// conversion designed to minimize the inliner weight and allow both to be
// inlined. There is also a test (TestInlining) which verifies that these are
// inlined.
// //
// Both of these wrapper functions still incur function call overhead since they // See https://github.com/golang/go/issues/42739 for discussion.
// will not be inlined. We could write Go/asm copies of Sum64 and Digest.Write
// for strings to squeeze out a bit more speed. Mid-stack inlining should
// eventually fix this.
// Sum64String computes the 64-bit xxHash digest of s. // Sum64String computes the 64-bit xxHash digest of s.
// It may be faster than Sum64([]byte(s)) by avoiding a copy. // It may be faster than Sum64([]byte(s)) by avoiding a copy.
func Sum64String(s string) uint64 { func Sum64String(s string) uint64 {
var b []byte b := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)}))
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
bh.Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data
bh.Len = len(s)
bh.Cap = len(s)
return Sum64(b) return Sum64(b)
} }
// WriteString adds more data to d. It always returns len(s), nil. // WriteString adds more data to d. It always returns len(s), nil.
// It may be faster than Write([]byte(s)) by avoiding a copy. // It may be faster than Write([]byte(s)) by avoiding a copy.
func (d *Digest) WriteString(s string) (n int, err error) { func (d *Digest) WriteString(s string) (n int, err error) {
var b []byte d.Write(*(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)})))
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) // d.Write always returns len(s), nil.
bh.Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data // Ignoring the return output and returning these fixed values buys a
bh.Len = len(s) // savings of 6 in the inliner's cost model.
bh.Cap = len(s) return len(s), nil
return d.Write(b) }
// sliceHeader is similar to reflect.SliceHeader, but it assumes that the layout
// of the first two words is the same as the layout of a string.
type sliceHeader struct {
s string
cap int
} }

@ -18,6 +18,8 @@ package content
import ( import (
"context" "context"
"errors"
"fmt"
"io" "io"
"math/rand" "math/rand"
"sync" "sync"
@ -26,7 +28,6 @@ import (
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
) )
var bufPool = sync.Pool{ var bufPool = sync.Pool{
@ -76,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)) cw, err := OpenWriter(ctx, cs, WithRef(ref), WithDescriptor(desc))
if err != nil { if err != nil {
if !errdefs.IsAlreadyExists(err) { 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 return nil // all ready present
@ -133,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 { func Copy(ctx context.Context, cw Writer, r io.Reader, size int64, expected digest.Digest, opts ...Opt) error {
ws, err := cw.Status() ws, err := cw.Status()
if err != nil { if err != nil {
return errors.Wrap(err, "failed to get status") return fmt.Errorf("failed to get status: %w", err)
} }
if ws.Offset > 0 { if ws.Offset > 0 {
r, err = seekReader(r, ws.Offset, size) r, err = seekReader(r, ws.Offset, size)
if err != nil { 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) copied, err := copyWithBuffer(cw, r)
if err != nil { 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 { if size != 0 && copied < size-ws.Offset {
// Short writes would return its own error, this indicates a read failure // 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 err := cw.Commit(ctx, size, expected, opts...); err != nil {
if !errdefs.IsAlreadyExists(err) { 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)
} }
} }
@ -171,11 +172,11 @@ func CopyReaderAt(cw Writer, ra ReaderAt, n int64) error {
copied, err := copyWithBuffer(cw, io.NewSectionReader(ra, ws.Offset, n)) copied, err := copyWithBuffer(cw, io.NewSectionReader(ra, ws.Offset, n))
if err != nil { if err != nil {
return errors.Wrap(err, "failed to copy") return fmt.Errorf("failed to copy: %w", err)
} }
if copied < n { if copied < n {
// Short writes would return its own error, this indicates a read failure // 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 return nil
} }
@ -189,13 +190,13 @@ func CopyReaderAt(cw Writer, ra ReaderAt, n int64) error {
func CopyReader(cw Writer, r io.Reader) (int64, error) { func CopyReader(cw Writer, r io.Reader) (int64, error) {
ws, err := cw.Status() ws, err := cw.Status()
if err != nil { 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 { if ws.Offset > 0 {
r, err = seekReader(r, ws.Offset, 0) r, err = seekReader(r, ws.Offset, 0)
if err != nil { 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)
} }
} }
@ -211,7 +212,10 @@ func seekReader(r io.Reader, offset, size int64) (io.Reader, error) {
if ok { if ok {
nn, err := seeker.Seek(offset, io.SeekStart) nn, err := seeker.Seek(offset, io.SeekStart)
if nn != offset { 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 { if err != nil {
@ -231,10 +235,10 @@ func seekReader(r io.Reader, offset, size int64) (io.Reader, error) {
// well then, let's just discard up to the offset // well then, let's just discard up to the offset
n, err := copyWithBuffer(io.Discard, io.LimitReader(r, offset)) n, err := copyWithBuffer(io.Discard, io.LimitReader(r, offset))
if err != nil { 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 { if n != offset {
return nil, errors.Errorf("unable to discard to offset") return nil, errors.New("unable to discard to offset")
} }
return r, nil return r, nil

@ -17,11 +17,11 @@
package local package local
import ( import (
"fmt"
"sync" "sync"
"time" "time"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/pkg/errors"
) )
// Handles locking references // Handles locking references
@ -44,9 +44,9 @@ func tryLock(ref string) error {
// Returning the duration may help developers distinguish dead locks (long duration) from // Returning the duration may help developers distinguish dead locks (long duration) from
// lock contentions (short duration). // lock contentions (short duration).
now := time.Now() now := time.Now()
return errors.Wrapf( return fmt.Errorf(
"ref %s locked for %s (since %s): %w", ref, now.Sub(v.since), v.since,
errdefs.ErrUnavailable, errdefs.ErrUnavailable,
"ref %s locked for %s (since %s)", ref, now.Sub(v.since), v.since,
) )
} }

@ -17,10 +17,9 @@
package local package local
import ( import (
"fmt"
"os" "os"
"github.com/pkg/errors"
"github.com/containerd/containerd/content" "github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
) )
@ -40,7 +39,7 @@ func OpenReader(p string) (content.ReaderAt, error) {
return nil, err 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) fp, err := os.Open(p)
@ -49,7 +48,7 @@ func OpenReader(p string) (content.ReaderAt, error) {
return nil, err 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 return sizeReaderAt{size: fi.Size(), fp: fp}, nil

@ -36,7 +36,6 @@ import (
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
) )
var bufPool = sync.Pool{ var bufPool = sync.Pool{
@ -93,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) { func (s *store) Info(ctx context.Context, dgst digest.Digest) (content.Info, error) {
p, err := s.blobPath(dgst) p, err := s.blobPath(dgst)
if err != nil { 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) fi, err := os.Stat(p)
if err != nil { if err != nil {
if os.IsNotExist(err) { 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 return content.Info{}, err
@ -128,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) { func (s *store) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.ReaderAt, error) {
p, err := s.blobPath(desc.Digest) p, err := s.blobPath(desc.Digest)
if err != nil { 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) reader, err := OpenReader(p)
if err != nil { 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 return reader, nil
@ -146,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 { func (s *store) Delete(ctx context.Context, dgst digest.Digest) error {
bp, err := s.blobPath(dgst) bp, err := s.blobPath(dgst)
if err != nil { 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 { if err := os.RemoveAll(bp); err != nil {
@ -154,7 +153,7 @@ func (s *store) Delete(ctx context.Context, dgst digest.Digest) error {
return err return err
} }
return errors.Wrapf(errdefs.ErrNotFound, "content %v", dgst) return fmt.Errorf("content %v: %w", dgst, errdefs.ErrNotFound)
} }
return nil return nil
@ -162,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) { func (s *store) Update(ctx context.Context, info content.Info, fieldpaths ...string) (content.Info, error) {
if s.ls == nil { 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) p, err := s.blobPath(info.Digest)
if err != nil { 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) fi, err := os.Stat(p)
if err != nil { if err != nil {
if os.IsNotExist(err) { 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 return content.Info{}, err
@ -200,7 +199,7 @@ func (s *store) Update(ctx context.Context, info content.Info, fieldpaths ...str
all = true all = true
labels = info.Labels labels = info.Labels
default: 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 { } else {
@ -377,7 +376,7 @@ func (s *store) status(ingestPath string) (content.Status, error) {
fi, err := os.Stat(dp) fi, err := os.Stat(dp)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
err = errors.Wrap(errdefs.ErrNotFound, err.Error()) err = fmt.Errorf("%s: %w", err.Error(), errdefs.ErrNotFound)
} }
return content.Status{}, err return content.Status{}, err
} }
@ -385,19 +384,19 @@ func (s *store) status(ingestPath string) (content.Status, error) {
ref, err := readFileString(filepath.Join(ingestPath, "ref")) ref, err := readFileString(filepath.Join(ingestPath, "ref"))
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
err = errors.Wrap(errdefs.ErrNotFound, err.Error()) err = fmt.Errorf("%s: %w", err.Error(), errdefs.ErrNotFound)
} }
return content.Status{}, err return content.Status{}, err
} }
startedAt, err := readFileTimestamp(filepath.Join(ingestPath, "startedat")) startedAt, err := readFileTimestamp(filepath.Join(ingestPath, "startedat"))
if err != nil { 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")) updatedAt, err := readFileTimestamp(filepath.Join(ingestPath, "updatedat"))
if err != nil { 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 // because we don't write updatedat on every write, the mod time may
@ -460,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 // TODO(AkihiroSuda): we could create a random string or one calculated based on the context
// https://github.com/containerd/containerd/issues/2129#issuecomment-380255019 // https://github.com/containerd/containerd/issues/2129#issuecomment-380255019
if wOpts.Ref == "" { 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 var lockErr error
for count := uint64(0); count < 10; count++ { for count := uint64(0); count < 10; count++ {
@ -494,16 +493,16 @@ func (s *store) resumeStatus(ref string, total int64, digester digest.Digester)
path, _, data := s.ingestPaths(ref) path, _, data := s.ingestPaths(ref)
status, err := s.status(path) status, err := s.status(path)
if err != nil { 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 { if ref != status.Ref {
// NOTE(stevvooe): This is fairly catastrophic. Either we have some // NOTE(stevvooe): This is fairly catastrophic. Either we have some
// layout corruption or a hash collision for the ref key. // 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 { 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 // TODO(stevvooe): slow slow slow!!, send to goroutine or use resumable hashes
@ -527,10 +526,10 @@ func (s *store) writer(ctx context.Context, ref string, total int64, expected di
if expected != "" { if expected != "" {
p, err := s.blobPath(expected) p, err := s.blobPath(expected)
if err != nil { 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 { 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)
} }
} }
@ -588,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) fp, err := os.OpenFile(data, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil { 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 { 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{ return &writer{
@ -614,7 +614,7 @@ func (s *store) Abort(ctx context.Context, ref string) error {
root := s.ingestRoot(ref) root := s.ingestRoot(ref)
if err := os.RemoveAll(root); err != nil { if err := os.RemoveAll(root); err != nil {
if os.IsNotExist(err) { 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 return err
@ -625,7 +625,7 @@ func (s *store) Abort(ctx context.Context, ref string) error {
func (s *store) blobPath(dgst digest.Digest) (string, error) { func (s *store) blobPath(dgst digest.Digest) (string, error) {
if err := dgst.Validate(); err != nil { 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 return filepath.Join(s.root, "blobs", dgst.Algorithm().String(), dgst.Hex()), nil
@ -664,14 +664,14 @@ func readFileTimestamp(p string) (time.Time, error) {
b, err := os.ReadFile(p) b, err := os.ReadFile(p)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
err = errors.Wrap(errdefs.ErrNotFound, err.Error()) err = fmt.Errorf("%s: %w", err.Error(), errdefs.ErrNotFound)
} }
return time.Time{}, err return time.Time{}, err
} }
var t time.Time var t time.Time
if err := t.UnmarshalText(b); err != nil { 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 return t, nil
@ -689,16 +689,16 @@ func writeToCompletion(path string, data []byte, mode os.FileMode) error {
tmp := fmt.Sprintf("%s.tmp", path) tmp := fmt.Sprintf("%s.tmp", path)
f, err := os.OpenFile(tmp, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_SYNC, mode) f, err := os.OpenFile(tmp, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_SYNC, mode)
if err != nil { if err != nil {
return errors.Wrap(err, "create tmp file") return fmt.Errorf("create tmp file: %w", err)
} }
_, err = f.Write(data) _, err = f.Write(data)
f.Close() f.Close()
if err != nil { if err != nil {
return errors.Wrap(err, "write tmp file") return fmt.Errorf("write tmp file: %w", err)
} }
err = os.Rename(tmp, path) err = os.Rename(tmp, path)
if err != nil { if err != nil {
return errors.Wrap(err, "rename tmp file") return fmt.Errorf("rename tmp file: %w", err)
} }
return nil return nil
} }

@ -27,7 +27,7 @@ import (
func getATime(fi os.FileInfo) time.Time { func getATime(fi os.FileInfo) time.Time {
if st, ok := fi.Sys().(*syscall.Stat_t); ok { 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() return fi.ModTime()

@ -27,7 +27,7 @@ import (
func getATime(fi os.FileInfo) time.Time { func getATime(fi os.FileInfo) time.Time {
if st, ok := fi.Sys().(*syscall.Stat_t); ok { 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() return fi.ModTime()

@ -27,7 +27,7 @@ import (
func getATime(fi os.FileInfo) time.Time { func getATime(fi os.FileInfo) time.Time {
if st, ok := fi.Sys().(*syscall.Stat_t); ok { 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() return fi.ModTime()

@ -18,6 +18,8 @@ package local
import ( import (
"context" "context"
"errors"
"fmt"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
@ -28,7 +30,6 @@ import (
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
"github.com/pkg/errors"
) )
// writer represents a write transaction against the blob store. // 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 w.fp = nil
if 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 { if err := fp.Sync(); err != nil {
fp.Close() fp.Close()
return errors.Wrap(err, "sync failed") return fmt.Errorf("sync failed: %w", err)
} }
fi, err := fp.Stat() fi, err := fp.Stat()
closeErr := fp.Close() closeErr := fp.Close()
if err != nil { 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 { 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() { 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() dgst := w.digester.Digest()
if expected != "" && expected != dgst { 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 ( var (
@ -127,9 +128,9 @@ func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest,
if _, err := os.Stat(target); err == nil { if _, err := os.Stat(target); err == nil {
// collision with the target file! // collision with the target file!
if err := os.RemoveAll(w.path); err != nil { 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 { 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() commitTime := time.Now()
if err := os.Chtimes(target, commitTime, commitTime); err != nil { 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!! // clean up!!
if err := os.RemoveAll(w.path); err != nil { 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 w.s.ls != nil && base.Labels != nil {
if err := w.s.ls.Set(dgst, base.Labels); err != 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 // NOTE: Windows does not support this operation
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
if err := os.Chmod(target, (fi.Mode()&os.ModePerm)&^0333); err != nil { 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")
} }
} }

@ -18,13 +18,13 @@ package proxy
import ( import (
"context" "context"
"fmt"
"io" "io"
contentapi "github.com/containerd/containerd/api/services/content/v1" contentapi "github.com/containerd/containerd/api/services/content/v1"
"github.com/containerd/containerd/content" "github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
"github.com/pkg/errors"
) )
type remoteWriter struct { type remoteWriter struct {
@ -57,7 +57,7 @@ func (rw *remoteWriter) Status() (content.Status, error) {
Action: contentapi.WriteActionStat, Action: contentapi.WriteActionStat,
}) })
if err != nil { 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{ return content.Status{
@ -82,7 +82,7 @@ func (rw *remoteWriter) Write(p []byte) (n int, err error) {
Data: p, Data: p,
}) })
if err != nil { 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) n = int(resp.Offset - offset)
@ -119,15 +119,15 @@ func (rw *remoteWriter) Commit(ctx context.Context, size int64, expected digest.
Labels: base.Labels, Labels: base.Labels,
}) })
if err != nil { 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 { 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 { 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 rw.digest = resp.Digest

@ -17,7 +17,7 @@
// Package errdefs defines the common errors used throughout containerd // Package errdefs defines the common errors used throughout containerd
// packages. // 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 // To detect an error class, use the IsXXX functions to tell whether an error
// is of a certain type. // is of a certain type.
@ -28,8 +28,7 @@ package errdefs
import ( import (
"context" "context"
"errors"
"github.com/pkg/errors"
) )
// Definitions of common error types used throughout containerd. All containerd // Definitions of common error types used throughout containerd. All containerd

@ -18,9 +18,9 @@ package errdefs
import ( import (
"context" "context"
"fmt"
"strings" "strings"
"github.com/pkg/errors"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "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 // ToGRPCf maps the error to grpc error codes, assembling the formatting string
// and combining it with the target error 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 { 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 // 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) msg := rebaseMessage(cls, err)
if msg != "" { if msg != "" {
err = errors.Wrap(cls, msg) err = fmt.Errorf("%s: %w", msg, cls)
} else { } else {
err = errors.WithStack(cls) err = cls
} }
return err return err

@ -21,7 +21,6 @@ import (
"io" "io"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/pkg/errors"
) )
/* /*
@ -71,7 +70,7 @@ func ParseAll(ss ...string) (Filter, error) {
for _, s := range ss { for _, s := range ss {
f, err := Parse(s) f, err := Parse(s)
if err != nil { 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) fs = append(fs, f)
@ -90,7 +89,7 @@ func (p *parser) parse() (Filter, error) {
ss, err := p.selectors() ss, err := p.selectors()
if err != nil { if err != nil {
return nil, errors.Wrap(err, "filters") return nil, fmt.Errorf("filters: %w", err)
} }
return ss, nil return ss, nil
@ -284,9 +283,9 @@ func (pe parseError) Error() string {
} }
func (p *parser) mkerr(pos int, format string, args ...interface{}) error { 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, input: p.input,
pos: pos, pos: pos,
msg: fmt.Sprintf(format, args...), msg: fmt.Sprintf(format, args...),
}, "parse error") })
} }

@ -17,9 +17,8 @@
package filters package filters
import ( import (
"errors"
"unicode/utf8" "unicode/utf8"
"github.com/pkg/errors"
) )
// NOTE(stevvooe): Most of this code in this file is copied from the stdlib // NOTE(stevvooe): Most of this code in this file is copied from the stdlib

@ -18,6 +18,7 @@ package images
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"sort" "sort"
@ -25,7 +26,6 @@ import (
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/platforms" "github.com/containerd/containerd/platforms"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"golang.org/x/sync/semaphore" "golang.org/x/sync/semaphore"
) )
@ -33,17 +33,17 @@ import (
var ( var (
// ErrSkipDesc is used to skip processing of a descriptor and // ErrSkipDesc is used to skip processing of a descriptor and
// its descendants. // its descendants.
ErrSkipDesc = fmt.Errorf("skip descriptor") ErrSkipDesc = errors.New("skip descriptor")
// ErrStopHandler is used to signify that the descriptor // ErrStopHandler is used to signify that the descriptor
// has been handled and should not be handled further. // has been handled and should not be handled further.
// This applies only to a single descriptor in a handler // This applies only to a single descriptor in a handler
// chain and does not apply to descendant descriptors. // 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 // ErrEmptyWalk is used when the WalkNotEmpty handlers return no
// children (e.g.: they were filtered out). // children (e.g.: they were filtered out).
ErrEmptyWalk = fmt.Errorf("image might be filtered out") ErrEmptyWalk = errors.New("image might be filtered out")
) )
// Handler handles image manifests // Handler handles image manifests
@ -308,7 +308,7 @@ func LimitManifests(f HandlerFunc, m platforms.MatchComparer, n int) HandlerFunc
if n > 0 { if n > 0 {
if len(children) == 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 { if len(children) > n {
children = children[:n] children = children[:n]

@ -29,7 +29,6 @@ import (
"github.com/containerd/containerd/platforms" "github.com/containerd/containerd/platforms"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
) )
// Image provides the model for how containerd views container images. // 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 var size int64
return size, Walk(ctx, Handlers(HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { return size, Walk(ctx, Handlers(HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
if desc.Size < 0 { 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 size += desc.Size
return nil, nil 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 { 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 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 { 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 var idx ocispec.Index
@ -236,15 +235,15 @@ func Manifest(ctx context.Context, provider content.Provider, image ocispec.Desc
} }
return descs, nil 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 { }), image); err != nil {
return ocispec.Manifest{}, err return ocispec.Manifest{}, err
} }
if len(m) == 0 { 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 { 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 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, []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 // 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) missing = append(missing, desc)
continue continue
} else { } 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() 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 { 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 // 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 { 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 var index ocispec.Index

@ -18,12 +18,12 @@ package images
import ( import (
"context" "context"
"fmt"
"sort" "sort"
"strings" "strings"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
) )
// mediatype definitions for image components handled in containerd. // mediatype definitions for image components handled in containerd.
@ -87,7 +87,7 @@ func DiffCompression(ctx context.Context, mediaType string) (string, error) {
} }
return "", nil return "", nil
default: default:
return "", errors.Wrapf(errdefs.ErrNotImplemented, "unrecognised mediatype %s", mediaType) return "", fmt.Errorf("unrecognised mediatype %s: %w", mediaType, errdefs.ErrNotImplemented)
} }
} }

@ -19,7 +19,3 @@ package labels
// LabelUncompressed is added to compressed layer contents. // LabelUncompressed is added to compressed layer contents.
// The value is digest of the uncompressed content. // The value is digest of the uncompressed content.
const LabelUncompressed = "containerd.io/uncompressed" const LabelUncompressed = "containerd.io/uncompressed"
// LabelSharedNamespace is added to a namespace to allow that namespaces
// contents to be shared.
const LabelSharedNamespace = "containerd.io/namespace.shareable"

@ -17,8 +17,9 @@
package labels package labels
import ( import (
"fmt"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/pkg/errors"
) )
const ( const (
@ -31,7 +32,7 @@ func Validate(k, v string) error {
if len(k) > 10 { if len(k) > 10 {
k = 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 return nil
} }

@ -18,6 +18,7 @@ package platforms
import ( import (
"bufio" "bufio"
"fmt"
"os" "os"
"runtime" "runtime"
"strings" "strings"
@ -25,7 +26,6 @@ import (
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/pkg/errors"
) )
// Present the ARM instruction set architecture, eg: v7, v8 // 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 // by ourselves. We can just parse these information from /proc/cpuinfo
func getCPUInfo(pattern string) (info string, err error) { func getCPUInfo(pattern string) (info string, err error) {
if !isLinuxOS(runtime.GOOS) { 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") cpuinfo, err := os.Open("/proc/cpuinfo")
@ -75,7 +75,7 @@ func getCPUInfo(pattern string) (info string, err error) {
return "", err 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 { func getCPUVariant() string {

@ -107,6 +107,7 @@
package platforms package platforms
import ( import (
"fmt"
"path" "path"
"regexp" "regexp"
"runtime" "runtime"
@ -115,7 +116,6 @@ import (
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
specs "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
) )
var ( var (
@ -167,14 +167,14 @@ func (m *matcher) String() string {
func Parse(specifier string) (specs.Platform, error) { func Parse(specifier string) (specs.Platform, error) {
if strings.Contains(specifier, "*") { if strings.Contains(specifier, "*") {
// TODO(stevvooe): need to work out exact wildcard handling // 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, "/") parts := strings.Split(specifier, "/")
for _, part := range parts { for _, part := range parts {
if !specifierRe.MatchString(part) { 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)
} }
} }
@ -206,7 +206,7 @@ func Parse(specifier string) (specs.Platform, error) {
return p, nil 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: case 2:
// In this case, we treat as a regular os/arch pair. We don't care // In this case, we treat as a regular os/arch pair. We don't care
// about whether or not we know of the platform. // about whether or not we know of the platform.
@ -228,7 +228,7 @@ func Parse(specifier string) (specs.Platform, error) {
return p, nil 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. // MustParse is like Parses but panics if the specifier cannot be parsed.

@ -19,6 +19,8 @@ package auth
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"fmt"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
@ -27,7 +29,6 @@ import (
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
remoteserrors "github.com/containerd/containerd/remotes/errors" remoteserrors "github.com/containerd/containerd/remotes/errors"
"github.com/containerd/containerd/version" "github.com/containerd/containerd/version"
"github.com/pkg/errors"
"golang.org/x/net/context/ctxhttp" "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) realmURL, err := url.Parse(realm)
if err != nil { 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{ to := TokenOptions{
@ -73,6 +74,15 @@ type TokenOptions struct {
Scopes []string Scopes []string
Username string Username string
Secret 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 // 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("username", to.Username)
form.Set("password", to.Secret) form.Set("password", to.Secret)
} }
if to.FetchRefreshToken {
form.Set("access_type", "offline")
}
req, err := http.NewRequest("POST", to.Realm, strings.NewReader(form.Encode())) req, err := http.NewRequest("POST", to.Realm, strings.NewReader(form.Encode()))
if err != nil { if err != nil {
@ -121,18 +134,18 @@ func FetchTokenWithOAuth(ctx context.Context, client *http.Client, headers http.
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 400 { if resp.StatusCode < 200 || resp.StatusCode >= 400 {
return nil, errors.WithStack(remoteserrors.NewUnexpectedStatusErr(resp)) return nil, remoteserrors.NewUnexpectedStatusErr(resp)
} }
decoder := json.NewDecoder(resp.Body) decoder := json.NewDecoder(resp.Body)
var tr OAuthTokenResponse var tr OAuthTokenResponse
if err = decoder.Decode(&tr); err != nil { 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 == "" { if tr.AccessToken == "" {
return nil, errors.WithStack(ErrNoToken) return nil, ErrNoToken
} }
return &tr, nil 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) req.SetBasicAuth(to.Username, to.Secret)
} }
if to.FetchRefreshToken {
reqParams.Add("offline_token", "true")
}
req.URL.RawQuery = reqParams.Encode() req.URL.RawQuery = reqParams.Encode()
resp, err := ctxhttp.Do(ctx, client, req) 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() defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 400 { if resp.StatusCode < 200 || resp.StatusCode >= 400 {
return nil, errors.WithStack(remoteserrors.NewUnexpectedStatusErr(resp)) return nil, remoteserrors.NewUnexpectedStatusErr(resp)
} }
decoder := json.NewDecoder(resp.Body) decoder := json.NewDecoder(resp.Body)
var tr FetchTokenResponse var tr FetchTokenResponse
if err = decoder.Decode(&tr); err != nil { 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 // `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 == "" { if tr.Token == "" {
return nil, errors.WithStack(ErrNoToken) return nil, ErrNoToken
} }
return &tr, nil return &tr, nil

@ -19,6 +19,7 @@ package docker
import ( import (
"context" "context"
"encoding/base64" "encoding/base64"
"errors"
"fmt" "fmt"
"net/http" "net/http"
"strings" "strings"
@ -28,7 +29,6 @@ import (
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/remotes/docker/auth" "github.com/containerd/containerd/remotes/docker/auth"
remoteerrors "github.com/containerd/containerd/remotes/errors" remoteerrors "github.com/containerd/containerd/remotes/errors"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -37,10 +37,12 @@ type dockerAuthorizer struct {
client *http.Client client *http.Client
header http.Header header http.Header
mu sync.Mutex mu sync.RWMutex
// indexed by host name // indexed by host name
handlers map[string]*authHandler handlers map[string]*authHandler
onFetchRefreshToken OnFetchRefreshToken
} }
// NewAuthorizer creates a Docker authorizer using the provided function to // 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 { type authorizerConfig struct {
credentials func(string) (string, string, error) credentials func(string) (string, string, error)
client *http.Client client *http.Client
header http.Header header http.Header
onFetchRefreshToken OnFetchRefreshToken
} }
// AuthorizerOpt configures an authorizer // 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 // NewDockerAuthorizer creates an authorizer using Docker's registry
// authentication spec. // authentication spec.
// See https://docs.docker.com/registry/spec/auth/ // See https://docs.docker.com/registry/spec/auth/
@ -94,10 +107,11 @@ func NewDockerAuthorizer(opts ...AuthorizerOpt) Authorizer {
} }
return &dockerAuthorizer{ return &dockerAuthorizer{
credentials: ao.credentials, credentials: ao.credentials,
client: ao.client, client: ao.client,
header: ao.header, header: ao.header,
handlers: make(map[string]*authHandler), 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 return nil
} }
auth, err := ah.authorize(ctx) auth, refreshToken, err := ah.authorize(ctx)
if err != nil { if err != nil {
return err return err
} }
req.Header.Set("Authorization", auth) 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 return nil
} }
@ -161,6 +184,7 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
if err != nil { if err != nil {
return err return err
} }
common.FetchRefreshToken = a.onFetchRefreshToken != nil
a.handlers[host] = newAuthHandler(a.client, a.header, c.Scheme, common) a.handlers[host] = newAuthHandler(a.client, a.header, c.Scheme, common)
return nil 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. // authResult is used to control limit rate.
type authResult struct { type authResult struct {
sync.WaitGroup sync.WaitGroup
token string token string
err error refreshToken string
err error
} }
// authHandler is used to handle auth request per registry server. // 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 { switch ah.scheme {
case auth.BasicAuth: case auth.BasicAuth:
return ah.doBasicAuth(ctx) return ah.doBasicAuth(ctx)
case auth.BearerAuth: case auth.BearerAuth:
return ah.doBearerAuth(ctx) return ah.doBearerAuth(ctx)
default: 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 username, secret := ah.common.Username, ah.common.Secret
if username == "" || 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)) 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 // copy common tokenOptions
to := ah.common 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 { if r, exist := ah.scopedTokens[scoped]; exist {
ah.Unlock() ah.Unlock()
r.Wait() r.Wait()
return r.token, r.err return r.token, r.refreshToken, r.err
} }
// only one fetch token job // only one fetch token job
@ -266,14 +291,16 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (token string, err erro
defer func() { defer func() {
token = fmt.Sprintf("Bearer %s", token) token = fmt.Sprintf("Bearer %s", token)
r.token, r.err = token, err r.token, r.refreshToken, r.err = token, refreshToken, err
r.Done() r.Done()
}() }()
// fetch token for the resource scope // fetch token for the resource scope
if to.Secret != "" { if to.Secret != "" {
defer func() { 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 // credential information is provided, use oauth POST endpoint
// TODO: Allow setting client_id // TODO: Allow setting client_id
@ -287,25 +314,25 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (token string, err erro
if (errStatus.StatusCode == 405 && to.Username != "") || errStatus.StatusCode == 404 || errStatus.StatusCode == 401 { if (errStatus.StatusCode == 405 && to.Username != "") || errStatus.StatusCode == 404 || errStatus.StatusCode == 401 {
resp, err := auth.FetchToken(ctx, ah.client, ah.header, to) resp, err := auth.FetchToken(ctx, ah.client, ah.header, to)
if err != nil { if err != nil {
return "", err return "", "", err
} }
return resp.Token, nil return resp.Token, resp.RefreshToken, nil
} }
log.G(ctx).WithFields(logrus.Fields{ log.G(ctx).WithFields(logrus.Fields{
"status": errStatus.Status, "status": errStatus.Status,
"body": string(errStatus.Body), "body": string(errStatus.Body),
}).Debugf("token request failed") }).Debugf("token request failed")
} }
return "", err return "", "", err
} }
return resp.AccessToken, nil return resp.AccessToken, resp.RefreshToken, nil
} }
// do request anonymously // do request anonymously
resp, err := auth.FetchToken(ctx, ah.client, ah.header, to) resp, err := auth.FetchToken(ctx, ah.client, ah.header, to)
if err != nil { 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 { func invalidAuthorization(c auth.Challenge, responses []*http.Response) error {
@ -319,7 +346,7 @@ func invalidAuthorization(c auth.Challenge, responses []*http.Response) error {
return nil 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 { func sameRequest(r1, r2 *http.Request) bool {

@ -28,7 +28,6 @@ import (
"github.com/containerd/containerd/remotes" "github.com/containerd/containerd/remotes"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
) )
// LegacyConfigMediaType should be replaced by OCI image spec. // 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 // read manifest data
mb, err := content.ReadBlob(ctx, store, desc) mb, err := content.ReadBlob(ctx, store, desc)
if err != nil { 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 var manifest ocispec.Manifest
if err := json.Unmarshal(mb, &manifest); err != nil { 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 // check config media type
@ -68,7 +67,7 @@ func ConvertManifest(ctx context.Context, store content.Store, desc ocispec.Desc
manifest.Config.MediaType = images.MediaTypeDockerSchema2Config manifest.Config.MediaType = images.MediaTypeDockerSchema2Config
data, err := json.MarshalIndent(manifest, "", " ") data, err := json.MarshalIndent(manifest, "", " ")
if err != nil { 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 // 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) ref := remotes.MakeRefKey(ctx, desc)
if err := content.WriteBlob(ctx, store, ref, bytes.NewReader(data), desc, content.WithLabels(labels)); err != nil { 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 return desc, nil
} }

@ -19,6 +19,7 @@ package docker
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
@ -29,7 +30,6 @@ import (
"github.com/containerd/containerd/images" "github.com/containerd/containerd/images"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
) )
type dockerFetcher struct { type dockerFetcher struct {
@ -41,7 +41,7 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
hosts := r.filterHosts(HostCapabilityPull) hosts := r.filterHosts(HostCapabilityPull)
if len(hosts) == 0 { 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) ctx, err := ContextWithRepositoryScope(ctx, r.refspec, false)
@ -141,9 +141,9 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
} }
if errdefs.IsNotFound(firstErr) { if errdefs.IsNotFound(firstErr) {
firstErr = errors.Wrapf(errdefs.ErrNotFound, firstErr = fmt.Errorf("could not fetch content descriptor %v (%v) from remote: %w",
"could not fetch content descriptor %v (%v) from remote", desc.Digest, desc.MediaType, errdefs.ErrNotFound,
desc.Digest, desc.MediaType) )
} }
return nil, firstErr return nil, firstErr
@ -178,19 +178,19 @@ func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string,
// implementation. // implementation.
if resp.StatusCode == http.StatusNotFound { 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 var registryErr Errors
if err := json.NewDecoder(resp.Body).Decode(&registryErr); err != nil || registryErr.Len() < 1 { if err := json.NewDecoder(resp.Body).Decode(&registryErr); 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 { if offset > 0 {
cr := resp.Header.Get("content-range") cr := resp.Header.Get("content-range")
if cr != "" { if cr != "" {
if !strings.HasPrefix(cr, fmt.Sprintf("bytes %d-", offset)) { 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 { } else {
@ -202,10 +202,10 @@ func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string,
// Could use buffer pool here but this case should be rare // Could use buffer pool here but this case should be rare
n, err := io.Copy(io.Discard, io.LimitReader(resp.Body, offset)) n, err := io.Copy(io.Discard, io.LimitReader(resp.Body, offset))
if err != nil { 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 { if n != offset {
return nil, errors.Errorf("unable to discard to offset") return nil, errors.New("unable to discard to offset")
} }
} }

@ -18,11 +18,11 @@ package docker
import ( import (
"bytes" "bytes"
"fmt"
"io" "io"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/pkg/errors"
) )
const maxRetry = 3 const maxRetry = 3
@ -69,7 +69,7 @@ func (hrs *httpReadSeeker) Read(p []byte) (n int, err error) {
} }
if hrs.rc != nil { if hrs.rc != nil {
if clsErr := hrs.rc.Close(); clsErr != 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 hrs.rc = nil
} }
@ -94,7 +94,7 @@ func (hrs *httpReadSeeker) Close() error {
func (hrs *httpReadSeeker) Seek(offset int64, whence int) (int64, error) { func (hrs *httpReadSeeker) Seek(offset int64, whence int) (int64, error) {
if hrs.closed { 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 abs := hrs.offset
@ -105,21 +105,21 @@ func (hrs *httpReadSeeker) Seek(offset int64, whence int) (int64, error) {
abs += offset abs += offset
case io.SeekEnd: case io.SeekEnd:
if hrs.size == -1 { 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 abs = hrs.size + offset
default: 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 { 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 abs != hrs.offset {
if hrs.rc != nil { if hrs.rc != nil {
if err := hrs.rc.Close(); err != 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 hrs.rc = nil
@ -140,17 +140,17 @@ func (hrs *httpReadSeeker) reader() (io.Reader, error) {
// only try to reopen the body request if we are seeking to a value // only try to reopen the body request if we are seeking to a value
// less than the actual size. // less than the actual size.
if hrs.open == nil { 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) rc, err := hrs.open(hrs.offset)
if err != nil { 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 hrs.rc != nil {
if err := hrs.rc.Close(); err != 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 hrs.rc = rc

@ -18,6 +18,8 @@ package docker
import ( import (
"context" "context"
"errors"
"fmt"
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
@ -32,7 +34,6 @@ import (
remoteserrors "github.com/containerd/containerd/remotes/errors" remoteserrors "github.com/containerd/containerd/remotes/errors"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
) )
type dockerPusher struct { type dockerPusher struct {
@ -55,7 +56,7 @@ func (p dockerPusher) Writer(ctx context.Context, opts ...content.WriterOpt) (co
} }
} }
if wOpts.Ref == "" { 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) return p.push(ctx, wOpts.Desc, wOpts.Ref, true)
} }
@ -76,22 +77,22 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
status, err := p.tracker.GetStatus(ref) status, err := p.tracker.GetStatus(ref)
if err == nil { if err == nil {
if status.Committed && status.Offset == status.Total { 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 {
// Another push of this ref is happening elsewhere. The rest of function // Another push of this ref is happening elsewhere. The rest of function
// will continue only when `errdefs.IsNotFound(err) == true` (i.e. there // will continue only when `errdefs.IsNotFound(err) == true` (i.e. there
// is no actively-tracked ref already). // 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 // TODO: Handle incomplete status
} else if !errdefs.IsNotFound(err) { } 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) hosts := p.filterHosts(HostCapabilityPush)
if len(hosts) == 0 { if len(hosts) == 0 {
return nil, errors.Wrap(errdefs.ErrNotFound, "no push hosts") return nil, fmt.Errorf("no push hosts: %w", errdefs.ErrNotFound)
} }
var ( var (
@ -143,7 +144,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
}, },
}) })
resp.Body.Close() 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 { } else if resp.StatusCode != http.StatusNotFound {
err := remoteserrors.NewUnexpectedStatusErr(resp) err := remoteserrors.NewUnexpectedStatusErr(resp)
@ -205,7 +206,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
Offset: desc.Size, 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: default:
err := remoteserrors.NewUnexpectedStatusErr(resp) err := remoteserrors.NewUnexpectedStatusErr(resp)
log.G(ctx).WithField("resp", resp).WithField("body", string(err.(remoteserrors.ErrUnexpectedStatus).Body)).Debug("unexpected response") log.G(ctx).WithField("resp", resp).WithField("body", string(err.(remoteserrors.ErrUnexpectedStatus).Body)).Debug("unexpected response")
@ -221,7 +222,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
if strings.HasPrefix(location, "/") { if strings.HasPrefix(location, "/") {
lurl, err = url.Parse(lhost.Scheme + "://" + lhost.Host + location) lurl, err = url.Parse(lhost.Scheme + "://" + lhost.Host + location)
if err != nil { 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 { } else {
if !strings.Contains(location, "://") { if !strings.Contains(location, "://") {
@ -229,7 +230,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
} }
lurl, err = url.Parse(location) lurl, err = url.Parse(location)
if err != nil { 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 { if lurl.Host != lhost.Host || lhost.Scheme != lurl.Scheme {
@ -374,7 +375,7 @@ func (pw *pushWriter) Digest() digest.Digest {
func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error { func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
// Check whether read has already thrown an error // Check whether read has already thrown an error
if _, err := pw.pipe.Write([]byte{}); err != nil && err != io.ErrClosedPipe { 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 { if err := pw.pipe.Close(); err != nil {
@ -397,11 +398,11 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
status, err := pw.tracker.GetStatus(pw.ref) status, err := pw.tracker.GetStatus(pw.ref)
if err != nil { 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 { 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 == "" { if expected == "" {
@ -410,11 +411,11 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
actual, err := digest.Parse(resp.Header.Get("Docker-Content-Digest")) actual, err := digest.Parse(resp.Header.Get("Docker-Content-Digest"))
if err != nil { 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 { 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 status.Committed = true

@ -17,10 +17,9 @@
package docker package docker
import ( import (
"errors"
"net" "net"
"net/http" "net/http"
"github.com/pkg/errors"
) )
// HostCapabilities represent the capabilities of the registry // HostCapabilities represent the capabilities of the registry

@ -18,6 +18,7 @@ package docker
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
@ -34,7 +35,6 @@ import (
"github.com/containerd/containerd/version" "github.com/containerd/containerd/version"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/net/context/ctxhttp" "golang.org/x/net/context/ctxhttp"
) )
@ -254,7 +254,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
hosts := base.filterHosts(caps) hosts := base.filterHosts(caps)
if len(hosts) == 0 { 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) ctx, err = ContextWithRepositoryScope(ctx, refspec, false)
@ -279,7 +279,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
resp, err := req.doWithRetries(ctx, nil) resp, err := req.doWithRetries(ctx, nil)
if err != nil { if err != nil {
if errors.Is(err, ErrInvalidAuthorization) { 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 // Store the error for referencing later
if firstErr == nil { if firstErr == nil {
@ -298,11 +298,11 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
if resp.StatusCode > 399 { if resp.StatusCode > 399 {
// Set firstErr when encountering the first non-404 status code. // Set firstErr when encountering the first non-404 status code.
if firstErr == nil { 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 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 size := resp.ContentLength
contentType := getManifestMediaType(resp) contentType := getManifestMediaType(resp)
@ -318,7 +318,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
if dgstHeader != "" && size != -1 { if dgstHeader != "" && size != -1 {
if err := dgstHeader.Validate(); err != nil { 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 dgst = dgstHeader
} }
@ -366,7 +366,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
// Prevent resolving to excessively large manifests // Prevent resolving to excessively large manifests
if size > MaxManifestSize { if size > MaxManifestSize {
if firstErr == nil { 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 continue
} }
@ -387,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. // means that either no registries were given or each registry returned 404.
if firstErr == nil { if firstErr == nil {
firstErr = errors.Wrap(errdefs.ErrNotFound, ref) firstErr = fmt.Errorf("%s: %w", ref, errdefs.ErrNotFound)
} }
return "", ocispec.Descriptor{}, firstErr return "", ocispec.Descriptor{}, firstErr
@ -547,7 +547,7 @@ func (r *request) do(ctx context.Context) (*http.Response, error) {
ctx = log.WithLogger(ctx, log.G(ctx).WithField("url", u)) ctx = log.WithLogger(ctx, log.G(ctx).WithField("url", u))
log.G(ctx).WithFields(requestFields(req)).Debug("do request") log.G(ctx).WithFields(requestFields(req)).Debug("do request")
if err := r.authorize(ctx, req); err != nil { 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{} var client = &http.Client{}
@ -559,13 +559,16 @@ func (r *request) do(ctx context.Context) (*http.Response, error) {
if len(via) >= 10 { if len(via) >= 10 {
return errors.New("stopped after 10 redirects") 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) resp, err := ctxhttp.Do(ctx, client, req)
if err != nil { 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") log.G(ctx).WithFields(responseFields(resp)).Debug("fetch response received")
return resp, nil return resp, nil

@ -21,6 +21,7 @@ import (
"context" "context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"strconv" "strconv"
@ -28,8 +29,6 @@ import (
"sync" "sync"
"time" "time"
"golang.org/x/sync/errgroup"
"github.com/containerd/containerd/archive/compression" "github.com/containerd/containerd/archive/compression"
"github.com/containerd/containerd/content" "github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
@ -39,7 +38,7 @@ import (
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
specs "github.com/opencontainers/image-spec/specs-go" specs "github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors" "golang.org/x/sync/errgroup"
) )
const ( const (
@ -158,12 +157,12 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De
history, diffIDs, err := c.schema1ManifestHistory() history, diffIDs, err := c.schema1ManifestHistory()
if err != nil { 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 var img ocispec.Image
if err := json.Unmarshal([]byte(c.pulledManifest.History[0].V1Compatibility), &img); err != nil { 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 img.History = history
@ -174,7 +173,7 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De
b, err := json.MarshalIndent(img, "", " ") b, err := json.MarshalIndent(img, "", " ")
if err != nil { 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{ config := ocispec.Descriptor{
@ -198,7 +197,7 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De
mb, err := json.MarshalIndent(manifest, "", " ") mb, err := json.MarshalIndent(manifest, "", " ")
if err != nil { 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{ desc := ocispec.Descriptor{
@ -215,12 +214,12 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De
ref := remotes.MakeRefKey(ctx, desc) ref := remotes.MakeRefKey(ctx, desc)
if err := content.WriteBlob(ctx, c.contentStore, ref, bytes.NewReader(mb), desc, content.WithLabels(labels)); err != nil { 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) ref = remotes.MakeRefKey(ctx, config)
if err := content.WriteBlob(ctx, c.contentStore, ref, bytes.NewReader(b), config); err != nil { 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 return desc, nil
@ -349,7 +348,7 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
if desc.Size == -1 { if desc.Size == -1 {
info, err := c.contentStore.Info(ctx, desc.Digest) info, err := c.contentStore.Info(ctx, desc.Digest)
if err != nil { 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 desc.Size = info.Size
} }
@ -370,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 { 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() c.mu.Lock()
@ -384,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) { func (c *Converter) reuseLabelBlobState(ctx context.Context, desc ocispec.Descriptor) (bool, error) {
cinfo, err := c.contentStore.Info(ctx, desc.Digest) cinfo, err := c.contentStore.Info(ctx, desc.Digest)
if err != nil { 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 desc.Size = cinfo.Size
@ -441,7 +440,7 @@ func (c *Converter) schema1ManifestHistory() ([]ocispec.History, []digest.Digest
for i := range m.History { for i := range m.History {
var h v1History var h v1History
if err := json.Unmarshal([]byte(m.History[i].V1Compatibility), &h); err != nil { 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 blobSum := m.FSLayers[i].BlobSum
@ -553,7 +552,7 @@ func stripSignature(b []byte) ([]byte, error) {
} }
pb, err := joseBase64UrlDecode(sig.Signatures[0].Protected) pb, err := joseBase64UrlDecode(sig.Signatures[0].Protected)
if err != nil { 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 var protected protectedBlock
@ -567,7 +566,7 @@ func stripSignature(b []byte) ([]byte, error) {
tail, err := joseBase64UrlDecode(protected.Tail) tail, err := joseBase64UrlDecode(protected.Tail)
if err != nil { 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 return append(b[:protected.Length], tail...), nil

@ -17,12 +17,12 @@
package docker package docker
import ( import (
"fmt"
"sync" "sync"
"github.com/containerd/containerd/content" "github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/moby/locker" "github.com/moby/locker"
"github.com/pkg/errors"
) )
// Status of a content operation // Status of a content operation
@ -67,7 +67,7 @@ func (t *memoryStatusTracker) GetStatus(ref string) (Status, error) {
defer t.m.Unlock() defer t.m.Unlock()
status, ok := t.statuses[ref] status, ok := t.statuses[ref]
if !ok { 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 return status, nil
} }

@ -18,6 +18,7 @@ package remotes
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"io" "io"
"strings" "strings"
@ -29,7 +30,6 @@ import (
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/platforms" "github.com/containerd/containerd/platforms"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/sync/semaphore" "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 // 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 // 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 // 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 ws.Offset == desc.Size {
// If writer is already complete, commit and return // If writer is already complete, commit and return
err := cw.Commit(ctx, desc.Size, desc.Digest) err := cw.Commit(ctx, desc.Size, desc.Digest)
if err != nil && !errdefs.IsAlreadyExists(err) { 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 return nil
} }
@ -243,8 +243,8 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, st
// as a marker for this problem // as a marker for this problem
if (manifestStack[i].MediaType == ocispec.MediaTypeImageIndex || if (manifestStack[i].MediaType == ocispec.MediaTypeImageIndex ||
manifestStack[i].MediaType == images.MediaTypeDockerSchema2ManifestList) && manifestStack[i].MediaType == images.MediaTypeDockerSchema2ManifestList) &&
errors.Cause(err) != nil && strings.Contains(errors.Cause(err).Error(), "400 Bad Request") { errors.Unwrap(err) != nil && strings.Contains(errors.Unwrap(err).Error(), "400 Bad Request") {
return errors.Wrap(err, "manifest list/index references to blobs and/or manifests are missing in your target registry") return fmt.Errorf("manifest list/index references to blobs and/or manifests are missing in your target registry: %w", err)
} }
return err return err
} }
@ -253,6 +253,43 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, st
return nil 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 // FilterManifestByPlatformHandler allows Handler to handle non-target
// platform's manifest and configuration data. // platform's manifest and configuration data.
func FilterManifestByPlatformHandler(f images.HandlerFunc, m platforms.Matcher) images.HandlerFunc { func FilterManifestByPlatformHandler(f images.HandlerFunc, m platforms.Matcher) images.HandlerFunc {

@ -18,6 +18,7 @@ package contentserver
import ( import (
"context" "context"
"fmt"
"io" "io"
"sync" "sync"
@ -28,7 +29,6 @@ import (
ptypes "github.com/gogo/protobuf/types" ptypes "github.com/gogo/protobuf/types"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "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 req.Offset == 0 && ws.Offset > 0 {
if err := wr.Truncate(req.Offset); err != nil { 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 msg.Offset = req.Offset
} }

@ -23,7 +23,7 @@ var (
Package = "github.com/containerd/containerd" Package = "github.com/containerd/containerd"
// Version holds the complete version number. Filled in at linking time. // Version holds the complete version number. Filled in at linking time.
Version = "1.6.0-beta.3+unknown" Version = "1.6.0-rc.1+unknown"
// Revision is filled with the VCS (e.g. git) revision being used to build // Revision is filled with the VCS (e.g. git) revision being used to build
// the program at linking time. // the program at linking time.

@ -1,5 +1,5 @@
//go:build darwin || freebsd || openbsd //go:build !(linux || solaris || windows)
// +build darwin freebsd openbsd // +build !linux,!solaris,!windows
/* /*
Copyright The containerd Authors. Copyright The containerd Authors.

@ -0,0 +1,29 @@
run:
timeout: 1m
tests: true
linters:
disable-all: true
enable:
- asciicheck
- deadcode
- errcheck
- forcetypeassert
- gocritic
- gofmt
- goimports
- gosimple
- govet
- ineffassign
- misspell
- revive
- staticcheck
- structcheck
- typecheck
- unused
- varcheck
issues:
exclude-use-default: false
max-issues-per-linter: 0
max-same-issues: 10

@ -0,0 +1,6 @@
# CHANGELOG
## v1.0.0-rc1
This is the first logged release. Major changes (including breaking changes)
have occurred since earlier tags.

@ -0,0 +1,17 @@
# Contributing
Logr is open to pull-requests, provided they fit within the intended scope of
the project. Specifically, this library aims to be VERY small and minimalist,
with no external dependencies.
## Compatibility
This project intends to follow [semantic versioning](http://semver.org) and
is very strict about compatibility. Any proposed changes MUST follow those
rules.
## Performance
As a logging library, logr must be as light-weight as possible. Any proposed
code change must include results of running the [benchmark](./benchmark)
before and after the change.

@ -1,112 +1,182 @@
# A more minimal logging API for Go # A minimal logging API for Go
Before you consider this package, please read [this blog post by the [![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.dev/github.com/go-logr/logr)
inimitable Dave Cheney][warning-makes-no-sense]. I really appreciate what
he has to say, and it largely aligns with my own experiences. Too many logr offers an(other) opinion on how Go programs and libraries can do logging
choices of levels means inconsistent logs. without becoming coupled to a particular logging implementation. This is not
an implementation of logging - it is an API. In fact it is two APIs with two
different sets of users.
The `Logger` type is intended for application and library authors. It provides
a relatively small API which can be used everywhere you want to emit logs. It
defers the actual act of writing logs (to files, to stdout, or whatever) to the
`LogSink` interface.
The `LogSink` interface is intended for logging library implementers. It is a
pure interface which can be implemented by logging frameworks to provide the actual logging
functionality.
This decoupling allows application and library developers to write code in
terms of `logr.Logger` (which has very low dependency fan-out) while the
implementation of logging is managed "up stack" (e.g. in or near `main()`.)
Application developers can then switch out implementations as necessary.
Many people assert that libraries should not be logging, and as such efforts
like this are pointless. Those people are welcome to convince the authors of
the tens-of-thousands of libraries that *DO* write logs that they are all
wrong. In the meantime, logr takes a more practical approach.
## Typical usage
Somewhere, early in an application's life, it will make a decision about which
logging library (implementation) it actually wants to use. Something like:
```
func main() {
// ... other setup code ...
// Create the "root" logger. We have chosen the "logimpl" implementation,
// which takes some initial parameters and returns a logr.Logger.
logger := logimpl.New(param1, param2)
// ... other setup code ...
```
Most apps will call into other libraries, create structures to govern the flow,
etc. The `logr.Logger` object can be passed to these other libraries, stored
in structs, or even used as a package-global variable, if needed. For example:
```
app := createTheAppObject(logger)
app.Run()
```
Outside of this early setup, no other packages need to know about the choice of
implementation. They write logs in terms of the `logr.Logger` that they
received:
This package offers a purely abstract interface, based on these ideas but with ```
a few twists. Code can depend on just this interface and have the actual type appObject struct {
logging implementation be injected from callers. Ideally only `main()` knows // ... other fields ...
what logging implementation is being used. logger logr.Logger
// ... other fields ...
}
# Differences from Dave's ideas func (app *appObject) Run() {
app.logger.Info("starting up", "timestamp", time.Now())
// ... app code ...
```
## Background
If the Go standard library had defined an interface for logging, this project
probably would not be needed. Alas, here we are.
### Inspiration
Before you consider this package, please read [this blog post by the
inimitable Dave Cheney][warning-makes-no-sense]. We really appreciate what
he has to say, and it largely aligns with our own experiences.
### Differences from Dave's ideas
The main differences are: The main differences are:
1) Dave basically proposes doing away with the notion of a logging API in favor 1. Dave basically proposes doing away with the notion of a logging API in favor
of `fmt.Printf()`. I disagree, especially when you consider things like output of `fmt.Printf()`. We disagree, especially when you consider things like output
locations, timestamps, file and line decorations, and structured logging. I locations, timestamps, file and line decorations, and structured logging. This
restrict the API to just 2 types of logs: info and error. package restricts the logging API to just 2 types of logs: info and error.
Info logs are things you want to tell the user which are not errors. Error Info logs are things you want to tell the user which are not errors. Error
logs are, well, errors. If your code receives an `error` from a subordinate logs are, well, errors. If your code receives an `error` from a subordinate
function call and is logging that `error` *and not returning it*, use error function call and is logging that `error` *and not returning it*, use error
logs. logs.
2) Verbosity-levels on info logs. This gives developers a chance to indicate 2. Verbosity-levels on info logs. This gives developers a chance to indicate
arbitrary grades of importance for info logs, without assigning names with arbitrary grades of importance for info logs, without assigning names with
semantic meaning such as "warning", "trace", and "debug". Superficially this semantic meaning such as "warning", "trace", and "debug." Superficially this
may feel very similar, but the primary difference is the lack of semantics. may feel very similar, but the primary difference is the lack of semantics.
Because verbosity is a numerical value, it's safe to assume that an app running Because verbosity is a numerical value, it's safe to assume that an app running
with higher verbosity means more (and less important) logs will be generated. with higher verbosity means more (and less important) logs will be generated.
This is a BETA grade API. ## Implementations (non-exhaustive)
There are implementations for the following logging libraries: There are implementations for the following logging libraries:
- **a function** (can bridge to non-structured libraries): [funcr](https://github.com/go-logr/logr/tree/master/funcr)
- **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr) - **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr)
- **k8s.io/klog**: [klogr](https://git.k8s.io/klog/klogr) - **k8s.io/klog** (for Kubernetes): [klogr](https://git.k8s.io/klog/klogr)
- **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr) - **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr)
- **log** (the Go standard library logger): - **log** (the Go standard library logger): [stdr](https://github.com/go-logr/stdr)
[stdr](https://github.com/go-logr/stdr)
- **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr) - **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr)
- **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend) - **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend)
- **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr) - **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr)
- **github.com/rs/zerolog**: [zerologr](https://github.com/go-logr/zerologr)
# FAQ ## FAQ
## Conceptual ### Conceptual
## Why structured logging? #### Why structured logging?
- **Structured logs are more easily queriable**: Since you've got - **Structured logs are more easily queryable**: Since you've got
key-value pairs, it's much easier to query your structured logs for key-value pairs, it's much easier to query your structured logs for
particular values by filtering on the contents of a particular key -- particular values by filtering on the contents of a particular key --
think searching request logs for error codes, Kubernetes reconcilers for think searching request logs for error codes, Kubernetes reconcilers for
the name and namespace of the reconciled object, etc the name and namespace of the reconciled object, etc.
- **Structured logging makes it easier to have cross-referencable logs**: - **Structured logging makes it easier to have cross-referenceable logs**:
Similarly to searchability, if you maintain conventions around your Similarly to searchability, if you maintain conventions around your
keys, it becomes easy to gather all log lines related to a particular keys, it becomes easy to gather all log lines related to a particular
concept. concept.
- **Structured logs allow better dimensions of filtering**: if you have - **Structured logs allow better dimensions of filtering**: if you have
structure to your logs, you've got more precise control over how much structure to your logs, you've got more precise control over how much
information is logged -- you might choose in a particular configuration information is logged -- you might choose in a particular configuration
to log certain keys but not others, only log lines where a certain key to log certain keys but not others, only log lines where a certain key
matches a certain value, etc, instead of just having v-levels and names matches a certain value, etc., instead of just having v-levels and names
to key off of. to key off of.
- **Structured logs better represent structured data**: sometimes, the - **Structured logs better represent structured data**: sometimes, the
data that you want to log is inherently structured (think tuple-link data that you want to log is inherently structured (think tuple-link
objects). Structured logs allow you to preserve that structure when objects.) Structured logs allow you to preserve that structure when
outputting. outputting.
## Why V-levels? #### Why V-levels?
**V-levels give operators an easy way to control the chattiness of log **V-levels give operators an easy way to control the chattiness of log
operations**. V-levels provide a way for a given package to distinguish operations**. V-levels provide a way for a given package to distinguish
the relative importance or verbosity of a given log message. Then, if the relative importance or verbosity of a given log message. Then, if
a particular logger or package is logging too many messages, the user a particular logger or package is logging too many messages, the user
of the package can simply change the v-levels for that library. of the package can simply change the v-levels for that library.
## Why not more named levels, like Warning? #### Why not named levels, like Info/Warning/Error?
Read [Dave Cheney's post][warning-makes-no-sense]. Then read [Differences Read [Dave Cheney's post][warning-makes-no-sense]. Then read [Differences
from Dave's ideas](#differences-from-daves-ideas). from Dave's ideas](#differences-from-daves-ideas).
## Why not allow format strings, too? #### Why not allow format strings, too?
**Format strings negate many of the benefits of structured logs**: **Format strings negate many of the benefits of structured logs**:
- They're not easily searchable without resorting to fuzzy searching, - They're not easily searchable without resorting to fuzzy searching,
regular expressions, etc regular expressions, etc.
- They don't store structured data well, since contents are flattened into - They don't store structured data well, since contents are flattened into
a string a string.
- They're not cross-referencable - They're not cross-referenceable.
- They don't compress easily, since the message is not constant - They don't compress easily, since the message is not constant.
(unless you turn positional parameters into key-value pairs with numerical (Unless you turn positional parameters into key-value pairs with numerical
keys, at which point you've gotten key-value logging with meaningless keys, at which point you've gotten key-value logging with meaningless
keys) keys.)
## Practical ### Practical
## Why key-value pairs, and not a map? #### Why key-value pairs, and not a map?
Key-value pairs are *much* easier to optimize, especially around Key-value pairs are *much* easier to optimize, especially around
allocations. Zap (a structured logger that inspired logr's interface) has allocations. Zap (a structured logger that inspired logr's interface) has
@ -117,26 +187,26 @@ While the interface ends up being a little less obvious, you get
potentially better performance, plus avoid making users type potentially better performance, plus avoid making users type
`map[string]string{}` every time they want to log. `map[string]string{}` every time they want to log.
## What if my V-levels differ between libraries? #### What if my V-levels differ between libraries?
That's fine. Control your V-levels on a per-logger basis, and use the That's fine. Control your V-levels on a per-logger basis, and use the
`WithName` function to pass different loggers to different libraries. `WithName` method to pass different loggers to different libraries.
Generally, you should take care to ensure that you have relatively Generally, you should take care to ensure that you have relatively
consistent V-levels within a given logger, however, as this makes deciding consistent V-levels within a given logger, however, as this makes deciding
on what verbosity of logs to request easier. on what verbosity of logs to request easier.
## But I *really* want to use a format string! #### But I really want to use a format string!
That's not actually a question. Assuming your question is "how do That's not actually a question. Assuming your question is "how do
I convert my mental model of logging with format strings to logging with I convert my mental model of logging with format strings to logging with
constant messages": constant messages":
1. figure out what the error actually is, as you'd write in a TL;DR style, 1. Figure out what the error actually is, as you'd write in a TL;DR style,
and use that as a message and use that as a message.
2. For every place you'd write a format specifier, look to the word before 2. For every place you'd write a format specifier, look to the word before
it, and add that as a key value pair it, and add that as a key value pair.
For instance, consider the following examples (all taken from spots in the For instance, consider the following examples (all taken from spots in the
Kubernetes codebase): Kubernetes codebase):
@ -150,34 +220,59 @@ Kubernetes codebase):
response when requesting url", "attempt", retries, "after response when requesting url", "attempt", retries, "after
seconds", seconds, "url", url)` seconds", seconds, "url", url)`
If you *really* must use a format string, place it as a key value, and If you *really* must use a format string, use it in a key's value, and
call `fmt.Sprintf` yourself -- for instance, `log.Printf("unable to call `fmt.Sprintf` yourself. For instance: `log.Printf("unable to
reflect over type %T")` becomes `logger.Info("unable to reflect over reflect over type %T")` becomes `logger.Info("unable to reflect over
type", "type", fmt.Sprintf("%T"))`. In general though, the cases where type", "type", fmt.Sprintf("%T"))`. In general though, the cases where
this is necessary should be few and far between. this is necessary should be few and far between.
## How do I choose my V-levels? #### How do I choose my V-levels?
This is basically the only hard constraint: increase V-levels to denote This is basically the only hard constraint: increase V-levels to denote
more verbose or more debug-y logs. more verbose or more debug-y logs.
Otherwise, you can start out with `0` as "you always want to see this", Otherwise, you can start out with `0` as "you always want to see this",
`1` as "common logging that you might *possibly* want to turn off", and `1` as "common logging that you might *possibly* want to turn off", and
`10` as "I would like to performance-test your log collection stack". `10` as "I would like to performance-test your log collection stack."
Then gradually choose levels in between as you need them, working your way Then gradually choose levels in between as you need them, working your way
down from 10 (for debug and trace style logs) and up from 1 (for chattier down from 10 (for debug and trace style logs) and up from 1 (for chattier
info-type logs). info-type logs.)
#### How do I choose my keys?
## How do I choose my keys Keys are fairly flexible, and can hold more or less any string
value. For best compatibility with implementations and consistency
with existing code in other projects, there are a few conventions you
should consider.
- make your keys human-readable - Make your keys human-readable.
- constant keys are generally a good idea - Constant keys are generally a good idea.
- be consistent across your codebase - Be consistent across your codebase.
- keys should naturally match parts of the message string - Keys should naturally match parts of the message string.
- Use lower case for simple keys and
[lowerCamelCase](https://en.wiktionary.org/wiki/lowerCamelCase) for
more complex ones. Kubernetes is one example of a project that has
[adopted that
convention](https://github.com/kubernetes/community/blob/HEAD/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments).
While key names are mostly unrestricted (and spaces are acceptable), While key names are mostly unrestricted (and spaces are acceptable),
it's generally a good idea to stick to printable ascii characters, or at it's generally a good idea to stick to printable ascii characters, or at
least match the general character set of your log lines. least match the general character set of your log lines.
#### Why should keys be constant values?
The point of structured logging is to make later log processing easier. Your
keys are, effectively, the schema of each log message. If you use different
keys across instances of the same log line, you will make your structured logs
much harder to use. `Sprintf()` is for values, not for keys!
#### Why is this not a pure interface?
The Logger type is implemented as a struct in order to allow the Go compiler to
optimize things like high-V `Info` logs that are not triggered. Not all of
these implementations are implemented yet, but this structure was suggested as
a way to ensure they *can* be implemented. All of the real work is behind the
`LogSink` interface.
[warning-makes-no-sense]: http://dave.cheney.net/2015/11/05/lets-talk-about-logging [warning-makes-no-sense]: http://dave.cheney.net/2015/11/05/lets-talk-about-logging

@ -16,36 +16,39 @@ limitations under the License.
package logr package logr
// Discard returns a valid Logger that discards all messages logged to it. // Discard returns a Logger that discards all messages logged to it. It can be
// It can be used whenever the caller is not interested in the logs. // used whenever the caller is not interested in the logs. Logger instances
// produced by this function always compare as equal.
func Discard() Logger { func Discard() Logger {
return DiscardLogger{} return Logger{
level: 0,
sink: discardLogSink{},
}
} }
// DiscardLogger is a Logger that discards all messages. // discardLogSink is a LogSink that discards all messages.
type DiscardLogger struct{} type discardLogSink struct{}
func (l DiscardLogger) Enabled() bool { // Verify that it actually implements the interface
return false var _ LogSink = discardLogSink{}
func (l discardLogSink) Init(RuntimeInfo) {
} }
func (l DiscardLogger) Info(msg string, keysAndValues ...interface{}) { func (l discardLogSink) Enabled(int) bool {
return false
} }
func (l DiscardLogger) Error(err error, msg string, keysAndValues ...interface{}) { func (l discardLogSink) Info(int, string, ...interface{}) {
} }
func (l DiscardLogger) V(level int) Logger { func (l discardLogSink) Error(error, string, ...interface{}) {
return l
} }
func (l DiscardLogger) WithValues(keysAndValues ...interface{}) Logger { func (l discardLogSink) WithValues(...interface{}) LogSink {
return l return l
} }
func (l DiscardLogger) WithName(name string) Logger { func (l discardLogSink) WithName(string) LogSink {
return l return l
} }
// Verify that it actually implements the interface
var _ Logger = DiscardLogger{}

@ -0,0 +1,759 @@
/*
Copyright 2021 The logr 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 funcr implements formatting of structured log messages and
// optionally captures the call site and timestamp.
//
// The simplest way to use it is via its implementation of a
// github.com/go-logr/logr.LogSink with output through an arbitrary
// "write" function. See New and NewJSON for details.
//
// Custom LogSinks
//
// For users who need more control, a funcr.Formatter can be embedded inside
// your own custom LogSink implementation. This is useful when the LogSink
// needs to implement additional methods, for example.
//
// Formatting
//
// This will respect logr.Marshaler, fmt.Stringer, and error interfaces for
// values which are being logged. When rendering a struct, funcr will use Go's
// standard JSON tags (all except "string").
package funcr
import (
"bytes"
"encoding"
"fmt"
"path/filepath"
"reflect"
"runtime"
"strconv"
"strings"
"time"
"github.com/go-logr/logr"
)
// New returns a logr.Logger which is implemented by an arbitrary function.
func New(fn func(prefix, args string), opts Options) logr.Logger {
return logr.New(newSink(fn, NewFormatter(opts)))
}
// NewJSON returns a logr.Logger which is implemented by an arbitrary function
// and produces JSON output.
func NewJSON(fn func(obj string), opts Options) logr.Logger {
fnWrapper := func(_, obj string) {
fn(obj)
}
return logr.New(newSink(fnWrapper, NewFormatterJSON(opts)))
}
// Underlier exposes access to the underlying logging function. Since
// callers only have a logr.Logger, they have to know which
// implementation is in use, so this interface is less of an
// abstraction and more of a way to test type conversion.
type Underlier interface {
GetUnderlying() func(prefix, args string)
}
func newSink(fn func(prefix, args string), formatter Formatter) logr.LogSink {
l := &fnlogger{
Formatter: formatter,
write: fn,
}
// For skipping fnlogger.Info and fnlogger.Error.
l.Formatter.AddCallDepth(1)
return l
}
// Options carries parameters which influence the way logs are generated.
type Options struct {
// LogCaller tells funcr to add a "caller" key to some or all log lines.
// This has some overhead, so some users might not want it.
LogCaller MessageClass
// LogCallerFunc tells funcr to also log the calling function name. This
// has no effect if caller logging is not enabled (see Options.LogCaller).
LogCallerFunc bool
// LogTimestamp tells funcr to add a "ts" key to log lines. This has some
// overhead, so some users might not want it.
LogTimestamp bool
// TimestampFormat tells funcr how to render timestamps when LogTimestamp
// is enabled. If not specified, a default format will be used. For more
// details, see docs for Go's time.Layout.
TimestampFormat string
// Verbosity tells funcr which V logs to produce. Higher values enable
// more logs. Info logs at or below this level will be written, while logs
// above this level will be discarded.
Verbosity int
// RenderBuiltinsHook allows users to mutate the list of key-value pairs
// while a log line is being rendered. The kvList argument follows logr
// conventions - each pair of slice elements is comprised of a string key
// and an arbitrary value (verified and sanitized before calling this
// hook). The value returned must follow the same conventions. This hook
// can be used to audit or modify logged data. For example, you might want
// to prefix all of funcr's built-in keys with some string. This hook is
// only called for built-in (provided by funcr itself) key-value pairs.
// Equivalent hooks are offered for key-value pairs saved via
// logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and
// for user-provided pairs (see RenderArgsHook).
RenderBuiltinsHook func(kvList []interface{}) []interface{}
// RenderValuesHook is the same as RenderBuiltinsHook, except that it is
// only called for key-value pairs saved via logr.Logger.WithValues. See
// RenderBuiltinsHook for more details.
RenderValuesHook func(kvList []interface{}) []interface{}
// RenderArgsHook is the same as RenderBuiltinsHook, except that it is only
// called for key-value pairs passed directly to Info and Error. See
// RenderBuiltinsHook for more details.
RenderArgsHook func(kvList []interface{}) []interface{}
// MaxLogDepth tells funcr how many levels of nested fields (e.g. a struct
// that contains a struct, etc.) it may log. Every time it finds a struct,
// slice, array, or map the depth is increased by one. When the maximum is
// reached, the value will be converted to a string indicating that the max
// depth has been exceeded. If this field is not specified, a default
// value will be used.
MaxLogDepth int
}
// MessageClass indicates which category or categories of messages to consider.
type MessageClass int
const (
// None ignores all message classes.
None MessageClass = iota
// All considers all message classes.
All
// Info only considers info messages.
Info
// Error only considers error messages.
Error
)
// fnlogger inherits some of its LogSink implementation from Formatter
// and just needs to add some glue code.
type fnlogger struct {
Formatter
write func(prefix, args string)
}
func (l fnlogger) WithName(name string) logr.LogSink {
l.Formatter.AddName(name)
return &l
}
func (l fnlogger) WithValues(kvList ...interface{}) logr.LogSink {
l.Formatter.AddValues(kvList)
return &l
}
func (l fnlogger) WithCallDepth(depth int) logr.LogSink {
l.Formatter.AddCallDepth(depth)
return &l
}
func (l fnlogger) Info(level int, msg string, kvList ...interface{}) {
prefix, args := l.FormatInfo(level, msg, kvList)
l.write(prefix, args)
}
func (l fnlogger) Error(err error, msg string, kvList ...interface{}) {
prefix, args := l.FormatError(err, msg, kvList)
l.write(prefix, args)
}
func (l fnlogger) GetUnderlying() func(prefix, args string) {
return l.write
}
// Assert conformance to the interfaces.
var _ logr.LogSink = &fnlogger{}
var _ logr.CallDepthLogSink = &fnlogger{}
var _ Underlier = &fnlogger{}
// NewFormatter constructs a Formatter which emits a JSON-like key=value format.
func NewFormatter(opts Options) Formatter {
return newFormatter(opts, outputKeyValue)
}
// NewFormatterJSON constructs a Formatter which emits strict JSON.
func NewFormatterJSON(opts Options) Formatter {
return newFormatter(opts, outputJSON)
}
// Defaults for Options.
const defaultTimestampFormat = "2006-01-02 15:04:05.000000"
const defaultMaxLogDepth = 16
func newFormatter(opts Options, outfmt outputFormat) Formatter {
if opts.TimestampFormat == "" {
opts.TimestampFormat = defaultTimestampFormat
}
if opts.MaxLogDepth == 0 {
opts.MaxLogDepth = defaultMaxLogDepth
}
f := Formatter{
outputFormat: outfmt,
prefix: "",
values: nil,
depth: 0,
opts: opts,
}
return f
}
// Formatter is an opaque struct which can be embedded in a LogSink
// implementation. It should be constructed with NewFormatter. Some of
// its methods directly implement logr.LogSink.
type Formatter struct {
outputFormat outputFormat
prefix string
values []interface{}
valuesStr string
depth int
opts Options
}
// outputFormat indicates which outputFormat to use.
type outputFormat int
const (
// outputKeyValue emits a JSON-like key=value format, but not strict JSON.
outputKeyValue outputFormat = iota
// outputJSON emits strict JSON.
outputJSON
)
// PseudoStruct is a list of key-value pairs that gets logged as a struct.
type PseudoStruct []interface{}
// render produces a log line, ready to use.
func (f Formatter) render(builtins, args []interface{}) string {
// Empirically bytes.Buffer is faster than strings.Builder for this.
buf := bytes.NewBuffer(make([]byte, 0, 1024))
if f.outputFormat == outputJSON {
buf.WriteByte('{')
}
vals := builtins
if hook := f.opts.RenderBuiltinsHook; hook != nil {
vals = hook(f.sanitize(vals))
}
f.flatten(buf, vals, false, false) // keys are ours, no need to escape
continuing := len(builtins) > 0
if len(f.valuesStr) > 0 {
if continuing {
if f.outputFormat == outputJSON {
buf.WriteByte(',')
} else {
buf.WriteByte(' ')
}
}
continuing = true
buf.WriteString(f.valuesStr)
}
vals = args
if hook := f.opts.RenderArgsHook; hook != nil {
vals = hook(f.sanitize(vals))
}
f.flatten(buf, vals, continuing, true) // escape user-provided keys
if f.outputFormat == outputJSON {
buf.WriteByte('}')
}
return buf.String()
}
// flatten renders a list of key-value pairs into a buffer. If continuing is
// true, it assumes that the buffer has previous values and will emit a
// separator (which depends on the output format) before the first pair it
// writes. If escapeKeys is true, the keys are assumed to have
// non-JSON-compatible characters in them and must be evaluated for escapes.
//
// This function returns a potentially modified version of kvList, which
// ensures that there is a value for every key (adding a value if needed) and
// that each key is a string (substituting a key if needed).
func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing bool, escapeKeys bool) []interface{} {
// This logic overlaps with sanitize() but saves one type-cast per key,
// which can be measurable.
if len(kvList)%2 != 0 {
kvList = append(kvList, noValue)
}
for i := 0; i < len(kvList); i += 2 {
k, ok := kvList[i].(string)
if !ok {
k = f.nonStringKey(kvList[i])
kvList[i] = k
}
v := kvList[i+1]
if i > 0 || continuing {
if f.outputFormat == outputJSON {
buf.WriteByte(',')
} else {
// In theory the format could be something we don't understand. In
// practice, we control it, so it won't be.
buf.WriteByte(' ')
}
}
if escapeKeys {
buf.WriteString(prettyString(k))
} else {
// this is faster
buf.WriteByte('"')
buf.WriteString(k)
buf.WriteByte('"')
}
if f.outputFormat == outputJSON {
buf.WriteByte(':')
} else {
buf.WriteByte('=')
}
buf.WriteString(f.pretty(v))
}
return kvList
}
func (f Formatter) pretty(value interface{}) string {
return f.prettyWithFlags(value, 0, 0)
}
const (
flagRawStruct = 0x1 // do not print braces on structs
)
// TODO: This is not fast. Most of the overhead goes here.
func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) string {
if depth > f.opts.MaxLogDepth {
return `"<max-log-depth-exceeded>"`
}
// Handle types that take full control of logging.
if v, ok := value.(logr.Marshaler); ok {
// Replace the value with what the type wants to get logged.
// That then gets handled below via reflection.
value = v.MarshalLog()
}
// Handle types that want to format themselves.
switch v := value.(type) {
case fmt.Stringer:
value = v.String()
case error:
value = v.Error()
}
// Handling the most common types without reflect is a small perf win.
switch v := value.(type) {
case bool:
return strconv.FormatBool(v)
case string:
return prettyString(v)
case int:
return strconv.FormatInt(int64(v), 10)
case int8:
return strconv.FormatInt(int64(v), 10)
case int16:
return strconv.FormatInt(int64(v), 10)
case int32:
return strconv.FormatInt(int64(v), 10)
case int64:
return strconv.FormatInt(int64(v), 10)
case uint:
return strconv.FormatUint(uint64(v), 10)
case uint8:
return strconv.FormatUint(uint64(v), 10)
case uint16:
return strconv.FormatUint(uint64(v), 10)
case uint32:
return strconv.FormatUint(uint64(v), 10)
case uint64:
return strconv.FormatUint(v, 10)
case uintptr:
return strconv.FormatUint(uint64(v), 10)
case float32:
return strconv.FormatFloat(float64(v), 'f', -1, 32)
case float64:
return strconv.FormatFloat(v, 'f', -1, 64)
case complex64:
return `"` + strconv.FormatComplex(complex128(v), 'f', -1, 64) + `"`
case complex128:
return `"` + strconv.FormatComplex(v, 'f', -1, 128) + `"`
case PseudoStruct:
buf := bytes.NewBuffer(make([]byte, 0, 1024))
v = f.sanitize(v)
if flags&flagRawStruct == 0 {
buf.WriteByte('{')
}
for i := 0; i < len(v); i += 2 {
if i > 0 {
buf.WriteByte(',')
}
// arbitrary keys might need escaping
buf.WriteString(prettyString(v[i].(string)))
buf.WriteByte(':')
buf.WriteString(f.prettyWithFlags(v[i+1], 0, depth+1))
}
if flags&flagRawStruct == 0 {
buf.WriteByte('}')
}
return buf.String()
}
buf := bytes.NewBuffer(make([]byte, 0, 256))
t := reflect.TypeOf(value)
if t == nil {
return "null"
}
v := reflect.ValueOf(value)
switch t.Kind() {
case reflect.Bool:
return strconv.FormatBool(v.Bool())
case reflect.String:
return prettyString(v.String())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return strconv.FormatInt(int64(v.Int()), 10)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return strconv.FormatUint(uint64(v.Uint()), 10)
case reflect.Float32:
return strconv.FormatFloat(float64(v.Float()), 'f', -1, 32)
case reflect.Float64:
return strconv.FormatFloat(v.Float(), 'f', -1, 64)
case reflect.Complex64:
return `"` + strconv.FormatComplex(complex128(v.Complex()), 'f', -1, 64) + `"`
case reflect.Complex128:
return `"` + strconv.FormatComplex(v.Complex(), 'f', -1, 128) + `"`
case reflect.Struct:
if flags&flagRawStruct == 0 {
buf.WriteByte('{')
}
for i := 0; i < t.NumField(); i++ {
fld := t.Field(i)
if fld.PkgPath != "" {
// reflect says this field is only defined for non-exported fields.
continue
}
if !v.Field(i).CanInterface() {
// reflect isn't clear exactly what this means, but we can't use it.
continue
}
name := ""
omitempty := false
if tag, found := fld.Tag.Lookup("json"); found {
if tag == "-" {
continue
}
if comma := strings.Index(tag, ","); comma != -1 {
if n := tag[:comma]; n != "" {
name = n
}
rest := tag[comma:]
if strings.Contains(rest, ",omitempty,") || strings.HasSuffix(rest, ",omitempty") {
omitempty = true
}
} else {
name = tag
}
}
if omitempty && isEmpty(v.Field(i)) {
continue
}
if i > 0 {
buf.WriteByte(',')
}
if fld.Anonymous && fld.Type.Kind() == reflect.Struct && name == "" {
buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), flags|flagRawStruct, depth+1))
continue
}
if name == "" {
name = fld.Name
}
// field names can't contain characters which need escaping
buf.WriteByte('"')
buf.WriteString(name)
buf.WriteByte('"')
buf.WriteByte(':')
buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), 0, depth+1))
}
if flags&flagRawStruct == 0 {
buf.WriteByte('}')
}
return buf.String()
case reflect.Slice, reflect.Array:
buf.WriteByte('[')
for i := 0; i < v.Len(); i++ {
if i > 0 {
buf.WriteByte(',')
}
e := v.Index(i)
buf.WriteString(f.prettyWithFlags(e.Interface(), 0, depth+1))
}
buf.WriteByte(']')
return buf.String()
case reflect.Map:
buf.WriteByte('{')
// This does not sort the map keys, for best perf.
it := v.MapRange()
i := 0
for it.Next() {
if i > 0 {
buf.WriteByte(',')
}
// If a map key supports TextMarshaler, use it.
keystr := ""
if m, ok := it.Key().Interface().(encoding.TextMarshaler); ok {
txt, err := m.MarshalText()
if err != nil {
keystr = fmt.Sprintf("<error-MarshalText: %s>", err.Error())
} else {
keystr = string(txt)
}
keystr = prettyString(keystr)
} else {
// prettyWithFlags will produce already-escaped values
keystr = f.prettyWithFlags(it.Key().Interface(), 0, depth+1)
if t.Key().Kind() != reflect.String {
// JSON only does string keys. Unlike Go's standard JSON, we'll
// convert just about anything to a string.
keystr = prettyString(keystr)
}
}
buf.WriteString(keystr)
buf.WriteByte(':')
buf.WriteString(f.prettyWithFlags(it.Value().Interface(), 0, depth+1))
i++
}
buf.WriteByte('}')
return buf.String()
case reflect.Ptr, reflect.Interface:
if v.IsNil() {
return "null"
}
return f.prettyWithFlags(v.Elem().Interface(), 0, depth)
}
return fmt.Sprintf(`"<unhandled-%s>"`, t.Kind().String())
}
func prettyString(s string) string {
// Avoid escaping (which does allocations) if we can.
if needsEscape(s) {
return strconv.Quote(s)
}
b := bytes.NewBuffer(make([]byte, 0, 1024))
b.WriteByte('"')
b.WriteString(s)
b.WriteByte('"')
return b.String()
}
// needsEscape determines whether the input string needs to be escaped or not,
// without doing any allocations.
func needsEscape(s string) bool {
for _, r := range s {
if !strconv.IsPrint(r) || r == '\\' || r == '"' {
return true
}
}
return false
}
func isEmpty(v reflect.Value) bool {
switch v.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
return v.Len() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Complex64, reflect.Complex128:
return v.Complex() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
}
return false
}
// Caller represents the original call site for a log line, after considering
// logr.Logger.WithCallDepth and logr.Logger.WithCallStackHelper. The File and
// Line fields will always be provided, while the Func field is optional.
// Users can set the render hook fields in Options to examine logged key-value
// pairs, one of which will be {"caller", Caller} if the Options.LogCaller
// field is enabled for the given MessageClass.
type Caller struct {
// File is the basename of the file for this call site.
File string `json:"file"`
// Line is the line number in the file for this call site.
Line int `json:"line"`
// Func is the function name for this call site, or empty if
// Options.LogCallerFunc is not enabled.
Func string `json:"function,omitempty"`
}
func (f Formatter) caller() Caller {
// +1 for this frame, +1 for Info/Error.
pc, file, line, ok := runtime.Caller(f.depth + 2)
if !ok {
return Caller{"<unknown>", 0, ""}
}
fn := ""
if f.opts.LogCallerFunc {
if fp := runtime.FuncForPC(pc); fp != nil {
fn = fp.Name()
}
}
return Caller{filepath.Base(file), line, fn}
}
const noValue = "<no-value>"
func (f Formatter) nonStringKey(v interface{}) string {
return fmt.Sprintf("<non-string-key: %s>", f.snippet(v))
}
// snippet produces a short snippet string of an arbitrary value.
func (f Formatter) snippet(v interface{}) string {
const snipLen = 16
snip := f.pretty(v)
if len(snip) > snipLen {
snip = snip[:snipLen]
}
return snip
}
// sanitize ensures that a list of key-value pairs has a value for every key
// (adding a value if needed) and that each key is a string (substituting a key
// if needed).
func (f Formatter) sanitize(kvList []interface{}) []interface{} {
if len(kvList)%2 != 0 {
kvList = append(kvList, noValue)
}
for i := 0; i < len(kvList); i += 2 {
_, ok := kvList[i].(string)
if !ok {
kvList[i] = f.nonStringKey(kvList[i])
}
}
return kvList
}
// Init configures this Formatter from runtime info, such as the call depth
// imposed by logr itself.
// Note that this receiver is a pointer, so depth can be saved.
func (f *Formatter) Init(info logr.RuntimeInfo) {
f.depth += info.CallDepth
}
// Enabled checks whether an info message at the given level should be logged.
func (f Formatter) Enabled(level int) bool {
return level <= f.opts.Verbosity
}
// GetDepth returns the current depth of this Formatter. This is useful for
// implementations which do their own caller attribution.
func (f Formatter) GetDepth() int {
return f.depth
}
// FormatInfo renders an Info log message into strings. The prefix will be
// empty when no names were set (via AddNames), or when the output is
// configured for JSON.
func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string) {
args := make([]interface{}, 0, 64) // using a constant here impacts perf
prefix = f.prefix
if f.outputFormat == outputJSON {
args = append(args, "logger", prefix)
prefix = ""
}
if f.opts.LogTimestamp {
args = append(args, "ts", time.Now().Format(f.opts.TimestampFormat))
}
if policy := f.opts.LogCaller; policy == All || policy == Info {
args = append(args, "caller", f.caller())
}
args = append(args, "level", level, "msg", msg)
return prefix, f.render(args, kvList)
}
// FormatError renders an Error log message into strings. The prefix will be
// empty when no names were set (via AddNames), or when the output is
// configured for JSON.
func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string) {
args := make([]interface{}, 0, 64) // using a constant here impacts perf
prefix = f.prefix
if f.outputFormat == outputJSON {
args = append(args, "logger", prefix)
prefix = ""
}
if f.opts.LogTimestamp {
args = append(args, "ts", time.Now().Format(f.opts.TimestampFormat))
}
if policy := f.opts.LogCaller; policy == All || policy == Error {
args = append(args, "caller", f.caller())
}
args = append(args, "msg", msg)
var loggableErr interface{}
if err != nil {
loggableErr = err.Error()
}
args = append(args, "error", loggableErr)
return f.prefix, f.render(args, kvList)
}
// AddName appends the specified name. funcr uses '/' characters to separate
// name elements. Callers should not pass '/' in the provided name string, but
// this library does not actually enforce that.
func (f *Formatter) AddName(name string) {
if len(f.prefix) > 0 {
f.prefix += "/"
}
f.prefix += name
}
// AddValues adds key-value pairs to the set of saved values to be logged with
// each log line.
func (f *Formatter) AddValues(kvList []interface{}) {
// Three slice args forces a copy.
n := len(f.values)
f.values = append(f.values[:n:n], kvList...)
vals := f.values
if hook := f.opts.RenderValuesHook; hook != nil {
vals = hook(f.sanitize(vals))
}
// Pre-render values, so we don't have to do it on each Info/Error call.
buf := bytes.NewBuffer(make([]byte, 0, 1024))
f.flatten(buf, vals, false, true) // escape user-provided keys
f.valuesStr = buf.String()
}
// AddCallDepth increases the number of stack-frames to skip when attributing
// the log line to a file and line.
func (f *Formatter) AddCallDepth(depth int) {
f.depth += depth
}

@ -1,3 +1,3 @@
module github.com/go-logr/logr module github.com/go-logr/logr
go 1.14 go 1.16

@ -16,83 +16,104 @@ limitations under the License.
// This design derives from Dave Cheney's blog: // This design derives from Dave Cheney's blog:
// http://dave.cheney.net/2015/11/05/lets-talk-about-logging // http://dave.cheney.net/2015/11/05/lets-talk-about-logging
//
// This is a BETA grade API. Until there is a significant 2nd implementation,
// I don't really know how it will change.
// Package logr defines abstract interfaces for logging. Packages can depend on // Package logr defines a general-purpose logging API and abstract interfaces
// these interfaces and callers can implement logging in whatever way is // to back that API. Packages in the Go ecosystem can depend on this package,
// appropriate. // while callers can implement logging with whatever backend is appropriate.
// //
// Usage // Usage
// //
// Logging is done using a Logger. Loggers can have name prefixes and named // Logging is done using a Logger instance. Logger is a concrete type with
// values attached, so that all log messages logged with that Logger have some // methods, which defers the actual logging to a LogSink interface. The main
// base context associated. // methods of Logger are Info() and Error(). Arguments to Info() and Error()
// are key/value pairs rather than printf-style formatted strings, emphasizing
// "structured logging".
// //
// The term "key" is used to refer to the name associated with a particular // With Go's standard log package, we might write:
// value, to disambiguate it from the general Logger name. // log.Printf("setting target value %s", targetValue)
// //
// For instance, suppose we're trying to reconcile the state of an object, and // With logr's structured logging, we'd write:
// we want to log that we've made some decision. // logger.Info("setting target", "value", targetValue)
// //
// With the traditional log package, we might write: // Errors are much the same. Instead of:
// log.Printf("decided to set field foo to value %q for object %s/%s", // log.Printf("failed to open the pod bay door for user %s: %v", user, err)
// targetValue, object.Namespace, object.Name)
// //
// With logr's structured logging, we'd write: // We'd write:
// // elsewhere in the file, set up the logger to log with the prefix of // logger.Error(err, "failed to open the pod bay door", "user", user)
// // "reconcilers", and the named value target-type=Foo, for extra context.
// log := mainLogger.WithName("reconcilers").WithValues("target-type", "Foo")
// //
// // later on... // Info() and Error() are very similar, but they are separate methods so that
// log.Info("setting foo on object", "value", targetValue, "object", object) // LogSink implementations can choose to do things like attach additional
// information (such as stack traces) on calls to Error(). Error() messages are
// always logged, regardless of the current verbosity. If there is no error
// instance available, passing nil is valid.
//
// Verbosity
//
// Often we want to log information only when the application in "verbose
// mode". To write log lines that are more verbose, Logger has a V() method.
// The higher the V-level of a log line, the less critical it is considered.
// Log-lines with V-levels that are not enabled (as per the LogSink) will not
// be written. Level V(0) is the default, and logger.V(0).Info() has the same
// meaning as logger.Info(). Negative V-levels have the same meaning as V(0).
// Error messages do not have a verbosity level and are always logged.
//
// Where we might have written:
// if flVerbose >= 2 {
// log.Printf("an unusual thing happened")
// }
//
// We can write:
// logger.V(2).Info("an unusual thing happened")
//
// Logger Names
//
// Logger instances can have name strings so that all messages logged through
// that instance have additional context. For example, you might want to add
// a subsystem name:
// //
// Depending on our logging implementation, we could then make logging decisions // logger.WithName("compactor").Info("started", "time", time.Now())
// based on field values (like only logging such events for objects in a certain
// namespace), or copy the structured information into a structured log store.
// //
// For logging errors, Logger has a method called Error. Suppose we wanted to // The WithName() method returns a new Logger, which can be passed to
// log an error while reconciling. With the traditional log package, we might // constructors or other functions for further use. Repeated use of WithName()
// write: // will accumulate name "segments". These name segments will be joined in some
// log.Errorf("unable to reconcile object %s/%s: %v", object.Namespace, object.Name, err) // way by the LogSink implementation. It is strongly recommended that name
// segments contain simple identifiers (letters, digits, and hyphen), and do
// not contain characters that could muddle the log output or confuse the
// joining operation (e.g. whitespace, commas, periods, slashes, brackets,
// quotes, etc).
// //
// With logr, we'd instead write: // Saved Values
// // assuming the above setup for log
// log.Error(err, "unable to reconcile object", "object", object)
// //
// This functions similarly to: // Logger instances can store any number of key/value pairs, which will be
// log.Info("unable to reconcile object", "error", err, "object", object) // logged alongside all messages logged through that instance. For example,
// you might want to create a Logger instance per managed object:
// //
// However, it ensures that a standard key for the error value ("error") is used // With the standard log package, we might write:
// across all error logging. Furthermore, certain implementations may choose to // log.Printf("decided to set field foo to value %q for object %s/%s",
// attach additional information (such as stack traces) on calls to Error, so // targetValue, object.Namespace, object.Name)
// it's preferred to use Error to log errors.
// //
// Parts of a log line // With logr we'd write:
// // Elsewhere: set up the logger to log the object name.
// obj.logger = mainLogger.WithValues(
// "name", obj.name, "namespace", obj.namespace)
// //
// Each log message from a Logger has four types of context: // // later on...
// logger name, log verbosity, log message, and the named values. // obj.logger.Info("setting foo", "value", targetValue)
// //
// The Logger name consists of a series of name "segments" added by successive // Best Practices
// calls to WithName. These name segments will be joined in some way by the
// underlying implementation. It is strongly recommended that name segments
// contain simple identifiers (letters, digits, and hyphen), and do not contain
// characters that could muddle the log output or confuse the joining operation
// (e.g. whitespace, commas, periods, slashes, brackets, quotes, etc).
// //
// Log verbosity represents how little a log matters. Level zero, the default, // Logger has very few hard rules, with the goal that LogSink implementations
// matters most. Increasing levels matter less and less. Try to avoid lots of // might have a lot of freedom to differentiate. There are, however, some
// different verbosity levels, and instead provide useful keys, logger names, // things to consider.
// and log messages for users to filter on. It's illegal to pass a log level
// below zero.
// //
// The log message consists of a constant message attached to the log line. // The log message consists of a constant message attached to the log line.
// This should generally be a simple description of what's occurring, and should // This should generally be a simple description of what's occurring, and should
// never be a format string. // never be a format string. Variable information can then be attached using
// named values.
// //
// Variable information can then be attached using named values (key/value // Keys are arbitrary strings, but should generally be constant values. Values
// pairs). Keys are arbitrary strings, while values may be any Go value. // may be any Go value, but how the value is formatted is determined by the
// LogSink implementation.
// //
// Key Naming Conventions // Key Naming Conventions
// //
@ -102,6 +123,7 @@ limitations under the License.
// * be constant (not dependent on input data) // * be constant (not dependent on input data)
// * contain only printable characters // * contain only printable characters
// * not contain whitespace or punctuation // * not contain whitespace or punctuation
// * use lower case for simple keys and lowerCamelCase for more complex ones
// //
// These guidelines help ensure that log data is processed properly regardless // These guidelines help ensure that log data is processed properly regardless
// of the log implementation. For example, log implementations will try to // of the log implementation. For example, log implementations will try to
@ -110,21 +132,22 @@ limitations under the License.
// While users are generally free to use key names of their choice, it's // While users are generally free to use key names of their choice, it's
// generally best to avoid using the following keys, as they're frequently used // generally best to avoid using the following keys, as they're frequently used
// by implementations: // by implementations:
// // * "caller": the calling information (file/line) of a particular log line
// * `"caller"`: the calling information (file/line) of a particular log line. // * "error": the underlying error value in the `Error` method
// * `"error"`: the underlying error value in the `Error` method. // * "level": the log level
// * `"level"`: the log level. // * "logger": the name of the associated logger
// * `"logger"`: the name of the associated logger. // * "msg": the log message
// * `"msg"`: the log message. // * "stacktrace": the stack trace associated with a particular log line or
// * `"stacktrace"`: the stack trace associated with a particular log line or // error (often from the `Error` message)
// error (often from the `Error` message). // * "ts": the timestamp for a log line
// * `"ts"`: the timestamp for a log line.
// //
// Implementations are encouraged to make use of these keys to represent the // Implementations are encouraged to make use of these keys to represent the
// above concepts, when necessary (for example, in a pure-JSON output form, it // above concepts, when necessary (for example, in a pure-JSON output form, it
// would be necessary to represent at least message and timestamp as ordinary // would be necessary to represent at least message and timestamp as ordinary
// named values). // named values).
// //
// Break Glass
//
// Implementations may choose to give callers access to the underlying // Implementations may choose to give callers access to the underlying
// logging implementation. The recommended pattern for this is: // logging implementation. The recommended pattern for this is:
// // Underlier exposes access to the underlying logging implementation. // // Underlier exposes access to the underlying logging implementation.
@ -134,81 +157,222 @@ limitations under the License.
// type Underlier interface { // type Underlier interface {
// GetUnderlying() <underlying-type> // GetUnderlying() <underlying-type>
// } // }
//
// Logger grants access to the sink to enable type assertions like this:
// func DoSomethingWithImpl(log logr.Logger) {
// if underlier, ok := log.GetSink()(impl.Underlier) {
// implLogger := underlier.GetUnderlying()
// ...
// }
// }
//
// Custom `With*` functions can be implemented by copying the complete
// Logger struct and replacing the sink in the copy:
// // WithFooBar changes the foobar parameter in the log sink and returns a
// // new logger with that modified sink. It does nothing for loggers where
// // the sink doesn't support that parameter.
// func WithFoobar(log logr.Logger, foobar int) logr.Logger {
// if foobarLogSink, ok := log.GetSink()(FoobarSink); ok {
// log = log.WithSink(foobarLogSink.WithFooBar(foobar))
// }
// return log
// }
//
// Don't use New to construct a new Logger with a LogSink retrieved from an
// existing Logger. Source code attribution might not work correctly and
// unexported fields in Logger get lost.
//
// Beware that the same LogSink instance may be shared by different logger
// instances. Calling functions that modify the LogSink will affect all of
// those.
package logr package logr
import ( import (
"context" "context"
) )
// TODO: consider adding back in format strings if they're really needed // New returns a new Logger instance. This is primarily used by libraries
// TODO: consider other bits of zap/zapcore functionality like ObjectMarshaller (for arbitrary objects) // implementing LogSink, rather than end users.
// TODO: consider other bits of glog functionality like Flush, OutputStats func New(sink LogSink) Logger {
logger := Logger{}
logger.setSink(sink)
sink.Init(runtimeInfo)
return logger
}
// Logger represents the ability to log messages, both errors and not. // setSink stores the sink and updates any related fields. It mutates the
type Logger interface { // logger and thus is only safe to use for loggers that are not currently being
// Enabled tests whether this Logger is enabled. For example, commandline // used concurrently.
// flags might be used to set the logging verbosity and disable some info func (l *Logger) setSink(sink LogSink) {
// logs. l.sink = sink
Enabled() bool }
// Info logs a non-error message with the given key/value pairs as context. // GetSink returns the stored sink.
// func (l Logger) GetSink() LogSink {
// The msg argument should be used to add some constant description to return l.sink
// the log line. The key/value pairs can then be used to add additional }
// variable information. The key/value pairs should alternate string
// keys and arbitrary values. // WithSink returns a copy of the logger with the new sink.
Info(msg string, keysAndValues ...interface{}) func (l Logger) WithSink(sink LogSink) Logger {
l.setSink(sink)
// Error logs an error, with the given message and key/value pairs as context. return l
// It functions similarly to calling Info with the "error" named value, but may }
// have unique behavior, and should be preferred for logging errors (see the
// package documentations for more information). // Logger is an interface to an abstract logging implementation. This is a
// // concrete type for performance reasons, but all the real work is passed on to
// The msg field should be used to add context to any underlying error, // a LogSink. Implementations of LogSink should provide their own constructors
// while the err field should be used to attach the actual error that // that return Logger, not LogSink.
// triggered this log line, if present. //
Error(err error, msg string, keysAndValues ...interface{}) // The underlying sink can be accessed through GetSink and be modified through
// WithSink. This enables the implementation of custom extensions (see "Break
// Glass" in the package documentation). Normally the sink should be used only
// indirectly.
type Logger struct {
sink LogSink
level int
}
// Enabled tests whether this Logger is enabled. For example, commandline
// flags might be used to set the logging verbosity and disable some info logs.
func (l Logger) Enabled() bool {
return l.sink.Enabled(l.level)
}
// Info logs a non-error message with the given key/value pairs as context.
//
// The msg argument should be used to add some constant description to the log
// line. The key/value pairs can then be used to add additional variable
// information. The key/value pairs must alternate string keys and arbitrary
// values.
func (l Logger) Info(msg string, keysAndValues ...interface{}) {
if l.Enabled() {
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
withHelper.GetCallStackHelper()()
}
l.sink.Info(l.level, msg, keysAndValues...)
}
}
// Error logs an error, with the given message and key/value pairs as context.
// It functions similarly to Info, but may have unique behavior, and should be
// preferred for logging errors (see the package documentations for more
// information). The log message will always be emitted, regardless of
// verbosity level.
//
// The msg argument should be used to add context to any underlying error,
// while the err argument should be used to attach the actual error that
// triggered this log line, if present. The err parameter is optional
// and nil may be passed instead of an error instance.
func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) {
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
withHelper.GetCallStackHelper()()
}
l.sink.Error(err, msg, keysAndValues...)
}
// V returns a new Logger instance for a specific verbosity level, relative to
// this Logger. In other words, V-levels are additive. A higher verbosity
// level means a log message is less important. Negative V-levels are treated
// as 0.
func (l Logger) V(level int) Logger {
if level < 0 {
level = 0
}
l.level += level
return l
}
// WithValues returns a new Logger instance with additional key/value pairs.
// See Info for documentation on how key/value pairs work.
func (l Logger) WithValues(keysAndValues ...interface{}) Logger {
l.setSink(l.sink.WithValues(keysAndValues...))
return l
}
// V returns an Logger value for a specific verbosity level, relative to // WithName returns a new Logger instance with the specified name element added
// this Logger. In other words, V values are additive. V higher verbosity // to the Logger's name. Successive calls with WithName append additional
// level means a log message is less important. It's illegal to pass a log // suffixes to the Logger's name. It's strongly recommended that name segments
// level less than zero. // contain only letters, digits, and hyphens (see the package documentation for
V(level int) Logger // more information).
func (l Logger) WithName(name string) Logger {
// WithValues adds some key-value pairs of context to a logger. l.setSink(l.sink.WithName(name))
// See Info for documentation on how key/value pairs work. return l
WithValues(keysAndValues ...interface{}) Logger
// WithName adds a new element to the logger's name.
// Successive calls with WithName continue to append
// suffixes to the logger's name. It's strongly recommended
// that name segments contain only letters, digits, and hyphens
// (see the package documentation for more information).
WithName(name string) Logger
} }
// InfoLogger provides compatibility with code that relies on the v0.1.0 // WithCallDepth returns a Logger instance that offsets the call stack by the
// interface. // specified number of frames when logging call site information, if possible.
// This is useful for users who have helper functions between the "real" call
// site and the actual calls to Logger methods. If depth is 0 the attribution
// should be to the direct caller of this function. If depth is 1 the
// attribution should skip 1 call frame, and so on. Successive calls to this
// are additive.
//
// If the underlying log implementation supports a WithCallDepth(int) method,
// it will be called and the result returned. If the implementation does not
// support CallDepthLogSink, the original Logger will be returned.
//
// To skip one level, WithCallStackHelper() should be used instead of
// WithCallDepth(1) because it works with implementions that support the
// CallDepthLogSink and/or CallStackHelperLogSink interfaces.
func (l Logger) WithCallDepth(depth int) Logger {
if withCallDepth, ok := l.sink.(CallDepthLogSink); ok {
l.setSink(withCallDepth.WithCallDepth(depth))
}
return l
}
// WithCallStackHelper returns a new Logger instance that skips the direct
// caller when logging call site information, if possible. This is useful for
// users who have helper functions between the "real" call site and the actual
// calls to Logger methods and want to support loggers which depend on marking
// each individual helper function, like loggers based on testing.T.
//
// In addition to using that new logger instance, callers also must call the
// returned function.
// //
// Deprecated: InfoLogger is an artifact of early versions of this API. New // If the underlying log implementation supports a WithCallDepth(int) method,
// users should never use it and existing users should use Logger instead. This // WithCallDepth(1) will be called to produce a new logger. If it supports a
// will be removed in a future release. // WithCallStackHelper() method, that will be also called. If the
type InfoLogger = Logger // implementation does not support either of these, the original Logger will be
// returned.
func (l Logger) WithCallStackHelper() (func(), Logger) {
var helper func()
if withCallDepth, ok := l.sink.(CallDepthLogSink); ok {
l.setSink(withCallDepth.WithCallDepth(1))
}
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
helper = withHelper.GetCallStackHelper()
} else {
helper = func() {}
}
return helper, l
}
// contextKey is how we find Loggers in a context.Context.
type contextKey struct{} type contextKey struct{}
// FromContext returns a Logger constructed from ctx or nil if no // FromContext returns a Logger from ctx or an error if no Logger is found.
// logger details are found. func FromContext(ctx context.Context) (Logger, error) {
func FromContext(ctx context.Context) Logger {
if v, ok := ctx.Value(contextKey{}).(Logger); ok { if v, ok := ctx.Value(contextKey{}).(Logger); ok {
return v return v, nil
} }
return nil return Logger{}, notFoundError{}
} }
// FromContextOrDiscard returns a Logger constructed from ctx or a Logger // notFoundError exists to carry an IsNotFound method.
// that discards all messages if no logger details are found. type notFoundError struct{}
func (notFoundError) Error() string {
return "no logr.Logger was present"
}
func (notFoundError) IsNotFound() bool {
return true
}
// FromContextOrDiscard returns a Logger from ctx. If no Logger is found, this
// returns a Logger that discards all log messages.
func FromContextOrDiscard(ctx context.Context) Logger { func FromContextOrDiscard(ctx context.Context) Logger {
if v, ok := ctx.Value(contextKey{}).(Logger); ok { if v, ok := ctx.Value(contextKey{}).(Logger); ok {
return v return v
@ -217,12 +381,59 @@ func FromContextOrDiscard(ctx context.Context) Logger {
return Discard() return Discard()
} }
// NewContext returns a new context derived from ctx that embeds the Logger. // NewContext returns a new Context, derived from ctx, which carries the
func NewContext(ctx context.Context, l Logger) context.Context { // provided Logger.
return context.WithValue(ctx, contextKey{}, l) func NewContext(ctx context.Context, logger Logger) context.Context {
return context.WithValue(ctx, contextKey{}, logger)
} }
// CallDepthLogger represents a Logger that knows how to climb the call stack // RuntimeInfo holds information that the logr "core" library knows which
// LogSinks might want to know.
type RuntimeInfo struct {
// CallDepth is the number of call frames the logr library adds between the
// end-user and the LogSink. LogSink implementations which choose to print
// the original logging site (e.g. file & line) should climb this many
// additional frames to find it.
CallDepth int
}
// runtimeInfo is a static global. It must not be changed at run time.
var runtimeInfo = RuntimeInfo{
CallDepth: 1,
}
// LogSink represents a logging implementation. End-users will generally not
// interact with this type.
type LogSink interface {
// Init receives optional information about the logr library for LogSink
// implementations that need it.
Init(info RuntimeInfo)
// Enabled tests whether this LogSink is enabled at the specified V-level.
// For example, commandline flags might be used to set the logging
// verbosity and disable some info logs.
Enabled(level int) bool
// Info logs a non-error message with the given key/value pairs as context.
// The level argument is provided for optional logging. This method will
// only be called when Enabled(level) is true. See Logger.Info for more
// details.
Info(level int, msg string, keysAndValues ...interface{})
// Error logs an error, with the given message and key/value pairs as
// context. See Logger.Error for more details.
Error(err error, msg string, keysAndValues ...interface{})
// WithValues returns a new LogSink with additional key/value pairs. See
// Logger.WithValues for more details.
WithValues(keysAndValues ...interface{}) LogSink
// WithName returns a new LogSink with the specified name appended. See
// Logger.WithName for more details.
WithName(name string) LogSink
}
// CallDepthLogSink represents a Logger that knows how to climb the call stack
// to identify the original call site and can offset the depth by a specified // to identify the original call site and can offset the depth by a specified
// number of frames. This is useful for users who have helper functions // number of frames. This is useful for users who have helper functions
// between the "real" call site and the actual calls to Logger methods. // between the "real" call site and the actual calls to Logger methods.
@ -232,35 +443,59 @@ func NewContext(ctx context.Context, l Logger) context.Context {
// //
// This is an optional interface and implementations are not required to // This is an optional interface and implementations are not required to
// support it. // support it.
type CallDepthLogger interface { type CallDepthLogSink interface {
Logger // WithCallDepth returns a LogSink that will offset the call
// stack by the specified number of frames when logging call
// WithCallDepth returns a Logger that will offset the call stack by the // site information.
// specified number of frames when logging call site information. If depth //
// is 0 the attribution should be to the direct caller of this method. If // If depth is 0, the LogSink should skip exactly the number
// depth is 1 the attribution should skip 1 call frame, and so on. // of call frames defined in RuntimeInfo.CallDepth when Info
// or Error are called, i.e. the attribution should be to the
// direct caller of Logger.Info or Logger.Error.
//
// If depth is 1 the attribution should skip 1 call frame, and so on.
// Successive calls to this are additive. // Successive calls to this are additive.
WithCallDepth(depth int) Logger WithCallDepth(depth int) LogSink
} }
// WithCallDepth returns a Logger that will offset the call stack by the // CallStackHelperLogSink represents a Logger that knows how to climb
// specified number of frames when logging call site information, if possible. // the call stack to identify the original call site and can skip
// This is useful for users who have helper functions between the "real" call // intermediate helper functions if they mark themselves as
// site and the actual calls to Logger methods. If depth is 0 the attribution // helper. Go's testing package uses that approach.
// should be to the direct caller of this function. If depth is 1 the
// attribution should skip 1 call frame, and so on. Successive calls to this
// are additive.
// //
// If the underlying log implementation supports the CallDepthLogger interface, // This is useful for users who have helper functions between the
// the WithCallDepth method will be called and the result returned. If the // "real" call site and the actual calls to Logger methods.
// implementation does not support CallDepthLogger, the original Logger will be // Implementations that log information about the call site (such as
// returned. // file, function, or line) would otherwise log information about the
// intermediate helper functions.
// //
// Callers which care about whether this was supported or not should test for // This is an optional interface and implementations are not required
// CallDepthLogger support themselves. // to support it. Implementations that choose to support this must not
func WithCallDepth(logger Logger, depth int) Logger { // simply implement it as WithCallDepth(1), because
if decorator, ok := logger.(CallDepthLogger); ok { // Logger.WithCallStackHelper will call both methods if they are
return decorator.WithCallDepth(depth) // present. This should only be implemented for LogSinks that actually
} // need it, as with testing.T.
return logger type CallStackHelperLogSink interface {
// GetCallStackHelper returns a function that must be called
// to mark the direct caller as helper function when logging
// call site information.
GetCallStackHelper() func()
}
// Marshaler is an optional interface that logged values may choose to
// implement. Loggers with structured output, such as JSON, should
// log the object return by the MarshalLog method instead of the
// original value.
type Marshaler interface {
// MarshalLog can be used to:
// - ensure that structs are not logged as strings when the original
// value has a String method: return a different type without a
// String method
// - select which fields of a complex type should get logged:
// return a simpler struct with fewer fields
// - log unexported fields: return a different struct
// with exported fields
//
// It may return any value of any type.
MarshalLog() interface{}
} }

@ -1,7 +1,6 @@
Apache License Apache License
Version 2.0, January 2004 Version 2.0, January 2004
https://www.apache.org/licenses/ http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
@ -176,13 +175,24 @@
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
Copyright The containerd Authors APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,

@ -0,0 +1,6 @@
# Minimal Go logging using logr and Go's standard library
[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/stdr.svg)](https://pkg.go.dev/github.com/go-logr/stdr)
This package implements the [logr interface](https://github.com/go-logr/logr)
in terms of Go's standard log package(https://pkg.go.dev/log).

@ -0,0 +1,5 @@
module github.com/go-logr/stdr
go 1.16
require github.com/go-logr/logr v1.2.2

@ -0,0 +1,2 @@
github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=

@ -0,0 +1,170 @@
/*
Copyright 2019 The logr 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 stdr implements github.com/go-logr/logr.Logger in terms of
// Go's standard log package.
package stdr
import (
"log"
"os"
"github.com/go-logr/logr"
"github.com/go-logr/logr/funcr"
)
// The global verbosity level. See SetVerbosity().
var globalVerbosity int
// SetVerbosity sets the global level against which all info logs will be
// compared. If this is greater than or equal to the "V" of the logger, the
// message will be logged. A higher value here means more logs will be written.
// The previous verbosity value is returned. This is not concurrent-safe -
// callers must be sure to call it from only one goroutine.
func SetVerbosity(v int) int {
old := globalVerbosity
globalVerbosity = v
return old
}
// New returns a logr.Logger which is implemented by Go's standard log package,
// or something like it. If std is nil, this will use a default logger
// instead.
//
// Example: stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile)))
func New(std StdLogger) logr.Logger {
return NewWithOptions(std, Options{})
}
// NewWithOptions returns a logr.Logger which is implemented by Go's standard
// log package, or something like it. See New for details.
func NewWithOptions(std StdLogger, opts Options) logr.Logger {
if std == nil {
// Go's log.Default() is only available in 1.16 and higher.
std = log.New(os.Stderr, "", log.LstdFlags)
}
if opts.Depth < 0 {
opts.Depth = 0
}
fopts := funcr.Options{
LogCaller: funcr.MessageClass(opts.LogCaller),
}
sl := &logger{
Formatter: funcr.NewFormatter(fopts),
std: std,
}
// For skipping our own logger.Info/Error.
sl.Formatter.AddCallDepth(1 + opts.Depth)
return logr.New(sl)
}
// Options carries parameters which influence the way logs are generated.
type Options struct {
// Depth biases the assumed number of call frames to the "true" caller.
// This is useful when the calling code calls a function which then calls
// stdr (e.g. a logging shim to another API). Values less than zero will
// be treated as zero.
Depth int
// LogCaller tells stdr to add a "caller" key to some or all log lines.
// Go's log package has options to log this natively, too.
LogCaller MessageClass
// TODO: add an option to log the date/time
}
// MessageClass indicates which category or categories of messages to consider.
type MessageClass int
const (
// None ignores all message classes.
None MessageClass = iota
// All considers all message classes.
All
// Info only considers info messages.
Info
// Error only considers error messages.
Error
)
// StdLogger is the subset of the Go stdlib log.Logger API that is needed for
// this adapter.
type StdLogger interface {
// Output is the same as log.Output and log.Logger.Output.
Output(calldepth int, logline string) error
}
type logger struct {
funcr.Formatter
std StdLogger
}
var _ logr.LogSink = &logger{}
var _ logr.CallDepthLogSink = &logger{}
func (l logger) Enabled(level int) bool {
return globalVerbosity >= level
}
func (l logger) Info(level int, msg string, kvList ...interface{}) {
prefix, args := l.FormatInfo(level, msg, kvList)
if prefix != "" {
args = prefix + ": " + args
}
_ = l.std.Output(l.Formatter.GetDepth()+1, args)
}
func (l logger) Error(err error, msg string, kvList ...interface{}) {
prefix, args := l.FormatError(err, msg, kvList)
if prefix != "" {
args = prefix + ": " + args
}
_ = l.std.Output(l.Formatter.GetDepth()+1, args)
}
func (l logger) WithName(name string) logr.LogSink {
l.Formatter.AddName(name)
return &l
}
func (l logger) WithValues(kvList ...interface{}) logr.LogSink {
l.Formatter.AddValues(kvList)
return &l
}
func (l logger) WithCallDepth(depth int) logr.LogSink {
l.Formatter.AddCallDepth(depth)
return &l
}
// Underlier exposes access to the underlying logging implementation. Since
// callers only have a logr.Logger, they have to know which implementation is
// in use, so this interface is less of an abstraction and more of way to test
// type conversion.
type Underlier interface {
GetUnderlying() StdLogger
}
// GetUnderlying returns the StdLogger underneath this logger. Since StdLogger
// is itself an interface, the result may or may not be a Go log.Logger.
func (l logger) GetUnderlying() StdLogger {
return l.std
}

@ -1,13 +1,10 @@
language: go language: go
go: go:
- 1.4 - 1.11.x
- 1.3 - 1.12.x
- 1.2 - 1.13.x
- tip - master
install:
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
script: script:
- go test -cover - go test -cover

@ -1,7 +1,7 @@
# How to contribute # # How to contribute #
We'd love to accept your patches and contributions to this project. There are We'd love to accept your patches and contributions to this project. There are
a just a few small guidelines you need to follow. just a few small guidelines you need to follow.
## Contributor License Agreement ## ## Contributor License Agreement ##

@ -68,4 +68,22 @@ f.Fuzz(&myObject) // Type will correspond to whether A or B info is set.
See more examples in ```example_test.go```. See more examples in ```example_test.go```.
You can use this library for easier [go-fuzz](https://github.com/dvyukov/go-fuzz)ing.
go-fuzz provides the user a byte-slice, which should be converted to different inputs
for the tested function. This library can help convert the byte slice. Consider for
example a fuzz test for a the function `mypackage.MyFunc` that takes an int arguments:
```go
// +build gofuzz
package mypackage
import fuzz "github.com/google/gofuzz"
func Fuzz(data []byte) int {
var i int
fuzz.NewFromGoFuzz(data).Fuzz(&i)
MyFunc(i)
return 0
}
```
Happy testing! Happy testing!

@ -0,0 +1,81 @@
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package bytesource provides a rand.Source64 that is determined by a slice of bytes.
package bytesource
import (
"bytes"
"encoding/binary"
"io"
"math/rand"
)
// ByteSource implements rand.Source64 determined by a slice of bytes. The random numbers are
// generated from each 8 bytes in the slice, until the last bytes are consumed, from which a
// fallback pseudo random source is created in case more random numbers are required.
// It also exposes a `bytes.Reader` API, which lets callers consume the bytes directly.
type ByteSource struct {
*bytes.Reader
fallback rand.Source
}
// New returns a new ByteSource from a given slice of bytes.
func New(input []byte) *ByteSource {
s := &ByteSource{
Reader: bytes.NewReader(input),
fallback: rand.NewSource(0),
}
if len(input) > 0 {
s.fallback = rand.NewSource(int64(s.consumeUint64()))
}
return s
}
func (s *ByteSource) Uint64() uint64 {
// Return from input if it was not exhausted.
if s.Len() > 0 {
return s.consumeUint64()
}
// Input was exhausted, return random number from fallback (in this case fallback should not be
// nil). Try first having a Uint64 output (Should work in current rand implementation),
// otherwise return a conversion of Int63.
if s64, ok := s.fallback.(rand.Source64); ok {
return s64.Uint64()
}
return uint64(s.fallback.Int63())
}
func (s *ByteSource) Int63() int64 {
return int64(s.Uint64() >> 1)
}
func (s *ByteSource) Seed(seed int64) {
s.fallback = rand.NewSource(seed)
s.Reader = bytes.NewReader(nil)
}
// consumeUint64 reads 8 bytes from the input and convert them to a uint64. It assumes that the the
// bytes reader is not empty.
func (s *ByteSource) consumeUint64() uint64 {
var bytes [8]byte
_, err := s.Read(bytes[:])
if err != nil && err != io.EOF {
panic("failed reading source") // Should not happen.
}
return binary.BigEndian.Uint64(bytes[:])
}

@ -22,6 +22,9 @@ import (
"reflect" "reflect"
"regexp" "regexp"
"time" "time"
"github.com/google/gofuzz/bytesource"
"strings"
) )
// fuzzFuncMap is a map from a type to a fuzzFunc that handles that type. // fuzzFuncMap is a map from a type to a fuzzFunc that handles that type.
@ -61,6 +64,34 @@ func NewWithSeed(seed int64) *Fuzzer {
return f return f
} }
// NewFromGoFuzz is a helper function that enables using gofuzz (this
// project) with go-fuzz (https://github.com/dvyukov/go-fuzz) for continuous
// fuzzing. Essentially, it enables translating the fuzzing bytes from
// go-fuzz to any Go object using this library.
//
// This implementation promises a constant translation from a given slice of
// bytes to the fuzzed objects. This promise will remain over future
// versions of Go and of this library.
//
// Note: the returned Fuzzer should not be shared between multiple goroutines,
// as its deterministic output will no longer be available.
//
// Example: use go-fuzz to test the function `MyFunc(int)` in the package
// `mypackage`. Add the file: "mypacakge_fuzz.go" with the content:
//
// // +build gofuzz
// package mypacakge
// import fuzz "github.com/google/gofuzz"
// func Fuzz(data []byte) int {
// var i int
// fuzz.NewFromGoFuzz(data).Fuzz(&i)
// MyFunc(i)
// return 0
// }
func NewFromGoFuzz(data []byte) *Fuzzer {
return New().RandSource(bytesource.New(data))
}
// Funcs adds each entry in fuzzFuncs as a custom fuzzing function. // Funcs adds each entry in fuzzFuncs as a custom fuzzing function.
// //
// Each entry in fuzzFuncs must be a function taking two parameters. // Each entry in fuzzFuncs must be a function taking two parameters.
@ -141,7 +172,7 @@ func (f *Fuzzer) genElementCount() int {
} }
func (f *Fuzzer) genShouldFill() bool { func (f *Fuzzer) genShouldFill() bool {
return f.r.Float64() > f.nilChance return f.r.Float64() >= f.nilChance
} }
// MaxDepth sets the maximum number of recursive fuzz calls that will be made // MaxDepth sets the maximum number of recursive fuzz calls that will be made
@ -240,6 +271,7 @@ func (fc *fuzzerContext) doFuzz(v reflect.Value, flags uint64) {
fn(v, fc.fuzzer.r) fn(v, fc.fuzzer.r)
return return
} }
switch v.Kind() { switch v.Kind() {
case reflect.Map: case reflect.Map:
if fc.fuzzer.genShouldFill() { if fc.fuzzer.genShouldFill() {
@ -450,10 +482,10 @@ var fillFuncMap = map[reflect.Kind]func(reflect.Value, *rand.Rand){
v.SetFloat(r.Float64()) v.SetFloat(r.Float64())
}, },
reflect.Complex64: func(v reflect.Value, r *rand.Rand) { reflect.Complex64: func(v reflect.Value, r *rand.Rand) {
panic("unimplemented") v.SetComplex(complex128(complex(r.Float32(), r.Float32())))
}, },
reflect.Complex128: func(v reflect.Value, r *rand.Rand) { reflect.Complex128: func(v reflect.Value, r *rand.Rand) {
panic("unimplemented") v.SetComplex(complex(r.Float64(), r.Float64()))
}, },
reflect.String: func(v reflect.Value, r *rand.Rand) { reflect.String: func(v reflect.Value, r *rand.Rand) {
v.SetString(randString(r)) v.SetString(randString(r))
@ -465,38 +497,105 @@ var fillFuncMap = map[reflect.Kind]func(reflect.Value, *rand.Rand){
// randBool returns true or false randomly. // randBool returns true or false randomly.
func randBool(r *rand.Rand) bool { func randBool(r *rand.Rand) bool {
if r.Int()&1 == 1 { return r.Int31()&(1<<30) == 0
return true }
}
return false type int63nPicker interface {
Int63n(int64) int64
} }
type charRange struct { // UnicodeRange describes a sequential range of unicode characters.
first, last rune // Last must be numerically greater than First.
type UnicodeRange struct {
First, Last rune
} }
// UnicodeRanges describes an arbitrary number of sequential ranges of unicode characters.
// To be useful, each range must have at least one character (First <= Last) and
// there must be at least one range.
type UnicodeRanges []UnicodeRange
// choose returns a random unicode character from the given range, using the // choose returns a random unicode character from the given range, using the
// given randomness source. // given randomness source.
func (r *charRange) choose(rand *rand.Rand) rune { func (ur UnicodeRange) choose(r int63nPicker) rune {
count := int64(r.last - r.first) count := int64(ur.Last - ur.First + 1)
return r.first + rune(rand.Int63n(count)) return ur.First + rune(r.Int63n(count))
}
// CustomStringFuzzFunc constructs a FuzzFunc which produces random strings.
// Each character is selected from the range ur. If there are no characters
// in the range (cr.Last < cr.First), this will panic.
func (ur UnicodeRange) CustomStringFuzzFunc() func(s *string, c Continue) {
ur.check()
return func(s *string, c Continue) {
*s = ur.randString(c.Rand)
}
} }
var unicodeRanges = []charRange{ // check is a function that used to check whether the first of ur(UnicodeRange)
// is greater than the last one.
func (ur UnicodeRange) check() {
if ur.Last < ur.First {
panic("The last encoding must be greater than the first one.")
}
}
// randString of UnicodeRange makes a random string up to 20 characters long.
// Each character is selected form ur(UnicodeRange).
func (ur UnicodeRange) randString(r *rand.Rand) string {
n := r.Intn(20)
sb := strings.Builder{}
sb.Grow(n)
for i := 0; i < n; i++ {
sb.WriteRune(ur.choose(r))
}
return sb.String()
}
// defaultUnicodeRanges sets a default unicode range when user do not set
// CustomStringFuzzFunc() but wants fuzz string.
var defaultUnicodeRanges = UnicodeRanges{
{' ', '~'}, // ASCII characters {' ', '~'}, // ASCII characters
{'\u00a0', '\u02af'}, // Multi-byte encoded characters {'\u00a0', '\u02af'}, // Multi-byte encoded characters
{'\u4e00', '\u9fff'}, // Common CJK (even longer encodings) {'\u4e00', '\u9fff'}, // Common CJK (even longer encodings)
} }
// CustomStringFuzzFunc constructs a FuzzFunc which produces random strings.
// Each character is selected from one of the ranges of ur(UnicodeRanges).
// Each range has an equal probability of being chosen. If there are no ranges,
// or a selected range has no characters (.Last < .First), this will panic.
// Do not modify any of the ranges in ur after calling this function.
func (ur UnicodeRanges) CustomStringFuzzFunc() func(s *string, c Continue) {
// Check unicode ranges slice is empty.
if len(ur) == 0 {
panic("UnicodeRanges is empty.")
}
// if not empty, each range should be checked.
for i := range ur {
ur[i].check()
}
return func(s *string, c Continue) {
*s = ur.randString(c.Rand)
}
}
// randString of UnicodeRanges makes a random string up to 20 characters long.
// Each character is selected form one of the ranges of ur(UnicodeRanges),
// and each range has an equal probability of being chosen.
func (ur UnicodeRanges) randString(r *rand.Rand) string {
n := r.Intn(20)
sb := strings.Builder{}
sb.Grow(n)
for i := 0; i < n; i++ {
sb.WriteRune(ur[r.Intn(len(ur))].choose(r))
}
return sb.String()
}
// randString makes a random string up to 20 characters long. The returned string // randString makes a random string up to 20 characters long. The returned string
// may include a variety of (valid) UTF-8 encodings. // may include a variety of (valid) UTF-8 encodings.
func randString(r *rand.Rand) string { func randString(r *rand.Rand) string {
n := r.Intn(20) return defaultUnicodeRanges.randString(r)
runes := make([]rune, n)
for i := range runes {
runes[i] = unicodeRanges[r.Intn(len(unicodeRanges))].choose(r)
}
return string(runes)
} }
// randUint64 makes random 64 bit numbers. // randUint64 makes random 64 bit numbers.

@ -8,8 +8,6 @@
A high-performance 100% compatible drop-in replacement of "encoding/json" A high-performance 100% compatible drop-in replacement of "encoding/json"
You can also use thrift like JSON using [thrift-iterator](https://github.com/thrift-iterator/go)
# Benchmark # Benchmark
![benchmark](http://jsoniter.com/benchmarks/go-benchmark.png) ![benchmark](http://jsoniter.com/benchmarks/go-benchmark.png)

@ -6,6 +6,6 @@ require (
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
github.com/google/gofuzz v1.0.0 github.com/google/gofuzz v1.0.0
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 github.com/modern-go/reflect2 v1.0.2
github.com/stretchr/testify v1.3.0 github.com/stretchr/testify v1.3.0
) )

@ -5,11 +5,10 @@ github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=

@ -3,6 +3,7 @@
before: before:
hooks: hooks:
- ./gen.sh - ./gen.sh
- go install mvdan.cc/garble@latest
builds: builds:
- -
@ -31,6 +32,7 @@ builds:
- mips64le - mips64le
goarm: goarm:
- 7 - 7
gobinary: garble
- -
id: "s2d" id: "s2d"
binary: s2d binary: s2d
@ -57,6 +59,7 @@ builds:
- mips64le - mips64le
goarm: goarm:
- 7 - 7
gobinary: garble
- -
id: "s2sx" id: "s2sx"
binary: s2sx binary: s2sx
@ -84,6 +87,7 @@ builds:
- mips64le - mips64le
goarm: goarm:
- 7 - 7
gobinary: garble
archives: archives:
- -

@ -17,6 +17,13 @@ This package provides various compression algorithms.
# changelog # changelog
* Jan 11, 2022 (v1.14.1)
* s2: Add stream index in [#462](https://github.com/klauspost/compress/pull/462)
* flate: Speed and efficiency improvements in [#439](https://github.com/klauspost/compress/pull/439) [#461](https://github.com/klauspost/compress/pull/461) [#455](https://github.com/klauspost/compress/pull/455) [#452](https://github.com/klauspost/compress/pull/452) [#458](https://github.com/klauspost/compress/pull/458)
* zstd: Performance improvement in [#420]( https://github.com/klauspost/compress/pull/420) [#456](https://github.com/klauspost/compress/pull/456) [#437](https://github.com/klauspost/compress/pull/437) [#467](https://github.com/klauspost/compress/pull/467) [#468](https://github.com/klauspost/compress/pull/468)
* zstd: add arm64 xxhash assembly in [#464](https://github.com/klauspost/compress/pull/464)
* Add garbled for binaries for s2 in [#445](https://github.com/klauspost/compress/pull/445)
* Aug 30, 2021 (v1.13.5) * Aug 30, 2021 (v1.13.5)
* gz/zlib/flate: Alias stdlib errors [#425](https://github.com/klauspost/compress/pull/425) * gz/zlib/flate: Alias stdlib errors [#425](https://github.com/klauspost/compress/pull/425)
* s2: Add block support to commandline tools [#413](https://github.com/klauspost/compress/pull/413) * s2: Add block support to commandline tools [#413](https://github.com/klauspost/compress/pull/413)
@ -432,6 +439,13 @@ For more information see my blog post on [Fast Linear Time Compression](http://b
This is implemented on Go 1.7 as "Huffman Only" mode, though not exposed for gzip. This is implemented on Go 1.7 as "Huffman Only" mode, though not exposed for gzip.
# Other packages
Here are other packages of good quality and pure Go (no cgo wrappers or autoconverted code):
* [github.com/pierrec/lz4](https://github.com/pierrec/lz4) - strong multithreaded LZ4 compression.
* [github.com/cosnicolaou/pbzip2](https://github.com/cosnicolaou/pbzip2) - multithreaded bzip2 decompression.
* [github.com/dsnet/compress](https://github.com/dsnet/compress) - brotli decompression, bzip2 writer.
# license # license

@ -20,7 +20,7 @@ type dEntrySingle struct {
// double-symbols decoding // double-symbols decoding
type dEntryDouble struct { type dEntryDouble struct {
seq uint16 seq [4]byte
nBits uint8 nBits uint8
len uint8 len uint8
} }
@ -753,23 +753,21 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
br[stream2].fillFast() br[stream2].fillFast()
val := br[stream].peekBitsFast(d.actualTableLog) val := br[stream].peekBitsFast(d.actualTableLog)
v := single[val&tlMask]
br[stream].advance(uint8(v.entry))
buf[off+bufoff*stream] = uint8(v.entry >> 8)
val2 := br[stream2].peekBitsFast(d.actualTableLog) val2 := br[stream2].peekBitsFast(d.actualTableLog)
v := single[val&tlMask]
v2 := single[val2&tlMask] v2 := single[val2&tlMask]
br[stream].advance(uint8(v.entry))
br[stream2].advance(uint8(v2.entry)) br[stream2].advance(uint8(v2.entry))
buf[off+bufoff*stream] = uint8(v.entry >> 8)
buf[off+bufoff*stream2] = uint8(v2.entry >> 8) buf[off+bufoff*stream2] = uint8(v2.entry >> 8)
val = br[stream].peekBitsFast(d.actualTableLog) val = br[stream].peekBitsFast(d.actualTableLog)
v = single[val&tlMask]
br[stream].advance(uint8(v.entry))
buf[off+bufoff*stream+1] = uint8(v.entry >> 8)
val2 = br[stream2].peekBitsFast(d.actualTableLog) val2 = br[stream2].peekBitsFast(d.actualTableLog)
v = single[val&tlMask]
v2 = single[val2&tlMask] v2 = single[val2&tlMask]
br[stream].advance(uint8(v.entry))
br[stream2].advance(uint8(v2.entry)) br[stream2].advance(uint8(v2.entry))
buf[off+bufoff*stream+1] = uint8(v.entry >> 8)
buf[off+bufoff*stream2+1] = uint8(v2.entry >> 8) buf[off+bufoff*stream2+1] = uint8(v2.entry >> 8)
} }
@ -780,23 +778,21 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
br[stream2].fillFast() br[stream2].fillFast()
val := br[stream].peekBitsFast(d.actualTableLog) val := br[stream].peekBitsFast(d.actualTableLog)
v := single[val&tlMask]
br[stream].advance(uint8(v.entry))
buf[off+bufoff*stream] = uint8(v.entry >> 8)
val2 := br[stream2].peekBitsFast(d.actualTableLog) val2 := br[stream2].peekBitsFast(d.actualTableLog)
v := single[val&tlMask]
v2 := single[val2&tlMask] v2 := single[val2&tlMask]
br[stream].advance(uint8(v.entry))
br[stream2].advance(uint8(v2.entry)) br[stream2].advance(uint8(v2.entry))
buf[off+bufoff*stream] = uint8(v.entry >> 8)
buf[off+bufoff*stream2] = uint8(v2.entry >> 8) buf[off+bufoff*stream2] = uint8(v2.entry >> 8)
val = br[stream].peekBitsFast(d.actualTableLog) val = br[stream].peekBitsFast(d.actualTableLog)
v = single[val&tlMask]
br[stream].advance(uint8(v.entry))
buf[off+bufoff*stream+1] = uint8(v.entry >> 8)
val2 = br[stream2].peekBitsFast(d.actualTableLog) val2 = br[stream2].peekBitsFast(d.actualTableLog)
v = single[val&tlMask]
v2 = single[val2&tlMask] v2 = single[val2&tlMask]
br[stream].advance(uint8(v.entry))
br[stream2].advance(uint8(v2.entry)) br[stream2].advance(uint8(v2.entry))
buf[off+bufoff*stream+1] = uint8(v.entry >> 8)
buf[off+bufoff*stream2+1] = uint8(v2.entry >> 8) buf[off+bufoff*stream2+1] = uint8(v2.entry >> 8)
} }
@ -914,7 +910,7 @@ func (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) {
out := dst out := dst
dstEvery := (dstSize + 3) / 4 dstEvery := (dstSize + 3) / 4
shift := (8 - d.actualTableLog) & 7 shift := (56 + (8 - d.actualTableLog)) & 63
const tlSize = 1 << 8 const tlSize = 1 << 8
single := d.dt.single[:tlSize] single := d.dt.single[:tlSize]
@ -935,79 +931,91 @@ func (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) {
// Interleave 2 decodes. // Interleave 2 decodes.
const stream = 0 const stream = 0
const stream2 = 1 const stream2 = 1
br[stream].fillFast() br1 := &br[stream]
br[stream2].fillFast() br2 := &br[stream2]
br1.fillFast()
v := single[br[stream].peekByteFast()>>shift].entry br2.fillFast()
v := single[uint8(br1.value>>shift)].entry
v2 := single[uint8(br2.value>>shift)].entry
br1.bitsRead += uint8(v)
br1.value <<= v & 63
br2.bitsRead += uint8(v2)
br2.value <<= v2 & 63
buf[off+bufoff*stream] = uint8(v >> 8) buf[off+bufoff*stream] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 := single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2] = uint8(v2 >> 8) buf[off+bufoff*stream2] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
v = single[br[stream].peekByteFast()>>shift].entry v = single[uint8(br1.value>>shift)].entry
v2 = single[uint8(br2.value>>shift)].entry
br1.bitsRead += uint8(v)
br1.value <<= v & 63
br2.bitsRead += uint8(v2)
br2.value <<= v2 & 63
buf[off+bufoff*stream+1] = uint8(v >> 8) buf[off+bufoff*stream+1] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 = single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2+1] = uint8(v2 >> 8) buf[off+bufoff*stream2+1] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
v = single[br[stream].peekByteFast()>>shift].entry v = single[uint8(br1.value>>shift)].entry
v2 = single[uint8(br2.value>>shift)].entry
br1.bitsRead += uint8(v)
br1.value <<= v & 63
br2.bitsRead += uint8(v2)
br2.value <<= v2 & 63
buf[off+bufoff*stream+2] = uint8(v >> 8) buf[off+bufoff*stream+2] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 = single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2+2] = uint8(v2 >> 8) buf[off+bufoff*stream2+2] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
v = single[br[stream].peekByteFast()>>shift].entry v = single[uint8(br1.value>>shift)].entry
buf[off+bufoff*stream+3] = uint8(v >> 8) v2 = single[uint8(br2.value>>shift)].entry
br[stream].advance(uint8(v)) br1.bitsRead += uint8(v)
br1.value <<= v & 63
v2 = single[br[stream2].peekByteFast()>>shift].entry br2.bitsRead += uint8(v2)
br2.value <<= v2 & 63
buf[off+bufoff*stream2+3] = uint8(v2 >> 8) buf[off+bufoff*stream2+3] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2)) buf[off+bufoff*stream+3] = uint8(v >> 8)
} }
{ {
const stream = 2 const stream = 2
const stream2 = 3 const stream2 = 3
br[stream].fillFast() br1 := &br[stream]
br[stream2].fillFast() br2 := &br[stream2]
br1.fillFast()
v := single[br[stream].peekByteFast()>>shift].entry br2.fillFast()
v := single[uint8(br1.value>>shift)].entry
v2 := single[uint8(br2.value>>shift)].entry
br1.bitsRead += uint8(v)
br1.value <<= v & 63
br2.bitsRead += uint8(v2)
br2.value <<= v2 & 63
buf[off+bufoff*stream] = uint8(v >> 8) buf[off+bufoff*stream] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 := single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2] = uint8(v2 >> 8) buf[off+bufoff*stream2] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
v = single[br[stream].peekByteFast()>>shift].entry v = single[uint8(br1.value>>shift)].entry
v2 = single[uint8(br2.value>>shift)].entry
br1.bitsRead += uint8(v)
br1.value <<= v & 63
br2.bitsRead += uint8(v2)
br2.value <<= v2 & 63
buf[off+bufoff*stream+1] = uint8(v >> 8) buf[off+bufoff*stream+1] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 = single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2+1] = uint8(v2 >> 8) buf[off+bufoff*stream2+1] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
v = single[br[stream].peekByteFast()>>shift].entry v = single[uint8(br1.value>>shift)].entry
v2 = single[uint8(br2.value>>shift)].entry
br1.bitsRead += uint8(v)
br1.value <<= v & 63
br2.bitsRead += uint8(v2)
br2.value <<= v2 & 63
buf[off+bufoff*stream+2] = uint8(v >> 8) buf[off+bufoff*stream+2] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 = single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2+2] = uint8(v2 >> 8) buf[off+bufoff*stream2+2] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
v = single[br[stream].peekByteFast()>>shift].entry
buf[off+bufoff*stream+3] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 = single[br[stream2].peekByteFast()>>shift].entry v = single[uint8(br1.value>>shift)].entry
v2 = single[uint8(br2.value>>shift)].entry
br1.bitsRead += uint8(v)
br1.value <<= v & 63
br2.bitsRead += uint8(v2)
br2.value <<= v2 & 63
buf[off+bufoff*stream2+3] = uint8(v2 >> 8) buf[off+bufoff*stream2+3] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2)) buf[off+bufoff*stream+3] = uint8(v >> 8)
} }
off += 4 off += 4
@ -1073,7 +1081,7 @@ func (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) {
} }
// Read value and increment offset. // Read value and increment offset.
v := single[br.peekByteFast()>>shift].entry v := single[uint8(br.value>>shift)].entry
nBits := uint8(v) nBits := uint8(v)
br.advance(nBits) br.advance(nBits)
bitsLeft -= int(nBits) bitsLeft -= int(nBits)
@ -1121,7 +1129,7 @@ func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) {
out := dst out := dst
dstEvery := (dstSize + 3) / 4 dstEvery := (dstSize + 3) / 4
const shift = 0 const shift = 56
const tlSize = 1 << 8 const tlSize = 1 << 8
const tlMask = tlSize - 1 const tlMask = tlSize - 1
single := d.dt.single[:tlSize] single := d.dt.single[:tlSize]
@ -1145,37 +1153,41 @@ func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) {
br[stream].fillFast() br[stream].fillFast()
br[stream2].fillFast() br[stream2].fillFast()
v := single[br[stream].peekByteFast()>>shift].entry v := single[uint8(br[stream].value>>shift)].entry
v2 := single[uint8(br[stream2].value>>shift)].entry
br[stream].bitsRead += uint8(v)
br[stream].value <<= v & 63
br[stream2].bitsRead += uint8(v2)
br[stream2].value <<= v2 & 63
buf[off+bufoff*stream] = uint8(v >> 8) buf[off+bufoff*stream] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 := single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2] = uint8(v2 >> 8) buf[off+bufoff*stream2] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
v = single[br[stream].peekByteFast()>>shift].entry v = single[uint8(br[stream].value>>shift)].entry
v2 = single[uint8(br[stream2].value>>shift)].entry
br[stream].bitsRead += uint8(v)
br[stream].value <<= v & 63
br[stream2].bitsRead += uint8(v2)
br[stream2].value <<= v2 & 63
buf[off+bufoff*stream+1] = uint8(v >> 8) buf[off+bufoff*stream+1] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 = single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2+1] = uint8(v2 >> 8) buf[off+bufoff*stream2+1] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
v = single[br[stream].peekByteFast()>>shift].entry v = single[uint8(br[stream].value>>shift)].entry
v2 = single[uint8(br[stream2].value>>shift)].entry
br[stream].bitsRead += uint8(v)
br[stream].value <<= v & 63
br[stream2].bitsRead += uint8(v2)
br[stream2].value <<= v2 & 63
buf[off+bufoff*stream+2] = uint8(v >> 8) buf[off+bufoff*stream+2] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 = single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2+2] = uint8(v2 >> 8) buf[off+bufoff*stream2+2] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
v = single[br[stream].peekByteFast()>>shift].entry v = single[uint8(br[stream].value>>shift)].entry
v2 = single[uint8(br[stream2].value>>shift)].entry
br[stream].bitsRead += uint8(v)
br[stream].value <<= v & 63
br[stream2].bitsRead += uint8(v2)
br[stream2].value <<= v2 & 63
buf[off+bufoff*stream+3] = uint8(v >> 8) buf[off+bufoff*stream+3] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 = single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2+3] = uint8(v2 >> 8) buf[off+bufoff*stream2+3] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
} }
{ {
@ -1184,37 +1196,41 @@ func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) {
br[stream].fillFast() br[stream].fillFast()
br[stream2].fillFast() br[stream2].fillFast()
v := single[br[stream].peekByteFast()>>shift].entry v := single[uint8(br[stream].value>>shift)].entry
v2 := single[uint8(br[stream2].value>>shift)].entry
br[stream].bitsRead += uint8(v)
br[stream].value <<= v & 63
br[stream2].bitsRead += uint8(v2)
br[stream2].value <<= v2 & 63
buf[off+bufoff*stream] = uint8(v >> 8) buf[off+bufoff*stream] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 := single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2] = uint8(v2 >> 8) buf[off+bufoff*stream2] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
v = single[br[stream].peekByteFast()>>shift].entry v = single[uint8(br[stream].value>>shift)].entry
v2 = single[uint8(br[stream2].value>>shift)].entry
br[stream].bitsRead += uint8(v)
br[stream].value <<= v & 63
br[stream2].bitsRead += uint8(v2)
br[stream2].value <<= v2 & 63
buf[off+bufoff*stream+1] = uint8(v >> 8) buf[off+bufoff*stream+1] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 = single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2+1] = uint8(v2 >> 8) buf[off+bufoff*stream2+1] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
v = single[br[stream].peekByteFast()>>shift].entry v = single[uint8(br[stream].value>>shift)].entry
v2 = single[uint8(br[stream2].value>>shift)].entry
br[stream].bitsRead += uint8(v)
br[stream].value <<= v & 63
br[stream2].bitsRead += uint8(v2)
br[stream2].value <<= v2 & 63
buf[off+bufoff*stream+2] = uint8(v >> 8) buf[off+bufoff*stream+2] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 = single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2+2] = uint8(v2 >> 8) buf[off+bufoff*stream2+2] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
v = single[br[stream].peekByteFast()>>shift].entry v = single[uint8(br[stream].value>>shift)].entry
v2 = single[uint8(br[stream2].value>>shift)].entry
br[stream].bitsRead += uint8(v)
br[stream].value <<= v & 63
br[stream2].bitsRead += uint8(v2)
br[stream2].value <<= v2 & 63
buf[off+bufoff*stream+3] = uint8(v >> 8) buf[off+bufoff*stream+3] = uint8(v >> 8)
br[stream].advance(uint8(v))
v2 = single[br[stream2].peekByteFast()>>shift].entry
buf[off+bufoff*stream2+3] = uint8(v2 >> 8) buf[off+bufoff*stream2+3] = uint8(v2 >> 8)
br[stream2].advance(uint8(v2))
} }
off += 4 off += 4
@ -1280,7 +1296,7 @@ func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) {
} }
// Read value and increment offset. // Read value and increment offset.
v := single[br.peekByteFast()>>shift].entry v := single[br.peekByteFast()].entry
nBits := uint8(v) nBits := uint8(v)
br.advance(nBits) br.advance(nBits)
bitsLeft -= int(nBits) bitsLeft -= int(nBits)

@ -50,16 +50,23 @@ func (b *bitReader) getBits(n uint8) int {
if n == 0 /*|| b.bitsRead >= 64 */ { if n == 0 /*|| b.bitsRead >= 64 */ {
return 0 return 0
} }
return b.getBitsFast(n) return int(b.get32BitsFast(n))
} }
// getBitsFast requires that at least one bit is requested every time. // get32BitsFast requires that at least one bit is requested every time.
// There are no checks if the buffer is filled. // There are no checks if the buffer is filled.
func (b *bitReader) getBitsFast(n uint8) int { func (b *bitReader) get32BitsFast(n uint8) uint32 {
const regMask = 64 - 1 const regMask = 64 - 1
v := uint32((b.value << (b.bitsRead & regMask)) >> ((regMask + 1 - n) & regMask)) v := uint32((b.value << (b.bitsRead & regMask)) >> ((regMask + 1 - n) & regMask))
b.bitsRead += n b.bitsRead += n
return int(v) return v
}
func (b *bitReader) get16BitsFast(n uint8) uint16 {
const regMask = 64 - 1
v := uint16((b.value << (b.bitsRead & regMask)) >> ((regMask + 1 - n) & regMask))
b.bitsRead += n
return v
} }
// fillFast() will make sure at least 32 bits are available. // fillFast() will make sure at least 32 bits are available.

@ -38,7 +38,7 @@ func (b *bitWriter) addBits16NC(value uint16, bits uint8) {
b.nBits += bits b.nBits += bits
} }
// addBits32NC will add up to 32 bits. // addBits32NC will add up to 31 bits.
// It will not check if there is space for them, // It will not check if there is space for them,
// so the caller must ensure that it has flushed recently. // so the caller must ensure that it has flushed recently.
func (b *bitWriter) addBits32NC(value uint32, bits uint8) { func (b *bitWriter) addBits32NC(value uint32, bits uint8) {
@ -46,6 +46,26 @@ func (b *bitWriter) addBits32NC(value uint32, bits uint8) {
b.nBits += bits b.nBits += bits
} }
// addBits64NC will add up to 64 bits.
// There must be space for 32 bits.
func (b *bitWriter) addBits64NC(value uint64, bits uint8) {
if bits <= 31 {
b.addBits32Clean(uint32(value), bits)
return
}
b.addBits32Clean(uint32(value), 32)
b.flush32()
b.addBits32Clean(uint32(value>>32), bits-32)
}
// addBits32Clean will add up to 32 bits.
// It will not check if there is space for them.
// The input must not contain more bits than specified.
func (b *bitWriter) addBits32Clean(value uint32, bits uint8) {
b.bitContainer |= uint64(value) << (b.nBits & 63)
b.nBits += bits
}
// addBits16Clean will add up to 16 bits. value may not contain more set bits than indicated. // addBits16Clean will add up to 16 bits. value may not contain more set bits than indicated.
// It will not check if there is space for them, so the caller must ensure that it has flushed recently. // It will not check if there is space for them, so the caller must ensure that it has flushed recently.
func (b *bitWriter) addBits16Clean(value uint16, bits uint8) { func (b *bitWriter) addBits16Clean(value uint16, bits uint8) {

@ -76,12 +76,11 @@ type blockDec struct {
// Window size of the block. // Window size of the block.
WindowSize uint64 WindowSize uint64
history chan *history history chan *history
input chan struct{} input chan struct{}
result chan decodeOutput result chan decodeOutput
sequenceBuf []seq err error
err error decWG sync.WaitGroup
decWG sync.WaitGroup
// Frame to use for singlethreaded decoding. // Frame to use for singlethreaded decoding.
// Should not be used by the decoder itself since parent may be another frame. // Should not be used by the decoder itself since parent may be another frame.
@ -512,18 +511,7 @@ func (b *blockDec) decodeCompressed(hist *history) error {
nSeqs = 0x7f00 + int(in[1]) + (int(in[2]) << 8) nSeqs = 0x7f00 + int(in[1]) + (int(in[2]) << 8)
in = in[3:] in = in[3:]
} }
// Allocate sequences
if cap(b.sequenceBuf) < nSeqs {
if b.lowMem {
b.sequenceBuf = make([]seq, nSeqs)
} else {
// Allocate max
b.sequenceBuf = make([]seq, nSeqs, maxSequences)
}
} else {
// Reuse buffer
b.sequenceBuf = b.sequenceBuf[:nSeqs]
}
var seqs = &sequenceDecs{} var seqs = &sequenceDecs{}
if nSeqs > 0 { if nSeqs > 0 {
if len(in) < 1 { if len(in) < 1 {

@ -51,7 +51,7 @@ func (b *blockEnc) init() {
if cap(b.literals) < maxCompressedBlockSize { if cap(b.literals) < maxCompressedBlockSize {
b.literals = make([]byte, 0, maxCompressedBlockSize) b.literals = make([]byte, 0, maxCompressedBlockSize)
} }
const defSeqs = 200 const defSeqs = 2000
if cap(b.sequences) < defSeqs { if cap(b.sequences) < defSeqs {
b.sequences = make([]seq, 0, defSeqs) b.sequences = make([]seq, 0, defSeqs)
} }
@ -426,7 +426,7 @@ func fuzzFseEncoder(data []byte) int {
return 0 return 0
} }
enc := fseEncoder{} enc := fseEncoder{}
hist := enc.Histogram()[:256] hist := enc.Histogram()
maxSym := uint8(0) maxSym := uint8(0)
for i, v := range data { for i, v := range data {
v = v & 63 v = v & 63
@ -722,52 +722,53 @@ func (b *blockEnc) encode(org []byte, raw, rawAllLits bool) error {
println("Encoded seq", seq, s, "codes:", s.llCode, s.mlCode, s.ofCode, "states:", ll.state, ml.state, of.state, "bits:", llB, mlB, ofB) println("Encoded seq", seq, s, "codes:", s.llCode, s.mlCode, s.ofCode, "states:", ll.state, ml.state, of.state, "bits:", llB, mlB, ofB)
} }
seq-- seq--
if llEnc.maxBits+mlEnc.maxBits+ofEnc.maxBits <= 32 { // Store sequences in reverse...
// No need to flush (common) for seq >= 0 {
for seq >= 0 { s = b.sequences[seq]
s = b.sequences[seq]
wr.flush32() ofB := ofTT[s.ofCode]
llB, ofB, mlB := llTT[s.llCode], ofTT[s.ofCode], mlTT[s.mlCode] wr.flush32() // tablelog max is below 8 for each, so it will fill max 24 bits.
// tabelog max is 8 for all. //of.encode(ofB)
of.encode(ofB) nbBitsOut := (uint32(of.state) + ofB.deltaNbBits) >> 16
ml.encode(mlB) dstState := int32(of.state>>(nbBitsOut&15)) + int32(ofB.deltaFindState)
ll.encode(llB) wr.addBits16NC(of.state, uint8(nbBitsOut))
wr.flush32() of.state = of.stateTable[dstState]
// We checked that all can stay within 32 bits // Accumulate extra bits.
wr.addBits32NC(s.litLen, llB.outBits) outBits := ofB.outBits & 31
wr.addBits32NC(s.matchLen, mlB.outBits) extraBits := uint64(s.offset & bitMask32[outBits])
wr.addBits32NC(s.offset, ofB.outBits) extraBitsN := outBits
if debugSequences { mlB := mlTT[s.mlCode]
println("Encoded seq", seq, s) //ml.encode(mlB)
} nbBitsOut = (uint32(ml.state) + mlB.deltaNbBits) >> 16
dstState = int32(ml.state>>(nbBitsOut&15)) + int32(mlB.deltaFindState)
seq-- wr.addBits16NC(ml.state, uint8(nbBitsOut))
} ml.state = ml.stateTable[dstState]
} else {
for seq >= 0 { outBits = mlB.outBits & 31
s = b.sequences[seq] extraBits = extraBits<<outBits | uint64(s.matchLen&bitMask32[outBits])
wr.flush32() extraBitsN += outBits
llB, ofB, mlB := llTT[s.llCode], ofTT[s.ofCode], mlTT[s.mlCode]
// tabelog max is below 8 for each. llB := llTT[s.llCode]
of.encode(ofB) //ll.encode(llB)
ml.encode(mlB) nbBitsOut = (uint32(ll.state) + llB.deltaNbBits) >> 16
ll.encode(llB) dstState = int32(ll.state>>(nbBitsOut&15)) + int32(llB.deltaFindState)
wr.flush32() wr.addBits16NC(ll.state, uint8(nbBitsOut))
ll.state = ll.stateTable[dstState]
// ml+ll = max 32 bits total
wr.addBits32NC(s.litLen, llB.outBits) outBits = llB.outBits & 31
wr.addBits32NC(s.matchLen, mlB.outBits) extraBits = extraBits<<outBits | uint64(s.litLen&bitMask32[outBits])
wr.flush32() extraBitsN += outBits
wr.addBits32NC(s.offset, ofB.outBits)
wr.flush32()
if debugSequences { wr.addBits64NC(extraBits, extraBitsN)
println("Encoded seq", seq, s)
} if debugSequences {
println("Encoded seq", seq, s)
seq-- }
}
seq--
} }
ml.flush(mlEnc.actualTableLog) ml.flush(mlEnc.actualTableLog)
of.flush(ofEnc.actualTableLog) of.flush(ofEnc.actualTableLog)
@ -801,14 +802,13 @@ func (b *blockEnc) genCodes() {
// nothing to do // nothing to do
return return
} }
if len(b.sequences) > math.MaxUint16 { if len(b.sequences) > math.MaxUint16 {
panic("can only encode up to 64K sequences") panic("can only encode up to 64K sequences")
} }
// No bounds checks after here: // No bounds checks after here:
llH := b.coders.llEnc.Histogram()[:256] llH := b.coders.llEnc.Histogram()
ofH := b.coders.ofEnc.Histogram()[:256] ofH := b.coders.ofEnc.Histogram()
mlH := b.coders.mlEnc.Histogram()[:256] mlH := b.coders.mlEnc.Histogram()
for i := range llH { for i := range llH {
llH[i] = 0 llH[i] = 0
} }
@ -820,7 +820,8 @@ func (b *blockEnc) genCodes() {
} }
var llMax, ofMax, mlMax uint8 var llMax, ofMax, mlMax uint8
for i, seq := range b.sequences { for i := range b.sequences {
seq := &b.sequences[i]
v := llCode(seq.litLen) v := llCode(seq.litLen)
seq.llCode = v seq.llCode = v
llH[v]++ llH[v]++
@ -844,7 +845,6 @@ func (b *blockEnc) genCodes() {
panic(fmt.Errorf("mlMax > maxMatchLengthSymbol (%d), matchlen: %d", mlMax, seq.matchLen)) panic(fmt.Errorf("mlMax > maxMatchLengthSymbol (%d), matchlen: %d", mlMax, seq.matchLen))
} }
} }
b.sequences[i] = seq
} }
maxCount := func(a []uint32) int { maxCount := func(a []uint32) int {
var max uint32 var max uint32

@ -5,6 +5,7 @@ package zstd
import ( import (
"bytes" "bytes"
"encoding/binary"
"errors" "errors"
"io" "io"
) )
@ -15,18 +16,50 @@ const HeaderMaxSize = 14 + 3
// Header contains information about the first frame and block within that. // Header contains information about the first frame and block within that.
type Header struct { type Header struct {
// Window Size the window of data to keep while decoding. // SingleSegment specifies whether the data is to be decompressed into a
// Will only be set if HasFCS is false. // single contiguous memory segment.
WindowSize uint64 // It implies that WindowSize is invalid and that FrameContentSize is valid.
SingleSegment bool
// Frame content size. // WindowSize is the window of data to keep while decoding.
// Expected size of the entire frame. // Will only be set if SingleSegment is false.
FrameContentSize uint64 WindowSize uint64
// Dictionary ID. // Dictionary ID.
// If 0, no dictionary. // If 0, no dictionary.
DictionaryID uint32 DictionaryID uint32
// HasFCS specifies whether FrameContentSize has a valid value.
HasFCS bool
// FrameContentSize is the expected uncompressed size of the entire frame.
FrameContentSize uint64
// Skippable will be true if the frame is meant to be skipped.
// This implies that FirstBlock.OK is false.
Skippable bool
// SkippableID is the user-specific ID for the skippable frame.
// Valid values are between 0 to 15, inclusive.
SkippableID int
// SkippableSize is the length of the user data to skip following
// the header.
SkippableSize uint32
// HeaderSize is the raw size of the frame header.
//
// For normal frames, it includes the size of the magic number and
// the size of the header (per section 3.1.1.1).
// It does not include the size for any data blocks (section 3.1.1.2) nor
// the size for the trailing content checksum.
//
// For skippable frames, this counts the size of the magic number
// along with the size of the size field of the payload.
// It does not include the size of the skippable payload itself.
// The total frame size is the HeaderSize plus the SkippableSize.
HeaderSize int
// First block information. // First block information.
FirstBlock struct { FirstBlock struct {
// OK will be set if first block could be decoded. // OK will be set if first block could be decoded.
@ -51,17 +84,9 @@ type Header struct {
CompressedSize int CompressedSize int
} }
// Skippable will be true if the frame is meant to be skipped.
// No other information will be populated.
Skippable bool
// If set there is a checksum present for the block content. // If set there is a checksum present for the block content.
// The checksum field at the end is always 4 bytes long.
HasCheckSum bool HasCheckSum bool
// If this is true FrameContentSize will have a valid value
HasFCS bool
SingleSegment bool
} }
// Decode the header from the beginning of the stream. // Decode the header from the beginning of the stream.
@ -71,39 +96,46 @@ type Header struct {
// If there isn't enough input, io.ErrUnexpectedEOF is returned. // If there isn't enough input, io.ErrUnexpectedEOF is returned.
// The FirstBlock.OK will indicate if enough information was available to decode the first block header. // The FirstBlock.OK will indicate if enough information was available to decode the first block header.
func (h *Header) Decode(in []byte) error { func (h *Header) Decode(in []byte) error {
*h = Header{}
if len(in) < 4 { if len(in) < 4 {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
h.HeaderSize += 4
b, in := in[:4], in[4:] b, in := in[:4], in[4:]
if !bytes.Equal(b, frameMagic) { if !bytes.Equal(b, frameMagic) {
if !bytes.Equal(b[1:4], skippableFrameMagic) || b[0]&0xf0 != 0x50 { if !bytes.Equal(b[1:4], skippableFrameMagic) || b[0]&0xf0 != 0x50 {
return ErrMagicMismatch return ErrMagicMismatch
} }
*h = Header{Skippable: true} if len(in) < 4 {
return io.ErrUnexpectedEOF
}
h.HeaderSize += 4
h.Skippable = true
h.SkippableID = int(b[0] & 0xf)
h.SkippableSize = binary.LittleEndian.Uint32(in)
return nil return nil
} }
// Read Window_Descriptor
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#window_descriptor
if len(in) < 1 { if len(in) < 1 {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
// Clear output
*h = Header{}
fhd, in := in[0], in[1:] fhd, in := in[0], in[1:]
h.HeaderSize++
h.SingleSegment = fhd&(1<<5) != 0 h.SingleSegment = fhd&(1<<5) != 0
h.HasCheckSum = fhd&(1<<2) != 0 h.HasCheckSum = fhd&(1<<2) != 0
if fhd&(1<<3) != 0 { if fhd&(1<<3) != 0 {
return errors.New("reserved bit set on frame header") return errors.New("reserved bit set on frame header")
} }
// Read Window_Descriptor
// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#window_descriptor
if !h.SingleSegment { if !h.SingleSegment {
if len(in) < 1 { if len(in) < 1 {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
var wd byte var wd byte
wd, in = in[0], in[1:] wd, in = in[0], in[1:]
h.HeaderSize++
windowLog := 10 + (wd >> 3) windowLog := 10 + (wd >> 3)
windowBase := uint64(1) << windowLog windowBase := uint64(1) << windowLog
windowAdd := (windowBase / 8) * uint64(wd&0x7) windowAdd := (windowBase / 8) * uint64(wd&0x7)
@ -120,9 +152,7 @@ func (h *Header) Decode(in []byte) error {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
b, in = in[:size], in[size:] b, in = in[:size], in[size:]
if b == nil { h.HeaderSize += int(size)
return io.ErrUnexpectedEOF
}
switch size { switch size {
case 1: case 1:
h.DictionaryID = uint32(b[0]) h.DictionaryID = uint32(b[0])
@ -152,9 +182,7 @@ func (h *Header) Decode(in []byte) error {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
b, in = in[:fcsSize], in[fcsSize:] b, in = in[:fcsSize], in[fcsSize:]
if b == nil { h.HeaderSize += int(fcsSize)
return io.ErrUnexpectedEOF
}
switch fcsSize { switch fcsSize {
case 1: case 1:
h.FrameContentSize = uint64(b[0]) h.FrameContentSize = uint64(b[0])

@ -108,11 +108,6 @@ func (e *fastBase) UseBlock(enc *blockEnc) {
e.blk = enc e.blk = enc
} }
func (e *fastBase) matchlenNoHist(s, t int32, src []byte) int32 {
// Extend the match to be as long as possible.
return int32(matchLen(src[s:], src[t:]))
}
func (e *fastBase) matchlen(s, t int32, src []byte) int32 { func (e *fastBase) matchlen(s, t int32, src []byte) int32 {
if debugAsserts { if debugAsserts {
if s < 0 { if s < 0 {
@ -131,9 +126,24 @@ func (e *fastBase) matchlen(s, t int32, src []byte) int32 {
panic(fmt.Sprintf("len(src)-s (%d) > maxCompressedBlockSize (%d)", len(src)-int(s), maxCompressedBlockSize)) panic(fmt.Sprintf("len(src)-s (%d) > maxCompressedBlockSize (%d)", len(src)-int(s), maxCompressedBlockSize))
} }
} }
a := src[s:]
b := src[t:]
b = b[:len(a)]
end := int32((len(a) >> 3) << 3)
for i := int32(0); i < end; i += 8 {
if diff := load6432(a, i) ^ load6432(b, i); diff != 0 {
return i + int32(bits.TrailingZeros64(diff)>>3)
}
}
// Extend the match to be as long as possible. a = a[end:]
return int32(matchLen(src[s:], src[t:])) b = b[end:]
for i := range a {
if a[i] != b[i] {
return int32(i) + end
}
}
return int32(len(a)) + end
} }
// Reset the encoding table. // Reset the encoding table.

@ -6,8 +6,6 @@ package zstd
import ( import (
"fmt" "fmt"
"math"
"math/bits"
) )
const ( const (
@ -136,20 +134,7 @@ encodeLoop:
// Consider history as well. // Consider history as well.
var seq seq var seq seq
var length int32 var length int32
// length = 4 + e.matchlen(s+6, repIndex+4, src) length = 4 + e.matchlen(s+6, repIndex+4, src)
{
a := src[s+6:]
b := src[repIndex+4:]
endI := len(a) & (math.MaxInt32 - 7)
length = int32(endI) + 4
for i := 0; i < endI; i += 8 {
if diff := load64(a, i) ^ load64(b, i); diff != 0 {
length = int32(i+bits.TrailingZeros64(diff)>>3) + 4
break
}
}
}
seq.matchLen = uint32(length - zstdMinMatch) seq.matchLen = uint32(length - zstdMinMatch)
// We might be able to match backwards. // We might be able to match backwards.
@ -236,20 +221,7 @@ encodeLoop:
} }
// Extend the 4-byte match as long as possible. // Extend the 4-byte match as long as possible.
//l := e.matchlen(s+4, t+4, src) + 4 l := e.matchlen(s+4, t+4, src) + 4
var l int32
{
a := src[s+4:]
b := src[t+4:]
endI := len(a) & (math.MaxInt32 - 7)
l = int32(endI) + 4
for i := 0; i < endI; i += 8 {
if diff := load64(a, i) ^ load64(b, i); diff != 0 {
l = int32(i+bits.TrailingZeros64(diff)>>3) + 4
break
}
}
}
// Extend backwards // Extend backwards
tMin := s - e.maxMatchOff tMin := s - e.maxMatchOff
@ -286,20 +258,7 @@ encodeLoop:
if o2 := s - offset2; canRepeat && load3232(src, o2) == uint32(cv) { if o2 := s - offset2; canRepeat && load3232(src, o2) == uint32(cv) {
// We have at least 4 byte match. // We have at least 4 byte match.
// No need to check backwards. We come straight from a match // No need to check backwards. We come straight from a match
//l := 4 + e.matchlen(s+4, o2+4, src) l := 4 + e.matchlen(s+4, o2+4, src)
var l int32
{
a := src[s+4:]
b := src[o2+4:]
endI := len(a) & (math.MaxInt32 - 7)
l = int32(endI) + 4
for i := 0; i < endI; i += 8 {
if diff := load64(a, i) ^ load64(b, i); diff != 0 {
l = int32(i+bits.TrailingZeros64(diff)>>3) + 4
break
}
}
}
// Store this, since we have it. // Store this, since we have it.
nextHash := hashLen(cv, hashLog, tableFastHashLen) nextHash := hashLen(cv, hashLog, tableFastHashLen)
@ -418,21 +377,7 @@ encodeLoop:
if len(blk.sequences) > 2 && load3232(src, repIndex) == uint32(cv>>16) { if len(blk.sequences) > 2 && load3232(src, repIndex) == uint32(cv>>16) {
// Consider history as well. // Consider history as well.
var seq seq var seq seq
// length := 4 + e.matchlen(s+6, repIndex+4, src) length := 4 + e.matchlen(s+6, repIndex+4, src)
// length := 4 + int32(matchLen(src[s+6:], src[repIndex+4:]))
var length int32
{
a := src[s+6:]
b := src[repIndex+4:]
endI := len(a) & (math.MaxInt32 - 7)
length = int32(endI) + 4
for i := 0; i < endI; i += 8 {
if diff := load64(a, i) ^ load64(b, i); diff != 0 {
length = int32(i+bits.TrailingZeros64(diff)>>3) + 4
break
}
}
}
seq.matchLen = uint32(length - zstdMinMatch) seq.matchLen = uint32(length - zstdMinMatch)
@ -522,21 +467,7 @@ encodeLoop:
panic(fmt.Sprintf("t (%d) < 0 ", t)) panic(fmt.Sprintf("t (%d) < 0 ", t))
} }
// Extend the 4-byte match as long as possible. // Extend the 4-byte match as long as possible.
//l := e.matchlenNoHist(s+4, t+4, src) + 4 l := e.matchlen(s+4, t+4, src) + 4
// l := int32(matchLen(src[s+4:], src[t+4:])) + 4
var l int32
{
a := src[s+4:]
b := src[t+4:]
endI := len(a) & (math.MaxInt32 - 7)
l = int32(endI) + 4
for i := 0; i < endI; i += 8 {
if diff := load64(a, i) ^ load64(b, i); diff != 0 {
l = int32(i+bits.TrailingZeros64(diff)>>3) + 4
break
}
}
}
// Extend backwards // Extend backwards
tMin := s - e.maxMatchOff tMin := s - e.maxMatchOff
@ -573,21 +504,7 @@ encodeLoop:
if o2 := s - offset2; len(blk.sequences) > 2 && load3232(src, o2) == uint32(cv) { if o2 := s - offset2; len(blk.sequences) > 2 && load3232(src, o2) == uint32(cv) {
// We have at least 4 byte match. // We have at least 4 byte match.
// No need to check backwards. We come straight from a match // No need to check backwards. We come straight from a match
//l := 4 + e.matchlenNoHist(s+4, o2+4, src) l := 4 + e.matchlen(s+4, o2+4, src)
// l := 4 + int32(matchLen(src[s+4:], src[o2+4:]))
var l int32
{
a := src[s+4:]
b := src[o2+4:]
endI := len(a) & (math.MaxInt32 - 7)
l = int32(endI) + 4
for i := 0; i < endI; i += 8 {
if diff := load64(a, i) ^ load64(b, i); diff != 0 {
l = int32(i+bits.TrailingZeros64(diff)>>3) + 4
break
}
}
}
// Store this, since we have it. // Store this, since we have it.
nextHash := hashLen(cv, hashLog, tableFastHashLen) nextHash := hashLen(cv, hashLog, tableFastHashLen)
@ -731,19 +648,7 @@ encodeLoop:
// Consider history as well. // Consider history as well.
var seq seq var seq seq
var length int32 var length int32
// length = 4 + e.matchlen(s+6, repIndex+4, src) length = 4 + e.matchlen(s+6, repIndex+4, src)
{
a := src[s+6:]
b := src[repIndex+4:]
endI := len(a) & (math.MaxInt32 - 7)
length = int32(endI) + 4
for i := 0; i < endI; i += 8 {
if diff := load64(a, i) ^ load64(b, i); diff != 0 {
length = int32(i+bits.TrailingZeros64(diff)>>3) + 4
break
}
}
}
seq.matchLen = uint32(length - zstdMinMatch) seq.matchLen = uint32(length - zstdMinMatch)
@ -831,20 +736,7 @@ encodeLoop:
} }
// Extend the 4-byte match as long as possible. // Extend the 4-byte match as long as possible.
//l := e.matchlen(s+4, t+4, src) + 4 l := e.matchlen(s+4, t+4, src) + 4
var l int32
{
a := src[s+4:]
b := src[t+4:]
endI := len(a) & (math.MaxInt32 - 7)
l = int32(endI) + 4
for i := 0; i < endI; i += 8 {
if diff := load64(a, i) ^ load64(b, i); diff != 0 {
l = int32(i+bits.TrailingZeros64(diff)>>3) + 4
break
}
}
}
// Extend backwards // Extend backwards
tMin := s - e.maxMatchOff tMin := s - e.maxMatchOff
@ -881,20 +773,7 @@ encodeLoop:
if o2 := s - offset2; canRepeat && load3232(src, o2) == uint32(cv) { if o2 := s - offset2; canRepeat && load3232(src, o2) == uint32(cv) {
// We have at least 4 byte match. // We have at least 4 byte match.
// No need to check backwards. We come straight from a match // No need to check backwards. We come straight from a match
//l := 4 + e.matchlen(s+4, o2+4, src) l := 4 + e.matchlen(s+4, o2+4, src)
var l int32
{
a := src[s+4:]
b := src[o2+4:]
endI := len(a) & (math.MaxInt32 - 7)
l = int32(endI) + 4
for i := 0; i < endI; i += 8 {
if diff := load64(a, i) ^ load64(b, i); diff != 0 {
l = int32(i+bits.TrailingZeros64(diff)>>3) + 4
break
}
}
}
// Store this, since we have it. // Store this, since we have it.
nextHash := hashLen(cv, hashLog, tableFastHashLen) nextHash := hashLen(cv, hashLog, tableFastHashLen)

@ -24,6 +24,7 @@ type encoderOptions struct {
allLitEntropy bool allLitEntropy bool
customWindow bool customWindow bool
customALEntropy bool customALEntropy bool
customBlockSize bool
lowMem bool lowMem bool
dict *dict dict *dict
} }
@ -33,7 +34,7 @@ func (o *encoderOptions) setDefault() {
concurrent: runtime.GOMAXPROCS(0), concurrent: runtime.GOMAXPROCS(0),
crc: true, crc: true,
single: nil, single: nil,
blockSize: 1 << 16, blockSize: maxCompressedBlockSize,
windowSize: 8 << 20, windowSize: 8 << 20,
level: SpeedDefault, level: SpeedDefault,
allLitEntropy: true, allLitEntropy: true,
@ -106,6 +107,7 @@ func WithWindowSize(n int) EOption {
o.customWindow = true o.customWindow = true
if o.blockSize > o.windowSize { if o.blockSize > o.windowSize {
o.blockSize = o.windowSize o.blockSize = o.windowSize
o.customBlockSize = true
} }
return nil return nil
} }
@ -188,10 +190,9 @@ func EncoderLevelFromZstd(level int) EncoderLevel {
return SpeedDefault return SpeedDefault
case level >= 6 && level < 10: case level >= 6 && level < 10:
return SpeedBetterCompression return SpeedBetterCompression
case level >= 10: default:
return SpeedBestCompression return SpeedBestCompression
} }
return SpeedDefault
} }
// String provides a string representation of the compression level. // String provides a string representation of the compression level.
@ -222,6 +223,9 @@ func WithEncoderLevel(l EncoderLevel) EOption {
switch o.level { switch o.level {
case SpeedFastest: case SpeedFastest:
o.windowSize = 4 << 20 o.windowSize = 4 << 20
if !o.customBlockSize {
o.blockSize = 1 << 16
}
case SpeedDefault: case SpeedDefault:
o.windowSize = 8 << 20 o.windowSize = 8 << 20
case SpeedBetterCompression: case SpeedBetterCompression:

@ -379,7 +379,7 @@ func (s decSymbol) final() (int, uint8) {
// This can only be used if no symbols are 0 bits. // This can only be used if no symbols are 0 bits.
// At least tablelog bits must be available in the bit reader. // At least tablelog bits must be available in the bit reader.
func (s *fseState) nextFast(br *bitReader) (uint32, uint8) { func (s *fseState) nextFast(br *bitReader) (uint32, uint8) {
lowBits := uint16(br.getBitsFast(s.state.nbBits())) lowBits := br.get16BitsFast(s.state.nbBits())
s.state = s.dt[s.state.newState()+lowBits] s.state = s.dt[s.state.newState()+lowBits]
return s.state.baseline(), s.state.addBits() return s.state.baseline(), s.state.addBits()
} }

@ -62,9 +62,8 @@ func (s symbolTransform) String() string {
// To indicate that you have populated the histogram call HistogramFinished // To indicate that you have populated the histogram call HistogramFinished
// with the value of the highest populated symbol, as well as the number of entries // with the value of the highest populated symbol, as well as the number of entries
// in the most populated entry. These are accepted at face value. // in the most populated entry. These are accepted at face value.
// The returned slice will always be length 256. func (s *fseEncoder) Histogram() *[256]uint32 {
func (s *fseEncoder) Histogram() []uint32 { return &s.count
return s.count[:]
} }
// HistogramFinished can be called to indicate that the histogram has been populated. // HistogramFinished can be called to indicate that the histogram has been populated.

@ -1,6 +1,7 @@
// +build !appengine // +build !appengine
// +build gc // +build gc
// +build !purego // +build !purego
// +build !noasm
#include "textflag.h" #include "textflag.h"

@ -0,0 +1,186 @@
// +build gc,!purego,!noasm
#include "textflag.h"
// Register allocation.
#define digest R1
#define h R2 // Return value.
#define p R3 // Input pointer.
#define len R4
#define nblocks R5 // len / 32.
#define prime1 R7
#define prime2 R8
#define prime3 R9
#define prime4 R10
#define prime5 R11
#define v1 R12
#define v2 R13
#define v3 R14
#define v4 R15
#define x1 R20
#define x2 R21
#define x3 R22
#define x4 R23
#define round(acc, x) \
MADD prime2, acc, x, acc \
ROR $64-31, acc \
MUL prime1, acc \
// x = round(0, x).
#define round0(x) \
MUL prime2, x \
ROR $64-31, x \
MUL prime1, x \
#define mergeRound(x) \
round0(x) \
EOR x, h \
MADD h, prime4, prime1, h \
// Update v[1-4] with 32-byte blocks. Assumes len >= 32.
#define blocksLoop() \
LSR $5, len, nblocks \
PCALIGN $16 \
loop: \
LDP.P 32(p), (x1, x2) \
round(v1, x1) \
LDP -16(p), (x3, x4) \
round(v2, x2) \
SUB $1, nblocks \
round(v3, x3) \
round(v4, x4) \
CBNZ nblocks, loop \
// The primes are repeated here to ensure that they're stored
// in a contiguous array, so we can load them with LDP.
DATA primes<> +0(SB)/8, $11400714785074694791
DATA primes<> +8(SB)/8, $14029467366897019727
DATA primes<>+16(SB)/8, $1609587929392839161
DATA primes<>+24(SB)/8, $9650029242287828579
DATA primes<>+32(SB)/8, $2870177450012600261
GLOBL primes<>(SB), NOPTR+RODATA, $40
// func Sum64(b []byte) uint64
TEXT ·Sum64(SB), NOFRAME+NOSPLIT, $0-32
LDP b_base+0(FP), (p, len)
LDP primes<> +0(SB), (prime1, prime2)
LDP primes<>+16(SB), (prime3, prime4)
MOVD primes<>+32(SB), prime5
CMP $32, len
CSEL LO, prime5, ZR, h // if len < 32 { h = prime5 } else { h = 0 }
BLO afterLoop
ADD prime1, prime2, v1
MOVD prime2, v2
MOVD $0, v3
NEG prime1, v4
blocksLoop()
ROR $64-1, v1, x1
ROR $64-7, v2, x2
ADD x1, x2
ROR $64-12, v3, x3
ROR $64-18, v4, x4
ADD x3, x4
ADD x2, x4, h
mergeRound(v1)
mergeRound(v2)
mergeRound(v3)
mergeRound(v4)
afterLoop:
ADD len, h
TBZ $4, len, try8
LDP.P 16(p), (x1, x2)
round0(x1)
ROR $64-27, h
EOR x1 @> 64-27, h, h
MADD h, prime4, prime1, h
round0(x2)
ROR $64-27, h
EOR x2 @> 64-27, h
MADD h, prime4, prime1, h
try8:
TBZ $3, len, try4
MOVD.P 8(p), x1
round0(x1)
ROR $64-27, h
EOR x1 @> 64-27, h
MADD h, prime4, prime1, h
try4:
TBZ $2, len, try2
MOVWU.P 4(p), x2
MUL prime1, x2
ROR $64-23, h
EOR x2 @> 64-23, h
MADD h, prime3, prime2, h
try2:
TBZ $1, len, try1
MOVHU.P 2(p), x3
AND $255, x3, x1
LSR $8, x3, x2
MUL prime5, x1
ROR $64-11, h
EOR x1 @> 64-11, h
MUL prime1, h
MUL prime5, x2
ROR $64-11, h
EOR x2 @> 64-11, h
MUL prime1, h
try1:
TBZ $0, len, end
MOVBU (p), x4
MUL prime5, x4
ROR $64-11, h
EOR x4 @> 64-11, h
MUL prime1, h
end:
EOR h >> 33, h
MUL prime2, h
EOR h >> 29, h
MUL prime3, h
EOR h >> 32, h
MOVD h, ret+24(FP)
RET
// func writeBlocks(d *Digest, b []byte) int
//
// Assumes len(b) >= 32.
TEXT ·writeBlocks(SB), NOFRAME+NOSPLIT, $0-40
LDP primes<>(SB), (prime1, prime2)
// Load state. Assume v[1-4] are stored contiguously.
MOVD d+0(FP), digest
LDP 0(digest), (v1, v2)
LDP 16(digest), (v3, v4)
LDP b_base+8(FP), (p, len)
blocksLoop()
// Store updated state.
STP (v1, v2), 0(digest)
STP (v3, v4), 16(digest)
BIC $31, len
MOVD len, ret+32(FP)
RET

@ -1,5 +1,9 @@
//go:build !appengine && gc && !purego //go:build (amd64 || arm64) && !appengine && gc && !purego && !noasm
// +build !appengine,gc,!purego // +build amd64 arm64
// +build !appengine
// +build gc
// +build !purego
// +build !noasm
package xxhash package xxhash

@ -1,5 +1,5 @@
//go:build !amd64 || appengine || !gc || purego //go:build (!amd64 && !arm64) || appengine || !gc || purego || noasm
// +build !amd64 appengine !gc purego // +build !amd64,!arm64 appengine !gc purego noasm
package xxhash package xxhash

@ -278,7 +278,7 @@ func (s *sequenceDecs) decode(seqs int, br *bitReader, hist []byte) error {
mlState = mlTable[mlState.newState()&maxTableMask] mlState = mlTable[mlState.newState()&maxTableMask]
ofState = ofTable[ofState.newState()&maxTableMask] ofState = ofTable[ofState.newState()&maxTableMask]
} else { } else {
bits := br.getBitsFast(nBits) bits := br.get32BitsFast(nBits)
lowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31)) lowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31))
llState = llTable[(llState.newState()+lowBits)&maxTableMask] llState = llTable[(llState.newState()+lowBits)&maxTableMask]
@ -326,7 +326,7 @@ func (s *sequenceDecs) updateAlt(br *bitReader) {
s.offsets.state.state = s.offsets.state.dt[c.newState()] s.offsets.state.state = s.offsets.state.dt[c.newState()]
return return
} }
bits := br.getBitsFast(nBits) bits := br.get32BitsFast(nBits)
lowBits := uint16(bits >> ((c.nbBits() + b.nbBits()) & 31)) lowBits := uint16(bits >> ((c.nbBits() + b.nbBits()) & 31))
s.litLengths.state.state = s.litLengths.state.dt[a.newState()+lowBits] s.litLengths.state.state = s.litLengths.state.dt[a.newState()+lowBits]

@ -770,6 +770,7 @@ type Vertex struct {
Started *time.Time `protobuf:"bytes,5,opt,name=started,proto3,stdtime" json:"started,omitempty"` Started *time.Time `protobuf:"bytes,5,opt,name=started,proto3,stdtime" json:"started,omitempty"`
Completed *time.Time `protobuf:"bytes,6,opt,name=completed,proto3,stdtime" json:"completed,omitempty"` Completed *time.Time `protobuf:"bytes,6,opt,name=completed,proto3,stdtime" json:"completed,omitempty"`
Error string `protobuf:"bytes,7,opt,name=error,proto3" json:"error,omitempty"` Error string `protobuf:"bytes,7,opt,name=error,proto3" json:"error,omitempty"`
ProgressGroup *pb.ProgressGroup `protobuf:"bytes,8,opt,name=progressGroup,proto3" json:"progressGroup,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -843,6 +844,13 @@ func (m *Vertex) GetError() string {
return "" return ""
} }
func (m *Vertex) GetProgressGroup() *pb.ProgressGroup {
if m != nil {
return m.ProgressGroup
}
return nil
}
type VertexStatus struct { type VertexStatus struct {
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
Vertex github_com_opencontainers_go_digest.Digest `protobuf:"bytes,2,opt,name=vertex,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"vertex"` Vertex github_com_opencontainers_go_digest.Digest `protobuf:"bytes,2,opt,name=vertex,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"vertex"`
@ -1261,103 +1269,104 @@ func init() {
func init() { proto.RegisterFile("control.proto", fileDescriptor_0c5120591600887d) } func init() { proto.RegisterFile("control.proto", fileDescriptor_0c5120591600887d) }
var fileDescriptor_0c5120591600887d = []byte{ var fileDescriptor_0c5120591600887d = []byte{
// 1521 bytes of a gzipped FileDescriptorProto // 1543 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4b, 0x6f, 0xdb, 0xc6, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xcd, 0x6f, 0x1b, 0x45,
0x16, 0x0e, 0x25, 0xeb, 0x75, 0x2c, 0x1b, 0xce, 0x24, 0x37, 0x20, 0x78, 0x71, 0x6d, 0x87, 0xc9, 0x14, 0xef, 0xda, 0xf1, 0xd7, 0x8b, 0x13, 0xa5, 0xd3, 0x52, 0xad, 0x16, 0x91, 0xa4, 0xdb, 0x22,
0x05, 0x84, 0x20, 0xa1, 0x1c, 0xb5, 0x29, 0x52, 0xf7, 0x81, 0x44, 0x56, 0x8a, 0x38, 0x88, 0xd1, 0x45, 0x55, 0xbb, 0x4e, 0x03, 0x85, 0x12, 0x3e, 0xd4, 0x3a, 0x2e, 0x34, 0x55, 0x23, 0xca, 0xa4,
0x74, 0x94, 0x34, 0x40, 0x16, 0x05, 0x28, 0x69, 0x24, 0x13, 0xa6, 0x38, 0xec, 0xcc, 0xd0, 0x89, 0xa5, 0x52, 0x0f, 0x48, 0x6b, 0x7b, 0xbc, 0x59, 0x65, 0xbd, 0xb3, 0xcc, 0xcc, 0xa6, 0x35, 0x7f,
0xfa, 0x03, 0xba, 0xee, 0xae, 0x3f, 0xa0, 0x8b, 0xae, 0xba, 0xee, 0x2f, 0x28, 0x90, 0x65, 0xd7, 0x00, 0x67, 0x6e, 0xfc, 0x01, 0x1c, 0x38, 0x71, 0xe6, 0x2f, 0x40, 0xea, 0x91, 0x73, 0x0f, 0x01,
0x59, 0xb8, 0x45, 0xf6, 0x2d, 0xba, 0xec, 0xb2, 0x98, 0x07, 0x65, 0xca, 0x92, 0xfc, 0x4a, 0x57, 0xf5, 0x0e, 0xe2, 0xc8, 0x11, 0xcd, 0xc7, 0x3a, 0xeb, 0xd8, 0xce, 0x57, 0x39, 0x79, 0xde, 0xcc,
0x9a, 0x33, 0x3c, 0xdf, 0xa7, 0xf3, 0x9c, 0x99, 0x03, 0x4b, 0x5d, 0x1a, 0x09, 0x46, 0x43, 0x2f, 0x7b, 0xbf, 0x7d, 0x9f, 0x33, 0xef, 0x19, 0xe6, 0x3a, 0x34, 0x16, 0x8c, 0x46, 0x5e, 0xc2, 0xa8,
0x66, 0x54, 0x50, 0xb4, 0x32, 0xa4, 0x9d, 0x91, 0xd7, 0x49, 0x82, 0xb0, 0xb7, 0x17, 0x08, 0x6f, 0xa0, 0x68, 0xa1, 0x4f, 0xdb, 0x03, 0xaf, 0x9d, 0x86, 0x51, 0x77, 0x37, 0x14, 0xde, 0xde, 0x4d,
0xff, 0xb6, 0x73, 0x6b, 0x10, 0x88, 0xdd, 0xa4, 0xe3, 0x75, 0xe9, 0xb0, 0x3e, 0xa0, 0x03, 0x5a, 0xe7, 0x46, 0x10, 0x8a, 0x9d, 0xb4, 0xed, 0x75, 0x68, 0xbf, 0x11, 0xd0, 0x80, 0x36, 0x14, 0x63,
0x57, 0x8a, 0x9d, 0xa4, 0xaf, 0x24, 0x25, 0xa8, 0x95, 0x26, 0x70, 0xd6, 0x06, 0x94, 0x0e, 0x42, 0x3b, 0xed, 0x29, 0x4a, 0x11, 0x6a, 0xa5, 0x01, 0x9c, 0xa5, 0x80, 0xd2, 0x20, 0x22, 0x07, 0x5c,
0x72, 0xa8, 0x25, 0x82, 0x21, 0xe1, 0xc2, 0x1f, 0xc6, 0x46, 0xe1, 0x66, 0x86, 0x4f, 0xfe, 0x59, 0x22, 0xec, 0x13, 0x2e, 0xfc, 0x7e, 0x62, 0x18, 0xae, 0xe7, 0xf0, 0xe4, 0xc7, 0x1a, 0xd9, 0xc7,
0x3d, 0xfd, 0xb3, 0x3a, 0xa7, 0xe1, 0x3e, 0x61, 0xf5, 0xb8, 0x53, 0xa7, 0x31, 0x37, 0xda, 0xf5, 0x1a, 0x9c, 0x46, 0x7b, 0x84, 0x35, 0x92, 0x76, 0x83, 0x26, 0xdc, 0x70, 0x37, 0xa6, 0x72, 0xfb,
0xb9, 0xda, 0x7e, 0x1c, 0xd4, 0xc5, 0x28, 0x26, 0xbc, 0xfe, 0x92, 0xb2, 0x3d, 0xc2, 0x34, 0xc0, 0x49, 0xd8, 0x10, 0x83, 0x84, 0xf0, 0xc6, 0x73, 0xca, 0x76, 0x09, 0xd3, 0x02, 0xee, 0xf7, 0x16,
0xfd, 0xd6, 0x82, 0xea, 0x13, 0x96, 0x44, 0x04, 0x93, 0xaf, 0x13, 0xc2, 0x05, 0xba, 0x02, 0xc5, 0xd4, 0x1f, 0xb1, 0x34, 0x26, 0x98, 0x7c, 0x9b, 0x12, 0x2e, 0xd0, 0x25, 0x28, 0xf7, 0xc2, 0x48,
0x7e, 0x10, 0x0a, 0xc2, 0x6c, 0x6b, 0x3d, 0x5f, 0xab, 0x60, 0x23, 0xa1, 0x15, 0xc8, 0xfb, 0x61, 0x10, 0x66, 0x5b, 0xcb, 0xc5, 0x95, 0x1a, 0x36, 0x14, 0x5a, 0x80, 0xa2, 0x1f, 0x45, 0x76, 0x61,
0x68, 0xe7, 0xd6, 0xad, 0x5a, 0x19, 0xcb, 0x25, 0xaa, 0x41, 0x75, 0x8f, 0x90, 0xb8, 0x95, 0x30, 0xd9, 0x5a, 0xa9, 0x62, 0xb9, 0x44, 0x2b, 0x50, 0xdf, 0x25, 0x24, 0x69, 0xa5, 0xcc, 0x17, 0x21,
0x5f, 0x04, 0x34, 0xb2, 0xf3, 0xeb, 0x56, 0x2d, 0xdf, 0x5c, 0x78, 0x7d, 0xb0, 0x66, 0xe1, 0x89, 0x8d, 0xed, 0xe2, 0xb2, 0xb5, 0x52, 0x6c, 0xce, 0xbc, 0xdc, 0x5f, 0xb2, 0xf0, 0xc8, 0x09, 0x72,
0x2f, 0xc8, 0x85, 0x8a, 0x94, 0x9b, 0x23, 0x41, 0xb8, 0xbd, 0x90, 0x51, 0x3b, 0xdc, 0x76, 0x6f, 0xa1, 0x26, 0xe9, 0xe6, 0x40, 0x10, 0x6e, 0xcf, 0xe4, 0xd8, 0x0e, 0xb6, 0xdd, 0x6b, 0xb0, 0xd0,
0xc0, 0x4a, 0x2b, 0xe0, 0x7b, 0xcf, 0xb8, 0x3f, 0x38, 0xc9, 0x16, 0xf7, 0x11, 0x5c, 0xcc, 0xe8, 0x0a, 0xf9, 0xee, 0x13, 0xee, 0x07, 0xc7, 0xe9, 0xe2, 0x3e, 0x80, 0xf3, 0x39, 0x5e, 0x9e, 0xd0,
0xf2, 0x98, 0x46, 0x9c, 0xa0, 0x3b, 0x50, 0x64, 0xa4, 0x4b, 0x59, 0x4f, 0x29, 0x2f, 0x36, 0xfe, 0x98, 0x13, 0x74, 0x0b, 0xca, 0x8c, 0x74, 0x28, 0xeb, 0x2a, 0xe6, 0xd9, 0xb5, 0x77, 0xbc, 0xc3,
0xe7, 0x1d, 0xcd, 0x8d, 0x67, 0x00, 0x52, 0x09, 0x1b, 0x65, 0xf7, 0xfb, 0x3c, 0x2c, 0x66, 0xf6, 0xb1, 0xf1, 0x8c, 0x80, 0x64, 0xc2, 0x86, 0xd9, 0xfd, 0xb1, 0x08, 0xb3, 0xb9, 0x7d, 0x34, 0x0f,
0xd1, 0x32, 0xe4, 0xb6, 0x5b, 0xb6, 0xb5, 0x6e, 0xd5, 0x2a, 0x38, 0xb7, 0xdd, 0x42, 0x36, 0x94, 0x85, 0xcd, 0x96, 0x6d, 0x2d, 0x5b, 0x2b, 0x35, 0x5c, 0xd8, 0x6c, 0x21, 0x1b, 0x2a, 0x5b, 0xa9,
0x76, 0x12, 0xe1, 0x77, 0x42, 0x62, 0x7c, 0x4f, 0x45, 0x74, 0x19, 0x0a, 0xdb, 0xd1, 0x33, 0x4e, 0xf0, 0xdb, 0x11, 0x31, 0xb6, 0x67, 0x24, 0xba, 0x08, 0xa5, 0xcd, 0xf8, 0x09, 0x27, 0xca, 0xf0,
0x94, 0xe3, 0x65, 0xac, 0x05, 0x84, 0x60, 0xa1, 0x1d, 0x7c, 0x43, 0xb4, 0x9b, 0x58, 0xad, 0x91, 0x2a, 0xd6, 0x04, 0x42, 0x30, 0xb3, 0x1d, 0x7e, 0x47, 0xb4, 0x99, 0x58, 0xad, 0x91, 0x03, 0xe5,
0x03, 0xc5, 0x27, 0x3e, 0x23, 0x91, 0xb0, 0x0b, 0x92, 0xb7, 0x99, 0xb3, 0x2d, 0x6c, 0x76, 0x50, 0x47, 0x3e, 0x23, 0xb1, 0xb0, 0x4b, 0x12, 0xb7, 0x59, 0xb0, 0x2d, 0x6c, 0x76, 0x50, 0x13, 0x6a,
0x13, 0x2a, 0x5b, 0x8c, 0xf8, 0x82, 0xf4, 0xee, 0x0b, 0xbb, 0xb8, 0x6e, 0xd5, 0x16, 0x1b, 0x8e, 0x1b, 0x8c, 0xf8, 0x82, 0x74, 0xef, 0x0a, 0xbb, 0xbc, 0x6c, 0xad, 0xcc, 0xae, 0x39, 0x9e, 0x4e,
0xa7, 0x8b, 0xc2, 0x4b, 0x8b, 0xc2, 0x7b, 0x9a, 0x16, 0x45, 0xb3, 0xfc, 0xfa, 0x60, 0xed, 0xc2, 0x0a, 0x2f, 0x4b, 0x0a, 0xef, 0x71, 0x96, 0x14, 0xcd, 0xea, 0xcb, 0xfd, 0xa5, 0x73, 0x3f, 0xfc,
0x77, 0xbf, 0xc9, 0xd8, 0x8d, 0x61, 0xe8, 0x1e, 0xc0, 0x63, 0x9f, 0x8b, 0x67, 0x5c, 0x91, 0x94, 0x21, 0x7d, 0x37, 0x14, 0x43, 0x77, 0x00, 0x1e, 0xfa, 0x5c, 0x3c, 0xe1, 0x0a, 0xa4, 0x72, 0x2c,
0x4e, 0x24, 0x59, 0x50, 0x04, 0x19, 0x0c, 0x5a, 0x05, 0x50, 0x41, 0xd8, 0xa2, 0x49, 0x24, 0xec, 0xc8, 0x8c, 0x02, 0xc8, 0xc9, 0xa0, 0x45, 0x00, 0xe5, 0x84, 0x0d, 0x9a, 0xc6, 0xc2, 0xae, 0x2a,
0xb2, 0xb2, 0x3d, 0xb3, 0x83, 0xd6, 0x61, 0xb1, 0x45, 0x78, 0x97, 0x05, 0xb1, 0x4a, 0x75, 0x45, 0xdd, 0x73, 0x3b, 0x68, 0x19, 0x66, 0x5b, 0x84, 0x77, 0x58, 0x98, 0xa8, 0x50, 0xd7, 0x94, 0x7b,
0x85, 0x27, 0xbb, 0x25, 0x19, 0x74, 0x04, 0x9f, 0x8e, 0x62, 0x62, 0x83, 0x52, 0xc8, 0xec, 0xc8, 0xf2, 0x5b, 0x12, 0x41, 0x7b, 0xf0, 0xf1, 0x20, 0x21, 0x36, 0x28, 0x86, 0xdc, 0x8e, 0x8c, 0xe5,
0x5c, 0xb6, 0x77, 0x7d, 0x46, 0x7a, 0xf6, 0xa2, 0x0a, 0x97, 0x91, 0x64, 0x7c, 0x75, 0x24, 0xb8, 0xf6, 0x8e, 0xcf, 0x48, 0xd7, 0x9e, 0x55, 0xee, 0x32, 0x94, 0xf4, 0xaf, 0xf6, 0x04, 0xb7, 0xeb,
0x5d, 0x55, 0x49, 0x4e, 0x45, 0xf7, 0x87, 0x22, 0x54, 0xdb, 0xb2, 0xc6, 0xd3, 0x72, 0x58, 0x81, 0x2a, 0xc8, 0x19, 0xe9, 0xfe, 0x54, 0x86, 0xfa, 0xb6, 0xcc, 0xf1, 0x2c, 0x1d, 0x16, 0xa0, 0x88,
0x3c, 0x26, 0x7d, 0x93, 0x1b, 0xb9, 0x44, 0x1e, 0x40, 0x8b, 0xf4, 0x83, 0x28, 0x50, 0x56, 0xe5, 0x49, 0xcf, 0xc4, 0x46, 0x2e, 0x91, 0x07, 0xd0, 0x22, 0xbd, 0x30, 0x0e, 0x95, 0x56, 0x05, 0x65,
0x94, 0xe3, 0xcb, 0x5e, 0xdc, 0xf1, 0x0e, 0x77, 0x71, 0x46, 0x03, 0x39, 0x50, 0x7e, 0xf0, 0x2a, 0xf8, 0xbc, 0x97, 0xb4, 0xbd, 0x83, 0x5d, 0x9c, 0xe3, 0x40, 0x0e, 0x54, 0xef, 0xbd, 0x48, 0x28,
0xa6, 0x4c, 0x96, 0x54, 0x5e, 0xd1, 0x8c, 0x65, 0xf4, 0x1c, 0x96, 0xd2, 0xf5, 0x7d, 0x21, 0x98, 0x93, 0x29, 0x55, 0x54, 0x30, 0x43, 0x1a, 0x3d, 0x85, 0xb9, 0x6c, 0x7d, 0x57, 0x08, 0x26, 0x13,
0x2c, 0x54, 0x59, 0x46, 0xb7, 0xa7, 0xcb, 0x28, 0x6b, 0x94, 0x37, 0x81, 0x79, 0x10, 0x09, 0x36, 0x55, 0xa6, 0xd1, 0xcd, 0xf1, 0x34, 0xca, 0x2b, 0xe5, 0x8d, 0xc8, 0xdc, 0x8b, 0x05, 0x1b, 0xe0,
0xc2, 0x93, 0x3c, 0xd2, 0xc3, 0x36, 0xe1, 0x5c, 0x5a, 0xa8, 0xd2, 0x8f, 0x53, 0x51, 0x9a, 0xf3, 0x51, 0x1c, 0x69, 0xe1, 0x36, 0xe1, 0x5c, 0x6a, 0xa8, 0xc2, 0x8f, 0x33, 0x52, 0xaa, 0xf3, 0x39,
0x19, 0xa3, 0x91, 0x20, 0x51, 0x4f, 0xa5, 0xbe, 0x82, 0xc7, 0xb2, 0x34, 0x27, 0x5d, 0x6b, 0x73, 0xa3, 0xb1, 0x20, 0x71, 0x57, 0x85, 0xbe, 0x86, 0x87, 0xb4, 0x54, 0x27, 0x5b, 0x6b, 0x75, 0x2a,
0x4a, 0xa7, 0x32, 0x67, 0x02, 0x63, 0xcc, 0x99, 0xd8, 0x43, 0x9b, 0x50, 0xd8, 0xf2, 0xbb, 0xbb, 0x27, 0x52, 0x67, 0x44, 0xc6, 0xa8, 0x33, 0xb2, 0x87, 0xd6, 0xa1, 0xb4, 0xe1, 0x77, 0x76, 0x88,
0x44, 0x65, 0x79, 0xb1, 0xb1, 0x3a, 0x4d, 0xa8, 0x3e, 0x7f, 0xae, 0xd2, 0xca, 0x55, 0xa3, 0x5e, 0x8a, 0xf2, 0xec, 0xda, 0xe2, 0x38, 0xa0, 0x3a, 0xfe, 0x52, 0x85, 0x95, 0xab, 0x42, 0x3d, 0x87,
0xc0, 0x1a, 0x82, 0xbe, 0x82, 0xea, 0x83, 0x48, 0x04, 0x22, 0x24, 0x43, 0x95, 0xb1, 0x8a, 0xcc, 0xb5, 0x08, 0xfa, 0x06, 0xea, 0xf7, 0x62, 0x11, 0x8a, 0x88, 0xf4, 0x55, 0xc4, 0x6a, 0x32, 0x62,
0x58, 0x73, 0xf3, 0xcd, 0xc1, 0xda, 0x07, 0x73, 0x0f, 0x9e, 0x44, 0x04, 0x61, 0x9d, 0x64, 0x50, 0xcd, 0xf5, 0x57, 0xfb, 0x4b, 0x1f, 0x4c, 0xbd, 0x78, 0x52, 0x11, 0x46, 0x0d, 0x92, 0x93, 0xf2,
0x5e, 0x86, 0x02, 0x4f, 0xf0, 0xa1, 0x17, 0xb0, 0x9c, 0x1a, 0xbb, 0x1d, 0xc5, 0x89, 0xe0, 0x36, 0x72, 0x10, 0x78, 0x04, 0x0f, 0x3d, 0x83, 0xf9, 0x4c, 0xd9, 0xcd, 0x38, 0x49, 0x05, 0xb7, 0x41,
0x28, 0xaf, 0x1b, 0xa7, 0xf4, 0x5a, 0x83, 0xb4, 0xdb, 0x47, 0x98, 0x9c, 0x7b, 0x80, 0xa6, 0x73, 0x59, 0xbd, 0x76, 0x42, 0xab, 0xb5, 0x90, 0x36, 0xfb, 0x10, 0x92, 0x73, 0x07, 0xd0, 0x78, 0xac,
0x25, 0x6b, 0x6a, 0x8f, 0x8c, 0xd2, 0x9a, 0xda, 0x23, 0x23, 0xd9, 0xd6, 0xfb, 0x7e, 0x98, 0xe8, 0x64, 0x4e, 0xed, 0x92, 0x41, 0x96, 0x53, 0xbb, 0x64, 0x20, 0xcb, 0x7a, 0xcf, 0x8f, 0x52, 0x5d,
0x76, 0xaf, 0x60, 0x2d, 0x6c, 0xe6, 0xee, 0x5a, 0x92, 0x61, 0x3a, 0xbc, 0x67, 0x62, 0xf8, 0x02, 0xee, 0x35, 0xac, 0x89, 0xf5, 0xc2, 0x6d, 0x4b, 0x22, 0x8c, 0xbb, 0xf7, 0x54, 0x08, 0x5f, 0xc1,
0x2e, 0xcd, 0x30, 0x75, 0x06, 0xc5, 0xf5, 0x2c, 0xc5, 0x74, 0x4d, 0x1f, 0x52, 0xba, 0x3f, 0xe5, 0x85, 0x09, 0xaa, 0x4e, 0x80, 0xb8, 0x9a, 0x87, 0x18, 0xcf, 0xe9, 0x03, 0x48, 0xf7, 0x97, 0x22,
0xa1, 0x9a, 0x4d, 0x18, 0xda, 0x80, 0x4b, 0xda, 0x4f, 0x4c, 0xfa, 0x2d, 0x12, 0x33, 0xd2, 0x95, 0xd4, 0xf3, 0x01, 0x43, 0xab, 0x70, 0x41, 0xdb, 0x89, 0x49, 0xaf, 0x45, 0x12, 0x46, 0x3a, 0xf2,
0xa7, 0x84, 0x21, 0x9f, 0xf5, 0x09, 0x35, 0xe0, 0xf2, 0xf6, 0xd0, 0x6c, 0xf3, 0x0c, 0x24, 0xa7, 0x96, 0x30, 0xe0, 0x93, 0x8e, 0xd0, 0x1a, 0x5c, 0xdc, 0xec, 0x9b, 0x6d, 0x9e, 0x13, 0x29, 0xa8,
0xfa, 0x71, 0xe6, 0x37, 0x44, 0xe1, 0x3f, 0x9a, 0x4a, 0x45, 0x22, 0x03, 0xca, 0xab, 0x84, 0x7d, 0x7a, 0x9c, 0x78, 0x86, 0x28, 0xbc, 0xa5, 0xa1, 0x94, 0x27, 0x72, 0x42, 0x45, 0x15, 0xb0, 0x8f,
0x78, 0x7c, 0x55, 0x79, 0x33, 0xb1, 0x3a, 0x6f, 0xb3, 0x79, 0xd1, 0x27, 0x50, 0xd2, 0x1f, 0xd2, 0x8e, 0xce, 0x2a, 0x6f, 0xa2, 0xac, 0x8e, 0xdb, 0x64, 0x5c, 0xf4, 0x29, 0x54, 0xf4, 0x41, 0x56,
0xc6, 0xbc, 0x76, 0xfc, 0x5f, 0x68, 0xb2, 0x14, 0x23, 0xe1, 0xda, 0x0f, 0x6e, 0x17, 0xce, 0x00, 0x98, 0x57, 0x8e, 0xfe, 0x84, 0x06, 0xcb, 0x64, 0xa4, 0xb8, 0xb6, 0x83, 0xdb, 0xa5, 0x53, 0x88,
0x37, 0x18, 0xe7, 0x21, 0x38, 0xf3, 0x4d, 0x3e, 0x4b, 0x09, 0xb8, 0x3f, 0x5a, 0x70, 0x71, 0xea, 0x1b, 0x19, 0xe7, 0x3e, 0x38, 0xd3, 0x55, 0x3e, 0x4d, 0x0a, 0xb8, 0x3f, 0x5b, 0x70, 0x7e, 0xec,
0x8f, 0xe4, 0xad, 0xa1, 0xce, 0x4d, 0x4d, 0xa1, 0xd6, 0xa8, 0x05, 0x05, 0xdd, 0xf9, 0x39, 0x65, 0x43, 0xf2, 0xd5, 0x50, 0xf7, 0xa6, 0x86, 0x50, 0x6b, 0xd4, 0x82, 0x92, 0xae, 0xfc, 0x82, 0x52,
0xb0, 0x77, 0x0a, 0x83, 0xbd, 0x4c, 0xdb, 0x6b, 0xb0, 0x73, 0x17, 0xe0, 0x7c, 0xc5, 0xea, 0xfe, 0xd8, 0x3b, 0x81, 0xc2, 0x5e, 0xae, 0xec, 0xb5, 0xb0, 0x73, 0x1b, 0xe0, 0x6c, 0xc9, 0xea, 0xfe,
0x6c, 0xc1, 0x92, 0xe9, 0x32, 0x73, 0xc5, 0xfa, 0xb0, 0x92, 0xb6, 0x50, 0xba, 0x67, 0x2e, 0xdb, 0x6a, 0xc1, 0x9c, 0xa9, 0x32, 0xf3, 0xc4, 0xfa, 0xb0, 0x90, 0x95, 0x50, 0xb6, 0x67, 0x1e, 0xdb,
0x3b, 0x73, 0x1b, 0x54, 0xab, 0x79, 0x47, 0x71, 0xda, 0xc6, 0x29, 0x3a, 0x67, 0x2b, 0xad, 0xab, 0x5b, 0x53, 0x0b, 0x54, 0xb3, 0x79, 0x87, 0xe5, 0xb4, 0x8e, 0x63, 0x70, 0xce, 0x46, 0x96, 0x57,
0x23, 0xaa, 0x67, 0xb2, 0xfc, 0x2a, 0x2c, 0xb5, 0x85, 0x2f, 0x12, 0x3e, 0xf7, 0xe6, 0x70, 0xff, 0x87, 0x58, 0x4f, 0xa5, 0xf9, 0x65, 0x98, 0xdb, 0x16, 0xbe, 0x48, 0xf9, 0xd4, 0x97, 0xc3, 0xfd,
0xb2, 0x60, 0x39, 0xd5, 0x31, 0xde, 0xbd, 0x0f, 0xe5, 0x7d, 0xc2, 0x04, 0x79, 0x45, 0xb8, 0xf1, 0xc7, 0x82, 0xf9, 0x8c, 0xc7, 0x58, 0xf7, 0x3e, 0x54, 0xf7, 0x08, 0x13, 0xe4, 0x05, 0xe1, 0xc6,
0xca, 0x9e, 0xf6, 0xea, 0x4b, 0xa5, 0x81, 0xc7, 0x9a, 0x68, 0x13, 0xca, 0x5c, 0xf1, 0x90, 0x34, 0x2a, 0x7b, 0xdc, 0xaa, 0xaf, 0x15, 0x07, 0x1e, 0x72, 0xa2, 0x75, 0xa8, 0x72, 0x85, 0x43, 0xb2,
0x51, 0xab, 0xf3, 0x50, 0xe6, 0xff, 0xc6, 0xfa, 0xa8, 0x0e, 0x0b, 0x21, 0x1d, 0x70, 0xd3, 0x33, 0x40, 0x2d, 0x4e, 0x93, 0x32, 0xdf, 0x1b, 0xf2, 0xa3, 0x06, 0xcc, 0x44, 0x34, 0xe0, 0xa6, 0x66,
0xff, 0x9d, 0x87, 0x7b, 0x4c, 0x07, 0x58, 0x29, 0xa2, 0x8f, 0xa0, 0xfc, 0xd2, 0x67, 0x51, 0x10, 0xde, 0x9e, 0x26, 0xf7, 0x90, 0x06, 0x58, 0x31, 0xa2, 0x8f, 0xa1, 0xfa, 0xdc, 0x67, 0x71, 0x18,
0x0d, 0xd2, 0x2e, 0x58, 0x9b, 0x07, 0x7a, 0xae, 0xf5, 0xf0, 0x18, 0xe0, 0x1e, 0xe4, 0xa0, 0xa8, 0x07, 0x59, 0x15, 0x2c, 0x4d, 0x13, 0x7a, 0xaa, 0xf9, 0xf0, 0x50, 0x40, 0x76, 0x3a, 0x65, 0x7d,
0xbf, 0xa1, 0x47, 0x50, 0xec, 0x05, 0x03, 0xc2, 0x85, 0x0e, 0x49, 0xb3, 0x21, 0x0f, 0xf9, 0x37, 0x86, 0x1e, 0x40, 0xb9, 0x1b, 0x06, 0x84, 0x0b, 0xed, 0x92, 0xe6, 0x9a, 0xbc, 0xe4, 0x5f, 0xed,
0x07, 0x6b, 0x37, 0x32, 0xa7, 0x38, 0x8d, 0x49, 0x24, 0x1f, 0xbb, 0x7e, 0x10, 0x11, 0xc6, 0xeb, 0x2f, 0x5d, 0xcb, 0xdd, 0xe2, 0x34, 0x21, 0xb1, 0x6c, 0x76, 0xfd, 0x30, 0x26, 0x8c, 0x37, 0x02,
0x03, 0x7a, 0x4b, 0x43, 0xbc, 0x96, 0xfa, 0xc1, 0x86, 0x41, 0x72, 0x05, 0xfa, 0xac, 0x56, 0xe7, 0x7a, 0x43, 0x8b, 0x78, 0x2d, 0xf5, 0x83, 0x0d, 0x82, 0xc4, 0x0a, 0xf5, 0x5d, 0xad, 0xee, 0x8b,
0xc5, 0xf9, 0xb8, 0x34, 0x83, 0x6c, 0x83, 0xc8, 0x1f, 0x12, 0x73, 0x37, 0xab, 0xb5, 0x7c, 0x38, 0xb3, 0x61, 0x69, 0x04, 0x59, 0x06, 0xb1, 0xdf, 0x27, 0xe6, 0x6d, 0x56, 0x6b, 0xd9, 0x38, 0x74,
0x74, 0x65, 0x9d, 0xf7, 0xd4, 0x93, 0xaa, 0x8c, 0x8d, 0x84, 0x36, 0xa1, 0xc4, 0x85, 0xcf, 0xe4, 0x64, 0x9e, 0x77, 0x55, 0x4b, 0x55, 0xc5, 0x86, 0x42, 0xeb, 0x50, 0xe1, 0xc2, 0x67, 0xf2, 0xce,
0x99, 0x53, 0x38, 0xe5, 0x8b, 0x27, 0x05, 0xa0, 0x4f, 0xa1, 0xd2, 0xa5, 0xc3, 0x38, 0x24, 0x12, 0x29, 0x9d, 0xb0, 0xe3, 0xc9, 0x04, 0xd0, 0x67, 0x50, 0xeb, 0xd0, 0x7e, 0x12, 0x11, 0x29, 0x5d,
0x5d, 0x3c, 0x25, 0xfa, 0x10, 0x22, 0x4b, 0x8f, 0x30, 0x46, 0x99, 0x7a, 0x6b, 0x55, 0xb0, 0x16, 0x3e, 0xa1, 0xf4, 0x81, 0x88, 0x4c, 0x3d, 0xc2, 0x18, 0x65, 0xaa, 0xd7, 0xaa, 0x61, 0x4d, 0xa0,
0xdc, 0x3f, 0x73, 0x50, 0xcd, 0x66, 0x7a, 0xea, 0x2d, 0xf9, 0x08, 0x8a, 0xba, 0x6e, 0x74, 0xc9, 0x0f, 0x61, 0x2e, 0x61, 0x34, 0x60, 0x84, 0xf3, 0x2f, 0x18, 0x4d, 0x13, 0xf3, 0xc2, 0x9e, 0x97,
0x9e, 0x2f, 0x54, 0x9a, 0x61, 0x66, 0xa8, 0x6c, 0x28, 0x75, 0x13, 0xa6, 0x1e, 0x9a, 0xfa, 0xf9, 0x97, 0xf7, 0xa3, 0xfc, 0x01, 0x1e, 0xe5, 0x73, 0xff, 0x2e, 0x40, 0x3d, 0x9f, 0x22, 0x63, 0x4d,
0x99, 0x8a, 0xd2, 0x60, 0x41, 0x85, 0x1f, 0xaa, 0x50, 0xe5, 0xb1, 0x16, 0xe4, 0xdb, 0x73, 0x3c, 0xe8, 0x03, 0x28, 0xeb, 0x84, 0xd3, 0xb9, 0x7e, 0x36, 0x1f, 0x6b, 0x84, 0x89, 0x3e, 0xb6, 0xa1,
0x6e, 0x9c, 0xed, 0xed, 0x39, 0x86, 0x65, 0xd3, 0x50, 0x7a, 0xa7, 0x34, 0x94, 0xcf, 0x9c, 0x06, 0xd2, 0x49, 0x99, 0xea, 0x50, 0x75, 0xdf, 0x9a, 0x91, 0xd2, 0x52, 0x41, 0x85, 0x1f, 0x29, 0x1f,
0xf7, 0x17, 0x0b, 0x2a, 0xe3, 0x16, 0xc9, 0x44, 0xd7, 0x7a, 0xe7, 0xe8, 0x4e, 0x44, 0x26, 0x77, 0x17, 0xb1, 0x26, 0x64, 0xd3, 0x3a, 0x9c, 0x53, 0x4e, 0xd7, 0xb4, 0x0e, 0xc5, 0xf2, 0xf1, 0xab,
0xbe, 0xc8, 0x5c, 0x81, 0x22, 0x17, 0x8c, 0xf8, 0x43, 0x3d, 0x19, 0x61, 0x23, 0xc9, 0xc3, 0x68, 0xbc, 0x51, 0xfc, 0xaa, 0xa7, 0x8e, 0x9f, 0xfb, 0x9b, 0x05, 0xb5, 0x61, 0x6d, 0xe5, 0xbc, 0x6b,
0xc8, 0x07, 0x2a, 0x43, 0x55, 0x2c, 0x97, 0xee, 0xdf, 0x16, 0x2c, 0x4d, 0x74, 0xed, 0xbf, 0xea, 0xbd, 0xb1, 0x77, 0x47, 0x3c, 0x53, 0x38, 0x9b, 0x67, 0x2e, 0x41, 0x99, 0x0b, 0x46, 0xfc, 0xbe,
0xcb, 0x65, 0x28, 0x84, 0x64, 0x9f, 0xe8, 0xd9, 0x2d, 0x8f, 0xb5, 0x20, 0x77, 0xf9, 0x2e, 0x65, 0x1e, 0xa9, 0xb0, 0xa1, 0xe4, 0x2d, 0xd6, 0xe7, 0x81, 0x8a, 0x50, 0x1d, 0xcb, 0xa5, 0xfb, 0xaf,
0x42, 0x19, 0x57, 0xc5, 0x5a, 0x90, 0x36, 0xf7, 0x88, 0xf0, 0x83, 0x50, 0x1d, 0x2f, 0x55, 0x6c, 0x05, 0x73, 0x23, 0xe5, 0xfe, 0xbf, 0xda, 0x72, 0x11, 0x4a, 0x11, 0xd9, 0x23, 0x7a, 0xe8, 0x2b,
0x24, 0x69, 0x73, 0xc2, 0x42, 0xf3, 0x7e, 0x95, 0x4b, 0xe4, 0xc2, 0x42, 0x10, 0xf5, 0xa9, 0x29, 0x62, 0x4d, 0xc8, 0x5d, 0xbe, 0x43, 0x99, 0x50, 0xca, 0xd5, 0xb1, 0x26, 0xa4, 0xce, 0x5d, 0x22,
0x1b, 0xf5, 0x40, 0x69, 0xd3, 0x84, 0x75, 0xc9, 0x76, 0xd4, 0xa7, 0x58, 0x7d, 0x43, 0x57, 0xa1, 0xfc, 0x30, 0x52, 0xf7, 0x52, 0x1d, 0x1b, 0x4a, 0xea, 0x9c, 0xb2, 0xc8, 0x34, 0xbe, 0x72, 0x89,
0xc8, 0xfc, 0x68, 0x40, 0xd2, 0xc7, 0x6b, 0x45, 0x6a, 0x61, 0xb9, 0x83, 0xcd, 0x07, 0xd7, 0x85, 0x5c, 0x98, 0x09, 0xe3, 0x1e, 0x35, 0x69, 0xa3, 0x3a, 0x9b, 0x6d, 0x9a, 0xb2, 0x0e, 0xd9, 0x8c,
0xaa, 0x9a, 0xff, 0x76, 0x08, 0x97, 0xd3, 0x86, 0x2c, 0xeb, 0x9e, 0x2f, 0x7c, 0xe5, 0x76, 0x15, 0x7b, 0x14, 0xab, 0x33, 0x74, 0x19, 0xca, 0xcc, 0x8f, 0x03, 0x92, 0x75, 0xbd, 0x35, 0xc9, 0x85,
0xab, 0xb5, 0x7b, 0x13, 0xd0, 0xe3, 0x80, 0x8b, 0xe7, 0x6a, 0x6e, 0xe5, 0x27, 0x0d, 0x87, 0x6d, 0xe5, 0x0e, 0x36, 0x07, 0xae, 0x0b, 0x75, 0x35, 0x38, 0x6e, 0x11, 0x2e, 0xc7, 0x14, 0x99, 0xd6,
0xb8, 0x34, 0xa1, 0x6d, 0x4e, 0xf7, 0x8f, 0x8f, 0x8c, 0x87, 0xd7, 0xa7, 0x0f, 0x4e, 0x35, 0x1e, 0x5d, 0x5f, 0xf8, 0xca, 0xec, 0x3a, 0x56, 0x6b, 0xf7, 0x3a, 0xa0, 0x87, 0x21, 0x17, 0x4f, 0xd5,
0x7b, 0x1a, 0x38, 0x39, 0x25, 0x36, 0xfe, 0xc8, 0x43, 0x69, 0x4b, 0x4f, 0xfe, 0xe8, 0x29, 0x54, 0xc0, 0xcb, 0x8f, 0x9b, 0x2a, 0xb7, 0xe1, 0xc2, 0x08, 0xb7, 0x79, 0x16, 0x3e, 0x39, 0x34, 0x57,
0xc6, 0xd3, 0x27, 0x72, 0xa7, 0x69, 0x8e, 0x8e, 0xb1, 0xce, 0xb5, 0x63, 0x75, 0x8c, 0x7d, 0x0f, 0x5e, 0x1d, 0xbf, 0x71, 0xd5, 0x5c, 0xed, 0x69, 0xc1, 0xd1, 0xf1, 0x72, 0xed, 0xaf, 0x22, 0x54,
0xa1, 0xa0, 0xe6, 0x70, 0x34, 0xe3, 0xfa, 0xc8, 0x0e, 0xe8, 0xce, 0xf1, 0x73, 0xed, 0x86, 0x25, 0x36, 0xf4, 0x5f, 0x06, 0xe8, 0x31, 0xd4, 0x86, 0x63, 0x2b, 0x72, 0xc7, 0x61, 0x0e, 0xcf, 0xbf,
0x99, 0xd4, 0xdd, 0x3b, 0x8b, 0x29, 0xfb, 0x6a, 0x76, 0xd6, 0x4e, 0xb8, 0xb4, 0xd1, 0x0e, 0x14, 0xce, 0x95, 0x23, 0x79, 0x8c, 0x7e, 0xf7, 0xa1, 0xa4, 0x06, 0x78, 0x34, 0xe1, 0xdd, 0xc9, 0x4f,
0xcd, 0x49, 0x36, 0x4b, 0x35, 0x7b, 0xc3, 0x3a, 0xeb, 0xf3, 0x15, 0x34, 0xd9, 0x86, 0x85, 0x76, 0xf6, 0xce, 0xd1, 0x03, 0xf1, 0xaa, 0x25, 0x91, 0xd4, 0xa3, 0x3d, 0x09, 0x29, 0xdf, 0x6e, 0x3b,
0xc6, 0x83, 0xd0, 0x2c, 0xd3, 0xb2, 0x65, 0xe0, 0x9c, 0xf0, 0xbd, 0x66, 0x6d, 0x58, 0xe8, 0x05, 0x4b, 0xc7, 0xbc, 0xf6, 0x68, 0x0b, 0xca, 0xe6, 0x26, 0x9b, 0xc4, 0x9a, 0x7f, 0x9a, 0x9d, 0xe5,
0x2c, 0x66, 0x12, 0x8d, 0x66, 0x24, 0x74, 0xba, 0x6a, 0x9c, 0xff, 0x9f, 0xa0, 0xa5, 0x8d, 0x6d, 0xe9, 0x0c, 0x1a, 0x6c, 0xd5, 0x42, 0x5b, 0xc3, 0x09, 0x6a, 0x92, 0x6a, 0xf9, 0x34, 0x70, 0x8e,
0x56, 0x5f, 0xbf, 0x5d, 0xb5, 0x7e, 0x7d, 0xbb, 0x6a, 0xfd, 0xfe, 0x76, 0xd5, 0xea, 0x14, 0x55, 0x39, 0x5f, 0xb1, 0x56, 0x2d, 0xf4, 0x0c, 0x66, 0x73, 0x81, 0x46, 0x13, 0x02, 0x3a, 0x9e, 0x35,
0xcb, 0xbf, 0xf7, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8f, 0x2a, 0x40, 0x92, 0xfd, 0x11, 0x00, 0xce, 0xbb, 0xc7, 0x70, 0x69, 0x65, 0x9b, 0xf5, 0x97, 0xaf, 0x17, 0xad, 0xdf, 0x5f, 0x2f, 0x5a,
0x00, 0x7f, 0xbe, 0x5e, 0xb4, 0xda, 0x65, 0x55, 0xf2, 0xef, 0xfd, 0x17, 0x00, 0x00, 0xff, 0xff, 0x54,
0x8e, 0x72, 0x11, 0x36, 0x12, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@ -2442,6 +2451,18 @@ func (m *Vertex) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized) i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized)
} }
if m.ProgressGroup != nil {
{
size, err := m.ProgressGroup.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintControl(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x42
}
if len(m.Error) > 0 { if len(m.Error) > 0 {
i -= len(m.Error) i -= len(m.Error)
copy(dAtA[i:], m.Error) copy(dAtA[i:], m.Error)
@ -2450,22 +2471,22 @@ func (m *Vertex) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0x3a dAtA[i] = 0x3a
} }
if m.Completed != nil { if m.Completed != nil {
n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Completed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Completed):]) n7, err7 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Completed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Completed):])
if err6 != nil { if err7 != nil {
return 0, err6 return 0, err7
} }
i -= n6 i -= n7
i = encodeVarintControl(dAtA, i, uint64(n6)) i = encodeVarintControl(dAtA, i, uint64(n7))
i-- i--
dAtA[i] = 0x32 dAtA[i] = 0x32
} }
if m.Started != nil { if m.Started != nil {
n7, err7 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Started, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Started):]) n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Started, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Started):])
if err7 != nil { if err8 != nil {
return 0, err7 return 0, err8
} }
i -= n7 i -= n8
i = encodeVarintControl(dAtA, i, uint64(n7)) i = encodeVarintControl(dAtA, i, uint64(n8))
i-- i--
dAtA[i] = 0x2a dAtA[i] = 0x2a
} }
@ -2530,31 +2551,31 @@ func (m *VertexStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) {
copy(dAtA[i:], m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized)
} }
if m.Completed != nil { if m.Completed != nil {
n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Completed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Completed):]) n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Completed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Completed):])
if err8 != nil { if err9 != nil {
return 0, err8 return 0, err9
} }
i -= n8 i -= n9
i = encodeVarintControl(dAtA, i, uint64(n8)) i = encodeVarintControl(dAtA, i, uint64(n9))
i-- i--
dAtA[i] = 0x42 dAtA[i] = 0x42
} }
if m.Started != nil { if m.Started != nil {
n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Started, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Started):]) n10, err10 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Started, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Started):])
if err9 != nil { if err10 != nil {
return 0, err9 return 0, err10
} }
i -= n9 i -= n10
i = encodeVarintControl(dAtA, i, uint64(n9)) i = encodeVarintControl(dAtA, i, uint64(n10))
i-- i--
dAtA[i] = 0x3a dAtA[i] = 0x3a
} }
n10, err10 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) n11, err11 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err10 != nil { if err11 != nil {
return 0, err10 return 0, err11
} }
i -= n10 i -= n11
i = encodeVarintControl(dAtA, i, uint64(n10)) i = encodeVarintControl(dAtA, i, uint64(n11))
i-- i--
dAtA[i] = 0x32 dAtA[i] = 0x32
if m.Total != 0 { if m.Total != 0 {
@ -2627,12 +2648,12 @@ func (m *VertexLog) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i-- i--
dAtA[i] = 0x18 dAtA[i] = 0x18
} }
n11, err11 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) n12, err12 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err11 != nil { if err12 != nil {
return 0, err11 return 0, err12
} }
i -= n11 i -= n12
i = encodeVarintControl(dAtA, i, uint64(n11)) i = encodeVarintControl(dAtA, i, uint64(n12))
i-- i--
dAtA[i] = 0x12 dAtA[i] = 0x12
if len(m.Vertex) > 0 { if len(m.Vertex) > 0 {
@ -3215,6 +3236,10 @@ func (m *Vertex) Size() (n int) {
if l > 0 { if l > 0 {
n += 1 + l + sovControl(uint64(l)) n += 1 + l + sovControl(uint64(l))
} }
if m.ProgressGroup != nil {
l = m.ProgressGroup.Size()
n += 1 + l + sovControl(uint64(l))
}
if m.XXX_unrecognized != nil { if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized) n += len(m.XXX_unrecognized)
} }
@ -5954,6 +5979,42 @@ func (m *Vertex) Unmarshal(dAtA []byte) error {
} }
m.Error = string(dAtA[iNdEx:postIndex]) m.Error = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex iNdEx = postIndex
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ProgressGroup", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowControl
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthControl
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthControl
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.ProgressGroup == nil {
m.ProgressGroup = &pb.ProgressGroup{}
}
if err := m.ProgressGroup.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipControl(dAtA[iNdEx:]) skippy, err := skipControl(dAtA[iNdEx:])

@ -115,6 +115,7 @@ message Vertex {
google.protobuf.Timestamp started = 5 [(gogoproto.stdtime) = true ]; google.protobuf.Timestamp started = 5 [(gogoproto.stdtime) = true ];
google.protobuf.Timestamp completed = 6 [(gogoproto.stdtime) = true ]; google.protobuf.Timestamp completed = 6 [(gogoproto.stdtime) = true ];
string error = 7; // typed errors? string error = 7; // typed errors?
pb.ProgressGroup progressGroup = 8;
} }
message VertexStatus { message VertexStatus {

@ -1,3 +1,3 @@
package moby_buildkit_v1 //nolint:golint package moby_buildkit_v1 //nolint:revive
//go:generate protoc -I=. -I=../../../vendor/ -I=../../../../../../ --gogo_out=plugins=grpc:. control.proto //go:generate protoc -I=. -I=../../../vendor/ -I=../../../../../../ --gogo_out=plugins=grpc:. control.proto

@ -1,3 +1,3 @@
package moby_buildkit_v1_types //nolint:golint package moby_buildkit_v1_types //nolint:revive
//go:generate protoc -I=. -I=../../vendor/ -I=../../../../../ --gogo_out=plugins=grpc:. worker.proto //go:generate protoc -I=. -I=../../vendor/ -I=../../../../../ --gogo_out=plugins=grpc:. worker.proto

@ -26,6 +26,7 @@ import (
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
) )
type Client struct { type Client struct {
@ -102,7 +103,7 @@ func New(ctx context.Context, address string, opts ...ClientOpt) (*Client, error
gopts = append(gopts, grpc.WithContextDialer(dialFn)) gopts = append(gopts, grpc.WithContextDialer(dialFn))
} }
if needWithInsecure { if needWithInsecure {
gopts = append(gopts, grpc.WithInsecure()) gopts = append(gopts, grpc.WithTransportCredentials(insecure.NewCredentials()))
} }
if address == "" { if address == "" {
address = appdefaults.Address address = appdefaults.Address

@ -8,13 +8,14 @@ import (
) )
type Vertex struct { type Vertex struct {
Digest digest.Digest Digest digest.Digest
Inputs []digest.Digest Inputs []digest.Digest
Name string Name string
Started *time.Time Started *time.Time
Completed *time.Time Completed *time.Time
Cached bool Cached bool
Error string Error string
ProgressGroup *pb.ProgressGroup
} }
type VertexStatus struct { type VertexStatus struct {

@ -160,7 +160,6 @@ func (d *DefinitionOp) Marshal(ctx context.Context, c *Constraints) (digest.Dige
meta := d.metas[d.dgst] meta := d.metas[d.dgst]
return d.dgst, d.defs[d.dgst], &meta, d.sources[d.dgst], nil return d.dgst, d.defs[d.dgst], &meta, d.sources[d.dgst], nil
} }
func (d *DefinitionOp) Output() Output { func (d *DefinitionOp) Output() Output {

@ -0,0 +1,108 @@
package llb
import (
"context"
"github.com/moby/buildkit/solver/pb"
digest "github.com/opencontainers/go-digest"
)
type DiffOp struct {
MarshalCache
lower Output
upper Output
output Output
constraints Constraints
}
func NewDiff(lower, upper State, c Constraints) *DiffOp {
addCap(&c, pb.CapDiffOp)
op := &DiffOp{
lower: lower.Output(),
upper: upper.Output(),
constraints: c,
}
op.output = &output{vertex: op}
return op
}
func (m *DiffOp) Validate(ctx context.Context, constraints *Constraints) error {
return nil
}
func (m *DiffOp) Marshal(ctx context.Context, constraints *Constraints) (digest.Digest, []byte, *pb.OpMetadata, []*SourceLocation, error) {
if m.Cached(constraints) {
return m.Load()
}
if err := m.Validate(ctx, constraints); err != nil {
return "", nil, nil, nil, err
}
proto, md := MarshalConstraints(constraints, &m.constraints)
proto.Platform = nil // diff op is not platform specific
op := &pb.DiffOp{}
op.Lower = &pb.LowerDiffInput{Input: pb.InputIndex(len(proto.Inputs))}
if m.lower == nil {
op.Lower.Input = pb.Empty
} else {
pbLowerInput, err := m.lower.ToInput(ctx, constraints)
if err != nil {
return "", nil, nil, nil, err
}
proto.Inputs = append(proto.Inputs, pbLowerInput)
}
op.Upper = &pb.UpperDiffInput{Input: pb.InputIndex(len(proto.Inputs))}
if m.upper == nil {
op.Upper.Input = pb.Empty
} else {
pbUpperInput, err := m.upper.ToInput(ctx, constraints)
if err != nil {
return "", nil, nil, nil, err
}
proto.Inputs = append(proto.Inputs, pbUpperInput)
}
proto.Op = &pb.Op_Diff{Diff: op}
dt, err := proto.Marshal()
if err != nil {
return "", nil, nil, nil, err
}
m.Store(dt, md, m.constraints.SourceLocations, constraints)
return m.Load()
}
func (m *DiffOp) Output() Output {
return m.output
}
func (m *DiffOp) Inputs() (out []Output) {
if m.lower != nil {
out = append(out, m.lower)
}
if m.upper != nil {
out = append(out, m.upper)
}
return out
}
func Diff(lower, upper State, opts ...ConstraintsOpt) State {
if lower.Output() == nil {
if upper.Output() == nil {
// diff of scratch and scratch is scratch
return Scratch()
}
// diff of scratch and upper is just upper
return upper
}
var c Constraints
for _, o := range opts {
o.SetConstraintsOption(&c)
}
return NewState(NewDiff(lower, upper, c).Output())
}

@ -284,6 +284,12 @@ func (e *ExecOp) Marshal(ctx context.Context, c *Constraints) (digest.Digest, []
if len(e.secrets) > 0 { if len(e.secrets) > 0 {
addCap(&e.constraints, pb.CapExecMountSecret) addCap(&e.constraints, pb.CapExecMountSecret)
for _, s := range e.secrets {
if s.IsEnv {
addCap(&e.constraints, pb.CapExecSecretEnv)
break
}
}
} }
if len(e.ssh) > 0 { if len(e.ssh) > 0 {
@ -369,18 +375,26 @@ func (e *ExecOp) Marshal(ctx context.Context, c *Constraints) (digest.Digest, []
} }
for _, s := range e.secrets { for _, s := range e.secrets {
pm := &pb.Mount{ if s.IsEnv {
Dest: s.Target, peo.Secretenv = append(peo.Secretenv, &pb.SecretEnv{
MountType: pb.MountType_SECRET,
SecretOpt: &pb.SecretOpt{
ID: s.ID, ID: s.ID,
Uid: uint32(s.UID), Name: s.Target,
Gid: uint32(s.GID),
Optional: s.Optional, Optional: s.Optional,
Mode: uint32(s.Mode), })
}, } else {
pm := &pb.Mount{
Dest: s.Target,
MountType: pb.MountType_SECRET,
SecretOpt: &pb.SecretOpt{
ID: s.ID,
Uid: uint32(s.UID),
Gid: uint32(s.GID),
Optional: s.Optional,
Mode: uint32(s.Mode),
},
}
peo.Mounts = append(peo.Mounts, pm)
} }
peo.Mounts = append(peo.Mounts, pm)
} }
for _, s := range e.ssh { for _, s := range e.ssh {
@ -661,6 +675,7 @@ type SecretInfo struct {
UID int UID int
GID int GID int
Optional bool Optional bool
IsEnv bool
} }
var SecretOptional = secretOptionFunc(func(si *SecretInfo) { var SecretOptional = secretOptionFunc(func(si *SecretInfo) {
@ -673,6 +688,13 @@ func SecretID(id string) SecretOption {
}) })
} }
// SecretAsEnv defines if the secret should be added as an environment variable
func SecretAsEnv(v bool) SecretOption {
return secretOptionFunc(func(si *SecretInfo) {
si.IsEnv = v
})
}
func SecretFileOpt(uid, gid, mode int) SecretOption { func SecretFileOpt(uid, gid, mode int) SecretOption {
return secretOptionFunc(func(si *SecretInfo) { return secretOptionFunc(func(si *SecretInfo) {
si.UID = uid si.UID = uid

@ -683,12 +683,18 @@ func (f *FileOp) Marshal(ctx context.Context, c *Constraints) (digest.Digest, []
f.constraints.Platform = p f.constraints.Platform = p
} }
state := newMarshalState(ctx)
for _, st := range state.actions {
if adder, isCapAdder := st.action.(capAdder); isCapAdder {
adder.addCaps(f)
}
}
pop, md := MarshalConstraints(c, &f.constraints) pop, md := MarshalConstraints(c, &f.constraints)
pop.Op = &pb.Op_File{ pop.Op = &pb.Op_File{
File: pfo, File: pfo,
} }
state := newMarshalState(ctx)
_, err := state.add(f.action, c) _, err := state.add(f.action, c)
if err != nil { if err != nil {
return "", nil, nil, nil, err return "", nil, nil, nil, err
@ -696,10 +702,6 @@ func (f *FileOp) Marshal(ctx context.Context, c *Constraints) (digest.Digest, []
pop.Inputs = state.inputs pop.Inputs = state.inputs
for i, st := range state.actions { for i, st := range state.actions {
if adder, isCapAdder := st.action.(capAdder); isCapAdder {
adder.addCaps(f)
}
output := pb.OutputIndex(-1) output := pb.OutputIndex(-1)
if i+1 == len(state.actions) { if i+1 == len(state.actions) {
output = 0 output = 0

@ -505,6 +505,10 @@ func mergeMetadata(m1, m2 pb.OpMetadata) pb.OpMetadata {
m1.Caps[k] = true m1.Caps[k] = true
} }
if m2.ProgressGroup != nil {
m1.ProgressGroup = m2.ProgressGroup
}
return m1 return m1
} }
@ -594,6 +598,12 @@ func LocalUniqueID(v string) ConstraintsOpt {
}) })
} }
func ProgressGroup(id, name string) ConstraintsOpt {
return constraintsOptFunc(func(c *Constraints) {
c.Metadata.ProgressGroup = &pb.ProgressGroup{Id: id, Name: name}
})
}
var ( var (
LinuxAmd64 = Platform(ocispecs.Platform{OS: "linux", Architecture: "amd64"}) LinuxAmd64 = Platform(ocispecs.Platform{OS: "linux", Architecture: "amd64"})
LinuxArmhf = Platform(ocispecs.Platform{OS: "linux", Architecture: "arm", Variant: "v7"}) LinuxArmhf = Platform(ocispecs.Platform{OS: "linux", Architecture: "arm", Variant: "v7"})

@ -263,13 +263,14 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
s := SolveStatus{} s := SolveStatus{}
for _, v := range resp.Vertexes { for _, v := range resp.Vertexes {
s.Vertexes = append(s.Vertexes, &Vertex{ s.Vertexes = append(s.Vertexes, &Vertex{
Digest: v.Digest, Digest: v.Digest,
Inputs: v.Inputs, Inputs: v.Inputs,
Name: v.Name, Name: v.Name,
Started: v.Started, Started: v.Started,
Completed: v.Completed, Completed: v.Completed,
Error: v.Error, Error: v.Error,
Cached: v.Cached, Cached: v.Cached,
ProgressGroup: v.ProgressGroup,
}) })
} }
for _, v := range resp.Statuses { for _, v := range resp.Statuses {
@ -459,7 +460,6 @@ func parseCacheOptions(ctx context.Context, opt SolveOpt) (*cacheOptions, error)
} }
} }
contentStores["local:"+csDir] = cs contentStores["local:"+csDir] = cs
} }
if im.Type == "registry" { if im.Type == "registry" {
legacyImportRef := attrs["ref"] legacyImportRef := attrs["ref"]

@ -3,6 +3,7 @@ package client
import ( import (
"context" "context"
"io" "io"
"syscall"
"github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/solver/pb" "github.com/moby/buildkit/solver/pb"
@ -76,7 +77,7 @@ type WinSize struct {
type ContainerProcess interface { type ContainerProcess interface {
Wait() error Wait() error
Resize(ctx context.Context, size WinSize) error Resize(ctx context.Context, size WinSize) error
// TODO Signal(ctx context.Context, sig os.Signal) Signal(ctx context.Context, sig syscall.Signal) error
} }
type Reference interface { type Reference interface {

@ -9,10 +9,9 @@ import (
"os" "os"
"strings" "strings"
"sync" "sync"
"syscall"
"time" "time"
"github.com/moby/buildkit/util/bklog"
"github.com/gogo/googleapis/google/rpc" "github.com/gogo/googleapis/google/rpc"
gogotypes "github.com/gogo/protobuf/types" gogotypes "github.com/gogo/protobuf/types"
"github.com/golang/protobuf/ptypes/any" "github.com/golang/protobuf/ptypes/any"
@ -22,7 +21,9 @@ import (
"github.com/moby/buildkit/identity" "github.com/moby/buildkit/identity"
opspb "github.com/moby/buildkit/solver/pb" opspb "github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/util/apicaps" "github.com/moby/buildkit/util/apicaps"
"github.com/moby/buildkit/util/bklog"
"github.com/moby/buildkit/util/grpcerrors" "github.com/moby/buildkit/util/grpcerrors"
"github.com/moby/sys/signal"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
"github.com/pkg/errors" "github.com/pkg/errors"
fstypes "github.com/tonistiigi/fsutil/types" fstypes "github.com/tonistiigi/fsutil/types"
@ -30,6 +31,7 @@ import (
spb "google.golang.org/genproto/googleapis/rpc/status" spb "google.golang.org/genproto/googleapis/rpc/status"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
) )
@ -642,6 +644,8 @@ func debugMessage(msg *pb.ExecMessage) string {
return fmt.Sprintf("File Message %s, fd=%d, %d bytes", msg.ProcessID, m.File.Fd, len(m.File.Data)) return fmt.Sprintf("File Message %s, fd=%d, %d bytes", msg.ProcessID, m.File.Fd, len(m.File.Data))
case *pb.ExecMessage_Resize: case *pb.ExecMessage_Resize:
return fmt.Sprintf("Resize Message %s", msg.ProcessID) return fmt.Sprintf("Resize Message %s", msg.ProcessID)
case *pb.ExecMessage_Signal:
return fmt.Sprintf("Signal Message %s: %s", msg.ProcessID, m.Signal.Name)
case *pb.ExecMessage_Started: case *pb.ExecMessage_Started:
return fmt.Sprintf("Started Message %s", msg.ProcessID) return fmt.Sprintf("Started Message %s", msg.ProcessID)
case *pb.ExecMessage_Exit: case *pb.ExecMessage_Exit:
@ -963,6 +967,29 @@ func (ctrProc *containerProcess) Resize(_ context.Context, size client.WinSize)
}) })
} }
var sigToName = map[syscall.Signal]string{}
func init() {
for name, value := range signal.SignalMap {
sigToName[value] = name
}
}
func (ctrProc *containerProcess) Signal(_ context.Context, sig syscall.Signal) error {
name := sigToName[sig]
if name == "" {
return errors.Errorf("unknown signal %v", sig)
}
return ctrProc.execMsgs.Send(&pb.ExecMessage{
ProcessID: ctrProc.id,
Input: &pb.ExecMessage_Signal{
Signal: &pb.SignalMessage{
Name: name,
},
},
})
}
type reference struct { type reference struct {
c *grpcClient c *grpcClient
id string id string
@ -1042,7 +1069,7 @@ func grpcClientConn(ctx context.Context) (context.Context, *grpc.ClientConn, err
return stdioConn(), nil return stdioConn(), nil
}) })
cc, err := grpc.DialContext(ctx, "localhost", dialOpt, grpc.WithInsecure(), grpc.WithUnaryInterceptor(grpcerrors.UnaryClientInterceptor), grpc.WithStreamInterceptor(grpcerrors.StreamClientInterceptor)) cc, err := grpc.DialContext(ctx, "localhost", dialOpt, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithUnaryInterceptor(grpcerrors.UnaryClientInterceptor), grpc.WithStreamInterceptor(grpcerrors.StreamClientInterceptor))
if err != nil { if err != nil {
return nil, nil, errors.Wrap(err, "failed to create grpc client") return nil, nil, errors.Wrap(err, "failed to create grpc client")
} }

@ -1,4 +1,4 @@
package moby_buildkit_v1_frontend //nolint:golint package moby_buildkit_v1_frontend //nolint:revive
import "github.com/moby/buildkit/util/apicaps" import "github.com/moby/buildkit/util/apicaps"
@ -44,6 +44,10 @@ const (
// /etc/hosts for containers created via gateway exec. // /etc/hosts for containers created via gateway exec.
CapGatewayExecExtraHosts apicaps.CapID = "gateway.exec.extrahosts" CapGatewayExecExtraHosts apicaps.CapID = "gateway.exec.extrahosts"
// CapGatewayExecExtraHosts is the capability to send signals to a process
// created via gateway exec.
CapGatewayExecSignals apicaps.CapID = "gateway.exec.signals"
// CapFrontendCaps can be used to check that frontends define support for certain capabilities // CapFrontendCaps can be used to check that frontends define support for certain capabilities
CapFrontendCaps apicaps.CapID = "frontend.caps" CapFrontendCaps apicaps.CapID = "frontend.caps"
@ -57,7 +61,6 @@ const (
) )
func init() { func init() {
Caps.Init(apicaps.Cap{ Caps.Init(apicaps.Cap{
ID: CapSolveBase, ID: CapSolveBase,
Enabled: true, Enabled: true,
@ -170,6 +173,13 @@ func init() {
Status: apicaps.CapStatusExperimental, Status: apicaps.CapStatusExperimental,
}) })
Caps.Init(apicaps.Cap{
ID: CapGatewayExecSignals,
Name: "gateway exec signals",
Enabled: true,
Status: apicaps.CapStatusExperimental,
})
Caps.Init(apicaps.Cap{ Caps.Init(apicaps.Cap{
ID: CapFrontendCaps, ID: CapFrontendCaps,
Name: "frontend capabilities", Name: "frontend capabilities",

@ -1,4 +1,4 @@
package moby_buildkit_v1_frontend //nolint:golint package moby_buildkit_v1_frontend //nolint:revive
import ( import (
"fmt" "fmt"

@ -1679,6 +1679,7 @@ type ExecMessage struct {
// *ExecMessage_Started // *ExecMessage_Started
// *ExecMessage_Exit // *ExecMessage_Exit
// *ExecMessage_Done // *ExecMessage_Done
// *ExecMessage_Signal
Input isExecMessage_Input `protobuf_oneof:"Input"` Input isExecMessage_Input `protobuf_oneof:"Input"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
@ -1742,6 +1743,9 @@ type ExecMessage_Exit struct {
type ExecMessage_Done struct { type ExecMessage_Done struct {
Done *DoneMessage `protobuf:"bytes,7,opt,name=Done,proto3,oneof" json:"Done,omitempty"` Done *DoneMessage `protobuf:"bytes,7,opt,name=Done,proto3,oneof" json:"Done,omitempty"`
} }
type ExecMessage_Signal struct {
Signal *SignalMessage `protobuf:"bytes,8,opt,name=Signal,proto3,oneof" json:"Signal,omitempty"`
}
func (*ExecMessage_Init) isExecMessage_Input() {} func (*ExecMessage_Init) isExecMessage_Input() {}
func (*ExecMessage_File) isExecMessage_Input() {} func (*ExecMessage_File) isExecMessage_Input() {}
@ -1749,6 +1753,7 @@ func (*ExecMessage_Resize) isExecMessage_Input() {}
func (*ExecMessage_Started) isExecMessage_Input() {} func (*ExecMessage_Started) isExecMessage_Input() {}
func (*ExecMessage_Exit) isExecMessage_Input() {} func (*ExecMessage_Exit) isExecMessage_Input() {}
func (*ExecMessage_Done) isExecMessage_Input() {} func (*ExecMessage_Done) isExecMessage_Input() {}
func (*ExecMessage_Signal) isExecMessage_Input() {}
func (m *ExecMessage) GetInput() isExecMessage_Input { func (m *ExecMessage) GetInput() isExecMessage_Input {
if m != nil { if m != nil {
@ -1806,6 +1811,13 @@ func (m *ExecMessage) GetDone() *DoneMessage {
return nil return nil
} }
func (m *ExecMessage) GetSignal() *SignalMessage {
if x, ok := m.GetInput().(*ExecMessage_Signal); ok {
return x.Signal
}
return nil
}
// XXX_OneofWrappers is for the internal use of the proto package. // XXX_OneofWrappers is for the internal use of the proto package.
func (*ExecMessage) XXX_OneofWrappers() []interface{} { func (*ExecMessage) XXX_OneofWrappers() []interface{} {
return []interface{}{ return []interface{}{
@ -1815,6 +1827,7 @@ func (*ExecMessage) XXX_OneofWrappers() []interface{} {
(*ExecMessage_Started)(nil), (*ExecMessage_Started)(nil),
(*ExecMessage_Exit)(nil), (*ExecMessage_Exit)(nil),
(*ExecMessage_Done)(nil), (*ExecMessage_Done)(nil),
(*ExecMessage_Signal)(nil),
} }
} }
@ -2148,6 +2161,55 @@ func (m *ResizeMessage) GetCols() uint32 {
return 0 return 0
} }
type SignalMessage struct {
// we only send name (ie HUP, INT) because the int values
// are platform dependent.
Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SignalMessage) Reset() { *m = SignalMessage{} }
func (m *SignalMessage) String() string { return proto.CompactTextString(m) }
func (*SignalMessage) ProtoMessage() {}
func (*SignalMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_f1a937782ebbded5, []int{35}
}
func (m *SignalMessage) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *SignalMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_SignalMessage.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *SignalMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_SignalMessage.Merge(m, src)
}
func (m *SignalMessage) XXX_Size() int {
return m.Size()
}
func (m *SignalMessage) XXX_DiscardUnknown() {
xxx_messageInfo_SignalMessage.DiscardUnknown(m)
}
var xxx_messageInfo_SignalMessage proto.InternalMessageInfo
func (m *SignalMessage) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func init() { func init() {
proto.RegisterType((*Result)(nil), "moby.buildkit.v1.frontend.Result") proto.RegisterType((*Result)(nil), "moby.buildkit.v1.frontend.Result")
proto.RegisterMapType((map[string][]byte)(nil), "moby.buildkit.v1.frontend.Result.MetadataEntry") proto.RegisterMapType((map[string][]byte)(nil), "moby.buildkit.v1.frontend.Result.MetadataEntry")
@ -2191,140 +2253,143 @@ func init() {
proto.RegisterType((*DoneMessage)(nil), "moby.buildkit.v1.frontend.DoneMessage") proto.RegisterType((*DoneMessage)(nil), "moby.buildkit.v1.frontend.DoneMessage")
proto.RegisterType((*FdMessage)(nil), "moby.buildkit.v1.frontend.FdMessage") proto.RegisterType((*FdMessage)(nil), "moby.buildkit.v1.frontend.FdMessage")
proto.RegisterType((*ResizeMessage)(nil), "moby.buildkit.v1.frontend.ResizeMessage") proto.RegisterType((*ResizeMessage)(nil), "moby.buildkit.v1.frontend.ResizeMessage")
proto.RegisterType((*SignalMessage)(nil), "moby.buildkit.v1.frontend.SignalMessage")
} }
func init() { proto.RegisterFile("gateway.proto", fileDescriptor_f1a937782ebbded5) } func init() { proto.RegisterFile("gateway.proto", fileDescriptor_f1a937782ebbded5) }
var fileDescriptor_f1a937782ebbded5 = []byte{ var fileDescriptor_f1a937782ebbded5 = []byte{
// 2048 bytes of a gzipped FileDescriptorProto // 2078 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xcd, 0x6f, 0x1b, 0xc7, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0x4f, 0x6f, 0x1b, 0xc7,
0x15, 0xf7, 0x8a, 0x94, 0x48, 0x3e, 0x7e, 0x58, 0x19, 0xa7, 0xe9, 0x7a, 0x11, 0x38, 0xca, 0x22, 0x15, 0xd7, 0x8a, 0x94, 0x48, 0x3e, 0xfe, 0xb1, 0x32, 0x4e, 0x53, 0x7a, 0x11, 0x38, 0xca, 0x36,
0x55, 0x69, 0x47, 0x59, 0xa6, 0x72, 0x02, 0xb9, 0x72, 0x90, 0xd4, 0xfa, 0x82, 0x94, 0x48, 0xb2, 0x55, 0x69, 0x47, 0x59, 0xa6, 0x72, 0x02, 0xb9, 0x72, 0x90, 0xd4, 0xfa, 0x07, 0x29, 0x91, 0x64,
0x3a, 0x4a, 0x61, 0x20, 0x48, 0x81, 0xae, 0xb8, 0x43, 0x7a, 0xe1, 0xd5, 0xce, 0x76, 0x76, 0x68, 0x75, 0x94, 0xc2, 0x40, 0x90, 0x02, 0x5d, 0x71, 0x87, 0xf4, 0xc2, 0xab, 0x9d, 0xed, 0xec, 0xd0,
0x59, 0xc9, 0xa5, 0xbd, 0xf5, 0x58, 0xa0, 0x40, 0xaf, 0x05, 0xfa, 0x17, 0xf4, 0xd2, 0x6b, 0xcf, 0xb2, 0x92, 0x4b, 0x7b, 0xeb, 0xb1, 0x40, 0x81, 0x5e, 0x0b, 0xf4, 0x13, 0xf4, 0x13, 0xf4, 0x9c,
0x39, 0xf6, 0x58, 0xf4, 0x10, 0x14, 0xfe, 0x1b, 0x8a, 0x9e, 0x8b, 0x37, 0x33, 0x4b, 0x2e, 0x29, 0x63, 0x8f, 0x45, 0x0f, 0x41, 0xe1, 0xcf, 0x50, 0x14, 0xe8, 0x2d, 0x78, 0x33, 0xb3, 0xe4, 0x92,
0x6a, 0x29, 0x22, 0x27, 0xee, 0xbc, 0x79, 0xbf, 0x37, 0xef, 0x6b, 0xde, 0x7b, 0x43, 0x68, 0xf6, 0xa2, 0x96, 0x24, 0x7c, 0xe2, 0xcc, 0xdb, 0xf7, 0x7b, 0xf3, 0xfe, 0xcd, 0x7b, 0x6f, 0x08, 0xf5,
0x7d, 0xc9, 0x2e, 0xfc, 0x4b, 0x2f, 0x11, 0x5c, 0x72, 0x72, 0xf7, 0x9c, 0x9f, 0x5d, 0x7a, 0x67, 0x9e, 0x27, 0xd9, 0xa5, 0x77, 0xe5, 0xc6, 0x82, 0x4b, 0x4e, 0xee, 0x5c, 0xf0, 0xf3, 0x2b, 0xf7,
0x83, 0x30, 0x0a, 0x5e, 0x84, 0xd2, 0x7b, 0xf9, 0x33, 0xaf, 0x27, 0x78, 0x2c, 0x59, 0x1c, 0x38, 0xbc, 0x1f, 0x84, 0xfe, 0xf3, 0x40, 0xba, 0x2f, 0x7e, 0xee, 0x76, 0x05, 0x8f, 0x24, 0x8b, 0x7c,
0x1f, 0xf4, 0x43, 0xf9, 0x7c, 0x70, 0xe6, 0x75, 0xf9, 0x79, 0xa7, 0xcf, 0xfb, 0xbc, 0xa3, 0x10, 0xfb, 0x83, 0x5e, 0x20, 0x9f, 0xf5, 0xcf, 0xdd, 0x0e, 0xbf, 0x68, 0xf7, 0x78, 0x8f, 0xb7, 0x15,
0x67, 0x83, 0x9e, 0x5a, 0xa9, 0x85, 0xfa, 0xd2, 0x92, 0x9c, 0xf5, 0x49, 0xf6, 0x3e, 0xe7, 0xfd, 0xe2, 0xbc, 0xdf, 0x55, 0x3b, 0xb5, 0x51, 0x2b, 0x2d, 0xc9, 0xde, 0x18, 0x67, 0xef, 0x71, 0xde,
0x88, 0xf9, 0x49, 0x98, 0x9a, 0xcf, 0x8e, 0x48, 0xba, 0x9d, 0x54, 0xfa, 0x72, 0x90, 0x1a, 0xcc, 0x0b, 0x99, 0x17, 0x07, 0x89, 0x59, 0xb6, 0x45, 0xdc, 0x69, 0x27, 0xd2, 0x93, 0xfd, 0xc4, 0x60,
0x5a, 0x0e, 0x83, 0x8a, 0x74, 0x32, 0x45, 0x3a, 0x29, 0x8f, 0x5e, 0x32, 0xd1, 0x49, 0xce, 0x3a, 0xd6, 0x33, 0x18, 0x54, 0xa4, 0x9d, 0x2a, 0xd2, 0x4e, 0x78, 0xf8, 0x82, 0x89, 0x76, 0x7c, 0xde,
0x3c, 0xc9, 0xb8, 0x3b, 0xd7, 0x72, 0xfb, 0x49, 0xd8, 0x91, 0x97, 0x09, 0x4b, 0x3b, 0x17, 0x5c, 0xe6, 0x71, 0xca, 0xdd, 0xbe, 0x91, 0xdb, 0x8b, 0x83, 0xb6, 0xbc, 0x8a, 0x59, 0xd2, 0xbe, 0xe4,
0xbc, 0x60, 0xc2, 0x00, 0x1e, 0x5e, 0x0b, 0x18, 0xc8, 0x30, 0x42, 0x54, 0xd7, 0x4f, 0x52, 0x3c, 0xe2, 0x39, 0x13, 0x06, 0xf0, 0xe0, 0x46, 0x40, 0x5f, 0x06, 0x21, 0xa2, 0x3a, 0x5e, 0x9c, 0xe0,
0x04, 0x7f, 0x0d, 0x28, 0x6f, 0xb6, 0xe4, 0x71, 0x98, 0xca, 0x30, 0xec, 0x87, 0x9d, 0x5e, 0xaa, 0x21, 0xf8, 0x6b, 0x40, 0x59, 0xb3, 0x25, 0x8f, 0x82, 0x44, 0x06, 0x41, 0x2f, 0x68, 0x77, 0x13,
0x30, 0xfa, 0x14, 0x34, 0x42, 0xb3, 0xbb, 0x7f, 0x28, 0xc1, 0x12, 0x65, 0xe9, 0x20, 0x92, 0x64, 0x85, 0xd1, 0xa7, 0xa0, 0x11, 0x9a, 0xdd, 0xf9, 0x63, 0x01, 0x96, 0x29, 0x4b, 0xfa, 0xa1, 0x24,
0x15, 0x9a, 0x82, 0xf5, 0x76, 0x58, 0x22, 0x58, 0xd7, 0x97, 0x2c, 0xb0, 0xad, 0x15, 0xab, 0x5d, 0x6b, 0x50, 0x17, 0xac, 0xbb, 0xcb, 0x62, 0xc1, 0x3a, 0x9e, 0x64, 0x7e, 0xd3, 0x5a, 0xb5, 0x5a,
0xdb, 0xbf, 0x45, 0xc7, 0xc9, 0xe4, 0x57, 0xd0, 0x12, 0xac, 0x97, 0xe6, 0x18, 0x17, 0x56, 0xac, 0x95, 0x83, 0x05, 0x3a, 0x4a, 0x26, 0xbf, 0x86, 0x86, 0x60, 0xdd, 0x24, 0xc3, 0xb8, 0xb8, 0x6a,
0x76, 0x7d, 0xfd, 0x7d, 0xef, 0xda, 0x60, 0x78, 0x94, 0xf5, 0x8e, 0xfc, 0x64, 0x04, 0xd9, 0xbf, 0xb5, 0xaa, 0x1b, 0xef, 0xbb, 0x37, 0x06, 0xc3, 0xa5, 0xac, 0x7b, 0xec, 0xc5, 0x43, 0xc8, 0xc1,
0x45, 0x27, 0x84, 0x90, 0x75, 0x28, 0x09, 0xd6, 0xb3, 0x4b, 0x4a, 0xd6, 0xbd, 0x62, 0x59, 0xfb, 0x02, 0x1d, 0x13, 0x42, 0x36, 0xa0, 0x20, 0x58, 0xb7, 0x59, 0x50, 0xb2, 0xee, 0xe6, 0xcb, 0x3a,
0xb7, 0x28, 0x32, 0x93, 0x0d, 0x28, 0xa3, 0x14, 0xbb, 0xac, 0x40, 0xef, 0xce, 0x54, 0x60, 0xff, 0x58, 0xa0, 0xc8, 0x4c, 0x36, 0xa1, 0x88, 0x52, 0x9a, 0x45, 0x05, 0x7a, 0x77, 0xaa, 0x02, 0x07,
0x16, 0x55, 0x00, 0xf2, 0x05, 0x54, 0xcf, 0x99, 0xf4, 0x03, 0x5f, 0xfa, 0x36, 0xac, 0x94, 0xda, 0x0b, 0x54, 0x01, 0xc8, 0x17, 0x50, 0xbe, 0x60, 0xd2, 0xf3, 0x3d, 0xe9, 0x35, 0x61, 0xb5, 0xd0,
0xf5, 0xf5, 0x4e, 0x21, 0x18, 0x1d, 0xe4, 0x1d, 0x19, 0xc4, 0x6e, 0x2c, 0xc5, 0x25, 0x1d, 0x0a, 0xaa, 0x6e, 0xb4, 0x73, 0xc1, 0xe8, 0x20, 0xf7, 0xd8, 0x20, 0xf6, 0x22, 0x29, 0xae, 0xe8, 0x40,
0x70, 0x1e, 0x43, 0x73, 0x6c, 0x8b, 0x2c, 0x43, 0xe9, 0x05, 0xbb, 0xd4, 0xfe, 0xa3, 0xf8, 0x49, 0x80, 0xfd, 0x08, 0xea, 0x23, 0x9f, 0xc8, 0x0a, 0x14, 0x9e, 0xb3, 0x2b, 0xed, 0x3f, 0x8a, 0x4b,
0xde, 0x84, 0xc5, 0x97, 0x7e, 0x34, 0x60, 0xca, 0x55, 0x0d, 0xaa, 0x17, 0x9b, 0x0b, 0x8f, 0xac, 0xf2, 0x26, 0x2c, 0xbd, 0xf0, 0xc2, 0x3e, 0x53, 0xae, 0xaa, 0x51, 0xbd, 0xd9, 0x5a, 0x7c, 0x68,
0xad, 0x2a, 0x2c, 0x09, 0x25, 0xde, 0xfd, 0xb3, 0x05, 0xcb, 0x93, 0x7e, 0x22, 0x07, 0xc6, 0x42, 0x6d, 0x97, 0x61, 0x59, 0x28, 0xf1, 0xce, 0x5f, 0x2c, 0x58, 0x19, 0xf7, 0x13, 0x39, 0x34, 0x16,
0x4b, 0x29, 0xf9, 0xf1, 0x1c, 0x2e, 0x46, 0x42, 0xaa, 0x55, 0x55, 0x22, 0x9c, 0x0d, 0xa8, 0x0d, 0x5a, 0x4a, 0xc9, 0x8f, 0xe7, 0x70, 0x31, 0x12, 0x12, 0xad, 0xaa, 0x12, 0x61, 0x6f, 0x42, 0x65,
0x49, 0xb3, 0x54, 0xac, 0xe5, 0x54, 0x74, 0x37, 0xa0, 0x44, 0x59, 0x8f, 0xb4, 0x60, 0x21, 0x34, 0x40, 0x9a, 0xa6, 0x62, 0x25, 0xa3, 0xa2, 0xb3, 0x09, 0x05, 0xca, 0xba, 0xa4, 0x01, 0x8b, 0x81,
0x49, 0x41, 0x17, 0xc2, 0x80, 0xac, 0x40, 0x29, 0x60, 0x3d, 0x13, 0xfc, 0x96, 0x97, 0x9c, 0x79, 0x49, 0x0a, 0xba, 0x18, 0xf8, 0x64, 0x15, 0x0a, 0x3e, 0xeb, 0x9a, 0xe0, 0x37, 0xdc, 0xf8, 0xdc,
0x3b, 0xac, 0x17, 0xc6, 0xa1, 0x0c, 0x79, 0x4c, 0x71, 0xcb, 0xfd, 0xab, 0x85, 0xc9, 0x85, 0x6a, 0xdd, 0x65, 0xdd, 0x20, 0x0a, 0x64, 0xc0, 0x23, 0x8a, 0x9f, 0x9c, 0xbf, 0x59, 0x98, 0x5c, 0xa8,
0x91, 0xcf, 0xc6, 0xec, 0x98, 0x9d, 0x2a, 0x57, 0xb4, 0x7f, 0x56, 0xac, 0xfd, 0x47, 0x79, 0xed, 0x16, 0xf9, 0x6c, 0xc4, 0x8e, 0xe9, 0xa9, 0x72, 0x4d, 0xfb, 0xa7, 0xf9, 0xda, 0x7f, 0x94, 0xd5,
0x67, 0xe6, 0x4f, 0xde, 0x3a, 0x09, 0x4d, 0xca, 0xe4, 0x40, 0xc4, 0x94, 0xfd, 0x76, 0xc0, 0x52, 0x7e, 0x6a, 0xfe, 0x64, 0xad, 0x93, 0x50, 0xa7, 0x4c, 0xf6, 0x45, 0x44, 0xd9, 0xef, 0xfa, 0x2c,
0x49, 0x7e, 0x9e, 0x45, 0x44, 0xc9, 0x9f, 0x95, 0x56, 0xc8, 0x48, 0x0d, 0x80, 0xb4, 0x61, 0x91, 0x91, 0xe4, 0x17, 0x69, 0x44, 0x94, 0xfc, 0x69, 0x69, 0x85, 0x8c, 0xd4, 0x00, 0x48, 0x0b, 0x96,
0x09, 0xc1, 0x85, 0xd1, 0x82, 0x78, 0xba, 0x72, 0x78, 0x22, 0xe9, 0x7a, 0xa7, 0xaa, 0x72, 0x50, 0x98, 0x10, 0x5c, 0x18, 0x2d, 0x88, 0xab, 0x2b, 0x87, 0x2b, 0xe2, 0x8e, 0x7b, 0xa6, 0x2a, 0x07,
0xcd, 0xe0, 0x2e, 0x43, 0x2b, 0x3b, 0x35, 0x4d, 0x78, 0x9c, 0x32, 0xf7, 0x36, 0x34, 0x0f, 0xe2, 0xd5, 0x0c, 0xce, 0x0a, 0x34, 0xd2, 0x53, 0x93, 0x98, 0x47, 0x09, 0x73, 0x6e, 0x41, 0xfd, 0x30,
0x64, 0x20, 0x53, 0xa3, 0x87, 0xfb, 0x0f, 0x0b, 0x5a, 0x19, 0x45, 0xf3, 0x90, 0xaf, 0xa1, 0x3e, 0x8a, 0xfb, 0x32, 0x31, 0x7a, 0x38, 0xff, 0xb0, 0xa0, 0x91, 0x52, 0x34, 0x0f, 0xf9, 0x1a, 0xaa,
0xf2, 0x71, 0xe6, 0xcc, 0xcd, 0x02, 0xfd, 0xc6, 0xf1, 0xb9, 0x00, 0x19, 0xdf, 0xe6, 0xc5, 0x39, 0x43, 0x1f, 0xa7, 0xce, 0xdc, 0xca, 0xd1, 0x6f, 0x14, 0x9f, 0x09, 0x90, 0xf1, 0x6d, 0x56, 0x9c,
0xc7, 0xb0, 0x3c, 0xc9, 0x30, 0xc5, 0xd3, 0xef, 0x8d, 0x7b, 0x7a, 0x32, 0xf0, 0x39, 0xcf, 0xfe, 0x7d, 0x02, 0x2b, 0xe3, 0x0c, 0x13, 0x3c, 0xfd, 0xde, 0xa8, 0xa7, 0xc7, 0x03, 0x9f, 0xf1, 0xec,
0xc9, 0x82, 0xbb, 0x94, 0xa9, 0x52, 0x78, 0x70, 0xee, 0xf7, 0xd9, 0x36, 0x8f, 0x7b, 0x61, 0x3f, 0x9f, 0x2d, 0xb8, 0x43, 0x99, 0x2a, 0x85, 0x87, 0x17, 0x5e, 0x8f, 0xed, 0xf0, 0xa8, 0x1b, 0xf4,
0x73, 0xf3, 0xb2, 0xca, 0xaa, 0x4c, 0x32, 0x26, 0x58, 0x1b, 0xaa, 0x27, 0x91, 0x2f, 0x7b, 0x5c, 0x52, 0x37, 0xaf, 0xa8, 0xac, 0x4a, 0x25, 0x63, 0x82, 0xb5, 0xa0, 0x7c, 0x1a, 0x7a, 0xb2, 0xcb,
0x9c, 0x1b, 0xe1, 0x0d, 0x14, 0x9e, 0xd1, 0xe8, 0x70, 0x97, 0xac, 0x40, 0xdd, 0x08, 0x3e, 0xe2, 0xc5, 0x85, 0x11, 0x5e, 0x43, 0xe1, 0x29, 0x8d, 0x0e, 0xbe, 0x92, 0x55, 0xa8, 0x1a, 0xc1, 0xc7,
0x01, 0x53, 0x35, 0xa3, 0x46, 0xf3, 0x24, 0x62, 0x43, 0xe5, 0x90, 0xf7, 0x8f, 0xfd, 0x73, 0xa6, 0xdc, 0x67, 0xaa, 0x66, 0x54, 0x68, 0x96, 0x44, 0x9a, 0x50, 0x3a, 0xe2, 0xbd, 0x13, 0xef, 0x82,
0x8a, 0x43, 0x8d, 0x66, 0x4b, 0xf7, 0x77, 0x16, 0x38, 0xd3, 0xb4, 0x32, 0x2e, 0xfe, 0x1c, 0x96, 0xa9, 0xe2, 0x50, 0xa1, 0xe9, 0xd6, 0xf9, 0xbd, 0x05, 0xf6, 0x24, 0xad, 0x8c, 0x8b, 0x3f, 0x87,
0x76, 0xc2, 0x3e, 0x4b, 0x75, 0xf4, 0x6b, 0x5b, 0xeb, 0xdf, 0x7d, 0xff, 0xce, 0xad, 0x7f, 0x7f, 0xe5, 0xdd, 0xa0, 0xc7, 0x12, 0x1d, 0xfd, 0xca, 0xf6, 0xc6, 0x77, 0xdf, 0xbf, 0xb3, 0xf0, 0xef,
0xff, 0xce, 0x83, 0x5c, 0x5d, 0xe5, 0x09, 0x8b, 0xbb, 0x3c, 0x96, 0x7e, 0x18, 0x33, 0x81, 0xed, 0xef, 0xdf, 0xb9, 0x9f, 0xa9, 0xab, 0x3c, 0x66, 0x51, 0x87, 0x47, 0xd2, 0x0b, 0x22, 0x26, 0xb0,
0xe1, 0x83, 0x40, 0x41, 0x3c, 0x8d, 0xa4, 0x46, 0x02, 0x79, 0x0b, 0x96, 0xb4, 0x74, 0x73, 0xed, 0x3d, 0x7c, 0xe0, 0x2b, 0x88, 0xab, 0x91, 0xd4, 0x48, 0x20, 0x6f, 0xc1, 0xb2, 0x96, 0x6e, 0xae,
0xcd, 0xca, 0xfd, 0xef, 0x22, 0x34, 0x4e, 0x51, 0x81, 0xcc, 0x17, 0x1e, 0xc0, 0xc8, 0x85, 0x26, 0xbd, 0xd9, 0x39, 0xff, 0x5d, 0x82, 0xda, 0x19, 0x2a, 0x90, 0xfa, 0xc2, 0x05, 0x18, 0xba, 0xd0,
0xed, 0x26, 0x1d, 0x9b, 0xe3, 0x20, 0x0e, 0x54, 0xf7, 0x4c, 0x88, 0xcd, 0x75, 0x1d, 0xae, 0xc9, 0xa4, 0xdd, 0xb8, 0x63, 0x33, 0x1c, 0xc4, 0x86, 0xf2, 0xbe, 0x09, 0xb1, 0xb9, 0xae, 0x83, 0x3d,
0x57, 0x50, 0xcf, 0xbe, 0x9f, 0x26, 0xd2, 0x2e, 0xa9, 0x1c, 0x79, 0x54, 0x90, 0x23, 0x79, 0x4d, 0xf9, 0x0a, 0xaa, 0xe9, 0xfa, 0x49, 0x2c, 0x9b, 0x05, 0x95, 0x23, 0x0f, 0x73, 0x72, 0x24, 0xab,
0xbc, 0x1c, 0xd4, 0x64, 0x48, 0x8e, 0x42, 0x3e, 0x81, 0xbb, 0x07, 0xe7, 0x09, 0x17, 0x72, 0xdb, 0x89, 0x9b, 0x81, 0x9a, 0x0c, 0xc9, 0x50, 0xc8, 0x27, 0x70, 0xe7, 0xf0, 0x22, 0xe6, 0x42, 0xee,
0xef, 0x3e, 0x67, 0x74, 0xbc, 0x0b, 0x94, 0x57, 0x4a, 0xed, 0x1a, 0xbd, 0x9e, 0x81, 0xac, 0xc1, 0x78, 0x9d, 0x67, 0x8c, 0x8e, 0x76, 0x81, 0xe2, 0x6a, 0xa1, 0x55, 0xa1, 0x37, 0x33, 0x90, 0x75,
0x1b, 0x7e, 0x14, 0xf1, 0x0b, 0x73, 0x69, 0x54, 0xfa, 0xdb, 0x8b, 0x2b, 0x56, 0xbb, 0x4a, 0xaf, 0x78, 0xc3, 0x0b, 0x43, 0x7e, 0x69, 0x2e, 0x8d, 0x4a, 0xff, 0xe6, 0xd2, 0xaa, 0xd5, 0x2a, 0xd3,
0x6e, 0x90, 0x0f, 0xe1, 0x4e, 0x8e, 0xf8, 0x44, 0x08, 0xff, 0x12, 0xf3, 0x65, 0x49, 0xf1, 0x4f, 0xeb, 0x1f, 0xc8, 0x87, 0x70, 0x3b, 0x43, 0x7c, 0x2c, 0x84, 0x77, 0x85, 0xf9, 0xb2, 0xac, 0xf8,
0xdb, 0xc2, 0x0a, 0xb6, 0x17, 0xc6, 0x7e, 0x64, 0x83, 0xe2, 0xd1, 0x0b, 0xe2, 0x42, 0x63, 0xf7, 0x27, 0x7d, 0xc2, 0x0a, 0xb6, 0x1f, 0x44, 0x5e, 0xd8, 0x04, 0xc5, 0xa3, 0x37, 0xc4, 0x81, 0xda,
0x15, 0xaa, 0xc4, 0xc4, 0x13, 0x29, 0x85, 0x5d, 0x57, 0xa1, 0x18, 0xa3, 0x91, 0x13, 0x68, 0x28, 0xde, 0x4b, 0x54, 0x89, 0x89, 0xc7, 0x52, 0x8a, 0x66, 0x55, 0x85, 0x62, 0x84, 0x46, 0x4e, 0xa1,
0x85, 0xb5, 0xee, 0xa9, 0xdd, 0x50, 0x4e, 0x5b, 0x2b, 0x70, 0x9a, 0x62, 0x7f, 0x9a, 0xe4, 0xae, 0xa6, 0x14, 0xd6, 0xba, 0x27, 0xcd, 0x9a, 0x72, 0xda, 0x7a, 0x8e, 0xd3, 0x14, 0xfb, 0x93, 0x38,
0xd2, 0x98, 0x04, 0xd2, 0x85, 0x56, 0xe6, 0x38, 0x7d, 0x07, 0xed, 0xa6, 0x92, 0xf9, 0x78, 0xde, 0x73, 0x95, 0x46, 0x24, 0x90, 0x0e, 0x34, 0x52, 0xc7, 0xe9, 0x3b, 0xd8, 0xac, 0x2b, 0x99, 0x8f,
0x40, 0x68, 0xb4, 0x3e, 0x62, 0x42, 0x24, 0xa6, 0xc1, 0x2e, 0x5e, 0x37, 0x5f, 0x32, 0xbb, 0xa5, 0xe6, 0x0d, 0x84, 0x46, 0xeb, 0x23, 0xc6, 0x44, 0x62, 0x1a, 0xec, 0xe1, 0x75, 0xf3, 0x24, 0x6b,
0x6c, 0x1e, 0xae, 0x9d, 0x4f, 0x61, 0x79, 0x32, 0x96, 0xf3, 0x14, 0x7d, 0xe7, 0x97, 0x70, 0x67, 0x36, 0x94, 0xcd, 0x83, 0xbd, 0xfd, 0x29, 0xac, 0x8c, 0xc7, 0x72, 0x9e, 0xa2, 0x6f, 0xff, 0x0a,
0x8a, 0x0a, 0x3f, 0xa8, 0x1e, 0xfc, 0xcd, 0x82, 0x37, 0xae, 0xf8, 0x8d, 0x10, 0x28, 0x7f, 0x79, 0x6e, 0x4f, 0x50, 0xe1, 0xb5, 0xea, 0xc1, 0xdf, 0x2d, 0x78, 0xe3, 0x9a, 0xdf, 0x08, 0x81, 0xe2,
0x99, 0x30, 0x23, 0x52, 0x7d, 0x93, 0x23, 0x58, 0xc4, 0xb8, 0xa4, 0xf6, 0x82, 0x72, 0xda, 0xc6, 0x97, 0x57, 0x31, 0x33, 0x22, 0xd5, 0x9a, 0x1c, 0xc3, 0x12, 0xc6, 0x25, 0x69, 0x2e, 0x2a, 0xa7,
0x3c, 0x81, 0xf0, 0x14, 0x52, 0x3b, 0x4c, 0x4b, 0x71, 0x1e, 0x01, 0x8c, 0x88, 0x73, 0xb5, 0xbe, 0x6d, 0xce, 0x13, 0x08, 0x57, 0x21, 0xb5, 0xc3, 0xb4, 0x14, 0xfb, 0x21, 0xc0, 0x90, 0x38, 0x57,
0xaf, 0xa1, 0x69, 0xa2, 0x62, 0xca, 0xc3, 0xb2, 0x9e, 0x52, 0x0c, 0x18, 0x67, 0x90, 0x51, 0xbb, 0xeb, 0xfb, 0x1a, 0xea, 0x26, 0x2a, 0xa6, 0x3c, 0xac, 0xe8, 0x29, 0xc5, 0x80, 0x71, 0x06, 0x19,
0x28, 0xcd, 0xd9, 0x2e, 0xdc, 0x6f, 0xe1, 0x36, 0x65, 0x7e, 0xb0, 0x17, 0x46, 0xec, 0xfa, 0xaa, 0xb6, 0x8b, 0xc2, 0x9c, 0xed, 0xc2, 0xf9, 0x16, 0x6e, 0x51, 0xe6, 0xf9, 0xfb, 0x41, 0xc8, 0x6e,
0x88, 0x77, 0x3d, 0x8c, 0xd8, 0x89, 0x2f, 0x9f, 0x0f, 0xef, 0xba, 0x59, 0x93, 0x4d, 0x58, 0xa4, 0xae, 0x8a, 0x78, 0xd7, 0x83, 0x90, 0x9d, 0x7a, 0xf2, 0xd9, 0xe0, 0xae, 0x9b, 0x3d, 0xd9, 0x82,
0x7e, 0xdc, 0x67, 0xe6, 0xe8, 0xf7, 0x0a, 0x8e, 0x56, 0x87, 0x20, 0x2f, 0xd5, 0x10, 0xf7, 0x31, 0x25, 0xea, 0x45, 0x3d, 0x66, 0x8e, 0x7e, 0x2f, 0xe7, 0x68, 0x75, 0x08, 0xf2, 0x52, 0x0d, 0x71,
0xd4, 0x86, 0x34, 0xac, 0x54, 0x4f, 0x7b, 0xbd, 0x94, 0xe9, 0xaa, 0x57, 0xa2, 0x66, 0x85, 0xf4, 0x1e, 0x41, 0x65, 0x40, 0xc3, 0x4a, 0xf5, 0xa4, 0xdb, 0x4d, 0x98, 0xae, 0x7a, 0x05, 0x6a, 0x76,
0x43, 0x16, 0xf7, 0xcd, 0xd1, 0x25, 0x6a, 0x56, 0xee, 0x2a, 0x8e, 0x2a, 0x99, 0xe6, 0xc6, 0x35, 0x48, 0x3f, 0x62, 0x51, 0xcf, 0x1c, 0x5d, 0xa0, 0x66, 0xe7, 0xac, 0xe1, 0xa8, 0x92, 0x6a, 0x6e,
0x04, 0xca, 0x3b, 0x38, 0x4f, 0x59, 0xea, 0x82, 0xa9, 0x6f, 0x37, 0xc0, 0x36, 0xe7, 0x07, 0x3b, 0x5c, 0x43, 0xa0, 0xb8, 0x8b, 0xf3, 0x94, 0xa5, 0x2e, 0x98, 0x5a, 0x3b, 0x3e, 0xb6, 0x39, 0xcf,
0xa1, 0xb8, 0xde, 0x40, 0x1b, 0x2a, 0x3b, 0xa1, 0xc8, 0xd9, 0x97, 0x2d, 0xc9, 0x2a, 0x36, 0xc0, 0xdf, 0x0d, 0xc4, 0xcd, 0x06, 0x36, 0xa1, 0xb4, 0x1b, 0x88, 0x8c, 0x7d, 0xe9, 0x96, 0xac, 0x61,
0x6e, 0x34, 0x08, 0xd0, 0x5a, 0xc9, 0x44, 0x6c, 0x2a, 0xfd, 0x04, 0xd5, 0xfd, 0x4c, 0xfb, 0x51, 0x03, 0xec, 0x84, 0x7d, 0x1f, 0xad, 0x95, 0x4c, 0x44, 0xa6, 0xd2, 0x8f, 0x51, 0x9d, 0xcf, 0xb4,
0x9d, 0x62, 0x94, 0x59, 0x83, 0x0a, 0x8b, 0xa5, 0x08, 0x59, 0xd6, 0x25, 0x89, 0xa7, 0x47, 0x60, 0x1f, 0xd5, 0x29, 0x46, 0x99, 0x75, 0x28, 0xb1, 0x48, 0x8a, 0x80, 0xa5, 0x5d, 0x92, 0xb8, 0x7a,
0x4f, 0x8d, 0xc0, 0xaa, 0x1b, 0xd3, 0x8c, 0xc5, 0xdd, 0x80, 0xdb, 0x48, 0x28, 0x0e, 0x04, 0x81, 0x04, 0x76, 0xd5, 0x08, 0xac, 0xba, 0x31, 0x4d, 0x59, 0x9c, 0x4d, 0xb8, 0x85, 0x84, 0xfc, 0x40,
0x72, 0x4e, 0x49, 0xf5, 0xed, 0x6e, 0xc2, 0xf2, 0x08, 0x68, 0x8e, 0x5e, 0x85, 0x32, 0x0e, 0xd8, 0x10, 0x28, 0x66, 0x94, 0x54, 0x6b, 0x67, 0x0b, 0x56, 0x86, 0x40, 0x73, 0xf4, 0x1a, 0x14, 0x71,
0xa6, 0x8c, 0x4f, 0x3b, 0x57, 0xed, 0xbb, 0x4d, 0xa8, 0x9f, 0x84, 0x71, 0xd6, 0x0f, 0xdd, 0xd7, 0xc0, 0x36, 0x65, 0x7c, 0xd2, 0xb9, 0xea, 0xbb, 0x53, 0x87, 0xea, 0x69, 0x10, 0xa5, 0xfd, 0xd0,
0x16, 0x34, 0x4e, 0x78, 0x3c, 0xea, 0x44, 0x27, 0x70, 0x3b, 0xbb, 0x81, 0x4f, 0x4e, 0x0e, 0xb6, 0x79, 0x65, 0x41, 0xed, 0x94, 0x47, 0xc3, 0x4e, 0x74, 0x0a, 0xb7, 0xd2, 0x1b, 0xf8, 0xf8, 0xf4,
0xfd, 0x24, 0x33, 0x65, 0xe5, 0x6a, 0x98, 0xcd, 0x5b, 0xc0, 0xd3, 0x8c, 0x5b, 0x65, 0x6c, 0x5a, 0x70, 0xc7, 0x8b, 0x53, 0x53, 0x56, 0xaf, 0x87, 0xd9, 0xbc, 0x05, 0x5c, 0xcd, 0xb8, 0x5d, 0xc4,
0x74, 0x12, 0x4e, 0x7e, 0x01, 0x95, 0xc3, 0xc3, 0x2d, 0x25, 0x69, 0x61, 0x2e, 0x49, 0x19, 0x8c, 0xa6, 0x45, 0xc7, 0xe1, 0xe4, 0x97, 0x50, 0x3a, 0x3a, 0xda, 0x56, 0x92, 0x16, 0xe7, 0x92, 0x94,
0x7c, 0x0a, 0x95, 0x67, 0xea, 0x89, 0x92, 0x9a, 0xc6, 0x32, 0x25, 0xe5, 0xb4, 0xa1, 0x9a, 0x8d, 0xc2, 0xc8, 0xa7, 0x50, 0x7a, 0xaa, 0x9e, 0x28, 0x89, 0x69, 0x2c, 0x13, 0x52, 0x4e, 0x1b, 0xaa,
0xb2, 0x2e, 0x17, 0x01, 0xcd, 0x40, 0xee, 0xff, 0x2c, 0xa8, 0x3f, 0xf3, 0x47, 0xb3, 0xd6, 0xe7, 0xd9, 0x28, 0xeb, 0x70, 0xe1, 0xd3, 0x14, 0xe4, 0xfc, 0xcf, 0x82, 0xea, 0x53, 0x6f, 0x38, 0x6b,
0xb0, 0x14, 0xfc, 0xe0, 0x6e, 0xab, 0x97, 0x78, 0x8b, 0x23, 0xf6, 0x92, 0x45, 0x26, 0x55, 0xf5, 0x7d, 0x0e, 0xcb, 0xfe, 0x6b, 0x77, 0x5b, 0xbd, 0xc5, 0x5b, 0x1c, 0xb2, 0x17, 0x2c, 0x34, 0xa9,
0x02, 0xa9, 0xe9, 0x73, 0x2e, 0xf4, 0xed, 0x6c, 0x50, 0xbd, 0xc0, 0xbc, 0x0e, 0x98, 0xf4, 0xc3, 0xaa, 0x37, 0x48, 0x4d, 0x9e, 0x71, 0xa1, 0x6f, 0x67, 0x8d, 0xea, 0x0d, 0xe6, 0xb5, 0xcf, 0xa4,
0x48, 0x75, 0xad, 0x06, 0x35, 0x2b, 0x8c, 0xfa, 0x40, 0x44, 0xaa, 0x29, 0xd5, 0x28, 0x7e, 0x12, 0x17, 0x84, 0xaa, 0x6b, 0xd5, 0xa8, 0xd9, 0x61, 0xd4, 0xfb, 0x22, 0x54, 0x4d, 0xa9, 0x42, 0x71,
0x17, 0xca, 0x61, 0xdc, 0xe3, 0xaa, 0xef, 0x98, 0xea, 0x76, 0xca, 0x07, 0xa2, 0xcb, 0x0e, 0xe2, 0x49, 0x1c, 0x28, 0x06, 0x51, 0x97, 0xab, 0xbe, 0x63, 0xaa, 0xdb, 0x19, 0xef, 0x8b, 0x0e, 0x3b,
0x1e, 0xa7, 0x6a, 0x8f, 0xbc, 0x0b, 0x4b, 0x02, 0xaf, 0x51, 0x6a, 0x57, 0x94, 0x53, 0x6a, 0xc8, 0x8c, 0xba, 0x9c, 0xaa, 0x6f, 0xe4, 0x5d, 0x58, 0x16, 0x78, 0x8d, 0x92, 0x66, 0x49, 0x39, 0xa5,
0xa5, 0x2f, 0x9b, 0xd9, 0x70, 0x5b, 0xd0, 0xd0, 0x76, 0x9b, 0x69, 0xef, 0x8f, 0x0b, 0x70, 0xe7, 0x82, 0x5c, 0xfa, 0xb2, 0x99, 0x0f, 0x4e, 0x03, 0x6a, 0xda, 0x6e, 0x33, 0xed, 0xfd, 0x69, 0x11,
0x98, 0x5d, 0x6c, 0x67, 0x76, 0x65, 0x0e, 0x59, 0x81, 0xfa, 0x90, 0x76, 0xb0, 0x63, 0xd2, 0x2f, 0x6e, 0x9f, 0xb0, 0xcb, 0x9d, 0xd4, 0xae, 0xd4, 0x21, 0xab, 0x50, 0x1d, 0xd0, 0x0e, 0x77, 0x4d,
0x4f, 0xc2, 0xc3, 0x8e, 0xf8, 0x20, 0x96, 0x59, 0x0c, 0xd5, 0x61, 0x8a, 0x42, 0xcd, 0x06, 0xf9, 0xfa, 0x65, 0x49, 0x78, 0xd8, 0x31, 0xef, 0x47, 0x32, 0x8d, 0xa1, 0x3a, 0x4c, 0x51, 0xa8, 0xf9,
0x09, 0x54, 0x8e, 0x99, 0xc4, 0xb7, 0xa4, 0xb2, 0xba, 0xb5, 0x5e, 0x47, 0x9e, 0x63, 0x26, 0x71, 0x40, 0x7e, 0x0a, 0xa5, 0x13, 0x26, 0xf1, 0x2d, 0xa9, 0xac, 0x6e, 0x6c, 0x54, 0x91, 0xe7, 0x84,
0x34, 0xa2, 0xd9, 0x1e, 0xce, 0x5b, 0x49, 0x36, 0x6f, 0x95, 0xa7, 0xcd, 0x5b, 0xd9, 0x2e, 0xd9, 0x49, 0x1c, 0x8d, 0x68, 0xfa, 0x0d, 0xe7, 0xad, 0x38, 0x9d, 0xb7, 0x8a, 0x93, 0xe6, 0xad, 0xf4,
0x80, 0x7a, 0x97, 0xc7, 0xa9, 0x14, 0x7e, 0x88, 0x07, 0x2f, 0x2a, 0xe6, 0x1f, 0x21, 0xb3, 0x0e, 0x2b, 0xd9, 0x84, 0x6a, 0x87, 0x47, 0x89, 0x14, 0x5e, 0x80, 0x07, 0x2f, 0x29, 0xe6, 0x1f, 0x21,
0xec, 0xf6, 0x68, 0x93, 0xe6, 0x39, 0xc9, 0x03, 0x00, 0xf6, 0x4a, 0x0a, 0x7f, 0x9f, 0xa7, 0x32, 0xb3, 0x0e, 0xec, 0xce, 0xf0, 0x23, 0xcd, 0x72, 0x92, 0xfb, 0x00, 0xec, 0xa5, 0x14, 0xde, 0x01,
0xb5, 0x97, 0x94, 0xc2, 0x80, 0x38, 0x24, 0x1c, 0x9c, 0xd0, 0xdc, 0xae, 0xfb, 0x16, 0xbc, 0x39, 0x4f, 0x64, 0xd2, 0x5c, 0x56, 0x0a, 0x03, 0xe2, 0x90, 0x70, 0x78, 0x4a, 0x33, 0x5f, 0x9d, 0xb7,
0xee, 0x11, 0xe3, 0xaa, 0xc7, 0xf0, 0x63, 0xca, 0x22, 0xe6, 0xa7, 0x6c, 0x7e, 0x6f, 0xb9, 0x0e, 0xe0, 0xcd, 0x51, 0x8f, 0x18, 0x57, 0x3d, 0x82, 0x1f, 0x53, 0x16, 0x32, 0x2f, 0x61, 0xf3, 0x7b,
0xd8, 0x57, 0xc1, 0x46, 0xf0, 0xdf, 0x4b, 0x50, 0xdf, 0x7d, 0xc5, 0xba, 0x47, 0x2c, 0x4d, 0xfd, 0xcb, 0xb1, 0xa1, 0x79, 0x1d, 0x6c, 0x04, 0xff, 0xbf, 0x00, 0xd5, 0xbd, 0x97, 0xac, 0x73, 0xcc,
0x3e, 0x23, 0x6f, 0x43, 0xed, 0x44, 0xf0, 0x2e, 0x4b, 0xd3, 0xa1, 0xac, 0x11, 0x81, 0x7c, 0x02, 0x92, 0xc4, 0xeb, 0x31, 0xf2, 0x36, 0x54, 0x4e, 0x05, 0xef, 0xb0, 0x24, 0x19, 0xc8, 0x1a, 0x12,
0xe5, 0x83, 0x38, 0x94, 0xa6, 0xcd, 0xad, 0x16, 0x0e, 0xdd, 0xa1, 0x34, 0x32, 0xf1, 0xc1, 0x89, 0xc8, 0x27, 0x50, 0x3c, 0x8c, 0x02, 0x69, 0xda, 0xdc, 0x5a, 0xee, 0xd0, 0x1d, 0x48, 0x23, 0x13,
0x4b, 0xb2, 0x09, 0x65, 0x2c, 0x12, 0x37, 0x29, 0xd4, 0x41, 0x0e, 0x8b, 0x18, 0xb2, 0xa5, 0x9e, 0x1f, 0x9c, 0xb8, 0x25, 0x5b, 0x50, 0xc4, 0x22, 0x31, 0x4b, 0xa1, 0xf6, 0x33, 0x58, 0xc4, 0x90,
0xe8, 0xe1, 0x37, 0xcc, 0x44, 0xa9, 0x5d, 0xdc, 0x61, 0xc2, 0x6f, 0xd8, 0x48, 0x82, 0x41, 0x92, 0x6d, 0xf5, 0x44, 0x0f, 0xbe, 0x61, 0x26, 0x4a, 0xad, 0xfc, 0x0e, 0x13, 0x7c, 0xc3, 0x86, 0x12,
0x5d, 0xa8, 0x9c, 0x4a, 0x5f, 0xe0, 0x9c, 0xa6, 0xa3, 0x77, 0xbf, 0x68, 0x10, 0xd1, 0x9c, 0x23, 0x0c, 0x92, 0xec, 0x41, 0xe9, 0x4c, 0x7a, 0x02, 0xe7, 0x34, 0x1d, 0xbd, 0x7b, 0x79, 0x83, 0x88,
0x29, 0x19, 0x16, 0x9d, 0xb0, 0xfb, 0x2a, 0x94, 0xe6, 0x36, 0x14, 0x39, 0x01, 0xd9, 0x72, 0x86, 0xe6, 0x1c, 0x4a, 0x49, 0xb1, 0xe8, 0x84, 0xbd, 0x97, 0x81, 0x34, 0xb7, 0x21, 0xcf, 0x09, 0xc8,
0xe0, 0x12, 0xd1, 0x3b, 0x3c, 0x66, 0x76, 0x65, 0x26, 0x1a, 0xd9, 0x72, 0x68, 0x5c, 0x6e, 0x55, 0x96, 0x31, 0x04, 0xb7, 0x88, 0xde, 0xe5, 0x11, 0x6b, 0x96, 0xa6, 0xa2, 0x91, 0x2d, 0x83, 0xc6,
0x60, 0x51, 0x4d, 0x22, 0xee, 0x5f, 0x2c, 0xa8, 0xe7, 0x7c, 0x7c, 0x83, 0x3b, 0xf3, 0x36, 0x94, 0x2d, 0xba, 0xe1, 0x2c, 0xe8, 0xe1, 0x7c, 0x57, 0x9e, 0xea, 0x06, 0xcd, 0x98, 0x71, 0x83, 0x26,
0xf1, 0x85, 0x6e, 0x62, 0x57, 0x55, 0x37, 0x86, 0x49, 0x9f, 0x2a, 0x2a, 0x5e, 0xfa, 0xbd, 0x40, 0x6c, 0x97, 0x60, 0x49, 0x4d, 0x33, 0xce, 0x5f, 0x2d, 0xa8, 0x66, 0xe2, 0x34, 0xc3, 0xbd, 0x7b,
0x17, 0xb4, 0x26, 0xc5, 0x4f, 0xa4, 0x7c, 0x29, 0x2f, 0x95, 0xbb, 0xab, 0x14, 0x3f, 0xc9, 0x1a, 0x1b, 0x8a, 0xf8, 0xca, 0x37, 0xf1, 0x2f, 0xab, 0x5b, 0xc7, 0xa4, 0x47, 0x15, 0x15, 0x0b, 0xc7,
0x54, 0x4f, 0x59, 0x77, 0x20, 0x42, 0x79, 0xa9, 0x1c, 0xd8, 0x5a, 0x5f, 0x56, 0xa5, 0xc0, 0xd0, 0xbe, 0xaf, 0x8b, 0x62, 0x9d, 0xe2, 0x12, 0x29, 0x5f, 0xca, 0x2b, 0x15, 0xb2, 0x32, 0xc5, 0x25,
0xd4, 0xc5, 0x1a, 0x72, 0xb8, 0x5f, 0x60, 0x62, 0x8d, 0x14, 0x24, 0x50, 0xde, 0xc6, 0x77, 0x0a, 0x59, 0x87, 0xf2, 0x19, 0xeb, 0xf4, 0x45, 0x20, 0xaf, 0x54, 0x10, 0x1a, 0x1b, 0x2b, 0xaa, 0x9c,
0x6a, 0xd6, 0xa4, 0xea, 0x1b, 0x9f, 0x8a, 0xbb, 0xb3, 0x9e, 0x8a, 0xbb, 0xd9, 0x53, 0x71, 0x3c, 0x18, 0x9a, 0xba, 0x9c, 0x03, 0x0e, 0xe7, 0x0b, 0x4c, 0xce, 0xa1, 0x82, 0x04, 0x8a, 0x3b, 0xf8,
0x20, 0xd8, 0x39, 0x72, 0x0e, 0x72, 0x9f, 0x40, 0x6d, 0x98, 0x34, 0xf8, 0x4a, 0xdf, 0x0b, 0xcc, 0xd6, 0x41, 0xcd, 0xea, 0x54, 0xad, 0xf1, 0xb9, 0xb9, 0x37, 0xed, 0xb9, 0xb9, 0x97, 0x3e, 0x37,
0x49, 0x0b, 0x7b, 0x01, 0x9a, 0xb2, 0xfb, 0x74, 0x4f, 0x9d, 0x52, 0xa5, 0xf8, 0x39, 0xec, 0xd3, 0x47, 0x83, 0x8a, 0xdd, 0x27, 0xe3, 0x64, 0xe7, 0x31, 0x54, 0x06, 0x89, 0x87, 0x2f, 0xfd, 0x7d,
0xa5, 0x5c, 0x9f, 0xde, 0xc0, 0x47, 0x70, 0x2e, 0x73, 0x90, 0x89, 0xf2, 0x8b, 0x34, 0x53, 0x19, 0xdf, 0x9c, 0xb4, 0xb8, 0xef, 0xa3, 0x29, 0x7b, 0x4f, 0xf6, 0xd5, 0x29, 0x65, 0x8a, 0xcb, 0x41,
0xbf, 0xb5, 0x19, 0x51, 0xaa, 0x64, 0x29, 0x33, 0xa2, 0x74, 0xfd, 0x5f, 0x35, 0xa8, 0x1d, 0x1e, 0xaf, 0x2f, 0x64, 0x7a, 0xfd, 0x26, 0x3e, 0xa4, 0x33, 0xd9, 0x87, 0x4c, 0x94, 0x5f, 0x26, 0xa9,
0x6e, 0x6d, 0x89, 0x30, 0xe8, 0x33, 0xf2, 0x7b, 0x0b, 0xc8, 0xd5, 0xb7, 0x15, 0xf9, 0xa8, 0x38, 0xca, 0xb8, 0xd6, 0x66, 0x84, 0x89, 0x92, 0xa5, 0xcc, 0x08, 0x13, 0xe7, 0x27, 0x50, 0x1f, 0x89,
0x61, 0xa7, 0x3f, 0x10, 0x9d, 0x8f, 0xe7, 0x44, 0x99, 0xb6, 0xf9, 0x15, 0x2c, 0xaa, 0x91, 0x8d, 0x17, 0x32, 0xa9, 0x97, 0x9b, 0x19, 0x09, 0x71, 0xbd, 0xf1, 0xaf, 0x0a, 0x54, 0x8e, 0x8e, 0xb6,
0xfc, 0xf4, 0x86, 0xa3, 0xb6, 0xd3, 0x9e, 0xcd, 0x68, 0x64, 0x77, 0xa1, 0x9a, 0x8d, 0x3d, 0xe4, 0xb7, 0x45, 0xe0, 0xf7, 0x18, 0xf9, 0x83, 0x05, 0xe4, 0xfa, 0x23, 0x8e, 0x7c, 0x94, 0x7f, 0x33,
0x41, 0xa1, 0x7a, 0x63, 0x53, 0x9d, 0xf3, 0xfe, 0x8d, 0x78, 0xcd, 0x21, 0xbf, 0x81, 0x8a, 0x99, 0x26, 0xbf, 0x44, 0xed, 0x8f, 0xe7, 0x44, 0x99, 0xfe, 0xfc, 0x15, 0x2c, 0xa9, 0xd9, 0x90, 0xfc,
0x66, 0xc8, 0xfd, 0x19, 0xb8, 0xd1, 0x5c, 0xe5, 0x3c, 0xb8, 0x09, 0xeb, 0xc8, 0x8c, 0x6c, 0x6a, 0x6c, 0xc6, 0x99, 0xde, 0x6e, 0x4d, 0x67, 0x34, 0xb2, 0x3b, 0x50, 0x4e, 0xe7, 0x2b, 0x72, 0x3f,
0x29, 0x34, 0x63, 0x62, 0x26, 0x2a, 0x34, 0xe3, 0xca, 0x18, 0xf4, 0x0c, 0xca, 0x38, 0xde, 0x90, 0x57, 0xbd, 0x91, 0xf1, 0xd1, 0x7e, 0x7f, 0x26, 0x5e, 0x73, 0xc8, 0x6f, 0xa1, 0x64, 0xc6, 0x26,
0xa2, 0x6b, 0x9e, 0x9b, 0x7f, 0x9c, 0xa2, 0x70, 0x8d, 0xcd, 0x45, 0xbf, 0xc6, 0x72, 0xa8, 0x9e, 0x72, 0x6f, 0x0a, 0x6e, 0x38, 0xc0, 0xd9, 0xf7, 0x67, 0x61, 0x1d, 0x9a, 0x91, 0x8e, 0x47, 0xb9,
0x88, 0xc5, 0x85, 0x30, 0xf7, 0x9f, 0x8e, 0x73, 0xff, 0x06, 0x9c, 0x23, 0xf1, 0xe6, 0x79, 0xd5, 0x66, 0x8c, 0x0d, 0x5f, 0xb9, 0x66, 0x5c, 0x9b, 0xb7, 0x9e, 0x42, 0x11, 0xe7, 0x28, 0x92, 0x57,
0xbe, 0xc1, 0x1f, 0x2b, 0xb3, 0xc5, 0x4f, 0xfc, 0x85, 0xc3, 0xa1, 0x91, 0xef, 0x72, 0xc4, 0x2b, 0x4f, 0x32, 0x83, 0x96, 0x9d, 0x17, 0xae, 0x91, 0x01, 0xec, 0x37, 0x58, 0x77, 0xd5, 0x5b, 0x34,
0x80, 0x4e, 0x19, 0x10, 0x9c, 0xce, 0x8d, 0xf9, 0xcd, 0x81, 0xdf, 0xe2, 0xa8, 0x3e, 0xde, 0x01, 0xbf, 0xe2, 0x66, 0xfe, 0x3c, 0xb2, 0xef, 0xcd, 0xc0, 0x39, 0x14, 0x6f, 0xde, 0x71, 0xad, 0x19,
0xc9, 0x7a, 0xa1, 0x3b, 0xa6, 0xf6, 0x5a, 0xe7, 0xe1, 0x5c, 0x18, 0x73, 0xb8, 0xaf, 0x3b, 0xac, 0xfe, 0xc1, 0x99, 0x2e, 0x7e, 0xec, 0xbf, 0x22, 0x0e, 0xb5, 0x6c, 0x3b, 0x25, 0x6e, 0x0e, 0x74,
0xe9, 0xa2, 0xa4, 0xb8, 0x61, 0x0c, 0x3b, 0xb1, 0x73, 0x43, 0xbe, 0xb6, 0xf5, 0xa1, 0x85, 0x79, 0xc2, 0x24, 0x62, 0xb7, 0x67, 0xe6, 0x37, 0x07, 0x7e, 0x8b, 0x6f, 0x82, 0xd1, 0x56, 0x4b, 0x36,
0x86, 0x93, 0x55, 0xa1, 0xec, 0xdc, 0xc8, 0x59, 0x98, 0x67, 0xf9, 0x11, 0x6d, 0xab, 0xf1, 0xdd, 0x72, 0xdd, 0x31, 0xb1, 0xa9, 0xdb, 0x0f, 0xe6, 0xc2, 0x98, 0xc3, 0x3d, 0xdd, 0xca, 0x4d, 0xbb,
0xeb, 0x7b, 0xd6, 0x3f, 0x5f, 0xdf, 0xb3, 0xfe, 0xf3, 0xfa, 0x9e, 0x75, 0xb6, 0xa4, 0xfe, 0x2f, 0x26, 0xf9, 0x9d, 0x69, 0xd0, 0xf2, 0xed, 0x19, 0xf9, 0x5a, 0xd6, 0x87, 0x16, 0xe6, 0x19, 0x8e,
0x7f, 0xf8, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8b, 0x9a, 0x89, 0x6b, 0x81, 0x18, 0x00, 0x00, 0x70, 0xb9, 0xb2, 0x33, 0xb3, 0x6d, 0x6e, 0x9e, 0x65, 0x67, 0xc1, 0xed, 0xda, 0x77, 0xaf, 0xee,
0x5a, 0xff, 0x7c, 0x75, 0xd7, 0xfa, 0xcf, 0xab, 0xbb, 0xd6, 0xf9, 0xb2, 0xfa, 0x63, 0xfe, 0xc1,
0x0f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x92, 0x5d, 0x25, 0xb8, 0xea, 0x18, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@ -4500,6 +4565,27 @@ func (m *ExecMessage_Done) MarshalToSizedBuffer(dAtA []byte) (int, error) {
} }
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
func (m *ExecMessage_Signal) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ExecMessage_Signal) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.Signal != nil {
{
size, err := m.Signal.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGateway(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x42
}
return len(dAtA) - i, nil
}
func (m *InitMessage) Marshal() (dAtA []byte, err error) { func (m *InitMessage) Marshal() (dAtA []byte, err error) {
size := m.Size() size := m.Size()
dAtA = make([]byte, size) dAtA = make([]byte, size)
@ -4540,20 +4626,20 @@ func (m *InitMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0x20 dAtA[i] = 0x20
} }
if len(m.Fds) > 0 { if len(m.Fds) > 0 {
dAtA25 := make([]byte, len(m.Fds)*10) dAtA26 := make([]byte, len(m.Fds)*10)
var j24 int var j25 int
for _, num := range m.Fds { for _, num := range m.Fds {
for num >= 1<<7 { for num >= 1<<7 {
dAtA25[j24] = uint8(uint64(num)&0x7f | 0x80) dAtA26[j25] = uint8(uint64(num)&0x7f | 0x80)
num >>= 7 num >>= 7
j24++ j25++
} }
dAtA25[j24] = uint8(num) dAtA26[j25] = uint8(num)
j24++ j25++
} }
i -= j24 i -= j25
copy(dAtA[i:], dAtA25[:j24]) copy(dAtA[i:], dAtA26[:j25])
i = encodeVarintGateway(dAtA, i, uint64(j24)) i = encodeVarintGateway(dAtA, i, uint64(j25))
i-- i--
dAtA[i] = 0x1a dAtA[i] = 0x1a
} }
@ -4763,6 +4849,40 @@ func (m *ResizeMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
func (m *SignalMessage) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *SignalMessage) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *SignalMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.Name) > 0 {
i -= len(m.Name)
copy(dAtA[i:], m.Name)
i = encodeVarintGateway(dAtA, i, uint64(len(m.Name)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintGateway(dAtA []byte, offset int, v uint64) int { func encodeVarintGateway(dAtA []byte, offset int, v uint64) int {
offset -= sovGateway(v) offset -= sovGateway(v)
base := offset base := offset
@ -5545,6 +5665,18 @@ func (m *ExecMessage_Done) Size() (n int) {
} }
return n return n
} }
func (m *ExecMessage_Signal) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Signal != nil {
l = m.Signal.Size()
n += 1 + l + sovGateway(uint64(l))
}
return n
}
func (m *InitMessage) Size() (n int) { func (m *InitMessage) Size() (n int) {
if m == nil { if m == nil {
return 0 return 0
@ -5661,6 +5793,22 @@ func (m *ResizeMessage) Size() (n int) {
return n return n
} }
func (m *SignalMessage) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Name)
if l > 0 {
n += 1 + l + sovGateway(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovGateway(x uint64) (n int) { func sovGateway(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7 return (math_bits.Len64(x|1) + 6) / 7
} }
@ -10031,6 +10179,41 @@ func (m *ExecMessage) Unmarshal(dAtA []byte) error {
} }
m.Input = &ExecMessage_Done{v} m.Input = &ExecMessage_Done{v}
iNdEx = postIndex iNdEx = postIndex
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Signal", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGateway
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGateway
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGateway
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
v := &SignalMessage{}
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Input = &ExecMessage_Signal{v}
iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipGateway(dAtA[iNdEx:]) skippy, err := skipGateway(dAtA[iNdEx:])
@ -10708,6 +10891,89 @@ func (m *ResizeMessage) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *SignalMessage) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGateway
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: SignalMessage: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: SignalMessage: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGateway
}
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 ErrInvalidLengthGateway
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGateway
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Name = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGateway(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGateway
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGateway(dAtA []byte) (n int, err error) { func skipGateway(dAtA []byte) (n int, err error) {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0

@ -223,6 +223,8 @@ message ExecMessage {
// DoneMessage from server to client will be the last message for any // DoneMessage from server to client will be the last message for any
// process. Note that FdMessage might be sent after ExitMessage. // process. Note that FdMessage might be sent after ExitMessage.
DoneMessage Done = 7; DoneMessage Done = 7;
// SignalMessage is used from client to server to send signal events
SignalMessage Signal = 8;
} }
} }
@ -253,3 +255,9 @@ message ResizeMessage{
uint32 Rows = 1; uint32 Rows = 1;
uint32 Cols = 2; uint32 Cols = 2;
} }
message SignalMessage {
// we only send name (ie HUP, INT) because the int values
// are platform dependent.
string Name = 1;
}

@ -1,3 +1,3 @@
package moby_buildkit_v1_frontend //nolint:golint package moby_buildkit_v1_frontend //nolint:revive
//go:generate protoc -I=. -I=../../../vendor/ -I=../../../../../../ --gogo_out=plugins=grpc:. gateway.proto //go:generate protoc -I=. -I=../../../vendor/ -I=../../../../../../ --gogo_out=plugins=grpc:. gateway.proto

@ -86,27 +86,25 @@ func (ap *authProvider) FetchToken(ctx context.Context, req *auth.FetchTokenRequ
progresswriter.Wrap(name, ap.logger, done) progresswriter.Wrap(name, ap.logger, done)
} }
ap.mu.Unlock() ap.mu.Unlock()
// try GET first because Docker Hub does not support POST // credential information is provided, use oauth POST endpoint
// switch once support has landed resp, err := authutil.FetchTokenWithOAuth(ctx, http.DefaultClient, nil, "buildkit-client", to)
resp, err := authutil.FetchToken(ctx, http.DefaultClient, nil, to)
if err != nil { if err != nil {
var errStatus remoteserrors.ErrUnexpectedStatus var errStatus remoteserrors.ErrUnexpectedStatus
if errors.As(err, &errStatus) { if errors.As(err, &errStatus) {
// retry with POST request // Registries without support for POST may return 404 for POST /v2/token.
// As of September 2017, GCR is known to return 404. // As of September 2017, GCR is known to return 404.
// As of February 2018, JFrog Artifactory is known to return 401. // As of February 2018, JFrog Artifactory is known to return 401.
if (errStatus.StatusCode == 405 && to.Username != "") || errStatus.StatusCode == 404 || errStatus.StatusCode == 401 { if (errStatus.StatusCode == 405 && to.Username != "") || errStatus.StatusCode == 404 || errStatus.StatusCode == 401 {
resp, err := authutil.FetchTokenWithOAuth(ctx, http.DefaultClient, nil, "buildkit-client", to) resp, err := authutil.FetchToken(ctx, http.DefaultClient, nil, to)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return toTokenResponse(resp.Token, resp.IssuedAt, resp.ExpiresIn), nil
return toTokenResponse(resp.AccessToken, resp.IssuedAt, resp.ExpiresIn), nil
} }
} }
return nil, err return nil, err
} }
return toTokenResponse(resp.Token, resp.IssuedAt, resp.ExpiresIn), nil return toTokenResponse(resp.AccessToken, resp.IssuedAt, resp.ExpiresIn), nil
} }
// do request anonymously // do request anonymously
resp, err := authutil.FetchToken(ctx, http.DefaultClient, nil, to) resp, err := authutil.FetchToken(ctx, http.DefaultClient, nil, to)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save