make `container` an explicit, required parameter

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2023-11-08 14:32:55 +01:00
parent a4abe42cbd
commit a2ec50a461
No known key found for this signature in database
GPG Key ID: 9858809D6F8F6E7E
3 changed files with 18 additions and 20 deletions

View File

@ -22,8 +22,6 @@ type AttachOptions struct {
NoStdin bool NoStdin bool
Proxy bool Proxy bool
DetachKeys string DetachKeys string
Container string
} }
func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, args string) (*types.ContainerJSON, error) { func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, args string) (*types.ContainerJSON, error) {
@ -47,14 +45,15 @@ func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, ar
// NewAttachCommand creates a new cobra.Command for `docker attach` // NewAttachCommand creates a new cobra.Command for `docker attach`
func NewAttachCommand(dockerCli command.Cli) *cobra.Command { func NewAttachCommand(dockerCli command.Cli) *cobra.Command {
var opts AttachOptions var opts AttachOptions
var container string
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "attach [OPTIONS] CONTAINER", Use: "attach [OPTIONS] CONTAINER",
Short: "Attach local standard input, output, and error streams to a running container", Short: "Attach local standard input, output, and error streams to a running container",
Args: cli.ExactArgs(1), Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
opts.Container = args[0] container = args[0]
return RunAttach(context.Background(), dockerCli, &opts) return RunAttach(context.Background(), dockerCli, container, &opts)
}, },
Annotations: map[string]string{ Annotations: map[string]string{
"aliases": "docker container attach, docker attach", "aliases": "docker container attach, docker attach",
@ -72,13 +71,13 @@ func NewAttachCommand(dockerCli command.Cli) *cobra.Command {
} }
// RunAttach executes an `attach` command // RunAttach executes an `attach` command
func RunAttach(ctx context.Context, dockerCli command.Cli, opts *AttachOptions) error { func RunAttach(ctx context.Context, dockerCli command.Cli, target string, opts *AttachOptions) error {
apiClient := dockerCli.Client() apiClient := dockerCli.Client()
// request channel to wait for client // request channel to wait for client
resultC, errC := apiClient.ContainerWait(ctx, opts.Container, "") resultC, errC := apiClient.ContainerWait(ctx, target, "")
c, err := inspectContainerAndCheckState(ctx, apiClient, opts.Container) c, err := inspectContainerAndCheckState(ctx, apiClient, target)
if err != nil { if err != nil {
return err return err
} }
@ -107,11 +106,11 @@ func RunAttach(ctx context.Context, dockerCli command.Cli, opts *AttachOptions)
if opts.Proxy && !c.Config.Tty { if opts.Proxy && !c.Config.Tty {
sigc := notifyAllSignals() sigc := notifyAllSignals()
go ForwardAllSignals(ctx, dockerCli, opts.Container, sigc) go ForwardAllSignals(ctx, dockerCli, target, sigc)
defer signal.StopCatch(sigc) defer signal.StopCatch(sigc)
} }
resp, errAttach := apiClient.ContainerAttach(ctx, opts.Container, options) resp, errAttach := apiClient.ContainerAttach(ctx, target, options)
if errAttach != nil { if errAttach != nil {
return errAttach return errAttach
} }
@ -125,13 +124,13 @@ func RunAttach(ctx context.Context, dockerCli command.Cli, opts *AttachOptions)
// the container and not exit. // the container and not exit.
// //
// Recheck the container's state to avoid attach block. // Recheck the container's state to avoid attach block.
_, err = inspectContainerAndCheckState(ctx, apiClient, opts.Container) _, err = inspectContainerAndCheckState(ctx, apiClient, target)
if err != nil { if err != nil {
return err return err
} }
if c.Config.Tty && dockerCli.Out().IsTerminal() { if c.Config.Tty && dockerCli.Out().IsTerminal() {
resizeTTY(ctx, dockerCli, opts.Container) resizeTTY(ctx, dockerCli, target)
} }
streamer := hijackedIOStreamer{ streamer := hijackedIOStreamer{

View File

@ -28,7 +28,6 @@ type ExecOptions struct {
Privileged bool Privileged bool
Env opts.ListOpts Env opts.ListOpts
Workdir string Workdir string
Container string
Command []string Command []string
EnvFile opts.ListOpts EnvFile opts.ListOpts
} }
@ -44,15 +43,16 @@ func NewExecOptions() ExecOptions {
// NewExecCommand creates a new cobra.Command for `docker exec` // NewExecCommand creates a new cobra.Command for `docker exec`
func NewExecCommand(dockerCli command.Cli) *cobra.Command { func NewExecCommand(dockerCli command.Cli) *cobra.Command {
options := NewExecOptions() options := NewExecOptions()
var container string
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "exec [OPTIONS] CONTAINER COMMAND [ARG...]", Use: "exec [OPTIONS] CONTAINER COMMAND [ARG...]",
Short: "Execute a command in a running container", Short: "Execute a command in a running container",
Args: cli.RequiresMinArgs(2), Args: cli.RequiresMinArgs(2),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
options.Container = args[0] container = args[0]
options.Command = args[1:] options.Command = args[1:]
return RunExec(context.Background(), dockerCli, options) return RunExec(context.Background(), dockerCli, container, options)
}, },
ValidArgsFunction: completion.ContainerNames(dockerCli, false, func(container types.Container) bool { ValidArgsFunction: completion.ContainerNames(dockerCli, false, func(container types.Container) bool {
return container.State != "paused" return container.State != "paused"
@ -96,7 +96,7 @@ func NewExecCommand(dockerCli command.Cli) *cobra.Command {
} }
// RunExec executes an `exec` command // RunExec executes an `exec` command
func RunExec(ctx context.Context, dockerCli command.Cli, options ExecOptions) error { func RunExec(ctx context.Context, dockerCli command.Cli, container string, options ExecOptions) error {
execConfig, err := parseExec(options, dockerCli.ConfigFile()) execConfig, err := parseExec(options, dockerCli.ConfigFile())
if err != nil { if err != nil {
return err return err
@ -108,7 +108,7 @@ func RunExec(ctx context.Context, dockerCli command.Cli, options ExecOptions) er
// otherwise if we error out we will leak execIDs on the server (and // otherwise if we error out we will leak execIDs on the server (and
// there's no easy way to clean those up). But also in order to make "not // there's no easy way to clean those up). But also in order to make "not
// exist" errors take precedence we do a dummy inspect first. // exist" errors take precedence we do a dummy inspect first.
if _, err := client.ContainerInspect(ctx, options.Container); err != nil { if _, err := client.ContainerInspect(ctx, container); err != nil {
return err return err
} }
if !execConfig.Detach { if !execConfig.Detach {
@ -119,7 +119,7 @@ func RunExec(ctx context.Context, dockerCli command.Cli, options ExecOptions) er
fillConsoleSize(execConfig, dockerCli) fillConsoleSize(execConfig, dockerCli)
response, err := client.ContainerExecCreate(ctx, options.Container, *execConfig) response, err := client.ContainerExecCreate(ctx, container, *execConfig)
if err != nil { if err != nil {
return err return err
} }

View File

@ -169,8 +169,7 @@ func TestRunExec(t *testing.T) {
{ {
doc: "successful detach", doc: "successful detach",
options: withDefaultOpts(ExecOptions{ options: withDefaultOpts(ExecOptions{
Container: "thecontainer", Detach: true,
Detach: true,
}), }),
client: fakeClient{execCreateFunc: execCreateWithID}, client: fakeClient{execCreateFunc: execCreateWithID},
}, },
@ -195,7 +194,7 @@ func TestRunExec(t *testing.T) {
t.Run(testcase.doc, func(t *testing.T) { t.Run(testcase.doc, func(t *testing.T) {
cli := test.NewFakeCli(&testcase.client) cli := test.NewFakeCli(&testcase.client)
err := RunExec(context.Background(), cli, testcase.options) err := RunExec(context.Background(), cli, "thecontainer", testcase.options)
if testcase.expectedError != "" { if testcase.expectedError != "" {
assert.ErrorContains(t, err, testcase.expectedError) assert.ErrorContains(t, err, testcase.expectedError)
} else { } else {