Unverified Commit 618b0f98 authored by Jacob Blain Christen's avatar Jacob Blain Christen Committed by GitHub

registry mirror repository rewrites (#3064)

Support repository regex rewrite rules when fetching image content. Example configuration: ```yaml # /etc/rancher/k3s/registries.yaml mirrors: "docker.io": endpoint: - "https://registry-1.docker.io/v2" rewrite: "^library/alpine$": "my-org/alpine" ``` This will instruct k3s containerd to fetch content for `alpine` images from `docker.io/my-org/alpine` instead of the default `docker.io/library/alpine` locations. Signed-off-by: 's avatarJacob Blain Christen <jacob@rancher.com>
parent 7c99f864
...@@ -8,9 +8,9 @@ replace ( ...@@ -8,9 +8,9 @@ replace (
github.com/containerd/btrfs => github.com/containerd/btrfs v0.0.0-20181101203652-af5082808c83 github.com/containerd/btrfs => github.com/containerd/btrfs v0.0.0-20181101203652-af5082808c83
github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59
github.com/containerd/console => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50 github.com/containerd/console => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50
github.com/containerd/containerd => github.com/k3s-io/containerd v1.4.3-k3s3 github.com/containerd/containerd => github.com/k3s-io/containerd v1.4.3-k3s5 // k3s-release/1.4
github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02 github.com/containerd/continuity => github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1 // see rancher/rke2#690
github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.2 // k3s-release/1.4 github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.4 // k3s-release/1.4
github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c
github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328 github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328
github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd
...@@ -108,7 +108,7 @@ require ( ...@@ -108,7 +108,7 @@ require (
go.etcd.io/etcd v0.5.0-alpha.5.0.20201208200253-50621aee4aea go.etcd.io/etcd v0.5.0-alpha.5.0.20201208200253-50621aee4aea
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3
google.golang.org/grpc v1.33.2 google.golang.org/grpc v1.33.2
gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v2 v2.3.0
k8s.io/api v0.19.0 k8s.io/api v0.19.0
......
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM= bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
...@@ -150,8 +151,6 @@ github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 h1:qWj4qVYZ95vL ...@@ -150,8 +151,6 @@ github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 h1:qWj4qVYZ95vL
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50 h1:WMpHmC6AxwWb9hMqhudkqG7A/p14KiMnl6d3r1iUMjU= github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50 h1:WMpHmC6AxwWb9hMqhudkqG7A/p14KiMnl6d3r1iUMjU=
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02 h1:tN9D97v5A5QuKdcKHKt+UMKrkQ5YXUnD8iM7IAAjEfI=
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c h1:KFbqHhDeaHM7IfFtXHfUHMDaUStpM2YwBR+iJCIOsKk= github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c h1:KFbqHhDeaHM7IfFtXHfUHMDaUStpM2YwBR+iJCIOsKk=
github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/go-cni v1.0.1 h1:VXr2EkOPD0v1gu7CKfof6XzEIDzsE/dI9yj/W7PSWLs= github.com/containerd/go-cni v1.0.1 h1:VXr2EkOPD0v1gu7CKfof6XzEIDzsE/dI9yj/W7PSWLs=
...@@ -510,10 +509,12 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7 ...@@ -510,10 +509,12 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
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=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/k3s-io/containerd v1.4.3-k3s3 h1:cCczsk6P0KYYnFuh4FauXNMDcNl2LmDilCD6igR71WU= github.com/k3s-io/containerd v1.4.3-k3s5 h1:wGKP+NNg9Kk2+gAdY6KvBFX6bSkeXfHX5pn+6cJhOQ0=
github.com/k3s-io/containerd v1.4.3-k3s3/go.mod h1:qHmUrsocqXRZQBvPKgoYfsBDfZ/tCtPta97L+VXqbak= github.com/k3s-io/containerd v1.4.3-k3s5/go.mod h1:2QPgKXi8SPBf4oL3yUt0jtbmtrfv2VJzqX1AVNCje/A=
github.com/k3s-io/cri v1.4.0-k3s.2 h1:HiJLH0P7k6sSJwbzjPwIN0CeY0iA6bKlb7OyThMiaEo= github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1 h1:KEz2rd9IDbrQT8w6RibEYlwfTXiu0P6hQDE+6O4IJdI=
github.com/k3s-io/cri v1.4.0-k3s.2/go.mod h1:fGPUUHMKQik/vIegSe05DtX/m4miovdtvVLqRUFAkK0= github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
github.com/k3s-io/cri v1.4.0-k3s.4 h1:4KNhSnHQAH6LuzwGfe5iZuRhxrxs9vtZk1BOSDIyICI=
github.com/k3s-io/cri v1.4.0-k3s.4/go.mod h1:fGPUUHMKQik/vIegSe05DtX/m4miovdtvVLqRUFAkK0=
github.com/k3s-io/cri-tools v1.20.0-k3s1 h1:pd6/NWvCwMeBiBvvkGSCBQHlVJFQ5Vj2f1oXXIA18RY= github.com/k3s-io/cri-tools v1.20.0-k3s1 h1:pd6/NWvCwMeBiBvvkGSCBQHlVJFQ5Vj2f1oXXIA18RY=
github.com/k3s-io/cri-tools v1.20.0-k3s1/go.mod h1:APtxWLVkA6SNZxmG5/ETT3QAxG0BptTtFc8EywLSdLQ= github.com/k3s-io/cri-tools v1.20.0-k3s1/go.mod h1:APtxWLVkA6SNZxmG5/ETT3QAxG0BptTtFc8EywLSdLQ=
github.com/k3s-io/etcd v0.5.0-alpha.5.0.20201208200253-50621aee4aea h1:7cwby0GoNAi8IsVrT0q+JfQpB6V76ZaEGhj6qts/mvU= github.com/k3s-io/etcd v0.5.0-alpha.5.0.20201208200253-50621aee4aea h1:7cwby0GoNAi8IsVrT0q+JfQpB6V76ZaEGhj6qts/mvU=
...@@ -848,6 +849,7 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B ...@@ -848,6 +849,7 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
...@@ -855,6 +857,7 @@ github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJ ...@@ -855,6 +857,7 @@ github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJ
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
......
...@@ -7,6 +7,11 @@ type Mirror struct { ...@@ -7,6 +7,11 @@ type Mirror struct {
// with host specified. // with host specified.
// The scheme, host and path from the endpoint URL will be used. // The scheme, host and path from the endpoint URL will be used.
Endpoints []string `toml:"endpoint" yaml:"endpoint"` Endpoints []string `toml:"endpoint" yaml:"endpoint"`
// Rewrites are repository rewrite rules for a namespace. When fetching image resources
// from an endpoint and a key matches the repository via regular expression matching
// it will be replaced with the corresponding value from the map in the resource request.
Rewrites map[string]string `toml:"rewrite" yaml:"rewrite"`
} }
// AuthConfig contains the config related to authentication to a specific registry // AuthConfig contains the config related to authentication to a specific registry
......
...@@ -53,6 +53,12 @@ const ContainerdConfigTemplate = ` ...@@ -53,6 +53,12 @@ const ContainerdConfigTemplate = `
{{range $k, $v := .PrivateRegistryConfig.Mirrors }} {{range $k, $v := .PrivateRegistryConfig.Mirrors }}
[plugins.cri.registry.mirrors."{{$k}}"] [plugins.cri.registry.mirrors."{{$k}}"]
endpoint = [{{range $i, $j := $v.Endpoints}}{{if $i}}, {{end}}{{printf "%q" .}}{{end}}] endpoint = [{{range $i, $j := $v.Endpoints}}{{if $i}}, {{end}}{{printf "%q" .}}{{end}}]
{{if $v.Rewrites}}
[plugins.cri.registry.mirrors."{{$k}}".rewrite]
{{range $pattern, $replace := $v.Rewrites}}
"{{$pattern}}" = "{{$replace}}"
{{end}}
{{end}}
{{end}} {{end}}
{{range $k, $v := .PrivateRegistryConfig.Configs }} {{range $k, $v := .PrivateRegistryConfig.Configs }}
......
...@@ -3,7 +3,8 @@ module github.com/containerd/containerd ...@@ -3,7 +3,8 @@ module github.com/containerd/containerd
go 1.14 go 1.14
replace ( replace (
github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.2 // k3s-release/1.4 github.com/containerd/continuity => github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1
github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.4 // k3s-release/1.4
github.com/golang/protobuf => github.com/golang/protobuf v1.3.5 github.com/golang/protobuf => github.com/golang/protobuf v1.3.5
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63 google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63
k8s.io/api => k8s.io/api v0.19.5 k8s.io/api => k8s.io/api v0.19.5
...@@ -71,14 +72,14 @@ require ( ...@@ -71,14 +72,14 @@ require (
github.com/opencontainers/selinux v1.6.0 github.com/opencontainers/selinux v1.6.0
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.7.1 github.com/prometheus/client_golang v1.7.1
github.com/sirupsen/logrus v1.6.0 github.com/sirupsen/logrus v1.7.0
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
github.com/tchap/go-patricia v2.2.6+incompatible // indirect github.com/tchap/go-patricia v2.2.6+incompatible // indirect
github.com/urfave/cli v1.22.2 github.com/urfave/cli v1.22.2
go.etcd.io/bbolt v1.3.5 go.etcd.io/bbolt v1.3.5
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3
google.golang.org/grpc v1.27.1 google.golang.org/grpc v1.27.1
gotest.tools/v3 v3.0.2 gotest.tools/v3 v3.0.2
) )
...@@ -131,10 +131,6 @@ github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go. ...@@ -131,10 +131,6 @@ github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
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-20200710164510-efbc4488d8fe h1:PEmIrUvwG9Yyv+0WKZqjXfSFDeZjs/q15g0m08BYS9k=
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
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 h1:qUtCegLdOUVfVJOw+KDg6eJyE1TGvLlkGEd1091kSSQ= github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b h1:qUtCegLdOUVfVJOw+KDg6eJyE1TGvLlkGEd1091kSSQ=
...@@ -404,8 +400,10 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X ...@@ -404,8 +400,10 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
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=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/k3s-io/cri v1.4.0-k3s.2 h1:HiJLH0P7k6sSJwbzjPwIN0CeY0iA6bKlb7OyThMiaEo= github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1 h1:KEz2rd9IDbrQT8w6RibEYlwfTXiu0P6hQDE+6O4IJdI=
github.com/k3s-io/cri v1.4.0-k3s.2/go.mod h1:fGPUUHMKQik/vIegSe05DtX/m4miovdtvVLqRUFAkK0= github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
github.com/k3s-io/cri v1.4.0-k3s.4 h1:4KNhSnHQAH6LuzwGfe5iZuRhxrxs9vtZk1BOSDIyICI=
github.com/k3s-io/cri v1.4.0-k3s.4/go.mod h1:fGPUUHMKQik/vIegSe05DtX/m4miovdtvVLqRUFAkK0=
github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
...@@ -486,7 +484,6 @@ github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB ...@@ -486,7 +484,6 @@ github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
...@@ -527,7 +524,6 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP ...@@ -527,7 +524,6 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
...@@ -583,13 +579,14 @@ github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvW ...@@ -583,13 +579,14 @@ github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvW
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
...@@ -672,7 +669,6 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= ...@@ -672,7 +669,6 @@ 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/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
...@@ -782,6 +778,7 @@ golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7w ...@@ -782,6 +778,7 @@ golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
...@@ -802,6 +799,8 @@ golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7w ...@@ -802,6 +799,8 @@ golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd h1:5CtCZbICpIOFdgO940moixOPjc0178IU44m4EjOO5IY= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd h1:5CtCZbICpIOFdgO940moixOPjc0178IU44m4EjOO5IY=
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
......
...@@ -71,6 +71,7 @@ type RegistryHost struct { ...@@ -71,6 +71,7 @@ type RegistryHost struct {
Path string Path string
Capabilities HostCapabilities Capabilities HostCapabilities
Header http.Header Header http.Header
Rewrites map[string]string
} }
func (h RegistryHost) isProxy(refhost string) bool { func (h RegistryHost) isProxy(refhost string) bool {
......
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
"regexp"
"strings" "strings"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
...@@ -462,7 +463,19 @@ func (r *dockerBase) request(host RegistryHost, method string, ps ...string) *re ...@@ -462,7 +463,19 @@ func (r *dockerBase) request(host RegistryHost, method string, ps ...string) *re
for key, value := range host.Header { for key, value := range host.Header {
header[key] = append(header[key], value...) header[key] = append(header[key], value...)
} }
parts := append([]string{"/", host.Path, r.repository}, ps...) repository := r.repository
for pattern, replace := range host.Rewrites {
exp, err := regexp.Compile(pattern)
if err != nil {
logrus.Warnf("failed to compile rewrite, `%s`, for %s", pattern, host.Host)
continue
}
if rr := exp.ReplaceAllString(repository, replace); rr != repository {
repository = rr
break
}
}
parts := append([]string{"/", host.Path, repository}, ps...)
p := path.Join(parts...) p := path.Join(parts...)
// Join strips trailing slash, re-add ending "/" if included // Join strips trailing slash, re-add ending "/" if included
if len(parts) > 0 && strings.HasSuffix(parts[len(parts)-1], "/") { if len(parts) > 0 && strings.HasSuffix(parts[len(parts)-1], "/") {
......
linters:
enable:
- structcheck
- varcheck
- staticcheck
- unconvert
- gofmt
- goimports
- golint
- ineffassign
- vet
- unused
- misspell
disable:
- errcheck
run:
timeout: 3m
language: go
sudo: required
go:
- 1.9.x
- 1.10.x
- 1.11.x
- tip
go_import_path: github.com/containerd/continuity
env:
# NOTE: we cannot set GOOS directly (because gimme overrides the value)
- TRAVIS_GOOS=windows
- TRAVIS_GOOS=linux
- TRAVIS_GOOS=darwin
install:
- go get -u github.com/vbatts/git-validation
- go get -u github.com/kunalkushwaha/ltag
- go get -u github.com/LK4D4/vndr
before_script:
- pushd ..; git clone https://github.com/containerd/project; popd
script:
- export GOOS=${TRAVIS_GOOS}
- DCO_VERBOSITY=-q ../project/script/validate/dco
- ../project/script/validate/fileheader ../project/
- ../project/script/validate/vendor
- make build binaries
- if [ "$GOOS" = "linux" ]; then make vet test; fi
- if [ "$GOOS" != "linux" ]; then make test-compile; fi
Aaron Lehmann <aaron.lehmann@docker.com> Aaron Lehmann <aaron.lehmann@docker.com>
Akash Gupta <akagup@microsoft.com> Akash Gupta <akagup@microsoft.com>
Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
Akihiro Suda <suda.akihiro@lab.ntt.co.jp> Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
Akihiro Suda <suda.kyoto@gmail.com>
Andrew Pennebaker <apennebaker@datapipe.com> Andrew Pennebaker <apennebaker@datapipe.com>
Brandon Philips <brandon.philips@coreos.com> Brandon Philips <brandon.philips@coreos.com>
Brian Goff <cpuguy83@gmail.com>
Christopher Jones <tophj@linux.vnet.ibm.com> Christopher Jones <tophj@linux.vnet.ibm.com>
Daniel, Dao Quang Minh <dqminh89@gmail.com> Daniel, Dao Quang Minh <dqminh89@gmail.com>
Darren Stahl <darst@microsoft.com>
Derek McGowan <derek@mcg.dev>
Derek McGowan <derek@mcgstyle.net> Derek McGowan <derek@mcgstyle.net>
Edward Pilatowicz <edward.pilatowicz@oracle.com> Edward Pilatowicz <edward.pilatowicz@oracle.com>
Ian Campbell <ijc@docker.com> Ian Campbell <ijc@docker.com>
Ivan Markin <sw@nogoegst.net>
Justin Cormack <justin.cormack@docker.com> Justin Cormack <justin.cormack@docker.com>
Justin Cummins <sul3n3t@gmail.com> Justin Cummins <sul3n3t@gmail.com>
Kasper Fabæch Brandt <poizan@poizan.dk>
Kir Kolyshkin <kolyshkin@gmail.com>
Michael Crosby <crosbymichael@gmail.com>
Michael Crosby <michael@thepasture.io>
Michael Wan <zirenwan@gmail.com>
Mike Brown <brownwm@us.ibm.com>
Niels de Vos <ndevos@redhat.com>
Phil Estes <estesp@gmail.com> Phil Estes <estesp@gmail.com>
Phil Estes <estesp@linux.vnet.ibm.com>
Samuel Karp <me@samuelkarp.com>
Sam Whited <sam@samwhited.com>
Sebastiaan van Stijn <github@gone.nl>
Shengjing Zhu <zhsj@debian.org>
Stephen J Day <stephen.day@docker.com> Stephen J Day <stephen.day@docker.com>
Tibor Vass <tibor@docker.com>
Tobias Klauser <tklauser@distanz.ch> Tobias Klauser <tklauser@distanz.ch>
Tom Faulhaber <tffaulha@amazon.com>
Tonis Tiigi <tonistiigi@gmail.com> Tonis Tiigi <tonistiigi@gmail.com>
Trevor Porter <trkporter@ucdavis.edu>
Wei Fu <fuweid89@gmail.com>
Wilbert van de Ridder <wilbert.ridder@gmail.com>
Xiaodong Ye <xiaodongy@vmware.com>
...@@ -18,14 +18,25 @@ PREFIX?=$(shell pwd) ...@@ -18,14 +18,25 @@ PREFIX?=$(shell pwd)
# Used to populate version variable in main package. # Used to populate version variable in main package.
VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always) VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always)
GO_LDFLAGS=-ldflags "-X `go list ./version`.Version=$(VERSION)" GO_LDFLAGS=-ldflags "-X `go list -mod=vendor ./version`.Version=$(VERSION)"
PACKAGES=$(shell go list ./... | grep -v /vendor/) PKG=github.com/containerd/continuity
.PHONY: clean all fmt vet lint build test binaries setup PACKAGES=$(shell go list -mod=vendor ./... | grep -v /vendor/)
TEST_REQUIRES_ROOT_PACKAGES=$(filter \
${PACKAGES}, \
$(shell \
for f in $$(git grep -l testutil.RequiresRoot | grep -v Makefile); do \
d="$$(dirname $$f)"; \
[ "$$d" = "." ] && echo "${PKG}" && continue; \
echo "${PKG}/$$d"; \
done | sort -u) \
)
.PHONY: clean all lint build test binaries
.DEFAULT: default .DEFAULT: default
# skip lint at the moment
all: AUTHORS clean fmt vet fmt build test binaries all: AUTHORS clean lint build test binaries
AUTHORS: .mailmap .git/HEAD AUTHORS: .mailmap .git/HEAD
git log --format='%aN <%aE>' | sort -fu > $@ git log --format='%aN <%aE>' | sort -fu > $@
...@@ -36,41 +47,30 @@ version/version.go: ...@@ -36,41 +47,30 @@ version/version.go:
${PREFIX}/bin/continuity: version/version.go $(shell find . -type f -name '*.go') ${PREFIX}/bin/continuity: version/version.go $(shell find . -type f -name '*.go')
@echo "+ $@" @echo "+ $@"
@go build -o $@ ${GO_LDFLAGS} ${GO_GCFLAGS} ./cmd/continuity @go build -mod=vendor -o $@ ${GO_LDFLAGS} ${GO_GCFLAGS} ./cmd/continuity
setup:
@echo "+ $@"
@go get -u github.com/golang/lint/golint
generate: generate:
go generate $(PACKAGES) go generate -mod=vendor $(PACKAGES)
# Depends on binaries because vet will silently fail if it can't load compiled
# imports
vet: binaries
@echo "+ $@"
@go vet $(PACKAGES)
fmt:
@echo "+ $@"
@test -z "$$(gofmt -s -l . | grep -v Godeps/_workspace/src/ | grep -v vendor/ | tee /dev/stderr)" || \
echo "+ please format Go code with 'gofmt -s'"
lint: lint:
@echo "+ $@" @echo "+ $@"
@test -z "$$(golint $(PACKAGES) | grep -v Godeps/_workspace/src/ | grep -v vendor/ |tee /dev/stderr)" @golangci-lint run
build: build:
@echo "+ $@" @echo "+ $@"
@go build -v ${GO_LDFLAGS} $(PACKAGES) @go build -mod=vendor -v ${GO_LDFLAGS} $(PACKAGES)
test: test:
@echo "+ $@" @echo "+ $@"
@go test $(PACKAGES) @go test -mod=vendor $(PACKAGES)
root-test:
@echo "+ $@"
@go test ${TEST_REQUIRES_ROOT_PACKAGES} -test.root
test-compile: test-compile:
@echo "+ $@" @echo "+ $@"
@for pkg in $(PACKAGES); do go test -c $$pkg; done @for pkg in $(PACKAGES); do go test -mod=vendor -c $$pkg; done
binaries: ${PREFIX}/bin/continuity binaries: ${PREFIX}/bin/continuity
@echo "+ $@" @echo "+ $@"
......
...@@ -63,6 +63,10 @@ $ stat -c %a Makefile ...@@ -63,6 +63,10 @@ $ stat -c %a Makefile
$ ./bin/continuity verify . /tmp/a.pb $ ./bin/continuity verify . /tmp/a.pb
``` ```
## Platforms
continuity primarily targets Linux. continuity may compile for and work on
other operating systems, but those platforms are not tested.
## Contribution Guide ## Contribution Guide
### Building Proto Package ### Building Proto Package
......
...@@ -596,7 +596,7 @@ func (c *context) Walk(fn filepath.WalkFunc) error { ...@@ -596,7 +596,7 @@ func (c *context) Walk(fn filepath.WalkFunc) error {
return err return err
} }
} }
return c.pathDriver.Walk(root, func(p string, fi os.FileInfo, err error) error { return c.pathDriver.Walk(root, func(p string, fi os.FileInfo, _ error) error {
contained, err := c.containWithRoot(p, root) contained, err := c.containWithRoot(p, root)
return fn(contained, fi, err) return fn(contained, fi, err)
}) })
...@@ -613,12 +613,6 @@ func (c *context) fullpath(p string) (string, error) { ...@@ -613,12 +613,6 @@ func (c *context) fullpath(p string) (string, error) {
return p, nil return p, nil
} }
// contain cleans and santizes the filesystem path p to be an absolute path,
// effectively relative to the context root.
func (c *context) contain(p string) (string, error) {
return c.containWithRoot(p, c.root)
}
// containWithRoot cleans and santizes the filesystem path p to be an absolute path, // containWithRoot cleans and santizes the filesystem path p to be an absolute path,
// effectively relative to the passed root. Extra care should be used when calling this // effectively relative to the passed root. Extra care should be used when calling this
// instead of contain. This is needed for Walk, as if context root is a symlink, // instead of contain. This is needed for Walk, as if context root is a symlink,
......
...@@ -32,6 +32,7 @@ func DeviceInfo(fi os.FileInfo) (uint64, uint64, error) { ...@@ -32,6 +32,7 @@ func DeviceInfo(fi os.FileInfo) (uint64, uint64, error) {
return 0, 0, fmt.Errorf("cannot extract device from os.FileInfo") return 0, 0, fmt.Errorf("cannot extract device from os.FileInfo")
} }
//nolint:unconvert
dev := uint64(sys.Rdev) dev := uint64(sys.Rdev)
return uint64(unix.Major(dev)), uint64(unix.Minor(dev)), nil return uint64(unix.Major(dev)), uint64(unix.Minor(dev)), nil
} }
...@@ -55,7 +56,7 @@ func Mknod(p string, mode os.FileMode, maj, min int) error { ...@@ -55,7 +56,7 @@ func Mknod(p string, mode os.FileMode, maj, min int) error {
m |= unix.S_IFIFO m |= unix.S_IFIFO
} }
return unix.Mknod(p, m, int(dev)) return mknod(p, m, dev)
} }
// syscallMode returns the syscall-specific mode bits from Go's portable mode bits. // syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
......
// +build !windows // +build freebsd
/* /*
Copyright The containerd Authors. Copyright The containerd Authors.
...@@ -16,11 +16,10 @@ ...@@ -16,11 +16,10 @@
limitations under the License. limitations under the License.
*/ */
package syscallx package devices
import "syscall" import "golang.org/x/sys/unix"
// Readlink returns the destination of the named symbolic link. func mknod(path string, mode uint32, dev uint64) (err error) {
func Readlink(path string, buf []byte) (n int, err error) { return unix.Mknod(path, mode, dev)
return syscall.Readlink(path, buf)
} }
// +build linux darwin solaris
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package devices
import "golang.org/x/sys/unix"
func mknod(path string, mode uint32, dev uint64) (err error) {
return unix.Mknod(path, mode, int(dev))
}
...@@ -88,13 +88,9 @@ func digestsMatch(as, bs []digest.Digest) bool { ...@@ -88,13 +88,9 @@ func digestsMatch(as, bs []digest.Digest) bool {
} }
disjoint := len(as) + len(bs) disjoint := len(as) + len(bs)
if len(uniqified) == disjoint { // if these two sets have the same cardinality, we know both sides
// if these two sets have the same cardinality, we know both sides // didn't share any digests.
// didn't share any digests. return len(uniqified) != disjoint
return false
}
return true
} }
type digestSlice []digest.Digest type digestSlice []digest.Digest
......
...@@ -138,6 +138,10 @@ func (d *driver) Lstat(p string) (os.FileInfo, error) { ...@@ -138,6 +138,10 @@ func (d *driver) Lstat(p string) (os.FileInfo, error) {
return os.Lstat(p) return os.Lstat(p)
} }
func (d *driver) Readlink(p string) (string, error) {
return os.Readlink(p)
}
func (d *driver) Mkdir(p string, mode os.FileMode) error { func (d *driver) Mkdir(p string, mode os.FileMode) error {
return os.Mkdir(p, mode) return os.Mkdir(p, mode)
} }
......
...@@ -131,8 +131,3 @@ func (d *driver) LSetxattr(path string, attrMap map[string][]byte) error { ...@@ -131,8 +131,3 @@ func (d *driver) LSetxattr(path string, attrMap map[string][]byte) error {
func (d *driver) DeviceInfo(fi os.FileInfo) (maj uint64, min uint64, err error) { func (d *driver) DeviceInfo(fi os.FileInfo) (maj uint64, min uint64, err error) {
return devices.DeviceInfo(fi) return devices.DeviceInfo(fi)
} }
// Readlink was forked on Windows to fix a Golang bug, use the "os" package here
func (d *driver) Readlink(p string) (string, error) {
return os.Readlink(p)
}
// +build go1.13
/* /*
Copyright The containerd Authors. Copyright The containerd Authors.
...@@ -14,12 +16,14 @@ ...@@ -14,12 +16,14 @@
limitations under the License. limitations under the License.
*/ */
// Go 1.13 is the minimally supported version for Windows.
// Earlier golang releases have bug in os.Readlink
// (see https://github.com/golang/go/issues/30463).
package driver package driver
import ( import (
"os" "os"
"github.com/containerd/continuity/sysx"
) )
func (d *driver) Mknod(path string, mode os.FileMode, major, minor int) error { func (d *driver) Mknod(path string, mode os.FileMode, major, minor int) error {
...@@ -35,9 +39,3 @@ func (d *driver) Lchmod(path string, mode os.FileMode) (err error) { ...@@ -35,9 +39,3 @@ func (d *driver) Lchmod(path string, mode os.FileMode) (err error) {
// TODO: Use Window's equivalent // TODO: Use Window's equivalent
return os.Chmod(path, mode) return os.Chmod(path, mode)
} }
// Readlink is forked in order to support Volume paths which are used
// in container layers.
func (d *driver) Readlink(p string) (string, error) {
return sysx.Readlink(p)
}
...@@ -39,6 +39,8 @@ type XAttrErrorHandler func(dst, src, xattrKey string, err error) error ...@@ -39,6 +39,8 @@ type XAttrErrorHandler func(dst, src, xattrKey string, err error) error
type copyDirOpts struct { type copyDirOpts struct {
xeh XAttrErrorHandler xeh XAttrErrorHandler
// xex contains a set of xattrs to exclude when copying
xex map[string]struct{}
} }
type CopyDirOpt func(*copyDirOpts) error type CopyDirOpt func(*copyDirOpts) error
...@@ -61,6 +63,19 @@ func WithAllowXAttrErrors() CopyDirOpt { ...@@ -61,6 +63,19 @@ func WithAllowXAttrErrors() CopyDirOpt {
return WithXAttrErrorHandler(xeh) return WithXAttrErrorHandler(xeh)
} }
// WithXAttrExclude allows for exclusion of specified xattr during CopyDir operation.
func WithXAttrExclude(keys ...string) CopyDirOpt {
return func(o *copyDirOpts) error {
if o.xex == nil {
o.xex = make(map[string]struct{}, len(keys))
}
for _, key := range keys {
o.xex[key] = struct{}{}
}
return nil
}
}
// CopyDir copies the directory from src to dst. // CopyDir copies the directory from src to dst.
// Most efficient copy of files is attempted. // Most efficient copy of files is attempted.
func CopyDir(dst, src string, opts ...CopyDirOpt) error { func CopyDir(dst, src string, opts ...CopyDirOpt) error {
...@@ -80,7 +95,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er ...@@ -80,7 +95,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
return errors.Wrapf(err, "failed to stat %s", src) return errors.Wrapf(err, "failed to stat %s", src)
} }
if !stat.IsDir() { if !stat.IsDir() {
return errors.Errorf("source is not directory") return errors.Errorf("source %s is not directory", src)
} }
if st, err := os.Stat(dst); err != nil { if st, err := os.Stat(dst); err != nil {
...@@ -104,6 +119,10 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er ...@@ -104,6 +119,10 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
return errors.Wrapf(err, "failed to copy file info for %s", dst) return errors.Wrapf(err, "failed to copy file info for %s", dst)
} }
if err := copyXAttrs(dst, src, o.xex, o.xeh); err != nil {
return errors.Wrap(err, "failed to copy xattrs")
}
for _, fi := range fis { for _, fi := range fis {
source := filepath.Join(src, fi.Name()) source := filepath.Join(src, fi.Name())
target := filepath.Join(dst, fi.Name()) target := filepath.Join(dst, fi.Name())
...@@ -146,7 +165,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er ...@@ -146,7 +165,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
return errors.Wrap(err, "failed to copy file info") return errors.Wrap(err, "failed to copy file info")
} }
if err := copyXAttrs(target, source, o.xeh); err != nil { if err := copyXAttrs(target, source, o.xex, o.xeh); err != nil {
return errors.Wrap(err, "failed to copy xattrs") return errors.Wrap(err, "failed to copy xattrs")
} }
} }
......
// +build darwin openbsd solaris
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package fs
import (
"os"
"syscall"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
)
func copyDevice(dst string, fi os.FileInfo) error {
st, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
return errors.New("unsupported stat type")
}
return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev))
}
func utimesNano(name string, atime, mtime syscall.Timespec) error {
timespec := []syscall.Timespec{atime, mtime}
return syscall.UtimesNano(name, timespec)
}
// +build freebsd
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package fs
import (
"os"
"syscall"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
)
func copyDevice(dst string, fi os.FileInfo) error {
st, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
return errors.New("unsupported stat type")
}
return unix.Mknod(dst, uint32(fi.Mode()), st.Rdev)
}
func utimesNano(name string, atime, mtime syscall.Timespec) error {
at := unix.NsecToTimespec(atime.Nano())
mt := unix.NsecToTimespec(mtime.Nano())
utimes := [2]unix.Timespec{at, mt}
return unix.UtimesNanoAt(unix.AT_FDCWD, name, utimes[0:], unix.AT_SYMLINK_NOFOLLOW)
}
...@@ -51,7 +51,10 @@ func copyFileInfo(fi os.FileInfo, name string) error { ...@@ -51,7 +51,10 @@ func copyFileInfo(fi os.FileInfo, name string) error {
} }
} }
timespec := []unix.Timespec{unix.Timespec(StatAtime(st)), unix.Timespec(StatMtime(st))} timespec := []unix.Timespec{
unix.NsecToTimespec(syscall.TimespecToNsec(StatAtime(st))),
unix.NsecToTimespec(syscall.TimespecToNsec(StatMtime(st))),
}
if err := unix.UtimesNanoAt(unix.AT_FDCWD, name, timespec, unix.AT_SYMLINK_NOFOLLOW); err != nil { if err := unix.UtimesNanoAt(unix.AT_FDCWD, name, timespec, unix.AT_SYMLINK_NOFOLLOW); err != nil {
return errors.Wrapf(err, "failed to utime %s", name) return errors.Wrapf(err, "failed to utime %s", name)
} }
...@@ -101,21 +104,24 @@ func copyFileContent(dst, src *os.File) error { ...@@ -101,21 +104,24 @@ func copyFileContent(dst, src *os.File) error {
return nil return nil
} }
func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error { func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAttrErrorHandler) error {
xattrKeys, err := sysx.LListxattr(src) xattrKeys, err := sysx.LListxattr(src)
if err != nil { if err != nil {
e := errors.Wrapf(err, "failed to list xattrs on %s", src) e := errors.Wrapf(err, "failed to list xattrs on %s", src)
if xeh != nil { if errorHandler != nil {
e = xeh(dst, src, "", e) e = errorHandler(dst, src, "", e)
} }
return e return e
} }
for _, xattr := range xattrKeys { for _, xattr := range xattrKeys {
if _, exclude := excludes[xattr]; exclude {
continue
}
data, err := sysx.LGetxattr(src, xattr) data, err := sysx.LGetxattr(src, xattr)
if err != nil { if err != nil {
e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src) e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
if xeh != nil { if errorHandler != nil {
if e = xeh(dst, src, xattr, e); e == nil { if e = errorHandler(dst, src, xattr, e); e == nil {
continue continue
} }
} }
...@@ -123,8 +129,8 @@ func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error { ...@@ -123,8 +129,8 @@ func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
} }
if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil { if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst) e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
if xeh != nil { if errorHandler != nil {
if e = xeh(dst, src, xattr, e); e == nil { if e = errorHandler(dst, src, xattr, e); e == nil {
continue continue
} }
} }
......
// +build solaris darwin freebsd // +build darwin freebsd openbsd solaris
/* /*
Copyright The containerd Authors. Copyright The containerd Authors.
...@@ -25,7 +25,6 @@ import ( ...@@ -25,7 +25,6 @@ import (
"github.com/containerd/continuity/sysx" "github.com/containerd/continuity/sysx"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/sys/unix"
) )
func copyFileInfo(fi os.FileInfo, name string) error { func copyFileInfo(fi os.FileInfo, name string) error {
...@@ -53,8 +52,7 @@ func copyFileInfo(fi os.FileInfo, name string) error { ...@@ -53,8 +52,7 @@ func copyFileInfo(fi os.FileInfo, name string) error {
} }
} }
timespec := []syscall.Timespec{StatAtime(st), StatMtime(st)} if err := utimesNano(name, StatAtime(st), StatMtime(st)); err != nil {
if err := syscall.UtimesNano(name, timespec); err != nil {
return errors.Wrapf(err, "failed to utime %s", name) return errors.Wrapf(err, "failed to utime %s", name)
} }
...@@ -69,21 +67,24 @@ func copyFileContent(dst, src *os.File) error { ...@@ -69,21 +67,24 @@ func copyFileContent(dst, src *os.File) error {
return err return err
} }
func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error { func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAttrErrorHandler) error {
xattrKeys, err := sysx.LListxattr(src) xattrKeys, err := sysx.LListxattr(src)
if err != nil { if err != nil {
e := errors.Wrapf(err, "failed to list xattrs on %s", src) e := errors.Wrapf(err, "failed to list xattrs on %s", src)
if xeh != nil { if errorHandler != nil {
e = xeh(dst, src, "", e) e = errorHandler(dst, src, "", e)
} }
return e return e
} }
for _, xattr := range xattrKeys { for _, xattr := range xattrKeys {
if _, exclude := excludes[xattr]; exclude {
continue
}
data, err := sysx.LGetxattr(src, xattr) data, err := sysx.LGetxattr(src, xattr)
if err != nil { if err != nil {
e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src) e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
if xeh != nil { if errorHandler != nil {
if e = xeh(dst, src, xattr, e); e == nil { if e = errorHandler(dst, src, xattr, e); e == nil {
continue continue
} }
} }
...@@ -91,8 +92,8 @@ func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error { ...@@ -91,8 +92,8 @@ func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
} }
if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil { if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst) e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
if xeh != nil { if errorHandler != nil {
if e = xeh(dst, src, xattr, e); e == nil { if e = errorHandler(dst, src, xattr, e); e == nil {
continue continue
} }
} }
...@@ -102,11 +103,3 @@ func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error { ...@@ -102,11 +103,3 @@ func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
return nil return nil
} }
func copyDevice(dst string, fi os.FileInfo) error {
st, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
return errors.New("unsupported stat type")
}
return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev))
}
...@@ -40,7 +40,7 @@ func copyFileContent(dst, src *os.File) error { ...@@ -40,7 +40,7 @@ func copyFileContent(dst, src *os.File) error {
return err return err
} }
func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error { func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAttrErrorHandler) error {
return nil return nil
} }
......
...@@ -25,6 +25,14 @@ import ( ...@@ -25,6 +25,14 @@ import (
"syscall" "syscall"
) )
// blocksUnitSize is the unit used by `st_blocks` in `stat` in bytes.
// See https://man7.org/linux/man-pages/man2/stat.2.html
// st_blocks
// This field indicates the number of blocks allocated to the
// file, in 512-byte units. (This may be smaller than
// st_size/512 when the file has holes.)
const blocksUnitSize = 512
type inode struct { type inode struct {
// TODO(stevvooe): Can probably reduce memory usage by not tracking // TODO(stevvooe): Can probably reduce memory usage by not tracking
// device, but we can leave this right for now. // device, but we can leave this right for now.
...@@ -33,9 +41,9 @@ type inode struct { ...@@ -33,9 +41,9 @@ type inode struct {
func newInode(stat *syscall.Stat_t) inode { func newInode(stat *syscall.Stat_t) inode {
return inode{ return inode{
// Dev is uint32 on darwin/bsd, uint64 on linux/solaris // Dev is uint32 on darwin/bsd, uint64 on linux/solaris/freebsd
dev: uint64(stat.Dev), // nolint: unconvert dev: uint64(stat.Dev), // nolint: unconvert
// Ino is uint32 on bsd, uint64 on darwin/linux/solaris // Ino is uint32 on bsd, uint64 on darwin/linux/solaris/freebsd
ino: uint64(stat.Ino), // nolint: unconvert ino: uint64(stat.Ino), // nolint: unconvert
} }
} }
...@@ -59,10 +67,11 @@ func diskUsage(ctx context.Context, roots ...string) (Usage, error) { ...@@ -59,10 +67,11 @@ func diskUsage(ctx context.Context, roots ...string) (Usage, error) {
default: default:
} }
inoKey := newInode(fi.Sys().(*syscall.Stat_t)) stat := fi.Sys().(*syscall.Stat_t)
inoKey := newInode(stat)
if _, ok := inodes[inoKey]; !ok { if _, ok := inodes[inoKey]; !ok {
inodes[inoKey] = struct{}{} inodes[inoKey] = struct{}{}
size += fi.Size() size += stat.Blocks * blocksUnitSize
} }
return nil return nil
...@@ -89,10 +98,11 @@ func diffUsage(ctx context.Context, a, b string) (Usage, error) { ...@@ -89,10 +98,11 @@ func diffUsage(ctx context.Context, a, b string) (Usage, error) {
} }
if kind == ChangeKindAdd || kind == ChangeKindModify { if kind == ChangeKindAdd || kind == ChangeKindModify {
inoKey := newInode(fi.Sys().(*syscall.Stat_t)) stat := fi.Sys().(*syscall.Stat_t)
inoKey := newInode(stat)
if _, ok := inodes[inoKey]; !ok { if _, ok := inodes[inoKey]; !ok {
inodes[inoKey] = struct{}{} inodes[inoKey] = struct{}{}
size += fi.Size() size += stat.Blocks * blocksUnitSize
} }
return nil return nil
......
...@@ -117,15 +117,13 @@ func sameFile(f1, f2 *currentPath) (bool, error) { ...@@ -117,15 +117,13 @@ func sameFile(f1, f2 *currentPath) (bool, error) {
// If the timestamp may have been truncated in both of the // If the timestamp may have been truncated in both of the
// files, check content of file to determine difference // files, check content of file to determine difference
if t1.Nanosecond() == 0 && t2.Nanosecond() == 0 { if t1.Nanosecond() == 0 && t2.Nanosecond() == 0 {
var eq bool
if (f1.f.Mode() & os.ModeSymlink) == os.ModeSymlink { if (f1.f.Mode() & os.ModeSymlink) == os.ModeSymlink {
eq, err = compareSymlinkTarget(f1.fullPath, f2.fullPath) return compareSymlinkTarget(f1.fullPath, f2.fullPath)
} else if f1.f.Size() > 0 {
eq, err = compareFileContent(f1.fullPath, f2.fullPath)
} }
if err != nil || !eq { if f1.f.Size() == 0 { // if file sizes are zero length, the files are the same by definition
return eq, err return true, nil
} }
return compareFileContent(f1.fullPath, f2.fullPath)
} else if t1.Nanosecond() != t2.Nanosecond() { } else if t1.Nanosecond() != t2.Nanosecond() {
return false, nil return false, nil
} }
......
// +build linux openbsd
/* /*
Copyright The containerd Authors. Copyright The containerd Authors.
......
module github.com/containerd/continuity
go 1.13
require (
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898
github.com/dustin/go-humanize v1.0.0
github.com/golang/protobuf v1.2.0
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.7.0
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95 // indirect
github.com/stretchr/testify v1.4.0 // indirect
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd // indirect
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3
)
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898 h1:SC+c6A1qTFstO9qmB86mPV2IpYme/2ZoEQ0hrP+wo+Q=
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee h1:GQkkv3XSnxhAMjdq2wLfEnptEVr+2BNvmHizILHn+d4=
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95 h1:j8jxLbQ0+T1DFggy6XoGvyUnrJWPR/JybflPvu5rwS4=
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
limitations under the License. limitations under the License.
*/ */
//nolint:unused,deadcode
package continuity package continuity
import ( import (
......
...@@ -53,7 +53,7 @@ func (hlm *hardlinkManager) Add(fi os.FileInfo, resource Resource) error { ...@@ -53,7 +53,7 @@ func (hlm *hardlinkManager) Add(fi os.FileInfo, resource Resource) error {
} }
// Merge processes the current state of the hardlink manager and merges any // Merge processes the current state of the hardlink manager and merges any
// shared nodes into hardlinked resources. // shared nodes into hard linked resources.
func (hlm *hardlinkManager) Merge() ([]Resource, error) { func (hlm *hardlinkManager) Merge() ([]Resource, error) {
var resources []Resource var resources []Resource
for key, linked := range hlm.hardlinks { for key, linked := range hlm.hardlinks {
......
...@@ -48,5 +48,6 @@ func newHardlinkKey(fi os.FileInfo) (hardlinkKey, error) { ...@@ -48,5 +48,6 @@ func newHardlinkKey(fi os.FileInfo) (hardlinkKey, error) {
return hardlinkKey{}, errNotAHardLink return hardlinkKey{}, errNotAHardLink
} }
//nolint:unconvert
return hardlinkKey{dev: uint64(sys.Dev), inode: uint64(sys.Ino)}, nil return hardlinkKey{dev: uint64(sys.Dev), inode: uint64(sys.Ino)}, nil
} }
...@@ -114,11 +114,13 @@ func BuildManifest(ctx Context) (*Manifest, error) { ...@@ -114,11 +114,13 @@ func BuildManifest(ctx Context) (*Manifest, error) {
} }
// merge and post-process the hardlinks. // merge and post-process the hardlinks.
// nolint:misspell
hardlinked, err := hardlinks.Merge() hardlinked, err := hardlinks.Merge()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// nolint:misspell
for _, resource := range hardlinked { for _, resource := range hardlinked {
resourcesByPath[resource.Path()] = resource resourcesByPath[resource.Path()] = resource
} }
......
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package syscallx
import (
"syscall"
"unsafe"
)
type reparseDataBuffer struct {
ReparseTag uint32
ReparseDataLength uint16
Reserved uint16
// GenericReparseBuffer
reparseBuffer byte
}
type mountPointReparseBuffer struct {
SubstituteNameOffset uint16
SubstituteNameLength uint16
PrintNameOffset uint16
PrintNameLength uint16
PathBuffer [1]uint16
}
type symbolicLinkReparseBuffer struct {
SubstituteNameOffset uint16
SubstituteNameLength uint16
PrintNameOffset uint16
PrintNameLength uint16
Flags uint32
PathBuffer [1]uint16
}
const (
_IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003
_SYMLINK_FLAG_RELATIVE = 1
)
// Readlink returns the destination of the named symbolic link.
func Readlink(path string, buf []byte) (n int, err error) {
fd, err := syscall.CreateFile(syscall.StringToUTF16Ptr(path), syscall.GENERIC_READ, 0, nil, syscall.OPEN_EXISTING,
syscall.FILE_FLAG_OPEN_REPARSE_POINT|syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
if err != nil {
return -1, err
}
defer syscall.CloseHandle(fd)
rdbbuf := make([]byte, syscall.MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
var bytesReturned uint32
err = syscall.DeviceIoControl(fd, syscall.FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
if err != nil {
return -1, err
}
rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
var s string
switch rdb.ReparseTag {
case syscall.IO_REPARSE_TAG_SYMLINK:
data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
s = syscall.UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2])
if data.Flags&_SYMLINK_FLAG_RELATIVE == 0 {
if len(s) >= 4 && s[:4] == `\??\` {
s = s[4:]
switch {
case len(s) >= 2 && s[1] == ':': // \??\C:\foo\bar
// do nothing
case len(s) >= 4 && s[:4] == `UNC\`: // \??\UNC\foo\bar
s = `\\` + s[4:]
default:
// unexpected; do nothing
}
} else {
// unexpected; do nothing
}
}
case _IO_REPARSE_TAG_MOUNT_POINT:
data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
s = syscall.UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2])
if len(s) >= 4 && s[:4] == `\??\` { // \??\C:\foo\bar
if len(s) < 48 || s[:11] != `\??\Volume{` {
s = s[4:]
}
} else {
// unexpected; do nothing
}
default:
// the path is not a symlink or junction but another type of reparse
// point
return -1, syscall.ENOENT
}
n = copy(buf, []byte(s))
return n, nil
}
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sysx
import (
"os"
"path/filepath"
"github.com/containerd/continuity/syscallx"
)
// Readlink returns the destination of the named symbolic link.
// If there is an error, it will be of type *PathError.
func Readlink(name string) (string, error) {
for len := 128; ; len *= 2 {
b := make([]byte, len)
n, e := fixCount(syscallx.Readlink(fixLongPath(name), b))
if e != nil {
return "", &os.PathError{Op: "readlink", Path: name, Err: e}
}
if n < len {
return string(b[0:n]), nil
}
}
}
// Many functions in package syscall return a count of -1 instead of 0.
// Using fixCount(call()) instead of call() corrects the count.
func fixCount(n int, err error) (int, error) {
if n < 0 {
n = 0
}
return n, err
}
// fixLongPath returns the extended-length (\\?\-prefixed) form of
// path when needed, in order to avoid the default 260 character file
// path limit imposed by Windows. If path is not easily converted to
// the extended-length form (for example, if path is a relative path
// or contains .. elements), or is short enough, fixLongPath returns
// path unmodified.
//
// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
func fixLongPath(path string) string {
// Do nothing (and don't allocate) if the path is "short".
// Empirically (at least on the Windows Server 2013 builder),
// the kernel is arbitrarily okay with < 248 bytes. That
// matches what the docs above say:
// "When using an API to create a directory, the specified
// path cannot be so long that you cannot append an 8.3 file
// name (that is, the directory name cannot exceed MAX_PATH
// minus 12)." Since MAX_PATH is 260, 260 - 12 = 248.
//
// The MSDN docs appear to say that a normal path that is 248 bytes long
// will work; empirically the path must be less then 248 bytes long.
if len(path) < 248 {
// Don't fix. (This is how Go 1.7 and earlier worked,
// not automatically generating the \\?\ form)
return path
}
// The extended form begins with \\?\, as in
// \\?\c:\windows\foo.txt or \\?\UNC\server\share\foo.txt.
// The extended form disables evaluation of . and .. path
// elements and disables the interpretation of / as equivalent
// to \. The conversion here rewrites / to \ and elides
// . elements as well as trailing or duplicate separators. For
// simplicity it avoids the conversion entirely for relative
// paths or paths containing .. elements. For now,
// \\server\share paths are not converted to
// \\?\UNC\server\share paths because the rules for doing so
// are less well-specified.
if len(path) >= 2 && path[:2] == `\\` {
// Don't canonicalize UNC paths.
return path
}
if !filepath.IsAbs(path) {
// Relative path
return path
}
const prefix = `\\?`
pathbuf := make([]byte, len(prefix)+len(path)+len(`\`))
copy(pathbuf, prefix)
n := len(path)
r, w := 0, len(prefix)
for r < n {
switch {
case os.IsPathSeparator(path[r]):
// empty block
r++
case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])):
// /./
r++
case r+1 < n && path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])):
// /../ is currently unhandled
return path
default:
pathbuf[w] = '\\'
w++
for ; r < n && !os.IsPathSeparator(path[r]); r++ {
pathbuf[w] = path[r]
w++
}
}
}
// A drive's root directory needs a trailing \
if w == len(`\\?\c:`) {
pathbuf[w] = '\\'
w++
}
return string(pathbuf[:w])
}
// +build darwin freebsd // +build darwin freebsd openbsd
/* /*
Copyright The containerd Authors. Copyright The containerd Authors.
......
...@@ -20,7 +20,6 @@ package sysx ...@@ -20,7 +20,6 @@ package sysx
import ( import (
"bytes" "bytes"
"syscall"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
...@@ -66,60 +65,53 @@ func LGetxattr(path, attr string) ([]byte, error) { ...@@ -66,60 +65,53 @@ func LGetxattr(path, attr string) ([]byte, error) {
return getxattrAll(path, attr, unix.Lgetxattr) return getxattrAll(path, attr, unix.Lgetxattr)
} }
const defaultXattrBufferSize = 5 const defaultXattrBufferSize = 128
type listxattrFunc func(path string, dest []byte) (int, error) type listxattrFunc func(path string, dest []byte) (int, error)
func listxattrAll(path string, listFunc listxattrFunc) ([]string, error) { func listxattrAll(path string, listFunc listxattrFunc) ([]string, error) {
var p []byte // nil on first execution buf := make([]byte, defaultXattrBufferSize)
n, err := listFunc(path, buf)
for { for err == unix.ERANGE {
n, err := listFunc(path, p) // first call gets buffer size. // Buffer too small, use zero-sized buffer to get the actual size
n, err = listFunc(path, []byte{})
if err != nil { if err != nil {
return nil, err return nil, err
} }
buf = make([]byte, n)
n, err = listFunc(path, buf)
}
if err != nil {
return nil, err
}
if n > len(p) { ps := bytes.Split(bytes.TrimSuffix(buf[:n], []byte{0}), []byte{0})
p = make([]byte, n) var entries []string
continue for _, p := range ps {
} if len(p) > 0 {
entries = append(entries, string(p))
p = p[:n]
ps := bytes.Split(bytes.TrimSuffix(p, []byte{0}), []byte{0})
var entries []string
for _, p := range ps {
s := string(p)
if s != "" {
entries = append(entries, s)
}
} }
return entries, nil
} }
return entries, nil
} }
type getxattrFunc func(string, string, []byte) (int, error) type getxattrFunc func(string, string, []byte) (int, error)
func getxattrAll(path, attr string, getFunc getxattrFunc) ([]byte, error) { func getxattrAll(path, attr string, getFunc getxattrFunc) ([]byte, error) {
p := make([]byte, defaultXattrBufferSize) buf := make([]byte, defaultXattrBufferSize)
for { n, err := getFunc(path, attr, buf)
n, err := getFunc(path, attr, p) for err == unix.ERANGE {
// Buffer too small, use zero-sized buffer to get the actual size
n, err = getFunc(path, attr, []byte{})
if err != nil { if err != nil {
if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERANGE {
p = make([]byte, len(p)*2) // this can't be ideal.
continue // try again!
}
return nil, err return nil, err
} }
buf = make([]byte, n)
// realloc to correct size and repeat n, err = getFunc(path, attr, buf)
if n > len(p) { }
p = make([]byte, n) if err != nil {
continue return nil, err
}
return p[:n], nil
} }
return buf[:n], nil
} }
...@@ -23,7 +23,7 @@ import ( ...@@ -23,7 +23,7 @@ import (
"runtime" "runtime"
) )
var unsupported = errors.New("extended attributes unsupported on " + runtime.GOOS) var errUnsupported = errors.New("extended attributes unsupported on " + runtime.GOOS)
// Listxattr calls syscall listxattr and reads all content // Listxattr calls syscall listxattr and reads all content
// and returns a string array // and returns a string array
...@@ -33,17 +33,17 @@ func Listxattr(path string) ([]string, error) { ...@@ -33,17 +33,17 @@ func Listxattr(path string) ([]string, error) {
// Removexattr calls syscall removexattr // Removexattr calls syscall removexattr
func Removexattr(path string, attr string) (err error) { func Removexattr(path string, attr string) (err error) {
return unsupported return errUnsupported
} }
// Setxattr calls syscall setxattr // Setxattr calls syscall setxattr
func Setxattr(path string, attr string, data []byte, flags int) (err error) { func Setxattr(path string, attr string, data []byte, flags int) (err error) {
return unsupported return errUnsupported
} }
// Getxattr calls syscall getxattr // Getxattr calls syscall getxattr
func Getxattr(path, attr string) ([]byte, error) { func Getxattr(path, attr string) ([]byte, error) {
return []byte{}, unsupported return []byte{}, errUnsupported
} }
// LListxattr lists xattrs, not following symlinks // LListxattr lists xattrs, not following symlinks
...@@ -53,12 +53,12 @@ func LListxattr(path string) ([]string, error) { ...@@ -53,12 +53,12 @@ func LListxattr(path string) ([]string, error) {
// LRemovexattr removes an xattr, not following symlinks // LRemovexattr removes an xattr, not following symlinks
func LRemovexattr(path string, attr string) (err error) { func LRemovexattr(path string, attr string) (err error) {
return unsupported return errUnsupported
} }
// LSetxattr sets an xattr, not following symlinks // LSetxattr sets an xattr, not following symlinks
func LSetxattr(path string, attr string, data []byte, flags int) (err error) { func LSetxattr(path string, attr string, data []byte, flags int) (err error) {
return unsupported return errUnsupported
} }
// LGetxattr gets an xattr, not following symlinks // LGetxattr gets an xattr, not following symlinks
......
bazil.org/fuse 371fbbdaa8987b715bdd21d6adc4c9b20155f748
github.com/dustin/go-humanize bb3d318650d48840a39aa21a027c6630e198e626
github.com/golang/protobuf 1e59b77b52bf8e4b449a57e6f79f21226d571845
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
github.com/opencontainers/go-digest 279bed98673dd5bef374d3b6e4b09e2af76183bf
github.com/pkg/errors f15c970de5b76fac0b59abb32d62c17cc7bed265
github.com/sirupsen/logrus 89742aefa4b206dcf400792f3bd35b542998eb3b
github.com/spf13/cobra 2da4a54c5ceefcee7ca5dd0eea1e18a3b6366489
github.com/spf13/pflag 4c012f6dcd9546820e378d0bdda4d8fc772cdfea
golang.org/x/crypto 9f005a07e0d31d45e6656d241bb5c0f2efd4bc94
golang.org/x/net a337091b0525af65de94df2eb7e98bd9962dcbe2
golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
golang.org/x/sys 77b0e4315053a57ed2962443614bdb28db152054
...@@ -118,6 +118,23 @@ type Mirror struct { ...@@ -118,6 +118,23 @@ type Mirror struct {
// with host specified. // with host specified.
// The scheme, host and path from the endpoint URL will be used. // The scheme, host and path from the endpoint URL will be used.
Endpoints []string `toml:"endpoint" json:"endpoint"` Endpoints []string `toml:"endpoint" json:"endpoint"`
// Rewrites are repository rewrite rules for a namespace. When fetching image resources
// from an endpoint and a key matches the repository via regular expression matching
// it will be replaced with the corresponding value from the map in the resource request.
//
// This example configures CRI to pull docker.io/library/* images from docker.io/my-org/*:
//
// [plugins]
// [plugins."io.containerd.grpc.v1.cri"]
// [plugins."io.containerd.grpc.v1.cri".registry]
// [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
// [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
// endpoint = ["https://registry-1.docker.io/v2"]
// [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io".rewrite]
// "^library/(.*)" = "my-org/$1"
//
Rewrites map[string]string `toml:"rewrite" json:"rewrite"`
} }
// AuthConfig contains the config related to authentication to a specific registry // AuthConfig contains the config related to authentication to a specific registry
......
...@@ -114,5 +114,5 @@ func copyExistingContents(source, destination string) error { ...@@ -114,5 +114,5 @@ func copyExistingContents(source, destination string) error {
if len(dstList) != 0 { if len(dstList) != 0 {
return errors.Errorf("volume at %q is not initially empty", destination) return errors.Errorf("volume at %q is not initially empty", destination)
} }
return fs.CopyDir(destination, source) return fs.CopyDir(destination, source, fs.WithXAttrExclude("security.selinux"))
} }
...@@ -319,6 +319,10 @@ func (c *criService) registryHosts(auth *runtime.AuthConfig) docker.RegistryHost ...@@ -319,6 +319,10 @@ func (c *criService) registryHosts(auth *runtime.AuthConfig) docker.RegistryHost
if err != nil { if err != nil {
return nil, errors.Wrap(err, "get registry endpoints") return nil, errors.Wrap(err, "get registry endpoints")
} }
rewrites, err := c.registryRewrites(host)
if err != nil {
return nil, errors.Wrap(err, "get registry rewrites")
}
for _, e := range endpoints { for _, e := range endpoints {
u, err := url.Parse(e) u, err := url.Parse(e)
if err != nil { if err != nil {
...@@ -357,6 +361,7 @@ func (c *criService) registryHosts(auth *runtime.AuthConfig) docker.RegistryHost ...@@ -357,6 +361,7 @@ func (c *criService) registryHosts(auth *runtime.AuthConfig) docker.RegistryHost
Scheme: u.Scheme, Scheme: u.Scheme,
Path: u.Path, Path: u.Path,
Capabilities: docker.HostCapabilityResolve | docker.HostCapabilityPull, Capabilities: docker.HostCapabilityResolve | docker.HostCapabilityPull,
Rewrites: rewrites,
}) })
} }
return registries, nil return registries, nil
...@@ -422,6 +427,20 @@ func (c *criService) registryEndpoints(host string) ([]string, error) { ...@@ -422,6 +427,20 @@ func (c *criService) registryEndpoints(host string) ([]string, error) {
return append(endpoints, defaultScheme(defaultHost)+"://"+defaultHost), nil return append(endpoints, defaultScheme(defaultHost)+"://"+defaultHost), nil
} }
func (c *criService) registryRewrites(host string) (map[string]string, error) {
var rewrites map[string]string
_, ok := c.config.Registry.Mirrors[host]
if ok {
rewrites = c.config.Registry.Mirrors[host].Rewrites
} else {
rewrites = c.config.Registry.Mirrors["*"].Rewrites
}
if rewrites == nil {
rewrites = map[string]string{}
}
return rewrites, nil
}
// newTransport returns a new HTTP transport used to pull image. // newTransport returns a new HTTP transport used to pull image.
// TODO(random-liu): Create a library and share this code with `ctr`. // TODO(random-liu): Create a library and share this code with `ctr`.
func newTransport() *http.Transport { func newTransport() *http.Transport {
......
...@@ -10,8 +10,8 @@ github.com/BurntSushi/toml v0.3.1 ...@@ -10,8 +10,8 @@ github.com/BurntSushi/toml v0.3.1
github.com/cespare/xxhash/v2 v2.1.1 github.com/cespare/xxhash/v2 v2.1.1
github.com/containerd/cgroups 318312a373405e5e91134d8063d04d59768a1bff github.com/containerd/cgroups 318312a373405e5e91134d8063d04d59768a1bff
github.com/containerd/console v1.0.0 github.com/containerd/console v1.0.0
github.com/containerd/containerd v1.4.1 github.com/containerd/containerd c35d6975c66d1e33bc0bf5af4ed549393e5cb866 https://github.com/k3s-io/containerd.git
github.com/containerd/continuity efbc4488d8fe1bdc16bde3b2d2990d9b3a899165 github.com/containerd/continuity f93269e0d5c1e116e1c7f1f5af80eae9a75f988b https://github.com/k3s-io/continuity.git
github.com/containerd/fifo f15a3290365b9d2627d189e619ab4008e0069caf github.com/containerd/fifo f15a3290365b9d2627d189e619ab4008e0069caf
github.com/containerd/go-runc 7016d3ce2328dd2cb1192b2076ebd565c4e8df0c github.com/containerd/go-runc 7016d3ce2328dd2cb1192b2076ebd565c4e8df0c
github.com/containerd/ttrpc v1.0.1 github.com/containerd/ttrpc v1.0.1
......
...@@ -178,7 +178,7 @@ github.com/containerd/cgroups/v2 ...@@ -178,7 +178,7 @@ github.com/containerd/cgroups/v2
github.com/containerd/cgroups/v2/stats github.com/containerd/cgroups/v2/stats
# github.com/containerd/console v1.0.0 => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50 # github.com/containerd/console v1.0.0 => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50
github.com/containerd/console github.com/containerd/console
# github.com/containerd/containerd v1.4.1 => github.com/k3s-io/containerd v1.4.3-k3s3 # github.com/containerd/containerd v1.4.1 => github.com/k3s-io/containerd v1.4.3-k3s5
## explicit ## explicit
github.com/containerd/containerd github.com/containerd/containerd
github.com/containerd/containerd/api/events github.com/containerd/containerd/api/events
...@@ -314,16 +314,15 @@ github.com/containerd/containerd/snapshots/storage ...@@ -314,16 +314,15 @@ github.com/containerd/containerd/snapshots/storage
github.com/containerd/containerd/sys github.com/containerd/containerd/sys
github.com/containerd/containerd/sys/reaper github.com/containerd/containerd/sys/reaper
github.com/containerd/containerd/version github.com/containerd/containerd/version
# github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe => github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02 # github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe => github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1
github.com/containerd/continuity github.com/containerd/continuity
github.com/containerd/continuity/devices github.com/containerd/continuity/devices
github.com/containerd/continuity/driver github.com/containerd/continuity/driver
github.com/containerd/continuity/fs github.com/containerd/continuity/fs
github.com/containerd/continuity/pathdriver github.com/containerd/continuity/pathdriver
github.com/containerd/continuity/proto github.com/containerd/continuity/proto
github.com/containerd/continuity/syscallx
github.com/containerd/continuity/sysx github.com/containerd/continuity/sysx
# github.com/containerd/cri v1.11.1-0.20200820101445-b0cc07999aa5 => github.com/k3s-io/cri v1.4.0-k3s.2 # github.com/containerd/cri v1.11.1-0.20200820101445-b0cc07999aa5 => github.com/k3s-io/cri v1.4.0-k3s.4
## explicit ## explicit
github.com/containerd/cri github.com/containerd/cri
github.com/containerd/cri/pkg/annotations github.com/containerd/cri/pkg/annotations
...@@ -1198,7 +1197,7 @@ golang.org/x/oauth2/jwt ...@@ -1198,7 +1197,7 @@ golang.org/x/oauth2/jwt
golang.org/x/sync/errgroup golang.org/x/sync/errgroup
golang.org/x/sync/semaphore golang.org/x/sync/semaphore
golang.org/x/sync/singleflight golang.org/x/sync/singleflight
# golang.org/x/sys v0.0.0-20201112073958-5cba982894dd => golang.org/x/sys v0.0.0-20201112073958-5cba982894dd # golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 => golang.org/x/sys v0.0.0-20201112073958-5cba982894dd
## explicit ## explicit
golang.org/x/sys/cpu golang.org/x/sys/cpu
golang.org/x/sys/internal/unsafeheader golang.org/x/sys/internal/unsafeheader
...@@ -2997,9 +2996,9 @@ sigs.k8s.io/yaml ...@@ -2997,9 +2996,9 @@ sigs.k8s.io/yaml
# github.com/containerd/btrfs => github.com/containerd/btrfs v0.0.0-20181101203652-af5082808c83 # github.com/containerd/btrfs => github.com/containerd/btrfs v0.0.0-20181101203652-af5082808c83
# github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 # github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59
# github.com/containerd/console => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50 # github.com/containerd/console => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50
# github.com/containerd/containerd => github.com/k3s-io/containerd v1.4.3-k3s3 # github.com/containerd/containerd => github.com/k3s-io/containerd v1.4.3-k3s5
# github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02 # github.com/containerd/continuity => github.com/k3s-io/continuity v0.0.0-20210309170710-f93269e0d5c1
# github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.2 # github.com/containerd/cri => github.com/k3s-io/cri v1.4.0-k3s.4
# github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c # github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c
# github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328 # github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328
# github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd # github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment