mirror of https://github.com/docker/buildx.git
				
				
				
			Merge pull request #2175 from jsternberg/vendor-update
deps: update buildkit, vendor changes
This commit is contained in:
		
						commit
						9060cab077
					
				
							
								
								
									
										18
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										18
									
								
								go.mod
								
								
								
								
							| 
						 | 
				
			
			@ -13,9 +13,9 @@ require (
 | 
			
		|||
	github.com/containerd/typeurl/v2 v2.1.1
 | 
			
		||||
	github.com/creack/pty v1.1.18
 | 
			
		||||
	github.com/distribution/reference v0.5.0
 | 
			
		||||
	github.com/docker/cli v25.0.0-beta.1+incompatible
 | 
			
		||||
	github.com/docker/cli v25.0.0-rc.1+incompatible
 | 
			
		||||
	github.com/docker/cli-docs-tool v0.6.0
 | 
			
		||||
	github.com/docker/docker v25.0.0-beta.1+incompatible
 | 
			
		||||
	github.com/docker/docker v25.0.0-rc.1+incompatible
 | 
			
		||||
	github.com/docker/go-units v0.5.0
 | 
			
		||||
	github.com/gofrs/flock v0.8.1
 | 
			
		||||
	github.com/gogo/protobuf v1.3.2
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +24,7 @@ require (
 | 
			
		|||
	github.com/google/uuid v1.3.0
 | 
			
		||||
	github.com/hashicorp/go-cty-funcs v0.0.0-20230405223818-a090f58aa992
 | 
			
		||||
	github.com/hashicorp/hcl/v2 v2.19.1
 | 
			
		||||
	github.com/moby/buildkit v0.13.0-beta1.0.20231219135447-957cb50df991 // master (v0.13.0-dev)
 | 
			
		||||
	github.com/moby/buildkit v0.13.0-beta1.0.20240105171016-6e200afad512 // master (v0.13.0-dev)
 | 
			
		||||
	github.com/moby/sys/mountinfo v0.6.2
 | 
			
		||||
	github.com/moby/sys/signal v0.7.0
 | 
			
		||||
	github.com/morikuni/aec v1.0.0
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ require (
 | 
			
		|||
	go.opentelemetry.io/otel/trace v1.19.0
 | 
			
		||||
	golang.org/x/mod v0.11.0
 | 
			
		||||
	golang.org/x/sync v0.3.0
 | 
			
		||||
	golang.org/x/term v0.13.0
 | 
			
		||||
	golang.org/x/term v0.15.0
 | 
			
		||||
	google.golang.org/grpc v1.58.3
 | 
			
		||||
	gopkg.in/yaml.v3 v3.0.1
 | 
			
		||||
	k8s.io/api v0.26.7
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ require (
 | 
			
		|||
	github.com/docker/go-connections v0.4.1-0.20231110212414-fa09c952e3ea // indirect
 | 
			
		||||
	github.com/docker/go-metrics v0.0.1 // indirect
 | 
			
		||||
	github.com/emicklei/go-restful/v3 v3.10.1 // indirect
 | 
			
		||||
	github.com/felixge/httpsnoop v1.0.3 // indirect
 | 
			
		||||
	github.com/felixge/httpsnoop v1.0.4 // indirect
 | 
			
		||||
	github.com/fvbommel/sortorder v1.0.1 // indirect
 | 
			
		||||
	github.com/go-logr/logr v1.2.4 // indirect
 | 
			
		||||
	github.com/go-logr/stdr v1.2.2 // indirect
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +102,7 @@ require (
 | 
			
		|||
	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 | 
			
		||||
	github.com/josharian/intern v1.0.0 // indirect
 | 
			
		||||
	github.com/json-iterator/go v1.1.12 // indirect
 | 
			
		||||
	github.com/klauspost/compress v1.17.2 // indirect
 | 
			
		||||
	github.com/klauspost/compress v1.17.4 // indirect
 | 
			
		||||
	github.com/mailru/easyjson v0.7.6 // indirect
 | 
			
		||||
	github.com/mattn/go-runewidth v0.0.15 // indirect
 | 
			
		||||
	github.com/mattn/go-shellwords v1.0.12 // indirect
 | 
			
		||||
| 
						 | 
				
			
			@ -148,12 +148,12 @@ require (
 | 
			
		|||
	go.opentelemetry.io/otel/sdk v1.19.0 // indirect
 | 
			
		||||
	go.opentelemetry.io/otel/sdk/metric v1.19.0 // indirect
 | 
			
		||||
	go.opentelemetry.io/proto/otlp v1.0.0 // indirect
 | 
			
		||||
	golang.org/x/crypto v0.14.0 // indirect
 | 
			
		||||
	golang.org/x/crypto v0.17.0 // indirect
 | 
			
		||||
	golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
 | 
			
		||||
	golang.org/x/net v0.17.0 // indirect
 | 
			
		||||
	golang.org/x/oauth2 v0.10.0 // indirect
 | 
			
		||||
	golang.org/x/sys v0.13.0 // indirect
 | 
			
		||||
	golang.org/x/text v0.13.0 // indirect
 | 
			
		||||
	golang.org/x/sys v0.15.0 // indirect
 | 
			
		||||
	golang.org/x/text v0.14.0 // indirect
 | 
			
		||||
	golang.org/x/time v0.3.0 // indirect
 | 
			
		||||
	golang.org/x/tools v0.10.0 // indirect
 | 
			
		||||
	google.golang.org/appengine v1.6.7 // indirect
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										40
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										40
									
								
								go.sum
								
								
								
								
							| 
						 | 
				
			
			@ -119,15 +119,15 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 | 
			
		|||
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
 | 
			
		||||
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
 | 
			
		||||
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
 | 
			
		||||
github.com/docker/cli v25.0.0-beta.1+incompatible h1:bJzIgR4mKNpceAwwi19SqZK0AbztMc3nQTgnvxxyY/A=
 | 
			
		||||
github.com/docker/cli v25.0.0-beta.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 | 
			
		||||
github.com/docker/cli v25.0.0-rc.1+incompatible h1:TRaJCO3nQ0XvMWa8gUeIKRO8Dq61QQClpMWV0PmSDHA=
 | 
			
		||||
github.com/docker/cli v25.0.0-rc.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 | 
			
		||||
github.com/docker/cli-docs-tool v0.6.0 h1:Z9x10SaZgFaB6jHgz3OWooynhSa40CsWkpe5hEnG/qA=
 | 
			
		||||
github.com/docker/cli-docs-tool v0.6.0/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o=
 | 
			
		||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 | 
			
		||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
 | 
			
		||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 | 
			
		||||
github.com/docker/docker v25.0.0-beta.1+incompatible h1:NiDFwGzVt+mR9Jb5oC4+cd8lE9Zs86TXhCQg0zGk/sk=
 | 
			
		||||
github.com/docker/docker v25.0.0-beta.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 | 
			
		||||
github.com/docker/docker v25.0.0-rc.1+incompatible h1:Bdb06U1Z1P78uxluMZE6MI94tGICXzWnArsiW5hg6pU=
 | 
			
		||||
github.com/docker/docker v25.0.0-rc.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 | 
			
		||||
github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8=
 | 
			
		||||
github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40=
 | 
			
		||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
 | 
			
		||||
| 
						 | 
				
			
			@ -157,8 +157,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
 | 
			
		|||
github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
 | 
			
		||||
github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
 | 
			
		||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
 | 
			
		||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
 | 
			
		||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 | 
			
		||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
 | 
			
		||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 | 
			
		||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 | 
			
		||||
github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE=
 | 
			
		||||
github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
 | 
			
		||||
| 
						 | 
				
			
			@ -278,8 +278,8 @@ github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVE
 | 
			
		|||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 | 
			
		||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 | 
			
		||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 | 
			
		||||
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
 | 
			
		||||
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
 | 
			
		||||
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
 | 
			
		||||
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
 | 
			
		||||
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.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 | 
			
		||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 | 
			
		||||
| 
						 | 
				
			
			@ -317,8 +317,8 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZX
 | 
			
		|||
github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 | 
			
		||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
 | 
			
		||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 | 
			
		||||
github.com/moby/buildkit v0.13.0-beta1.0.20231219135447-957cb50df991 h1:r80LLQ91uOLxU1ElAvrB1o8oBsph51lPzVnr7t2b200=
 | 
			
		||||
github.com/moby/buildkit v0.13.0-beta1.0.20231219135447-957cb50df991/go.mod h1:6MddWPSL5jxy+W8eMMHWDOfZzzRRKWXPZqajw72YHBc=
 | 
			
		||||
github.com/moby/buildkit v0.13.0-beta1.0.20240105171016-6e200afad512 h1:jbAJul+OeYr9/mGeNDQc9Q4hd58Z/FXCehQ27ooD8JI=
 | 
			
		||||
github.com/moby/buildkit v0.13.0-beta1.0.20240105171016-6e200afad512/go.mod h1:9jtsOuy5EtZ13ArTt+RqH61qZ3Ik7kly25Qy4m0zSCk=
 | 
			
		||||
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/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
 | 
			
		||||
| 
						 | 
				
			
			@ -363,8 +363,8 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I
 | 
			
		|||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
 | 
			
		||||
github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
 | 
			
		||||
github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
 | 
			
		||||
github.com/opencontainers/runc v1.1.10 h1:EaL5WeO9lv9wmS6SASjszOeQdSctvpbu0DdBQBizE40=
 | 
			
		||||
github.com/opencontainers/runc v1.1.10/go.mod h1:+/R6+KmDlh+hOO8NkjmgkG9Qzvypzk0yXxAPYYR65+M=
 | 
			
		||||
github.com/opencontainers/runc v1.1.11 h1:9LjxyVlE0BPMRP2wuQDRlHV4941Jp9rc3F0+YKimopA=
 | 
			
		||||
github.com/opencontainers/runc v1.1.11/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8=
 | 
			
		||||
github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
 | 
			
		||||
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
 | 
			
		||||
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
 | 
			
		||||
| 
						 | 
				
			
			@ -519,8 +519,8 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
 | 
			
		|||
golang.org/x/crypto v0.0.0-20200422194213-44a606286825/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 | 
			
		||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
 | 
			
		||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
 | 
			
		||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
 | 
			
		||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
 | 
			
		||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 | 
			
		||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
 | 
			
		||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
 | 
			
		||||
| 
						 | 
				
			
			@ -574,16 +574,16 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc
 | 
			
		|||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
 | 
			
		||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
 | 
			
		||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
			
		||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 | 
			
		||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
 | 
			
		||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
 | 
			
		||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
 | 
			
		||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
 | 
			
		||||
golang.org/x/text v0.3.0/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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 | 
			
		||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
 | 
			
		||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 | 
			
		||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 | 
			
		||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 | 
			
		||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
 | 
			
		||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
# This file lists all contributors to the repository.
 | 
			
		||||
# See scripts/docs/generate-authors.sh to make modifications.
 | 
			
		||||
 | 
			
		||||
A. Lester Buck III <github-reg@nbolt.com>
 | 
			
		||||
Aanand Prasad <aanand.prasad@gmail.com>
 | 
			
		||||
Aaron L. Xu <liker.xu@foxmail.com>
 | 
			
		||||
Aaron Lehmann <alehmann@netflix.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +17,7 @@ Adolfo Ochagavía <aochagavia92@gmail.com>
 | 
			
		|||
Adrian Plata <adrian.plata@docker.com>
 | 
			
		||||
Adrien Duermael <adrien@duermael.com>
 | 
			
		||||
Adrien Folie <folie.adrien@gmail.com>
 | 
			
		||||
Adyanth Hosavalike <ahosavalike@ucsd.edu>
 | 
			
		||||
Ahmet Alp Balkan <ahmetb@microsoft.com>
 | 
			
		||||
Aidan Feldman <aidan.feldman@gmail.com>
 | 
			
		||||
Aidan Hobson Sayers <aidanhs@cantab.net>
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +28,7 @@ Akim Demaille <akim.demaille@docker.com>
 | 
			
		|||
Alan Thompson <cloojure@gmail.com>
 | 
			
		||||
Albert Callarisa <shark234@gmail.com>
 | 
			
		||||
Alberto Roura <mail@albertoroura.com>
 | 
			
		||||
Albin Kerouanton <albin@akerouanton.name>
 | 
			
		||||
Albin Kerouanton <albinker@gmail.com>
 | 
			
		||||
Aleksa Sarai <asarai@suse.de>
 | 
			
		||||
Aleksander Piotrowski <apiotrowski312@gmail.com>
 | 
			
		||||
Alessandro Boch <aboch@tetrationanalytics.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +36,7 @@ Alex Couture-Beil <alex@earthly.dev>
 | 
			
		|||
Alex Mavrogiannis <alex.mavrogiannis@docker.com>
 | 
			
		||||
Alex Mayer <amayer5125@gmail.com>
 | 
			
		||||
Alexander Boyd <alex@opengroove.org>
 | 
			
		||||
Alexander Chneerov <achneerov@gmail.com>
 | 
			
		||||
Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
Alexander Morozov <lk4d4math@gmail.com>
 | 
			
		||||
Alexander Ryabov <i@sepa.spb.ru>
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +44,7 @@ Alexandre González <agonzalezro@gmail.com>
 | 
			
		|||
Alexey Igrychev <alexey.igrychev@flant.com>
 | 
			
		||||
Alexis Couvreur <alexiscouvreur.pro@gmail.com>
 | 
			
		||||
Alfred Landrum <alfred.landrum@docker.com>
 | 
			
		||||
Ali Rostami <rostami.ali@gmail.com>
 | 
			
		||||
Alicia Lauerman <alicia@eta.im>
 | 
			
		||||
Allen Sun <allensun.shl@alibaba-inc.com>
 | 
			
		||||
Alvin Deng <alvin.q.deng@utexas.edu>
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +83,9 @@ Arko Dasgupta <arko@tetrate.io>
 | 
			
		|||
Arnaud Porterie <icecrime@gmail.com>
 | 
			
		||||
Arnaud Rebillout <elboulangero@gmail.com>
 | 
			
		||||
Arthur Peka <arthur.peka@outlook.com>
 | 
			
		||||
Ashly Mathew <ashly.mathew@sap.com>
 | 
			
		||||
Ashwini Oruganti <ashwini.oruganti@gmail.com>
 | 
			
		||||
Aslam Ahemad <aslamahemad@gmail.com>
 | 
			
		||||
Azat Khuyiyakhmetov <shadow_uz@mail.ru>
 | 
			
		||||
Bardia Keyoumarsi <bkeyouma@ucsc.edu>
 | 
			
		||||
Barnaby Gray <barnaby@pickle.me.uk>
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +104,9 @@ Bill Wang <ozbillwang@gmail.com>
 | 
			
		|||
Bin Liu <liubin0329@gmail.com>
 | 
			
		||||
Bingshen Wang <bingshen.wbs@alibaba-inc.com>
 | 
			
		||||
Bishal Das <bishalhnj127@gmail.com>
 | 
			
		||||
Bjorn Neergaard <bjorn.neergaard@docker.com>
 | 
			
		||||
Boaz Shuster <ripcurld.github@gmail.com>
 | 
			
		||||
Boban Acimovic <boban.acimovic@gmail.com>
 | 
			
		||||
Bogdan Anton <contact@bogdananton.ro>
 | 
			
		||||
Boris Pruessmann <boris@pruessmann.org>
 | 
			
		||||
Brad Baker <brad@brad.fi>
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +117,7 @@ Brent Salisbury <brent.salisbury@docker.com>
 | 
			
		|||
Bret Fisher <bret@bretfisher.com>
 | 
			
		||||
Brian (bex) Exelbierd <bexelbie@redhat.com>
 | 
			
		||||
Brian Goff <cpuguy83@gmail.com>
 | 
			
		||||
Brian Tracy <brian.tracy33@gmail.com>
 | 
			
		||||
Brian Wieder <brian@4wieders.com>
 | 
			
		||||
Bruno Sousa <bruno.sousa@docker.com>
 | 
			
		||||
Bryan Bess <squarejaw@bsbess.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -136,6 +145,7 @@ Chen Chuanliang <chen.chuanliang@zte.com.cn>
 | 
			
		|||
Chen Hanxiao <chenhanxiao@cn.fujitsu.com>
 | 
			
		||||
Chen Mingjie <chenmingjie0828@163.com>
 | 
			
		||||
Chen Qiu <cheney-90@hotmail.com>
 | 
			
		||||
Chris Chinchilla <chris@chrischinchilla.com>
 | 
			
		||||
Chris Couzens <ccouzens@gmail.com>
 | 
			
		||||
Chris Gavin <chris@chrisgavin.me>
 | 
			
		||||
Chris Gibson <chris@chrisg.io>
 | 
			
		||||
| 
						 | 
				
			
			@ -163,6 +173,8 @@ Conner Crosby <conner@cavcrosby.tech>
 | 
			
		|||
Corey Farrell <git@cfware.com>
 | 
			
		||||
Corey Quon <corey.quon@docker.com>
 | 
			
		||||
Cory Bennet <cbennett@netflix.com>
 | 
			
		||||
Cory Snider <csnider@mirantis.com>
 | 
			
		||||
Craig Osterhout <craig.osterhout@docker.com>
 | 
			
		||||
Craig Wilhite <crwilhit@microsoft.com>
 | 
			
		||||
Cristian Staretu <cristian.staretu@gmail.com>
 | 
			
		||||
Daehyeok Mun <daehyeok@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -171,6 +183,7 @@ Daisuke Ito <itodaisuke00@gmail.com>
 | 
			
		|||
dalanlan <dalanlan925@gmail.com>
 | 
			
		||||
Damien Nadé <github@livna.org>
 | 
			
		||||
Dan Cotora <dan@bluevision.ro>
 | 
			
		||||
Danial Gharib <danial.mail.gh@gmail.com>
 | 
			
		||||
Daniel Artine <daniel.artine@ufrj.br>
 | 
			
		||||
Daniel Cassidy <mail@danielcassidy.me.uk>
 | 
			
		||||
Daniel Dao <dqminh@cloudflare.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -210,6 +223,7 @@ Denis Defreyne <denis@soundcloud.com>
 | 
			
		|||
Denis Gladkikh <denis@gladkikh.email>
 | 
			
		||||
Denis Ollier <larchunix@users.noreply.github.com>
 | 
			
		||||
Dennis Docter <dennis@d23.nl>
 | 
			
		||||
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
 | 
			
		||||
Derek McGowan <derek@mcg.dev>
 | 
			
		||||
Des Preston <despreston@gmail.com>
 | 
			
		||||
Deshi Xiao <dxiao@redhat.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -232,11 +246,13 @@ DongGeon Lee <secmatth1996@gmail.com>
 | 
			
		|||
Doug Davis <dug@us.ibm.com>
 | 
			
		||||
Drew Erny <derny@mirantis.com>
 | 
			
		||||
Ed Costello <epc@epcostello.com>
 | 
			
		||||
Ed Morley <501702+edmorley@users.noreply.github.com>
 | 
			
		||||
Elango Sivanandam <elango.siva@docker.com>
 | 
			
		||||
Eli Uriegas <eli.uriegas@docker.com>
 | 
			
		||||
Eli Uriegas <seemethere101@gmail.com>
 | 
			
		||||
Elias Faxö <elias.faxo@tre.se>
 | 
			
		||||
Elliot Luo <956941328@qq.com>
 | 
			
		||||
Eric Bode <eric.bode@foundries.io>
 | 
			
		||||
Eric Curtin <ericcurtin17@gmail.com>
 | 
			
		||||
Eric Engestrom <eric@engestrom.ch>
 | 
			
		||||
Eric G. Noriega <enoriega@vizuri.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -254,6 +270,7 @@ Eugene Yakubovich <eugene.yakubovich@coreos.com>
 | 
			
		|||
Evan Allrich <evan@unguku.com>
 | 
			
		||||
Evan Hazlett <ejhazlett@gmail.com>
 | 
			
		||||
Evan Krall <krall@yelp.com>
 | 
			
		||||
Evan Lezar <elezar@nvidia.com>
 | 
			
		||||
Evelyn Xu <evelynhsu21@gmail.com>
 | 
			
		||||
Everett Toews <everett.toews@rackspace.com>
 | 
			
		||||
Fabio Falci <fabiofalci@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -275,6 +292,7 @@ Frederik Nordahl Jul Sabroe <frederikns@gmail.com>
 | 
			
		|||
Frieder Bluemle <frieder.bluemle@gmail.com>
 | 
			
		||||
Gabriel Gore <gabgore@cisco.com>
 | 
			
		||||
Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com>
 | 
			
		||||
Gabriela Georgieva <gabriela.georgieva@docker.com>
 | 
			
		||||
Gaetan de Villele <gdevillele@gmail.com>
 | 
			
		||||
Gang Qiao <qiaohai8866@gmail.com>
 | 
			
		||||
Gary Schaetz <gary@schaetzkc.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -288,6 +306,7 @@ Gleb Stsenov <gleb.stsenov@gmail.com>
 | 
			
		|||
Goksu Toprak <goksu.toprak@docker.com>
 | 
			
		||||
Gou Rao <gou@portworx.com>
 | 
			
		||||
Govind Rai <raigovind93@gmail.com>
 | 
			
		||||
Graeme Wiebe <graeme.wiebe@gmail.com>
 | 
			
		||||
Grant Reaber <grant.reaber@gmail.com>
 | 
			
		||||
Greg Pflaum <gpflaum@users.noreply.github.com>
 | 
			
		||||
Gsealy <jiaojingwei1001@hotmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -311,6 +330,7 @@ Hernan Garcia <hernandanielg@gmail.com>
 | 
			
		|||
Hongbin Lu <hongbin034@gmail.com>
 | 
			
		||||
Hu Keping <hukeping@huawei.com>
 | 
			
		||||
Huayi Zhang <irachex@gmail.com>
 | 
			
		||||
Hugo Chastel <Hugo-C@users.noreply.github.com>
 | 
			
		||||
Hugo Gabriel Eyherabide <hugogabriel.eyherabide@gmail.com>
 | 
			
		||||
huqun <huqun@zju.edu.cn>
 | 
			
		||||
Huu Nguyen <huu@prismskylabs.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -329,9 +349,12 @@ Ivan Grund <ivan.grund@gmail.com>
 | 
			
		|||
Ivan Markin <sw@nogoegst.net>
 | 
			
		||||
Jacob Atzen <jacob@jacobatzen.dk>
 | 
			
		||||
Jacob Tomlinson <jacob@tom.linson.uk>
 | 
			
		||||
Jacopo Rigoli <rigoli.jacopo@gmail.com>
 | 
			
		||||
Jaivish Kothari <janonymous.codevulture@gmail.com>
 | 
			
		||||
Jake Lambert <jake.lambert@volusion.com>
 | 
			
		||||
Jake Sanders <jsand@google.com>
 | 
			
		||||
Jake Stokes <contactjake@developerjake.com>
 | 
			
		||||
Jakub Panek <me@panekj.dev>
 | 
			
		||||
James Nesbitt <james.nesbitt@wunderkraut.com>
 | 
			
		||||
James Turnbull <james@lovedthanlost.net>
 | 
			
		||||
Jamie Hannaford <jamie@limetree.org>
 | 
			
		||||
| 
						 | 
				
			
			@ -408,10 +431,12 @@ Josh Chorlton <jchorlton@gmail.com>
 | 
			
		|||
Josh Hawn <josh.hawn@docker.com>
 | 
			
		||||
Josh Horwitz <horwitz@addthis.com>
 | 
			
		||||
Josh Soref <jsoref@gmail.com>
 | 
			
		||||
Julian <gitea+julian@ic.thejulian.uk>
 | 
			
		||||
Julien Barbier <write0@gmail.com>
 | 
			
		||||
Julien Kassar <github@kassisol.com>
 | 
			
		||||
Julien Maitrehenry <julien.maitrehenry@me.com>
 | 
			
		||||
Justas Brazauskas <brazauskasjustas@gmail.com>
 | 
			
		||||
Justin Chadwell <me@jedevc.com>
 | 
			
		||||
Justin Cormack <justin.cormack@docker.com>
 | 
			
		||||
Justin Simonelis <justin.p.simonelis@gmail.com>
 | 
			
		||||
Justyn Temme <justyntemme@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -434,7 +459,7 @@ Kelton Bassingthwaite <KeltonBassingthwaite@gmail.com>
 | 
			
		|||
Ken Cochrane <kencochrane@gmail.com>
 | 
			
		||||
Ken ICHIKAWA <ichikawa.ken@jp.fujitsu.com>
 | 
			
		||||
Kenfe-Mickaël Laventure <mickael.laventure@gmail.com>
 | 
			
		||||
Kevin Alvarez <crazy-max@users.noreply.github.com>
 | 
			
		||||
Kevin Alvarez <github@crazymax.dev>
 | 
			
		||||
Kevin Burke <kev@inburke.com>
 | 
			
		||||
Kevin Feyrer <kevin.feyrer@btinternet.com>
 | 
			
		||||
Kevin Kern <kaiwentan@harmonycloud.cn>
 | 
			
		||||
| 
						 | 
				
			
			@ -454,6 +479,7 @@ Kyle Mitofsky <Kylemit@gmail.com>
 | 
			
		|||
Lachlan Cooper <lachlancooper@gmail.com>
 | 
			
		||||
Lai Jiangshan <jiangshanlai@gmail.com>
 | 
			
		||||
Lars Kellogg-Stedman <lars@redhat.com>
 | 
			
		||||
Laura Brehm <laurabrehm@hey.com>
 | 
			
		||||
Laura Frank <ljfrank@gmail.com>
 | 
			
		||||
Laurent Erignoux <lerignoux@gmail.com>
 | 
			
		||||
Lee Gaines <eightlimbed@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -462,10 +488,10 @@ Lennie <github@consolejunkie.net>
 | 
			
		|||
Leo Gallucci <elgalu3@gmail.com>
 | 
			
		||||
Leonid Skorospelov <leosko94@gmail.com>
 | 
			
		||||
Lewis Daly <lewisdaly@me.com>
 | 
			
		||||
Li Fu Bang <lifubang@acmcoder.com>
 | 
			
		||||
Li Yi <denverdino@gmail.com>
 | 
			
		||||
Li Yi <weiyuan.yl@alibaba-inc.com>
 | 
			
		||||
Liang-Chi Hsieh <viirya@gmail.com>
 | 
			
		||||
Lifubang <lifubang@acmcoder.com>
 | 
			
		||||
Lihua Tang <lhtang@alauda.io>
 | 
			
		||||
Lily Guo <lily.guo@docker.com>
 | 
			
		||||
Lin Lu <doraalin@163.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -480,6 +506,7 @@ Louis Opter <kalessin@kalessin.fr>
 | 
			
		|||
Luca Favatella <luca.favatella@erlang-solutions.com>
 | 
			
		||||
Luca Marturana <lucamarturana@gmail.com>
 | 
			
		||||
Lucas Chan <lucas-github@lucaschan.com>
 | 
			
		||||
Luis Henrique Mulinari <luis.mulinari@gmail.com>
 | 
			
		||||
Luka Hartwig <mail@lukahartwig.de>
 | 
			
		||||
Lukas Heeren <lukas-heeren@hotmail.com>
 | 
			
		||||
Lukasz Zajaczkowski <Lukasz.Zajaczkowski@ts.fujitsu.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -498,6 +525,7 @@ mapk0y <mapk0y@gmail.com>
 | 
			
		|||
Marc Bihlmaier <marc.bihlmaier@reddoxx.com>
 | 
			
		||||
Marc Cornellà <hello@mcornella.com>
 | 
			
		||||
Marco Mariani <marco.mariani@alterway.fr>
 | 
			
		||||
Marco Spiess <marco.spiess@hotmail.de>
 | 
			
		||||
Marco Vedovati <mvedovati@suse.com>
 | 
			
		||||
Marcus Martins <marcus@docker.com>
 | 
			
		||||
Marianna Tessel <mtesselh@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -522,6 +550,7 @@ Max Shytikov <mshytikov@gmail.com>
 | 
			
		|||
Maxime Petazzoni <max@signalfuse.com>
 | 
			
		||||
Maximillian Fan Xavier <maximillianfx@gmail.com>
 | 
			
		||||
Mei ChunTao <mei.chuntao@zte.com.cn>
 | 
			
		||||
Melroy van den Berg <melroy@melroy.org>
 | 
			
		||||
Metal <2466052+tedhexaflow@users.noreply.github.com>
 | 
			
		||||
Micah Zoltu <micah@newrelic.com>
 | 
			
		||||
Michael A. Smith <michael@smith-li.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -593,6 +622,7 @@ Nishant Totla <nishanttotla@gmail.com>
 | 
			
		|||
NIWA Hideyuki <niwa.niwa@nifty.ne.jp>
 | 
			
		||||
Noah Treuhaft <noah.treuhaft@docker.com>
 | 
			
		||||
O.S. Tezer <ostezer@gmail.com>
 | 
			
		||||
Oded Arbel <oded@geek.co.il>
 | 
			
		||||
Odin Ugedal <odin@ugedal.com>
 | 
			
		||||
ohmystack <jun.jiang02@ele.me>
 | 
			
		||||
OKA Naoya <git@okanaoya.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -604,19 +634,21 @@ Otto Kekäläinen <otto@seravo.fi>
 | 
			
		|||
Ovidio Mallo <ovidio.mallo@gmail.com>
 | 
			
		||||
Pascal Borreli <pascal@borreli.com>
 | 
			
		||||
Patrick Böänziger <patrick.baenziger@bsi-software.com>
 | 
			
		||||
Patrick Daigle <114765035+pdaig@users.noreply.github.com>
 | 
			
		||||
Patrick Hemmer <patrick.hemmer@gmail.com>
 | 
			
		||||
Patrick Lang <plang@microsoft.com>
 | 
			
		||||
Paul <paul9869@gmail.com>
 | 
			
		||||
Paul Kehrer <paul.l.kehrer@gmail.com>
 | 
			
		||||
Paul Lietar <paul@lietar.net>
 | 
			
		||||
Paul Mulders <justinkb@gmail.com>
 | 
			
		||||
Paul Seyfert <pseyfert.mathphys@gmail.com>
 | 
			
		||||
Paul Weaver <pauweave@cisco.com>
 | 
			
		||||
Pavel Pospisil <pospispa@gmail.com>
 | 
			
		||||
Paweł Gronowski <pawel.gronowski@docker.com>
 | 
			
		||||
Paweł Pokrywka <pepawel@users.noreply.github.com>
 | 
			
		||||
Paweł Szczekutowicz <pszczekutowicz@gmail.com>
 | 
			
		||||
Peeyush Gupta <gpeeyush@linux.vnet.ibm.com>
 | 
			
		||||
Per Lundberg <per.lundberg@ecraft.com>
 | 
			
		||||
Per Lundberg <perlun@gmail.com>
 | 
			
		||||
Peter Dave Hello <hsu@peterdavehello.org>
 | 
			
		||||
Peter Edge <peter.edge@gmail.com>
 | 
			
		||||
Peter Hsu <shhsu@microsoft.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -639,6 +671,7 @@ Preston Cowley <preston.cowley@sony.com>
 | 
			
		|||
Pure White <daniel48@126.com>
 | 
			
		||||
Qiang Huang <h.huangqiang@huawei.com>
 | 
			
		||||
Qinglan Peng <qinglanpeng@zju.edu.cn>
 | 
			
		||||
QQ喵 <gqqnb2005@gmail.com>
 | 
			
		||||
qudongfang <qudongfang@gmail.com>
 | 
			
		||||
Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>
 | 
			
		||||
Rahul Kadyan <hi@znck.me>
 | 
			
		||||
| 
						 | 
				
			
			@ -657,6 +690,7 @@ Rick Wieman <git@rickw.nl>
 | 
			
		|||
Ritesh H Shukla <sritesh@vmware.com>
 | 
			
		||||
Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
 | 
			
		||||
Rob Gulewich <rgulewich@netflix.com>
 | 
			
		||||
Rob Murray <rob.murray@docker.com>
 | 
			
		||||
Robert Wallis <smilingrob@gmail.com>
 | 
			
		||||
Robin Naundorf <r.naundorf@fh-muenster.de>
 | 
			
		||||
Robin Speekenbrink <robin@kingsquare.nl>
 | 
			
		||||
| 
						 | 
				
			
			@ -689,6 +723,7 @@ Sandro Jäckel <sandro.jaeckel@gmail.com>
 | 
			
		|||
Santhosh Manohar <santhosh@docker.com>
 | 
			
		||||
Sargun Dhillon <sargun@netflix.com>
 | 
			
		||||
Saswat Bhattacharya <sas.saswat@gmail.com>
 | 
			
		||||
Saurabh Kumar <saurabhkumar0184@gmail.com>
 | 
			
		||||
Scott Brenner <scott@scottbrenner.me>
 | 
			
		||||
Scott Collier <emailscottcollier@gmail.com>
 | 
			
		||||
Sean Christopherson <sean.j.christopherson@intel.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -788,6 +823,7 @@ uhayate <uhayate.gong@daocloud.io>
 | 
			
		|||
Ulrich Bareth <ulrich.bareth@gmail.com>
 | 
			
		||||
Ulysses Souza <ulysses.souza@docker.com>
 | 
			
		||||
Umesh Yadav <umesh4257@gmail.com>
 | 
			
		||||
Vaclav Struhar <struharv@gmail.com>
 | 
			
		||||
Valentin Lorentz <progval+git@progval.net>
 | 
			
		||||
Vardan Pogosian <vardan.pogosyan@gmail.com>
 | 
			
		||||
Venkateswara Reddy Bukkasamudram <bukkasamudram@outlook.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -795,6 +831,7 @@ Veres Lajos <vlajos@gmail.com>
 | 
			
		|||
Victor Vieux <victor.vieux@docker.com>
 | 
			
		||||
Victoria Bialas <victoria.bialas@docker.com>
 | 
			
		||||
Viktor Stanchev <me@viktorstanchev.com>
 | 
			
		||||
Ville Skyttä <ville.skytta@iki.fi>
 | 
			
		||||
Vimal Raghubir <vraghubir0418@gmail.com>
 | 
			
		||||
Vincent Batts <vbatts@redhat.com>
 | 
			
		||||
Vincent Bernat <Vincent.Bernat@exoscale.ch>
 | 
			
		||||
| 
						 | 
				
			
			@ -831,6 +868,7 @@ Yong Tang <yong.tang.github@outlook.com>
 | 
			
		|||
Yosef Fertel <yfertel@gmail.com>
 | 
			
		||||
Yu Peng <yu.peng36@zte.com.cn>
 | 
			
		||||
Yuan Sun <sunyuan3@huawei.com>
 | 
			
		||||
Yucheng Wu <wyc123wyc@gmail.com>
 | 
			
		||||
Yue Zhang <zy675793960@yeah.net>
 | 
			
		||||
Yunxiang Huang <hyxqshk@vip.qq.com>
 | 
			
		||||
Zachary Romero <zacromero3@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package manager
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +46,6 @@ func wrapAsPluginError(err error, msg string) error {
 | 
			
		|||
 | 
			
		||||
// NewPluginError creates a new pluginError, analogous to
 | 
			
		||||
// errors.Errorf.
 | 
			
		||||
func NewPluginError(msg string, args ...interface{}) error {
 | 
			
		||||
func NewPluginError(msg string, args ...any) error {
 | 
			
		||||
	return &pluginError{cause: errors.Errorf(msg, args...)}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,12 @@
 | 
			
		|||
package plugin
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +18,11 @@ import (
 | 
			
		|||
	"github.com/spf13/cobra"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CLIPluginSocketEnvKey is used to pass the plugin being
 | 
			
		||||
// executed the abstract socket name it should listen on to know
 | 
			
		||||
// when the CLI has exited.
 | 
			
		||||
const CLIPluginSocketEnvKey = "DOCKER_CLI_PLUGIN_SOCKET"
 | 
			
		||||
 | 
			
		||||
// PersistentPreRunE must be called by any plugin command (or
 | 
			
		||||
// subcommand) which uses the cobra `PersistentPreRun*` hook. Plugins
 | 
			
		||||
// which do not make use of `PersistentPreRun*` do not need to call
 | 
			
		||||
| 
						 | 
				
			
			@ -24,15 +33,57 @@ import (
 | 
			
		|||
// called.
 | 
			
		||||
var PersistentPreRunE func(*cobra.Command, []string) error
 | 
			
		||||
 | 
			
		||||
// closeOnCLISocketClose connects to the socket specified
 | 
			
		||||
// by the DOCKER_CLI_PLUGIN_SOCKET env var, if present, and attempts
 | 
			
		||||
// to read from it until it receives an EOF, which signals that
 | 
			
		||||
// the CLI is going to exit and the plugin should also exit.
 | 
			
		||||
func closeOnCLISocketClose(cancel func()) {
 | 
			
		||||
	socketAddr, ok := os.LookupEnv(CLIPluginSocketEnvKey)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		// if a plugin compiled against a more recent version of docker/cli
 | 
			
		||||
		// is executed by an older CLI binary, ignore missing environment
 | 
			
		||||
		// variable and behave as usual
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	addr, err := net.ResolveUnixAddr("unix", socketAddr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	cliCloseConn, err := net.DialUnix("unix", nil, addr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	go func() {
 | 
			
		||||
		b := make([]byte, 1)
 | 
			
		||||
		for {
 | 
			
		||||
			_, err := cliCloseConn.Read(b)
 | 
			
		||||
			if errors.Is(err, io.EOF) {
 | 
			
		||||
				cancel()
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RunPlugin executes the specified plugin command
 | 
			
		||||
func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager.Metadata) error {
 | 
			
		||||
	tcmd := newPluginCommand(dockerCli, plugin, meta)
 | 
			
		||||
 | 
			
		||||
	var persistentPreRunOnce sync.Once
 | 
			
		||||
	PersistentPreRunE = func(_ *cobra.Command, _ []string) error {
 | 
			
		||||
	PersistentPreRunE = func(cmd *cobra.Command, _ []string) error {
 | 
			
		||||
		var err error
 | 
			
		||||
		persistentPreRunOnce.Do(func() {
 | 
			
		||||
			var opts []command.InitializeOpt
 | 
			
		||||
			cmdContext := cmd.Context()
 | 
			
		||||
			// TODO: revisit and make sure this check makes sense
 | 
			
		||||
			// see: https://github.com/docker/cli/pull/4599#discussion_r1422487271
 | 
			
		||||
			if cmdContext == nil {
 | 
			
		||||
				cmdContext = context.TODO()
 | 
			
		||||
			}
 | 
			
		||||
			ctx, cancel := context.WithCancel(cmdContext)
 | 
			
		||||
			cmd.SetContext(ctx)
 | 
			
		||||
			closeOnCLISocketClose(cancel)
 | 
			
		||||
 | 
			
		||||
			var opts []command.CLIOption
 | 
			
		||||
			if os.Getenv("DOCKER_CLI_PLUGIN_USE_DIAL_STDIO") != "" {
 | 
			
		||||
				opts = append(opts, withPluginClientConn(plugin.Name()))
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +129,7 @@ func Run(makeCmd func(command.Cli) *cobra.Command, meta manager.Metadata) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func withPluginClientConn(name string) command.InitializeOpt {
 | 
			
		||||
func withPluginClientConn(name string) command.CLIOption {
 | 
			
		||||
	return command.WithInitializeClient(func(dockerCli *command.DockerCli) (client.APIClient, error) {
 | 
			
		||||
		cmd := "docker"
 | 
			
		||||
		if x := os.Getenv(manager.ReexecEnvvar); x != "" {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -176,7 +176,7 @@ func (tcmd *TopLevelCommand) HandleGlobalFlags() (*cobra.Command, []string, erro
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// Initialize finalises global option parsing and initializes the docker client.
 | 
			
		||||
func (tcmd *TopLevelCommand) Initialize(ops ...command.InitializeOpt) error {
 | 
			
		||||
func (tcmd *TopLevelCommand) Initialize(ops ...command.CLIOption) error {
 | 
			
		||||
	tcmd.opts.SetDefaultOptions(tcmd.flags)
 | 
			
		||||
	return tcmd.dockerCli.Initialize(tcmd.opts, ops...)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package command
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +52,7 @@ type Cli interface {
 | 
			
		|||
	Client() client.APIClient
 | 
			
		||||
	Streams
 | 
			
		||||
	SetIn(in *streams.In)
 | 
			
		||||
	Apply(ops ...DockerCliOption) error
 | 
			
		||||
	Apply(ops ...CLIOption) error
 | 
			
		||||
	ConfigFile() *configfile.ConfigFile
 | 
			
		||||
	ServerInfo() ServerInfo
 | 
			
		||||
	NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +85,11 @@ type DockerCli struct {
 | 
			
		|||
	dockerEndpoint     docker.Endpoint
 | 
			
		||||
	contextStoreConfig store.Config
 | 
			
		||||
	initTimeout        time.Duration
 | 
			
		||||
 | 
			
		||||
	// baseCtx is the base context used for internal operations. In the future
 | 
			
		||||
	// this may be replaced by explicitly passing a context to functions that
 | 
			
		||||
	// need it.
 | 
			
		||||
	baseCtx context.Context
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DefaultVersion returns api.defaultVersion.
 | 
			
		||||
| 
						 | 
				
			
			@ -194,11 +202,8 @@ func (cli *DockerCli) RegistryClient(allowInsecure bool) registryclient.Registry
 | 
			
		|||
	return registryclient.NewRegistryClient(resolver, UserAgent(), allowInsecure)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InitializeOpt is the type of the functional options passed to DockerCli.Initialize
 | 
			
		||||
type InitializeOpt func(dockerCli *DockerCli) error
 | 
			
		||||
 | 
			
		||||
// WithInitializeClient is passed to DockerCli.Initialize by callers who wish to set a particular API Client for use by the CLI.
 | 
			
		||||
func WithInitializeClient(makeClient func(dockerCli *DockerCli) (client.APIClient, error)) InitializeOpt {
 | 
			
		||||
func WithInitializeClient(makeClient func(dockerCli *DockerCli) (client.APIClient, error)) CLIOption {
 | 
			
		||||
	return func(dockerCli *DockerCli) error {
 | 
			
		||||
		var err error
 | 
			
		||||
		dockerCli.client, err = makeClient(dockerCli)
 | 
			
		||||
| 
						 | 
				
			
			@ -208,7 +213,7 @@ func WithInitializeClient(makeClient func(dockerCli *DockerCli) (client.APIClien
 | 
			
		|||
 | 
			
		||||
// Initialize the dockerCli runs initialization that must happen after command
 | 
			
		||||
// line flags are parsed.
 | 
			
		||||
func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...InitializeOpt) error {
 | 
			
		||||
func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...CLIOption) error {
 | 
			
		||||
	for _, o := range ops {
 | 
			
		||||
		if err := o(cli); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
| 
						 | 
				
			
			@ -323,8 +328,7 @@ func (cli *DockerCli) getInitTimeout() time.Duration {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (cli *DockerCli) initializeFromClient() {
 | 
			
		||||
	ctx := context.Background()
 | 
			
		||||
	ctx, cancel := context.WithTimeout(ctx, cli.getInitTimeout())
 | 
			
		||||
	ctx, cancel := context.WithTimeout(cli.baseCtx, cli.getInitTimeout())
 | 
			
		||||
	defer cancel()
 | 
			
		||||
 | 
			
		||||
	ping, err := cli.client.Ping(ctx)
 | 
			
		||||
| 
						 | 
				
			
			@ -394,7 +398,7 @@ func (cli *DockerCli) CurrentContext() string {
 | 
			
		|||
// occur when trying to use it.
 | 
			
		||||
//
 | 
			
		||||
// Refer to [DockerCli.CurrentContext] above for further details.
 | 
			
		||||
func resolveContextName(opts *cliflags.ClientOptions, config *configfile.ConfigFile) string {
 | 
			
		||||
func resolveContextName(opts *cliflags.ClientOptions, cfg *configfile.ConfigFile) string {
 | 
			
		||||
	if opts != nil && opts.Context != "" {
 | 
			
		||||
		return opts.Context
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -407,9 +411,9 @@ func resolveContextName(opts *cliflags.ClientOptions, config *configfile.ConfigF
 | 
			
		|||
	if ctxName := os.Getenv(EnvOverrideContext); ctxName != "" {
 | 
			
		||||
		return ctxName
 | 
			
		||||
	}
 | 
			
		||||
	if config != nil && config.CurrentContext != "" {
 | 
			
		||||
	if cfg != nil && cfg.CurrentContext != "" {
 | 
			
		||||
		// We don't validate if this context exists: errors may occur when trying to use it.
 | 
			
		||||
		return config.CurrentContext
 | 
			
		||||
		return cfg.CurrentContext
 | 
			
		||||
	}
 | 
			
		||||
	return DefaultContextName
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -444,13 +448,16 @@ func (cli *DockerCli) initialize() error {
 | 
			
		|||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if cli.baseCtx == nil {
 | 
			
		||||
			cli.baseCtx = context.Background()
 | 
			
		||||
		}
 | 
			
		||||
		cli.initializeFromClient()
 | 
			
		||||
	})
 | 
			
		||||
	return cli.initErr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Apply all the operation on the cli
 | 
			
		||||
func (cli *DockerCli) Apply(ops ...DockerCliOption) error {
 | 
			
		||||
func (cli *DockerCli) Apply(ops ...CLIOption) error {
 | 
			
		||||
	for _, op := range ops {
 | 
			
		||||
		if err := op(cli); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
| 
						 | 
				
			
			@ -479,15 +486,15 @@ type ServerInfo struct {
 | 
			
		|||
// NewDockerCli returns a DockerCli instance with all operators applied on it.
 | 
			
		||||
// It applies by default the standard streams, and the content trust from
 | 
			
		||||
// environment.
 | 
			
		||||
func NewDockerCli(ops ...DockerCliOption) (*DockerCli, error) {
 | 
			
		||||
	defaultOps := []DockerCliOption{
 | 
			
		||||
func NewDockerCli(ops ...CLIOption) (*DockerCli, error) {
 | 
			
		||||
	defaultOps := []CLIOption{
 | 
			
		||||
		WithContentTrustFromEnv(),
 | 
			
		||||
		WithDefaultContextStoreConfig(),
 | 
			
		||||
		WithStandardStreams(),
 | 
			
		||||
	}
 | 
			
		||||
	ops = append(defaultOps, ops...)
 | 
			
		||||
 | 
			
		||||
	cli := &DockerCli{}
 | 
			
		||||
	cli := &DockerCli{baseCtx: context.Background()}
 | 
			
		||||
	if err := cli.Apply(ops...); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -514,7 +521,7 @@ func UserAgent() string {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
var defaultStoreEndpoints = []store.NamedTypeGetter{
 | 
			
		||||
	store.EndpointTypeGetter(docker.DockerEndpoint, func() interface{} { return &docker.EndpointMeta{} }),
 | 
			
		||||
	store.EndpointTypeGetter(docker.DockerEndpoint, func() any { return &docker.EndpointMeta{} }),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RegisterDefaultStoreEndpoints registers a new named endpoint
 | 
			
		||||
| 
						 | 
				
			
			@ -528,7 +535,7 @@ func RegisterDefaultStoreEndpoints(ep ...store.NamedTypeGetter) {
 | 
			
		|||
// DefaultContextStoreConfig returns a new store.Config with the default set of endpoints configured.
 | 
			
		||||
func DefaultContextStoreConfig() store.Config {
 | 
			
		||||
	return store.NewConfig(
 | 
			
		||||
		func() interface{} { return &DockerContext{} },
 | 
			
		||||
		func() any { return &DockerContext{} },
 | 
			
		||||
		defaultStoreEndpoints...,
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
package command
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
| 
						 | 
				
			
			@ -10,11 +11,21 @@ import (
 | 
			
		|||
	"github.com/moby/term"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CLIOption applies a modification on a DockerCli.
 | 
			
		||||
type CLIOption func(cli *DockerCli) error
 | 
			
		||||
 | 
			
		||||
// DockerCliOption applies a modification on a DockerCli.
 | 
			
		||||
type DockerCliOption func(cli *DockerCli) error
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: use [CLIOption] instead.
 | 
			
		||||
type DockerCliOption = CLIOption
 | 
			
		||||
 | 
			
		||||
// InitializeOpt is the type of the functional options passed to DockerCli.Initialize
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: use [CLIOption] instead.
 | 
			
		||||
type InitializeOpt = CLIOption
 | 
			
		||||
 | 
			
		||||
// WithStandardStreams sets a cli in, out and err streams with the standard streams.
 | 
			
		||||
func WithStandardStreams() DockerCliOption {
 | 
			
		||||
func WithStandardStreams() CLIOption {
 | 
			
		||||
	return func(cli *DockerCli) error {
 | 
			
		||||
		// Set terminal emulation based on platform as required.
 | 
			
		||||
		stdin, stdout, stderr := term.StdStreams()
 | 
			
		||||
| 
						 | 
				
			
			@ -25,8 +36,17 @@ func WithStandardStreams() DockerCliOption {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithBaseContext sets the base context of a cli. It is used to propagate
 | 
			
		||||
// the context from the command line to the client.
 | 
			
		||||
func WithBaseContext(ctx context.Context) CLIOption {
 | 
			
		||||
	return func(cli *DockerCli) error {
 | 
			
		||||
		cli.baseCtx = ctx
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithCombinedStreams uses the same stream for the output and error streams.
 | 
			
		||||
func WithCombinedStreams(combined io.Writer) DockerCliOption {
 | 
			
		||||
func WithCombinedStreams(combined io.Writer) CLIOption {
 | 
			
		||||
	return func(cli *DockerCli) error {
 | 
			
		||||
		cli.out = streams.NewOut(combined)
 | 
			
		||||
		cli.err = combined
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +55,7 @@ func WithCombinedStreams(combined io.Writer) DockerCliOption {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// WithInputStream sets a cli input stream.
 | 
			
		||||
func WithInputStream(in io.ReadCloser) DockerCliOption {
 | 
			
		||||
func WithInputStream(in io.ReadCloser) CLIOption {
 | 
			
		||||
	return func(cli *DockerCli) error {
 | 
			
		||||
		cli.in = streams.NewIn(in)
 | 
			
		||||
		return nil
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +63,7 @@ func WithInputStream(in io.ReadCloser) DockerCliOption {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// WithOutputStream sets a cli output stream.
 | 
			
		||||
func WithOutputStream(out io.Writer) DockerCliOption {
 | 
			
		||||
func WithOutputStream(out io.Writer) CLIOption {
 | 
			
		||||
	return func(cli *DockerCli) error {
 | 
			
		||||
		cli.out = streams.NewOut(out)
 | 
			
		||||
		return nil
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +71,7 @@ func WithOutputStream(out io.Writer) DockerCliOption {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// WithErrorStream sets a cli error stream.
 | 
			
		||||
func WithErrorStream(err io.Writer) DockerCliOption {
 | 
			
		||||
func WithErrorStream(err io.Writer) CLIOption {
 | 
			
		||||
	return func(cli *DockerCli) error {
 | 
			
		||||
		cli.err = err
 | 
			
		||||
		return nil
 | 
			
		||||
| 
						 | 
				
			
			@ -59,7 +79,7 @@ func WithErrorStream(err io.Writer) DockerCliOption {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// WithContentTrustFromEnv enables content trust on a cli from environment variable DOCKER_CONTENT_TRUST value.
 | 
			
		||||
func WithContentTrustFromEnv() DockerCliOption {
 | 
			
		||||
func WithContentTrustFromEnv() CLIOption {
 | 
			
		||||
	return func(cli *DockerCli) error {
 | 
			
		||||
		cli.contentTrust = false
 | 
			
		||||
		if e := os.Getenv("DOCKER_CONTENT_TRUST"); e != "" {
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +93,7 @@ func WithContentTrustFromEnv() DockerCliOption {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// WithContentTrust enables content trust on a cli.
 | 
			
		||||
func WithContentTrust(enabled bool) DockerCliOption {
 | 
			
		||||
func WithContentTrust(enabled bool) CLIOption {
 | 
			
		||||
	return func(cli *DockerCli) error {
 | 
			
		||||
		cli.contentTrust = enabled
 | 
			
		||||
		return nil
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +101,7 @@ func WithContentTrust(enabled bool) DockerCliOption {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// WithDefaultContextStoreConfig configures the cli to use the default context store configuration.
 | 
			
		||||
func WithDefaultContextStoreConfig() DockerCliOption {
 | 
			
		||||
func WithDefaultContextStoreConfig() CLIOption {
 | 
			
		||||
	return func(cli *DockerCli) error {
 | 
			
		||||
		cli.contextStoreConfig = DefaultContextStoreConfig()
 | 
			
		||||
		return nil
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +109,7 @@ func WithDefaultContextStoreConfig() DockerCliOption {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// WithAPIClient configures the cli to use the given API client.
 | 
			
		||||
func WithAPIClient(c client.APIClient) DockerCliOption {
 | 
			
		||||
func WithAPIClient(c client.APIClient) CLIOption {
 | 
			
		||||
	return func(cli *DockerCli) error {
 | 
			
		||||
		cli.client = c
 | 
			
		||||
		return nil
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package command
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -10,12 +13,12 @@ import (
 | 
			
		|||
// DockerContext is a typed representation of what we put in Context metadata
 | 
			
		||||
type DockerContext struct {
 | 
			
		||||
	Description      string
 | 
			
		||||
	AdditionalFields map[string]interface{}
 | 
			
		||||
	AdditionalFields map[string]any
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalJSON implements custom JSON marshalling
 | 
			
		||||
func (dc DockerContext) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	s := map[string]interface{}{}
 | 
			
		||||
	s := map[string]any{}
 | 
			
		||||
	if dc.Description != "" {
 | 
			
		||||
		s["Description"] = dc.Description
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +32,7 @@ func (dc DockerContext) MarshalJSON() ([]byte, error) {
 | 
			
		|||
 | 
			
		||||
// UnmarshalJSON implements custom JSON marshalling
 | 
			
		||||
func (dc *DockerContext) UnmarshalJSON(payload []byte) error {
 | 
			
		||||
	var data map[string]interface{}
 | 
			
		||||
	var data map[string]any
 | 
			
		||||
	if err := json.Unmarshal(payload, &data); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +42,7 @@ func (dc *DockerContext) UnmarshalJSON(payload []byte) error {
 | 
			
		|||
			dc.Description = v.(string)
 | 
			
		||||
		default:
 | 
			
		||||
			if dc.AdditionalFields == nil {
 | 
			
		||||
				dc.AdditionalFields = make(map[string]interface{})
 | 
			
		||||
				dc.AdditionalFields = make(map[string]any)
 | 
			
		||||
			}
 | 
			
		||||
			dc.AdditionalFields[k] = v
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package command
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +47,9 @@ type EndpointDefaultResolver interface {
 | 
			
		|||
	// the lack of a default (e.g. because the config file which
 | 
			
		||||
	// would contain it is missing). If there is no default then
 | 
			
		||||
	// returns nil, nil, nil.
 | 
			
		||||
	ResolveDefault() (interface{}, *store.EndpointTLSData, error)
 | 
			
		||||
	//
 | 
			
		||||
	//nolint:dupword // ignore "Duplicate words (nil,) found"
 | 
			
		||||
	ResolveDefault() (any, *store.EndpointTLSData, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResolveDefaultContext creates a Metadata for the current CLI invocation parameters
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +58,7 @@ func ResolveDefaultContext(opts *cliflags.ClientOptions, config store.Config) (*
 | 
			
		|||
		Endpoints: make(map[string]store.EndpointTLSData),
 | 
			
		||||
	}
 | 
			
		||||
	contextMetadata := store.Metadata{
 | 
			
		||||
		Endpoints: make(map[string]interface{}),
 | 
			
		||||
		Endpoints: make(map[string]any),
 | 
			
		||||
		Metadata: DockerContext{
 | 
			
		||||
			Description: "",
 | 
			
		||||
		},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
package formatter
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -171,13 +171,13 @@ func (c *buildCacheContext) LastUsedSince() string {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (c *buildCacheContext) UsageCount() string {
 | 
			
		||||
	return fmt.Sprintf("%d", c.v.UsageCount)
 | 
			
		||||
	return strconv.Itoa(c.v.UsageCount)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *buildCacheContext) InUse() string {
 | 
			
		||||
	return fmt.Sprintf("%t", c.v.InUse)
 | 
			
		||||
	return strconv.FormatBool(c.v.InUse)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *buildCacheContext) Shared() string {
 | 
			
		||||
	return fmt.Sprintf("%t", c.v.Shared)
 | 
			
		||||
	return strconv.FormatBool(c.v.Shared)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package formatter
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +89,7 @@ type ContainerContext struct {
 | 
			
		|||
	// used in the template. It's currently only used to detect use of the .Size
 | 
			
		||||
	// field which (if used) automatically sets the '--size' option when making
 | 
			
		||||
	// the API call.
 | 
			
		||||
	FieldsUsed map[string]interface{}
 | 
			
		||||
	FieldsUsed map[string]any
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewContainerContext creates a new context for rendering containers
 | 
			
		||||
| 
						 | 
				
			
			@ -226,7 +229,7 @@ func (c *ContainerContext) Status() string {
 | 
			
		|||
// Size returns the container's size and virtual size (e.g. "2B (virtual 21.5MB)")
 | 
			
		||||
func (c *ContainerContext) Size() string {
 | 
			
		||||
	if c.FieldsUsed == nil {
 | 
			
		||||
		c.FieldsUsed = map[string]interface{}{}
 | 
			
		||||
		c.FieldsUsed = map[string]any{}
 | 
			
		||||
	}
 | 
			
		||||
	c.FieldsUsed["Size"] = struct{}{}
 | 
			
		||||
	srw := units.HumanSizeWithPrecision(float64(c.c.SizeRw), 3)
 | 
			
		||||
| 
						 | 
				
			
			@ -245,7 +248,7 @@ func (c *ContainerContext) Labels() string {
 | 
			
		|||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var joinLabels []string
 | 
			
		||||
	joinLabels := make([]string, 0, len(c.c.Labels))
 | 
			
		||||
	for k, v := range c.c.Labels {
 | 
			
		||||
		joinLabels = append(joinLabels, k+"="+v)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -265,7 +268,7 @@ func (c *ContainerContext) Label(name string) string {
 | 
			
		|||
// If the trunc option is set, names can be truncated (ellipsized).
 | 
			
		||||
func (c *ContainerContext) Mounts() string {
 | 
			
		||||
	var name string
 | 
			
		||||
	var mounts []string
 | 
			
		||||
	mounts := make([]string, 0, len(c.c.Mounts))
 | 
			
		||||
	for _, m := range c.c.Mounts {
 | 
			
		||||
		if m.Name == "" {
 | 
			
		||||
			name = m.Source
 | 
			
		||||
| 
						 | 
				
			
			@ -289,7 +292,7 @@ func (c *ContainerContext) LocalVolumes() string {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return fmt.Sprintf("%d", count)
 | 
			
		||||
	return strconv.Itoa(count)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Networks returns a comma-separated string of networks that the container is
 | 
			
		||||
| 
						 | 
				
			
			@ -299,7 +302,7 @@ func (c *ContainerContext) Networks() string {
 | 
			
		|||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	networks := []string{}
 | 
			
		||||
	networks := make([]string, 0, len(c.c.NetworkSettings.Networks))
 | 
			
		||||
	for k := range c.c.NetworkSettings.Networks {
 | 
			
		||||
		networks = append(networks, k)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -316,7 +319,7 @@ func DisplayablePorts(ports []types.Port) string {
 | 
			
		|||
		last  uint16
 | 
			
		||||
	}
 | 
			
		||||
	groupMap := make(map[string]*portGroup)
 | 
			
		||||
	var result []string
 | 
			
		||||
	var result []string //nolint:prealloc
 | 
			
		||||
	var hostMappings []string
 | 
			
		||||
	var groupMapKeys []string
 | 
			
		||||
	sort.Slice(ports, func(i, j int) bool {
 | 
			
		||||
| 
						 | 
				
			
			@ -331,7 +334,7 @@ func DisplayablePorts(ports []types.Port) string {
 | 
			
		|||
				hostMappings = append(hostMappings, fmt.Sprintf("%s:%d->%d/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type))
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			portKey = fmt.Sprintf("%s/%s", port.IP, port.Type)
 | 
			
		||||
			portKey = port.IP + "/" + port.Type
 | 
			
		||||
		}
 | 
			
		||||
		group := groupMap[portKey]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -372,7 +375,7 @@ func formGroup(key string, start, last uint16) string {
 | 
			
		|||
	if ip != "" {
 | 
			
		||||
		group = fmt.Sprintf("%s:%s->%s", ip, group, group)
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("%s/%s", group, groupType)
 | 
			
		||||
	return group + "/" + groupType
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func comparePorts(i, j types.Port) bool {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package formatter
 | 
			
		||||
 | 
			
		||||
import "strings"
 | 
			
		||||
| 
						 | 
				
			
			@ -22,7 +25,7 @@ const (
 | 
			
		|||
 | 
			
		||||
// SubContext defines what Context implementation should provide
 | 
			
		||||
type SubContext interface {
 | 
			
		||||
	FullHeader() interface{}
 | 
			
		||||
	FullHeader() any
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SubHeaderContext is a map destined to formatter header (table format)
 | 
			
		||||
| 
						 | 
				
			
			@ -39,10 +42,10 @@ func (c SubHeaderContext) Label(name string) string {
 | 
			
		|||
 | 
			
		||||
// HeaderContext provides the subContext interface for managing headers
 | 
			
		||||
type HeaderContext struct {
 | 
			
		||||
	Header interface{}
 | 
			
		||||
	Header any
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FullHeader returns the header as an interface
 | 
			
		||||
func (c *HeaderContext) FullHeader() interface{} {
 | 
			
		||||
func (c *HeaderContext) FullHeader() any {
 | 
			
		||||
	return c.Header
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ func Ellipsis(s string, maxDisplayWidth int) string {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
		display      []int
 | 
			
		||||
		display      = make([]int, 0, len(rs))
 | 
			
		||||
		displayWidth int
 | 
			
		||||
	)
 | 
			
		||||
	for _, r := range rs {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package formatter
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +54,7 @@ type Context struct {
 | 
			
		|||
 | 
			
		||||
	// internal element
 | 
			
		||||
	finalFormat string
 | 
			
		||||
	header      interface{}
 | 
			
		||||
	header      any
 | 
			
		||||
	buffer      *bytes.Buffer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
package formatter
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/distribution/reference"
 | 
			
		||||
| 
						 | 
				
			
			@ -26,11 +26,11 @@ type ImageContext struct {
 | 
			
		|||
	Digest bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isDangling(image image.Summary) bool {
 | 
			
		||||
	if len(image.RepoTags) == 0 && len(image.RepoDigests) == 0 {
 | 
			
		||||
func isDangling(img image.Summary) bool {
 | 
			
		||||
	if len(img.RepoTags) == 0 && len(img.RepoDigests) == 0 {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return len(image.RepoTags) == 1 && image.RepoTags[0] == "<none>:<none>" && len(image.RepoDigests) == 1 && image.RepoDigests[0] == "<none>@<none>"
 | 
			
		||||
	return len(img.RepoTags) == 1 && img.RepoTags[0] == "<none>:<none>" && len(img.RepoDigests) == 1 && img.RepoDigests[0] == "<none>@<none>"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewImageFormat returns a format for rendering an ImageContext
 | 
			
		||||
| 
						 | 
				
			
			@ -88,18 +88,18 @@ func needDigest(ctx ImageContext) bool {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func imageFormat(ctx ImageContext, images []image.Summary, format func(subContext SubContext) error) error {
 | 
			
		||||
	for _, image := range images {
 | 
			
		||||
	for _, img := range images {
 | 
			
		||||
		formatted := []*imageContext{}
 | 
			
		||||
		if isDangling(image) {
 | 
			
		||||
		if isDangling(img) {
 | 
			
		||||
			formatted = append(formatted, &imageContext{
 | 
			
		||||
				trunc:  ctx.Trunc,
 | 
			
		||||
				i:      image,
 | 
			
		||||
				i:      img,
 | 
			
		||||
				repo:   "<none>",
 | 
			
		||||
				tag:    "<none>",
 | 
			
		||||
				digest: "<none>",
 | 
			
		||||
			})
 | 
			
		||||
		} else {
 | 
			
		||||
			formatted = imageFormatTaggedAndDigest(ctx, image)
 | 
			
		||||
			formatted = imageFormatTaggedAndDigest(ctx, img)
 | 
			
		||||
		}
 | 
			
		||||
		for _, imageCtx := range formatted {
 | 
			
		||||
			if err := format(imageCtx); err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -110,12 +110,12 @@ func imageFormat(ctx ImageContext, images []image.Summary, format func(subContex
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func imageFormatTaggedAndDigest(ctx ImageContext, image image.Summary) []*imageContext {
 | 
			
		||||
func imageFormatTaggedAndDigest(ctx ImageContext, img image.Summary) []*imageContext {
 | 
			
		||||
	repoTags := map[string][]string{}
 | 
			
		||||
	repoDigests := map[string][]string{}
 | 
			
		||||
	images := []*imageContext{}
 | 
			
		||||
 | 
			
		||||
	for _, refString := range image.RepoTags {
 | 
			
		||||
	for _, refString := range img.RepoTags {
 | 
			
		||||
		ref, err := reference.ParseNormalizedNamed(refString)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			continue
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +125,7 @@ func imageFormatTaggedAndDigest(ctx ImageContext, image image.Summary) []*imageC
 | 
			
		|||
			repoTags[familiarRef] = append(repoTags[familiarRef], nt.Tag())
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for _, refString := range image.RepoDigests {
 | 
			
		||||
	for _, refString := range img.RepoDigests {
 | 
			
		||||
		ref, err := reference.ParseNormalizedNamed(refString)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			continue
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +139,7 @@ func imageFormatTaggedAndDigest(ctx ImageContext, image image.Summary) []*imageC
 | 
			
		|||
	addImage := func(repo, tag, digest string) {
 | 
			
		||||
		images = append(images, &imageContext{
 | 
			
		||||
			trunc:  ctx.Trunc,
 | 
			
		||||
			i:      image,
 | 
			
		||||
			i:      img,
 | 
			
		||||
			repo:   repo,
 | 
			
		||||
			tag:    tag,
 | 
			
		||||
			digest: digest,
 | 
			
		||||
| 
						 | 
				
			
			@ -166,7 +166,6 @@ func imageFormatTaggedAndDigest(ctx ImageContext, image image.Summary) []*imageC
 | 
			
		|||
			for _, dgst := range digests {
 | 
			
		||||
				addImage(repo, tag, dgst)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -256,7 +255,7 @@ func (c *imageContext) Containers() string {
 | 
			
		|||
	if c.i.Containers == -1 {
 | 
			
		||||
		return "N/A"
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("%d", c.i.Containers)
 | 
			
		||||
	return strconv.FormatInt(c.i.Containers, 10)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// VirtualSize shows the virtual size of the image and all of its parent
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package formatter
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -10,7 +13,7 @@ import (
 | 
			
		|||
 | 
			
		||||
// MarshalJSON marshals x into json
 | 
			
		||||
// It differs a bit from encoding/json MarshalJSON function for formatter
 | 
			
		||||
func MarshalJSON(x interface{}) ([]byte, error) {
 | 
			
		||||
func MarshalJSON(x any) ([]byte, error) {
 | 
			
		||||
	m, err := marshalMap(x)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
| 
						 | 
				
			
			@ -18,8 +21,8 @@ func MarshalJSON(x interface{}) ([]byte, error) {
 | 
			
		|||
	return json.Marshal(m)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// marshalMap marshals x to map[string]interface{}
 | 
			
		||||
func marshalMap(x interface{}) (map[string]interface{}, error) {
 | 
			
		||||
// marshalMap marshals x to map[string]any
 | 
			
		||||
func marshalMap(x any) (map[string]any, error) {
 | 
			
		||||
	val := reflect.ValueOf(x)
 | 
			
		||||
	if val.Kind() != reflect.Ptr {
 | 
			
		||||
		return nil, errors.Errorf("expected a pointer to a struct, got %v", val.Kind())
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +35,7 @@ func marshalMap(x interface{}) (map[string]interface{}, error) {
 | 
			
		|||
		return nil, errors.Errorf("expected a pointer to a struct, got a pointer to %v", valElem.Kind())
 | 
			
		||||
	}
 | 
			
		||||
	typ := val.Type()
 | 
			
		||||
	m := make(map[string]interface{})
 | 
			
		||||
	m := make(map[string]any)
 | 
			
		||||
	for i := 0; i < val.NumMethod(); i++ {
 | 
			
		||||
		k, v, err := marshalForMethod(typ.Method(i), val.Method(i))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +52,7 @@ var unmarshallableNames = map[string]struct{}{"FullHeader": {}}
 | 
			
		|||
 | 
			
		||||
// marshalForMethod returns the map key and the map value for marshalling the method.
 | 
			
		||||
// It returns ("", nil, nil) for valid but non-marshallable parameter. (e.g. "unexportedFunc()")
 | 
			
		||||
func marshalForMethod(typ reflect.Method, val reflect.Value) (string, interface{}, error) {
 | 
			
		||||
func marshalForMethod(typ reflect.Method, val reflect.Value) (string, any, error) {
 | 
			
		||||
	if val.Kind() != reflect.Func {
 | 
			
		||||
		return "", nil, errors.Errorf("expected func, got %v", val.Kind())
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,7 @@
 | 
			
		|||
 | 
			
		||||
// based on https://github.com/golang/go/blob/master/src/text/tabwriter/tabwriter.go Last modified 690ac40 on 31 Jan
 | 
			
		||||
 | 
			
		||||
//nolint:gocyclo,nakedret,revive,stylecheck,unused // ignore linting errors, so that we can stick close to upstream
 | 
			
		||||
//nolint:gocyclo,nakedret,stylecheck,unused // ignore linting errors, so that we can stick close to upstream
 | 
			
		||||
package tabwriter
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -202,7 +202,7 @@ const (
 | 
			
		|||
//
 | 
			
		||||
//	minwidth	minimal cell width including any padding
 | 
			
		||||
//	tabwidth	width of tab characters (equivalent number of spaces)
 | 
			
		||||
//	padding		padding added to a cell before computing its width
 | 
			
		||||
//	padding		the padding added to a cell before computing its width
 | 
			
		||||
//	padchar		ASCII char used for padding
 | 
			
		||||
//			if padchar == '\t', the Writer will assume that the
 | 
			
		||||
//			width of a '\t' in the formatted output is tabwidth,
 | 
			
		||||
| 
						 | 
				
			
			@ -576,18 +576,16 @@ func (b *Writer) Write(buf []byte) (n int, err error) {
 | 
			
		|||
					b.startEscape(ch)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
		} else if ch == b.endChar {
 | 
			
		||||
			// inside escape
 | 
			
		||||
			if ch == b.endChar {
 | 
			
		||||
				// end of tag/entity
 | 
			
		||||
				j := i + 1
 | 
			
		||||
				if ch == Escape && b.flags&StripEscape != 0 {
 | 
			
		||||
					j = i // strip Escape
 | 
			
		||||
				}
 | 
			
		||||
				b.append(buf[n:j])
 | 
			
		||||
				n = i + 1 // ch consumed
 | 
			
		||||
				b.endEscape()
 | 
			
		||||
			// end of tag/entity
 | 
			
		||||
			j := i + 1
 | 
			
		||||
			if ch == Escape && b.flags&StripEscape != 0 {
 | 
			
		||||
				j = i // strip Escape
 | 
			
		||||
			}
 | 
			
		||||
			b.append(buf[n:j])
 | 
			
		||||
			n = i + 1 // ch consumed
 | 
			
		||||
			b.endEscape()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,7 +100,7 @@ func (c *volumeContext) Labels() string {
 | 
			
		|||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var joinLabels []string
 | 
			
		||||
	joinLabels := make([]string, 0, len(c.v.Labels))
 | 
			
		||||
	for k, v := range c.v.Labels {
 | 
			
		||||
		joinLabels = append(joinLabels, k+"="+v)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package command
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +61,7 @@ func capitalizeFirst(s string) string {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// PrettyPrint outputs arbitrary data for human formatted output by uppercasing the first letter.
 | 
			
		||||
func PrettyPrint(i interface{}) string {
 | 
			
		||||
func PrettyPrint(i any) string {
 | 
			
		||||
	switch t := i.(type) {
 | 
			
		||||
	case nil:
 | 
			
		||||
		return "None"
 | 
			
		||||
| 
						 | 
				
			
			@ -184,17 +187,17 @@ func stringSliceIndex(s, subs []string) int {
 | 
			
		|||
	return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StringSliceReplaceAt replaces the sub-slice old, with the sub-slice new, in the string
 | 
			
		||||
// StringSliceReplaceAt replaces the sub-slice find, with the sub-slice replace, in the string
 | 
			
		||||
// slice s, returning a new slice and a boolean indicating if the replacement happened.
 | 
			
		||||
// requireIdx is the index at which old needs to be found at (or -1 to disregard that).
 | 
			
		||||
func StringSliceReplaceAt(s, old, new []string, requireIndex int) ([]string, bool) {
 | 
			
		||||
	idx := stringSliceIndex(s, old)
 | 
			
		||||
func StringSliceReplaceAt(s, find, replace []string, requireIndex int) ([]string, bool) {
 | 
			
		||||
	idx := stringSliceIndex(s, find)
 | 
			
		||||
	if (requireIndex != -1 && requireIndex != idx) || idx == -1 {
 | 
			
		||||
		return s, false
 | 
			
		||||
	}
 | 
			
		||||
	out := append([]string{}, s[:idx]...)
 | 
			
		||||
	out = append(out, new...)
 | 
			
		||||
	out = append(out, s[idx+len(old):]...)
 | 
			
		||||
	out = append(out, replace...)
 | 
			
		||||
	out = append(out, s[idx+len(find):]...)
 | 
			
		||||
	return out, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,5 +6,4 @@ import (
 | 
			
		|||
	"os/exec"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func setPdeathsig(cmd *exec.Cmd) {
 | 
			
		||||
}
 | 
			
		||||
func setPdeathsig(*exec.Cmd) {}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,8 +40,7 @@ func getConnectionHelper(daemonURL string, sshFlags []string) (*ConnectionHelper
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	switch scheme := u.Scheme; scheme {
 | 
			
		||||
	case "ssh":
 | 
			
		||||
	if u.Scheme == "ssh" {
 | 
			
		||||
		sp, err := ssh.ParseURL(daemonURL)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, errors.Wrap(err, "ssh host connection is not valid")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,7 +98,6 @@ func (ep *Endpoint) ClientOpts() ([]client.Opt, error) {
 | 
			
		|||
				withHTTPClient(tlsConfig),
 | 
			
		||||
				client.WithHost(ep.Host),
 | 
			
		||||
			)
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
			result = append(result,
 | 
			
		||||
				client.WithHTTPClient(&http.Client{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package store
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -40,12 +43,12 @@ func (s *metadataStore) createOrUpdate(meta Metadata) error {
 | 
			
		|||
	return ioutils.AtomicWriteFile(filepath.Join(contextDir, metaFile), bytes, 0o644)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseTypedOrMap(payload []byte, getter TypeGetter) (interface{}, error) {
 | 
			
		||||
func parseTypedOrMap(payload []byte, getter TypeGetter) (any, error) {
 | 
			
		||||
	if len(payload) == 0 || string(payload) == "null" {
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
	if getter == nil {
 | 
			
		||||
		var res map[string]interface{}
 | 
			
		||||
		var res map[string]any
 | 
			
		||||
		if err := json.Unmarshal(payload, &res); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +80,7 @@ func (s *metadataStore) getByID(id contextdir) (Metadata, error) {
 | 
			
		|||
	}
 | 
			
		||||
	var untyped untypedContextMetadata
 | 
			
		||||
	r := Metadata{
 | 
			
		||||
		Endpoints: make(map[string]interface{}),
 | 
			
		||||
		Endpoints: make(map[string]any),
 | 
			
		||||
	}
 | 
			
		||||
	if err := json.Unmarshal(bytes, &untyped); err != nil {
 | 
			
		||||
		return Metadata{}, fmt.Errorf("parsing %s: %v", fileName, err)
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +112,7 @@ func (s *metadataStore) list() ([]Metadata, error) {
 | 
			
		|||
		}
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	var res []Metadata
 | 
			
		||||
	res := make([]Metadata, 0, len(ctxDirs))
 | 
			
		||||
	for _, dir := range ctxDirs {
 | 
			
		||||
		c, err := s.getByID(contextdir(dir))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package store
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -70,9 +73,9 @@ type ReaderWriter interface {
 | 
			
		|||
 | 
			
		||||
// Metadata contains metadata about a context and its endpoints
 | 
			
		||||
type Metadata struct {
 | 
			
		||||
	Name      string                 `json:",omitempty"`
 | 
			
		||||
	Metadata  interface{}            `json:",omitempty"`
 | 
			
		||||
	Endpoints map[string]interface{} `json:",omitempty"`
 | 
			
		||||
	Name      string         `json:",omitempty"`
 | 
			
		||||
	Metadata  any            `json:",omitempty"`
 | 
			
		||||
	Endpoints map[string]any `json:",omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StorageInfo contains data about where a given context is stored
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +128,7 @@ func Names(s Lister) ([]string, error) {
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	var names []string
 | 
			
		||||
	names := make([]string, 0, len(list))
 | 
			
		||||
	for _, item := range list {
 | 
			
		||||
		names = append(names, item.Name)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -475,8 +478,8 @@ func parseMetadata(data []byte, name string) (Metadata, error) {
 | 
			
		|||
	return meta, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func importEndpointTLS(tlsData *ContextTLSData, path string, data []byte) error {
 | 
			
		||||
	parts := strings.SplitN(strings.TrimPrefix(path, "tls/"), "/", 2)
 | 
			
		||||
func importEndpointTLS(tlsData *ContextTLSData, tlsPath string, data []byte) error {
 | 
			
		||||
	parts := strings.SplitN(strings.TrimPrefix(tlsPath, "tls/"), "/", 2)
 | 
			
		||||
	if len(parts) != 2 {
 | 
			
		||||
		// TLS endpoints require archived file directory with 2 layers
 | 
			
		||||
		// i.e. tls/{endpointName}/{fileName}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,12 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package store
 | 
			
		||||
 | 
			
		||||
// TypeGetter is a func used to determine the concrete type of a context or
 | 
			
		||||
// endpoint metadata by returning a pointer to an instance of the object
 | 
			
		||||
// eg: for a context of type DockerContext, the corresponding TypeGetter should return new(DockerContext)
 | 
			
		||||
type TypeGetter func() interface{}
 | 
			
		||||
type TypeGetter func() any
 | 
			
		||||
 | 
			
		||||
// NamedTypeGetter is a TypeGetter associated with a name
 | 
			
		||||
type NamedTypeGetter struct {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,8 +149,8 @@ func manifestToFilename(root, manifestList, manifest string) string {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func makeFilesafeName(ref string) string {
 | 
			
		||||
	fileName := strings.Replace(ref, ":", "-", -1)
 | 
			
		||||
	return strings.Replace(fileName, "/", "_", -1)
 | 
			
		||||
	fileName := strings.ReplaceAll(ref, ":", "-")
 | 
			
		||||
	return strings.ReplaceAll(fileName, "/", "_")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type notFoundError struct {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,14 +55,18 @@ func PlatformSpecFromOCI(p *ocispec.Platform) *manifestlist.PlatformSpec {
 | 
			
		|||
 | 
			
		||||
// Blobs returns the digests for all the blobs referenced by this manifest
 | 
			
		||||
func (i ImageManifest) Blobs() []digest.Digest {
 | 
			
		||||
	digests := []digest.Digest{}
 | 
			
		||||
	var digests []digest.Digest
 | 
			
		||||
	switch {
 | 
			
		||||
	case i.SchemaV2Manifest != nil:
 | 
			
		||||
		for _, descriptor := range i.SchemaV2Manifest.References() {
 | 
			
		||||
		refs := i.SchemaV2Manifest.References()
 | 
			
		||||
		digests = make([]digest.Digest, 0, len(refs))
 | 
			
		||||
		for _, descriptor := range refs {
 | 
			
		||||
			digests = append(digests, descriptor.Digest)
 | 
			
		||||
		}
 | 
			
		||||
	case i.OCIManifest != nil:
 | 
			
		||||
		for _, descriptor := range i.OCIManifest.References() {
 | 
			
		||||
		refs := i.OCIManifest.References()
 | 
			
		||||
		digests = make([]digest.Digest, 0, len(refs))
 | 
			
		||||
		for _, descriptor := range refs {
 | 
			
		||||
			digests = append(digests, descriptor.Digest)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -262,8 +262,8 @@ func GetSignableRoles(repo client.Repository, target *client.Target) ([]data.Rol
 | 
			
		|||
		return signableRoles, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// there are delegation roles, find every delegation role we have a key for, and
 | 
			
		||||
	// attempt to sign into into all those roles.
 | 
			
		||||
	// there are delegation roles, find every delegation role we have a key for,
 | 
			
		||||
	// and attempt to sign in to all those roles.
 | 
			
		||||
	for _, delegationRole := range allDelegationRoles {
 | 
			
		||||
		// We do not support signing any delegation role that isn't a direct child of the targets role.
 | 
			
		||||
		// Also don't bother checking the keys if we can't add the target
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -161,21 +161,53 @@ func ParseTCPAddr(tryAddr string, defaultAddr string) (string, error) {
 | 
			
		|||
	return fmt.Sprintf("tcp://%s%s", net.JoinHostPort(host, port), u.Path), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ValidateExtraHost validates that the specified string is a valid extrahost and returns it.
 | 
			
		||||
// ExtraHost is in the form of name:ip where the ip has to be a valid ip (IPv4 or IPv6).
 | 
			
		||||
// ValidateExtraHost validates that the specified string is a valid extrahost and
 | 
			
		||||
// returns it. ExtraHost is in the form of name:ip or name=ip, where the ip has
 | 
			
		||||
// to be a valid ip (IPv4 or IPv6). The address may be enclosed in square
 | 
			
		||||
// brackets.
 | 
			
		||||
//
 | 
			
		||||
// TODO(thaJeztah): remove client-side validation, and delegate to the API server.
 | 
			
		||||
// For example:
 | 
			
		||||
//
 | 
			
		||||
//	my-hostname:127.0.0.1
 | 
			
		||||
//	my-hostname:::1
 | 
			
		||||
//	my-hostname=::1
 | 
			
		||||
//	my-hostname:[::1]
 | 
			
		||||
//
 | 
			
		||||
// For compatibility with the API server, this function normalises the given
 | 
			
		||||
// argument to use the ':' separator and strip square brackets enclosing the
 | 
			
		||||
// address.
 | 
			
		||||
func ValidateExtraHost(val string) (string, error) {
 | 
			
		||||
	// allow for IPv6 addresses in extra hosts by only splitting on first ":"
 | 
			
		||||
	k, v, ok := strings.Cut(val, ":")
 | 
			
		||||
	if !ok || k == "" {
 | 
			
		||||
	k, v, ok := strings.Cut(val, "=")
 | 
			
		||||
	if !ok {
 | 
			
		||||
		// allow for IPv6 addresses in extra hosts by only splitting on first ":"
 | 
			
		||||
		k, v, ok = strings.Cut(val, ":")
 | 
			
		||||
	}
 | 
			
		||||
	// Check that a hostname was given, and that it doesn't contain a ":". (Colon
 | 
			
		||||
	// isn't allowed in a hostname, along with many other characters. It's
 | 
			
		||||
	// special-cased here because the API server doesn't know about '=' separators in
 | 
			
		||||
	// '--add-host'. So, it'll split at the first colon and generate a strange error
 | 
			
		||||
	// message.)
 | 
			
		||||
	if !ok || k == "" || strings.Contains(k, ":") {
 | 
			
		||||
		return "", fmt.Errorf("bad format for add-host: %q", val)
 | 
			
		||||
	}
 | 
			
		||||
	// Skip IPaddr validation for "host-gateway" string
 | 
			
		||||
	if v != hostGatewayName {
 | 
			
		||||
		// If the address is enclosed in square brackets, extract it (for IPv6, but
 | 
			
		||||
		// permit it for IPv4 as well; we don't know the address family here, but it's
 | 
			
		||||
		// unambiguous).
 | 
			
		||||
		if len(v) > 2 && v[0] == '[' && v[len(v)-1] == ']' {
 | 
			
		||||
			v = v[1 : len(v)-1]
 | 
			
		||||
		}
 | 
			
		||||
		// ValidateIPAddress returns the address in canonical form (for example,
 | 
			
		||||
		// 0:0:0:0:0:0:0:1 -> ::1). But, stick with the original form, to avoid
 | 
			
		||||
		// surprising a user who's expecting to see the address they supplied in the
 | 
			
		||||
		// output of 'docker inspect' or '/etc/hosts'.
 | 
			
		||||
		if _, err := ValidateIPAddress(v); err != nil {
 | 
			
		||||
			return "", fmt.Errorf("invalid IP address in add-host: %q", v)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return val, nil
 | 
			
		||||
	// This result is passed directly to the API, the daemon doesn't accept the '='
 | 
			
		||||
	// separator or an address enclosed in brackets. So, construct something it can
 | 
			
		||||
	// understand.
 | 
			
		||||
	return k + ":" + v, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -116,16 +116,7 @@ func (m *MountOpt) Set(value string) error {
 | 
			
		|||
			}
 | 
			
		||||
			logrus.Warn("bind-nonrecursive is deprecated, use bind-recursive=disabled instead")
 | 
			
		||||
		case "bind-recursive":
 | 
			
		||||
			valS := val
 | 
			
		||||
			// Allow boolean as an alias to "enabled" or "disabled"
 | 
			
		||||
			if b, err := strconv.ParseBool(valS); err == nil {
 | 
			
		||||
				if b {
 | 
			
		||||
					valS = "enabled"
 | 
			
		||||
				} else {
 | 
			
		||||
					valS = "disabled"
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			switch valS {
 | 
			
		||||
			switch val {
 | 
			
		||||
			case "enabled": // read-only mounts are recursively read-only if Engine >= v25 && kernel >= v5.12, otherwise writable
 | 
			
		||||
				// NOP
 | 
			
		||||
			case "disabled": // alias of bind-nonrecursive=true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,9 +62,8 @@ type ThrottledeviceOpt struct {
 | 
			
		|||
 | 
			
		||||
// NewThrottledeviceOpt creates a new ThrottledeviceOpt
 | 
			
		||||
func NewThrottledeviceOpt(validator ValidatorThrottleFctType) ThrottledeviceOpt {
 | 
			
		||||
	values := []*blkiodev.ThrottleDevice{}
 | 
			
		||||
	return ThrottledeviceOpt{
 | 
			
		||||
		values:    values,
 | 
			
		||||
		values:    []*blkiodev.ThrottleDevice{},
 | 
			
		||||
		validator: validator,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +84,7 @@ func (opt *ThrottledeviceOpt) Set(val string) error {
 | 
			
		|||
 | 
			
		||||
// String returns ThrottledeviceOpt values as a string.
 | 
			
		||||
func (opt *ThrottledeviceOpt) String() string {
 | 
			
		||||
	var out []string
 | 
			
		||||
	out := make([]string, 0, len(opt.values))
 | 
			
		||||
	for _, v := range opt.values {
 | 
			
		||||
		out = append(out, v.String())
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +94,9 @@ func (opt *ThrottledeviceOpt) String() string {
 | 
			
		|||
 | 
			
		||||
// GetList returns a slice of pointers to ThrottleDevices.
 | 
			
		||||
func (opt *ThrottledeviceOpt) GetList() []*blkiodev.ThrottleDevice {
 | 
			
		||||
	return append([]*blkiodev.ThrottleDevice{}, opt.values...)
 | 
			
		||||
	out := make([]*blkiodev.ThrottleDevice, 0, len(opt.values))
 | 
			
		||||
	copy(out, opt.values)
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Type returns the option type
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,7 @@ func (o *UlimitOpt) Set(val string) error {
 | 
			
		|||
 | 
			
		||||
// String returns Ulimit values as a string. Values are sorted by name.
 | 
			
		||||
func (o *UlimitOpt) String() string {
 | 
			
		||||
	var out []string
 | 
			
		||||
	out := make([]string, 0, len(*o.values))
 | 
			
		||||
	for _, v := range *o.values {
 | 
			
		||||
		out = append(out, v.String())
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +44,7 @@ func (o *UlimitOpt) String() string {
 | 
			
		|||
 | 
			
		||||
// GetList returns a slice of pointers to Ulimits. Values are sorted by name.
 | 
			
		||||
func (o *UlimitOpt) GetList() []*units.Ulimit {
 | 
			
		||||
	var ulimits []*units.Ulimit
 | 
			
		||||
	ulimits := make([]*units.Ulimit, 0, len(*o.values))
 | 
			
		||||
	for _, v := range *o.values {
 | 
			
		||||
		ulimits = append(ulimits, v)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,7 +65,7 @@ func (opt *WeightdeviceOpt) Set(val string) error {
 | 
			
		|||
 | 
			
		||||
// String returns WeightdeviceOpt values as a string.
 | 
			
		||||
func (opt *WeightdeviceOpt) String() string {
 | 
			
		||||
	var out []string
 | 
			
		||||
	out := make([]string, 0, len(opt.values))
 | 
			
		||||
	for _, v := range opt.values {
 | 
			
		||||
		out = append(out, v.String())
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
 | 
			
		||||
//go:build go1.19
 | 
			
		||||
 | 
			
		||||
package templates
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -10,17 +13,21 @@ import (
 | 
			
		|||
// basicFunctions are the set of initial
 | 
			
		||||
// functions provided to every template.
 | 
			
		||||
var basicFunctions = template.FuncMap{
 | 
			
		||||
	"json": func(v interface{}) string {
 | 
			
		||||
	"json": func(v any) string {
 | 
			
		||||
		buf := &bytes.Buffer{}
 | 
			
		||||
		enc := json.NewEncoder(buf)
 | 
			
		||||
		enc.SetEscapeHTML(false)
 | 
			
		||||
		enc.Encode(v)
 | 
			
		||||
		err := enc.Encode(v)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Remove the trailing new line added by the encoder
 | 
			
		||||
		return strings.TrimSpace(buf.String())
 | 
			
		||||
	},
 | 
			
		||||
	"split":    strings.Split,
 | 
			
		||||
	"join":     strings.Join,
 | 
			
		||||
	"title":    strings.Title, //nolint:staticcheck // strings.Title is deprecated, but we only use it for ASCII, so replacing with golang.org/x/text is out of scope
 | 
			
		||||
	"title":    strings.Title, //nolint:nolintlint,staticcheck // strings.Title is deprecated, but we only use it for ASCII, so replacing with golang.org/x/text is out of scope
 | 
			
		||||
	"lower":    strings.ToLower,
 | 
			
		||||
	"upper":    strings.ToUpper,
 | 
			
		||||
	"pad":      padWithSpace,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -238,6 +238,7 @@ Ben Golub <ben.golub@dotcloud.com>
 | 
			
		|||
Ben Gould <ben@bengould.co.uk>
 | 
			
		||||
Ben Hall <ben@benhall.me.uk>
 | 
			
		||||
Ben Langfeld <ben@langfeld.me>
 | 
			
		||||
Ben Lovy <ben@deciduously.com>
 | 
			
		||||
Ben Sargent <ben@brokendigits.com>
 | 
			
		||||
Ben Severson <BenSeverson@users.noreply.github.com>
 | 
			
		||||
Ben Toews <mastahyeti@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -281,6 +282,7 @@ Brandon Liu <bdon@bdon.org>
 | 
			
		|||
Brandon Philips <brandon.philips@coreos.com>
 | 
			
		||||
Brandon Rhodes <brandon@rhodesmill.org>
 | 
			
		||||
Brendan Dixon <brendand@microsoft.com>
 | 
			
		||||
Brennan Kinney <5098581+polarathene@users.noreply.github.com>
 | 
			
		||||
Brent Salisbury <brent.salisbury@docker.com>
 | 
			
		||||
Brett Higgins <brhiggins@arbor.net>
 | 
			
		||||
Brett Kochendorfer <brett.kochendorfer@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -365,6 +367,7 @@ chenyuzhu <chenyuzhi@oschina.cn>
 | 
			
		|||
Chetan Birajdar <birajdar.chetan@gmail.com>
 | 
			
		||||
Chewey <prosto-chewey@users.noreply.github.com>
 | 
			
		||||
Chia-liang Kao <clkao@clkao.org>
 | 
			
		||||
Chiranjeevi Tirunagari <vchiranjeeviak.tirunagari@gmail.com>
 | 
			
		||||
chli <chli@freewheel.tv>
 | 
			
		||||
Cholerae Hu <choleraehyq@gmail.com>
 | 
			
		||||
Chris Alfonso <calfonso@redhat.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -515,6 +518,7 @@ David Dooling <dooling@gmail.com>
 | 
			
		|||
David Gageot <david@gageot.net>
 | 
			
		||||
David Gebler <davidgebler@gmail.com>
 | 
			
		||||
David Glasser <glasser@davidglasser.net>
 | 
			
		||||
David Karlsson <35727626+dvdksn@users.noreply.github.com>
 | 
			
		||||
David Lawrence <david.lawrence@docker.com>
 | 
			
		||||
David Lechner <david@lechnology.com>
 | 
			
		||||
David M. Karr <davidmichaelkarr@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -639,6 +643,7 @@ Emily Rose <emily@contactvibe.com>
 | 
			
		|||
Emir Ozer <emirozer@yandex.com>
 | 
			
		||||
Eng Zer Jun <engzerjun@gmail.com>
 | 
			
		||||
Enguerran <engcolson@gmail.com>
 | 
			
		||||
Enrico Weigelt, metux IT consult <info@metux.net>
 | 
			
		||||
Eohyung Lee <liquidnuker@gmail.com>
 | 
			
		||||
epeterso <epeterson@breakpoint-labs.com>
 | 
			
		||||
er0k <er0k@er0k.net>
 | 
			
		||||
| 
						 | 
				
			
			@ -748,6 +753,7 @@ Frank Groeneveld <frank@ivaldi.nl>
 | 
			
		|||
Frank Herrmann <fgh@4gh.tv>
 | 
			
		||||
Frank Macreery <frank@macreery.com>
 | 
			
		||||
Frank Rosquin <frank.rosquin+github@gmail.com>
 | 
			
		||||
Frank Villaro-Dixon <frank.villarodixon@merkle.com>
 | 
			
		||||
Frank Yang <yyb196@gmail.com>
 | 
			
		||||
Fred Lifton <fred.lifton@docker.com>
 | 
			
		||||
Frederick F. Kautz IV <fkautz@redhat.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1190,6 +1196,7 @@ Ke Xu <leonhartx.k@gmail.com>
 | 
			
		|||
Kei Ohmura <ohmura.kei@gmail.com>
 | 
			
		||||
Keith Hudgins <greenman@greenman.org>
 | 
			
		||||
Keli Hu <dev@keli.hu>
 | 
			
		||||
Ken Bannister <kb2ma@runbox.com>
 | 
			
		||||
Ken Cochrane <kencochrane@gmail.com>
 | 
			
		||||
Ken Herner <kherner@progress.com>
 | 
			
		||||
Ken ICHIKAWA <ichikawa.ken@jp.fujitsu.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1314,6 +1321,7 @@ Lorenzo Fontana <fontanalorenz@gmail.com>
 | 
			
		|||
Lotus Fenn <fenn.lotus@gmail.com>
 | 
			
		||||
Louis Delossantos <ldelossa.ld@gmail.com>
 | 
			
		||||
Louis Opter <kalessin@kalessin.fr>
 | 
			
		||||
Luboslav Pivarc <lpivarc@redhat.com>
 | 
			
		||||
Luca Favatella <luca.favatella@erlang-solutions.com>
 | 
			
		||||
Luca Marturana <lucamarturana@gmail.com>
 | 
			
		||||
Luca Orlandi <luca.orlandi@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1352,6 +1360,7 @@ Manuel Meurer <manuel@krautcomputing.com>
 | 
			
		|||
Manuel Rüger <manuel@rueg.eu>
 | 
			
		||||
Manuel Woelker <github@manuel.woelker.org>
 | 
			
		||||
mapk0y <mapk0y@gmail.com>
 | 
			
		||||
Marat Radchenko <marat@slonopotamus.org>
 | 
			
		||||
Marc Abramowitz <marc@marc-abramowitz.com>
 | 
			
		||||
Marc Kuo <kuomarc2@gmail.com>
 | 
			
		||||
Marc Tamsky <mtamsky@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1391,6 +1400,7 @@ Martijn van Oosterhout <kleptog@svana.org>
 | 
			
		|||
Martin Braun <braun@neuroforge.de>
 | 
			
		||||
Martin Dojcak <martin.dojcak@lablabs.io>
 | 
			
		||||
Martin Honermeyer <maze@strahlungsfrei.de>
 | 
			
		||||
Martin Jirku <martin@jirku.sk>
 | 
			
		||||
Martin Kelly <martin@surround.io>
 | 
			
		||||
Martin Mosegaard Amdisen <martin.amdisen@praqma.com>
 | 
			
		||||
Martin Muzatko <martin@happy-css.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1469,6 +1479,7 @@ Michael Holzheu <holzheu@linux.vnet.ibm.com>
 | 
			
		|||
Michael Hudson-Doyle <michael.hudson@canonical.com>
 | 
			
		||||
Michael Huettermann <michael@huettermann.net>
 | 
			
		||||
Michael Irwin <mikesir87@gmail.com>
 | 
			
		||||
Michael Kebe <michael.kebe@hkm.de>
 | 
			
		||||
Michael Kuehn <micha@kuehn.io>
 | 
			
		||||
Michael Käufl <docker@c.michael-kaeufl.de>
 | 
			
		||||
Michael Neale <michael.neale@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1517,6 +1528,7 @@ Mike Lundy <mike@fluffypenguin.org>
 | 
			
		|||
Mike MacCana <mike.maccana@gmail.com>
 | 
			
		||||
Mike Naberezny <mike@naberezny.com>
 | 
			
		||||
Mike Snitzer <snitzer@redhat.com>
 | 
			
		||||
Mike Sul <mike.sul@foundries.io>
 | 
			
		||||
mikelinjie <294893458@qq.com>
 | 
			
		||||
Mikhail Sobolev <mss@mawhrin.net>
 | 
			
		||||
Miklos Szegedi <miklos.szegedi@cloudera.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1532,6 +1544,7 @@ mlarcher <github@ringabell.org>
 | 
			
		|||
Mohammad Banikazemi <MBanikazemi@gmail.com>
 | 
			
		||||
Mohammad Nasirifar <farnasirim@gmail.com>
 | 
			
		||||
Mohammed Aaqib Ansari <maaquib@gmail.com>
 | 
			
		||||
Mohd Sadiq <mohdsadiq058@gmail.com>
 | 
			
		||||
Mohit Soni <mosoni@ebay.com>
 | 
			
		||||
Moorthy RS <rsmoorthy@gmail.com>
 | 
			
		||||
Morgan Bauer <mbauer@us.ibm.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1684,6 +1697,7 @@ Pavlos Ratis <dastergon@gentoo.org>
 | 
			
		|||
Pavol Vargovcik <pallly.vargovcik@gmail.com>
 | 
			
		||||
Pawel Konczalski <mail@konczalski.de>
 | 
			
		||||
Paweł Gronowski <pawel.gronowski@docker.com>
 | 
			
		||||
payall4u <payall4u@qq.com>
 | 
			
		||||
Peeyush Gupta <gpeeyush@linux.vnet.ibm.com>
 | 
			
		||||
Peggy Li <peggyli.224@gmail.com>
 | 
			
		||||
Pei Su <sillyousu@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1715,6 +1729,7 @@ Phil Spitler <pspitler@gmail.com>
 | 
			
		|||
Philip Alexander Etling <paetling@gmail.com>
 | 
			
		||||
Philip K. Warren <pkwarren@gmail.com>
 | 
			
		||||
Philip Monroe <phil@philmonroe.com>
 | 
			
		||||
Philipp Fruck <dev@p-fruck.de>
 | 
			
		||||
Philipp Gillé <philipp.gille@gmail.com>
 | 
			
		||||
Philipp Wahala <philipp.wahala@gmail.com>
 | 
			
		||||
Philipp Weissensteiner <mail@philippweissensteiner.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1752,6 +1767,7 @@ Quentin Brossard <qbrossard@gmail.com>
 | 
			
		|||
Quentin Perez <qperez@ocs.online.net>
 | 
			
		||||
Quentin Tayssier <qtayssier@gmail.com>
 | 
			
		||||
r0n22 <cameron.regan@gmail.com>
 | 
			
		||||
Rachit Sharma <rachitsharma613@gmail.com>
 | 
			
		||||
Radostin Stoyanov <rstoyanov1@gmail.com>
 | 
			
		||||
Rafal Jeczalik <rjeczalik@gmail.com>
 | 
			
		||||
Rafe Colton <rafael.colton@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1784,6 +1800,7 @@ Rich Horwood <rjhorwood@apple.com>
 | 
			
		|||
Rich Moyse <rich@moyse.us>
 | 
			
		||||
Rich Seymour <rseymour@gmail.com>
 | 
			
		||||
Richard Burnison <rburnison@ebay.com>
 | 
			
		||||
Richard Hansen <rhansen@rhansen.org>
 | 
			
		||||
Richard Harvey <richard@squarecows.com>
 | 
			
		||||
Richard Mathie <richard.mathie@amey.co.uk>
 | 
			
		||||
Richard Metzler <richard@paadee.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1799,6 +1816,7 @@ Ritesh H Shukla <sritesh@vmware.com>
 | 
			
		|||
Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
 | 
			
		||||
Rob Cowsill <42620235+rcowsill@users.noreply.github.com>
 | 
			
		||||
Rob Gulewich <rgulewich@netflix.com>
 | 
			
		||||
Rob Murray <rob.murray@docker.com>
 | 
			
		||||
Rob Vesse <rvesse@dotnetrdf.org>
 | 
			
		||||
Robert Bachmann <rb@robertbachmann.at>
 | 
			
		||||
Robert Bittle <guywithnose@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1880,6 +1898,7 @@ ryancooper7 <ryan.cooper7@gmail.com>
 | 
			
		|||
RyanDeng <sheldon.d1018@gmail.com>
 | 
			
		||||
Ryo Nakao <nakabonne@gmail.com>
 | 
			
		||||
Ryoga Saito <contact@proelbtn.com>
 | 
			
		||||
Régis Behmo <regis@behmo.com>
 | 
			
		||||
Rémy Greinhofer <remy.greinhofer@livelovely.com>
 | 
			
		||||
s. rannou <mxs@sbrk.org>
 | 
			
		||||
Sabin Basyal <sabin.basyal@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1896,6 +1915,7 @@ Sam J Sharpe <sam.sharpe@digital.cabinet-office.gov.uk>
 | 
			
		|||
Sam Neirinck <sam@samneirinck.com>
 | 
			
		||||
Sam Reis <sreis@atlassian.com>
 | 
			
		||||
Sam Rijs <srijs@airpost.net>
 | 
			
		||||
Sam Thibault <sam.thibault@docker.com>
 | 
			
		||||
Sam Whited <sam@samwhited.com>
 | 
			
		||||
Sambuddha Basu <sambuddhabasu1@gmail.com>
 | 
			
		||||
Sami Wagiaalla <swagiaal@redhat.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -1919,6 +1939,7 @@ Satoshi Tagomori <tagomoris@gmail.com>
 | 
			
		|||
Scott Bessler <scottbessler@gmail.com>
 | 
			
		||||
Scott Collier <emailscottcollier@gmail.com>
 | 
			
		||||
Scott Johnston <scott@docker.com>
 | 
			
		||||
Scott Moser <smoser@brickies.net>
 | 
			
		||||
Scott Percival <scottp@lastyard.com>
 | 
			
		||||
Scott Stamp <scottstamp851@gmail.com>
 | 
			
		||||
Scott Walls <sawalls@umich.edu>
 | 
			
		||||
| 
						 | 
				
			
			@ -2008,6 +2029,7 @@ Stanislav Bondarenko <stanislav.bondarenko@gmail.com>
 | 
			
		|||
Stanislav Levin <slev@altlinux.org>
 | 
			
		||||
Steeve Morin <steeve.morin@gmail.com>
 | 
			
		||||
Stefan Berger <stefanb@linux.vnet.ibm.com>
 | 
			
		||||
Stefan Gehrig <stefan.gehrig.hn@googlemail.com>
 | 
			
		||||
Stefan J. Wernli <swernli@microsoft.com>
 | 
			
		||||
Stefan Praszalowicz <stefan@greplin.com>
 | 
			
		||||
Stefan S. <tronicum@user.github.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -2015,6 +2037,7 @@ Stefan Scherer <stefan.scherer@docker.com>
 | 
			
		|||
Stefan Staudenmeyer <doerte@instana.com>
 | 
			
		||||
Stefan Weil <sw@weilnetz.de>
 | 
			
		||||
Steffen Butzer <steffen.butzer@outlook.com>
 | 
			
		||||
Stephan Henningsen <stephan-henningsen@users.noreply.github.com>
 | 
			
		||||
Stephan Spindler <shutefan@gmail.com>
 | 
			
		||||
Stephen Benjamin <stephen@redhat.com>
 | 
			
		||||
Stephen Crosby <stevecrozz@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			@ -2303,7 +2326,7 @@ xiekeyang <xiekeyang@huawei.com>
 | 
			
		|||
Ximo Guanter Gonzálbez <joaquin.guantergonzalbez@telefonica.com>
 | 
			
		||||
xin.li <xin.li@daocloud.io>
 | 
			
		||||
Xinbo Weng <xihuanbo_0521@zju.edu.cn>
 | 
			
		||||
Xinfeng Liu <xinfeng.liu@gmail.com>
 | 
			
		||||
Xinfeng Liu <XinfengLiu@icloud.com>
 | 
			
		||||
Xinzi Zhou <imdreamrunner@gmail.com>
 | 
			
		||||
Xiuming Chen <cc@cxm.cc>
 | 
			
		||||
Xuecong Liao <satorulogic@gmail.com>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
//go:build !windows
 | 
			
		||||
 | 
			
		||||
package api // import "github.com/docker/docker/api"
 | 
			
		||||
 | 
			
		||||
// MinVersion represents Minimum REST API version supported
 | 
			
		||||
const MinVersion = "1.12"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +0,0 @@
 | 
			
		|||
package api // import "github.com/docker/docker/api"
 | 
			
		||||
 | 
			
		||||
// MinVersion represents Minimum REST API version supported
 | 
			
		||||
// Technically the first daemon API version released on Windows is v1.25 in
 | 
			
		||||
// engine version 1.13. However, some clients are explicitly using downlevel
 | 
			
		||||
// APIs (e.g. docker-compose v2.1 file format) and that is just too restrictive.
 | 
			
		||||
// Hence also allowing 1.24 on Windows.
 | 
			
		||||
const MinVersion string = "1.24"
 | 
			
		||||
| 
						 | 
				
			
			@ -1398,7 +1398,8 @@ definitions:
 | 
			
		|||
    type: "object"
 | 
			
		||||
    properties:
 | 
			
		||||
      Bridge:
 | 
			
		||||
        description: Name of the network's bridge (for example, `docker0`).
 | 
			
		||||
        description: |
 | 
			
		||||
          Name of the default bridge interface when dockerd's --bridge flag is set.
 | 
			
		||||
        type: "string"
 | 
			
		||||
        example: "docker0"
 | 
			
		||||
      SandboxID:
 | 
			
		||||
| 
						 | 
				
			
			@ -1408,34 +1409,40 @@ definitions:
 | 
			
		|||
      HairpinMode:
 | 
			
		||||
        description: |
 | 
			
		||||
          Indicates if hairpin NAT should be enabled on the virtual interface.
 | 
			
		||||
 | 
			
		||||
          Deprecated: This field is never set and will be removed in a future release.
 | 
			
		||||
        type: "boolean"
 | 
			
		||||
        example: false
 | 
			
		||||
      LinkLocalIPv6Address:
 | 
			
		||||
        description: IPv6 unicast address using the link-local prefix.
 | 
			
		||||
        description: |
 | 
			
		||||
          IPv6 unicast address using the link-local prefix.
 | 
			
		||||
 | 
			
		||||
          Deprecated: This field is never set and will be removed in a future release.
 | 
			
		||||
        type: "string"
 | 
			
		||||
        example: "fe80::42:acff:fe11:1"
 | 
			
		||||
        example: ""
 | 
			
		||||
      LinkLocalIPv6PrefixLen:
 | 
			
		||||
        description: Prefix length of the IPv6 unicast address.
 | 
			
		||||
        description: |
 | 
			
		||||
          Prefix length of the IPv6 unicast address.
 | 
			
		||||
 | 
			
		||||
          Deprecated: This field is never set and will be removed in a future release.
 | 
			
		||||
        type: "integer"
 | 
			
		||||
        example: "64"
 | 
			
		||||
        example: ""
 | 
			
		||||
      Ports:
 | 
			
		||||
        $ref: "#/definitions/PortMap"
 | 
			
		||||
      SandboxKey:
 | 
			
		||||
        description: SandboxKey identifies the sandbox
 | 
			
		||||
        description: SandboxKey is the full path of the netns handle
 | 
			
		||||
        type: "string"
 | 
			
		||||
        example: "/var/run/docker/netns/8ab54b426c38"
 | 
			
		||||
 | 
			
		||||
      # TODO is SecondaryIPAddresses actually used?
 | 
			
		||||
      SecondaryIPAddresses:
 | 
			
		||||
        description: ""
 | 
			
		||||
        description: "Deprecated: This field is never set and will be removed in a future release."
 | 
			
		||||
        type: "array"
 | 
			
		||||
        items:
 | 
			
		||||
          $ref: "#/definitions/Address"
 | 
			
		||||
        x-nullable: true
 | 
			
		||||
 | 
			
		||||
      # TODO is SecondaryIPv6Addresses actually used?
 | 
			
		||||
      SecondaryIPv6Addresses:
 | 
			
		||||
        description: ""
 | 
			
		||||
        description: "Deprecated: This field is never set and will be removed in a future release."
 | 
			
		||||
        type: "array"
 | 
			
		||||
        items:
 | 
			
		||||
          $ref: "#/definitions/Address"
 | 
			
		||||
| 
						 | 
				
			
			@ -1744,10 +1751,15 @@ definitions:
 | 
			
		|||
          The ID of the container that was used to create the image.
 | 
			
		||||
 | 
			
		||||
          Depending on how the image was created, this field may be empty.
 | 
			
		||||
 | 
			
		||||
          **Deprecated**: this field is kept for backward compatibility, but
 | 
			
		||||
          will be removed in API v1.45.
 | 
			
		||||
        type: "string"
 | 
			
		||||
        x-nullable: false
 | 
			
		||||
        example: "65974bc86f1770ae4bff79f651ebdbce166ae9aada632ee3fa9af3a264911735"
 | 
			
		||||
      ContainerConfig:
 | 
			
		||||
        description: |
 | 
			
		||||
          **Deprecated**: this field is kept for backward compatibility, but
 | 
			
		||||
          will be removed in API v1.45.
 | 
			
		||||
        $ref: "#/definitions/ContainerConfig"
 | 
			
		||||
      DockerVersion:
 | 
			
		||||
        description: |
 | 
			
		||||
| 
						 | 
				
			
			@ -2525,6 +2537,21 @@ definitions:
 | 
			
		|||
        example:
 | 
			
		||||
          com.example.some-label: "some-value"
 | 
			
		||||
          com.example.some-other-label: "some-other-value"
 | 
			
		||||
      DNSNames:
 | 
			
		||||
        description: |
 | 
			
		||||
          List of all DNS names an endpoint has on a specific network. This
 | 
			
		||||
          list is based on the container name, network aliases, container short
 | 
			
		||||
          ID, and hostname.
 | 
			
		||||
 | 
			
		||||
          These DNS names are non-fully qualified but can contain several dots.
 | 
			
		||||
          You can get fully qualified DNS names by appending `.<network-name>`.
 | 
			
		||||
          For instance, if container name is `my.ctr` and the network is named
 | 
			
		||||
          `testnet`, `DNSNames` will contain `my.ctr` and the FQDN will be
 | 
			
		||||
          `my.ctr.testnet`.
 | 
			
		||||
        type: array
 | 
			
		||||
        items:
 | 
			
		||||
          type: string
 | 
			
		||||
        example: ["foobar", "server_x", "server_y", "my.ctr"]
 | 
			
		||||
 | 
			
		||||
  EndpointIPAMConfig:
 | 
			
		||||
    description: |
 | 
			
		||||
| 
						 | 
				
			
			@ -3022,8 +3049,6 @@ definitions:
 | 
			
		|||
            Name: "journald"
 | 
			
		||||
          - Type: "Log"
 | 
			
		||||
            Name: "json-file"
 | 
			
		||||
          - Type: "Log"
 | 
			
		||||
            Name: "logentries"
 | 
			
		||||
          - Type: "Log"
 | 
			
		||||
            Name: "splunk"
 | 
			
		||||
          - Type: "Log"
 | 
			
		||||
| 
						 | 
				
			
			@ -3978,6 +4003,44 @@ definitions:
 | 
			
		|||
      - "remove"
 | 
			
		||||
      - "orphaned"
 | 
			
		||||
 | 
			
		||||
  ContainerStatus:
 | 
			
		||||
    type: "object"
 | 
			
		||||
    description: "represents the status of a container."
 | 
			
		||||
    properties:
 | 
			
		||||
      ContainerID:
 | 
			
		||||
        type: "string"
 | 
			
		||||
      PID:
 | 
			
		||||
        type: "integer"
 | 
			
		||||
      ExitCode:
 | 
			
		||||
        type: "integer"
 | 
			
		||||
 | 
			
		||||
  PortStatus:
 | 
			
		||||
    type: "object"
 | 
			
		||||
    description: "represents the port status of a task's host ports whose service has published host ports"
 | 
			
		||||
    properties:
 | 
			
		||||
      Ports:
 | 
			
		||||
        type: "array"
 | 
			
		||||
        items:
 | 
			
		||||
          $ref: "#/definitions/EndpointPortConfig"
 | 
			
		||||
 | 
			
		||||
  TaskStatus:
 | 
			
		||||
    type: "object"
 | 
			
		||||
    description: "represents the status of a task."
 | 
			
		||||
    properties:
 | 
			
		||||
      Timestamp:
 | 
			
		||||
        type: "string"
 | 
			
		||||
        format: "dateTime"
 | 
			
		||||
      State:
 | 
			
		||||
        $ref: "#/definitions/TaskState"
 | 
			
		||||
      Message:
 | 
			
		||||
        type: "string"
 | 
			
		||||
      Err:
 | 
			
		||||
        type: "string"
 | 
			
		||||
      ContainerStatus:
 | 
			
		||||
        $ref: "#/definitions/ContainerStatus"
 | 
			
		||||
      PortStatus:
 | 
			
		||||
        $ref: "#/definitions/PortStatus"
 | 
			
		||||
 | 
			
		||||
  Task:
 | 
			
		||||
    type: "object"
 | 
			
		||||
    properties:
 | 
			
		||||
| 
						 | 
				
			
			@ -4013,26 +4076,7 @@ definitions:
 | 
			
		|||
      AssignedGenericResources:
 | 
			
		||||
        $ref: "#/definitions/GenericResources"
 | 
			
		||||
      Status:
 | 
			
		||||
        type: "object"
 | 
			
		||||
        properties:
 | 
			
		||||
          Timestamp:
 | 
			
		||||
            type: "string"
 | 
			
		||||
            format: "dateTime"
 | 
			
		||||
          State:
 | 
			
		||||
            $ref: "#/definitions/TaskState"
 | 
			
		||||
          Message:
 | 
			
		||||
            type: "string"
 | 
			
		||||
          Err:
 | 
			
		||||
            type: "string"
 | 
			
		||||
          ContainerStatus:
 | 
			
		||||
            type: "object"
 | 
			
		||||
            properties:
 | 
			
		||||
              ContainerID:
 | 
			
		||||
                type: "string"
 | 
			
		||||
              PID:
 | 
			
		||||
                type: "integer"
 | 
			
		||||
              ExitCode:
 | 
			
		||||
                type: "integer"
 | 
			
		||||
        $ref: "#/definitions/TaskStatus"
 | 
			
		||||
      DesiredState:
 | 
			
		||||
        $ref: "#/definitions/TaskState"
 | 
			
		||||
      JobIteration:
 | 
			
		||||
| 
						 | 
				
			
			@ -4248,7 +4292,10 @@ definitions:
 | 
			
		|||
              - "stop-first"
 | 
			
		||||
              - "start-first"
 | 
			
		||||
      Networks:
 | 
			
		||||
        description: "Specifies which networks the service should attach to."
 | 
			
		||||
        description: |
 | 
			
		||||
          Specifies which networks the service should attach to.
 | 
			
		||||
 | 
			
		||||
          Deprecated: This field is deprecated since v1.44. The Networks field in TaskSpec should be used instead.
 | 
			
		||||
        type: "array"
 | 
			
		||||
        items:
 | 
			
		||||
          $ref: "#/definitions/NetworkAttachmentConfig"
 | 
			
		||||
| 
						 | 
				
			
			@ -5414,7 +5461,7 @@ definitions:
 | 
			
		|||
        type: "array"
 | 
			
		||||
        items:
 | 
			
		||||
          type: "string"
 | 
			
		||||
        example: ["awslogs", "fluentd", "gcplogs", "gelf", "journald", "json-file", "logentries", "splunk", "syslog"]
 | 
			
		||||
        example: ["awslogs", "fluentd", "gcplogs", "gelf", "journald", "json-file", "splunk", "syslog"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  RegistryServiceConfig:
 | 
			
		||||
| 
						 | 
				
			
			@ -5612,6 +5659,28 @@ definitions:
 | 
			
		|||
        items:
 | 
			
		||||
          type: "string"
 | 
			
		||||
        example: ["--debug", "--systemd-cgroup=false"]
 | 
			
		||||
      status:
 | 
			
		||||
        description: |
 | 
			
		||||
          Information specific to the runtime.
 | 
			
		||||
 | 
			
		||||
          While this API specification does not define data provided by runtimes,
 | 
			
		||||
          the following well-known properties may be provided by runtimes:
 | 
			
		||||
 | 
			
		||||
          `org.opencontainers.runtime-spec.features`: features structure as defined
 | 
			
		||||
          in the [OCI Runtime Specification](https://github.com/opencontainers/runtime-spec/blob/main/features.md),
 | 
			
		||||
          in a JSON string representation.
 | 
			
		||||
 | 
			
		||||
          <p><br /></p>
 | 
			
		||||
 | 
			
		||||
          > **Note**: The information returned in this field, including the
 | 
			
		||||
          > formatting of values and labels, should not be considered stable,
 | 
			
		||||
          > and may change without notice.
 | 
			
		||||
        type: "object"
 | 
			
		||||
        x-nullable: true
 | 
			
		||||
        additionalProperties:
 | 
			
		||||
          type: "string"
 | 
			
		||||
        example:
 | 
			
		||||
          "org.opencontainers.runtime-spec.features": "{\"ociVersionMin\":\"1.0.0\",\"ociVersionMax\":\"1.1.0\",\"...\":\"...\"}"
 | 
			
		||||
 | 
			
		||||
  Commit:
 | 
			
		||||
    description: |
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,32 +1,5 @@
 | 
			
		|||
package types // import "github.com/docker/docker/api/types"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/docker/docker/api/types/container"
 | 
			
		||||
	"github.com/docker/docker/api/types/network"
 | 
			
		||||
	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// configs holds structs used for internal communication between the
 | 
			
		||||
// frontend (such as an http server) and the backend (such as the
 | 
			
		||||
// docker daemon).
 | 
			
		||||
 | 
			
		||||
// ContainerCreateConfig is the parameter set to ContainerCreate()
 | 
			
		||||
type ContainerCreateConfig struct {
 | 
			
		||||
	Name             string
 | 
			
		||||
	Config           *container.Config
 | 
			
		||||
	HostConfig       *container.HostConfig
 | 
			
		||||
	NetworkingConfig *network.NetworkingConfig
 | 
			
		||||
	Platform         *ocispec.Platform
 | 
			
		||||
	AdjustCPUShares  bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ContainerRmConfig holds arguments for the container remove
 | 
			
		||||
// operation. This struct is used to tell the backend what operations
 | 
			
		||||
// to perform.
 | 
			
		||||
type ContainerRmConfig struct {
 | 
			
		||||
	ForceRemove, RemoveVolume, RemoveLink bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ExecConfig is a small subset of the Config struct that holds the configuration
 | 
			
		||||
// for the exec feature of docker.
 | 
			
		||||
type ExecConfig struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -43,25 +16,3 @@ type ExecConfig struct {
 | 
			
		|||
	WorkingDir   string   // Working directory
 | 
			
		||||
	Cmd          []string // Execution commands and args
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PluginRmConfig holds arguments for plugin remove.
 | 
			
		||||
type PluginRmConfig struct {
 | 
			
		||||
	ForceRemove bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PluginEnableConfig holds arguments for plugin enable
 | 
			
		||||
type PluginEnableConfig struct {
 | 
			
		||||
	Timeout int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PluginDisableConfig holds arguments for plugin disable.
 | 
			
		||||
type PluginDisableConfig struct {
 | 
			
		||||
	ForceDisable bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NetworkListConfig stores the options available for listing networks
 | 
			
		||||
type NetworkListConfig struct {
 | 
			
		||||
	// TODO(@cpuguy83): naming is hard, this is pulled from what was being used in the router before moving here
 | 
			
		||||
	Detailed bool
 | 
			
		||||
	Verbose  bool
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@ import (
 | 
			
		|||
 | 
			
		||||
	"github.com/docker/docker/api/types/blkiodev"
 | 
			
		||||
	"github.com/docker/docker/api/types/mount"
 | 
			
		||||
	"github.com/docker/docker/api/types/network"
 | 
			
		||||
	"github.com/docker/docker/api/types/strslice"
 | 
			
		||||
	"github.com/docker/go-connections/nat"
 | 
			
		||||
	units "github.com/docker/go-units"
 | 
			
		||||
| 
						 | 
				
			
			@ -133,12 +134,12 @@ type NetworkMode string
 | 
			
		|||
 | 
			
		||||
// IsNone indicates whether container isn't using a network stack.
 | 
			
		||||
func (n NetworkMode) IsNone() bool {
 | 
			
		||||
	return n == "none"
 | 
			
		||||
	return n == network.NetworkNone
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsDefault indicates whether container uses the default network stack.
 | 
			
		||||
func (n NetworkMode) IsDefault() bool {
 | 
			
		||||
	return n == "default"
 | 
			
		||||
	return n == network.NetworkDefault
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsPrivate indicates whether container uses its private network stack.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,8 @@
 | 
			
		|||
 | 
			
		||||
package container // import "github.com/docker/docker/api/types/container"
 | 
			
		||||
 | 
			
		||||
import "github.com/docker/docker/api/types/network"
 | 
			
		||||
 | 
			
		||||
// IsValid indicates if an isolation technology is valid
 | 
			
		||||
func (i Isolation) IsValid() bool {
 | 
			
		||||
	return i.IsDefault()
 | 
			
		||||
| 
						 | 
				
			
			@ -10,15 +12,15 @@ func (i Isolation) IsValid() bool {
 | 
			
		|||
// NetworkName returns the name of the network stack.
 | 
			
		||||
func (n NetworkMode) NetworkName() string {
 | 
			
		||||
	if n.IsBridge() {
 | 
			
		||||
		return "bridge"
 | 
			
		||||
		return network.NetworkBridge
 | 
			
		||||
	} else if n.IsHost() {
 | 
			
		||||
		return "host"
 | 
			
		||||
		return network.NetworkHost
 | 
			
		||||
	} else if n.IsContainer() {
 | 
			
		||||
		return "container"
 | 
			
		||||
	} else if n.IsNone() {
 | 
			
		||||
		return "none"
 | 
			
		||||
		return network.NetworkNone
 | 
			
		||||
	} else if n.IsDefault() {
 | 
			
		||||
		return "default"
 | 
			
		||||
		return network.NetworkDefault
 | 
			
		||||
	} else if n.IsUserDefined() {
 | 
			
		||||
		return n.UserDefined()
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -27,12 +29,12 @@ func (n NetworkMode) NetworkName() string {
 | 
			
		|||
 | 
			
		||||
// IsBridge indicates whether container uses the bridge network stack
 | 
			
		||||
func (n NetworkMode) IsBridge() bool {
 | 
			
		||||
	return n == "bridge"
 | 
			
		||||
	return n == network.NetworkBridge
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsHost indicates whether container uses the host network stack.
 | 
			
		||||
func (n NetworkMode) IsHost() bool {
 | 
			
		||||
	return n == "host"
 | 
			
		||||
	return n == network.NetworkHost
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsUserDefined indicates user-created network
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,11 @@
 | 
			
		|||
package container // import "github.com/docker/docker/api/types/container"
 | 
			
		||||
 | 
			
		||||
import "github.com/docker/docker/api/types/network"
 | 
			
		||||
 | 
			
		||||
// IsBridge indicates whether container uses the bridge network stack
 | 
			
		||||
// in windows it is given the name NAT
 | 
			
		||||
func (n NetworkMode) IsBridge() bool {
 | 
			
		||||
	return n == "nat"
 | 
			
		||||
	return n == network.NetworkNat
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsHost indicates whether container uses the host network stack.
 | 
			
		||||
| 
						 | 
				
			
			@ -25,11 +27,11 @@ func (i Isolation) IsValid() bool {
 | 
			
		|||
// NetworkName returns the name of the network stack.
 | 
			
		||||
func (n NetworkMode) NetworkName() string {
 | 
			
		||||
	if n.IsDefault() {
 | 
			
		||||
		return "default"
 | 
			
		||||
		return network.NetworkDefault
 | 
			
		||||
	} else if n.IsBridge() {
 | 
			
		||||
		return "nat"
 | 
			
		||||
		return network.NetworkNat
 | 
			
		||||
	} else if n.IsNone() {
 | 
			
		||||
		return "none"
 | 
			
		||||
		return network.NetworkNone
 | 
			
		||||
	} else if n.IsContainer() {
 | 
			
		||||
		return "container"
 | 
			
		||||
	} else if n.IsUserDefined() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ type EndpointSettings struct {
 | 
			
		|||
	// Configurations
 | 
			
		||||
	IPAMConfig *EndpointIPAMConfig
 | 
			
		||||
	Links      []string
 | 
			
		||||
	Aliases    []string
 | 
			
		||||
	Aliases    []string // Aliases holds the list of extra, user-specified DNS names for this endpoint.
 | 
			
		||||
	MacAddress string
 | 
			
		||||
	// Operational data
 | 
			
		||||
	NetworkID           string
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +25,9 @@ type EndpointSettings struct {
 | 
			
		|||
	GlobalIPv6Address   string
 | 
			
		||||
	GlobalIPv6PrefixLen int
 | 
			
		||||
	DriverOpts          map[string]string
 | 
			
		||||
	// DNSNames holds all the (non fully qualified) DNS names associated to this endpoint. First entry is used to
 | 
			
		||||
	// generate PTR records.
 | 
			
		||||
	DNSNames []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Copy makes a deep copy of `EndpointSettings`
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +46,12 @@ func (es *EndpointSettings) Copy() *EndpointSettings {
 | 
			
		|||
		aliases := make([]string, 0, len(es.Aliases))
 | 
			
		||||
		epCopy.Aliases = append(aliases, es.Aliases...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(es.DNSNames) > 0 {
 | 
			
		||||
		epCopy.DNSNames = make([]string, len(es.DNSNames))
 | 
			
		||||
		copy(epCopy.DNSNames, es.DNSNames)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &epCopy
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,22 @@
 | 
			
		|||
package network // import "github.com/docker/docker/api/types/network"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/docker/docker/api/types/filters"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// NetworkDefault is a platform-independent alias to choose the platform-specific default network stack.
 | 
			
		||||
	NetworkDefault = "default"
 | 
			
		||||
	// NetworkHost is the name of the predefined network used when the NetworkMode host is selected (only available on Linux)
 | 
			
		||||
	NetworkHost = "host"
 | 
			
		||||
	// NetworkNone is the name of the predefined network used when the NetworkMode none is selected (available on both Linux and Windows)
 | 
			
		||||
	NetworkNone = "none"
 | 
			
		||||
	// NetworkBridge is the name of the default network on Linux
 | 
			
		||||
	NetworkBridge = "bridge"
 | 
			
		||||
	// NetworkNat is the name of the default network on Windows
 | 
			
		||||
	NetworkNat = "nat"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Address represents an IP address
 | 
			
		||||
type Address struct {
 | 
			
		||||
	Addr      string
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,9 +34,9 @@ type ServiceSpec struct {
 | 
			
		|||
	UpdateConfig   *UpdateConfig `json:",omitempty"`
 | 
			
		||||
	RollbackConfig *UpdateConfig `json:",omitempty"`
 | 
			
		||||
 | 
			
		||||
	// Networks field in ServiceSpec is deprecated. The
 | 
			
		||||
	// same field in TaskSpec should be used instead.
 | 
			
		||||
	// This field will be removed in a future release.
 | 
			
		||||
	// Networks specifies which networks the service should attach to.
 | 
			
		||||
	//
 | 
			
		||||
	// Deprecated: This field is deprecated since v1.44. The Networks field in TaskSpec should be used instead.
 | 
			
		||||
	Networks     []NetworkAttachmentConfig `json:",omitempty"`
 | 
			
		||||
	EndpointSpec *EndpointSpec             `json:",omitempty"`
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,7 +58,7 @@ type Info struct {
 | 
			
		|||
	Labels             []string
 | 
			
		||||
	ExperimentalBuild  bool
 | 
			
		||||
	ServerVersion      string
 | 
			
		||||
	Runtimes           map[string]Runtime
 | 
			
		||||
	Runtimes           map[string]RuntimeWithStatus
 | 
			
		||||
	DefaultRuntime     string
 | 
			
		||||
	Swarm              swarm.Info
 | 
			
		||||
	// LiveRestoreEnabled determines whether containers should be kept
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,3 +12,9 @@ type Runtime struct {
 | 
			
		|||
	Type    string                 `json:"runtimeType,omitempty"`
 | 
			
		||||
	Options map[string]interface{} `json:"options,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RuntimeWithStatus extends [Runtime] to hold [RuntimeStatus].
 | 
			
		||||
type RuntimeWithStatus struct {
 | 
			
		||||
	Runtime
 | 
			
		||||
	Status map[string]string `json:"status,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,6 +77,8 @@ type ImageInspect struct {
 | 
			
		|||
	// Container is the ID of the container that was used to create the image.
 | 
			
		||||
	//
 | 
			
		||||
	// Depending on how the image was created, this field may be empty.
 | 
			
		||||
	//
 | 
			
		||||
	// Deprecated: this field is omitted in API v1.45, but kept for backward compatibility.
 | 
			
		||||
	Container string
 | 
			
		||||
 | 
			
		||||
	// ContainerConfig is an optional field containing the configuration of the
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +86,8 @@ type ImageInspect struct {
 | 
			
		|||
	//
 | 
			
		||||
	// Previous versions of Docker builder used this field to store build cache,
 | 
			
		||||
	// and it is not in active use anymore.
 | 
			
		||||
	//
 | 
			
		||||
	// Deprecated: this field is omitted in API v1.45, but kept for backward compatibility.
 | 
			
		||||
	ContainerConfig *container.Config
 | 
			
		||||
 | 
			
		||||
	// DockerVersion is the version of Docker that was used to build the image.
 | 
			
		||||
| 
						 | 
				
			
			@ -335,17 +339,27 @@ type SummaryNetworkSettings struct {
 | 
			
		|||
	Networks map[string]*network.EndpointSettings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NetworkSettingsBase holds basic information about networks
 | 
			
		||||
// NetworkSettingsBase holds networking state for a container when inspecting it.
 | 
			
		||||
type NetworkSettingsBase struct {
 | 
			
		||||
	Bridge                 string      // Bridge is the Bridge name the network uses(e.g. `docker0`)
 | 
			
		||||
	SandboxID              string      // SandboxID uniquely represents a container's network stack
 | 
			
		||||
	HairpinMode            bool        // HairpinMode specifies if hairpin NAT should be enabled on the virtual interface
 | 
			
		||||
	LinkLocalIPv6Address   string      // LinkLocalIPv6Address is an IPv6 unicast address using the link-local prefix
 | 
			
		||||
	LinkLocalIPv6PrefixLen int         // LinkLocalIPv6PrefixLen is the prefix length of an IPv6 unicast address
 | 
			
		||||
	Ports                  nat.PortMap // Ports is a collection of PortBinding indexed by Port
 | 
			
		||||
	SandboxKey             string      // SandboxKey identifies the sandbox
 | 
			
		||||
	SecondaryIPAddresses   []network.Address
 | 
			
		||||
	SecondaryIPv6Addresses []network.Address
 | 
			
		||||
	Bridge     string      // Bridge contains the name of the default bridge interface iff it was set through the daemon --bridge flag.
 | 
			
		||||
	SandboxID  string      // SandboxID uniquely represents a container's network stack
 | 
			
		||||
	SandboxKey string      // SandboxKey identifies the sandbox
 | 
			
		||||
	Ports      nat.PortMap // Ports is a collection of PortBinding indexed by Port
 | 
			
		||||
 | 
			
		||||
	// HairpinMode specifies if hairpin NAT should be enabled on the virtual interface
 | 
			
		||||
	//
 | 
			
		||||
	// Deprecated: This field is never set and will be removed in a future release.
 | 
			
		||||
	HairpinMode bool
 | 
			
		||||
	// LinkLocalIPv6Address is an IPv6 unicast address using the link-local prefix
 | 
			
		||||
	//
 | 
			
		||||
	// Deprecated: This field is never set and will be removed in a future release.
 | 
			
		||||
	LinkLocalIPv6Address string
 | 
			
		||||
	// LinkLocalIPv6PrefixLen is the prefix length of an IPv6 unicast address
 | 
			
		||||
	//
 | 
			
		||||
	// Deprecated: This field is never set and will be removed in a future release.
 | 
			
		||||
	LinkLocalIPv6PrefixLen int
 | 
			
		||||
	SecondaryIPAddresses   []network.Address // Deprecated: This field is never set and will be removed in a future release.
 | 
			
		||||
	SecondaryIPv6Addresses []network.Address // Deprecated: This field is never set and will be removed in a future release.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DefaultNetworkSettings holds network information
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,10 @@
 | 
			
		|||
# Go client for the Docker Engine API
 | 
			
		||||
 | 
			
		||||
The `docker` command uses this package to communicate with the daemon. It can also be used by your own Go applications to do anything the command-line interface does – running containers, pulling images, managing swarms, etc.
 | 
			
		||||
The `docker` command uses this package to communicate with the daemon. It can
 | 
			
		||||
also be used by your own Go applications to do anything the command-line
 | 
			
		||||
interface does – running containers, pulling images, managing swarms, etc.
 | 
			
		||||
 | 
			
		||||
For example, to list running containers (the equivalent of `docker ps`):
 | 
			
		||||
For example, to list all containers (the equivalent of `docker ps --all`):
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
package main
 | 
			
		||||
| 
						 | 
				
			
			@ -11,26 +13,26 @@ import (
 | 
			
		|||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	"github.com/docker/docker/api/types/container"
 | 
			
		||||
	"github.com/docker/docker/client"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	cli, err := client.NewClientWithOpts(client.FromEnv)
 | 
			
		||||
	apiClient, err := client.NewClientWithOpts(client.FromEnv)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	defer cli.Close()
 | 
			
		||||
	defer apiClient.Close()
 | 
			
		||||
 | 
			
		||||
	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
 | 
			
		||||
	containers, err := apiClient.ContainerList(context.Background(), container.ListOptions{All: true})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, container := range containers {
 | 
			
		||||
		fmt.Printf("%s %s\n", container.ID[:10], container.Image)
 | 
			
		||||
	for _, ctr := range containers {
 | 
			
		||||
		fmt.Printf("%s %s (status: %s)\n", ctr.ID, ctr.Image, ctr.Status)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[Full documentation is available on GoDoc.](https://godoc.org/github.com/docker/docker/client)
 | 
			
		||||
[Full documentation is available on pkg.go.dev.](https://pkg.go.dev/github.com/docker/docker/client)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,6 +90,13 @@ import (
 | 
			
		|||
// [Go stdlib]: https://github.com/golang/go/blob/6244b1946bc2101b01955468f1be502dbadd6807/src/net/http/transport.go#L558-L569
 | 
			
		||||
const DummyHost = "api.moby.localhost"
 | 
			
		||||
 | 
			
		||||
// fallbackAPIVersion is the version to fallback to if API-version negotiation
 | 
			
		||||
// fails. This version is the highest version of the API before API-version
 | 
			
		||||
// negotiation was introduced. If negotiation fails (or no API version was
 | 
			
		||||
// included in the API response), we assume the API server uses the most
 | 
			
		||||
// recent version before negotiation was introduced.
 | 
			
		||||
const fallbackAPIVersion = "1.24"
 | 
			
		||||
 | 
			
		||||
// Client is the API client that performs all operations
 | 
			
		||||
// against a docker server.
 | 
			
		||||
type Client struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -329,7 +336,7 @@ func (cli *Client) NegotiateAPIVersionPing(pingResponse types.Ping) {
 | 
			
		|||
func (cli *Client) negotiateAPIVersionPing(pingResponse types.Ping) {
 | 
			
		||||
	// default to the latest version before versioning headers existed
 | 
			
		||||
	if pingResponse.APIVersion == "" {
 | 
			
		||||
		pingResponse.APIVersion = "1.24"
 | 
			
		||||
		pingResponse.APIVersion = fallbackAPIVersion
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// if the client is not initialized with a version, start with the latest supported version
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,18 +6,13 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/http/httputil"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types"
 | 
			
		||||
	"github.com/docker/docker/api/types/versions"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"go.opentelemetry.io/otel"
 | 
			
		||||
	"go.opentelemetry.io/otel/codes"
 | 
			
		||||
	"go.opentelemetry.io/otel/propagation"
 | 
			
		||||
	"go.opentelemetry.io/otel/semconv/v1.17.0/httpconv"
 | 
			
		||||
	"go.opentelemetry.io/otel/trace"
 | 
			
		||||
	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// postHijacked sends a POST request and hijacks the connection.
 | 
			
		||||
| 
						 | 
				
			
			@ -55,32 +50,16 @@ func (cli *Client) setupHijackConn(req *http.Request, proto string) (_ net.Conn,
 | 
			
		|||
	req.Header.Set("Connection", "Upgrade")
 | 
			
		||||
	req.Header.Set("Upgrade", proto)
 | 
			
		||||
 | 
			
		||||
	// We aren't using the configured RoundTripper here so manually inject the trace context
 | 
			
		||||
	tp := cli.tp
 | 
			
		||||
	if tp == nil {
 | 
			
		||||
		if span := trace.SpanFromContext(ctx); span.SpanContext().IsValid() {
 | 
			
		||||
			tp = span.TracerProvider()
 | 
			
		||||
		} else {
 | 
			
		||||
			tp = otel.GetTracerProvider()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx, span := tp.Tracer("").Start(ctx, req.Method+" "+req.URL.Path, trace.WithSpanKind(trace.SpanKindClient))
 | 
			
		||||
	span.SetAttributes(httpconv.ClientRequest(req)...)
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if retErr != nil {
 | 
			
		||||
			span.RecordError(retErr)
 | 
			
		||||
			span.SetStatus(codes.Error, retErr.Error())
 | 
			
		||||
		}
 | 
			
		||||
		span.End()
 | 
			
		||||
	}()
 | 
			
		||||
	otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header))
 | 
			
		||||
 | 
			
		||||
	dialer := cli.Dialer()
 | 
			
		||||
	conn, err := dialer(ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, "", errors.Wrap(err, "cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")
 | 
			
		||||
	}
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if retErr != nil {
 | 
			
		||||
			conn.Close()
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	// When we set up a TCP connection for hijack, there could be long periods
 | 
			
		||||
	// of inactivity (a long running command with no output) that in certain
 | 
			
		||||
| 
						 | 
				
			
			@ -92,38 +71,29 @@ func (cli *Client) setupHijackConn(req *http.Request, proto string) (_ net.Conn,
 | 
			
		|||
		_ = tcpConn.SetKeepAlivePeriod(30 * time.Second)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	clientconn := httputil.NewClientConn(conn, nil)
 | 
			
		||||
	defer clientconn.Close()
 | 
			
		||||
	hc := &hijackedConn{conn, bufio.NewReader(conn)}
 | 
			
		||||
 | 
			
		||||
	// Server hijacks the connection, error 'connection closed' expected
 | 
			
		||||
	resp, err := clientconn.Do(req)
 | 
			
		||||
	if resp != nil {
 | 
			
		||||
		span.SetStatus(httpconv.ClientStatus(resp.StatusCode))
 | 
			
		||||
	resp, err := otelhttp.NewTransport(hc).RoundTrip(req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, "", err
 | 
			
		||||
	}
 | 
			
		||||
	if resp.StatusCode != http.StatusSwitchingProtocols {
 | 
			
		||||
		_ = resp.Body.Close()
 | 
			
		||||
		return nil, "", fmt.Errorf("unable to upgrade to %s, received %d", proto, resp.StatusCode)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//nolint:staticcheck // ignore SA1019 for connecting to old (pre go1.8) daemons
 | 
			
		||||
	if err != httputil.ErrPersistEOF {
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, "", err
 | 
			
		||||
		}
 | 
			
		||||
		if resp.StatusCode != http.StatusSwitchingProtocols {
 | 
			
		||||
			_ = resp.Body.Close()
 | 
			
		||||
			return nil, "", fmt.Errorf("unable to upgrade to %s, received %d", proto, resp.StatusCode)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c, br := clientconn.Hijack()
 | 
			
		||||
	if br.Buffered() > 0 {
 | 
			
		||||
	if hc.r.Buffered() > 0 {
 | 
			
		||||
		// If there is buffered content, wrap the connection.  We return an
 | 
			
		||||
		// object that implements CloseWrite if the underlying connection
 | 
			
		||||
		// implements it.
 | 
			
		||||
		if _, ok := c.(types.CloseWriter); ok {
 | 
			
		||||
			c = &hijackedConnCloseWriter{&hijackedConn{c, br}}
 | 
			
		||||
		if _, ok := hc.Conn.(types.CloseWriter); ok {
 | 
			
		||||
			conn = &hijackedConnCloseWriter{hc}
 | 
			
		||||
		} else {
 | 
			
		||||
			c = &hijackedConn{c, br}
 | 
			
		||||
			conn = hc
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		br.Reset(nil)
 | 
			
		||||
		hc.r.Reset(nil)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var mediaType string
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +102,7 @@ func (cli *Client) setupHijackConn(req *http.Request, proto string) (_ net.Conn,
 | 
			
		|||
		mediaType = resp.Header.Get("Content-Type")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c, mediaType, nil
 | 
			
		||||
	return conn, mediaType, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// hijackedConn wraps a net.Conn and is returned by setupHijackConn in the case
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +114,13 @@ type hijackedConn struct {
 | 
			
		|||
	r *bufio.Reader
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *hijackedConn) RoundTrip(req *http.Request) (*http.Response, error) {
 | 
			
		||||
	if err := req.Write(c.Conn); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return http.ReadResponse(c.r, req)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *hijackedConn) Read(b []byte) (int, error) {
 | 
			
		||||
	return c.r.Read(b)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,10 @@
 | 
			
		|||
package errdefs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"errors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type causer interface {
 | 
			
		||||
	Cause() error
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -105,3 +110,8 @@ func IsDataLoss(err error) bool {
 | 
			
		|||
	_, ok := getImplementer(err).(ErrDataLoss)
 | 
			
		||||
	return ok
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsContext returns if the passed in error is due to context cancellation or deadline exceeded.
 | 
			
		||||
func IsContext(err error) bool {
 | 
			
		||||
	return errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
language: go
 | 
			
		||||
 | 
			
		||||
go:
 | 
			
		||||
  - 1.6
 | 
			
		||||
  - 1.7
 | 
			
		||||
  - 1.8
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
.PHONY: ci generate clean
 | 
			
		||||
 | 
			
		||||
ci: clean generate
 | 
			
		||||
	go test -v ./...
 | 
			
		||||
	go test -race -v ./...
 | 
			
		||||
 | 
			
		||||
generate:
 | 
			
		||||
	go generate .
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,8 +7,8 @@ http.Handlers.
 | 
			
		|||
Doing this requires non-trivial wrapping of the http.ResponseWriter interface,
 | 
			
		||||
which is also exposed for users interested in a more low-level API.
 | 
			
		||||
 | 
			
		||||
[](https://godoc.org/github.com/felixge/httpsnoop)
 | 
			
		||||
[](https://travis-ci.org/felixge/httpsnoop)
 | 
			
		||||
[](https://pkg.go.dev/github.com/felixge/httpsnoop)
 | 
			
		||||
[](https://github.com/felixge/httpsnoop/actions/workflows/main.yaml)
 | 
			
		||||
 | 
			
		||||
## Usage Example
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ func (m *Metrics) CaptureMetrics(w http.ResponseWriter, fn func(http.ResponseWri
 | 
			
		|||
				return func(code int) {
 | 
			
		||||
					next(code)
 | 
			
		||||
 | 
			
		||||
					if !headerWritten {
 | 
			
		||||
					if !(code >= 100 && code <= 199) && !headerWritten {
 | 
			
		||||
						m.Code = code
 | 
			
		||||
						headerWritten = true
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
// +build go1.8
 | 
			
		||||
// Code generated by "httpsnoop/codegen"; DO NOT EDIT
 | 
			
		||||
// Code generated by "httpsnoop/codegen"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package httpsnoop
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
// +build !go1.8
 | 
			
		||||
// Code generated by "httpsnoop/codegen"; DO NOT EDIT
 | 
			
		||||
// Code generated by "httpsnoop/codegen"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package httpsnoop
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,14 @@ This package provides various compression algorithms.
 | 
			
		|||
 | 
			
		||||
# changelog
 | 
			
		||||
 | 
			
		||||
* Oct 22nd, 2023 - [v1.17.2](https://github.com/klauspost/compress/releases/tag/v1.17.2)
 | 
			
		||||
	* zstd: Fix rare *CORRUPTION* output in "best" mode. See https://github.com/klauspost/compress/pull/876
 | 
			
		||||
 | 
			
		||||
* Oct 14th, 2023 - [v1.17.1](https://github.com/klauspost/compress/releases/tag/v1.17.1)
 | 
			
		||||
	* s2: Fix S2 "best" dictionary wrong encoding by @klauspost in https://github.com/klauspost/compress/pull/871
 | 
			
		||||
	* flate: Reduce allocations in decompressor and minor code improvements by @fakefloordiv in https://github.com/klauspost/compress/pull/869
 | 
			
		||||
	* s2: Fix EstimateBlockSize on 6&7 length input by @klauspost in https://github.com/klauspost/compress/pull/867
 | 
			
		||||
 | 
			
		||||
* Sept 19th, 2023 - [v1.17.0](https://github.com/klauspost/compress/releases/tag/v1.17.0)
 | 
			
		||||
	* Add experimental dictionary builder  https://github.com/klauspost/compress/pull/853
 | 
			
		||||
	* Add xerial snappy read/writer https://github.com/klauspost/compress/pull/838
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -212,7 +212,7 @@ func (s *Scratch) writeCount() error {
 | 
			
		|||
		previous0 bool
 | 
			
		||||
		charnum   uint16
 | 
			
		||||
 | 
			
		||||
		maxHeaderSize = ((int(s.symbolLen) * int(tableLog)) >> 3) + 3
 | 
			
		||||
		maxHeaderSize = ((int(s.symbolLen)*int(tableLog) + 4 + 2) >> 3) + 3
 | 
			
		||||
 | 
			
		||||
		// Write Table Size
 | 
			
		||||
		bitStream = uint32(tableLog - minTablelog)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,44 +0,0 @@
 | 
			
		|||
// Copyright 2018 Klaus Post. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.
 | 
			
		||||
 | 
			
		||||
package huff0
 | 
			
		||||
 | 
			
		||||
// byteReader provides a byte reader that reads
 | 
			
		||||
// little endian values from a byte stream.
 | 
			
		||||
// The input stream is manually advanced.
 | 
			
		||||
// The reader performs no bounds checks.
 | 
			
		||||
type byteReader struct {
 | 
			
		||||
	b   []byte
 | 
			
		||||
	off int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// init will initialize the reader and set the input.
 | 
			
		||||
func (b *byteReader) init(in []byte) {
 | 
			
		||||
	b.b = in
 | 
			
		||||
	b.off = 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Int32 returns a little endian int32 starting at current offset.
 | 
			
		||||
func (b byteReader) Int32() int32 {
 | 
			
		||||
	v3 := int32(b.b[b.off+3])
 | 
			
		||||
	v2 := int32(b.b[b.off+2])
 | 
			
		||||
	v1 := int32(b.b[b.off+1])
 | 
			
		||||
	v0 := int32(b.b[b.off])
 | 
			
		||||
	return (v3 << 24) | (v2 << 16) | (v1 << 8) | v0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Uint32 returns a little endian uint32 starting at current offset.
 | 
			
		||||
func (b byteReader) Uint32() uint32 {
 | 
			
		||||
	v3 := uint32(b.b[b.off+3])
 | 
			
		||||
	v2 := uint32(b.b[b.off+2])
 | 
			
		||||
	v1 := uint32(b.b[b.off+1])
 | 
			
		||||
	v0 := uint32(b.b[b.off])
 | 
			
		||||
	return (v3 << 24) | (v2 << 16) | (v1 << 8) | v0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// remain will return the number of bytes remaining.
 | 
			
		||||
func (b byteReader) remain() int {
 | 
			
		||||
	return len(b.b) - b.off
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -350,6 +350,7 @@ func (s *Scratch) compress4Xp(src []byte) ([]byte, error) {
 | 
			
		|||
// Does not update s.clearCount.
 | 
			
		||||
func (s *Scratch) countSimple(in []byte) (max int, reuse bool) {
 | 
			
		||||
	reuse = true
 | 
			
		||||
	_ = s.count // Assert that s != nil to speed up the following loop.
 | 
			
		||||
	for _, v := range in {
 | 
			
		||||
		s.count[v]++
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -415,7 +416,7 @@ func (s *Scratch) validateTable(c cTable) bool {
 | 
			
		|||
 | 
			
		||||
// minTableLog provides the minimum logSize to safely represent a distribution.
 | 
			
		||||
func (s *Scratch) minTableLog() uint8 {
 | 
			
		||||
	minBitsSrc := highBit32(uint32(s.br.remain())) + 1
 | 
			
		||||
	minBitsSrc := highBit32(uint32(s.srcLen)) + 1
 | 
			
		||||
	minBitsSymbols := highBit32(uint32(s.symbolLen-1)) + 2
 | 
			
		||||
	if minBitsSrc < minBitsSymbols {
 | 
			
		||||
		return uint8(minBitsSrc)
 | 
			
		||||
| 
						 | 
				
			
			@ -427,7 +428,7 @@ func (s *Scratch) minTableLog() uint8 {
 | 
			
		|||
func (s *Scratch) optimalTableLog() {
 | 
			
		||||
	tableLog := s.TableLog
 | 
			
		||||
	minBits := s.minTableLog()
 | 
			
		||||
	maxBitsSrc := uint8(highBit32(uint32(s.br.remain()-1))) - 1
 | 
			
		||||
	maxBitsSrc := uint8(highBit32(uint32(s.srcLen-1))) - 1
 | 
			
		||||
	if maxBitsSrc < tableLog {
 | 
			
		||||
		// Accuracy can be reduced
 | 
			
		||||
		tableLog = maxBitsSrc
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,7 +88,7 @@ type Scratch struct {
 | 
			
		|||
	// Decoders will return ErrMaxDecodedSizeExceeded is this limit is exceeded.
 | 
			
		||||
	MaxDecodedSize int
 | 
			
		||||
 | 
			
		||||
	br byteReader
 | 
			
		||||
	srcLen int
 | 
			
		||||
 | 
			
		||||
	// MaxSymbolValue will override the maximum symbol value of the next block.
 | 
			
		||||
	MaxSymbolValue uint8
 | 
			
		||||
| 
						 | 
				
			
			@ -170,7 +170,7 @@ func (s *Scratch) prepare(in []byte) (*Scratch, error) {
 | 
			
		|||
	if s.fse == nil {
 | 
			
		||||
		s.fse = &fse.Scratch{}
 | 
			
		||||
	}
 | 
			
		||||
	s.br.init(in)
 | 
			
		||||
	s.srcLen = len(in)
 | 
			
		||||
 | 
			
		||||
	return s, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -259,7 +259,7 @@ nyc-taxi-data-10M.csv   gzkp    1   3325605752  922273214   13929   227.68
 | 
			
		|||
 | 
			
		||||
## Decompressor
 | 
			
		||||
 | 
			
		||||
Staus: STABLE - there may still be subtle bugs, but a wide variety of content has been tested.
 | 
			
		||||
Status: STABLE - there may still be subtle bugs, but a wide variety of content has been tested.
 | 
			
		||||
 | 
			
		||||
This library is being continuously [fuzz-tested](https://github.com/klauspost/compress-fuzz),
 | 
			
		||||
kindly supplied by [fuzzit.dev](https://fuzzit.dev/). 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ func (m *match) estBits(bitsPerByte int32) {
 | 
			
		|||
	if m.rep < 0 {
 | 
			
		||||
		ofc = ofCode(uint32(m.s-m.offset) + 3)
 | 
			
		||||
	} else {
 | 
			
		||||
		ofc = ofCode(uint32(m.rep))
 | 
			
		||||
		ofc = ofCode(uint32(m.rep) & 3)
 | 
			
		||||
	}
 | 
			
		||||
	// Cost, excluding
 | 
			
		||||
	ofTT, mlTT := fsePredefEnc[tableOffsets].ct.symbolTT[ofc], fsePredefEnc[tableMatchLengths].ct.symbolTT[mlc]
 | 
			
		||||
| 
						 | 
				
			
			@ -227,7 +227,7 @@ encodeLoop:
 | 
			
		|||
				}
 | 
			
		||||
			}
 | 
			
		||||
			l := 4 + e.matchlen(s+4, offset+4, src)
 | 
			
		||||
			if rep < 0 {
 | 
			
		||||
			if true {
 | 
			
		||||
				// Extend candidate match backwards as far as possible.
 | 
			
		||||
				tMin := s - e.maxMatchOff
 | 
			
		||||
				if tMin < 0 {
 | 
			
		||||
| 
						 | 
				
			
			@ -282,6 +282,7 @@ encodeLoop:
 | 
			
		|||
		// Load next and check...
 | 
			
		||||
		e.longTable[nextHashL] = prevEntry{offset: s + e.cur, prev: candidateL.offset}
 | 
			
		||||
		e.table[nextHashS] = prevEntry{offset: s + e.cur, prev: candidateS.offset}
 | 
			
		||||
		index0 := s + 1
 | 
			
		||||
 | 
			
		||||
		// Look far ahead, unless we have a really long match already...
 | 
			
		||||
		if best.length < goodEnough {
 | 
			
		||||
| 
						 | 
				
			
			@ -357,19 +358,16 @@ encodeLoop:
 | 
			
		|||
			blk.sequences = append(blk.sequences, seq)
 | 
			
		||||
 | 
			
		||||
			// Index old s + 1 -> s - 1
 | 
			
		||||
			index0 := s + 1
 | 
			
		||||
			s = best.s + best.length
 | 
			
		||||
 | 
			
		||||
			nextEmit = s
 | 
			
		||||
			if s >= sLimit {
 | 
			
		||||
				if debugEncoder {
 | 
			
		||||
					println("repeat ended", s, best.length)
 | 
			
		||||
				}
 | 
			
		||||
				break encodeLoop
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Index skipped...
 | 
			
		||||
			end := s
 | 
			
		||||
			if s > sLimit+4 {
 | 
			
		||||
				end = sLimit + 4
 | 
			
		||||
			}
 | 
			
		||||
			off := index0 + e.cur
 | 
			
		||||
			for index0 < s {
 | 
			
		||||
			for index0 < end {
 | 
			
		||||
				cv0 := load6432(src, index0)
 | 
			
		||||
				h0 := hashLen(cv0, bestLongTableBits, bestLongLen)
 | 
			
		||||
				h1 := hashLen(cv0, bestShortTableBits, bestShortLen)
 | 
			
		||||
| 
						 | 
				
			
			@ -378,6 +376,7 @@ encodeLoop:
 | 
			
		|||
				off++
 | 
			
		||||
				index0++
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			switch best.rep {
 | 
			
		||||
			case 2, 4 | 1:
 | 
			
		||||
				offset1, offset2 = offset2, offset1
 | 
			
		||||
| 
						 | 
				
			
			@ -386,12 +385,17 @@ encodeLoop:
 | 
			
		|||
			case 4 | 3:
 | 
			
		||||
				offset1, offset2, offset3 = offset1-1, offset1, offset2
 | 
			
		||||
			}
 | 
			
		||||
			if s >= sLimit {
 | 
			
		||||
				if debugEncoder {
 | 
			
		||||
					println("repeat ended", s, best.length)
 | 
			
		||||
				}
 | 
			
		||||
				break encodeLoop
 | 
			
		||||
			}
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// A 4-byte match has been found. Update recent offsets.
 | 
			
		||||
		// We'll later see if more than 4 bytes.
 | 
			
		||||
		index0 := s + 1
 | 
			
		||||
		s = best.s
 | 
			
		||||
		t := best.offset
 | 
			
		||||
		offset1, offset2, offset3 = s-t, offset1, offset2
 | 
			
		||||
| 
						 | 
				
			
			@ -419,19 +423,25 @@ encodeLoop:
 | 
			
		|||
		}
 | 
			
		||||
		blk.sequences = append(blk.sequences, seq)
 | 
			
		||||
		nextEmit = s
 | 
			
		||||
		if s >= sLimit {
 | 
			
		||||
			break encodeLoop
 | 
			
		||||
 | 
			
		||||
		// Index old s + 1 -> s - 1 or sLimit
 | 
			
		||||
		end := s
 | 
			
		||||
		if s > sLimit-4 {
 | 
			
		||||
			end = sLimit - 4
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Index old s + 1 -> s - 1
 | 
			
		||||
		for index0 < s {
 | 
			
		||||
		off := index0 + e.cur
 | 
			
		||||
		for index0 < end {
 | 
			
		||||
			cv0 := load6432(src, index0)
 | 
			
		||||
			h0 := hashLen(cv0, bestLongTableBits, bestLongLen)
 | 
			
		||||
			h1 := hashLen(cv0, bestShortTableBits, bestShortLen)
 | 
			
		||||
			off := index0 + e.cur
 | 
			
		||||
			e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}
 | 
			
		||||
			e.table[h1] = prevEntry{offset: off, prev: e.table[h1].offset}
 | 
			
		||||
			index0++
 | 
			
		||||
			off++
 | 
			
		||||
		}
 | 
			
		||||
		if s >= sLimit {
 | 
			
		||||
			break encodeLoop
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -145,7 +145,7 @@ encodeLoop:
 | 
			
		|||
		var t int32
 | 
			
		||||
		// We allow the encoder to optionally turn off repeat offsets across blocks
 | 
			
		||||
		canRepeat := len(blk.sequences) > 2
 | 
			
		||||
		var matched int32
 | 
			
		||||
		var matched, index0 int32
 | 
			
		||||
 | 
			
		||||
		for {
 | 
			
		||||
			if debugAsserts && canRepeat && offset1 == 0 {
 | 
			
		||||
| 
						 | 
				
			
			@ -162,6 +162,7 @@ encodeLoop:
 | 
			
		|||
			off := s + e.cur
 | 
			
		||||
			e.longTable[nextHashL] = prevEntry{offset: off, prev: candidateL.offset}
 | 
			
		||||
			e.table[nextHashS] = tableEntry{offset: off, val: uint32(cv)}
 | 
			
		||||
			index0 = s + 1
 | 
			
		||||
 | 
			
		||||
			if canRepeat {
 | 
			
		||||
				if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -258,7 +259,6 @@ encodeLoop:
 | 
			
		|||
					}
 | 
			
		||||
					blk.sequences = append(blk.sequences, seq)
 | 
			
		||||
 | 
			
		||||
					index0 := s + repOff2
 | 
			
		||||
					s += lenght + repOff2
 | 
			
		||||
					nextEmit = s
 | 
			
		||||
					if s >= sLimit {
 | 
			
		||||
| 
						 | 
				
			
			@ -498,15 +498,15 @@ encodeLoop:
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		// Index match start+1 (long) -> s - 1
 | 
			
		||||
		index0 := s - l + 1
 | 
			
		||||
		off := index0 + e.cur
 | 
			
		||||
		for index0 < s-1 {
 | 
			
		||||
			cv0 := load6432(src, index0)
 | 
			
		||||
			cv1 := cv0 >> 8
 | 
			
		||||
			h0 := hashLen(cv0, betterLongTableBits, betterLongLen)
 | 
			
		||||
			off := index0 + e.cur
 | 
			
		||||
			e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}
 | 
			
		||||
			e.table[hashLen(cv1, betterShortTableBits, betterShortLen)] = tableEntry{offset: off + 1, val: uint32(cv1)}
 | 
			
		||||
			index0 += 2
 | 
			
		||||
			off += 2
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cv = load6432(src, s)
 | 
			
		||||
| 
						 | 
				
			
			@ -672,7 +672,7 @@ encodeLoop:
 | 
			
		|||
		var t int32
 | 
			
		||||
		// We allow the encoder to optionally turn off repeat offsets across blocks
 | 
			
		||||
		canRepeat := len(blk.sequences) > 2
 | 
			
		||||
		var matched int32
 | 
			
		||||
		var matched, index0 int32
 | 
			
		||||
 | 
			
		||||
		for {
 | 
			
		||||
			if debugAsserts && canRepeat && offset1 == 0 {
 | 
			
		||||
| 
						 | 
				
			
			@ -691,6 +691,7 @@ encodeLoop:
 | 
			
		|||
			e.markLongShardDirty(nextHashL)
 | 
			
		||||
			e.table[nextHashS] = tableEntry{offset: off, val: uint32(cv)}
 | 
			
		||||
			e.markShortShardDirty(nextHashS)
 | 
			
		||||
			index0 = s + 1
 | 
			
		||||
 | 
			
		||||
			if canRepeat {
 | 
			
		||||
				if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -726,7 +727,6 @@ encodeLoop:
 | 
			
		|||
					blk.sequences = append(blk.sequences, seq)
 | 
			
		||||
 | 
			
		||||
					// Index match start+1 (long) -> s - 1
 | 
			
		||||
					index0 := s + repOff
 | 
			
		||||
					s += lenght + repOff
 | 
			
		||||
 | 
			
		||||
					nextEmit = s
 | 
			
		||||
| 
						 | 
				
			
			@ -790,7 +790,6 @@ encodeLoop:
 | 
			
		|||
					}
 | 
			
		||||
					blk.sequences = append(blk.sequences, seq)
 | 
			
		||||
 | 
			
		||||
					index0 := s + repOff2
 | 
			
		||||
					s += lenght + repOff2
 | 
			
		||||
					nextEmit = s
 | 
			
		||||
					if s >= sLimit {
 | 
			
		||||
| 
						 | 
				
			
			@ -1024,18 +1023,18 @@ encodeLoop:
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		// Index match start+1 (long) -> s - 1
 | 
			
		||||
		index0 := s - l + 1
 | 
			
		||||
		off := index0 + e.cur
 | 
			
		||||
		for index0 < s-1 {
 | 
			
		||||
			cv0 := load6432(src, index0)
 | 
			
		||||
			cv1 := cv0 >> 8
 | 
			
		||||
			h0 := hashLen(cv0, betterLongTableBits, betterLongLen)
 | 
			
		||||
			off := index0 + e.cur
 | 
			
		||||
			e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}
 | 
			
		||||
			e.markLongShardDirty(h0)
 | 
			
		||||
			h1 := hashLen(cv1, betterShortTableBits, betterShortLen)
 | 
			
		||||
			e.table[h1] = tableEntry{offset: off + 1, val: uint32(cv1)}
 | 
			
		||||
			e.markShortShardDirty(h1)
 | 
			
		||||
			index0 += 2
 | 
			
		||||
			off += 2
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cv = load6432(src, s)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,7 @@ import (
 | 
			
		|||
 | 
			
		||||
	"github.com/moby/buildkit/util/bklog"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"go.opentelemetry.io/otel"
 | 
			
		||||
	"go.opentelemetry.io/otel/exporters/prometheus"
 | 
			
		||||
	"go.opentelemetry.io/otel/metric"
 | 
			
		||||
	sdkmetric "go.opentelemetry.io/otel/sdk/metric"
 | 
			
		||||
| 
						 | 
				
			
			@ -29,8 +30,6 @@ type detector struct {
 | 
			
		|||
var ServiceName string
 | 
			
		||||
var Recorder *TraceRecorder
 | 
			
		||||
 | 
			
		||||
var Resource *resource.Resource
 | 
			
		||||
 | 
			
		||||
var detectors map[string]detector
 | 
			
		||||
var once sync.Once
 | 
			
		||||
var tp trace.TracerProvider
 | 
			
		||||
| 
						 | 
				
			
			@ -114,17 +113,7 @@ func detect() error {
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if Resource == nil {
 | 
			
		||||
		res, err := resource.Detect(context.Background(), serviceNameDetector{})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		res, err = resource.Merge(resource.Default(), res)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		Resource = res
 | 
			
		||||
	}
 | 
			
		||||
	res := Resource()
 | 
			
		||||
 | 
			
		||||
	// enable log with traceID when valid exporter
 | 
			
		||||
	if texp != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -138,7 +127,7 @@ func detect() error {
 | 
			
		|||
 | 
			
		||||
		sdktp := sdktrace.NewTracerProvider(
 | 
			
		||||
			sdktrace.WithSpanProcessor(sp),
 | 
			
		||||
			sdktrace.WithResource(Resource),
 | 
			
		||||
			sdktrace.WithResource(res),
 | 
			
		||||
		)
 | 
			
		||||
		closers = append(closers, sdktp.Shutdown)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -164,7 +153,7 @@ func detect() error {
 | 
			
		|||
 | 
			
		||||
	if len(readers) > 0 {
 | 
			
		||||
		opts := make([]sdkmetric.Option, 0, len(readers)+1)
 | 
			
		||||
		opts = append(opts, sdkmetric.WithResource(Resource))
 | 
			
		||||
		opts = append(opts, sdkmetric.WithResource(res))
 | 
			
		||||
		for _, r := range readers {
 | 
			
		||||
			opts = append(opts, sdkmetric.WithReader(r))
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -220,6 +209,35 @@ func Shutdown(ctx context.Context) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	detectedResource     *resource.Resource
 | 
			
		||||
	detectedResourceOnce sync.Once
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Resource() *resource.Resource {
 | 
			
		||||
	detectedResourceOnce.Do(func() {
 | 
			
		||||
		res, err := resource.New(context.Background(),
 | 
			
		||||
			resource.WithDetectors(serviceNameDetector{}),
 | 
			
		||||
			resource.WithFromEnv(),
 | 
			
		||||
			resource.WithTelemetrySDK(),
 | 
			
		||||
		)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			otel.Handle(err)
 | 
			
		||||
		}
 | 
			
		||||
		detectedResource = res
 | 
			
		||||
	})
 | 
			
		||||
	return detectedResource
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OverrideResource overrides the resource returned from Resource.
 | 
			
		||||
//
 | 
			
		||||
// This must be invoked before Resource is called otherwise it is a no-op.
 | 
			
		||||
func OverrideResource(res *resource.Resource) {
 | 
			
		||||
	detectedResourceOnce.Do(func() {
 | 
			
		||||
		detectedResource = res
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type serviceNameDetector struct{}
 | 
			
		||||
 | 
			
		||||
func (serviceNameDetector) Detect(ctx context.Context) (*resource.Resource, error) {
 | 
			
		||||
| 
						 | 
				
			
			@ -227,9 +245,6 @@ func (serviceNameDetector) Detect(ctx context.Context) (*resource.Resource, erro
 | 
			
		|||
		semconv.SchemaURL,
 | 
			
		||||
		semconv.ServiceNameKey,
 | 
			
		||||
		func() (string, error) {
 | 
			
		||||
			if n := os.Getenv("OTEL_SERVICE_NAME"); n != "" {
 | 
			
		||||
				return n, nil
 | 
			
		||||
			}
 | 
			
		||||
			if ServiceName != "" {
 | 
			
		||||
				return ServiceName, nil
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,404 +0,0 @@
 | 
			
		|||
// Copyright The OpenTelemetry 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 internal // import "go.opentelemetry.io/otel/semconv/internal/v2"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/codes"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// HTTPConv are the HTTP semantic convention attributes defined for a version
 | 
			
		||||
// of the OpenTelemetry specification.
 | 
			
		||||
type HTTPConv struct {
 | 
			
		||||
	NetConv *NetConv
 | 
			
		||||
 | 
			
		||||
	EnduserIDKey                 attribute.Key
 | 
			
		||||
	HTTPClientIPKey              attribute.Key
 | 
			
		||||
	HTTPFlavorKey                attribute.Key
 | 
			
		||||
	HTTPMethodKey                attribute.Key
 | 
			
		||||
	HTTPRequestContentLengthKey  attribute.Key
 | 
			
		||||
	HTTPResponseContentLengthKey attribute.Key
 | 
			
		||||
	HTTPRouteKey                 attribute.Key
 | 
			
		||||
	HTTPSchemeHTTP               attribute.KeyValue
 | 
			
		||||
	HTTPSchemeHTTPS              attribute.KeyValue
 | 
			
		||||
	HTTPStatusCodeKey            attribute.Key
 | 
			
		||||
	HTTPTargetKey                attribute.Key
 | 
			
		||||
	HTTPURLKey                   attribute.Key
 | 
			
		||||
	HTTPUserAgentKey             attribute.Key
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ClientResponse returns attributes for an HTTP response received by a client
 | 
			
		||||
// from a server. The following attributes are returned if the related values
 | 
			
		||||
// are defined in resp: "http.status.code", "http.response_content_length".
 | 
			
		||||
//
 | 
			
		||||
// This does not add all OpenTelemetry required attributes for an HTTP event,
 | 
			
		||||
// it assumes ClientRequest was used to create the span with a complete set of
 | 
			
		||||
// attributes. If a complete set of attributes can be generated using the
 | 
			
		||||
// request contained in resp. For example:
 | 
			
		||||
//
 | 
			
		||||
//	append(ClientResponse(resp), ClientRequest(resp.Request)...)
 | 
			
		||||
func (c *HTTPConv) ClientResponse(resp *http.Response) []attribute.KeyValue {
 | 
			
		||||
	var n int
 | 
			
		||||
	if resp.StatusCode > 0 {
 | 
			
		||||
		n++
 | 
			
		||||
	}
 | 
			
		||||
	if resp.ContentLength > 0 {
 | 
			
		||||
		n++
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	attrs := make([]attribute.KeyValue, 0, n)
 | 
			
		||||
	if resp.StatusCode > 0 {
 | 
			
		||||
		attrs = append(attrs, c.HTTPStatusCodeKey.Int(resp.StatusCode))
 | 
			
		||||
	}
 | 
			
		||||
	if resp.ContentLength > 0 {
 | 
			
		||||
		attrs = append(attrs, c.HTTPResponseContentLengthKey.Int(int(resp.ContentLength)))
 | 
			
		||||
	}
 | 
			
		||||
	return attrs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ClientRequest returns attributes for an HTTP request made by a client. The
 | 
			
		||||
// following attributes are always returned: "http.url", "http.flavor",
 | 
			
		||||
// "http.method", "net.peer.name". The following attributes are returned if the
 | 
			
		||||
// related values are defined in req: "net.peer.port", "http.user_agent",
 | 
			
		||||
// "http.request_content_length", "enduser.id".
 | 
			
		||||
func (c *HTTPConv) ClientRequest(req *http.Request) []attribute.KeyValue {
 | 
			
		||||
	n := 3 // URL, peer name, proto, and method.
 | 
			
		||||
	var h string
 | 
			
		||||
	if req.URL != nil {
 | 
			
		||||
		h = req.URL.Host
 | 
			
		||||
	}
 | 
			
		||||
	peer, p := firstHostPort(h, req.Header.Get("Host"))
 | 
			
		||||
	port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", p)
 | 
			
		||||
	if port > 0 {
 | 
			
		||||
		n++
 | 
			
		||||
	}
 | 
			
		||||
	useragent := req.UserAgent()
 | 
			
		||||
	if useragent != "" {
 | 
			
		||||
		n++
 | 
			
		||||
	}
 | 
			
		||||
	if req.ContentLength > 0 {
 | 
			
		||||
		n++
 | 
			
		||||
	}
 | 
			
		||||
	userID, _, hasUserID := req.BasicAuth()
 | 
			
		||||
	if hasUserID {
 | 
			
		||||
		n++
 | 
			
		||||
	}
 | 
			
		||||
	attrs := make([]attribute.KeyValue, 0, n)
 | 
			
		||||
 | 
			
		||||
	attrs = append(attrs, c.method(req.Method))
 | 
			
		||||
	attrs = append(attrs, c.proto(req.Proto))
 | 
			
		||||
 | 
			
		||||
	var u string
 | 
			
		||||
	if req.URL != nil {
 | 
			
		||||
		// Remove any username/password info that may be in the URL.
 | 
			
		||||
		userinfo := req.URL.User
 | 
			
		||||
		req.URL.User = nil
 | 
			
		||||
		u = req.URL.String()
 | 
			
		||||
		// Restore any username/password info that was removed.
 | 
			
		||||
		req.URL.User = userinfo
 | 
			
		||||
	}
 | 
			
		||||
	attrs = append(attrs, c.HTTPURLKey.String(u))
 | 
			
		||||
 | 
			
		||||
	attrs = append(attrs, c.NetConv.PeerName(peer))
 | 
			
		||||
	if port > 0 {
 | 
			
		||||
		attrs = append(attrs, c.NetConv.PeerPort(port))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if useragent != "" {
 | 
			
		||||
		attrs = append(attrs, c.HTTPUserAgentKey.String(useragent))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if l := req.ContentLength; l > 0 {
 | 
			
		||||
		attrs = append(attrs, c.HTTPRequestContentLengthKey.Int64(l))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if hasUserID {
 | 
			
		||||
		attrs = append(attrs, c.EnduserIDKey.String(userID))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return attrs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ServerRequest returns attributes for an HTTP request received by a server.
 | 
			
		||||
//
 | 
			
		||||
// The server must be the primary server name if it is known. For example this
 | 
			
		||||
// would be the ServerName directive
 | 
			
		||||
// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache
 | 
			
		||||
// server, and the server_name directive
 | 
			
		||||
// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an
 | 
			
		||||
// nginx server. More generically, the primary server name would be the host
 | 
			
		||||
// header value that matches the default virtual host of an HTTP server. It
 | 
			
		||||
// should include the host identifier and if a port is used to route to the
 | 
			
		||||
// server that port identifier should be included as an appropriate port
 | 
			
		||||
// suffix.
 | 
			
		||||
//
 | 
			
		||||
// If the primary server name is not known, server should be an empty string.
 | 
			
		||||
// The req Host will be used to determine the server instead.
 | 
			
		||||
//
 | 
			
		||||
// The following attributes are always returned: "http.method", "http.scheme",
 | 
			
		||||
// "http.flavor", "http.target", "net.host.name". The following attributes are
 | 
			
		||||
// returned if they related values are defined in req: "net.host.port",
 | 
			
		||||
// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id",
 | 
			
		||||
// "http.client_ip".
 | 
			
		||||
func (c *HTTPConv) ServerRequest(server string, req *http.Request) []attribute.KeyValue {
 | 
			
		||||
	// TODO: This currently does not add the specification required
 | 
			
		||||
	// `http.target` attribute. It has too high of a cardinality to safely be
 | 
			
		||||
	// added. An alternate should be added, or this comment removed, when it is
 | 
			
		||||
	// addressed by the specification. If it is ultimately decided to continue
 | 
			
		||||
	// not including the attribute, the HTTPTargetKey field of the HTTPConv
 | 
			
		||||
	// should be removed as well.
 | 
			
		||||
 | 
			
		||||
	n := 4 // Method, scheme, proto, and host name.
 | 
			
		||||
	var host string
 | 
			
		||||
	var p int
 | 
			
		||||
	if server == "" {
 | 
			
		||||
		host, p = splitHostPort(req.Host)
 | 
			
		||||
	} else {
 | 
			
		||||
		// Prioritize the primary server name.
 | 
			
		||||
		host, p = splitHostPort(server)
 | 
			
		||||
		if p < 0 {
 | 
			
		||||
			_, p = splitHostPort(req.Host)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	hostPort := requiredHTTPPort(req.TLS != nil, p)
 | 
			
		||||
	if hostPort > 0 {
 | 
			
		||||
		n++
 | 
			
		||||
	}
 | 
			
		||||
	peer, peerPort := splitHostPort(req.RemoteAddr)
 | 
			
		||||
	if peer != "" {
 | 
			
		||||
		n++
 | 
			
		||||
		if peerPort > 0 {
 | 
			
		||||
			n++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	useragent := req.UserAgent()
 | 
			
		||||
	if useragent != "" {
 | 
			
		||||
		n++
 | 
			
		||||
	}
 | 
			
		||||
	userID, _, hasUserID := req.BasicAuth()
 | 
			
		||||
	if hasUserID {
 | 
			
		||||
		n++
 | 
			
		||||
	}
 | 
			
		||||
	clientIP := serverClientIP(req.Header.Get("X-Forwarded-For"))
 | 
			
		||||
	if clientIP != "" {
 | 
			
		||||
		n++
 | 
			
		||||
	}
 | 
			
		||||
	attrs := make([]attribute.KeyValue, 0, n)
 | 
			
		||||
 | 
			
		||||
	attrs = append(attrs, c.method(req.Method))
 | 
			
		||||
	attrs = append(attrs, c.scheme(req.TLS != nil))
 | 
			
		||||
	attrs = append(attrs, c.proto(req.Proto))
 | 
			
		||||
	attrs = append(attrs, c.NetConv.HostName(host))
 | 
			
		||||
 | 
			
		||||
	if hostPort > 0 {
 | 
			
		||||
		attrs = append(attrs, c.NetConv.HostPort(hostPort))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if peer != "" {
 | 
			
		||||
		// The Go HTTP server sets RemoteAddr to "IP:port", this will not be a
 | 
			
		||||
		// file-path that would be interpreted with a sock family.
 | 
			
		||||
		attrs = append(attrs, c.NetConv.SockPeerAddr(peer))
 | 
			
		||||
		if peerPort > 0 {
 | 
			
		||||
			attrs = append(attrs, c.NetConv.SockPeerPort(peerPort))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if useragent != "" {
 | 
			
		||||
		attrs = append(attrs, c.HTTPUserAgentKey.String(useragent))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if hasUserID {
 | 
			
		||||
		attrs = append(attrs, c.EnduserIDKey.String(userID))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if clientIP != "" {
 | 
			
		||||
		attrs = append(attrs, c.HTTPClientIPKey.String(clientIP))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return attrs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *HTTPConv) method(method string) attribute.KeyValue {
 | 
			
		||||
	if method == "" {
 | 
			
		||||
		return c.HTTPMethodKey.String(http.MethodGet)
 | 
			
		||||
	}
 | 
			
		||||
	return c.HTTPMethodKey.String(method)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *HTTPConv) scheme(https bool) attribute.KeyValue { // nolint:revive
 | 
			
		||||
	if https {
 | 
			
		||||
		return c.HTTPSchemeHTTPS
 | 
			
		||||
	}
 | 
			
		||||
	return c.HTTPSchemeHTTP
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *HTTPConv) proto(proto string) attribute.KeyValue {
 | 
			
		||||
	switch proto {
 | 
			
		||||
	case "HTTP/1.0":
 | 
			
		||||
		return c.HTTPFlavorKey.String("1.0")
 | 
			
		||||
	case "HTTP/1.1":
 | 
			
		||||
		return c.HTTPFlavorKey.String("1.1")
 | 
			
		||||
	case "HTTP/2":
 | 
			
		||||
		return c.HTTPFlavorKey.String("2.0")
 | 
			
		||||
	case "HTTP/3":
 | 
			
		||||
		return c.HTTPFlavorKey.String("3.0")
 | 
			
		||||
	default:
 | 
			
		||||
		return c.HTTPFlavorKey.String(proto)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func serverClientIP(xForwardedFor string) string {
 | 
			
		||||
	if idx := strings.Index(xForwardedFor, ","); idx >= 0 {
 | 
			
		||||
		xForwardedFor = xForwardedFor[:idx]
 | 
			
		||||
	}
 | 
			
		||||
	return xForwardedFor
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func requiredHTTPPort(https bool, port int) int { // nolint:revive
 | 
			
		||||
	if https {
 | 
			
		||||
		if port > 0 && port != 443 {
 | 
			
		||||
			return port
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if port > 0 && port != 80 {
 | 
			
		||||
			return port
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Return the request host and port from the first non-empty source.
 | 
			
		||||
func firstHostPort(source ...string) (host string, port int) {
 | 
			
		||||
	for _, hostport := range source {
 | 
			
		||||
		host, port = splitHostPort(hostport)
 | 
			
		||||
		if host != "" || port > 0 {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RequestHeader returns the contents of h as OpenTelemetry attributes.
 | 
			
		||||
func (c *HTTPConv) RequestHeader(h http.Header) []attribute.KeyValue {
 | 
			
		||||
	return c.header("http.request.header", h)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResponseHeader returns the contents of h as OpenTelemetry attributes.
 | 
			
		||||
func (c *HTTPConv) ResponseHeader(h http.Header) []attribute.KeyValue {
 | 
			
		||||
	return c.header("http.response.header", h)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *HTTPConv) header(prefix string, h http.Header) []attribute.KeyValue {
 | 
			
		||||
	key := func(k string) attribute.Key {
 | 
			
		||||
		k = strings.ToLower(k)
 | 
			
		||||
		k = strings.ReplaceAll(k, "-", "_")
 | 
			
		||||
		k = fmt.Sprintf("%s.%s", prefix, k)
 | 
			
		||||
		return attribute.Key(k)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	attrs := make([]attribute.KeyValue, 0, len(h))
 | 
			
		||||
	for k, v := range h {
 | 
			
		||||
		attrs = append(attrs, key(k).StringSlice(v))
 | 
			
		||||
	}
 | 
			
		||||
	return attrs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ClientStatus returns a span status code and message for an HTTP status code
 | 
			
		||||
// value received by a client.
 | 
			
		||||
func (c *HTTPConv) ClientStatus(code int) (codes.Code, string) {
 | 
			
		||||
	stat, valid := validateHTTPStatusCode(code)
 | 
			
		||||
	if !valid {
 | 
			
		||||
		return stat, fmt.Sprintf("Invalid HTTP status code %d", code)
 | 
			
		||||
	}
 | 
			
		||||
	return stat, ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ServerStatus returns a span status code and message for an HTTP status code
 | 
			
		||||
// value returned by a server. Status codes in the 400-499 range are not
 | 
			
		||||
// returned as errors.
 | 
			
		||||
func (c *HTTPConv) ServerStatus(code int) (codes.Code, string) {
 | 
			
		||||
	stat, valid := validateHTTPStatusCode(code)
 | 
			
		||||
	if !valid {
 | 
			
		||||
		return stat, fmt.Sprintf("Invalid HTTP status code %d", code)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if code/100 == 4 {
 | 
			
		||||
		return codes.Unset, ""
 | 
			
		||||
	}
 | 
			
		||||
	return stat, ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type codeRange struct {
 | 
			
		||||
	fromInclusive int
 | 
			
		||||
	toInclusive   int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r codeRange) contains(code int) bool {
 | 
			
		||||
	return r.fromInclusive <= code && code <= r.toInclusive
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var validRangesPerCategory = map[int][]codeRange{
 | 
			
		||||
	1: {
 | 
			
		||||
		{http.StatusContinue, http.StatusEarlyHints},
 | 
			
		||||
	},
 | 
			
		||||
	2: {
 | 
			
		||||
		{http.StatusOK, http.StatusAlreadyReported},
 | 
			
		||||
		{http.StatusIMUsed, http.StatusIMUsed},
 | 
			
		||||
	},
 | 
			
		||||
	3: {
 | 
			
		||||
		{http.StatusMultipleChoices, http.StatusUseProxy},
 | 
			
		||||
		{http.StatusTemporaryRedirect, http.StatusPermanentRedirect},
 | 
			
		||||
	},
 | 
			
		||||
	4: {
 | 
			
		||||
		{http.StatusBadRequest, http.StatusTeapot}, // yes, teapot is so useful…
 | 
			
		||||
		{http.StatusMisdirectedRequest, http.StatusUpgradeRequired},
 | 
			
		||||
		{http.StatusPreconditionRequired, http.StatusTooManyRequests},
 | 
			
		||||
		{http.StatusRequestHeaderFieldsTooLarge, http.StatusRequestHeaderFieldsTooLarge},
 | 
			
		||||
		{http.StatusUnavailableForLegalReasons, http.StatusUnavailableForLegalReasons},
 | 
			
		||||
	},
 | 
			
		||||
	5: {
 | 
			
		||||
		{http.StatusInternalServerError, http.StatusLoopDetected},
 | 
			
		||||
		{http.StatusNotExtended, http.StatusNetworkAuthenticationRequired},
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// validateHTTPStatusCode validates the HTTP status code and returns
 | 
			
		||||
// corresponding span status code. If the `code` is not a valid HTTP status
 | 
			
		||||
// code, returns span status Error and false.
 | 
			
		||||
func validateHTTPStatusCode(code int) (codes.Code, bool) {
 | 
			
		||||
	category := code / 100
 | 
			
		||||
	ranges, ok := validRangesPerCategory[category]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return codes.Error, false
 | 
			
		||||
	}
 | 
			
		||||
	ok = false
 | 
			
		||||
	for _, crange := range ranges {
 | 
			
		||||
		ok = crange.contains(code)
 | 
			
		||||
		if ok {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return codes.Error, false
 | 
			
		||||
	}
 | 
			
		||||
	if category > 0 && category < 4 {
 | 
			
		||||
		return codes.Unset, true
 | 
			
		||||
	}
 | 
			
		||||
	return codes.Error, true
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,324 +0,0 @@
 | 
			
		|||
// Copyright The OpenTelemetry 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 internal // import "go.opentelemetry.io/otel/semconv/internal/v2"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// NetConv are the network semantic convention attributes defined for a version
 | 
			
		||||
// of the OpenTelemetry specification.
 | 
			
		||||
type NetConv struct {
 | 
			
		||||
	NetHostNameKey     attribute.Key
 | 
			
		||||
	NetHostPortKey     attribute.Key
 | 
			
		||||
	NetPeerNameKey     attribute.Key
 | 
			
		||||
	NetPeerPortKey     attribute.Key
 | 
			
		||||
	NetSockFamilyKey   attribute.Key
 | 
			
		||||
	NetSockPeerAddrKey attribute.Key
 | 
			
		||||
	NetSockPeerPortKey attribute.Key
 | 
			
		||||
	NetSockHostAddrKey attribute.Key
 | 
			
		||||
	NetSockHostPortKey attribute.Key
 | 
			
		||||
	NetTransportOther  attribute.KeyValue
 | 
			
		||||
	NetTransportTCP    attribute.KeyValue
 | 
			
		||||
	NetTransportUDP    attribute.KeyValue
 | 
			
		||||
	NetTransportInProc attribute.KeyValue
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *NetConv) Transport(network string) attribute.KeyValue {
 | 
			
		||||
	switch network {
 | 
			
		||||
	case "tcp", "tcp4", "tcp6":
 | 
			
		||||
		return c.NetTransportTCP
 | 
			
		||||
	case "udp", "udp4", "udp6":
 | 
			
		||||
		return c.NetTransportUDP
 | 
			
		||||
	case "unix", "unixgram", "unixpacket":
 | 
			
		||||
		return c.NetTransportInProc
 | 
			
		||||
	default:
 | 
			
		||||
		// "ip:*", "ip4:*", and "ip6:*" all are considered other.
 | 
			
		||||
		return c.NetTransportOther
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Host returns attributes for a network host address.
 | 
			
		||||
func (c *NetConv) Host(address string) []attribute.KeyValue {
 | 
			
		||||
	h, p := splitHostPort(address)
 | 
			
		||||
	var n int
 | 
			
		||||
	if h != "" {
 | 
			
		||||
		n++
 | 
			
		||||
		if p > 0 {
 | 
			
		||||
			n++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if n == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	attrs := make([]attribute.KeyValue, 0, n)
 | 
			
		||||
	attrs = append(attrs, c.HostName(h))
 | 
			
		||||
	if p > 0 {
 | 
			
		||||
		attrs = append(attrs, c.HostPort(int(p)))
 | 
			
		||||
	}
 | 
			
		||||
	return attrs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Server returns attributes for a network listener listening at address. See
 | 
			
		||||
// net.Listen for information about acceptable address values, address should
 | 
			
		||||
// be the same as the one used to create ln. If ln is nil, only network host
 | 
			
		||||
// attributes will be returned that describe address. Otherwise, the socket
 | 
			
		||||
// level information about ln will also be included.
 | 
			
		||||
func (c *NetConv) Server(address string, ln net.Listener) []attribute.KeyValue {
 | 
			
		||||
	if ln == nil {
 | 
			
		||||
		return c.Host(address)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lAddr := ln.Addr()
 | 
			
		||||
	if lAddr == nil {
 | 
			
		||||
		return c.Host(address)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hostName, hostPort := splitHostPort(address)
 | 
			
		||||
	sockHostAddr, sockHostPort := splitHostPort(lAddr.String())
 | 
			
		||||
	network := lAddr.Network()
 | 
			
		||||
	sockFamily := family(network, sockHostAddr)
 | 
			
		||||
 | 
			
		||||
	n := nonZeroStr(hostName, network, sockHostAddr, sockFamily)
 | 
			
		||||
	n += positiveInt(hostPort, sockHostPort)
 | 
			
		||||
	attr := make([]attribute.KeyValue, 0, n)
 | 
			
		||||
	if hostName != "" {
 | 
			
		||||
		attr = append(attr, c.HostName(hostName))
 | 
			
		||||
		if hostPort > 0 {
 | 
			
		||||
			// Only if net.host.name is set should net.host.port be.
 | 
			
		||||
			attr = append(attr, c.HostPort(hostPort))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if network != "" {
 | 
			
		||||
		attr = append(attr, c.Transport(network))
 | 
			
		||||
	}
 | 
			
		||||
	if sockFamily != "" {
 | 
			
		||||
		attr = append(attr, c.NetSockFamilyKey.String(sockFamily))
 | 
			
		||||
	}
 | 
			
		||||
	if sockHostAddr != "" {
 | 
			
		||||
		attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr))
 | 
			
		||||
		if sockHostPort > 0 {
 | 
			
		||||
			// Only if net.sock.host.addr is set should net.sock.host.port be.
 | 
			
		||||
			attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return attr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *NetConv) HostName(name string) attribute.KeyValue {
 | 
			
		||||
	return c.NetHostNameKey.String(name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *NetConv) HostPort(port int) attribute.KeyValue {
 | 
			
		||||
	return c.NetHostPortKey.Int(port)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Client returns attributes for a client network connection to address. See
 | 
			
		||||
// net.Dial for information about acceptable address values, address should be
 | 
			
		||||
// the same as the one used to create conn. If conn is nil, only network peer
 | 
			
		||||
// attributes will be returned that describe address. Otherwise, the socket
 | 
			
		||||
// level information about conn will also be included.
 | 
			
		||||
func (c *NetConv) Client(address string, conn net.Conn) []attribute.KeyValue {
 | 
			
		||||
	if conn == nil {
 | 
			
		||||
		return c.Peer(address)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lAddr, rAddr := conn.LocalAddr(), conn.RemoteAddr()
 | 
			
		||||
 | 
			
		||||
	var network string
 | 
			
		||||
	switch {
 | 
			
		||||
	case lAddr != nil:
 | 
			
		||||
		network = lAddr.Network()
 | 
			
		||||
	case rAddr != nil:
 | 
			
		||||
		network = rAddr.Network()
 | 
			
		||||
	default:
 | 
			
		||||
		return c.Peer(address)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	peerName, peerPort := splitHostPort(address)
 | 
			
		||||
	var (
 | 
			
		||||
		sockFamily   string
 | 
			
		||||
		sockPeerAddr string
 | 
			
		||||
		sockPeerPort int
 | 
			
		||||
		sockHostAddr string
 | 
			
		||||
		sockHostPort int
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	if lAddr != nil {
 | 
			
		||||
		sockHostAddr, sockHostPort = splitHostPort(lAddr.String())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if rAddr != nil {
 | 
			
		||||
		sockPeerAddr, sockPeerPort = splitHostPort(rAddr.String())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch {
 | 
			
		||||
	case sockHostAddr != "":
 | 
			
		||||
		sockFamily = family(network, sockHostAddr)
 | 
			
		||||
	case sockPeerAddr != "":
 | 
			
		||||
		sockFamily = family(network, sockPeerAddr)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	n := nonZeroStr(peerName, network, sockPeerAddr, sockHostAddr, sockFamily)
 | 
			
		||||
	n += positiveInt(peerPort, sockPeerPort, sockHostPort)
 | 
			
		||||
	attr := make([]attribute.KeyValue, 0, n)
 | 
			
		||||
	if peerName != "" {
 | 
			
		||||
		attr = append(attr, c.PeerName(peerName))
 | 
			
		||||
		if peerPort > 0 {
 | 
			
		||||
			// Only if net.peer.name is set should net.peer.port be.
 | 
			
		||||
			attr = append(attr, c.PeerPort(peerPort))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if network != "" {
 | 
			
		||||
		attr = append(attr, c.Transport(network))
 | 
			
		||||
	}
 | 
			
		||||
	if sockFamily != "" {
 | 
			
		||||
		attr = append(attr, c.NetSockFamilyKey.String(sockFamily))
 | 
			
		||||
	}
 | 
			
		||||
	if sockPeerAddr != "" {
 | 
			
		||||
		attr = append(attr, c.NetSockPeerAddrKey.String(sockPeerAddr))
 | 
			
		||||
		if sockPeerPort > 0 {
 | 
			
		||||
			// Only if net.sock.peer.addr is set should net.sock.peer.port be.
 | 
			
		||||
			attr = append(attr, c.NetSockPeerPortKey.Int(sockPeerPort))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if sockHostAddr != "" {
 | 
			
		||||
		attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr))
 | 
			
		||||
		if sockHostPort > 0 {
 | 
			
		||||
			// Only if net.sock.host.addr is set should net.sock.host.port be.
 | 
			
		||||
			attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return attr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func family(network, address string) string {
 | 
			
		||||
	switch network {
 | 
			
		||||
	case "unix", "unixgram", "unixpacket":
 | 
			
		||||
		return "unix"
 | 
			
		||||
	default:
 | 
			
		||||
		if ip := net.ParseIP(address); ip != nil {
 | 
			
		||||
			if ip.To4() == nil {
 | 
			
		||||
				return "inet6"
 | 
			
		||||
			}
 | 
			
		||||
			return "inet"
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func nonZeroStr(strs ...string) int {
 | 
			
		||||
	var n int
 | 
			
		||||
	for _, str := range strs {
 | 
			
		||||
		if str != "" {
 | 
			
		||||
			n++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func positiveInt(ints ...int) int {
 | 
			
		||||
	var n int
 | 
			
		||||
	for _, i := range ints {
 | 
			
		||||
		if i > 0 {
 | 
			
		||||
			n++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Peer returns attributes for a network peer address.
 | 
			
		||||
func (c *NetConv) Peer(address string) []attribute.KeyValue {
 | 
			
		||||
	h, p := splitHostPort(address)
 | 
			
		||||
	var n int
 | 
			
		||||
	if h != "" {
 | 
			
		||||
		n++
 | 
			
		||||
		if p > 0 {
 | 
			
		||||
			n++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if n == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	attrs := make([]attribute.KeyValue, 0, n)
 | 
			
		||||
	attrs = append(attrs, c.PeerName(h))
 | 
			
		||||
	if p > 0 {
 | 
			
		||||
		attrs = append(attrs, c.PeerPort(int(p)))
 | 
			
		||||
	}
 | 
			
		||||
	return attrs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *NetConv) PeerName(name string) attribute.KeyValue {
 | 
			
		||||
	return c.NetPeerNameKey.String(name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *NetConv) PeerPort(port int) attribute.KeyValue {
 | 
			
		||||
	return c.NetPeerPortKey.Int(port)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *NetConv) SockPeerAddr(addr string) attribute.KeyValue {
 | 
			
		||||
	return c.NetSockPeerAddrKey.String(addr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *NetConv) SockPeerPort(port int) attribute.KeyValue {
 | 
			
		||||
	return c.NetSockPeerPortKey.Int(port)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// splitHostPort splits a network address hostport of the form "host",
 | 
			
		||||
// "host%zone", "[host]", "[host%zone], "host:port", "host%zone:port",
 | 
			
		||||
// "[host]:port", "[host%zone]:port", or ":port" into host or host%zone and
 | 
			
		||||
// port.
 | 
			
		||||
//
 | 
			
		||||
// An empty host is returned if it is not provided or unparsable. A negative
 | 
			
		||||
// port is returned if it is not provided or unparsable.
 | 
			
		||||
func splitHostPort(hostport string) (host string, port int) {
 | 
			
		||||
	port = -1
 | 
			
		||||
 | 
			
		||||
	if strings.HasPrefix(hostport, "[") {
 | 
			
		||||
		addrEnd := strings.LastIndex(hostport, "]")
 | 
			
		||||
		if addrEnd < 0 {
 | 
			
		||||
			// Invalid hostport.
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if i := strings.LastIndex(hostport[addrEnd:], ":"); i < 0 {
 | 
			
		||||
			host = hostport[1:addrEnd]
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if i := strings.LastIndex(hostport, ":"); i < 0 {
 | 
			
		||||
			host = hostport
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	host, pStr, err := net.SplitHostPort(hostport)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p, err := strconv.ParseUint(pStr, 10, 16)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return host, int(p)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,152 +0,0 @@
 | 
			
		|||
// Copyright The OpenTelemetry 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 httpconv provides OpenTelemetry HTTP semantic conventions for
 | 
			
		||||
// tracing telemetry.
 | 
			
		||||
package httpconv // import "go.opentelemetry.io/otel/semconv/v1.17.0/httpconv"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"go.opentelemetry.io/otel/attribute"
 | 
			
		||||
	"go.opentelemetry.io/otel/codes"
 | 
			
		||||
	"go.opentelemetry.io/otel/semconv/internal/v2"
 | 
			
		||||
	semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	nc = &internal.NetConv{
 | 
			
		||||
		NetHostNameKey:     semconv.NetHostNameKey,
 | 
			
		||||
		NetHostPortKey:     semconv.NetHostPortKey,
 | 
			
		||||
		NetPeerNameKey:     semconv.NetPeerNameKey,
 | 
			
		||||
		NetPeerPortKey:     semconv.NetPeerPortKey,
 | 
			
		||||
		NetSockPeerAddrKey: semconv.NetSockPeerAddrKey,
 | 
			
		||||
		NetSockPeerPortKey: semconv.NetSockPeerPortKey,
 | 
			
		||||
		NetTransportOther:  semconv.NetTransportOther,
 | 
			
		||||
		NetTransportTCP:    semconv.NetTransportTCP,
 | 
			
		||||
		NetTransportUDP:    semconv.NetTransportUDP,
 | 
			
		||||
		NetTransportInProc: semconv.NetTransportInProc,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hc = &internal.HTTPConv{
 | 
			
		||||
		NetConv: nc,
 | 
			
		||||
 | 
			
		||||
		EnduserIDKey:                 semconv.EnduserIDKey,
 | 
			
		||||
		HTTPClientIPKey:              semconv.HTTPClientIPKey,
 | 
			
		||||
		HTTPFlavorKey:                semconv.HTTPFlavorKey,
 | 
			
		||||
		HTTPMethodKey:                semconv.HTTPMethodKey,
 | 
			
		||||
		HTTPRequestContentLengthKey:  semconv.HTTPRequestContentLengthKey,
 | 
			
		||||
		HTTPResponseContentLengthKey: semconv.HTTPResponseContentLengthKey,
 | 
			
		||||
		HTTPRouteKey:                 semconv.HTTPRouteKey,
 | 
			
		||||
		HTTPSchemeHTTP:               semconv.HTTPSchemeHTTP,
 | 
			
		||||
		HTTPSchemeHTTPS:              semconv.HTTPSchemeHTTPS,
 | 
			
		||||
		HTTPStatusCodeKey:            semconv.HTTPStatusCodeKey,
 | 
			
		||||
		HTTPTargetKey:                semconv.HTTPTargetKey,
 | 
			
		||||
		HTTPURLKey:                   semconv.HTTPURLKey,
 | 
			
		||||
		HTTPUserAgentKey:             semconv.HTTPUserAgentKey,
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ClientResponse returns trace attributes for an HTTP response received by a
 | 
			
		||||
// client from a server. It will return the following attributes if the related
 | 
			
		||||
// values are defined in resp: "http.status.code",
 | 
			
		||||
// "http.response_content_length".
 | 
			
		||||
//
 | 
			
		||||
// This does not add all OpenTelemetry required attributes for an HTTP event,
 | 
			
		||||
// it assumes ClientRequest was used to create the span with a complete set of
 | 
			
		||||
// attributes. If a complete set of attributes can be generated using the
 | 
			
		||||
// request contained in resp. For example:
 | 
			
		||||
//
 | 
			
		||||
//	append(ClientResponse(resp), ClientRequest(resp.Request)...)
 | 
			
		||||
func ClientResponse(resp *http.Response) []attribute.KeyValue {
 | 
			
		||||
	return hc.ClientResponse(resp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ClientRequest returns trace attributes for an HTTP request made by a client.
 | 
			
		||||
// The following attributes are always returned: "http.url", "http.flavor",
 | 
			
		||||
// "http.method", "net.peer.name". The following attributes are returned if the
 | 
			
		||||
// related values are defined in req: "net.peer.port", "http.user_agent",
 | 
			
		||||
// "http.request_content_length", "enduser.id".
 | 
			
		||||
func ClientRequest(req *http.Request) []attribute.KeyValue {
 | 
			
		||||
	return hc.ClientRequest(req)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ClientStatus returns a span status code and message for an HTTP status code
 | 
			
		||||
// value received by a client.
 | 
			
		||||
func ClientStatus(code int) (codes.Code, string) {
 | 
			
		||||
	return hc.ClientStatus(code)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ServerRequest returns trace attributes for an HTTP request received by a
 | 
			
		||||
// server.
 | 
			
		||||
//
 | 
			
		||||
// The server must be the primary server name if it is known. For example this
 | 
			
		||||
// would be the ServerName directive
 | 
			
		||||
// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache
 | 
			
		||||
// server, and the server_name directive
 | 
			
		||||
// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an
 | 
			
		||||
// nginx server. More generically, the primary server name would be the host
 | 
			
		||||
// header value that matches the default virtual host of an HTTP server. It
 | 
			
		||||
// should include the host identifier and if a port is used to route to the
 | 
			
		||||
// server that port identifier should be included as an appropriate port
 | 
			
		||||
// suffix.
 | 
			
		||||
//
 | 
			
		||||
// If the primary server name is not known, server should be an empty string.
 | 
			
		||||
// The req Host will be used to determine the server instead.
 | 
			
		||||
//
 | 
			
		||||
// The following attributes are always returned: "http.method", "http.scheme",
 | 
			
		||||
// "http.flavor", "http.target", "net.host.name". The following attributes are
 | 
			
		||||
// returned if they related values are defined in req: "net.host.port",
 | 
			
		||||
// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id",
 | 
			
		||||
// "http.client_ip".
 | 
			
		||||
func ServerRequest(server string, req *http.Request) []attribute.KeyValue {
 | 
			
		||||
	return hc.ServerRequest(server, req)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ServerStatus returns a span status code and message for an HTTP status code
 | 
			
		||||
// value returned by a server. Status codes in the 400-499 range are not
 | 
			
		||||
// returned as errors.
 | 
			
		||||
func ServerStatus(code int) (codes.Code, string) {
 | 
			
		||||
	return hc.ServerStatus(code)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RequestHeader returns the contents of h as attributes.
 | 
			
		||||
//
 | 
			
		||||
// Instrumentation should require an explicit configuration of which headers to
 | 
			
		||||
// captured and then prune what they pass here. Including all headers can be a
 | 
			
		||||
// security risk - explicit configuration helps avoid leaking sensitive
 | 
			
		||||
// information.
 | 
			
		||||
//
 | 
			
		||||
// The User-Agent header is already captured in the http.user_agent attribute
 | 
			
		||||
// from ClientRequest and ServerRequest. Instrumentation may provide an option
 | 
			
		||||
// to capture that header here even though it is not recommended. Otherwise,
 | 
			
		||||
// instrumentation should filter that out of what is passed.
 | 
			
		||||
func RequestHeader(h http.Header) []attribute.KeyValue {
 | 
			
		||||
	return hc.RequestHeader(h)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResponseHeader returns the contents of h as attributes.
 | 
			
		||||
//
 | 
			
		||||
// Instrumentation should require an explicit configuration of which headers to
 | 
			
		||||
// captured and then prune what they pass here. Including all headers can be a
 | 
			
		||||
// security risk - explicit configuration helps avoid leaking sensitive
 | 
			
		||||
// information.
 | 
			
		||||
//
 | 
			
		||||
// The User-Agent header is already captured in the http.user_agent attribute
 | 
			
		||||
// from ClientRequest and ServerRequest. Instrumentation may provide an option
 | 
			
		||||
// to capture that header here even though it is not recommended. Otherwise,
 | 
			
		||||
// instrumentation should filter that out of what is passed.
 | 
			
		||||
func ResponseHeader(h http.Header) []attribute.KeyValue {
 | 
			
		||||
	return hc.ResponseHeader(h)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build gc && !purego
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
 | 
			
		||||
package chacha20
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build gc && !purego
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build (!arm64 && !s390x && !ppc64le) || !gc || purego
 | 
			
		||||
// +build !arm64,!s390x,!ppc64le !gc purego
 | 
			
		||||
 | 
			
		||||
package chacha20
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build gc && !purego
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
 | 
			
		||||
package chacha20
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,6 @@
 | 
			
		|||
// due to the calling conventions and initialization of constants.
 | 
			
		||||
 | 
			
		||||
//go:build gc && !purego
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build gc && !purego
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
 | 
			
		||||
package chacha20
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build gc && !purego
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
 | 
			
		||||
#include "go_asm.h"
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
//go:build amd64 && gc && !purego
 | 
			
		||||
// +build amd64,gc,!purego
 | 
			
		||||
 | 
			
		||||
package field
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
//go:build amd64 && gc && !purego
 | 
			
		||||
// +build amd64,gc,!purego
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build !amd64 || !gc || purego
 | 
			
		||||
// +build !amd64 !gc purego
 | 
			
		||||
 | 
			
		||||
package field
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build arm64 && gc && !purego
 | 
			
		||||
// +build arm64,gc,!purego
 | 
			
		||||
 | 
			
		||||
package field
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build arm64 && gc && !purego
 | 
			
		||||
// +build arm64,gc,!purego
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build !arm64 || !gc || purego
 | 
			
		||||
// +build !arm64 !gc purego
 | 
			
		||||
 | 
			
		||||
package field
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build !purego
 | 
			
		||||
// +build !purego
 | 
			
		||||
 | 
			
		||||
// Package alias implements memory aliasing tests.
 | 
			
		||||
package alias
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build purego
 | 
			
		||||
// +build purego
 | 
			
		||||
 | 
			
		||||
// Package alias implements memory aliasing tests.
 | 
			
		||||
package alias
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build !go1.13
 | 
			
		||||
// +build !go1.13
 | 
			
		||||
 | 
			
		||||
package poly1305
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build go1.13
 | 
			
		||||
// +build go1.13
 | 
			
		||||
 | 
			
		||||
package poly1305
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build (!amd64 && !ppc64le && !s390x) || !gc || purego
 | 
			
		||||
// +build !amd64,!ppc64le,!s390x !gc purego
 | 
			
		||||
 | 
			
		||||
package poly1305
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build gc && !purego
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
 | 
			
		||||
package poly1305
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build gc && !purego
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build gc && !purego
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
 | 
			
		||||
package poly1305
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build gc && !purego
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build gc && !purego
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
 | 
			
		||||
package poly1305
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//go:build gc && !purego
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -141,9 +141,14 @@ const (
 | 
			
		|||
	agentAddSmartcardKeyConstrained = 26
 | 
			
		||||
 | 
			
		||||
	// 3.7 Key constraint identifiers
 | 
			
		||||
	agentConstrainLifetime  = 1
 | 
			
		||||
	agentConstrainConfirm   = 2
 | 
			
		||||
	agentConstrainExtension = 3
 | 
			
		||||
	agentConstrainLifetime = 1
 | 
			
		||||
	agentConstrainConfirm  = 2
 | 
			
		||||
	// Constraint extension identifier up to version 2 of the protocol. A
 | 
			
		||||
	// backward incompatible change will be required if we want to add support
 | 
			
		||||
	// for SSH_AGENT_CONSTRAIN_MAXSIGN which uses the same ID.
 | 
			
		||||
	agentConstrainExtensionV00 = 3
 | 
			
		||||
	// Constraint extension identifier in version 3 and later of the protocol.
 | 
			
		||||
	agentConstrainExtension = 255
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// maxAgentResponseBytes is the maximum agent reply size that is accepted. This
 | 
			
		||||
| 
						 | 
				
			
			@ -205,7 +210,7 @@ type constrainLifetimeAgentMsg struct {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
type constrainExtensionAgentMsg struct {
 | 
			
		||||
	ExtensionName    string `sshtype:"3"`
 | 
			
		||||
	ExtensionName    string `sshtype:"255|3"`
 | 
			
		||||
	ExtensionDetails []byte
 | 
			
		||||
 | 
			
		||||
	// Rest is a field used for parsing, not part of message
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -208,7 +208,7 @@ func parseConstraints(constraints []byte) (lifetimeSecs uint32, confirmBeforeUse
 | 
			
		|||
		case agentConstrainConfirm:
 | 
			
		||||
			confirmBeforeUse = true
 | 
			
		||||
			constraints = constraints[1:]
 | 
			
		||||
		case agentConstrainExtension:
 | 
			
		||||
		case agentConstrainExtension, agentConstrainExtensionV00:
 | 
			
		||||
			var msg constrainExtensionAgentMsg
 | 
			
		||||
			if err = ssh.Unmarshal(constraints, &msg); err != nil {
 | 
			
		||||
				return 0, false, nil, err
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -187,9 +187,11 @@ type channel struct {
 | 
			
		|||
	pending    *buffer
 | 
			
		||||
	extPending *buffer
 | 
			
		||||
 | 
			
		||||
	// windowMu protects myWindow, the flow-control window.
 | 
			
		||||
	windowMu sync.Mutex
 | 
			
		||||
	myWindow uint32
 | 
			
		||||
	// windowMu protects myWindow, the flow-control window, and myConsumed,
 | 
			
		||||
	// the number of bytes consumed since we last increased myWindow
 | 
			
		||||
	windowMu   sync.Mutex
 | 
			
		||||
	myWindow   uint32
 | 
			
		||||
	myConsumed uint32
 | 
			
		||||
 | 
			
		||||
	// writeMu serializes calls to mux.conn.writePacket() and
 | 
			
		||||
	// protects sentClose and packetPool. This mutex must be
 | 
			
		||||
| 
						 | 
				
			
			@ -332,14 +334,24 @@ func (ch *channel) handleData(packet []byte) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *channel) adjustWindow(n uint32) error {
 | 
			
		||||
func (c *channel) adjustWindow(adj uint32) error {
 | 
			
		||||
	c.windowMu.Lock()
 | 
			
		||||
	// Since myWindow is managed on our side, and can never exceed
 | 
			
		||||
	// the initial window setting, we don't worry about overflow.
 | 
			
		||||
	c.myWindow += uint32(n)
 | 
			
		||||
	// Since myConsumed and myWindow are managed on our side, and can never
 | 
			
		||||
	// exceed the initial window setting, we don't worry about overflow.
 | 
			
		||||
	c.myConsumed += adj
 | 
			
		||||
	var sendAdj uint32
 | 
			
		||||
	if (channelWindowSize-c.myWindow > 3*c.maxIncomingPayload) ||
 | 
			
		||||
		(c.myWindow < channelWindowSize/2) {
 | 
			
		||||
		sendAdj = c.myConsumed
 | 
			
		||||
		c.myConsumed = 0
 | 
			
		||||
		c.myWindow += sendAdj
 | 
			
		||||
	}
 | 
			
		||||
	c.windowMu.Unlock()
 | 
			
		||||
	if sendAdj == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return c.sendMessage(windowAdjustMsg{
 | 
			
		||||
		AdditionalBytes: uint32(n),
 | 
			
		||||
		AdditionalBytes: sendAdj,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan
 | 
			
		|||
 | 
			
		||||
	if err := conn.clientHandshake(addr, &fullConf); err != nil {
 | 
			
		||||
		c.Close()
 | 
			
		||||
		return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %v", err)
 | 
			
		||||
		return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	conn.mux = newMux(conn.transport)
 | 
			
		||||
	return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -307,7 +307,10 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
 | 
			
		|||
	}
 | 
			
		||||
	var methods []string
 | 
			
		||||
	var errSigAlgo error
 | 
			
		||||
	for _, signer := range signers {
 | 
			
		||||
 | 
			
		||||
	origSignersLen := len(signers)
 | 
			
		||||
	for idx := 0; idx < len(signers); idx++ {
 | 
			
		||||
		signer := signers[idx]
 | 
			
		||||
		pub := signer.PublicKey()
 | 
			
		||||
		as, algo, err := pickSignatureAlgorithm(signer, extensions)
 | 
			
		||||
		if err != nil && errSigAlgo == nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -321,6 +324,21 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
 | 
			
		|||
		if err != nil {
 | 
			
		||||
			return authFailure, nil, err
 | 
			
		||||
		}
 | 
			
		||||
		// OpenSSH 7.2-7.7 advertises support for rsa-sha2-256 and rsa-sha2-512
 | 
			
		||||
		// in the "server-sig-algs" extension but doesn't support these
 | 
			
		||||
		// algorithms for certificate authentication, so if the server rejects
 | 
			
		||||
		// the key try to use the obtained algorithm as if "server-sig-algs" had
 | 
			
		||||
		// not been implemented if supported from the algorithm signer.
 | 
			
		||||
		if !ok && idx < origSignersLen && isRSACert(algo) && algo != CertAlgoRSAv01 {
 | 
			
		||||
			if contains(as.Algorithms(), KeyAlgoRSA) {
 | 
			
		||||
				// We retry using the compat algorithm after all signers have
 | 
			
		||||
				// been tried normally.
 | 
			
		||||
				signers = append(signers, &multiAlgorithmSigner{
 | 
			
		||||
					AlgorithmSigner:     as,
 | 
			
		||||
					supportedAlgorithms: []string{KeyAlgoRSA},
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if !ok {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue