Merge pull request #2499 from thaJeztah/bump_buildkit

vendor: buildkit, docker/docker and docker/cli v27.0.1
This commit is contained in:
Tõnis Tiigi 2024-06-27 20:42:35 -07:00 committed by GitHub
commit 04000db8da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
226 changed files with 11962 additions and 5384 deletions

View File

@ -26,7 +26,7 @@ import (
"github.com/docker/buildx/util/resolver" "github.com/docker/buildx/util/resolver"
"github.com/docker/buildx/util/waitmap" "github.com/docker/buildx/util/waitmap"
"github.com/docker/cli/opts" "github.com/docker/cli/opts"
imagetypes "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/jsonmessage"
"github.com/moby/buildkit/client" "github.com/moby/buildkit/client"
"github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/client/llb"
@ -666,7 +666,7 @@ func pushWithMoby(ctx context.Context, d *driver.DriverHandle, name string, l pr
return err return err
} }
rc, err := api.ImagePush(ctx, name, imagetypes.PushOptions{ rc, err := api.ImagePush(ctx, name, image.PushOptions{
RegistryAuth: creds, RegistryAuth: creds,
}) })
if err != nil { if err != nil {
@ -745,11 +745,11 @@ func remoteDigestWithMoby(ctx context.Context, d *driver.DriverHandle, name stri
if err != nil { if err != nil {
return "", err return "", err
} }
image, _, err := api.ImageInspectWithRaw(ctx, name) img, _, err := api.ImageInspectWithRaw(ctx, name)
if err != nil { if err != nil {
return "", err return "", err
} }
if len(image.RepoDigests) == 0 { if len(img.RepoDigests) == 0 {
return "", nil return "", nil
} }
remoteImage, err := api.DistributionInspect(ctx, name, creds) remoteImage, err := api.DistributionInspect(ctx, name, creds)

View File

@ -21,7 +21,7 @@ import (
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config" "github.com/docker/cli/cli/config"
dockeropts "github.com/docker/cli/opts" dockeropts "github.com/docker/cli/opts"
"github.com/docker/go-units" "github.com/docker/docker/api/types/container"
"github.com/moby/buildkit/client" "github.com/moby/buildkit/client"
"github.com/moby/buildkit/session/auth/authprovider" "github.com/moby/buildkit/session/auth/authprovider"
"github.com/moby/buildkit/util/grpcerrors" "github.com/moby/buildkit/util/grpcerrors"
@ -270,9 +270,9 @@ func controllerUlimitOpt2DockerUlimit(u *controllerapi.UlimitOpt) *dockeropts.Ul
if u == nil { if u == nil {
return nil return nil
} }
values := make(map[string]*units.Ulimit) values := make(map[string]*container.Ulimit)
for k, v := range u.Values { for k, v := range u.Values {
values[k] = &units.Ulimit{ values[k] = &container.Ulimit{
Name: v.Name, Name: v.Name,
Hard: v.Hard, Hard: v.Hard,
Soft: v.Soft, Soft: v.Soft,

View File

@ -18,9 +18,8 @@ import (
"github.com/docker/buildx/util/imagetools" "github.com/docker/buildx/util/imagetools"
"github.com/docker/buildx/util/progress" "github.com/docker/buildx/util/progress"
"github.com/docker/cli/opts" "github.com/docker/cli/opts"
dockertypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
imagetypes "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/system" "github.com/docker/docker/api/types/system"
@ -96,7 +95,7 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error {
if err != nil { if err != nil {
return err return err
} }
rc, err := d.DockerAPI.ImageCreate(ctx, imageName, imagetypes.CreateOptions{ rc, err := d.DockerAPI.ImageCreate(ctx, imageName, image.CreateOptions{
RegistryAuth: ra, RegistryAuth: ra,
}) })
if err != nil { if err != nil {
@ -256,17 +255,16 @@ func (d *Driver) copyToContainer(ctx context.Context, files map[string][]byte) e
defer srcArchive.Close() defer srcArchive.Close()
baseDir := path.Dir(confutil.DefaultBuildKitConfigDir) baseDir := path.Dir(confutil.DefaultBuildKitConfigDir)
return d.DockerAPI.CopyToContainer(ctx, d.Name, baseDir, srcArchive, dockertypes.CopyToContainerOptions{}) return d.DockerAPI.CopyToContainer(ctx, d.Name, baseDir, srcArchive, container.CopyToContainerOptions{})
} }
func (d *Driver) exec(ctx context.Context, cmd []string) (string, net.Conn, error) { func (d *Driver) exec(ctx context.Context, cmd []string) (string, net.Conn, error) {
execConfig := dockertypes.ExecConfig{ response, err := d.DockerAPI.ContainerExecCreate(ctx, d.Name, container.ExecOptions{
Cmd: cmd, Cmd: cmd,
AttachStdin: true, AttachStdin: true,
AttachStdout: true, AttachStdout: true,
AttachStderr: true, AttachStderr: true,
} })
response, err := d.DockerAPI.ContainerExecCreate(ctx, d.Name, execConfig)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
@ -276,7 +274,7 @@ func (d *Driver) exec(ctx context.Context, cmd []string) (string, net.Conn, erro
return "", nil, errors.New("exec ID empty") return "", nil, errors.New("exec ID empty")
} }
resp, err := d.DockerAPI.ContainerExecAttach(ctx, execID, dockertypes.ExecStartCheck{}) resp, err := d.DockerAPI.ContainerExecAttach(ctx, execID, container.ExecStartOptions{})
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }

13
go.mod
View File

@ -15,9 +15,9 @@ require (
github.com/containerd/typeurl/v2 v2.1.1 github.com/containerd/typeurl/v2 v2.1.1
github.com/creack/pty v1.1.21 github.com/creack/pty v1.1.21
github.com/distribution/reference v0.6.0 github.com/distribution/reference v0.6.0
github.com/docker/cli v26.1.4+incompatible github.com/docker/cli v27.0.1+incompatible
github.com/docker/cli-docs-tool v0.7.0 github.com/docker/cli-docs-tool v0.7.0
github.com/docker/docker v26.1.4+incompatible github.com/docker/docker v27.0.1+incompatible
github.com/docker/go-units v0.5.0 github.com/docker/go-units v0.5.0
github.com/gofrs/flock v0.8.1 github.com/gofrs/flock v0.8.1
github.com/gogo/protobuf v1.3.2 github.com/gogo/protobuf v1.3.2
@ -28,7 +28,7 @@ require (
github.com/hashicorp/hcl/v2 v2.20.1 github.com/hashicorp/hcl/v2 v2.20.1
github.com/in-toto/in-toto-golang v0.5.0 github.com/in-toto/in-toto-golang v0.5.0
github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/mitchellh/hashstructure/v2 v2.0.2
github.com/moby/buildkit v0.14.1 github.com/moby/buildkit v0.14.1-0.20240625190127-aaaf86e5470b // master (v0.15-dev)
github.com/moby/sys/mountinfo v0.7.1 github.com/moby/sys/mountinfo v0.7.1
github.com/moby/sys/signal v0.7.0 github.com/moby/sys/signal v0.7.0
github.com/morikuni/aec v1.0.0 github.com/morikuni/aec v1.0.0
@ -49,7 +49,7 @@ require (
go.opentelemetry.io/otel/trace v1.21.0 go.opentelemetry.io/otel/trace v1.21.0
golang.org/x/mod v0.17.0 golang.org/x/mod v0.17.0
golang.org/x/sync v0.6.0 golang.org/x/sync v0.6.0
golang.org/x/sys v0.18.0 golang.org/x/sys v0.20.0
golang.org/x/term v0.18.0 golang.org/x/term v0.18.0
golang.org/x/text v0.14.0 golang.org/x/text v0.14.0
google.golang.org/grpc v1.59.0 google.golang.org/grpc v1.59.0
@ -82,7 +82,7 @@ require (
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/containerd/ttrpc v1.2.4 // indirect github.com/containerd/ttrpc v1.2.5 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/docker/docker-credential-helpers v0.8.2 // indirect
@ -112,7 +112,7 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.4 // indirect github.com/klauspost/compress v1.17.9 // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect
@ -140,6 +140,7 @@ require (
github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect
github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect
github.com/theupdateframework/notary v0.7.0 // indirect github.com/theupdateframework/notary v0.7.0 // indirect
github.com/tonistiigi/go-csvvalue v0.0.0-20240619222358-bb8dd5cba3c2 // indirect
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab // indirect github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect

30
go.sum
View File

@ -105,8 +105,8 @@ github.com/containerd/nydus-snapshotter v0.13.7/go.mod h1:VPVKQ3jmHFIcUIV2yiQ1kI
github.com/containerd/stargz-snapshotter v0.15.1 h1:fpsP4kf/Z4n2EYnU0WT8ZCE3eiKDwikDhL6VwxIlgeA= github.com/containerd/stargz-snapshotter v0.15.1 h1:fpsP4kf/Z4n2EYnU0WT8ZCE3eiKDwikDhL6VwxIlgeA=
github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU=
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
github.com/containerd/ttrpc v1.2.4 h1:eQCQK4h9dxDmpOb9QOOMh2NHTfzroH1IkmHiKZi05Oo= github.com/containerd/ttrpc v1.2.5 h1:IFckT1EFQoFBMG4c3sMdT8EP3/aKfumK1msY+Ze4oLU=
github.com/containerd/ttrpc v1.2.4/go.mod h1:ojvb8SJBSch0XkqNO0L0YX/5NxR3UnVk2LzFKBK0upc= github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4= github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4=
github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0= github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@ -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/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v26.1.4+incompatible h1:I8PHdc0MtxEADqYJZvhBrW9bo8gawKwwenxRM7/rLu8= github.com/docker/cli v27.0.1+incompatible h1:d/OrlblkOTkhJ1IaAGD1bLgUBtFQC/oP0VjkFMIN+B0=
github.com/docker/cli v26.1.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v27.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli-docs-tool v0.7.0 h1:M2Da98Unz2kz3A5d4yeSGbhyOge2mfYSNjAFt01Rw0M= github.com/docker/cli-docs-tool v0.7.0 h1:M2Da98Unz2kz3A5d4yeSGbhyOge2mfYSNjAFt01Rw0M=
github.com/docker/cli-docs-tool v0.7.0/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o= github.com/docker/cli-docs-tool v0.7.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.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 h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v26.1.4+incompatible h1:vuTpXDuoga+Z38m1OZHzl7NKisKWaWlhjQk7IDPSLsU= github.com/docker/docker v27.0.1+incompatible h1:AbszR+lCnR3f297p/g0arbQoyhAkImxQOR/XO9YZeIg=
github.com/docker/docker v26.1.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v27.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
@ -263,8 +263,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/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 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/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
@ -300,8 +300,8 @@ github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/z
github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/buildkit v0.14.1 h1:2epLCZTkn4CikdImtsLtIa++7DzCimrrZCT1sway+oI= github.com/moby/buildkit v0.14.1-0.20240625190127-aaaf86e5470b h1:x1TdL3kMOFi3qdlAYBPVf4YzPD8fIZAjIjGfRycru8Q=
github.com/moby/buildkit v0.14.1/go.mod h1:1XssG7cAqv5Bz1xcGMxJL123iCv5TYN4Z/qf647gfuk= github.com/moby/buildkit v0.14.1-0.20240625190127-aaaf86e5470b/go.mod h1:ui4ZkNR6Z3kVMVqLY5JcoWcmlibi7TJL3bdzikvs5Yw=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
@ -350,8 +350,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.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
@ -435,6 +435,8 @@ github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4D
github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c h1:+6wg/4ORAbnSoGDzg2Q1i3CeMcT/jjhye/ZfnBHy7/M= github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c h1:+6wg/4ORAbnSoGDzg2Q1i3CeMcT/jjhye/ZfnBHy7/M=
github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c/go.mod h1:vbbYqJlnswsbJqWUcJN8fKtBhnEgldDrcagTgnBVKKM= github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c/go.mod h1:vbbYqJlnswsbJqWUcJN8fKtBhnEgldDrcagTgnBVKKM=
github.com/tonistiigi/go-csvvalue v0.0.0-20240619222358-bb8dd5cba3c2 h1:4dXTcm/McJMoXXFhqr+4rNL4WkLqMoHkdMhT4nU0Z28=
github.com/tonistiigi/go-csvvalue v0.0.0-20240619222358-bb8dd5cba3c2/go.mod h1:278M4p8WsNh3n4a1eqiFcV2FGk7wE5fwUpUom9mK9lE=
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0= github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0=
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk= github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk=
github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab h1:H6aJ0yKQ0gF49Qb2z5hI1UHxSQt4JMyxebFR15KnApw= github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab h1:H6aJ0yKQ0gF49Qb2z5hI1UHxSQt4JMyxebFR15KnApw=
@ -540,8 +542,8 @@ 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-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.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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.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.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=

View File

@ -1,6 +1,6 @@
# ttrpc # ttrpc
[![Build Status](https://github.com/containerd/ttrpc/workflows/CI/badge.svg)](https://github.com/containerd/ttrpc/actions?query=workflow%3ACI) [![Build Status](https://github.com/containerd/ttrpc/actions/workflows/ci.yml/badge.svg)](https://github.com/containerd/ttrpc/actions/workflows/ci.yml)
GRPC for low-memory environments. GRPC for low-memory environments.

View File

@ -27,7 +27,7 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/sirupsen/logrus" "github.com/containerd/log"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
@ -368,7 +368,7 @@ func (c *Client) receiveLoop() error {
sid := streamID(msg.header.StreamID) sid := streamID(msg.header.StreamID)
s := c.getStream(sid) s := c.getStream(sid)
if s == nil { if s == nil {
logrus.WithField("stream", sid).Errorf("ttrpc: received message on inactive stream") log.G(c.ctx).WithField("stream", sid).Error("ttrpc: received message on inactive stream")
continue continue
} }
@ -376,7 +376,7 @@ func (c *Client) receiveLoop() error {
s.closeWithError(err) s.closeWithError(err)
} else { } else {
if err := s.receive(c.ctx, msg); err != nil { if err := s.receive(c.ctx, msg); err != nil {
logrus.WithError(err).WithField("stream", sid).Errorf("ttrpc: failed to handle message") log.G(c.ctx).WithFields(log.Fields{"error": err, "stream": sid}).Error("ttrpc: failed to handle message")
} }
} }
} }

View File

@ -27,7 +27,7 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/sirupsen/logrus" "github.com/containerd/log"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
) )
@ -109,7 +109,7 @@ func (s *Server) Serve(ctx context.Context, l net.Listener) error {
} }
sleep := time.Duration(rand.Int63n(int64(backoff))) sleep := time.Duration(rand.Int63n(int64(backoff)))
logrus.WithError(err).Errorf("ttrpc: failed accept; backoff %v", sleep) log.G(ctx).WithError(err).Errorf("ttrpc: failed accept; backoff %v", sleep)
time.Sleep(sleep) time.Sleep(sleep)
continue continue
} }
@ -121,14 +121,14 @@ func (s *Server) Serve(ctx context.Context, l net.Listener) error {
approved, handshake, err := handshaker.Handshake(ctx, conn) approved, handshake, err := handshaker.Handshake(ctx, conn)
if err != nil { if err != nil {
logrus.WithError(err).Error("ttrpc: refusing connection after handshake") log.G(ctx).WithError(err).Error("ttrpc: refusing connection after handshake")
conn.Close() conn.Close()
continue continue
} }
sc, err := s.newConn(approved, handshake) sc, err := s.newConn(approved, handshake)
if err != nil { if err != nil {
logrus.WithError(err).Error("ttrpc: create connection failed") log.G(ctx).WithError(err).Error("ttrpc: create connection failed")
conn.Close() conn.Close()
continue continue
} }
@ -513,12 +513,12 @@ func (c *serverConn) run(sctx context.Context) {
Payload: response.data, Payload: response.data,
}) })
if err != nil { if err != nil {
logrus.WithError(err).Error("failed marshaling response") log.G(ctx).WithError(err).Error("failed marshaling response")
return return
} }
if err := ch.send(response.id, messageTypeResponse, 0, p); err != nil { if err := ch.send(response.id, messageTypeResponse, 0, p); err != nil {
logrus.WithError(err).Error("failed sending message on channel") log.G(ctx).WithError(err).Error("failed sending message on channel")
return return
} }
} else { } else {
@ -530,7 +530,7 @@ func (c *serverConn) run(sctx context.Context) {
flags = flags | flagNoData flags = flags | flagNoData
} }
if err := ch.send(response.id, messageTypeData, flags, response.data); err != nil { if err := ch.send(response.id, messageTypeData, flags, response.data); err != nil {
logrus.WithError(err).Error("failed sending message on channel") log.G(ctx).WithError(err).Error("failed sending message on channel")
return return
} }
} }
@ -552,7 +552,7 @@ func (c *serverConn) run(sctx context.Context) {
// requests, so that the client connection is closed // requests, so that the client connection is closed
return return
} }
logrus.WithError(err).Error("error receiving message") log.G(ctx).WithError(err).Error("error receiving message")
// else, initiate shutdown // else, initiate shutdown
case <-shutdown: case <-shutdown:
return return

20
vendor/github.com/docker/cli/AUTHORS generated vendored
View File

@ -26,6 +26,7 @@ Akhil Mohan <akhil.mohan@mayadata.io>
Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp> Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
Akim Demaille <akim.demaille@docker.com> Akim Demaille <akim.demaille@docker.com>
Alan Thompson <cloojure@gmail.com> Alan Thompson <cloojure@gmail.com>
Alano Terblanche <alano.terblanche@docker.com>
Albert Callarisa <shark234@gmail.com> Albert Callarisa <shark234@gmail.com>
Alberto Roura <mail@albertoroura.com> Alberto Roura <mail@albertoroura.com>
Albin Kerouanton <albinker@gmail.com> Albin Kerouanton <albinker@gmail.com>
@ -65,6 +66,7 @@ Andrew Hsu <andrewhsu@docker.com>
Andrew Macpherson <hopscotch23@gmail.com> Andrew Macpherson <hopscotch23@gmail.com>
Andrew McDonnell <bugs@andrewmcdonnell.net> Andrew McDonnell <bugs@andrewmcdonnell.net>
Andrew Po <absourd.noise@gmail.com> Andrew Po <absourd.noise@gmail.com>
Andrew-Zipperer <atzipperer@gmail.com>
Andrey Petrov <andrey.petrov@shazow.net> Andrey Petrov <andrey.petrov@shazow.net>
Andrii Berehuliak <berkusandrew@gmail.com> Andrii Berehuliak <berkusandrew@gmail.com>
André Martins <aanm90@gmail.com> André Martins <aanm90@gmail.com>
@ -124,11 +126,13 @@ Bryan Bess <squarejaw@bsbess.com>
Bryan Boreham <bjboreham@gmail.com> Bryan Boreham <bjboreham@gmail.com>
Bryan Murphy <bmurphy1976@gmail.com> Bryan Murphy <bmurphy1976@gmail.com>
bryfry <bryon.fryer@gmail.com> bryfry <bryon.fryer@gmail.com>
Calvin Liu <flycalvin@qq.com>
Cameron Spear <cameronspear@gmail.com> Cameron Spear <cameronspear@gmail.com>
Cao Weiwei <cao.weiwei30@zte.com.cn> Cao Weiwei <cao.weiwei30@zte.com.cn>
Carlo Mion <mion00@gmail.com> Carlo Mion <mion00@gmail.com>
Carlos Alexandro Becker <caarlos0@gmail.com> Carlos Alexandro Becker <caarlos0@gmail.com>
Carlos de Paula <me@carlosedp.com> Carlos de Paula <me@carlosedp.com>
Casey Korver <casey@korver.dev>
Ce Gao <ce.gao@outlook.com> Ce Gao <ce.gao@outlook.com>
Cedric Davies <cedricda@microsoft.com> Cedric Davies <cedricda@microsoft.com>
Cezar Sa Espinola <cezarsa@gmail.com> Cezar Sa Espinola <cezarsa@gmail.com>
@ -160,6 +164,8 @@ Christophe Vidal <kriss@krizalys.com>
Christopher Biscardi <biscarch@sketcht.com> Christopher Biscardi <biscarch@sketcht.com>
Christopher Crone <christopher.crone@docker.com> Christopher Crone <christopher.crone@docker.com>
Christopher Jones <tophj@linux.vnet.ibm.com> Christopher Jones <tophj@linux.vnet.ibm.com>
Christopher Petito <47751006+krissetto@users.noreply.github.com>
Christopher Petito <chrisjpetito@gmail.com>
Christopher Svensson <stoffus@stoffus.com> Christopher Svensson <stoffus@stoffus.com>
Christy Norman <christy@linux.vnet.ibm.com> Christy Norman <christy@linux.vnet.ibm.com>
Chun Chen <ramichen@tencent.com> Chun Chen <ramichen@tencent.com>
@ -212,6 +218,7 @@ David Cramer <davcrame@cisco.com>
David Dooling <dooling@gmail.com> David Dooling <dooling@gmail.com>
David Gageot <david@gageot.net> David Gageot <david@gageot.net>
David Karlsson <david.karlsson@docker.com> David Karlsson <david.karlsson@docker.com>
David le Blanc <systemmonkey42@users.noreply.github.com>
David Lechner <david@lechnology.com> David Lechner <david@lechnology.com>
David Scott <dave@recoil.org> David Scott <dave@recoil.org>
David Sheets <dsheets@docker.com> David Sheets <dsheets@docker.com>
@ -298,6 +305,7 @@ Gang Qiao <qiaohai8866@gmail.com>
Gary Schaetz <gary@schaetzkc.com> Gary Schaetz <gary@schaetzkc.com>
Genki Takiuchi <genki@s21g.com> Genki Takiuchi <genki@s21g.com>
George MacRorie <gmacr31@gmail.com> George MacRorie <gmacr31@gmail.com>
George Margaritis <gmargaritis@protonmail.com>
George Xie <georgexsh@gmail.com> George Xie <georgexsh@gmail.com>
Gianluca Borello <g.borello@gmail.com> Gianluca Borello <g.borello@gmail.com>
Gildas Cuisinier <gildas.cuisinier@gcuisinier.net> Gildas Cuisinier <gildas.cuisinier@gcuisinier.net>
@ -306,6 +314,7 @@ Gleb Stsenov <gleb.stsenov@gmail.com>
Goksu Toprak <goksu.toprak@docker.com> Goksu Toprak <goksu.toprak@docker.com>
Gou Rao <gou@portworx.com> Gou Rao <gou@portworx.com>
Govind Rai <raigovind93@gmail.com> Govind Rai <raigovind93@gmail.com>
Grace Choi <grace.54109@gmail.com>
Graeme Wiebe <graeme.wiebe@gmail.com> Graeme Wiebe <graeme.wiebe@gmail.com>
Grant Reaber <grant.reaber@gmail.com> Grant Reaber <grant.reaber@gmail.com>
Greg Pflaum <gpflaum@users.noreply.github.com> Greg Pflaum <gpflaum@users.noreply.github.com>
@ -386,6 +395,7 @@ Jezeniel Zapanta <jpzapanta22@gmail.com>
Jian Zhang <zhangjian.fnst@cn.fujitsu.com> Jian Zhang <zhangjian.fnst@cn.fujitsu.com>
Jie Luo <luo612@zju.edu.cn> Jie Luo <luo612@zju.edu.cn>
Jilles Oldenbeuving <ojilles@gmail.com> Jilles Oldenbeuving <ojilles@gmail.com>
Jim Chen <njucjc@gmail.com>
Jim Galasyn <jim.galasyn@docker.com> Jim Galasyn <jim.galasyn@docker.com>
Jim Lin <b04705003@ntu.edu.tw> Jim Lin <b04705003@ntu.edu.tw>
Jimmy Leger <jimmy.leger@gmail.com> Jimmy Leger <jimmy.leger@gmail.com>
@ -416,6 +426,7 @@ John Willis <john.willis@docker.com>
Jon Johnson <jonjohnson@google.com> Jon Johnson <jonjohnson@google.com>
Jon Zeolla <zeolla@gmail.com> Jon Zeolla <zeolla@gmail.com>
Jonatas Baldin <jonatas.baldin@gmail.com> Jonatas Baldin <jonatas.baldin@gmail.com>
Jonathan A. Sternberg <jonathansternberg@gmail.com>
Jonathan Boulle <jonathanboulle@gmail.com> Jonathan Boulle <jonathanboulle@gmail.com>
Jonathan Lee <jonjohn1232009@gmail.com> Jonathan Lee <jonjohn1232009@gmail.com>
Jonathan Lomas <jonathan@floatinglomas.ca> Jonathan Lomas <jonathan@floatinglomas.ca>
@ -470,6 +481,7 @@ Kevin Woblick <mail@kovah.de>
khaled souf <khaled.souf@gmail.com> khaled souf <khaled.souf@gmail.com>
Kim Eik <kim@heldig.org> Kim Eik <kim@heldig.org>
Kir Kolyshkin <kolyshkin@gmail.com> Kir Kolyshkin <kolyshkin@gmail.com>
Kirill A. Korinsky <kirill@korins.ky>
Kotaro Yoshimatsu <kotaro.yoshimatsu@gmail.com> Kotaro Yoshimatsu <kotaro.yoshimatsu@gmail.com>
Krasi Georgiev <krasi@vip-consult.solutions> Krasi Georgiev <krasi@vip-consult.solutions>
Kris-Mikael Krister <krismikael@protonmail.com> Kris-Mikael Krister <krismikael@protonmail.com>
@ -530,6 +542,7 @@ Marco Vedovati <mvedovati@suse.com>
Marcus Martins <marcus@docker.com> Marcus Martins <marcus@docker.com>
Marianna Tessel <mtesselh@gmail.com> Marianna Tessel <mtesselh@gmail.com>
Marius Ileana <marius.ileana@gmail.com> Marius Ileana <marius.ileana@gmail.com>
Marius Meschter <marius@meschter.me>
Marius Sturm <marius@graylog.com> Marius Sturm <marius@graylog.com>
Mark Oates <fl0yd@me.com> Mark Oates <fl0yd@me.com>
Marsh Macy <marsma@microsoft.com> Marsh Macy <marsma@microsoft.com>
@ -538,6 +551,7 @@ Mary Anthony <mary.anthony@docker.com>
Mason Fish <mason.fish@docker.com> Mason Fish <mason.fish@docker.com>
Mason Malone <mason.malone@gmail.com> Mason Malone <mason.malone@gmail.com>
Mateusz Major <apkd@users.noreply.github.com> Mateusz Major <apkd@users.noreply.github.com>
Mathias Duedahl <64321057+Lussebullen@users.noreply.github.com>
Mathieu Champlon <mathieu.champlon@docker.com> Mathieu Champlon <mathieu.champlon@docker.com>
Mathieu Rollet <matletix@gmail.com> Mathieu Rollet <matletix@gmail.com>
Matt Gucci <matt9ucci@gmail.com> Matt Gucci <matt9ucci@gmail.com>
@ -547,6 +561,7 @@ Matthew Heon <mheon@redhat.com>
Matthieu Hauglustaine <matt.hauglustaine@gmail.com> Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
Mauro Porras P <mauroporrasp@gmail.com> Mauro Porras P <mauroporrasp@gmail.com>
Max Shytikov <mshytikov@gmail.com> Max Shytikov <mshytikov@gmail.com>
Max-Julian Pogner <max-julian@pogner.at>
Maxime Petazzoni <max@signalfuse.com> Maxime Petazzoni <max@signalfuse.com>
Maximillian Fan Xavier <maximillianfx@gmail.com> Maximillian Fan Xavier <maximillianfx@gmail.com>
Mei ChunTao <mei.chuntao@zte.com.cn> Mei ChunTao <mei.chuntao@zte.com.cn>
@ -610,6 +625,7 @@ Nathan McCauley <nathan.mccauley@docker.com>
Neil Peterson <neilpeterson@outlook.com> Neil Peterson <neilpeterson@outlook.com>
Nick Adcock <nick.adcock@docker.com> Nick Adcock <nick.adcock@docker.com>
Nick Santos <nick.santos@docker.com> Nick Santos <nick.santos@docker.com>
Nick Sieger <nick@nicksieger.com>
Nico Stapelbroek <nstapelbroek@gmail.com> Nico Stapelbroek <nstapelbroek@gmail.com>
Nicola Kabar <nicolaka@gmail.com> Nicola Kabar <nicolaka@gmail.com>
Nicolas Borboën <ponsfrilus@gmail.com> Nicolas Borboën <ponsfrilus@gmail.com>
@ -704,6 +720,7 @@ Rory Hunter <roryhunter2@gmail.com>
Ross Boucher <rboucher@gmail.com> Ross Boucher <rboucher@gmail.com>
Rubens Figueiredo <r.figueiredo.52@gmail.com> Rubens Figueiredo <r.figueiredo.52@gmail.com>
Rui Cao <ruicao@alauda.io> Rui Cao <ruicao@alauda.io>
Rui JingAn <quiterace@gmail.com>
Ryan Belgrave <rmb1993@gmail.com> Ryan Belgrave <rmb1993@gmail.com>
Ryan Detzel <ryan.detzel@gmail.com> Ryan Detzel <ryan.detzel@gmail.com>
Ryan Stelly <ryan.stelly@live.com> Ryan Stelly <ryan.stelly@live.com>
@ -797,6 +814,7 @@ Tim Hockin <thockin@google.com>
Tim Sampson <tim@sampson.fi> Tim Sampson <tim@sampson.fi>
Tim Smith <timbot@google.com> Tim Smith <timbot@google.com>
Tim Waugh <twaugh@redhat.com> Tim Waugh <twaugh@redhat.com>
Tim Welsh <timothy.welsh@docker.com>
Tim Wraight <tim.wraight@tangentlabs.co.uk> Tim Wraight <tim.wraight@tangentlabs.co.uk>
timfeirg <kkcocogogo@gmail.com> timfeirg <kkcocogogo@gmail.com>
Timothy Hobbs <timothyhobbs@seznam.cz> Timothy Hobbs <timothyhobbs@seznam.cz>
@ -880,9 +898,11 @@ Zhang Wei <zhangwei555@huawei.com>
Zhang Wentao <zhangwentao234@huawei.com> Zhang Wentao <zhangwentao234@huawei.com>
ZhangHang <stevezhang2014@gmail.com> ZhangHang <stevezhang2014@gmail.com>
zhenghenghuo <zhenghenghuo@zju.edu.cn> zhenghenghuo <zhenghenghuo@zju.edu.cn>
Zhiwei Liang <zliang@akamai.com>
Zhou Hao <zhouhao@cn.fujitsu.com> Zhou Hao <zhouhao@cn.fujitsu.com>
Zhoulin Xie <zhoulin.xie@daocloud.io> Zhoulin Xie <zhoulin.xie@daocloud.io>
Zhu Guihua <zhugh.fnst@cn.fujitsu.com> Zhu Guihua <zhugh.fnst@cn.fujitsu.com>
Zhuo Zhi <h.dwwwwww@gmail.com>
Álex González <agonzalezro@gmail.com> Álex González <agonzalezro@gmail.com>
Álvaro Lázaro <alvaro.lazaro.g@gmail.com> Álvaro Lázaro <alvaro.lazaro.g@gmail.com>
Átila Camurça Alves <camurca.home@gmail.com> Átila Camurça Alves <camurca.home@gmail.com>

View File

@ -14,6 +14,6 @@ United States and other governments.
It is your responsibility to ensure that your use and/or transfer does not It is your responsibility to ensure that your use and/or transfer does not
violate applicable laws. violate applicable laws.
For more information, please see https://www.bis.doc.gov For more information, see https://www.bis.doc.gov
See also https://www.apache.org/dev/crypto.html and/or seek legal counsel. See also https://www.apache.org/dev/crypto.html and/or seek legal counsel.

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package manager package manager

View File

@ -1,6 +1,7 @@
package manager package manager
import ( import (
"context"
"encoding/json" "encoding/json"
"strings" "strings"
@ -28,29 +29,36 @@ type HookPluginData struct {
// a main CLI command was executed. It calls the hook subcommand for all // a main CLI command was executed. It calls the hook subcommand for all
// present CLI plugins that declare support for hooks in their metadata and // present CLI plugins that declare support for hooks in their metadata and
// parses/prints their responses. // parses/prints their responses.
func RunCLICommandHooks(dockerCli command.Cli, rootCmd, subCommand *cobra.Command, cmdErrorMessage string) { func RunCLICommandHooks(ctx context.Context, dockerCli command.Cli, rootCmd, subCommand *cobra.Command, cmdErrorMessage string) {
commandName := strings.TrimPrefix(subCommand.CommandPath(), rootCmd.Name()+" ") commandName := strings.TrimPrefix(subCommand.CommandPath(), rootCmd.Name()+" ")
flags := getCommandFlags(subCommand) flags := getCommandFlags(subCommand)
runHooks(dockerCli, rootCmd, subCommand, commandName, flags, cmdErrorMessage) runHooks(ctx, dockerCli, rootCmd, subCommand, commandName, flags, cmdErrorMessage)
} }
// RunPluginHooks is the entrypoint for the hooks execution flow // RunPluginHooks is the entrypoint for the hooks execution flow
// after a plugin command was just executed by the CLI. // after a plugin command was just executed by the CLI.
func RunPluginHooks(dockerCli command.Cli, rootCmd, subCommand *cobra.Command, args []string) { func RunPluginHooks(ctx context.Context, dockerCli command.Cli, rootCmd, subCommand *cobra.Command, args []string) {
commandName := strings.Join(args, " ") commandName := strings.Join(args, " ")
flags := getNaiveFlags(args) flags := getNaiveFlags(args)
runHooks(dockerCli, rootCmd, subCommand, commandName, flags, "") runHooks(ctx, dockerCli, rootCmd, subCommand, commandName, flags, "")
} }
func runHooks(dockerCli command.Cli, rootCmd, subCommand *cobra.Command, invokedCommand string, flags map[string]string, cmdErrorMessage string) { func runHooks(ctx context.Context, dockerCli command.Cli, rootCmd, subCommand *cobra.Command, invokedCommand string, flags map[string]string, cmdErrorMessage string) {
nextSteps := invokeAndCollectHooks(dockerCli, rootCmd, subCommand, invokedCommand, flags, cmdErrorMessage) nextSteps := invokeAndCollectHooks(ctx, dockerCli, rootCmd, subCommand, invokedCommand, flags, cmdErrorMessage)
hooks.PrintNextSteps(dockerCli.Err(), nextSteps) hooks.PrintNextSteps(dockerCli.Err(), nextSteps)
} }
func invokeAndCollectHooks(dockerCli command.Cli, rootCmd, subCmd *cobra.Command, subCmdStr string, flags map[string]string, cmdErrorMessage string) []string { func invokeAndCollectHooks(ctx context.Context, dockerCli command.Cli, rootCmd, subCmd *cobra.Command, subCmdStr string, flags map[string]string, cmdErrorMessage string) []string {
// check if the context was cancelled before invoking hooks
select {
case <-ctx.Done():
return nil
default:
}
pluginsCfg := dockerCli.ConfigFile().Plugins pluginsCfg := dockerCli.ConfigFile().Plugins
if pluginsCfg == nil { if pluginsCfg == nil {
return nil return nil
@ -68,7 +76,7 @@ func invokeAndCollectHooks(dockerCli command.Cli, rootCmd, subCmd *cobra.Command
continue continue
} }
hookReturn, err := p.RunHook(HookPluginData{ hookReturn, err := p.RunHook(ctx, HookPluginData{
RootCmd: match, RootCmd: match,
Flags: flags, Flags: flags,
CommandError: cmdErrorMessage, CommandError: cmdErrorMessage,

View File

@ -49,6 +49,16 @@ func IsNotFound(err error) bool {
return ok return ok
} }
// getPluginDirs returns the platform-specific locations to search for plugins
// in order of preference.
//
// Plugin-discovery is performed in the following order of preference:
//
// 1. The "cli-plugins" directory inside the CLIs [config.Path] (usually "~/.docker/cli-plugins").
// 2. Additional plugin directories as configured through [ConfigFile.CLIPluginsExtraDirs].
// 3. Platform-specific defaultSystemPluginDirs.
//
// [ConfigFile.CLIPluginsExtraDirs]: https://pkg.go.dev/github.com/docker/cli@v26.1.4+incompatible/cli/config/configfile#ConfigFile.CLIPluginsExtraDirs
func getPluginDirs(cfg *configfile.ConfigFile) ([]string, error) { func getPluginDirs(cfg *configfile.ConfigFile) ([]string, error) {
var pluginDirs []string var pluginDirs []string

View File

@ -2,7 +2,19 @@
package manager package manager
// defaultSystemPluginDirs are the platform-specific locations to search
// for plugins in order of preference.
//
// Plugin-discovery is performed in the following order of preference:
//
// 1. The "cli-plugins" directory inside the CLIs config-directory (usually "~/.docker/cli-plugins").
// 2. Additional plugin directories as configured through [ConfigFile.CLIPluginsExtraDirs].
// 3. Platform-specific defaultSystemPluginDirs (as defined below).
//
// [ConfigFile.CLIPluginsExtraDirs]: https://pkg.go.dev/github.com/docker/cli@v26.1.4+incompatible/cli/config/configfile#ConfigFile.CLIPluginsExtraDirs
var defaultSystemPluginDirs = []string{ var defaultSystemPluginDirs = []string{
"/usr/local/lib/docker/cli-plugins", "/usr/local/libexec/docker/cli-plugins", "/usr/local/lib/docker/cli-plugins",
"/usr/lib/docker/cli-plugins", "/usr/libexec/docker/cli-plugins", "/usr/local/libexec/docker/cli-plugins",
"/usr/lib/docker/cli-plugins",
"/usr/libexec/docker/cli-plugins",
} }

View File

@ -5,6 +5,16 @@ import (
"path/filepath" "path/filepath"
) )
// defaultSystemPluginDirs are the platform-specific locations to search
// for plugins in order of preference.
//
// Plugin-discovery is performed in the following order of preference:
//
// 1. The "cli-plugins" directory inside the CLIs config-directory (usually "~/.docker/cli-plugins").
// 2. Additional plugin directories as configured through [ConfigFile.CLIPluginsExtraDirs].
// 3. Platform-specific defaultSystemPluginDirs (as defined below).
//
// [ConfigFile.CLIPluginsExtraDirs]: https://pkg.go.dev/github.com/docker/cli@v26.1.4+incompatible/cli/config/configfile#ConfigFile.CLIPluginsExtraDirs
var defaultSystemPluginDirs = []string{ var defaultSystemPluginDirs = []string{
filepath.Join(os.Getenv("ProgramData"), "Docker", "cli-plugins"), filepath.Join(os.Getenv("ProgramData"), "Docker", "cli-plugins"),
filepath.Join(os.Getenv("ProgramFiles"), "Docker", "cli-plugins"), filepath.Join(os.Getenv("ProgramFiles"), "Docker", "cli-plugins"),

View File

@ -1,6 +1,7 @@
package manager package manager
import ( import (
"context"
"encoding/json" "encoding/json"
"os" "os"
"os/exec" "os/exec"
@ -105,13 +106,13 @@ func newPlugin(c Candidate, cmds []*cobra.Command) (Plugin, error) {
// RunHook executes the plugin's hooks command // RunHook executes the plugin's hooks command
// and returns its unprocessed output. // and returns its unprocessed output.
func (p *Plugin) RunHook(hookData HookPluginData) ([]byte, error) { func (p *Plugin) RunHook(ctx context.Context, hookData HookPluginData) ([]byte, error) {
hDataBytes, err := json.Marshal(hookData) hDataBytes, err := json.Marshal(hookData)
if err != nil { if err != nil {
return nil, wrapAsPluginError(err, "failed to marshall hook data") return nil, wrapAsPluginError(err, "failed to marshall hook data")
} }
pCmd := exec.Command(p.Path, p.Name, HookSubcommandName, string(hDataBytes)) pCmd := exec.CommandContext(ctx, p.Path, p.Name, HookSubcommandName, string(hDataBytes))
pCmd.Env = os.Environ() pCmd.Env = os.Environ()
pCmd.Env = append(pCmd.Env, ReexecEnvvar+"="+os.Args[0]) pCmd.Env = append(pCmd.Env, ReexecEnvvar+"="+os.Args[0])
hookCmdOutput, err := pCmd.Output() hookCmdOutput, err := pCmd.Output()

View File

@ -36,13 +36,7 @@ func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager
PersistentPreRunE = func(cmd *cobra.Command, _ []string) error { PersistentPreRunE = func(cmd *cobra.Command, _ []string) error {
var err error var err error
persistentPreRunOnce.Do(func() { persistentPreRunOnce.Do(func() {
cmdContext := cmd.Context() ctx, cancel := context.WithCancel(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) cmd.SetContext(ctx)
// Set up the context to cancel based on signalling via CLI socket. // Set up the context to cancel based on signalling via CLI socket.
socket.ConnectAndWait(cancel) socket.ConnectAndWait(cancel)
@ -51,6 +45,7 @@ func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager
if os.Getenv("DOCKER_CLI_PLUGIN_USE_DIAL_STDIO") != "" { if os.Getenv("DOCKER_CLI_PLUGIN_USE_DIAL_STDIO") != "" {
opts = append(opts, withPluginClientConn(plugin.Name())) opts = append(opts, withPluginClientConn(plugin.Name()))
} }
opts = append(opts, command.WithEnableGlobalMeterProvider(), command.WithEnableGlobalTracerProvider())
err = tcmd.Initialize(opts...) err = tcmd.Initialize(opts...)
ogRunE := cmd.RunE ogRunE := cmd.RunE
if ogRunE == nil { if ogRunE == nil {

View File

@ -9,6 +9,8 @@ import (
"os" "os"
"runtime" "runtime"
"sync" "sync"
"github.com/sirupsen/logrus"
) )
// EnvKey represents the well-known environment variable used to pass the // EnvKey represents the well-known environment variable used to pass the
@ -30,6 +32,7 @@ func NewPluginServer(h func(net.Conn)) (*PluginServer, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
logrus.Trace("Plugin server listening on ", l.Addr())
if h == nil { if h == nil {
h = func(net.Conn) {} h = func(net.Conn) {}
@ -92,6 +95,7 @@ func (pl *PluginServer) Addr() net.Addr {
// //
// The error value is that of the underlying [net.Listner.Close] call. // The error value is that of the underlying [net.Listner.Close] call.
func (pl *PluginServer) Close() error { func (pl *PluginServer) Close() error {
logrus.Trace("Closing plugin server")
// Close connections first to ensure the connections get io.EOF instead // Close connections first to ensure the connections get io.EOF instead
// of a connection reset. // of a connection reset.
pl.closeAllConns() pl.closeAllConns()
@ -107,6 +111,10 @@ func (pl *PluginServer) closeAllConns() {
pl.mu.Lock() pl.mu.Lock()
defer pl.mu.Unlock() defer pl.mu.Unlock()
if pl.closed {
return
}
// Prevent new connections from being accepted. // Prevent new connections from being accepted.
pl.closed = true pl.closed = true

View File

@ -54,7 +54,7 @@ func setupCommonRootCommand(rootCmd *cobra.Command) (*cliflags.ClientOptions, *c
rootCmd.SetHelpCommand(helpCommand) rootCmd.SetHelpCommand(helpCommand)
rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage") rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage")
rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help") rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "use --help")
rootCmd.PersistentFlags().Lookup("help").Hidden = true rootCmd.PersistentFlags().Lookup("help").Hidden = true
rootCmd.Annotations = map[string]string{ rootCmd.Annotations = map[string]string{

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package command package command
@ -44,7 +44,7 @@ const defaultInitTimeout = 2 * time.Second
type Streams interface { type Streams interface {
In() *streams.In In() *streams.In
Out() *streams.Out Out() *streams.Out
Err() io.Writer Err() *streams.Out
} }
// Cli represents the docker command line client. // Cli represents the docker command line client.
@ -75,7 +75,7 @@ type DockerCli struct {
options *cliflags.ClientOptions options *cliflags.ClientOptions
in *streams.In in *streams.In
out *streams.Out out *streams.Out
err io.Writer err *streams.Out
client client.APIClient client client.APIClient
serverInfo ServerInfo serverInfo ServerInfo
contentTrust bool contentTrust bool
@ -92,6 +92,8 @@ type DockerCli struct {
// this may be replaced by explicitly passing a context to functions that // this may be replaced by explicitly passing a context to functions that
// need it. // need it.
baseCtx context.Context baseCtx context.Context
enableGlobalMeter, enableGlobalTracer bool
} }
// DefaultVersion returns api.defaultVersion. // DefaultVersion returns api.defaultVersion.
@ -124,7 +126,7 @@ func (cli *DockerCli) Out() *streams.Out {
} }
// Err returns the writer used for stderr // Err returns the writer used for stderr
func (cli *DockerCli) Err() io.Writer { func (cli *DockerCli) Err() *streams.Out {
return cli.err return cli.err
} }
@ -184,9 +186,18 @@ func (cli *DockerCli) BuildKitEnabled() (bool, error) {
if _, ok := aliasMap["builder"]; ok { if _, ok := aliasMap["builder"]; ok {
return true, nil return true, nil
} }
// otherwise, assume BuildKit is enabled but
// not if wcow reported from server side si := cli.ServerInfo()
return cli.ServerInfo().OSType != "windows", nil if si.BuildkitVersion == types.BuilderBuildKit {
// The daemon advertised BuildKit as the preferred builder; this may
// be either a Linux daemon or a Windows daemon with experimental
// BuildKit support enabled.
return true, nil
}
// otherwise, assume BuildKit is enabled for Linux, but disabled for
// Windows / WCOW, which does not yet support BuildKit by default.
return si.OSType != "windows", nil
} }
// HooksEnabled returns whether plugin hooks are enabled. // HooksEnabled returns whether plugin hooks are enabled.
@ -275,8 +286,12 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...CLIOption)
} }
// TODO(krissetto): pass ctx to the funcs instead of using this // TODO(krissetto): pass ctx to the funcs instead of using this
if cli.enableGlobalMeter {
cli.createGlobalMeterProvider(cli.baseCtx) cli.createGlobalMeterProvider(cli.baseCtx)
}
if cli.enableGlobalTracer {
cli.createGlobalTracerProvider(cli.baseCtx) cli.createGlobalTracerProvider(cli.baseCtx)
}
return nil return nil
} }
@ -315,7 +330,7 @@ func newAPIClientFromEndpoint(ep docker.Endpoint, configFile *configfile.ConfigF
func resolveDockerEndpoint(s store.Reader, contextName string) (docker.Endpoint, error) { func resolveDockerEndpoint(s store.Reader, contextName string) (docker.Endpoint, error) {
if s == nil { if s == nil {
return docker.Endpoint{}, fmt.Errorf("no context store initialized") return docker.Endpoint{}, errors.New("no context store initialized")
} }
ctxMeta, err := s.GetMetadata(contextName) ctxMeta, err := s.GetMetadata(contextName)
if err != nil { if err != nil {
@ -546,7 +561,7 @@ func getServerHost(hosts []string, tlsOptions *tlsconfig.Options) (string, error
case 1: case 1:
host = hosts[0] host = hosts[0]
default: default:
return "", errors.New("Please specify only one -H") return "", errors.New("Specify only one -H")
} }
return dopts.ParseHost(tlsOptions != nil, host) return dopts.ParseHost(tlsOptions != nil, host)

View File

@ -23,7 +23,7 @@ func WithStandardStreams() CLIOption {
stdin, stdout, stderr := term.StdStreams() stdin, stdout, stderr := term.StdStreams()
cli.in = streams.NewIn(stdin) cli.in = streams.NewIn(stdin)
cli.out = streams.NewOut(stdout) cli.out = streams.NewOut(stdout)
cli.err = stderr cli.err = streams.NewOut(stderr)
return nil return nil
} }
} }
@ -40,8 +40,9 @@ func WithBaseContext(ctx context.Context) CLIOption {
// WithCombinedStreams uses the same stream for the output and error streams. // WithCombinedStreams uses the same stream for the output and error streams.
func WithCombinedStreams(combined io.Writer) CLIOption { func WithCombinedStreams(combined io.Writer) CLIOption {
return func(cli *DockerCli) error { return func(cli *DockerCli) error {
cli.out = streams.NewOut(combined) s := streams.NewOut(combined)
cli.err = combined cli.out = s
cli.err = s
return nil return nil
} }
} }
@ -65,7 +66,7 @@ func WithOutputStream(out io.Writer) CLIOption {
// WithErrorStream sets a cli error stream. // WithErrorStream sets a cli error stream.
func WithErrorStream(err io.Writer) CLIOption { func WithErrorStream(err io.Writer) CLIOption {
return func(cli *DockerCli) error { return func(cli *DockerCli) error {
cli.err = err cli.err = streams.NewOut(err)
return nil return nil
} }
} }

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package command package command

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package command package command

View File

@ -1,51 +0,0 @@
package command
import (
"sync"
"github.com/docker/docker/api/types/events"
"github.com/sirupsen/logrus"
)
// EventHandler is abstract interface for user to customize
// own handle functions of each type of events
//
// Deprecated: EventHandler is no longer used, and will be removed in the next release.
type EventHandler interface {
Handle(action events.Action, h func(events.Message))
Watch(c <-chan events.Message)
}
// InitEventHandler initializes and returns an EventHandler
//
// Deprecated: InitEventHandler is no longer used, and will be removed in the next release.
func InitEventHandler() EventHandler {
return &eventHandler{handlers: make(map[events.Action]func(events.Message))}
}
type eventHandler struct {
handlers map[events.Action]func(events.Message)
mu sync.Mutex
}
func (w *eventHandler) Handle(action events.Action, h func(events.Message)) {
w.mu.Lock()
w.handlers[action] = h
w.mu.Unlock()
}
// Watch ranges over the passed in event chan and processes the events based on the
// handlers created for a given action.
// To stop watching, close the event chan.
func (w *eventHandler) Watch(c <-chan events.Message) {
for e := range c {
w.mu.Lock()
h, exists := w.handlers[e.Action]
w.mu.Unlock()
if !exists {
continue
}
logrus.Debugf("event handler: received event: %v", e)
go h(e)
}
}

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package formatter package formatter

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package formatter package formatter

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package formatter package formatter

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package formatter package formatter

View File

@ -106,7 +106,7 @@ type Writer struct {
cell cell // current incomplete cell; cell.width is up to buf[pos] excluding ignored sections cell cell // current incomplete cell; cell.width is up to buf[pos] excluding ignored sections
endChar byte // terminating char of escaped sequence (Escape for escapes, '>', ';' for HTML tags/entities, or 0) endChar byte // terminating char of escaped sequence (Escape for escapes, '>', ';' for HTML tags/entities, or 0)
lines [][]cell // list of lines; each line is a list of cells lines [][]cell // list of lines; each line is a list of cells
widths []int // list of column widths in runes - re-used during formatting widths []int // list of column widths in runes - reused during formatting
} }
// addLine adds a new line. // addLine adds a new line.
@ -115,7 +115,7 @@ type Writer struct {
func (b *Writer) addLine(flushed bool) { func (b *Writer) addLine(flushed bool) {
// Grow slice instead of appending, // Grow slice instead of appending,
// as that gives us an opportunity // as that gives us an opportunity
// to re-use an existing []cell. // to reuse an existing []cell.
if n := len(b.lines) + 1; n <= cap(b.lines) { if n := len(b.lines) + 1; n <= cap(b.lines) {
b.lines = b.lines[:n] b.lines = b.lines[:n]
b.lines[n-1] = b.lines[n-1][:0] b.lines[n-1] = b.lines[n-1][:0]
@ -159,7 +159,7 @@ func (b *Writer) reset() {
// - the sizes and widths of processed text are kept in the lines list // - the sizes and widths of processed text are kept in the lines list
// which contains a list of cells for each line // which contains a list of cells for each line
// - the widths list is a temporary list with current widths used during // - the widths list is a temporary list with current widths used during
// formatting; it is kept in Writer because it's re-used // formatting; it is kept in Writer because it's reused
// //
// |<---------- size ---------->| // |<---------- size ---------->|
// | | // | |

View File

@ -2,6 +2,7 @@ package command
import ( import (
"bufio" "bufio"
"context"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -10,6 +11,7 @@ import (
"github.com/distribution/reference" "github.com/distribution/reference"
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/config/credentials"
configtypes "github.com/docker/cli/cli/config/types" configtypes "github.com/docker/cli/cli/config/types"
"github.com/docker/cli/cli/hints" "github.com/docker/cli/cli/hints"
"github.com/docker/cli/cli/streams" "github.com/docker/cli/cli/streams"
@ -27,14 +29,21 @@ const patSuggest = "You can log in with your password or a Personal Access " +
// RegistryAuthenticationPrivilegedFunc returns a RequestPrivilegeFunc from the specified registry index info // RegistryAuthenticationPrivilegedFunc returns a RequestPrivilegeFunc from the specified registry index info
// for the given command. // for the given command.
func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInfo, cmdName string) types.RequestPrivilegeFunc { func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInfo, cmdName string) types.RequestPrivilegeFunc {
return func() (string, error) { return func(ctx context.Context) (string, error) {
fmt.Fprintf(cli.Out(), "\nPlease login prior to %s:\n", cmdName) fmt.Fprintf(cli.Out(), "\nLogin prior to %s:\n", cmdName)
indexServer := registry.GetAuthConfigKey(index) indexServer := registry.GetAuthConfigKey(index)
isDefaultRegistry := indexServer == registry.IndexServer isDefaultRegistry := indexServer == registry.IndexServer
authConfig, err := GetDefaultAuthConfig(cli.ConfigFile(), true, indexServer, isDefaultRegistry) authConfig, err := GetDefaultAuthConfig(cli.ConfigFile(), true, indexServer, isDefaultRegistry)
if err != nil { if err != nil {
fmt.Fprintf(cli.Err(), "Unable to retrieve stored credentials for %s, error: %s.\n", indexServer, err) fmt.Fprintf(cli.Err(), "Unable to retrieve stored credentials for %s, error: %s.\n", indexServer, err)
} }
select {
case <-ctx.Done():
return "", ctx.Err()
default:
}
err = ConfigureAuth(cli, "", "", &authConfig, isDefaultRegistry) err = ConfigureAuth(cli, "", "", &authConfig, isDefaultRegistry)
if err != nil { if err != nil {
return "", err return "", err
@ -63,7 +72,7 @@ func ResolveAuthConfig(cfg *configfile.ConfigFile, index *registrytypes.IndexInf
// If credentials for given serverAddress exists in the credential store, the configuration will be populated with values in it // If credentials for given serverAddress exists in the credential store, the configuration will be populated with values in it
func GetDefaultAuthConfig(cfg *configfile.ConfigFile, checkCredStore bool, serverAddress string, isDefaultRegistry bool) (registrytypes.AuthConfig, error) { func GetDefaultAuthConfig(cfg *configfile.ConfigFile, checkCredStore bool, serverAddress string, isDefaultRegistry bool) (registrytypes.AuthConfig, error) {
if !isDefaultRegistry { if !isDefaultRegistry {
serverAddress = registry.ConvertToHostname(serverAddress) serverAddress = credentials.ConvertToHostname(serverAddress)
} }
authconfig := configtypes.AuthConfig{} authconfig := configtypes.AuthConfig{}
var err error var err error

View File

@ -1,11 +1,10 @@
// FIXME(jsternberg): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // FIXME(jsternberg): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
//go:build go1.19 //go:build go1.21
package command package command
import ( import (
"context" "context"
"fmt"
"net/url" "net/url"
"os" "os"
"path" "path"
@ -85,7 +84,7 @@ func dockerExporterOTLPEndpoint(cli Cli) (endpoint string, secure bool) {
// needs the scheme to use the correct resolver. // needs the scheme to use the correct resolver.
// //
// We'll just handle this in a special way and add the unix:// back to the endpoint. // We'll just handle this in a special way and add the unix:// back to the endpoint.
endpoint = fmt.Sprintf("unix://%s", path.Join(u.Host, u.Path)) endpoint = "unix://" + path.Join(u.Host, u.Path)
case "https": case "https":
secure = true secure = true
fallthrough fallthrough

View File

@ -0,0 +1,25 @@
package command
// WithEnableGlobalMeterProvider configures the DockerCli to create a new
// MeterProvider from the initialized DockerCli struct, and set it as
// the global meter provider.
//
// WARNING: For internal use, don't depend on this.
func WithEnableGlobalMeterProvider() CLIOption {
return func(cli *DockerCli) error {
cli.enableGlobalMeter = true
return nil
}
}
// WithEnableGlobalTracerProvider configures the DockerCli to create a new
// TracerProvider from the initialized DockerCli struct, and set it as
// the global tracer provider.
//
// WARNING: For internal use, don't depend on this.
func WithEnableGlobalTracerProvider() CLIOption {
return func(cli *DockerCli) error {
cli.enableGlobalTracer = true
return nil
}
}

View File

@ -7,7 +7,6 @@ import (
"time" "time"
"github.com/docker/cli/cli/version" "github.com/docker/cli/cli/version"
"github.com/moby/term"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
@ -101,12 +100,10 @@ func startCobraCommandTimer(mp metric.MeterProvider, attrs []attribute.KeyValue)
} }
func stdioAttributes(streams Streams) []attribute.KeyValue { func stdioAttributes(streams Streams) []attribute.KeyValue {
// we don't wrap stderr, but we do wrap in/out
_, stderrTty := term.GetFdInfo(streams.Err())
return []attribute.KeyValue{ return []attribute.KeyValue{
attribute.Bool("command.stdin.isatty", streams.In().IsTerminal()), attribute.Bool("command.stdin.isatty", streams.In().IsTerminal()),
attribute.Bool("command.stdout.isatty", streams.Out().IsTerminal()), attribute.Bool("command.stdout.isatty", streams.Out().IsTerminal()),
attribute.Bool("command.stderr.isatty", stderrTty), attribute.Bool("command.stderr.isatty", streams.Err().IsTerminal()),
} }
} }

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package command package command
@ -9,11 +9,9 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"os/signal"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
"syscall"
"github.com/docker/cli/cli/streams" "github.com/docker/cli/cli/streams"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
@ -103,11 +101,6 @@ func PromptForConfirmation(ctx context.Context, ins io.Reader, outs io.Writer, m
result := make(chan bool) result := make(chan bool)
// Catch the termination signal and exit the prompt gracefully.
// The caller is responsible for properly handling the termination.
notifyCtx, notifyCancel := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
defer notifyCancel()
go func() { go func() {
var res bool var res bool
scanner := bufio.NewScanner(ins) scanner := bufio.NewScanner(ins)
@ -121,8 +114,7 @@ func PromptForConfirmation(ctx context.Context, ins io.Reader, outs io.Writer, m
}() }()
select { select {
case <-notifyCtx.Done(): case <-ctx.Done():
// print a newline on termination
_, _ = fmt.Fprintln(outs, "") _, _ = fmt.Fprintln(outs, "")
return false, ErrPromptTerminated return false, ErrPromptTerminated
case r := <-result: case r := <-result:

View File

@ -4,14 +4,15 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"os/user"
"path/filepath" "path/filepath"
"runtime"
"strings" "strings"
"sync" "sync"
"github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/config/credentials" "github.com/docker/cli/cli/config/credentials"
"github.com/docker/cli/cli/config/types" "github.com/docker/cli/cli/config/types"
"github.com/docker/docker/pkg/homedir"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -42,12 +43,38 @@ func resetConfigDir() {
initConfigDir = new(sync.Once) initConfigDir = new(sync.Once)
} }
// getHomeDir returns the home directory of the current user with the help of
// environment variables depending on the target operating system.
// Returned path should be used with "path/filepath" to form new paths.
//
// On non-Windows platforms, it falls back to nss lookups, if the home
// directory cannot be obtained from environment-variables.
//
// If linking statically with cgo enabled against glibc, ensure the
// osusergo build tag is used.
//
// If needing to do nss lookups, do not disable cgo or set osusergo.
//
// getHomeDir is a copy of [pkg/homedir.Get] to prevent adding docker/docker
// as dependency for consumers that only need to read the config-file.
//
// [pkg/homedir.Get]: https://pkg.go.dev/github.com/docker/docker@v26.1.4+incompatible/pkg/homedir#Get
func getHomeDir() string {
home, _ := os.UserHomeDir()
if home == "" && runtime.GOOS != "windows" {
if u, err := user.Current(); err == nil {
return u.HomeDir
}
}
return home
}
// Dir returns the directory the configuration file is stored in // Dir returns the directory the configuration file is stored in
func Dir() string { func Dir() string {
initConfigDir.Do(func() { initConfigDir.Do(func() {
configDir = os.Getenv(EnvOverrideConfigDir) configDir = os.Getenv(EnvOverrideConfigDir)
if configDir == "" { if configDir == "" {
configDir = filepath.Join(homedir.Get(), configFileDir) configDir = filepath.Join(getHomeDir(), configFileDir)
} }
}) })
return configDir return configDir
@ -75,7 +102,7 @@ func Path(p ...string) (string, error) {
} }
// LoadFromReader is a convenience function that creates a ConfigFile object from // LoadFromReader is a convenience function that creates a ConfigFile object from
// a reader // a reader. It returns an error if configData is malformed.
func LoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) { func LoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) {
configFile := configfile.ConfigFile{ configFile := configfile.ConfigFile{
AuthConfigs: make(map[string]types.AuthConfig), AuthConfigs: make(map[string]types.AuthConfig),
@ -84,8 +111,14 @@ func LoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) {
return &configFile, err return &configFile, err
} }
// Load reads the configuration files in the given directory, and sets up // Load reads the configuration file ([ConfigFileName]) from the given directory.
// the auth config information and returns values. // If no directory is given, it uses the default [Dir]. A [*configfile.ConfigFile]
// is returned containing the contents of the configuration file, or a default
// struct if no configfile exists in the given location.
//
// Load returns an error if a configuration file exists in the given location,
// but cannot be read, or is malformed. Consumers must handle errors to prevent
// overwriting an existing configuration file.
func Load(configDir string) (*configfile.ConfigFile, error) { func Load(configDir string) (*configfile.ConfigFile, error) {
if configDir == "" { if configDir == "" {
configDir = Dir() configDir = Dir()
@ -100,29 +133,37 @@ func load(configDir string) (*configfile.ConfigFile, error) {
file, err := os.Open(filename) file, err := os.Open(filename)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
// // It is OK for no configuration file to be present, in which
// if file is there but we can't stat it for any reason other // case we return a default struct.
// than it doesn't exist then stop
return configFile, nil return configFile, nil
} }
// if file is there but we can't stat it for any reason other // Any other error happening when failing to read the file must be returned.
// than it doesn't exist then stop return configFile, errors.Wrap(err, "loading config file")
return configFile, nil
} }
defer file.Close() defer file.Close()
err = configFile.LoadFromReader(file) err = configFile.LoadFromReader(file)
if err != nil { if err != nil {
err = errors.Wrap(err, filename) err = errors.Wrapf(err, "loading config file: %s: ", filename)
} }
return configFile, err return configFile, err
} }
// LoadDefaultConfigFile attempts to load the default config file and returns // LoadDefaultConfigFile attempts to load the default config file and returns
// an initialized ConfigFile struct if none is found. // a reference to the ConfigFile struct. If none is found or when failing to load
// the configuration file, it initializes a default ConfigFile struct. If no
// credentials-store is set in the configuration file, it attempts to discover
// the default store to use for the current platform.
//
// Important: LoadDefaultConfigFile prints a warning to stderr when failing to
// load the configuration file, but otherwise ignores errors. Consumers should
// consider using [Load] (and [credentials.DetectDefaultStore]) to detect errors
// when updating the configuration file, to prevent discarding a (malformed)
// configuration file.
func LoadDefaultConfigFile(stderr io.Writer) *configfile.ConfigFile { func LoadDefaultConfigFile(stderr io.Writer) *configfile.ConfigFile {
configFile, err := load(Dir()) configFile, err := load(Dir())
if err != nil { if err != nil {
_, _ = fmt.Fprintf(stderr, "WARNING: Error loading config file: %v\n", err) // FIXME(thaJeztah): we should not proceed here to prevent overwriting existing (but malformed) config files; see https://github.com/docker/cli/issues/5075
_, _ = fmt.Fprintln(stderr, "WARNING: Error", err)
} }
if !configFile.ContainsAuth() { if !configFile.ContainsAuth() {
configFile.CredentialsStore = credentials.DetectDefaultStore(configFile.CredentialsStore) configFile.CredentialsStore = credentials.DetectDefaultStore(configFile.CredentialsStore)

View File

@ -1,6 +1,7 @@
package credentials package credentials
import ( import (
"net/url"
"strings" "strings"
"github.com/docker/cli/cli/config/types" "github.com/docker/cli/cli/config/types"
@ -68,14 +69,14 @@ func (c *fileStore) IsFileStore() bool {
// ConvertToHostname converts a registry url which has http|https prepended // ConvertToHostname converts a registry url which has http|https prepended
// to just an hostname. // to just an hostname.
// Copied from github.com/docker/docker/registry.ConvertToHostname to reduce dependencies. // Copied from github.com/docker/docker/registry.ConvertToHostname to reduce dependencies.
func ConvertToHostname(url string) string { func ConvertToHostname(maybeURL string) string {
stripped := url stripped := maybeURL
if strings.HasPrefix(url, "http://") { if strings.Contains(stripped, "://") {
stripped = strings.TrimPrefix(url, "http://") u, err := url.Parse(stripped)
} else if strings.HasPrefix(url, "https://") { if err == nil && u.Hostname() != "" {
stripped = strings.TrimPrefix(url, "https://") return u.Hostname()
}
} }
hostName, _, _ := strings.Cut(stripped, "/") hostName, _, _ := strings.Cut(stripped, "/")
return hostName return hostName
} }

View File

@ -149,7 +149,7 @@ func (c *commandConn) handleEOF(err error) error {
c.stderrMu.Lock() c.stderrMu.Lock()
stderr := c.stderr.String() stderr := c.stderr.String()
c.stderrMu.Unlock() c.stderrMu.Unlock()
return errors.Errorf("command %v has exited with %v, please make sure the URL is valid, and Docker 18.09 or later is installed on the remote host: stderr=%s", c.cmd.Args, werr, stderr) return errors.Errorf("command %v has exited with %v, make sure the URL is valid, and Docker 18.09 or later is installed on the remote host: stderr=%s", c.cmd.Args, werr, stderr)
} }
func ignorableCloseError(err error) bool { func ignorableCloseError(err error) bool {

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package store package store

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package store package store

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package store package store
@ -14,7 +14,7 @@ type NamedTypeGetter struct {
typeGetter TypeGetter typeGetter TypeGetter
} }
// EndpointTypeGetter returns a NamedTypeGetter with the spcecified name and getter // EndpointTypeGetter returns a NamedTypeGetter with the specified name and getter
func EndpointTypeGetter(name string, getter TypeGetter) NamedTypeGetter { func EndpointTypeGetter(name string, getter TypeGetter) NamedTypeGetter {
return NamedTypeGetter{ return NamedTypeGetter{
name: name, name: name,

View File

@ -2,7 +2,6 @@ package store
import ( import (
"encoding/json" "encoding/json"
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@ -162,7 +161,7 @@ func newNotFoundError(ref string) *notFoundError {
} }
func (n *notFoundError) Error() string { func (n *notFoundError) Error() string {
return fmt.Sprintf("No such manifest: %s", n.object) return "No such manifest: " + n.object
} }
// NotFound interface // NotFound interface

View File

@ -101,23 +101,23 @@ func (c *client) MountBlob(ctx context.Context, sourceRef reference.Canonical, t
func (c *client) PutManifest(ctx context.Context, ref reference.Named, manifest distribution.Manifest) (digest.Digest, error) { func (c *client) PutManifest(ctx context.Context, ref reference.Named, manifest distribution.Manifest) (digest.Digest, error) {
repoEndpoint, err := newDefaultRepositoryEndpoint(ref, c.insecureRegistry) repoEndpoint, err := newDefaultRepositoryEndpoint(ref, c.insecureRegistry)
if err != nil { if err != nil {
return digest.Digest(""), err return "", err
} }
repoEndpoint.actions = trust.ActionsPushAndPull repoEndpoint.actions = trust.ActionsPushAndPull
repo, err := c.getRepositoryForReference(ctx, ref, repoEndpoint) repo, err := c.getRepositoryForReference(ctx, ref, repoEndpoint)
if err != nil { if err != nil {
return digest.Digest(""), err return "", err
} }
manifestService, err := repo.Manifests(ctx) manifestService, err := repo.Manifests(ctx)
if err != nil { if err != nil {
return digest.Digest(""), err return "", err
} }
_, opts, err := getManifestOptionsFromReference(ref) _, opts, err := getManifestOptionsFromReference(ref)
if err != nil { if err != nil {
return digest.Digest(""), err return "", err
} }
dgst, err := manifestService.Put(ctx, manifest, opts...) dgst, err := manifestService.Put(ctx, manifest, opts...)

View File

@ -1,7 +1,6 @@
package client package client
import ( import (
"fmt"
"net" "net"
"net/http" "net/http"
"time" "time"
@ -83,7 +82,6 @@ func getHTTPTransport(authConfig registrytypes.AuthConfig, endpoint registry.API
Dial: (&net.Dialer{ Dial: (&net.Dialer{
Timeout: 30 * time.Second, Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second, KeepAlive: 30 * time.Second,
DualStack: true,
}).Dial, }).Dial,
TLSHandshakeTimeout: 10 * time.Second, TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: endpoint.TLSConfig, TLSClientConfig: endpoint.TLSConfig,
@ -126,7 +124,7 @@ type existingTokenHandler struct {
} }
func (th *existingTokenHandler) AuthorizeRequest(req *http.Request, _ map[string]string) error { func (th *existingTokenHandler) AuthorizeRequest(req *http.Request, _ map[string]string) error {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", th.token)) req.Header.Set("Authorization", "Bearer "+th.token)
return nil return nil
} }

View File

@ -270,7 +270,7 @@ func (c *client) iterateEndpoints(ctx context.Context, namedRef reference.Named,
return newNotFoundError(namedRef.String()) return newNotFoundError(namedRef.String())
} }
// allEndpoints returns a list of endpoints ordered by priority (v2, https, v1). // allEndpoints returns a list of endpoints ordered by priority (v2, http).
func allEndpoints(namedRef reference.Named, insecure bool) ([]registry.APIEndpoint, error) { func allEndpoints(namedRef reference.Named, insecure bool) ([]registry.APIEndpoint, error) {
repoInfo, err := registry.ParseRepositoryInfo(namedRef) repoInfo, err := registry.ParseRepositoryInfo(namedRef)
if err != nil { if err != nil {

View File

@ -119,7 +119,6 @@ func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo
Dial: (&net.Dialer{ Dial: (&net.Dialer{
Timeout: 30 * time.Second, Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second, KeepAlive: 30 * time.Second,
DualStack: true,
}).Dial, }).Dial,
TLSHandshakeTimeout: 10 * time.Second, TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: cfg, TLSClientConfig: cfg,

View File

@ -2,6 +2,7 @@ package opts
import ( import (
"encoding/csv" "encoding/csv"
"errors"
"fmt" "fmt"
"os" "os"
"strconv" "strconv"
@ -68,7 +69,7 @@ func (o *ConfigOpt) Set(value string) error {
} }
if options.ConfigName == "" { if options.ConfigName == "" {
return fmt.Errorf("source is required") return errors.New("source is required")
} }
if options.File.Name == "" { if options.File.Name == "" {
options.File.Name = options.ConfigName options.File.Name = options.ConfigName

View File

@ -18,7 +18,7 @@ type ErrBadKey struct {
} }
func (e ErrBadKey) Error() string { func (e ErrBadKey) Error() string {
return fmt.Sprintf("poorly formatted environment: %s", e.msg) return "poorly formatted environment: " + e.msg
} }
func parseKeyValueFile(filename string, emptyFn func(string) (string, bool)) ([]string, error) { func parseKeyValueFile(filename string, emptyFn func(string) (string, bool)) ([]string, error) {

View File

@ -165,11 +165,11 @@ func (m *MountOpt) Set(value string) error {
} }
if mount.Type == "" { if mount.Type == "" {
return fmt.Errorf("type is required") return errors.New("type is required")
} }
if mount.Target == "" { if mount.Target == "" {
return fmt.Errorf("target is required") return errors.New("target is required")
} }
if mount.VolumeOptions != nil && mount.Type != mounttypes.TypeVolume { if mount.VolumeOptions != nil && mount.Type != mounttypes.TypeVolume {

View File

@ -2,6 +2,7 @@ package opts
import ( import (
"encoding/csv" "encoding/csv"
"errors"
"fmt" "fmt"
"regexp" "regexp"
"strings" "strings"
@ -83,11 +84,11 @@ func (n *NetworkOpt) Set(value string) error { //nolint:gocyclo
} }
netOpt.DriverOpts[key] = val netOpt.DriverOpts[key] = val
default: default:
return fmt.Errorf("invalid field key %s", key) return errors.New("invalid field key " + key)
} }
} }
if len(netOpt.Target) == 0 { if len(netOpt.Target) == 0 {
return fmt.Errorf("network name/id is not specified") return errors.New("network name/id is not specified")
} }
} else { } else {
netOpt.Target = value netOpt.Target = value
@ -126,7 +127,7 @@ func parseDriverOpt(driverOpt string) (string, string, error) {
// TODO(thaJeztah): should value be converted to lowercase as well, or only the key? // TODO(thaJeztah): should value be converted to lowercase as well, or only the key?
key, value, ok := strings.Cut(strings.ToLower(driverOpt), "=") key, value, ok := strings.Cut(strings.ToLower(driverOpt), "=")
if !ok || key == "" { if !ok || key == "" {
return "", "", fmt.Errorf("invalid key value pair format in driver options") return "", "", errors.New("invalid key value pair format in driver options")
} }
key = strings.TrimSpace(key) key = strings.TrimSpace(key)
value = strings.TrimSpace(value) value = strings.TrimSpace(value)

View File

@ -401,7 +401,7 @@ func ParseCPUs(value string) (int64, error) {
} }
nano := cpu.Mul(cpu, big.NewRat(1e9, 1)) nano := cpu.Mul(cpu, big.NewRat(1e9, 1))
if !nano.IsInt() { if !nano.IsInt() {
return 0, fmt.Errorf("value is too precise") return 0, errors.New("value is too precise")
} }
return nano.Num().Int64(), nil return nano.Num().Int64(), nil
} }
@ -409,14 +409,14 @@ func ParseCPUs(value string) (int64, error) {
// ParseLink parses and validates the specified string as a link format (name:alias) // ParseLink parses and validates the specified string as a link format (name:alias)
func ParseLink(val string) (string, string, error) { func ParseLink(val string) (string, string, error) {
if val == "" { if val == "" {
return "", "", fmt.Errorf("empty string specified for links") return "", "", errors.New("empty string specified for links")
} }
// We expect two parts, but restrict to three to allow detecting invalid formats. // We expect two parts, but restrict to three to allow detecting invalid formats.
arr := strings.SplitN(val, ":", 3) arr := strings.SplitN(val, ":", 3)
// TODO(thaJeztah): clean up this logic!! // TODO(thaJeztah): clean up this logic!!
if len(arr) > 2 { if len(arr) > 2 {
return "", "", fmt.Errorf("bad format for links: %s", val) return "", "", errors.New("bad format for links: " + val)
} }
// TODO(thaJeztah): this should trim the "/" prefix as well?? // TODO(thaJeztah): this should trim the "/" prefix as well??
if len(arr) == 1 { if len(arr) == 1 {

View File

@ -1,7 +1,7 @@
package opts package opts
import ( import (
"fmt" "errors"
"os" "os"
"strconv" "strconv"
"strings" "strings"
@ -81,12 +81,12 @@ func ParseRestartPolicy(policy string) (container.RestartPolicy, error) {
p := container.RestartPolicy{} p := container.RestartPolicy{}
k, v, ok := strings.Cut(policy, ":") k, v, ok := strings.Cut(policy, ":")
if ok && k == "" { if ok && k == "" {
return container.RestartPolicy{}, fmt.Errorf("invalid restart policy format: no policy provided before colon") return container.RestartPolicy{}, errors.New("invalid restart policy format: no policy provided before colon")
} }
if v != "" { if v != "" {
count, err := strconv.Atoi(v) count, err := strconv.Atoi(v)
if err != nil { if err != nil {
return container.RestartPolicy{}, fmt.Errorf("invalid restart policy format: maximum retry count must be an integer") return container.RestartPolicy{}, errors.New("invalid restart policy format: maximum retry count must be an integer")
} }
p.MaximumRetryCount = count p.MaximumRetryCount = count
} }

View File

@ -2,6 +2,7 @@ package opts
import ( import (
"encoding/csv" "encoding/csv"
"errors"
"fmt" "fmt"
"net" "net"
"regexp" "regexp"
@ -102,7 +103,7 @@ func (p *PortOpt) Set(value string) error {
for _, portBindings := range portBindingMap { for _, portBindings := range portBindingMap {
for _, portBinding := range portBindings { for _, portBinding := range portBindings {
if portBinding.HostIP != "" { if portBinding.HostIP != "" {
return fmt.Errorf("hostip is not supported") return errors.New("hostip is not supported")
} }
} }
} }

View File

@ -2,6 +2,7 @@ package opts
import ( import (
"encoding/csv" "encoding/csv"
"errors"
"fmt" "fmt"
"os" "os"
"strconv" "strconv"
@ -62,12 +63,12 @@ func (o *SecretOpt) Set(value string) error {
options.File.Mode = os.FileMode(m) options.File.Mode = os.FileMode(m)
default: default:
return fmt.Errorf("invalid field in secret request: %s", key) return errors.New("invalid field in secret request: " + key)
} }
} }
if options.SecretName == "" { if options.SecretName == "" {
return fmt.Errorf("source is required") return errors.New("source is required")
} }
if options.File.Name == "" { if options.File.Name == "" {
options.File.Name = options.SecretName options.File.Name = options.SecretName

View File

@ -4,24 +4,27 @@ import (
"fmt" "fmt"
"sort" "sort"
"github.com/docker/docker/api/types/container"
"github.com/docker/go-units" "github.com/docker/go-units"
) )
// UlimitOpt defines a map of Ulimits // UlimitOpt defines a map of Ulimits
type UlimitOpt struct { type UlimitOpt struct {
values *map[string]*units.Ulimit values *map[string]*container.Ulimit
} }
// NewUlimitOpt creates a new UlimitOpt. Ulimits are not validated. // NewUlimitOpt creates a new UlimitOpt. Ulimits are not validated.
func NewUlimitOpt(ref *map[string]*units.Ulimit) *UlimitOpt { func NewUlimitOpt(ref *map[string]*container.Ulimit) *UlimitOpt {
// TODO(thaJeztah): why do we need a map with pointers here?
if ref == nil { if ref == nil {
ref = &map[string]*units.Ulimit{} ref = &map[string]*container.Ulimit{}
} }
return &UlimitOpt{ref} return &UlimitOpt{ref}
} }
// Set validates a Ulimit and sets its name as a key in UlimitOpt // Set validates a Ulimit and sets its name as a key in UlimitOpt
func (o *UlimitOpt) Set(val string) error { func (o *UlimitOpt) Set(val string) error {
// FIXME(thaJeztah): these functions also need to be moved over from go-units.
l, err := units.ParseUlimit(val) l, err := units.ParseUlimit(val)
if err != nil { if err != nil {
return err return err
@ -43,8 +46,8 @@ func (o *UlimitOpt) String() string {
} }
// GetList returns a slice of pointers to Ulimits. Values are sorted by name. // GetList returns a slice of pointers to Ulimits. Values are sorted by name.
func (o *UlimitOpt) GetList() []*units.Ulimit { func (o *UlimitOpt) GetList() []*container.Ulimit {
ulimits := make([]*units.Ulimit, 0, len(*o.values)) ulimits := make([]*container.Ulimit, 0, len(*o.values))
for _, v := range *o.values { for _, v := range *o.values {
ulimits = append(ulimits, v) ulimits = append(ulimits, v)
} }

View File

@ -1,5 +1,5 @@
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: // 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 //go:build go1.21
package templates package templates

View File

@ -10,6 +10,7 @@ Aaron Huslage <huslage@gmail.com>
Aaron L. Xu <liker.xu@foxmail.com> Aaron L. Xu <liker.xu@foxmail.com>
Aaron Lehmann <alehmann@netflix.com> Aaron Lehmann <alehmann@netflix.com>
Aaron Welch <welch@packet.net> Aaron Welch <welch@packet.net>
Aaron Yoshitake <airandfingers@gmail.com>
Abel Muiño <amuino@gmail.com> Abel Muiño <amuino@gmail.com>
Abhijeet Kasurde <akasurde@redhat.com> Abhijeet Kasurde <akasurde@redhat.com>
Abhinandan Prativadi <aprativadi@gmail.com> Abhinandan Prativadi <aprativadi@gmail.com>
@ -62,6 +63,7 @@ alambike <alambike@gmail.com>
Alan Hoyle <alan@alanhoyle.com> Alan Hoyle <alan@alanhoyle.com>
Alan Scherger <flyinprogrammer@gmail.com> Alan Scherger <flyinprogrammer@gmail.com>
Alan Thompson <cloojure@gmail.com> Alan Thompson <cloojure@gmail.com>
Alano Terblanche <alano.terblanche@docker.com>
Albert Callarisa <shark234@gmail.com> Albert Callarisa <shark234@gmail.com>
Albert Zhang <zhgwenming@gmail.com> Albert Zhang <zhgwenming@gmail.com>
Albin Kerouanton <albinker@gmail.com> Albin Kerouanton <albinker@gmail.com>
@ -141,6 +143,7 @@ Andreas Tiefenthaler <at@an-ti.eu>
Andrei Gherzan <andrei@resin.io> Andrei Gherzan <andrei@resin.io>
Andrei Ushakov <aushakov@netflix.com> Andrei Ushakov <aushakov@netflix.com>
Andrei Vagin <avagin@gmail.com> Andrei Vagin <avagin@gmail.com>
Andrew Baxter <423qpsxzhh8k3h@s.rendaw.me>
Andrew C. Bodine <acbodine@us.ibm.com> Andrew C. Bodine <acbodine@us.ibm.com>
Andrew Clay Shafer <andrewcshafer@gmail.com> Andrew Clay Shafer <andrewcshafer@gmail.com>
Andrew Duckworth <grillopress@gmail.com> Andrew Duckworth <grillopress@gmail.com>
@ -193,6 +196,7 @@ Anton Löfgren <anton.lofgren@gmail.com>
Anton Nikitin <anton.k.nikitin@gmail.com> Anton Nikitin <anton.k.nikitin@gmail.com>
Anton Polonskiy <anton.polonskiy@gmail.com> Anton Polonskiy <anton.polonskiy@gmail.com>
Anton Tiurin <noxiouz@yandex.ru> Anton Tiurin <noxiouz@yandex.ru>
Antonio Aguilar <antonio@zoftko.com>
Antonio Murdaca <antonio.murdaca@gmail.com> Antonio Murdaca <antonio.murdaca@gmail.com>
Antonis Kalipetis <akalipetis@gmail.com> Antonis Kalipetis <akalipetis@gmail.com>
Antony Messerli <amesserl@rackspace.com> Antony Messerli <amesserl@rackspace.com>
@ -221,7 +225,6 @@ Avi Das <andas222@gmail.com>
Avi Kivity <avi@scylladb.com> Avi Kivity <avi@scylladb.com>
Avi Miller <avi.miller@oracle.com> Avi Miller <avi.miller@oracle.com>
Avi Vaid <avaid1996@gmail.com> Avi Vaid <avaid1996@gmail.com>
ayoshitake <airandfingers@gmail.com>
Azat Khuyiyakhmetov <shadow_uz@mail.ru> Azat Khuyiyakhmetov <shadow_uz@mail.ru>
Bao Yonglei <baoyonglei@huawei.com> Bao Yonglei <baoyonglei@huawei.com>
Bardia Keyoumarsi <bkeyouma@ucsc.edu> Bardia Keyoumarsi <bkeyouma@ucsc.edu>
@ -316,6 +319,7 @@ Burke Libbey <burke@libbey.me>
Byung Kang <byung.kang.ctr@amrdec.army.mil> Byung Kang <byung.kang.ctr@amrdec.army.mil>
Caleb Spare <cespare@gmail.com> Caleb Spare <cespare@gmail.com>
Calen Pennington <cale@edx.org> Calen Pennington <cale@edx.org>
Calvin Liu <flycalvin@qq.com>
Cameron Boehmer <cameron.boehmer@gmail.com> Cameron Boehmer <cameron.boehmer@gmail.com>
Cameron Sparr <gh@sparr.email> Cameron Sparr <gh@sparr.email>
Cameron Spear <cameronspear@gmail.com> Cameron Spear <cameronspear@gmail.com>
@ -362,6 +366,7 @@ Chen Qiu <cheney-90@hotmail.com>
Cheng-mean Liu <soccerl@microsoft.com> Cheng-mean Liu <soccerl@microsoft.com>
Chengfei Shang <cfshang@alauda.io> Chengfei Shang <cfshang@alauda.io>
Chengguang Xu <cgxu519@gmx.com> Chengguang Xu <cgxu519@gmx.com>
Chentianze <cmoman@126.com>
Chenyang Yan <memory.yancy@gmail.com> Chenyang Yan <memory.yancy@gmail.com>
chenyuzhu <chenyuzhi@oschina.cn> chenyuzhu <chenyuzhi@oschina.cn>
Chetan Birajdar <birajdar.chetan@gmail.com> Chetan Birajdar <birajdar.chetan@gmail.com>
@ -409,6 +414,7 @@ Christopher Crone <christopher.crone@docker.com>
Christopher Currie <codemonkey+github@gmail.com> Christopher Currie <codemonkey+github@gmail.com>
Christopher Jones <tophj@linux.vnet.ibm.com> Christopher Jones <tophj@linux.vnet.ibm.com>
Christopher Latham <sudosurootdev@gmail.com> Christopher Latham <sudosurootdev@gmail.com>
Christopher Petito <chrisjpetito@gmail.com>
Christopher Rigor <crigor@gmail.com> Christopher Rigor <crigor@gmail.com>
Christy Norman <christy@linux.vnet.ibm.com> Christy Norman <christy@linux.vnet.ibm.com>
Chun Chen <ramichen@tencent.com> Chun Chen <ramichen@tencent.com>
@ -777,6 +783,7 @@ Gabriel L. Somlo <gsomlo@gmail.com>
Gabriel Linder <linder.gabriel@gmail.com> Gabriel Linder <linder.gabriel@gmail.com>
Gabriel Monroy <gabriel@opdemand.com> Gabriel Monroy <gabriel@opdemand.com>
Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com> Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com>
Gabriel Tomitsuka <gabriel@tomitsuka.com>
Gaetan de Villele <gdevillele@gmail.com> Gaetan de Villele <gdevillele@gmail.com>
Galen Sampson <galen.sampson@gmail.com> Galen Sampson <galen.sampson@gmail.com>
Gang Qiao <qiaohai8866@gmail.com> Gang Qiao <qiaohai8866@gmail.com>
@ -792,6 +799,7 @@ Geoff Levand <geoff@infradead.org>
Geoffrey Bachelet <grosfrais@gmail.com> Geoffrey Bachelet <grosfrais@gmail.com>
Geon Kim <geon0250@gmail.com> Geon Kim <geon0250@gmail.com>
George Kontridze <george@bugsnag.com> George Kontridze <george@bugsnag.com>
George Ma <mayangang@outlook.com>
George MacRorie <gmacr31@gmail.com> George MacRorie <gmacr31@gmail.com>
George Xie <georgexsh@gmail.com> George Xie <georgexsh@gmail.com>
Georgi Hristozov <georgi@forkbomb.nl> Georgi Hristozov <georgi@forkbomb.nl>
@ -913,6 +921,7 @@ Illo Abdulrahim <abdulrahim.illo@nokia.com>
Ilya Dmitrichenko <errordeveloper@gmail.com> Ilya Dmitrichenko <errordeveloper@gmail.com>
Ilya Gusev <mail@igusev.ru> Ilya Gusev <mail@igusev.ru>
Ilya Khlopotov <ilya.khlopotov@gmail.com> Ilya Khlopotov <ilya.khlopotov@gmail.com>
imalasong <2879499479@qq.com>
imre Fitos <imre.fitos+github@gmail.com> imre Fitos <imre.fitos+github@gmail.com>
inglesp <peter.inglesby@gmail.com> inglesp <peter.inglesby@gmail.com>
Ingo Gottwald <in.gottwald@gmail.com> Ingo Gottwald <in.gottwald@gmail.com>
@ -930,6 +939,7 @@ J Bruni <joaohbruni@yahoo.com.br>
J. Nunn <jbnunn@gmail.com> J. Nunn <jbnunn@gmail.com>
Jack Danger Canty <jackdanger@squareup.com> Jack Danger Canty <jackdanger@squareup.com>
Jack Laxson <jackjrabbit@gmail.com> Jack Laxson <jackjrabbit@gmail.com>
Jack Walker <90711509+j2walker@users.noreply.github.com>
Jacob Atzen <jacob@jacobatzen.dk> Jacob Atzen <jacob@jacobatzen.dk>
Jacob Edelman <edelman.jd@gmail.com> Jacob Edelman <edelman.jd@gmail.com>
Jacob Tomlinson <jacob@tom.linson.uk> Jacob Tomlinson <jacob@tom.linson.uk>
@ -989,6 +999,7 @@ Jason Shepherd <jason@jasonshepherd.net>
Jason Smith <jasonrichardsmith@gmail.com> Jason Smith <jasonrichardsmith@gmail.com>
Jason Sommer <jsdirv@gmail.com> Jason Sommer <jsdirv@gmail.com>
Jason Stangroome <jason@codeassassin.com> Jason Stangroome <jason@codeassassin.com>
Jasper Siepkes <siepkes@serviceplanet.nl>
Javier Bassi <javierbassi@gmail.com> Javier Bassi <javierbassi@gmail.com>
jaxgeller <jacksongeller@gmail.com> jaxgeller <jacksongeller@gmail.com>
Jay <teguhwpurwanto@gmail.com> Jay <teguhwpurwanto@gmail.com>
@ -1100,6 +1111,7 @@ Jon Johnson <jonjohnson@google.com>
Jon Surrell <jon.surrell@gmail.com> Jon Surrell <jon.surrell@gmail.com>
Jon Wedaman <jweede@gmail.com> Jon Wedaman <jweede@gmail.com>
Jonas Dohse <jonas@dohse.ch> Jonas Dohse <jonas@dohse.ch>
Jonas Geiler <git@jonasgeiler.com>
Jonas Heinrich <Jonas@JonasHeinrich.com> Jonas Heinrich <Jonas@JonasHeinrich.com>
Jonas Pfenniger <jonas@pfenniger.name> Jonas Pfenniger <jonas@pfenniger.name>
Jonathan A. Schweder <jonathanschweder@gmail.com> Jonathan A. Schweder <jonathanschweder@gmail.com>
@ -1267,6 +1279,7 @@ Lakshan Perera <lakshan@laktek.com>
Lalatendu Mohanty <lmohanty@redhat.com> Lalatendu Mohanty <lmohanty@redhat.com>
Lance Chen <cyen0312@gmail.com> Lance Chen <cyen0312@gmail.com>
Lance Kinley <lkinley@loyaltymethods.com> Lance Kinley <lkinley@loyaltymethods.com>
Lars Andringa <l.s.andringa@rug.nl>
Lars Butler <Lars.Butler@gmail.com> Lars Butler <Lars.Butler@gmail.com>
Lars Kellogg-Stedman <lars@redhat.com> Lars Kellogg-Stedman <lars@redhat.com>
Lars R. Damerow <lars@pixar.com> Lars R. Damerow <lars@pixar.com>
@ -1673,6 +1686,7 @@ Patrick Böänziger <patrick.baenziger@bsi-software.com>
Patrick Devine <patrick.devine@docker.com> Patrick Devine <patrick.devine@docker.com>
Patrick Haas <patrickhaas@google.com> Patrick Haas <patrickhaas@google.com>
Patrick Hemmer <patrick.hemmer@gmail.com> Patrick Hemmer <patrick.hemmer@gmail.com>
Patrick St. laurent <patrick@saint-laurent.us>
Patrick Stapleton <github@gdi2290.com> Patrick Stapleton <github@gdi2290.com>
Patrik Cyvoct <patrik@ptrk.io> Patrik Cyvoct <patrik@ptrk.io>
pattichen <craftsbear@gmail.com> pattichen <craftsbear@gmail.com>
@ -1878,6 +1892,7 @@ Royce Remer <royceremer@gmail.com>
Rozhnov Alexandr <nox73@ya.ru> Rozhnov Alexandr <nox73@ya.ru>
Rudolph Gottesheim <r.gottesheim@loot.at> Rudolph Gottesheim <r.gottesheim@loot.at>
Rui Cao <ruicao@alauda.io> Rui Cao <ruicao@alauda.io>
Rui JingAn <quiterace@gmail.com>
Rui Lopes <rgl@ruilopes.com> Rui Lopes <rgl@ruilopes.com>
Ruilin Li <liruilin4@huawei.com> Ruilin Li <liruilin4@huawei.com>
Runshen Zhu <runshen.zhu@gmail.com> Runshen Zhu <runshen.zhu@gmail.com>
@ -2184,6 +2199,7 @@ Tomek Mańko <tomek.manko@railgun-solutions.com>
Tommaso Visconti <tommaso.visconti@gmail.com> Tommaso Visconti <tommaso.visconti@gmail.com>
Tomoya Tabuchi <t@tomoyat1.com> Tomoya Tabuchi <t@tomoyat1.com>
Tomáš Hrčka <thrcka@redhat.com> Tomáš Hrčka <thrcka@redhat.com>
Tomáš Virtus <nechtom@gmail.com>
tonic <tonicbupt@gmail.com> tonic <tonicbupt@gmail.com>
Tonny Xu <tonny.xu@gmail.com> Tonny Xu <tonny.xu@gmail.com>
Tony Abboud <tdabboud@hotmail.com> Tony Abboud <tdabboud@hotmail.com>
@ -2228,6 +2244,7 @@ Victor I. Wood <viw@t2am.com>
Victor Lyuboslavsky <victor@victoreda.com> Victor Lyuboslavsky <victor@victoreda.com>
Victor Marmol <vmarmol@google.com> Victor Marmol <vmarmol@google.com>
Victor Palma <palma.victor@gmail.com> Victor Palma <palma.victor@gmail.com>
Victor Toni <victor.toni@gmail.com>
Victor Vieux <victor.vieux@docker.com> Victor Vieux <victor.vieux@docker.com>
Victoria Bialas <victoria.bialas@docker.com> Victoria Bialas <victoria.bialas@docker.com>
Vijaya Kumar K <vijayak@caviumnetworks.com> Vijaya Kumar K <vijayak@caviumnetworks.com>
@ -2279,6 +2296,7 @@ Wassim Dhif <wassimdhif@gmail.com>
Wataru Ishida <ishida.wataru@lab.ntt.co.jp> Wataru Ishida <ishida.wataru@lab.ntt.co.jp>
Wayne Chang <wayne@neverfear.org> Wayne Chang <wayne@neverfear.org>
Wayne Song <wsong@docker.com> Wayne Song <wsong@docker.com>
weebney <weebney@gmail.com>
Weerasak Chongnguluam <singpor@gmail.com> Weerasak Chongnguluam <singpor@gmail.com>
Wei Fu <fuweid89@gmail.com> Wei Fu <fuweid89@gmail.com>
Wei Wu <wuwei4455@gmail.com> Wei Wu <wuwei4455@gmail.com>

View File

@ -3,7 +3,7 @@ package api // import "github.com/docker/docker/api"
// Common constants for daemon and client. // Common constants for daemon and client.
const ( const (
// DefaultVersion of the current REST API. // DefaultVersion of the current REST API.
DefaultVersion = "1.45" DefaultVersion = "1.46"
// MinSupportedAPIVersion is the minimum API version that can be supported // MinSupportedAPIVersion is the minimum API version that can be supported
// by the API server, specified as "major.minor". Note that the daemon // by the API server, specified as "major.minor". Note that the daemon

View File

@ -19,10 +19,10 @@ produces:
consumes: consumes:
- "application/json" - "application/json"
- "text/plain" - "text/plain"
basePath: "/v1.45" basePath: "/v1.46"
info: info:
title: "Docker Engine API" title: "Docker Engine API"
version: "1.45" version: "1.46"
x-logo: x-logo:
url: "https://docs.docker.com/assets/images/logo-docker-main.png" url: "https://docs.docker.com/assets/images/logo-docker-main.png"
description: | description: |
@ -55,8 +55,8 @@ info:
the URL is not supported by the daemon, a HTTP `400 Bad Request` error message the URL is not supported by the daemon, a HTTP `400 Bad Request` error message
is returned. is returned.
If you omit the version-prefix, the current version of the API (v1.45) is used. If you omit the version-prefix, the current version of the API (v1.46) is used.
For example, calling `/info` is the same as calling `/v1.45/info`. Using the For example, calling `/info` is the same as calling `/v1.46/info`. Using the
API without a version-prefix is deprecated and will be removed in a future release. API without a version-prefix is deprecated and will be removed in a future release.
Engine releases in the near future should support this version of the API, Engine releases in the near future should support this version of the API,
@ -442,6 +442,21 @@ definitions:
Mode: Mode:
description: "The permission mode for the tmpfs mount in an integer." description: "The permission mode for the tmpfs mount in an integer."
type: "integer" type: "integer"
Options:
description: |
The options to be passed to the tmpfs mount. An array of arrays.
Flag options should be provided as 1-length arrays. Other types
should be provided as as 2-length arrays, where the first item is
the key and the second the value.
type: "array"
items:
type: "array"
minItems: 1
maxItems: 2
items:
type: "string"
example:
[["noexec"]]
RestartPolicy: RestartPolicy:
description: | description: |
@ -1198,13 +1213,6 @@ definitions:
ContainerConfig: ContainerConfig:
description: | description: |
Configuration for a container that is portable between hosts. Configuration for a container that is portable between hosts.
When used as `ContainerConfig` field in an image, `ContainerConfig` is an
optional field containing the configuration of the container that was last
committed when creating the image.
Previous versions of Docker builder used this field to store build cache,
and it is not in active use anymore.
type: "object" type: "object"
properties: properties:
Hostname: Hostname:
@ -1363,6 +1371,289 @@ definitions:
type: "string" type: "string"
example: ["/bin/sh", "-c"] example: ["/bin/sh", "-c"]
ImageConfig:
description: |
Configuration of the image. These fields are used as defaults
when starting a container from the image.
type: "object"
properties:
Hostname:
description: |
The hostname to use for the container, as a valid RFC 1123 hostname.
<p><br /></p>
> **Deprecated**: this field is not part of the image specification and is
> always empty. It must not be used, and will be removed in API v1.47.
type: "string"
example: ""
Domainname:
description: |
The domain name to use for the container.
<p><br /></p>
> **Deprecated**: this field is not part of the image specification and is
> always empty. It must not be used, and will be removed in API v1.47.
type: "string"
example: ""
User:
description: "The user that commands are run as inside the container."
type: "string"
example: "web:web"
AttachStdin:
description: |
Whether to attach to `stdin`.
<p><br /></p>
> **Deprecated**: this field is not part of the image specification and is
> always false. It must not be used, and will be removed in API v1.47.
type: "boolean"
default: false
example: false
AttachStdout:
description: |
Whether to attach to `stdout`.
<p><br /></p>
> **Deprecated**: this field is not part of the image specification and is
> always false. It must not be used, and will be removed in API v1.47.
type: "boolean"
default: false
example: false
AttachStderr:
description: |
Whether to attach to `stderr`.
<p><br /></p>
> **Deprecated**: this field is not part of the image specification and is
> always false. It must not be used, and will be removed in API v1.47.
type: "boolean"
default: false
example: false
ExposedPorts:
description: |
An object mapping ports to an empty object in the form:
`{"<port>/<tcp|udp|sctp>": {}}`
type: "object"
x-nullable: true
additionalProperties:
type: "object"
enum:
- {}
default: {}
example: {
"80/tcp": {},
"443/tcp": {}
}
Tty:
description: |
Attach standard streams to a TTY, including `stdin` if it is not closed.
<p><br /></p>
> **Deprecated**: this field is not part of the image specification and is
> always false. It must not be used, and will be removed in API v1.47.
type: "boolean"
default: false
example: false
OpenStdin:
description: |
Open `stdin`
<p><br /></p>
> **Deprecated**: this field is not part of the image specification and is
> always false. It must not be used, and will be removed in API v1.47.
type: "boolean"
default: false
example: false
StdinOnce:
description: |
Close `stdin` after one attached client disconnects.
<p><br /></p>
> **Deprecated**: this field is not part of the image specification and is
> always false. It must not be used, and will be removed in API v1.47.
type: "boolean"
default: false
example: false
Env:
description: |
A list of environment variables to set inside the container in the
form `["VAR=value", ...]`. A variable without `=` is removed from the
environment, rather than to have an empty value.
type: "array"
items:
type: "string"
example:
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Cmd:
description: |
Command to run specified as a string or an array of strings.
type: "array"
items:
type: "string"
example: ["/bin/sh"]
Healthcheck:
$ref: "#/definitions/HealthConfig"
ArgsEscaped:
description: "Command is already escaped (Windows only)"
type: "boolean"
default: false
example: false
x-nullable: true
Image:
description: |
The name (or reference) of the image to use when creating the container,
or which was used when the container was created.
<p><br /></p>
> **Deprecated**: this field is not part of the image specification and is
> always empty. It must not be used, and will be removed in API v1.47.
type: "string"
default: ""
example: ""
Volumes:
description: |
An object mapping mount point paths inside the container to empty
objects.
type: "object"
additionalProperties:
type: "object"
enum:
- {}
default: {}
example:
"/app/data": {}
"/app/config": {}
WorkingDir:
description: "The working directory for commands to run in."
type: "string"
example: "/public/"
Entrypoint:
description: |
The entry point for the container as a string or an array of strings.
If the array consists of exactly one empty string (`[""]`) then the
entry point is reset to system default (i.e., the entry point used by
docker when there is no `ENTRYPOINT` instruction in the `Dockerfile`).
type: "array"
items:
type: "string"
example: []
NetworkDisabled:
description: |
Disable networking for the container.
<p><br /></p>
> **Deprecated**: this field is not part of the image specification and is
> always omitted. It must not be used, and will be removed in API v1.47.
type: "boolean"
default: false
example: false
x-nullable: true
MacAddress:
description: |
MAC address of the container.
<p><br /></p>
> **Deprecated**: this field is not part of the image specification and is
> always omitted. It must not be used, and will be removed in API v1.47.
type: "string"
default: ""
example: ""
x-nullable: true
OnBuild:
description: |
`ONBUILD` metadata that were defined in the image's `Dockerfile`.
type: "array"
x-nullable: true
items:
type: "string"
example: []
Labels:
description: "User-defined key/value metadata."
type: "object"
additionalProperties:
type: "string"
example:
com.example.some-label: "some-value"
com.example.some-other-label: "some-other-value"
StopSignal:
description: |
Signal to stop a container as a string or unsigned integer.
type: "string"
example: "SIGTERM"
x-nullable: true
StopTimeout:
description: |
Timeout to stop a container in seconds.
<p><br /></p>
> **Deprecated**: this field is not part of the image specification and is
> always omitted. It must not be used, and will be removed in API v1.47.
type: "integer"
default: 10
x-nullable: true
Shell:
description: |
Shell for when `RUN`, `CMD`, and `ENTRYPOINT` uses a shell.
type: "array"
x-nullable: true
items:
type: "string"
example: ["/bin/sh", "-c"]
# FIXME(thaJeztah): temporarily using a full example to remove some "omitempty" fields. Remove once the fields are removed.
example:
"Hostname": ""
"Domainname": ""
"User": "web:web"
"AttachStdin": false
"AttachStdout": false
"AttachStderr": false
"ExposedPorts": {
"80/tcp": {},
"443/tcp": {}
}
"Tty": false
"OpenStdin": false
"StdinOnce": false
"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"]
"Cmd": ["/bin/sh"]
"Healthcheck": {
"Test": ["string"],
"Interval": 0,
"Timeout": 0,
"Retries": 0,
"StartPeriod": 0,
"StartInterval": 0
}
"ArgsEscaped": true
"Image": ""
"Volumes": {
"/app/data": {},
"/app/config": {}
}
"WorkingDir": "/public/"
"Entrypoint": []
"OnBuild": []
"Labels": {
"com.example.some-label": "some-value",
"com.example.some-other-label": "some-other-value"
}
"StopSignal": "SIGTERM"
"Shell": ["/bin/sh", "-c"]
NetworkingConfig: NetworkingConfig:
description: | description: |
NetworkingConfig represents the container's networking configuration for NetworkingConfig represents the container's networking configuration for
@ -1758,21 +2049,6 @@ definitions:
format: "dateTime" format: "dateTime"
x-nullable: true x-nullable: true
example: "2022-02-04T21:20:12.497794809Z" example: "2022-02-04T21:20:12.497794809Z"
Container:
description: |
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"
example: "65974bc86f1770ae4bff79f651ebdbce166ae9aada632ee3fa9af3a264911735"
ContainerConfig:
description: |
**Deprecated**: this field is kept for backward compatibility, but
will be removed in API v1.45.
$ref: "#/definitions/ContainerConfig"
DockerVersion: DockerVersion:
description: | description: |
The version of Docker that was used to build the image. The version of Docker that was used to build the image.
@ -1780,7 +2056,7 @@ definitions:
Depending on how the image was created, this field may be empty. Depending on how the image was created, this field may be empty.
type: "string" type: "string"
x-nullable: false x-nullable: false
example: "20.10.7" example: "27.0.1"
Author: Author:
description: | description: |
Name of the author that was specified when committing the image, or as Name of the author that was specified when committing the image, or as
@ -1789,7 +2065,7 @@ definitions:
x-nullable: false x-nullable: false
example: "" example: ""
Config: Config:
$ref: "#/definitions/ContainerConfig" $ref: "#/definitions/ImageConfig"
Architecture: Architecture:
description: | description: |
Hardware CPU architecture that the image runs on. Hardware CPU architecture that the image runs on.
@ -1866,6 +2142,7 @@ definitions:
format: "dateTime" format: "dateTime"
example: "2022-02-28T14:40:02.623929178Z" example: "2022-02-28T14:40:02.623929178Z"
x-nullable: true x-nullable: true
ImageSummary: ImageSummary:
type: "object" type: "object"
x-go-name: "Summary" x-go-name: "Summary"
@ -2380,6 +2657,24 @@ definitions:
type: "string" type: "string"
example: "10.133.77.91" example: "10.133.77.91"
NetworkCreateResponse:
description: "OK response to NetworkCreate operation"
type: "object"
title: "NetworkCreateResponse"
x-go-name: "CreateResponse"
required: [Id, Warning]
properties:
Id:
description: "The ID of the created network."
type: "string"
x-nullable: false
example: "b5c4fc71e8022147cd25de22b22173de4e3b170134117172eb595cb91b4e7e5d"
Warning:
description: "Warnings encountered when creating the container"
type: "string"
x-nullable: false
example: ""
BuildInfo: BuildInfo:
type: "object" type: "object"
properties: properties:
@ -2579,6 +2874,17 @@ definitions:
example: example:
- "server_x" - "server_x"
- "server_y" - "server_y"
DriverOpts:
description: |
DriverOpts is a mapping of driver options and values. These options
are passed directly to the driver and are driver specific.
type: "object"
x-nullable: true
additionalProperties:
type: "string"
example:
com.example.some-label: "some-value"
com.example.some-other-label: "some-other-value"
# Operational data # Operational data
NetworkID: NetworkID:
@ -2622,17 +2928,6 @@ definitions:
type: "integer" type: "integer"
format: "int64" format: "int64"
example: 64 example: 64
DriverOpts:
description: |
DriverOpts is a mapping of driver options and values. These options
are passed directly to the driver and are driver specific.
type: "object"
x-nullable: true
additionalProperties:
type: "string"
example:
com.example.some-label: "some-value"
com.example.some-other-label: "some-other-value"
DNSNames: DNSNames:
description: | description: |
List of all DNS names an endpoint has on a specific network. This List of all DNS names an endpoint has on a specific network. This
@ -3804,6 +4099,13 @@ definitions:
but this is just provided for lookup/display purposes. The but this is just provided for lookup/display purposes. The
secret in the reference will be identified by its ID. secret in the reference will be identified by its ID.
type: "string" type: "string"
OomScoreAdj:
type: "integer"
format: "int64"
description: |
An integer value containing the score given to the container in
order to tune OOM killer preferences.
example: 0
Configs: Configs:
description: | description: |
Configs contains references to zero or more configs that will be Configs contains references to zero or more configs that will be
@ -4000,7 +4302,7 @@ definitions:
`node.platform.os` | Node operating system | `node.platform.os==windows` `node.platform.os` | Node operating system | `node.platform.os==windows`
`node.platform.arch` | Node architecture | `node.platform.arch==x86_64` `node.platform.arch` | Node architecture | `node.platform.arch==x86_64`
`node.labels` | User-defined node labels | `node.labels.security==high` `node.labels` | User-defined node labels | `node.labels.security==high`
`engine.labels` | Docker Engine's labels | `engine.labels.operatingsystem==ubuntu-14.04` `engine.labels` | Docker Engine's labels | `engine.labels.operatingsystem==ubuntu-24.04`
`engine.labels` apply to Docker Engine labels like operating system, `engine.labels` apply to Docker Engine labels like operating system,
drivers, etc. Swarm administrators add `node.labels` for operational drivers, etc. Swarm administrators add `node.labels` for operational
@ -4723,6 +5025,12 @@ definitions:
properties: properties:
NetworkMode: NetworkMode:
type: "string" type: "string"
Annotations:
description: "Arbitrary key-value metadata attached to container"
type: "object"
x-nullable: true
additionalProperties:
type: "string"
NetworkSettings: NetworkSettings:
description: "A summary of the container's network settings" description: "A summary of the container's network settings"
type: "object" type: "object"
@ -4991,7 +5299,7 @@ definitions:
Version of the component Version of the component
type: "string" type: "string"
x-nullable: false x-nullable: false
example: "19.03.12" example: "27.0.1"
Details: Details:
description: | description: |
Key/value pairs of strings with additional information about the Key/value pairs of strings with additional information about the
@ -5005,17 +5313,17 @@ definitions:
Version: Version:
description: "The version of the daemon" description: "The version of the daemon"
type: "string" type: "string"
example: "19.03.12" example: "27.0.1"
ApiVersion: ApiVersion:
description: | description: |
The default (and highest) API version that is supported by the daemon The default (and highest) API version that is supported by the daemon
type: "string" type: "string"
example: "1.40" example: "1.46"
MinAPIVersion: MinAPIVersion:
description: | description: |
The minimum API version that is supported by the daemon The minimum API version that is supported by the daemon
type: "string" type: "string"
example: "1.12" example: "1.24"
GitCommit: GitCommit:
description: | description: |
The Git commit of the source code that was used to build the daemon The Git commit of the source code that was used to build the daemon
@ -5026,7 +5334,7 @@ definitions:
The version Go used to compile the daemon, and the version of the Go The version Go used to compile the daemon, and the version of the Go
runtime in use. runtime in use.
type: "string" type: "string"
example: "go1.13.14" example: "go1.21.11"
Os: Os:
description: | description: |
The operating system that the daemon is running on ("linux" or "windows") The operating system that the daemon is running on ("linux" or "windows")
@ -5043,7 +5351,7 @@ definitions:
This field is omitted when empty. This field is omitted when empty.
type: "string" type: "string"
example: "4.19.76-linuxkit" example: "6.8.0-31-generic"
Experimental: Experimental:
description: | description: |
Indicates if the daemon is started with experimental features enabled. Indicates if the daemon is started with experimental features enabled.
@ -5249,13 +5557,13 @@ definitions:
information is queried from the <kbd>HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\</kbd> information is queried from the <kbd>HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\</kbd>
registry value, for example _"10.0 14393 (14393.1198.amd64fre.rs1_release_sec.170427-1353)"_. registry value, for example _"10.0 14393 (14393.1198.amd64fre.rs1_release_sec.170427-1353)"_.
type: "string" type: "string"
example: "4.9.38-moby" example: "6.8.0-31-generic"
OperatingSystem: OperatingSystem:
description: | description: |
Name of the host's operating system, for example: "Ubuntu 16.04.2 LTS" Name of the host's operating system, for example: "Ubuntu 24.04 LTS"
or "Windows Server 2016 Datacenter" or "Windows Server 2016 Datacenter"
type: "string" type: "string"
example: "Alpine Linux v3.5" example: "Ubuntu 24.04 LTS"
OSVersion: OSVersion:
description: | description: |
Version of the host's operating system Version of the host's operating system
@ -5266,7 +5574,7 @@ definitions:
> very existence, and the formatting of values, should not be considered > very existence, and the formatting of values, should not be considered
> stable, and may change without notice. > stable, and may change without notice.
type: "string" type: "string"
example: "16.04" example: "24.04"
OSType: OSType:
description: | description: |
Generic type of the operating system of the host, as returned by the Generic type of the operating system of the host, as returned by the
@ -5368,7 +5676,7 @@ definitions:
description: | description: |
Version string of the daemon. Version string of the daemon.
type: "string" type: "string"
example: "24.0.2" example: "27.0.1"
Runtimes: Runtimes:
description: | description: |
List of [OCI compliant](https://github.com/opencontainers/runtime-spec) List of [OCI compliant](https://github.com/opencontainers/runtime-spec)
@ -5520,6 +5828,58 @@ definitions:
example: example:
- "/etc/cdi" - "/etc/cdi"
- "/var/run/cdi" - "/var/run/cdi"
Containerd:
$ref: "#/definitions/ContainerdInfo"
x-nullable: true
ContainerdInfo:
description: |
Information for connecting to the containerd instance that is used by the daemon.
This is included for debugging purposes only.
type: "object"
properties:
Address:
description: "The address of the containerd socket."
type: "string"
example: "/run/containerd/containerd.sock"
Namespaces:
description: |
The namespaces that the daemon uses for running containers and
plugins in containerd. These namespaces can be configured in the
daemon configuration, and are considered to be used exclusively
by the daemon, Tampering with the containerd instance may cause
unexpected behavior.
As these namespaces are considered to be exclusively accessed
by the daemon, it is not recommended to change these values,
or to change them to a value that is used by other systems,
such as cri-containerd.
type: "object"
properties:
Containers:
description: |
The default containerd namespace used for containers managed
by the daemon.
The default namespace for containers is "moby", but will be
suffixed with the `<uid>.<gid>` of the remapped `root` if
user-namespaces are enabled and the containerd image-store
is used.
type: "string"
default: "moby"
example: "moby"
Plugins:
description: |
The default containerd namespace used for plugins managed by
the daemon.
The default namespace for plugins is "plugins.moby", but will be
suffixed with the `<uid>.<gid>` of the remapped `root` if
user-namespaces are enabled and the containerd image-store
is used.
type: "string"
default: "plugins.moby"
example: "plugins.moby"
# PluginsInfo is a temp struct holding Plugins name # PluginsInfo is a temp struct holding Plugins name
# registered with docker daemon. It is used by Info struct # registered with docker daemon. It is used by Info struct
@ -6372,6 +6732,8 @@ paths:
SizeRootFs: 0 SizeRootFs: 0
HostConfig: HostConfig:
NetworkMode: "default" NetworkMode: "default"
Annotations:
io.kubernetes.docker.type: "container"
NetworkSettings: NetworkSettings:
Networks: Networks:
bridge: bridge:
@ -6407,6 +6769,9 @@ paths:
SizeRootFs: 0 SizeRootFs: 0
HostConfig: HostConfig:
NetworkMode: "default" NetworkMode: "default"
Annotations:
io.kubernetes.docker.type: "container"
io.kubernetes.sandbox.id: "3befe639bed0fd6afdd65fd1fa84506756f59360ec4adc270b0fdac9be22b4d3"
NetworkSettings: NetworkSettings:
Networks: Networks:
bridge: bridge:
@ -6435,6 +6800,9 @@ paths:
SizeRootFs: 0 SizeRootFs: 0
HostConfig: HostConfig:
NetworkMode: "default" NetworkMode: "default"
Annotations:
io.kubernetes.image.id: "d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82"
io.kubernetes.image.name: "ubuntu:latest"
NetworkSettings: NetworkSettings:
Networks: Networks:
bridge: bridge:
@ -6463,6 +6831,8 @@ paths:
SizeRootFs: 0 SizeRootFs: 0
HostConfig: HostConfig:
NetworkMode: "default" NetworkMode: "default"
Annotations:
io.kubernetes.config.source: "api"
NetworkSettings: NetworkSettings:
Networks: Networks:
bridge: bridge:
@ -8740,6 +9110,11 @@ paths:
details. details.
type: "string" type: "string"
required: true required: true
- name: "platform"
in: "query"
description: "Select a platform-specific manifest to be pushed. OCI platform (JSON encoded)"
type: "string"
x-nullable: true
tags: ["Image"] tags: ["Image"]
/images/{name}/tag: /images/{name}/tag:
post: post:
@ -9188,7 +9563,7 @@ paths:
Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `exec_die`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, `update`, and `prune` Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `exec_die`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, `update`, and `prune`
Images report these events: `delete`, `import`, `load`, `pull`, `push`, `save`, `tag`, `untag`, and `prune` Images report these events: `create, `delete`, `import`, `load`, `pull`, `push`, `save`, `tag`, `untag`, and `prune`
Volumes report these events: `create`, `mount`, `unmount`, `destroy`, and `prune` Volumes report these events: `create`, `mount`, `unmount`, `destroy`, and `prune`
@ -10144,19 +10519,9 @@ paths:
- "application/json" - "application/json"
responses: responses:
201: 201:
description: "No error" description: "Network created successfully"
schema: schema:
type: "object" $ref: "#/definitions/NetworkCreateResponse"
title: "NetworkCreateResponse"
properties:
Id:
description: "The ID of the created network."
type: "string"
Warning:
type: "string"
example:
Id: "22be93d5babb089c5aab8dbc369042fad48ff791584ca2da2100db837a1c7c30"
Warning: ""
400: 400:
description: "bad parameter" description: "bad parameter"
schema: schema:
@ -10189,11 +10554,6 @@ paths:
description: "The network's name." description: "The network's name."
type: "string" type: "string"
example: "my_network" example: "my_network"
CheckDuplicate:
description: |
Deprecated: CheckDuplicate is now always enabled.
type: "boolean"
example: true
Driver: Driver:
description: "Name of the network driver plugin to use." description: "Name of the network driver plugin to use."
type: "string" type: "string"
@ -11366,6 +11726,7 @@ paths:
Mode: 384 Mode: 384
SecretID: "fpjqlhnwb19zds35k8wn80lq9" SecretID: "fpjqlhnwb19zds35k8wn80lq9"
SecretName: "example_org_domain_key" SecretName: "example_org_domain_key"
OomScoreAdj: 0
LogDriver: LogDriver:
Name: "json-file" Name: "json-file"
Options: Options:
@ -11518,6 +11879,7 @@ paths:
Image: "busybox" Image: "busybox"
Args: Args:
- "top" - "top"
OomScoreAdj: 0
Resources: Resources:
Limits: {} Limits: {}
Reservations: {} Reservations: {}

View File

@ -2,43 +2,15 @@ package types // import "github.com/docker/docker/api/types"
import ( import (
"bufio" "bufio"
"context"
"io" "io"
"net" "net"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/registry"
units "github.com/docker/go-units"
) )
// ContainerExecInspect holds information returned by exec inspect.
type ContainerExecInspect struct {
ExecID string `json:"ID"`
ContainerID string
Running bool
ExitCode int
Pid int
}
// CopyToContainerOptions holds information
// about files to copy into a container
type CopyToContainerOptions struct {
AllowOverwriteDirWithFile bool
CopyUIDGID bool
}
// EventsOptions holds parameters to filter events with.
type EventsOptions struct {
Since string
Until string
Filters filters.Args
}
// NetworkListOptions holds parameters to filter the list of networks with.
type NetworkListOptions struct {
Filters filters.Args
}
// NewHijackedResponse intializes a HijackedResponse type // NewHijackedResponse intializes a HijackedResponse type
func NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse { func NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse {
return HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType} return HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType}
@ -101,7 +73,7 @@ type ImageBuildOptions struct {
NetworkMode string NetworkMode string
ShmSize int64 ShmSize int64
Dockerfile string Dockerfile string
Ulimits []*units.Ulimit Ulimits []*container.Ulimit
// BuildArgs needs to be a *string instead of just a string so that // BuildArgs needs to be a *string instead of just a string so that
// we can tell the difference between "" (empty string) and no value // we can tell the difference between "" (empty string) and no value
// at all (nil). See the parsing of buildArgs in // at all (nil). See the parsing of buildArgs in
@ -122,7 +94,7 @@ type ImageBuildOptions struct {
Target string Target string
SessionID string SessionID string
Platform string Platform string
// Version specifies the version of the unerlying builder to use // Version specifies the version of the underlying builder to use
Version BuilderVersion Version BuilderVersion
// BuildID is an optional identifier that can be passed together with the // BuildID is an optional identifier that can be passed together with the
// build request. The same identifier can be used to gracefully cancel the // build request. The same identifier can be used to gracefully cancel the
@ -157,34 +129,13 @@ type ImageBuildResponse struct {
OSType string OSType string
} }
// ImageImportSource holds source information for ImageImport
type ImageImportSource struct {
Source io.Reader // Source is the data to send to the server to create this image from. You must set SourceName to "-" to leverage this.
SourceName string // SourceName is the name of the image to pull. Set to "-" to leverage the Source attribute.
}
// ImageLoadResponse returns information to the client about a load process.
type ImageLoadResponse struct {
// Body must be closed to avoid a resource leak
Body io.ReadCloser
JSON bool
}
// RequestPrivilegeFunc is a function interface that // RequestPrivilegeFunc is a function interface that
// clients can supply to retry operations after // clients can supply to retry operations after
// getting an authorization error. // getting an authorization error.
// This function returns the registry authentication // This function returns the registry authentication
// header value in base 64 format, or an error // header value in base 64 format, or an error
// if the privilege request fails. // if the privilege request fails.
type RequestPrivilegeFunc func() (string, error) type RequestPrivilegeFunc func(context.Context) (string, error)
// ImageSearchOptions holds parameters to search images with.
type ImageSearchOptions struct {
RegistryAuth string
PrivilegeFunc RequestPrivilegeFunc
Filters filters.Args
Limit int
}
// NodeListOptions holds parameters to list nodes with. // NodeListOptions holds parameters to list nodes with.
type NodeListOptions struct { type NodeListOptions struct {
@ -289,7 +240,7 @@ type PluginInstallOptions struct {
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
RemoteRef string // RemoteRef is the plugin name on the registry RemoteRef string // RemoteRef is the plugin name on the registry
PrivilegeFunc RequestPrivilegeFunc PrivilegeFunc RequestPrivilegeFunc
AcceptPermissionsFunc func(PluginPrivileges) (bool, error) AcceptPermissionsFunc func(context.Context, PluginPrivileges) (bool, error)
Args []string Args []string
} }

View File

@ -1,18 +0,0 @@
package types // import "github.com/docker/docker/api/types"
// ExecConfig is a small subset of the Config struct that holds the configuration
// for the exec feature of docker.
type ExecConfig struct {
User string // User that will run the command
Privileged bool // Is the container in privileged mode
Tty bool // Attach standard streams to a tty.
ConsoleSize *[2]uint `json:",omitempty"` // Initial console size [height, width]
AttachStdin bool // Attach the standard input, makes possible user interaction
AttachStderr bool // Attach the standard error
AttachStdout bool // Attach the standard output
Detach bool // Execute in detach mode
DetachKeys string // Escape keys for detach
Env []string // Environment variables
WorkingDir string // Working directory
Cmd []string // Execution commands and args
}

View File

@ -1,7 +1,6 @@
package container // import "github.com/docker/docker/api/types/container" package container // import "github.com/docker/docker/api/types/container"
import ( import (
"io"
"time" "time"
"github.com/docker/docker/api/types/strslice" "github.com/docker/docker/api/types/strslice"
@ -36,14 +35,6 @@ type StopOptions struct {
// HealthConfig holds configuration settings for the HEALTHCHECK feature. // HealthConfig holds configuration settings for the HEALTHCHECK feature.
type HealthConfig = dockerspec.HealthcheckConfig type HealthConfig = dockerspec.HealthcheckConfig
// ExecStartOptions holds the options to start container's exec.
type ExecStartOptions struct {
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
ConsoleSize *[2]uint `json:",omitempty"`
}
// Config contains the configuration data about a container. // Config contains the configuration data about a container.
// It should hold only portable information about the container. // It should hold only portable information about the container.
// Here, "portable" means "independent from the host we are running on". // Here, "portable" means "independent from the host we are running on".

View File

@ -0,0 +1,44 @@
package container
import (
"io"
"os"
"time"
)
// PruneReport contains the response for Engine API:
// POST "/containers/prune"
type PruneReport struct {
ContainersDeleted []string
SpaceReclaimed uint64
}
// PathStat is used to encode the header from
// GET "/containers/{name:.*}/archive"
// "Name" is the file or directory name.
type PathStat struct {
Name string `json:"name"`
Size int64 `json:"size"`
Mode os.FileMode `json:"mode"`
Mtime time.Time `json:"mtime"`
LinkTarget string `json:"linkTarget"`
}
// CopyToContainerOptions holds information
// about files to copy into a container
type CopyToContainerOptions struct {
AllowOverwriteDirWithFile bool
CopyUIDGID bool
}
// StatsResponseReader wraps an io.ReadCloser to read (a stream of) stats
// for a container, as produced by the GET "/stats" endpoint.
//
// The OSType field is set to the server's platform to allow
// platform-specific handling of the response.
//
// TODO(thaJeztah): remove this wrapper, and make OSType part of [StatsResponse].
type StatsResponseReader struct {
Body io.ReadCloser `json:"body"`
OSType string `json:"ostype"`
}

View File

@ -0,0 +1,13 @@
package container
import "github.com/docker/docker/api/types/network"
// CreateRequest is the request message sent to the server for container
// create calls. It is a config wrapper that holds the container [Config]
// (portable) and the corresponding [HostConfig] (non-portable) and
// [network.NetworkingConfig].
type CreateRequest struct {
*Config
HostConfig *HostConfig `json:"HostConfig,omitempty"`
NetworkingConfig *network.NetworkingConfig `json:"NetworkingConfig,omitempty"`
}

View File

@ -0,0 +1,43 @@
package container
// ExecOptions is a small subset of the Config struct that holds the configuration
// for the exec feature of docker.
type ExecOptions struct {
User string // User that will run the command
Privileged bool // Is the container in privileged mode
Tty bool // Attach standard streams to a tty.
ConsoleSize *[2]uint `json:",omitempty"` // Initial console size [height, width]
AttachStdin bool // Attach the standard input, makes possible user interaction
AttachStderr bool // Attach the standard error
AttachStdout bool // Attach the standard output
Detach bool // Execute in detach mode
DetachKeys string // Escape keys for detach
Env []string // Environment variables
WorkingDir string // Working directory
Cmd []string // Execution commands and args
}
// ExecStartOptions is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package
type ExecStartOptions struct {
// ExecStart will first check if it's detached
Detach bool
// Check if there's a tty
Tty bool
// Terminal size [height, width], unused if Tty == false
ConsoleSize *[2]uint `json:",omitempty"`
}
// ExecAttachOptions is a temp struct used by execAttach.
//
// TODO(thaJeztah): make this a separate type; ContainerExecAttach does not use the Detach option, and cannot run detached.
type ExecAttachOptions = ExecStartOptions
// ExecInspect holds information returned by exec inspect.
type ExecInspect struct {
ExecID string `json:"ID"`
ContainerID string
Running bool
ExitCode int
Pid int
}

View File

@ -360,6 +360,12 @@ type LogConfig struct {
Config map[string]string Config map[string]string
} }
// Ulimit is an alias for [units.Ulimit], which may be moving to a different
// location or become a local type. This alias is to help transitioning.
//
// Users are recommended to use this alias instead of using [units.Ulimit] directly.
type Ulimit = units.Ulimit
// Resources contains container's resources (cgroups config, ulimits...) // Resources contains container's resources (cgroups config, ulimits...)
type Resources struct { type Resources struct {
// Applicable to all platforms // Applicable to all platforms
@ -394,7 +400,7 @@ type Resources struct {
MemorySwappiness *int64 // Tuning container memory swappiness behaviour MemorySwappiness *int64 // Tuning container memory swappiness behaviour
OomKillDisable *bool // Whether to disable OOM Killer or not OomKillDisable *bool // Whether to disable OOM Killer or not
PidsLimit *int64 // Setting PIDs limit for a container; Set `0` or `-1` for unlimited, or `null` to not change. PidsLimit *int64 // Setting PIDs limit for a container; Set `0` or `-1` for unlimited, or `null` to not change.
Ulimits []*units.Ulimit // List of ulimits to be set in the container Ulimits []*Ulimit // List of ulimits to be set in the container
// Applicable to Windows // Applicable to Windows
CPUCount int64 `json:"CpuCount"` // CPU count CPUCount int64 `json:"CpuCount"` // CPU count

View File

@ -9,24 +9,6 @@ func (i Isolation) IsValid() bool {
return i.IsDefault() return i.IsDefault()
} }
// NetworkName returns the name of the network stack.
func (n NetworkMode) NetworkName() string {
if n.IsBridge() {
return network.NetworkBridge
} else if n.IsHost() {
return network.NetworkHost
} else if n.IsContainer() {
return "container"
} else if n.IsNone() {
return network.NetworkNone
} else if n.IsDefault() {
return network.NetworkDefault
} else if n.IsUserDefined() {
return n.UserDefined()
}
return ""
}
// IsBridge indicates whether container uses the bridge network stack // IsBridge indicates whether container uses the bridge network stack
func (n NetworkMode) IsBridge() bool { func (n NetworkMode) IsBridge() bool {
return n == network.NetworkBridge return n == network.NetworkBridge
@ -41,3 +23,23 @@ func (n NetworkMode) IsHost() bool {
func (n NetworkMode) IsUserDefined() bool { func (n NetworkMode) IsUserDefined() bool {
return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer() return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer()
} }
// NetworkName returns the name of the network stack.
func (n NetworkMode) NetworkName() string {
switch {
case n.IsDefault():
return network.NetworkDefault
case n.IsBridge():
return network.NetworkBridge
case n.IsHost():
return network.NetworkHost
case n.IsNone():
return network.NetworkNone
case n.IsContainer():
return "container"
case n.IsUserDefined():
return n.UserDefined()
default:
return ""
}
}

View File

@ -2,6 +2,11 @@ package container // import "github.com/docker/docker/api/types/container"
import "github.com/docker/docker/api/types/network" import "github.com/docker/docker/api/types/network"
// IsValid indicates if an isolation technology is valid
func (i Isolation) IsValid() bool {
return i.IsDefault() || i.IsHyperV() || i.IsProcess()
}
// IsBridge indicates whether container uses the bridge network stack // IsBridge indicates whether container uses the bridge network stack
// in windows it is given the name NAT // in windows it is given the name NAT
func (n NetworkMode) IsBridge() bool { func (n NetworkMode) IsBridge() bool {
@ -19,24 +24,24 @@ func (n NetworkMode) IsUserDefined() bool {
return !n.IsDefault() && !n.IsNone() && !n.IsBridge() && !n.IsContainer() return !n.IsDefault() && !n.IsNone() && !n.IsBridge() && !n.IsContainer()
} }
// IsValid indicates if an isolation technology is valid
func (i Isolation) IsValid() bool {
return i.IsDefault() || i.IsHyperV() || i.IsProcess()
}
// NetworkName returns the name of the network stack. // NetworkName returns the name of the network stack.
func (n NetworkMode) NetworkName() string { func (n NetworkMode) NetworkName() string {
if n.IsDefault() { switch {
case n.IsDefault():
return network.NetworkDefault return network.NetworkDefault
} else if n.IsBridge() { case n.IsBridge():
return network.NetworkNat return network.NetworkNat
} else if n.IsNone() { case n.IsHost():
// Windows currently doesn't support host network-mode, so
// this would currently never happen..
return network.NetworkHost
case n.IsNone():
return network.NetworkNone return network.NetworkNone
} else if n.IsContainer() { case n.IsContainer():
return "container" return "container"
} else if n.IsUserDefined() { case n.IsUserDefined():
return n.UserDefined() return n.UserDefined()
} default:
return "" return ""
}
} }

View File

@ -1,6 +1,4 @@
// Package types is used for API stability in the types and response to the package container
// consumers of the API stats endpoint.
package types // import "github.com/docker/docker/api/types"
import "time" import "time"
@ -169,8 +167,10 @@ type Stats struct {
MemoryStats MemoryStats `json:"memory_stats,omitempty"` MemoryStats MemoryStats `json:"memory_stats,omitempty"`
} }
// StatsJSON is newly used Networks // StatsResponse is newly used Networks.
type StatsJSON struct { //
// TODO(thaJeztah): unify with [Stats]. This wrapper was to account for pre-api v1.21 changes, see https://github.com/moby/moby/commit/d3379946ec96fb6163cb8c4517d7d5a067045801
type StatsResponse struct {
Stats Stats
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`

View File

@ -1,4 +1,5 @@
package events // import "github.com/docker/docker/api/types/events" package events // import "github.com/docker/docker/api/types/events"
import "github.com/docker/docker/api/types/filters"
// Type is used for event-types. // Type is used for event-types.
type Type string type Type string
@ -125,3 +126,10 @@ type Message struct {
Time int64 `json:"time,omitempty"` Time int64 `json:"time,omitempty"`
TimeNano int64 `json:"timeNano,omitempty"` TimeNano int64 `json:"timeNano,omitempty"`
} }
// ListOptions holds parameters to filter events with.
type ListOptions struct {
Since string
Until string
Filters filters.Args
}

View File

@ -1,9 +1,47 @@
package image package image
import "time" import (
"io"
"time"
)
// Metadata contains engine-local data about the image. // Metadata contains engine-local data about the image.
type Metadata struct { type Metadata struct {
// LastTagTime is the date and time at which the image was last tagged. // LastTagTime is the date and time at which the image was last tagged.
LastTagTime time.Time `json:",omitempty"` LastTagTime time.Time `json:",omitempty"`
} }
// PruneReport contains the response for Engine API:
// POST "/images/prune"
type PruneReport struct {
ImagesDeleted []DeleteResponse
SpaceReclaimed uint64
}
// LoadResponse returns information to the client about a load process.
//
// TODO(thaJeztah): remove this type, and just use an io.ReadCloser
//
// This type was added in https://github.com/moby/moby/pull/18878, related
// to https://github.com/moby/moby/issues/19177;
//
// Make docker load to output json when the response content type is json
// Swarm hijacks the response from docker load and returns JSON rather
// than plain text like the Engine does. This makes the API library to return
// information to figure that out.
//
// However the "load" endpoint unconditionally returns JSON;
// https://github.com/moby/moby/blob/7b9d2ef6e5518a3d3f3cc418459f8df786cfbbd1/api/server/router/image/image_routes.go#L248-L255
//
// PR https://github.com/moby/moby/pull/21959 made the response-type depend
// on whether "quiet" was set, but this logic got changed in a follow-up
// https://github.com/moby/moby/pull/25557, which made the JSON response-type
// unconditionally, but the output produced depend on whether"quiet" was set.
//
// We should deprecated the "quiet" option, as it's really a client
// responsibility.
type LoadResponse struct {
// Body must be closed to avoid a resource leak
Body io.ReadCloser
JSON bool
}

View File

@ -1,6 +1,18 @@
package image package image
import "github.com/docker/docker/api/types/filters" import (
"context"
"io"
"github.com/docker/docker/api/types/filters"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// ImportSource holds source information for ImageImport
type ImportSource struct {
Source io.Reader // Source is the data to send to the server to create this image from. You must set SourceName to "-" to leverage this.
SourceName string // SourceName is the name of the image to pull. Set to "-" to leverage the Source attribute.
}
// ImportOptions holds information to import images from the client host. // ImportOptions holds information to import images from the client host.
type ImportOptions struct { type ImportOptions struct {
@ -27,12 +39,28 @@ type PullOptions struct {
// privilege request fails. // privilege request fails.
// //
// Also see [github.com/docker/docker/api/types.RequestPrivilegeFunc]. // Also see [github.com/docker/docker/api/types.RequestPrivilegeFunc].
PrivilegeFunc func() (string, error) PrivilegeFunc func(context.Context) (string, error)
Platform string Platform string
} }
// PushOptions holds information to push images. // PushOptions holds information to push images.
type PushOptions PullOptions type PushOptions struct {
All bool
RegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry
// PrivilegeFunc is a function that clients can supply to retry operations
// after getting an authorization error. This function returns the registry
// authentication header value in base64 encoded format, or an error if the
// privilege request fails.
//
// Also see [github.com/docker/docker/api/types.RequestPrivilegeFunc].
PrivilegeFunc func(context.Context) (string, error)
// Platform is an optional field that selects a specific platform to push
// when the image is a multi-platform image.
// Using this will only push a single platform-specific manifest.
Platform *ocispec.Platform `json:",omitempty"`
}
// ListOptions holds parameters to list images with. // ListOptions holds parameters to list images with.
type ListOptions struct { type ListOptions struct {

View File

@ -119,7 +119,11 @@ type TmpfsOptions struct {
SizeBytes int64 `json:",omitempty"` SizeBytes int64 `json:",omitempty"`
// Mode of the tmpfs upon creation // Mode of the tmpfs upon creation
Mode os.FileMode `json:",omitempty"` Mode os.FileMode `json:",omitempty"`
// Options to be passed to the tmpfs mount. An array of arrays. Flag
// options should be provided as 1-length arrays. Other types should be
// provided as 2-length arrays, where the first item is the key and the
// second the value.
Options [][]string `json:",omitempty"`
// TODO(stevvooe): There are several more tmpfs flags, specified in the // TODO(stevvooe): There are several more tmpfs flags, specified in the
// daemon, that are accepted. Only the most basic are added for now. // daemon, that are accepted. Only the most basic are added for now.
// //

View File

@ -0,0 +1,19 @@
package network
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
// CreateResponse NetworkCreateResponse
//
// OK response to NetworkCreate operation
// swagger:model CreateResponse
type CreateResponse struct {
// The ID of the created network.
// Required: true
ID string `json:"Id"`
// Warnings encountered when creating the container
// Required: true
Warning string `json:"Warning"`
}

View File

@ -18,6 +18,7 @@ type EndpointSettings struct {
// Once the container is running, it becomes operational data (it may contain a // Once the container is running, it becomes operational data (it may contain a
// generated address). // generated address).
MacAddress string MacAddress string
DriverOpts map[string]string
// Operational data // Operational data
NetworkID string NetworkID string
EndpointID string EndpointID string
@ -27,7 +28,6 @@ type EndpointSettings struct {
IPv6Gateway string IPv6Gateway string
GlobalIPv6Address string GlobalIPv6Address string
GlobalIPv6PrefixLen int GlobalIPv6PrefixLen int
DriverOpts map[string]string
// DNSNames holds all the (non fully qualified) DNS names associated to this endpoint. First entry is used to // DNSNames holds all the (non fully qualified) DNS names associated to this endpoint. First entry is used to
// generate PTR records. // generate PTR records.
DNSNames []string DNSNames []string

View File

@ -1,6 +1,8 @@
package network // import "github.com/docker/docker/api/types/network" package network // import "github.com/docker/docker/api/types/network"
import ( import (
"time"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
) )
@ -17,6 +19,82 @@ const (
NetworkNat = "nat" NetworkNat = "nat"
) )
// CreateRequest is the request message sent to the server for network create call.
type CreateRequest struct {
CreateOptions
Name string // Name is the requested name of the network.
// Deprecated: CheckDuplicate is deprecated since API v1.44, but it defaults to true when sent by the client
// package to older daemons.
CheckDuplicate *bool `json:",omitempty"`
}
// CreateOptions holds options to create a network.
type CreateOptions struct {
Driver string // Driver is the driver-name used to create the network (e.g. `bridge`, `overlay`)
Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level).
EnableIPv6 *bool `json:",omitempty"` // EnableIPv6 represents whether to enable IPv6.
IPAM *IPAM // IPAM is the network's IP Address Management.
Internal bool // Internal represents if the network is used internal only.
Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
Ingress bool // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
ConfigOnly bool // ConfigOnly creates a config-only network. Config-only networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
ConfigFrom *ConfigReference // ConfigFrom specifies the source which will provide the configuration for this network. The specified network must be a config-only network; see [CreateOptions.ConfigOnly].
Options map[string]string // Options specifies the network-specific options to use for when creating the network.
Labels map[string]string // Labels holds metadata specific to the network being created.
}
// ListOptions holds parameters to filter the list of networks with.
type ListOptions struct {
Filters filters.Args
}
// InspectOptions holds parameters to inspect network.
type InspectOptions struct {
Scope string
Verbose bool
}
// ConnectOptions represents the data to be used to connect a container to the
// network.
type ConnectOptions struct {
Container string
EndpointConfig *EndpointSettings `json:",omitempty"`
}
// DisconnectOptions represents the data to be used to disconnect a container
// from the network.
type DisconnectOptions struct {
Container string
Force bool
}
// Inspect is the body of the "get network" http response message.
type Inspect struct {
Name string // Name is the name of the network
ID string `json:"Id"` // ID uniquely identifies a network on a single machine
Created time.Time // Created is the time the network created
Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level)
Driver string // Driver is the Driver name used to create the network (e.g. `bridge`, `overlay`)
EnableIPv6 bool // EnableIPv6 represents whether to enable IPv6
IPAM IPAM // IPAM is the network's IP Address Management
Internal bool // Internal represents if the network is used internal only
Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
Ingress bool // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
ConfigFrom ConfigReference // ConfigFrom specifies the source which will provide the configuration for this network.
ConfigOnly bool // ConfigOnly networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
Containers map[string]EndpointResource // Containers contains endpoints belonging to the network
Options map[string]string // Options holds the network specific options to use for when creating the network
Labels map[string]string // Labels holds metadata specific to the network being created
Peers []PeerInfo `json:",omitempty"` // List of peer nodes for an overlay network
Services map[string]ServiceInfo `json:",omitempty"`
}
// Summary is used as response when listing networks. It currently is an alias
// for [Inspect], but may diverge in the future, as not all information may
// be included when listing networks.
type Summary = Inspect
// Address represents an IP address // Address represents an IP address
type Address struct { type Address struct {
Addr string Addr string
@ -45,6 +123,16 @@ type ServiceInfo struct {
Tasks []Task Tasks []Task
} }
// EndpointResource contains network resources allocated and used for a
// container in a network.
type EndpointResource struct {
Name string
EndpointID string
MacAddress string
IPv4Address string
IPv6Address string
}
// NetworkingConfig represents the container's networking configuration for each of its interfaces // NetworkingConfig represents the container's networking configuration for each of its interfaces
// Carries the networking configs specified in the `docker run` and `docker network connect` commands // Carries the networking configs specified in the `docker run` and `docker network connect` commands
type NetworkingConfig struct { type NetworkingConfig struct {
@ -70,3 +158,9 @@ var acceptedFilters = map[string]bool{
func ValidateFilters(filter filters.Args) error { func ValidateFilters(filter filters.Args) error {
return filter.Validate(acceptedFilters) return filter.Validate(acceptedFilters)
} }
// PruneReport contains the response for Engine API:
// POST "/networks/prune"
type PruneReport struct {
NetworksDeleted []string
}

View File

@ -84,32 +84,6 @@ type IndexInfo struct {
Official bool Official bool
} }
// SearchResult describes a search result returned from a registry
type SearchResult struct {
// StarCount indicates the number of stars this repository has
StarCount int `json:"star_count"`
// IsOfficial is true if the result is from an official repository.
IsOfficial bool `json:"is_official"`
// Name is the name of the repository
Name string `json:"name"`
// IsAutomated indicates whether the result is automated.
//
// Deprecated: the "is_automated" field is deprecated and will always be "false".
IsAutomated bool `json:"is_automated"`
// Description is a textual description of the repository
Description string `json:"description"`
}
// SearchResults lists a collection search results returned from a registry
type SearchResults struct {
// Query contains the query string that generated the search results
Query string `json:"query"`
// NumResults indicates the number of results the query returned
NumResults int `json:"num_results"`
// Results is a slice containing the actual results for the search
Results []SearchResult `json:"results"`
}
// DistributionInspect describes the result obtained from contacting the // DistributionInspect describes the result obtained from contacting the
// registry to retrieve image metadata // registry to retrieve image metadata
type DistributionInspect struct { type DistributionInspect struct {

View File

@ -0,0 +1,47 @@
package registry
import (
"context"
"github.com/docker/docker/api/types/filters"
)
// SearchOptions holds parameters to search images with.
type SearchOptions struct {
RegistryAuth string
// PrivilegeFunc is a [types.RequestPrivilegeFunc] the client can
// supply to retry operations after getting an authorization error.
//
// It must return the registry authentication header value in base64
// format, or an error if the privilege request fails.
PrivilegeFunc func(context.Context) (string, error)
Filters filters.Args
Limit int
}
// SearchResult describes a search result returned from a registry
type SearchResult struct {
// StarCount indicates the number of stars this repository has
StarCount int `json:"star_count"`
// IsOfficial is true if the result is from an official repository.
IsOfficial bool `json:"is_official"`
// Name is the name of the repository
Name string `json:"name"`
// IsAutomated indicates whether the result is automated.
//
// Deprecated: the "is_automated" field is deprecated and will always be "false".
IsAutomated bool `json:"is_automated"`
// Description is a textual description of the repository
Description string `json:"description"`
}
// SearchResults lists a collection search results returned from a registry
type SearchResults struct {
// Query contains the query string that generated the search results
Query string `json:"query"`
// NumResults indicates the number of results the query returned
NumResults int `json:"num_results"`
// Results is a slice containing the actual results for the search
Results []SearchResult `json:"results"`
}

View File

@ -5,7 +5,6 @@ import (
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/mount"
"github.com/docker/go-units"
) )
// DNSConfig specifies DNS related configurations in resolver configuration file (resolv.conf) // DNSConfig specifies DNS related configurations in resolver configuration file (resolv.conf)
@ -115,5 +114,6 @@ type ContainerSpec struct {
Sysctls map[string]string `json:",omitempty"` Sysctls map[string]string `json:",omitempty"`
CapabilityAdd []string `json:",omitempty"` CapabilityAdd []string `json:",omitempty"`
CapabilityDrop []string `json:",omitempty"` CapabilityDrop []string `json:",omitempty"`
Ulimits []*units.Ulimit `json:",omitempty"` Ulimits []*container.Ulimit `json:",omitempty"`
OomScoreAdj int64 `json:",omitempty"`
} }

View File

@ -75,6 +75,8 @@ type Info struct {
DefaultAddressPools []NetworkAddressPool `json:",omitempty"` DefaultAddressPools []NetworkAddressPool `json:",omitempty"`
CDISpecDirs []string CDISpecDirs []string
Containerd *ContainerdInfo `json:",omitempty"`
// Legacy API fields for older API versions. // Legacy API fields for older API versions.
legacyFields legacyFields
@ -85,6 +87,43 @@ type Info struct {
Warnings []string Warnings []string
} }
// ContainerdInfo holds information about the containerd instance used by the daemon.
type ContainerdInfo struct {
// Address is the path to the containerd socket.
Address string `json:",omitempty"`
// Namespaces is the containerd namespaces used by the daemon.
Namespaces ContainerdNamespaces
}
// ContainerdNamespaces reflects the containerd namespaces used by the daemon.
//
// These namespaces can be configured in the daemon configuration, and are
// considered to be used exclusively by the daemon,
//
// As these namespaces are considered to be exclusively accessed
// by the daemon, it is not recommended to change these values,
// or to change them to a value that is used by other systems,
// such as cri-containerd.
type ContainerdNamespaces struct {
// Containers holds the default containerd namespace used for
// containers managed by the daemon.
//
// The default namespace for containers is "moby", but will be
// suffixed with the `<uid>.<gid>` of the remapped `root` if
// user-namespaces are enabled and the containerd image-store
// is used.
Containers string
// Plugins holds the default containerd namespace used for
// plugins managed by the daemon.
//
// The default namespace for plugins is "moby", but will be
// suffixed with the `<uid>.<gid>` of the remapped `root` if
// user-namespaces are enabled and the containerd image-store
// is used.
Plugins string
}
type legacyFields struct { type legacyFields struct {
ExecutionDriver string `json:",omitempty"` // Deprecated: deprecated since API v1.25, but returned for older versions. ExecutionDriver string `json:",omitempty"` // Deprecated: deprecated since API v1.25, but returned for older versions.
} }

View File

@ -1,8 +1,6 @@
package types // import "github.com/docker/docker/api/types" package types // import "github.com/docker/docker/api/types"
import ( import (
"io"
"os"
"time" "time"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
@ -156,35 +154,12 @@ type Container struct {
Status string Status string
HostConfig struct { HostConfig struct {
NetworkMode string `json:",omitempty"` NetworkMode string `json:",omitempty"`
Annotations map[string]string `json:",omitempty"`
} }
NetworkSettings *SummaryNetworkSettings NetworkSettings *SummaryNetworkSettings
Mounts []MountPoint Mounts []MountPoint
} }
// CopyConfig contains request body of Engine API:
// POST "/containers/"+containerID+"/copy"
type CopyConfig struct {
Resource string
}
// ContainerPathStat is used to encode the header from
// GET "/containers/{name:.*}/archive"
// "Name" is the file or directory name.
type ContainerPathStat struct {
Name string `json:"name"`
Size int64 `json:"size"`
Mode os.FileMode `json:"mode"`
Mtime time.Time `json:"mtime"`
LinkTarget string `json:"linkTarget"`
}
// ContainerStats contains response of Engine API:
// GET "/stats"
type ContainerStats struct {
Body io.ReadCloser `json:"body"`
OSType string `json:"ostype"`
}
// Ping contains response of Engine API: // Ping contains response of Engine API:
// GET "/_ping" // GET "/_ping"
type Ping struct { type Ping struct {
@ -230,17 +205,6 @@ type Version struct {
BuildTime string `json:",omitempty"` BuildTime string `json:",omitempty"`
} }
// ExecStartCheck is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package
type ExecStartCheck struct {
// ExecStart will first check if it's detached
Detach bool
// Check if there's a tty
Tty bool
// Terminal size [height, width], unused if Tty == false
ConsoleSize *[2]uint `json:",omitempty"`
}
// HealthcheckResult stores information about a single run of a healthcheck probe // HealthcheckResult stores information about a single run of a healthcheck probe
type HealthcheckResult struct { type HealthcheckResult struct {
Start time.Time // Start is the time this check started Start time.Time // Start is the time this check started
@ -423,84 +387,6 @@ type MountPoint struct {
Propagation mount.Propagation Propagation mount.Propagation
} }
// NetworkResource is the body of the "get network" http response message
type NetworkResource struct {
Name string // Name is the requested name of the network
ID string `json:"Id"` // ID uniquely identifies a network on a single machine
Created time.Time // Created is the time the network created
Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level)
Driver string // Driver is the Driver name used to create the network (e.g. `bridge`, `overlay`)
EnableIPv6 bool // EnableIPv6 represents whether to enable IPv6
IPAM network.IPAM // IPAM is the network's IP Address Management
Internal bool // Internal represents if the network is used internal only
Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
Ingress bool // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
ConfigFrom network.ConfigReference // ConfigFrom specifies the source which will provide the configuration for this network.
ConfigOnly bool // ConfigOnly networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
Containers map[string]EndpointResource // Containers contains endpoints belonging to the network
Options map[string]string // Options holds the network specific options to use for when creating the network
Labels map[string]string // Labels holds metadata specific to the network being created
Peers []network.PeerInfo `json:",omitempty"` // List of peer nodes for an overlay network
Services map[string]network.ServiceInfo `json:",omitempty"`
}
// EndpointResource contains network resources allocated and used for a container in a network
type EndpointResource struct {
Name string
EndpointID string
MacAddress string
IPv4Address string
IPv6Address string
}
// NetworkCreate is the expected body of the "create network" http request message
type NetworkCreate struct {
// Deprecated: CheckDuplicate is deprecated since API v1.44, but it defaults to true when sent by the client
// package to older daemons.
CheckDuplicate bool `json:",omitempty"`
Driver string // Driver is the driver-name used to create the network (e.g. `bridge`, `overlay`)
Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level).
EnableIPv6 bool // EnableIPv6 represents whether to enable IPv6.
IPAM *network.IPAM // IPAM is the network's IP Address Management.
Internal bool // Internal represents if the network is used internal only.
Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
Ingress bool // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
ConfigOnly bool // ConfigOnly creates a config-only network. Config-only networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
ConfigFrom *network.ConfigReference // ConfigFrom specifies the source which will provide the configuration for this network. The specified network must be a config-only network; see [NetworkCreate.ConfigOnly].
Options map[string]string // Options specifies the network-specific options to use for when creating the network.
Labels map[string]string // Labels holds metadata specific to the network being created.
}
// NetworkCreateRequest is the request message sent to the server for network create call.
type NetworkCreateRequest struct {
NetworkCreate
Name string // Name is the requested name of the network.
}
// NetworkCreateResponse is the response message sent by the server for network create call
type NetworkCreateResponse struct {
ID string `json:"Id"`
Warning string
}
// NetworkConnect represents the data to be used to connect a container to the network
type NetworkConnect struct {
Container string
EndpointConfig *network.EndpointSettings `json:",omitempty"`
}
// NetworkDisconnect represents the data to be used to disconnect a container from the network
type NetworkDisconnect struct {
Container string
Force bool
}
// NetworkInspectOptions holds parameters to inspect network
type NetworkInspectOptions struct {
Scope string
Verbose bool
}
// DiskUsageObject represents an object type used for disk usage query filtering. // DiskUsageObject represents an object type used for disk usage query filtering.
type DiskUsageObject string type DiskUsageObject string
@ -533,27 +419,6 @@ type DiskUsage struct {
BuilderSize int64 `json:",omitempty"` // Deprecated: deprecated in API 1.38, and no longer used since API 1.40. BuilderSize int64 `json:",omitempty"` // Deprecated: deprecated in API 1.38, and no longer used since API 1.40.
} }
// ContainersPruneReport contains the response for Engine API:
// POST "/containers/prune"
type ContainersPruneReport struct {
ContainersDeleted []string
SpaceReclaimed uint64
}
// VolumesPruneReport contains the response for Engine API:
// POST "/volumes/prune"
type VolumesPruneReport struct {
VolumesDeleted []string
SpaceReclaimed uint64
}
// ImagesPruneReport contains the response for Engine API:
// POST "/images/prune"
type ImagesPruneReport struct {
ImagesDeleted []image.DeleteResponse
SpaceReclaimed uint64
}
// BuildCachePruneReport contains the response for Engine API: // BuildCachePruneReport contains the response for Engine API:
// POST "/build/prune" // POST "/build/prune"
type BuildCachePruneReport struct { type BuildCachePruneReport struct {
@ -561,12 +426,6 @@ type BuildCachePruneReport struct {
SpaceReclaimed uint64 SpaceReclaimed uint64
} }
// NetworksPruneReport contains the response for Engine API:
// POST "/networks/prune"
type NetworksPruneReport struct {
NetworksDeleted []string
}
// SecretCreateResponse contains the information returned to a client // SecretCreateResponse contains the information returned to a client
// on the creation of a new secret. // on the creation of a new secret.
type SecretCreateResponse struct { type SecretCreateResponse struct {

View File

@ -1,35 +1,196 @@
package types package types
import ( import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/volume"
) )
// ImageImportOptions holds information to import images from the client host. // ImagesPruneReport contains the response for Engine API:
// POST "/images/prune"
// //
// Deprecated: use [image.ImportOptions]. // Deprecated: use [image.PruneReport].
type ImageImportOptions = image.ImportOptions type ImagesPruneReport = image.PruneReport
// ImageCreateOptions holds information to create images. // VolumesPruneReport contains the response for Engine API:
// POST "/volumes/prune".
// //
// Deprecated: use [image.CreateOptions]. // Deprecated: use [volume.PruneReport].
type ImageCreateOptions = image.CreateOptions type VolumesPruneReport = volume.PruneReport
// ImagePullOptions holds information to pull images. // NetworkCreateRequest is the request message sent to the server for network create call.
// //
// Deprecated: use [image.PullOptions]. // Deprecated: use [network.CreateRequest].
type ImagePullOptions = image.PullOptions type NetworkCreateRequest = network.CreateRequest
// ImagePushOptions holds information to push images. // NetworkCreate is the expected body of the "create network" http request message
// //
// Deprecated: use [image.PushOptions]. // Deprecated: use [network.CreateOptions].
type ImagePushOptions = image.PushOptions type NetworkCreate = network.CreateOptions
// ImageListOptions holds parameters to list images with. // NetworkListOptions holds parameters to filter the list of networks with.
// //
// Deprecated: use [image.ListOptions]. // Deprecated: use [network.ListOptions].
type ImageListOptions = image.ListOptions type NetworkListOptions = network.ListOptions
// ImageRemoveOptions holds parameters to remove images. // NetworkCreateResponse is the response message sent by the server for network create call.
// //
// Deprecated: use [image.RemoveOptions]. // Deprecated: use [network.CreateResponse].
type ImageRemoveOptions = image.RemoveOptions type NetworkCreateResponse = network.CreateResponse
// NetworkInspectOptions holds parameters to inspect network.
//
// Deprecated: use [network.InspectOptions].
type NetworkInspectOptions = network.InspectOptions
// NetworkConnect represents the data to be used to connect a container to the network
//
// Deprecated: use [network.ConnectOptions].
type NetworkConnect = network.ConnectOptions
// NetworkDisconnect represents the data to be used to disconnect a container from the network
//
// Deprecated: use [network.DisconnectOptions].
type NetworkDisconnect = network.DisconnectOptions
// EndpointResource contains network resources allocated and used for a container in a network.
//
// Deprecated: use [network.EndpointResource].
type EndpointResource = network.EndpointResource
// NetworkResource is the body of the "get network" http response message/
//
// Deprecated: use [network.Inspect] or [network.Summary] (for list operations).
type NetworkResource = network.Inspect
// NetworksPruneReport contains the response for Engine API:
// POST "/networks/prune"
//
// Deprecated: use [network.PruneReport].
type NetworksPruneReport = network.PruneReport
// ExecConfig is a small subset of the Config struct that holds the configuration
// for the exec feature of docker.
//
// Deprecated: use [container.ExecOptions].
type ExecConfig = container.ExecOptions
// ExecStartCheck is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package
//
// Deprecated: use [container.ExecStartOptions] or [container.ExecAttachOptions].
type ExecStartCheck = container.ExecStartOptions
// ContainerExecInspect holds information returned by exec inspect.
//
// Deprecated: use [container.ExecInspect].
type ContainerExecInspect = container.ExecInspect
// ContainersPruneReport contains the response for Engine API:
// POST "/containers/prune"
//
// Deprecated: use [container.PruneReport].
type ContainersPruneReport = container.PruneReport
// ContainerPathStat is used to encode the header from
// GET "/containers/{name:.*}/archive"
// "Name" is the file or directory name.
//
// Deprecated: use [container.PathStat].
type ContainerPathStat = container.PathStat
// CopyToContainerOptions holds information
// about files to copy into a container.
//
// Deprecated: use [container.CopyToContainerOptions],
type CopyToContainerOptions = container.CopyToContainerOptions
// ContainerStats contains response of Engine API:
// GET "/stats"
//
// Deprecated: use [container.StatsResponseReader].
type ContainerStats = container.StatsResponseReader
// ThrottlingData stores CPU throttling stats of one running container.
// Not used on Windows.
//
// Deprecated: use [container.ThrottlingData].
type ThrottlingData = container.ThrottlingData
// CPUUsage stores All CPU stats aggregated since container inception.
//
// Deprecated: use [container.CPUUsage].
type CPUUsage = container.CPUUsage
// CPUStats aggregates and wraps all CPU related info of container
//
// Deprecated: use [container.CPUStats].
type CPUStats = container.CPUStats
// MemoryStats aggregates all memory stats since container inception on Linux.
// Windows returns stats for commit and private working set only.
//
// Deprecated: use [container.MemoryStats].
type MemoryStats = container.MemoryStats
// BlkioStatEntry is one small entity to store a piece of Blkio stats
// Not used on Windows.
//
// Deprecated: use [container.BlkioStatEntry].
type BlkioStatEntry = container.BlkioStatEntry
// BlkioStats stores All IO service stats for data read and write.
// This is a Linux specific structure as the differences between expressing
// block I/O on Windows and Linux are sufficiently significant to make
// little sense attempting to morph into a combined structure.
//
// Deprecated: use [container.BlkioStats].
type BlkioStats = container.BlkioStats
// StorageStats is the disk I/O stats for read/write on Windows.
//
// Deprecated: use [container.StorageStats].
type StorageStats = container.StorageStats
// NetworkStats aggregates the network stats of one container
//
// Deprecated: use [container.NetworkStats].
type NetworkStats = container.NetworkStats
// PidsStats contains the stats of a container's pids
//
// Deprecated: use [container.PidsStats].
type PidsStats = container.PidsStats
// Stats is Ultimate struct aggregating all types of stats of one container
//
// Deprecated: use [container.Stats].
type Stats = container.Stats
// StatsJSON is newly used Networks
//
// Deprecated: use [container.StatsResponse].
type StatsJSON = container.StatsResponse
// EventsOptions holds parameters to filter events with.
//
// Deprecated: use [events.ListOptions].
type EventsOptions = events.ListOptions
// ImageSearchOptions holds parameters to search images with.
//
// Deprecated: use [registry.SearchOptions].
type ImageSearchOptions = registry.SearchOptions
// ImageImportSource holds source information for ImageImport
//
// Deprecated: use [image.ImportSource].
type ImageImportSource image.ImportSource
// ImageLoadResponse returns information to the client about a load process.
//
// Deprecated: use [image.LoadResponse].
type ImageLoadResponse = image.LoadResponse

View File

@ -6,3 +6,10 @@ import "github.com/docker/docker/api/types/filters"
type ListOptions struct { type ListOptions struct {
Filters filters.Args Filters filters.Args
} }
// PruneReport contains the response for Engine API:
// POST "/volumes/prune"
type PruneReport struct {
VolumesDeleted []string
SpaceReclaimed uint64
}

View File

@ -49,6 +49,8 @@ import (
"net/url" "net/url"
"path" "path"
"strings" "strings"
"sync"
"sync/atomic"
"time" "time"
"github.com/docker/docker/api" "github.com/docker/docker/api"
@ -131,7 +133,10 @@ type Client struct {
negotiateVersion bool negotiateVersion bool
// negotiated indicates that API version negotiation took place // negotiated indicates that API version negotiation took place
negotiated bool negotiated atomic.Bool
// negotiateLock is used to single-flight the version negotiation process
negotiateLock sync.Mutex
tp trace.TracerProvider tp trace.TracerProvider
@ -266,7 +271,16 @@ func (cli *Client) Close() error {
// be negotiated when making the actual requests, and for which cases // be negotiated when making the actual requests, and for which cases
// we cannot do the negotiation lazily. // we cannot do the negotiation lazily.
func (cli *Client) checkVersion(ctx context.Context) error { func (cli *Client) checkVersion(ctx context.Context) error {
if !cli.manualOverride && cli.negotiateVersion && !cli.negotiated { if !cli.manualOverride && cli.negotiateVersion && !cli.negotiated.Load() {
// Ensure exclusive write access to version and negotiated fields
cli.negotiateLock.Lock()
defer cli.negotiateLock.Unlock()
// May have been set during last execution of critical zone
if cli.negotiated.Load() {
return nil
}
ping, err := cli.Ping(ctx) ping, err := cli.Ping(ctx)
if err != nil { if err != nil {
return err return err
@ -312,6 +326,10 @@ func (cli *Client) ClientVersion() string {
// added (1.24). // added (1.24).
func (cli *Client) NegotiateAPIVersion(ctx context.Context) { func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
if !cli.manualOverride { if !cli.manualOverride {
// Avoid concurrent modification of version-related fields
cli.negotiateLock.Lock()
defer cli.negotiateLock.Unlock()
ping, err := cli.Ping(ctx) ping, err := cli.Ping(ctx)
if err != nil { if err != nil {
// FIXME(thaJeztah): Ping returns an error when failing to connect to the API; we should not swallow the error here, and instead returning it. // FIXME(thaJeztah): Ping returns an error when failing to connect to the API; we should not swallow the error here, and instead returning it.
@ -336,6 +354,10 @@ func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
// added (1.24). // added (1.24).
func (cli *Client) NegotiateAPIVersionPing(pingResponse types.Ping) { func (cli *Client) NegotiateAPIVersionPing(pingResponse types.Ping) {
if !cli.manualOverride { if !cli.manualOverride {
// Avoid concurrent modification of version-related fields
cli.negotiateLock.Lock()
defer cli.negotiateLock.Unlock()
cli.negotiateAPIVersionPing(pingResponse) cli.negotiateAPIVersionPing(pingResponse)
} }
} }
@ -361,7 +383,7 @@ func (cli *Client) negotiateAPIVersionPing(pingResponse types.Ping) {
// Store the results, so that automatic API version negotiation (if enabled) // Store the results, so that automatic API version negotiation (if enabled)
// won't be performed on the next request. // won't be performed on the next request.
if cli.negotiateVersion { if cli.negotiateVersion {
cli.negotiated = true cli.negotiated.Store(true)
} }
} }

View File

@ -11,11 +11,11 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container"
) )
// ContainerStatPath returns stat information about a path inside the container filesystem. // ContainerStatPath returns stat information about a path inside the container filesystem.
func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path string) (types.ContainerPathStat, error) { func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path string) (container.PathStat, error) {
query := url.Values{} query := url.Values{}
query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API. query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API.
@ -23,14 +23,14 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri
response, err := cli.head(ctx, urlStr, query, nil) response, err := cli.head(ctx, urlStr, query, nil)
defer ensureReaderClosed(response) defer ensureReaderClosed(response)
if err != nil { if err != nil {
return types.ContainerPathStat{}, err return container.PathStat{}, err
} }
return getContainerPathStatFromHeader(response.header) return getContainerPathStatFromHeader(response.header)
} }
// CopyToContainer copies content into the container filesystem. // CopyToContainer copies content into the container filesystem.
// Note that `content` must be a Reader for a TAR archive // Note that `content` must be a Reader for a TAR archive
func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options types.CopyToContainerOptions) error { func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options container.CopyToContainerOptions) error {
query := url.Values{} query := url.Values{}
query.Set("path", filepath.ToSlash(dstPath)) // Normalize the paths used in the API. query.Set("path", filepath.ToSlash(dstPath)) // Normalize the paths used in the API.
// Do not allow for an existing directory to be overwritten by a non-directory and vice versa. // Do not allow for an existing directory to be overwritten by a non-directory and vice versa.
@ -55,14 +55,14 @@ func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath str
// CopyFromContainer gets the content from the container and returns it as a Reader // CopyFromContainer gets the content from the container and returns it as a Reader
// for a TAR archive to manipulate it in the host. It's up to the caller to close the reader. // for a TAR archive to manipulate it in the host. It's up to the caller to close the reader.
func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) { func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, container.PathStat, error) {
query := make(url.Values, 1) query := make(url.Values, 1)
query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API. query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API.
apiPath := "/containers/" + containerID + "/archive" apiPath := "/containers/" + containerID + "/archive"
response, err := cli.get(ctx, apiPath, query, nil) response, err := cli.get(ctx, apiPath, query, nil)
if err != nil { if err != nil {
return nil, types.ContainerPathStat{}, err return nil, container.PathStat{}, err
} }
// In order to get the copy behavior right, we need to know information // In order to get the copy behavior right, we need to know information
@ -78,8 +78,8 @@ func (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath s
return response.body, stat, err return response.body, stat, err
} }
func getContainerPathStatFromHeader(header http.Header) (types.ContainerPathStat, error) { func getContainerPathStatFromHeader(header http.Header) (container.PathStat, error) {
var stat types.ContainerPathStat var stat container.PathStat
encodedStat := header.Get("X-Docker-Container-Path-Stat") encodedStat := header.Get("X-Docker-Container-Path-Stat")
statDecoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(encodedStat)) statDecoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(encodedStat))

View File

@ -6,11 +6,12 @@ import (
"net/http" "net/http"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
) )
// ContainerExecCreate creates a new exec configuration to run an exec process. // ContainerExecCreate creates a new exec configuration to run an exec process.
func (cli *Client) ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error) { func (cli *Client) ContainerExecCreate(ctx context.Context, container string, options container.ExecOptions) (types.IDResponse, error) {
var response types.IDResponse var response types.IDResponse
// Make sure we negotiated (if the client is configured to do so), // Make sure we negotiated (if the client is configured to do so),
@ -22,14 +23,14 @@ func (cli *Client) ContainerExecCreate(ctx context.Context, container string, co
return response, err return response, err
} }
if err := cli.NewVersionError(ctx, "1.25", "env"); len(config.Env) != 0 && err != nil { if err := cli.NewVersionError(ctx, "1.25", "env"); len(options.Env) != 0 && err != nil {
return response, err return response, err
} }
if versions.LessThan(cli.ClientVersion(), "1.42") { if versions.LessThan(cli.ClientVersion(), "1.42") {
config.ConsoleSize = nil options.ConsoleSize = nil
} }
resp, err := cli.post(ctx, "/containers/"+container+"/exec", nil, config, nil) resp, err := cli.post(ctx, "/containers/"+container+"/exec", nil, options, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {
return response, err return response, err
@ -39,7 +40,7 @@ func (cli *Client) ContainerExecCreate(ctx context.Context, container string, co
} }
// ContainerExecStart starts an exec process already created in the docker host. // ContainerExecStart starts an exec process already created in the docker host.
func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error { func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config container.ExecStartOptions) error {
if versions.LessThan(cli.ClientVersion(), "1.42") { if versions.LessThan(cli.ClientVersion(), "1.42") {
config.ConsoleSize = nil config.ConsoleSize = nil
} }
@ -52,7 +53,7 @@ func (cli *Client) ContainerExecStart(ctx context.Context, execID string, config
// It returns a types.HijackedConnection with the hijacked connection // It returns a types.HijackedConnection with the hijacked connection
// and the a reader to get output. It's up to the called to close // and the a reader to get output. It's up to the called to close
// the hijacked connection by calling types.HijackedResponse.Close. // the hijacked connection by calling types.HijackedResponse.Close.
func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error) { func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config container.ExecAttachOptions) (types.HijackedResponse, error) {
if versions.LessThan(cli.ClientVersion(), "1.42") { if versions.LessThan(cli.ClientVersion(), "1.42") {
config.ConsoleSize = nil config.ConsoleSize = nil
} }
@ -62,8 +63,8 @@ func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, confi
} }
// ContainerExecInspect returns information about a specific exec process on the docker host. // ContainerExecInspect returns information about a specific exec process on the docker host.
func (cli *Client) ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) { func (cli *Client) ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error) {
var response types.ContainerExecInspect var response container.ExecInspect
resp, err := cli.get(ctx, "/exec/"+execID+"/json", nil, nil) resp, err := cli.get(ctx, "/exec/"+execID+"/json", nil, nil)
if err != nil { if err != nil {
return response, err return response, err

View File

@ -5,13 +5,13 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
) )
// ContainersPrune requests the daemon to delete unused data // ContainersPrune requests the daemon to delete unused data
func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) { func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) {
var report types.ContainersPruneReport var report container.PruneReport
if err := cli.NewVersionError(ctx, "1.25", "container prune"); err != nil { if err := cli.NewVersionError(ctx, "1.25", "container prune"); err != nil {
return report, err return report, err

View File

@ -4,12 +4,12 @@ import (
"context" "context"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container"
) )
// ContainerStats returns near realtime stats for a given container. // ContainerStats returns near realtime stats for a given container.
// It's up to the caller to close the io.ReadCloser returned. // It's up to the caller to close the io.ReadCloser returned.
func (cli *Client) ContainerStats(ctx context.Context, containerID string, stream bool) (types.ContainerStats, error) { func (cli *Client) ContainerStats(ctx context.Context, containerID string, stream bool) (container.StatsResponseReader, error) {
query := url.Values{} query := url.Values{}
query.Set("stream", "0") query.Set("stream", "0")
if stream { if stream {
@ -18,10 +18,10 @@ func (cli *Client) ContainerStats(ctx context.Context, containerID string, strea
resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil) resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil)
if err != nil { if err != nil {
return types.ContainerStats{}, err return container.StatsResponseReader{}, err
} }
return types.ContainerStats{ return container.StatsResponseReader{
Body: resp.body, Body: resp.body,
OSType: getDockerOS(resp.header.Get("Server")), OSType: getDockerOS(resp.header.Get("Server")),
}, nil }, nil
@ -29,17 +29,17 @@ func (cli *Client) ContainerStats(ctx context.Context, containerID string, strea
// ContainerStatsOneShot gets a single stat entry from a container. // ContainerStatsOneShot gets a single stat entry from a container.
// It differs from `ContainerStats` in that the API should not wait to prime the stats // It differs from `ContainerStats` in that the API should not wait to prime the stats
func (cli *Client) ContainerStatsOneShot(ctx context.Context, containerID string) (types.ContainerStats, error) { func (cli *Client) ContainerStatsOneShot(ctx context.Context, containerID string) (container.StatsResponseReader, error) {
query := url.Values{} query := url.Values{}
query.Set("stream", "0") query.Set("stream", "0")
query.Set("one-shot", "1") query.Set("one-shot", "1")
resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil) resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil)
if err != nil { if err != nil {
return types.ContainerStats{}, err return container.StatsResponseReader{}, err
} }
return types.ContainerStats{ return container.StatsResponseReader{
Body: resp.body, Body: resp.body,
OSType: getDockerOS(resp.header.Get("Server")), OSType: getDockerOS(resp.header.Get("Server")),
}, nil }, nil

View File

@ -6,7 +6,6 @@ import (
"net/url" "net/url"
"time" "time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
timetypes "github.com/docker/docker/api/types/time" timetypes "github.com/docker/docker/api/types/time"
@ -16,7 +15,7 @@ import (
// by cancelling the context. Once the stream has been completely read an io.EOF error will // by cancelling the context. Once the stream has been completely read an io.EOF error will
// be sent over the error channel. If an error is sent all processing will be stopped. It's up // be sent over the error channel. If an error is sent all processing will be stopped. It's up
// to the caller to reopen the stream in the event of an error by reinvoking this method. // to the caller to reopen the stream in the event of an error by reinvoking this method.
func (cli *Client) Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error) { func (cli *Client) Events(ctx context.Context, options events.ListOptions) (<-chan events.Message, <-chan error) {
messages := make(chan events.Message) messages := make(chan events.Message)
errs := make(chan error, 1) errs := make(chan error, 1)
@ -68,7 +67,7 @@ func (cli *Client) Events(ctx context.Context, options types.EventsOptions) (<-c
return messages, errs return messages, errs
} }
func buildEventsQueryParams(cliVersion string, options types.EventsOptions) (url.Values, error) { func buildEventsQueryParams(cliVersion string, options events.ListOptions) (url.Values, error) {
query := url.Values{} query := url.Values{}
ref := time.Now() ref := time.Now()

View File

@ -7,13 +7,12 @@ import (
"strings" "strings"
"github.com/distribution/reference" "github.com/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
) )
// ImageImport creates a new image based on the source options. // ImageImport creates a new image based on the source options.
// It returns the JSON content in the response body. // It returns the JSON content in the response body.
func (cli *Client) ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) { func (cli *Client) ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) {
if ref != "" { if ref != "" {
// Check if the given image name can be resolved // Check if the given image name can be resolved
if _, err := reference.ParseNormalizedNamed(ref); err != nil { if _, err := reference.ParseNormalizedNamed(ref); err != nil {

View File

@ -6,13 +6,13 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/image"
) )
// ImageLoad loads an image in the docker host from the client host. // ImageLoad loads an image in the docker host from the client host.
// It's up to the caller to close the io.ReadCloser in the // It's up to the caller to close the io.ReadCloser in the
// ImageLoadResponse returned by this function. // ImageLoadResponse returned by this function.
func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error) { func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (image.LoadResponse, error) {
v := url.Values{} v := url.Values{}
v.Set("quiet", "0") v.Set("quiet", "0")
if quiet { if quiet {
@ -22,9 +22,9 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (
"Content-Type": {"application/x-tar"}, "Content-Type": {"application/x-tar"},
}) })
if err != nil { if err != nil {
return types.ImageLoadResponse{}, err return image.LoadResponse{}, err
} }
return types.ImageLoadResponse{ return image.LoadResponse{
Body: resp.body, Body: resp.body,
JSON: resp.header.Get("Content-Type") == "application/json", JSON: resp.header.Get("Content-Type") == "application/json",
}, nil }, nil

View File

@ -5,13 +5,13 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
) )
// ImagesPrune requests the daemon to delete unused data // ImagesPrune requests the daemon to delete unused data
func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (types.ImagesPruneReport, error) { func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (image.PruneReport, error) {
var report types.ImagesPruneReport var report image.PruneReport
if err := cli.NewVersionError(ctx, "1.25", "image prune"); err != nil { if err := cli.NewVersionError(ctx, "1.25", "image prune"); err != nil {
return report, err return report, err

View File

@ -36,7 +36,7 @@ func (cli *Client) ImagePull(ctx context.Context, refStr string, options image.P
resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth) resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth)
if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
newAuthHeader, privilegeErr := options.PrivilegeFunc() newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx)
if privilegeErr != nil { if privilegeErr != nil {
return nil, privilegeErr return nil, privilegeErr
} }

View File

@ -2,7 +2,9 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"encoding/json"
"errors" "errors"
"fmt"
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
@ -36,9 +38,23 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options image.Pu
} }
} }
if options.Platform != nil {
if err := cli.NewVersionError(ctx, "1.46", "platform"); err != nil {
return nil, err
}
p := *options.Platform
pJson, err := json.Marshal(p)
if err != nil {
return nil, fmt.Errorf("invalid platform: %v", err)
}
query.Set("platform", string(pJson))
}
resp, err := cli.tryImagePush(ctx, name, query, options.RegistryAuth) resp, err := cli.tryImagePush(ctx, name, query, options.RegistryAuth)
if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
newAuthHeader, privilegeErr := options.PrivilegeFunc() newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx)
if privilegeErr != nil { if privilegeErr != nil {
return nil, privilegeErr return nil, privilegeErr
} }

View File

@ -7,7 +7,6 @@ import (
"net/url" "net/url"
"strconv" "strconv"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/errdefs" "github.com/docker/docker/errdefs"
@ -15,7 +14,7 @@ import (
// ImageSearch makes the docker host search by a term in a remote registry. // ImageSearch makes the docker host search by a term in a remote registry.
// The list of results is not sorted in any fashion. // The list of results is not sorted in any fashion.
func (cli *Client) ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) { func (cli *Client) ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error) {
var results []registry.SearchResult var results []registry.SearchResult
query := url.Values{} query := url.Values{}
query.Set("term", term) query.Set("term", term)
@ -34,7 +33,7 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options types.I
resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth) resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
newAuthHeader, privilegeErr := options.PrivilegeFunc() newAuthHeader, privilegeErr := options.PrivilegeFunc(ctx)
if privilegeErr != nil { if privilegeErr != nil {
return results, privilegeErr return results, privilegeErr
} }

View File

@ -50,11 +50,11 @@ type ContainerAPIClient interface {
ContainerCommit(ctx context.Context, container string, options container.CommitOptions) (types.IDResponse, error) ContainerCommit(ctx context.Context, container string, options container.CommitOptions) (types.IDResponse, error)
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error)
ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error) ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error)
ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error) ContainerExecAttach(ctx context.Context, execID string, options container.ExecAttachOptions) (types.HijackedResponse, error)
ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error) ContainerExecCreate(ctx context.Context, container string, options container.ExecOptions) (types.IDResponse, error)
ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error)
ContainerExecResize(ctx context.Context, execID string, options container.ResizeOptions) error ContainerExecResize(ctx context.Context, execID string, options container.ResizeOptions) error
ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error ContainerExecStart(ctx context.Context, execID string, options container.ExecStartOptions) error
ContainerExport(ctx context.Context, container string) (io.ReadCloser, error) ContainerExport(ctx context.Context, container string) (io.ReadCloser, error)
ContainerInspect(ctx context.Context, container string) (types.ContainerJSON, error) ContainerInspect(ctx context.Context, container string) (types.ContainerJSON, error)
ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (types.ContainerJSON, []byte, error) ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (types.ContainerJSON, []byte, error)
@ -66,18 +66,18 @@ type ContainerAPIClient interface {
ContainerRename(ctx context.Context, container, newContainerName string) error ContainerRename(ctx context.Context, container, newContainerName string) error
ContainerResize(ctx context.Context, container string, options container.ResizeOptions) error ContainerResize(ctx context.Context, container string, options container.ResizeOptions) error
ContainerRestart(ctx context.Context, container string, options container.StopOptions) error ContainerRestart(ctx context.Context, container string, options container.StopOptions) error
ContainerStatPath(ctx context.Context, container, path string) (types.ContainerPathStat, error) ContainerStatPath(ctx context.Context, container, path string) (container.PathStat, error)
ContainerStats(ctx context.Context, container string, stream bool) (types.ContainerStats, error) ContainerStats(ctx context.Context, container string, stream bool) (container.StatsResponseReader, error)
ContainerStatsOneShot(ctx context.Context, container string) (types.ContainerStats, error) ContainerStatsOneShot(ctx context.Context, container string) (container.StatsResponseReader, error)
ContainerStart(ctx context.Context, container string, options container.StartOptions) error ContainerStart(ctx context.Context, container string, options container.StartOptions) error
ContainerStop(ctx context.Context, container string, options container.StopOptions) error ContainerStop(ctx context.Context, container string, options container.StopOptions) error
ContainerTop(ctx context.Context, container string, arguments []string) (container.ContainerTopOKBody, error) ContainerTop(ctx context.Context, container string, arguments []string) (container.ContainerTopOKBody, error)
ContainerUnpause(ctx context.Context, container string) error ContainerUnpause(ctx context.Context, container string) error
ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) (container.ContainerUpdateOKBody, error) ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) (container.ContainerUpdateOKBody, error)
ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error)
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error)
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error CopyToContainer(ctx context.Context, container, path string, content io.Reader, options container.CopyToContainerOptions) error
ContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error)
} }
// DistributionAPIClient defines API client methods for the registry // DistributionAPIClient defines API client methods for the registry
@ -92,29 +92,29 @@ type ImageAPIClient interface {
BuildCancel(ctx context.Context, id string) error BuildCancel(ctx context.Context, id string) error
ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error) ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error)
ImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, error) ImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, error)
ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error)
ImageInspectWithRaw(ctx context.Context, image string) (types.ImageInspect, []byte, error) ImageInspectWithRaw(ctx context.Context, image string) (types.ImageInspect, []byte, error)
ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error) ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error)
ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (image.LoadResponse, error)
ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error) ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error)
ImagePush(ctx context.Context, ref string, options image.PushOptions) (io.ReadCloser, error) ImagePush(ctx context.Context, ref string, options image.PushOptions) (io.ReadCloser, error)
ImageRemove(ctx context.Context, image string, options image.RemoveOptions) ([]image.DeleteResponse, error) ImageRemove(ctx context.Context, image string, options image.RemoveOptions) ([]image.DeleteResponse, error)
ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error)
ImageSave(ctx context.Context, images []string) (io.ReadCloser, error) ImageSave(ctx context.Context, images []string) (io.ReadCloser, error)
ImageTag(ctx context.Context, image, ref string) error ImageTag(ctx context.Context, image, ref string) error
ImagesPrune(ctx context.Context, pruneFilter filters.Args) (types.ImagesPruneReport, error) ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error)
} }
// NetworkAPIClient defines API client methods for the networks // NetworkAPIClient defines API client methods for the networks
type NetworkAPIClient interface { type NetworkAPIClient interface {
NetworkConnect(ctx context.Context, network, container string, config *network.EndpointSettings) error NetworkConnect(ctx context.Context, network, container string, config *network.EndpointSettings) error
NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) NetworkCreate(ctx context.Context, name string, options network.CreateOptions) (network.CreateResponse, error)
NetworkDisconnect(ctx context.Context, network, container string, force bool) error NetworkDisconnect(ctx context.Context, network, container string, force bool) error
NetworkInspect(ctx context.Context, network string, options types.NetworkInspectOptions) (types.NetworkResource, error) NetworkInspect(ctx context.Context, network string, options network.InspectOptions) (network.Inspect, error)
NetworkInspectWithRaw(ctx context.Context, network string, options types.NetworkInspectOptions) (types.NetworkResource, []byte, error) NetworkInspectWithRaw(ctx context.Context, network string, options network.InspectOptions) (network.Inspect, []byte, error)
NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) NetworkList(ctx context.Context, options network.ListOptions) ([]network.Summary, error)
NetworkRemove(ctx context.Context, network string) error NetworkRemove(ctx context.Context, network string) error
NetworksPrune(ctx context.Context, pruneFilter filters.Args) (types.NetworksPruneReport, error) NetworksPrune(ctx context.Context, pruneFilter filters.Args) (network.PruneReport, error)
} }
// NodeAPIClient defines API client methods for the nodes // NodeAPIClient defines API client methods for the nodes
@ -165,7 +165,7 @@ type SwarmAPIClient interface {
// SystemAPIClient defines API client methods for the system // SystemAPIClient defines API client methods for the system
type SystemAPIClient interface { type SystemAPIClient interface {
Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error) Events(ctx context.Context, options events.ListOptions) (<-chan events.Message, <-chan error)
Info(ctx context.Context) (system.Info, error) Info(ctx context.Context) (system.Info, error)
RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error) RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error)
DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error) DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error)
@ -179,7 +179,7 @@ type VolumeAPIClient interface {
VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error) VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error)
VolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error) VolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error)
VolumeRemove(ctx context.Context, volumeID string, force bool) error VolumeRemove(ctx context.Context, volumeID string, force bool) error
VolumesPrune(ctx context.Context, pruneFilter filters.Args) (types.VolumesPruneReport, error) VolumesPrune(ctx context.Context, pruneFilter filters.Args) (volume.PruneReport, error)
VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error
} }

View File

@ -3,13 +3,12 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
) )
// NetworkConnect connects a container to an existent network in the docker host. // NetworkConnect connects a container to an existent network in the docker host.
func (cli *Client) NetworkConnect(ctx context.Context, networkID, containerID string, config *network.EndpointSettings) error { func (cli *Client) NetworkConnect(ctx context.Context, networkID, containerID string, config *network.EndpointSettings) error {
nc := types.NetworkConnect{ nc := network.ConnectOptions{
Container: containerID, Container: containerID,
EndpointConfig: config, EndpointConfig: config,
} }

View File

@ -4,13 +4,13 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
) )
// NetworkCreate creates a new network in the docker host. // NetworkCreate creates a new network in the docker host.
func (cli *Client) NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) { func (cli *Client) NetworkCreate(ctx context.Context, name string, options network.CreateOptions) (network.CreateResponse, error) {
var response types.NetworkCreateResponse var response network.CreateResponse
// Make sure we negotiated (if the client is configured to do so), // Make sure we negotiated (if the client is configured to do so),
// as code below contains API-version specific handling of options. // as code below contains API-version specific handling of options.
@ -21,12 +21,13 @@ func (cli *Client) NetworkCreate(ctx context.Context, name string, options types
return response, err return response, err
} }
networkCreateRequest := types.NetworkCreateRequest{ networkCreateRequest := network.CreateRequest{
NetworkCreate: options, CreateOptions: options,
Name: name, Name: name,
} }
if versions.LessThan(cli.version, "1.44") { if versions.LessThan(cli.version, "1.44") {
networkCreateRequest.CheckDuplicate = true //nolint:staticcheck // ignore SA1019: CheckDuplicate is deprecated since API v1.44. enabled := true
networkCreateRequest.CheckDuplicate = &enabled //nolint:staticcheck // ignore SA1019: CheckDuplicate is deprecated since API v1.44.
} }
serverResp, err := cli.post(ctx, "/networks/create", nil, networkCreateRequest, nil) serverResp, err := cli.post(ctx, "/networks/create", nil, networkCreateRequest, nil)

View File

@ -3,12 +3,15 @@ package client // import "github.com/docker/docker/client"
import ( import (
"context" "context"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/network"
) )
// NetworkDisconnect disconnects a container from an existent network in the docker host. // NetworkDisconnect disconnects a container from an existent network in the docker host.
func (cli *Client) NetworkDisconnect(ctx context.Context, networkID, containerID string, force bool) error { func (cli *Client) NetworkDisconnect(ctx context.Context, networkID, containerID string, force bool) error {
nd := types.NetworkDisconnect{Container: containerID, Force: force} nd := network.DisconnectOptions{
Container: containerID,
Force: force,
}
resp, err := cli.post(ctx, "/networks/"+networkID+"/disconnect", nil, nd, nil) resp, err := cli.post(ctx, "/networks/"+networkID+"/disconnect", nil, nd, nil)
ensureReaderClosed(resp) ensureReaderClosed(resp)
return err return err

View File

@ -7,25 +7,20 @@ import (
"io" "io"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/network"
) )
// NetworkInspect returns the information for a specific network configured in the docker host. // NetworkInspect returns the information for a specific network configured in the docker host.
func (cli *Client) NetworkInspect(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, error) { func (cli *Client) NetworkInspect(ctx context.Context, networkID string, options network.InspectOptions) (network.Inspect, error) {
networkResource, _, err := cli.NetworkInspectWithRaw(ctx, networkID, options) networkResource, _, err := cli.NetworkInspectWithRaw(ctx, networkID, options)
return networkResource, err return networkResource, err
} }
// NetworkInspectWithRaw returns the information for a specific network configured in the docker host and its raw representation. // NetworkInspectWithRaw returns the information for a specific network configured in the docker host and its raw representation.
func (cli *Client) NetworkInspectWithRaw(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, []byte, error) { func (cli *Client) NetworkInspectWithRaw(ctx context.Context, networkID string, options network.InspectOptions) (network.Inspect, []byte, error) {
if networkID == "" { if networkID == "" {
return types.NetworkResource{}, nil, objectNotFoundError{object: "network", id: networkID} return network.Inspect{}, nil, objectNotFoundError{object: "network", id: networkID}
} }
var (
networkResource types.NetworkResource
resp serverResponse
err error
)
query := url.Values{} query := url.Values{}
if options.Verbose { if options.Verbose {
query.Set("verbose", "true") query.Set("verbose", "true")
@ -33,17 +28,19 @@ func (cli *Client) NetworkInspectWithRaw(ctx context.Context, networkID string,
if options.Scope != "" { if options.Scope != "" {
query.Set("scope", options.Scope) query.Set("scope", options.Scope)
} }
resp, err = cli.get(ctx, "/networks/"+networkID, query, nil)
resp, err := cli.get(ctx, "/networks/"+networkID, query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {
return networkResource, nil, err return network.Inspect{}, nil, err
} }
body, err := io.ReadAll(resp.body) raw, err := io.ReadAll(resp.body)
if err != nil { if err != nil {
return networkResource, nil, err return network.Inspect{}, nil, err
} }
rdr := bytes.NewReader(body)
err = json.NewDecoder(rdr).Decode(&networkResource) var nw network.Inspect
return networkResource, body, err err = json.NewDecoder(bytes.NewReader(raw)).Decode(&nw)
return nw, raw, err
} }

View File

@ -5,12 +5,12 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/network"
) )
// NetworkList returns the list of networks configured in the docker host. // NetworkList returns the list of networks configured in the docker host.
func (cli *Client) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) { func (cli *Client) NetworkList(ctx context.Context, options network.ListOptions) ([]network.Summary, error) {
query := url.Values{} query := url.Values{}
if options.Filters.Len() > 0 { if options.Filters.Len() > 0 {
//nolint:staticcheck // ignore SA1019 for old code //nolint:staticcheck // ignore SA1019 for old code
@ -21,7 +21,7 @@ func (cli *Client) NetworkList(ctx context.Context, options types.NetworkListOpt
query.Set("filters", filterJSON) query.Set("filters", filterJSON)
} }
var networkResources []types.NetworkResource var networkResources []network.Summary
resp, err := cli.get(ctx, "/networks", query, nil) resp, err := cli.get(ctx, "/networks", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {

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