mirror of https://github.com/docker/cli.git
cli/command/container: rename some variables
Rename some variables to prevent shadowing and for clarity. Also made some minor formatting changes. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
1a83595c7c
commit
851277f966
|
@ -433,18 +433,18 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpCo
|
||||||
// so we have to check for a `/` or `.` prefix. Also, in the case of a Windows
|
// so we have to check for a `/` or `.` prefix. Also, in the case of a Windows
|
||||||
// client, a `:` could be part of an absolute Windows path, in which case it
|
// client, a `:` could be part of an absolute Windows path, in which case it
|
||||||
// is immediately proceeded by a backslash.
|
// is immediately proceeded by a backslash.
|
||||||
func splitCpArg(arg string) (container, path string) {
|
func splitCpArg(arg string) (ctr, path string) {
|
||||||
if system.IsAbs(arg) {
|
if system.IsAbs(arg) {
|
||||||
// Explicit local absolute path, e.g., `C:\foo` or `/foo`.
|
// Explicit local absolute path, e.g., `C:\foo` or `/foo`.
|
||||||
return "", arg
|
return "", arg
|
||||||
}
|
}
|
||||||
|
|
||||||
container, path, ok := strings.Cut(arg, ":")
|
ctr, path, ok := strings.Cut(arg, ":")
|
||||||
if !ok || strings.HasPrefix(container, ".") {
|
if !ok || strings.HasPrefix(ctr, ".") {
|
||||||
// Either there's no `:` in the arg
|
// Either there's no `:` in the arg
|
||||||
// OR it's an explicit local relative path like `./file:name.txt`.
|
// OR it's an explicit local relative path like `./file:name.txt`.
|
||||||
return "", arg
|
return "", arg
|
||||||
}
|
}
|
||||||
|
|
||||||
return container, path
|
return ctr, path
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/docker/cli/cli/config/configfile"
|
"github.com/docker/cli/cli/config/configfile"
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
apiclient "github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -43,19 +43,18 @@ 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 {
|
||||||
container = args[0]
|
containerIDorName := args[0]
|
||||||
options.Command = args[1:]
|
options.Command = args[1:]
|
||||||
return RunExec(cmd.Context(), dockerCli, container, options)
|
return RunExec(cmd.Context(), dockerCli, containerIDorName, options)
|
||||||
},
|
},
|
||||||
ValidArgsFunction: completion.ContainerNames(dockerCli, false, func(container types.Container) bool {
|
ValidArgsFunction: completion.ContainerNames(dockerCli, false, func(ctr types.Container) bool {
|
||||||
return container.State != "paused"
|
return ctr.State != "paused"
|
||||||
}),
|
}),
|
||||||
Annotations: map[string]string{
|
Annotations: map[string]string{
|
||||||
"category-top": "2",
|
"category-top": "2",
|
||||||
|
@ -79,47 +78,41 @@ func NewExecCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
flags.StringVarP(&options.Workdir, "workdir", "w", "", "Working directory inside the container")
|
flags.StringVarP(&options.Workdir, "workdir", "w", "", "Working directory inside the container")
|
||||||
flags.SetAnnotation("workdir", "version", []string{"1.35"})
|
flags.SetAnnotation("workdir", "version", []string{"1.35"})
|
||||||
|
|
||||||
cmd.RegisterFlagCompletionFunc(
|
_ = cmd.RegisterFlagCompletionFunc("env", func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||||
"env",
|
|
||||||
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
return os.Environ(), cobra.ShellCompDirectiveNoFileComp
|
return os.Environ(), cobra.ShellCompDirectiveNoFileComp
|
||||||
},
|
})
|
||||||
)
|
_ = cmd.RegisterFlagCompletionFunc("env-file", func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||||
cmd.RegisterFlagCompletionFunc(
|
|
||||||
"env-file",
|
|
||||||
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
||||||
return nil, cobra.ShellCompDirectiveDefault // _filedir
|
return nil, cobra.ShellCompDirectiveDefault // _filedir
|
||||||
},
|
})
|
||||||
)
|
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunExec executes an `exec` command
|
// RunExec executes an `exec` command
|
||||||
func RunExec(ctx context.Context, dockerCli command.Cli, container string, options ExecOptions) error {
|
func RunExec(ctx context.Context, dockerCli command.Cli, containerIDorName string, options ExecOptions) error {
|
||||||
execConfig, err := parseExec(options, dockerCli.ConfigFile())
|
execOptions, err := parseExec(options, dockerCli.ConfigFile())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
client := dockerCli.Client()
|
apiClient := dockerCli.Client()
|
||||||
|
|
||||||
// We need to check the tty _before_ we do the ContainerExecCreate, because
|
// We need to check the tty _before_ we do the ContainerExecCreate, because
|
||||||
// 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, container); err != nil {
|
if _, err := apiClient.ContainerInspect(ctx, containerIDorName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !execConfig.Detach {
|
if !execOptions.Detach {
|
||||||
if err := dockerCli.In().CheckTty(execConfig.AttachStdin, execConfig.Tty); err != nil {
|
if err := dockerCli.In().CheckTty(execOptions.AttachStdin, execOptions.Tty); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fillConsoleSize(execConfig, dockerCli)
|
fillConsoleSize(execOptions, dockerCli)
|
||||||
|
|
||||||
response, err := client.ContainerExecCreate(ctx, container, *execConfig)
|
response, err := apiClient.ContainerExecCreate(ctx, containerIDorName, *execOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -129,15 +122,14 @@ func RunExec(ctx context.Context, dockerCli command.Cli, container string, optio
|
||||||
return errors.New("exec ID empty")
|
return errors.New("exec ID empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
if execConfig.Detach {
|
if execOptions.Detach {
|
||||||
execStartCheck := types.ExecStartCheck{
|
return apiClient.ContainerExecStart(ctx, execID, types.ExecStartCheck{
|
||||||
Detach: execConfig.Detach,
|
Detach: execOptions.Detach,
|
||||||
Tty: execConfig.Tty,
|
Tty: execOptions.Tty,
|
||||||
ConsoleSize: execConfig.ConsoleSize,
|
ConsoleSize: execOptions.ConsoleSize,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return client.ContainerExecStart(ctx, execID, execStartCheck)
|
return interactiveExec(ctx, dockerCli, execOptions, execID)
|
||||||
}
|
|
||||||
return interactiveExec(ctx, dockerCli, execConfig, execID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func fillConsoleSize(execConfig *types.ExecConfig, dockerCli command.Cli) {
|
func fillConsoleSize(execConfig *types.ExecConfig, dockerCli command.Cli) {
|
||||||
|
@ -147,34 +139,33 @@ func fillConsoleSize(execConfig *types.ExecConfig, dockerCli command.Cli) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func interactiveExec(ctx context.Context, dockerCli command.Cli, execConfig *types.ExecConfig, execID string) error {
|
func interactiveExec(ctx context.Context, dockerCli command.Cli, execOptions *types.ExecConfig, execID string) error {
|
||||||
// Interactive exec requested.
|
// Interactive exec requested.
|
||||||
var (
|
var (
|
||||||
out, stderr io.Writer
|
out, stderr io.Writer
|
||||||
in io.ReadCloser
|
in io.ReadCloser
|
||||||
)
|
)
|
||||||
|
|
||||||
if execConfig.AttachStdin {
|
if execOptions.AttachStdin {
|
||||||
in = dockerCli.In()
|
in = dockerCli.In()
|
||||||
}
|
}
|
||||||
if execConfig.AttachStdout {
|
if execOptions.AttachStdout {
|
||||||
out = dockerCli.Out()
|
out = dockerCli.Out()
|
||||||
}
|
}
|
||||||
if execConfig.AttachStderr {
|
if execOptions.AttachStderr {
|
||||||
if execConfig.Tty {
|
if execOptions.Tty {
|
||||||
stderr = dockerCli.Out()
|
stderr = dockerCli.Out()
|
||||||
} else {
|
} else {
|
||||||
stderr = dockerCli.Err()
|
stderr = dockerCli.Err()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fillConsoleSize(execConfig, dockerCli)
|
fillConsoleSize(execOptions, dockerCli)
|
||||||
|
|
||||||
client := dockerCli.Client()
|
apiClient := dockerCli.Client()
|
||||||
execStartCheck := types.ExecStartCheck{
|
resp, err := apiClient.ContainerExecAttach(ctx, execID, types.ExecStartCheck{
|
||||||
Tty: execConfig.Tty,
|
Tty: execOptions.Tty,
|
||||||
ConsoleSize: execConfig.ConsoleSize,
|
ConsoleSize: execOptions.ConsoleSize,
|
||||||
}
|
})
|
||||||
resp, err := client.ContainerExecAttach(ctx, execID, execStartCheck)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -191,17 +182,17 @@ func interactiveExec(ctx context.Context, dockerCli command.Cli, execConfig *typ
|
||||||
outputStream: out,
|
outputStream: out,
|
||||||
errorStream: stderr,
|
errorStream: stderr,
|
||||||
resp: resp,
|
resp: resp,
|
||||||
tty: execConfig.Tty,
|
tty: execOptions.Tty,
|
||||||
detachKeys: execConfig.DetachKeys,
|
detachKeys: execOptions.DetachKeys,
|
||||||
}
|
}
|
||||||
|
|
||||||
return streamer.stream(ctx)
|
return streamer.stream(ctx)
|
||||||
}()
|
}()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if execConfig.Tty && dockerCli.In().IsTerminal() {
|
if execOptions.Tty && dockerCli.In().IsTerminal() {
|
||||||
if err := MonitorTtySize(ctx, dockerCli, execID, true); err != nil {
|
if err := MonitorTtySize(ctx, dockerCli, execID, true); err != nil {
|
||||||
fmt.Fprintln(dockerCli.Err(), "Error monitoring TTY size:", err)
|
_, _ = fmt.Fprintln(dockerCli.Err(), "Error monitoring TTY size:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,14 +201,14 @@ func interactiveExec(ctx context.Context, dockerCli command.Cli, execConfig *typ
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return getExecExitStatus(ctx, client, execID)
|
return getExecExitStatus(ctx, apiClient, execID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExecExitStatus(ctx context.Context, client apiclient.ContainerAPIClient, execID string) error {
|
func getExecExitStatus(ctx context.Context, apiClient client.ContainerAPIClient, execID string) error {
|
||||||
resp, err := client.ContainerExecInspect(ctx, execID)
|
resp, err := apiClient.ContainerExecInspect(ctx, execID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If we can't connect, then the daemon probably died.
|
// If we can't connect, then the daemon probably died.
|
||||||
if !apiclient.IsErrConnectionFailed(err) {
|
if !client.IsErrConnectionFailed(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return cli.StatusError{StatusCode: -1}
|
return cli.StatusError{StatusCode: -1}
|
||||||
|
@ -232,7 +223,7 @@ func getExecExitStatus(ctx context.Context, client apiclient.ContainerAPIClient,
|
||||||
// parseExec parses the specified args for the specified command and generates
|
// parseExec parses the specified args for the specified command and generates
|
||||||
// an ExecConfig from it.
|
// an ExecConfig from it.
|
||||||
func parseExec(execOpts ExecOptions, configFile *configfile.ConfigFile) (*types.ExecConfig, error) {
|
func parseExec(execOpts ExecOptions, configFile *configfile.ConfigFile) (*types.ExecConfig, error) {
|
||||||
execConfig := &types.ExecConfig{
|
execOptions := &types.ExecConfig{
|
||||||
User: execOpts.User,
|
User: execOpts.User,
|
||||||
Privileged: execOpts.Privileged,
|
Privileged: execOpts.Privileged,
|
||||||
Tty: execOpts.TTY,
|
Tty: execOpts.TTY,
|
||||||
|
@ -243,23 +234,23 @@ func parseExec(execOpts ExecOptions, configFile *configfile.ConfigFile) (*types.
|
||||||
|
|
||||||
// collect all the environment variables for the container
|
// collect all the environment variables for the container
|
||||||
var err error
|
var err error
|
||||||
if execConfig.Env, err = opts.ReadKVEnvStrings(execOpts.EnvFile.GetAll(), execOpts.Env.GetAll()); err != nil {
|
if execOptions.Env, err = opts.ReadKVEnvStrings(execOpts.EnvFile.GetAll(), execOpts.Env.GetAll()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If -d is not set, attach to everything by default
|
// If -d is not set, attach to everything by default
|
||||||
if !execOpts.Detach {
|
if !execOpts.Detach {
|
||||||
execConfig.AttachStdout = true
|
execOptions.AttachStdout = true
|
||||||
execConfig.AttachStderr = true
|
execOptions.AttachStderr = true
|
||||||
if execOpts.Interactive {
|
if execOpts.Interactive {
|
||||||
execConfig.AttachStdin = true
|
execOptions.AttachStdin = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if execOpts.DetachKeys != "" {
|
if execOpts.DetachKeys != "" {
|
||||||
execConfig.DetachKeys = execOpts.DetachKeys
|
execOptions.DetachKeys = execOpts.DetachKeys
|
||||||
} else {
|
} else {
|
||||||
execConfig.DetachKeys = configFile.DetachKeys
|
execOptions.DetachKeys = configFile.DetachKeys
|
||||||
}
|
}
|
||||||
return execConfig, nil
|
return execOptions, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue