diff --git a/cli/command/container/rename.go b/cli/command/container/rename.go index 84d6c1a34..f875bddea 100644 --- a/cli/command/container/rename.go +++ b/cli/command/container/rename.go @@ -1,7 +1,6 @@ package container import ( - "errors" "fmt" "github.com/docker/cli/cli" @@ -19,10 +18,6 @@ func newRenameCommand(dockerCLI command.Cli) *cobra.Command { Args: cli.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { oldName, newName := args[0], args[1] - if newName == "" { - // TODO(thaJeztah): remove once https://github.com/moby/moby/pull/51336 is merged and vendored. - return errors.New("new name cannot be blank") - } _, err := dockerCLI.Client().ContainerRename(cmd.Context(), oldName, client.ContainerRenameOptions{ NewName: newName, }) diff --git a/cli/command/container/rename_test.go b/cli/command/container/rename_test.go deleted file mode 100644 index 4ca80c70f..000000000 --- a/cli/command/container/rename_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package container - -import ( - "context" - "errors" - "io" - "testing" - - "github.com/docker/cli/internal/test" - "gotest.tools/v3/assert" -) - -func TestRunRename(t *testing.T) { - testcases := []struct { - doc, oldName, newName, expectedErr string - }{ - { - doc: "success", - oldName: "oldName", - newName: "newName", - expectedErr: "", - }, - { - doc: "empty old name", - oldName: "", - newName: "newName", - expectedErr: "invalid container name or ID: value is empty", - }, - { - doc: "empty new name", - oldName: "oldName", - newName: "", - expectedErr: "new name cannot be blank", - }, - } - - for _, tc := range testcases { - t.Run(tc.doc, func(t *testing.T) { - cli := test.NewFakeCli(&fakeClient{ - containerRenameFunc: func(ctx context.Context, oldName, newName string) error { - if oldName == "" { - return errors.New("invalid container name or ID: value is empty") - } - return nil - }, - }) - - cmd := newRenameCommand(cli) - cmd.SetOut(io.Discard) - cmd.SetErr(io.Discard) - cmd.SetArgs([]string{tc.oldName, tc.newName}) - - err := cmd.Execute() - - if tc.expectedErr != "" { - assert.ErrorContains(t, err, tc.expectedErr) - } else { - assert.NilError(t, err) - } - }) - } -} diff --git a/cli/command/registry/login.go b/cli/command/registry/login.go index fb138f8bf..266a40192 100644 --- a/cli/command/registry/login.go +++ b/cli/command/registry/login.go @@ -332,7 +332,7 @@ func loginClientSide(ctx context.Context, options client.RegistryLoginOptions) ( } return client.RegistryLoginResult{ - Auth: registrytypes.AuthenticateOKBody{ + Auth: registrytypes.AuthResponse{ Status: "Login Succeeded", IdentityToken: token, }, diff --git a/cli/command/registry/login_test.go b/cli/command/registry/login_test.go index fba83e55a..41f833483 100644 --- a/cli/command/registry/login_test.go +++ b/cli/command/registry/login_test.go @@ -43,7 +43,7 @@ func (*fakeClient) RegistryLogin(_ context.Context, options client.RegistryLogin } if options.Password == useToken { return client.RegistryLoginResult{ - Auth: registrytypes.AuthenticateOKBody{IdentityToken: options.Password}, + Auth: registrytypes.AuthResponse{IdentityToken: options.Password}, }, nil } if options.Username == unknownUser { diff --git a/e2e/container/rename_test.go b/e2e/container/rename_test.go index bbaf5ebc7..c1879bd11 100644 --- a/e2e/container/rename_test.go +++ b/e2e/container/rename_test.go @@ -26,3 +26,27 @@ func TestContainerRename(t *testing.T) { res.Assert(t, icmd.Success) assert.Equal(t, "/"+newName, strings.TrimSpace(res.Stdout())) } + +func TestContainerRenameEmptyOldName(t *testing.T) { + res := icmd.RunCommand("docker", "container", "rename", "", "newName") + res.Assert(t, icmd.Expected{ + ExitCode: 1, + Err: "invalid container name or ID: value is empty", + }) +} + +func TestContainerRenameEmptyNewName(t *testing.T) { + oldName := "old_name_" + t.Name() + res := icmd.RunCommand("docker", "run", "-d", "--name", oldName, fixtures.AlpineImage, "sleep", "60") + res.Assert(t, icmd.Success) + cID := strings.TrimSpace(res.Stdout()) + t.Cleanup(func() { + icmd.RunCommand("docker", "container", "rm", "-f", cID).Assert(t, icmd.Success) + }) + + res = icmd.RunCommand("docker", "container", "rename", oldName, "") + res.Assert(t, icmd.Expected{ + ExitCode: 1, + Err: "new name cannot be blank", + }) +} diff --git a/vendor.mod b/vendor.mod index b0be232a2..72916c7ef 100644 --- a/vendor.mod +++ b/vendor.mod @@ -28,8 +28,8 @@ require ( github.com/google/uuid v1.6.0 github.com/mattn/go-runewidth v0.0.17 github.com/moby/go-archive v0.1.0 - github.com/moby/moby/api v1.52.0-beta.2.0.20251029165853-ef17deb3a0fb // master - github.com/moby/moby/client v0.1.0-beta.2.0.20251029165853-ef17deb3a0fb // master + github.com/moby/moby/api v1.52.0-beta.2.0.20251029225139-7a97e1cb401f // master + github.com/moby/moby/client v0.1.0-beta.2.0.20251029225139-7a97e1cb401f // master github.com/moby/patternmatcher v0.6.0 github.com/moby/swarmkit/v2 v2.1.0 github.com/moby/sys/atomicwriter v0.1.0 diff --git a/vendor.sum b/vendor.sum index ce0ba0edb..b4e9327af 100644 --- a/vendor.sum +++ b/vendor.sum @@ -170,10 +170,10 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ= github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo= -github.com/moby/moby/api v1.52.0-beta.2.0.20251029165853-ef17deb3a0fb h1:t4RxpXuvv26rIVUBqUm0xgmaSmmTJTv5fzEDxg5piWE= -github.com/moby/moby/api v1.52.0-beta.2.0.20251029165853-ef17deb3a0fb/go.mod h1:v0K/motq8oWmx+rtApG1rBTIpQ8KUONUjpf+U73gags= -github.com/moby/moby/client v0.1.0-beta.2.0.20251029165853-ef17deb3a0fb h1:3F0iF/yIxE43JcK3rJp4k/TsVmfvFMgRyGT/tg+K1xI= -github.com/moby/moby/client v0.1.0-beta.2.0.20251029165853-ef17deb3a0fb/go.mod h1:1YrJTvhL771Q4xiwwe72NSS17lgsCF67xu8fEfSd77g= +github.com/moby/moby/api v1.52.0-beta.2.0.20251029225139-7a97e1cb401f h1:agkZxo7k3fXBqdq6leYCCv0K45OjkH/H3fzPjwcoDkY= +github.com/moby/moby/api v1.52.0-beta.2.0.20251029225139-7a97e1cb401f/go.mod h1:v0K/motq8oWmx+rtApG1rBTIpQ8KUONUjpf+U73gags= +github.com/moby/moby/client v0.1.0-beta.2.0.20251029225139-7a97e1cb401f h1:I0uikdmKsCbOxQV+DIn7gyY8bD0d19g8920FuxI9l3E= +github.com/moby/moby/client v0.1.0-beta.2.0.20251029225139-7a97e1cb401f/go.mod h1:1YrJTvhL771Q4xiwwe72NSS17lgsCF67xu8fEfSd77g= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/swarmkit/v2 v2.1.0 h1:u+cJ5hSyF3HnzsyI+NtegYxdIPQIuibk7IbpXNxuISM= diff --git a/vendor/github.com/moby/moby/api/types/registry/auth_response.go b/vendor/github.com/moby/moby/api/types/registry/auth_response.go new file mode 100644 index 000000000..94c2e1bb3 --- /dev/null +++ b/vendor/github.com/moby/moby/api/types/registry/auth_response.go @@ -0,0 +1,21 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package registry + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +// AuthResponse An identity token was generated successfully. +// +// swagger:model AuthResponse +type AuthResponse struct { + + // An opaque token used to authenticate a user after a successful login + // Example: 9cbaf023786cd7... + IdentityToken string `json:"IdentityToken,omitempty"` + + // The status of the authentication + // Example: Login Succeeded + // Required: true + Status string `json:"Status"` +} diff --git a/vendor/github.com/moby/moby/api/types/registry/authenticate.go b/vendor/github.com/moby/moby/api/types/registry/authenticate.go deleted file mode 100644 index 42cac4430..000000000 --- a/vendor/github.com/moby/moby/api/types/registry/authenticate.go +++ /dev/null @@ -1,21 +0,0 @@ -package registry - -// ---------------------------------------------------------------------------- -// DO NOT EDIT THIS FILE -// This file was generated by `swagger generate operation` -// -// See hack/generate-swagger-api.sh -// ---------------------------------------------------------------------------- - -// AuthenticateOKBody authenticate o k body -// swagger:model AuthenticateOKBody -type AuthenticateOKBody struct { - - // An opaque token used to authenticate a user after a successful login - // Required: true - IdentityToken string `json:"IdentityToken"` - - // The status of the authentication - // Required: true - Status string `json:"Status"` -} diff --git a/vendor/github.com/moby/moby/client/client.go b/vendor/github.com/moby/moby/client/client.go index 950f3adc7..8fe97d590 100644 --- a/vendor/github.com/moby/moby/client/client.go +++ b/vendor/github.com/moby/moby/client/client.go @@ -8,8 +8,10 @@ https://docs.docker.com/reference/api/engine/ You use the library by constructing a client object using [NewClientWithOpts] and calling methods on it. The client can be configured from environment -variables by passing the [FromEnv] option, or configured manually by passing any -of the other available [Opts]. +variables by passing the [FromEnv] option, and the [WithAPIVersionNegotiation] +option to allow downgrading the API version used when connecting with an older +daemon version. Other options cen be configured manually by passing any of +the available [Opt] options. For example, to list running containers (the equivalent of "docker ps"): @@ -18,23 +20,33 @@ For example, to list running containers (the equivalent of "docker ps"): import ( "context" "fmt" + "log" "github.com/moby/moby/client" ) func main() { - cli, err := client.NewClientWithOpts(client.FromEnv) + // Create a new client that handles common environment variables + // for configuration (DOCKER_HOST, DOCKER_API_VERSION), and does + // API-version negotiation to allow downgrading the API version + // when connecting with an older daemon version. + apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { - panic(err) + log.Fatal(err) } - containers, err := cli.ContainerList(context.Background(), client.ContainerListOptions{}) + // List all containers (both stopped and running). + result, err := apiClient.ContainerList(context.Background(), client.ContainerListOptions{ + All: true, + }) if err != nil { - panic(err) + log.Fatal(err) } - for _, ctr := range containers { - fmt.Printf("%s %s\n", ctr.ID, ctr.Image) + // Print each container's ID, status and the image it was created from. + fmt.Printf("%s %-22s %s\n", "ID", "STATUS", "IMAGE") + for _, ctr := range result.Items { + fmt.Printf("%s %-22s %s\n", ctr.ID, ctr.Status, ctr.Image) } } */ diff --git a/vendor/github.com/moby/moby/client/container_rename.go b/vendor/github.com/moby/moby/client/container_rename.go index 6ce150008..7c6d515b3 100644 --- a/vendor/github.com/moby/moby/client/container_rename.go +++ b/vendor/github.com/moby/moby/client/container_rename.go @@ -3,6 +3,9 @@ package client import ( "context" "net/url" + "strings" + + "github.com/containerd/errdefs" ) // ContainerRenameOptions represents the options for renaming a container. @@ -21,6 +24,12 @@ func (cli *Client) ContainerRename(ctx context.Context, containerID string, opti if err != nil { return ContainerRenameResult{}, err } + options.NewName = strings.TrimSpace(options.NewName) + if options.NewName == "" || strings.TrimPrefix(options.NewName, "/") == "" { + // daemons before v29.0 did not handle the canonical name ("/") well + // let's be nice and validate it here before sending + return ContainerRenameResult{}, errdefs.ErrInvalidArgument.WithMessage("new name cannot be blank") + } query := url.Values{} query.Set("name", options.NewName) diff --git a/vendor/github.com/moby/moby/client/login.go b/vendor/github.com/moby/moby/client/login.go index 6974ec22c..b295080ab 100644 --- a/vendor/github.com/moby/moby/client/login.go +++ b/vendor/github.com/moby/moby/client/login.go @@ -18,7 +18,7 @@ type RegistryLoginOptions struct { // RegistryLoginResult holds the result of a RegistryLogin query. type RegistryLoginResult struct { - Auth registry.AuthenticateOKBody + Auth registry.AuthResponse } // RegistryLogin authenticates the docker server with a given docker registry. @@ -39,7 +39,7 @@ func (cli *Client) RegistryLogin(ctx context.Context, options RegistryLoginOptio return RegistryLoginResult{}, err } - var response registry.AuthenticateOKBody + var response registry.AuthResponse err = json.NewDecoder(resp.Body).Decode(&response) return RegistryLoginResult{Auth: response}, err } diff --git a/vendor/modules.txt b/vendor/modules.txt index 8c552ca01..68335c66b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -168,7 +168,7 @@ github.com/moby/docker-image-spec/specs-go/v1 github.com/moby/go-archive github.com/moby/go-archive/compression github.com/moby/go-archive/tarheader -# github.com/moby/moby/api v1.52.0-beta.2.0.20251029165853-ef17deb3a0fb +# github.com/moby/moby/api v1.52.0-beta.2.0.20251029225139-7a97e1cb401f ## explicit; go 1.23.0 github.com/moby/moby/api/pkg/authconfig github.com/moby/moby/api/pkg/stdcopy @@ -190,7 +190,7 @@ github.com/moby/moby/api/types/storage github.com/moby/moby/api/types/swarm github.com/moby/moby/api/types/system github.com/moby/moby/api/types/volume -# github.com/moby/moby/client v0.1.0-beta.2.0.20251029165853-ef17deb3a0fb +# github.com/moby/moby/client v0.1.0-beta.2.0.20251029225139-7a97e1cb401f ## explicit; go 1.23.0 github.com/moby/moby/client github.com/moby/moby/client/internal