Skip to content

Commit

Permalink
make runAttach public and allow passing context
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <[email protected]>
  • Loading branch information
ndeloof committed Nov 6, 2023
1 parent 9cb175f commit 71b3c52
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 25 deletions.
49 changes: 25 additions & 24 deletions cli/command/container/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ import (
"github.com/spf13/cobra"
)

type attachOptions struct {
noStdin bool
proxy bool
detachKeys string
// AttachOptions group options for `attach` command
type AttachOptions struct {
NoStdin bool
Proxy bool
DetachKeys string

container string
Container string
}

func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, args string) (*types.ContainerJSON, error) {
Expand All @@ -45,15 +46,15 @@ func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, ar

// NewAttachCommand creates a new cobra.Command for `docker attach`
func NewAttachCommand(dockerCli command.Cli) *cobra.Command {
var opts attachOptions
var opts AttachOptions

cmd := &cobra.Command{
Use: "attach [OPTIONS] CONTAINER",
Short: "Attach local standard input, output, and error streams to a running container",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.container = args[0]
return runAttach(dockerCli, &opts)
opts.Container = args[0]
return RunAttach(context.Background(), dockerCli, &opts)
},
Annotations: map[string]string{
"aliases": "docker container attach, docker attach",
Expand All @@ -64,36 +65,36 @@ func NewAttachCommand(dockerCli command.Cli) *cobra.Command {
}

flags := cmd.Flags()
flags.BoolVar(&opts.noStdin, "no-stdin", false, "Do not attach STDIN")
flags.BoolVar(&opts.proxy, "sig-proxy", true, "Proxy all received signals to the process")
flags.StringVar(&opts.detachKeys, "detach-keys", "", "Override the key sequence for detaching a container")
flags.BoolVar(&opts.NoStdin, "no-stdin", false, "Do not attach STDIN")
flags.BoolVar(&opts.Proxy, "sig-proxy", true, "Proxy all received signals to the process")
flags.StringVar(&opts.DetachKeys, "detach-keys", "", "Override the key sequence for detaching a container")
return cmd
}

func runAttach(dockerCli command.Cli, opts *attachOptions) error {
ctx := context.Background()
// RunAttach executes an `attach` command
func RunAttach(ctx context.Context, dockerCli command.Cli, opts *AttachOptions) error {
apiClient := dockerCli.Client()

// request channel to wait for client
resultC, errC := apiClient.ContainerWait(ctx, opts.container, "")
resultC, errC := apiClient.ContainerWait(ctx, opts.Container, "")

c, err := inspectContainerAndCheckState(ctx, apiClient, opts.container)
c, err := inspectContainerAndCheckState(ctx, apiClient, opts.Container)
if err != nil {
return err
}

if err := dockerCli.In().CheckTty(!opts.noStdin, c.Config.Tty); err != nil {
if err := dockerCli.In().CheckTty(!opts.NoStdin, c.Config.Tty); err != nil {
return err
}

detachKeys := dockerCli.ConfigFile().DetachKeys
if opts.detachKeys != "" {
detachKeys = opts.detachKeys
if opts.DetachKeys != "" {
detachKeys = opts.DetachKeys
}

options := container.AttachOptions{
Stream: true,
Stdin: !opts.noStdin && c.Config.OpenStdin,
Stdin: !opts.NoStdin && c.Config.OpenStdin,
Stdout: true,
Stderr: true,
DetachKeys: detachKeys,
Expand All @@ -104,13 +105,13 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
in = dockerCli.In()
}

if opts.proxy && !c.Config.Tty {
if opts.Proxy && !c.Config.Tty {
sigc := notifyAllSignals()
go ForwardAllSignals(ctx, dockerCli, opts.container, sigc)
go ForwardAllSignals(ctx, dockerCli, opts.Container, sigc)
defer signal.StopCatch(sigc)
}

resp, errAttach := apiClient.ContainerAttach(ctx, opts.container, options)
resp, errAttach := apiClient.ContainerAttach(ctx, opts.Container, options)
if errAttach != nil {
return errAttach
}
Expand All @@ -124,13 +125,13 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
// the container and not exit.
//
// Recheck the container's state to avoid attach block.
_, err = inspectContainerAndCheckState(ctx, apiClient, opts.container)
_, err = inspectContainerAndCheckState(ctx, apiClient, opts.Container)
if err != nil {
return err
}

if c.Config.Tty && dockerCli.Out().IsTerminal() {
resizeTTY(ctx, dockerCli, opts.container)
resizeTTY(ctx, dockerCli, opts.Container)
}

streamer := hijackedIOStreamer{
Expand Down
6 changes: 5 additions & 1 deletion cli/command/container/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,16 @@ func NewExecCommand(dockerCli command.Cli) *cobra.Command {

// RunExec executes an `exec` command
func RunExec(dockerCli command.Cli, options ExecOptions) error {
return RunExecWithContext(context.Background(), dockerCli, options)
}

// RunExecWithContext executes an `exec` command
func RunExecWithContext(ctx context.Context, dockerCli command.Cli, options ExecOptions) error {
execConfig, err := parseExec(options, dockerCli.ConfigFile())
if err != nil {
return err
}

ctx := context.Background()
client := dockerCli.Client()

// We need to check the tty _before_ we do the ContainerExecCreate, because
Expand Down

0 comments on commit 71b3c52

Please sign in to comment.