RunStart executes a `start` command nolint:gocyclo
(ctx context.Context, dockerCli command.Cli, opts *StartOptions)
| 67 | // |
| 68 | //nolint:gocyclo |
| 69 | func RunStart(ctx context.Context, dockerCli command.Cli, opts *StartOptions) error { |
| 70 | ctx, cancelFun := context.WithCancel(ctx) |
| 71 | defer cancelFun() |
| 72 | |
| 73 | detachKeys := opts.DetachKeys |
| 74 | if detachKeys == "" { |
| 75 | detachKeys = dockerCli.ConfigFile().DetachKeys |
| 76 | } |
| 77 | if err := validateDetachKeys(detachKeys); err != nil { |
| 78 | return err |
| 79 | } |
| 80 | |
| 81 | switch { |
| 82 | case opts.Attach || opts.OpenStdin: |
| 83 | // We're going to attach to a container. |
| 84 | // 1. Ensure we only have one container. |
| 85 | if len(opts.Containers) > 1 { |
| 86 | return errors.New("you cannot start and attach multiple containers at once") |
| 87 | } |
| 88 | |
| 89 | // 2. Attach to the container. |
| 90 | ctr := opts.Containers[0] |
| 91 | c, err := dockerCli.Client().ContainerInspect(ctx, ctr, client.ContainerInspectOptions{}) |
| 92 | if err != nil { |
| 93 | return err |
| 94 | } |
| 95 | |
| 96 | // We always use c.ID instead of container to maintain consistency during `docker start` |
| 97 | if !c.Container.Config.Tty { |
| 98 | sigc := notifyAllSignals() |
| 99 | bgCtx := context.WithoutCancel(ctx) |
| 100 | go ForwardAllSignals(bgCtx, dockerCli.Client(), c.Container.ID, sigc) |
| 101 | defer signal.StopCatch(sigc) |
| 102 | } |
| 103 | |
| 104 | options := client.ContainerAttachOptions{ |
| 105 | Stream: true, |
| 106 | Stdin: opts.OpenStdin && c.Container.Config.OpenStdin, |
| 107 | Stdout: true, |
| 108 | Stderr: true, |
| 109 | DetachKeys: detachKeys, |
| 110 | } |
| 111 | |
| 112 | var in io.ReadCloser |
| 113 | |
| 114 | if options.Stdin { |
| 115 | in = dockerCli.In() |
| 116 | } |
| 117 | |
| 118 | resp, errAttach := dockerCli.Client().ContainerAttach(ctx, c.Container.ID, options) |
| 119 | if errAttach != nil { |
| 120 | return errAttach |
| 121 | } |
| 122 | defer resp.HijackedResponse.Close() |
| 123 | |
| 124 | cErr := make(chan error, 1) |
| 125 | |
| 126 | go func() { |
no test coverage detected
searching dependent graphs…