Skip to content

Commit 24d3404

Browse files
authored
Merge pull request docker#11181 from g0t4/11153-compose-attach-override-container-attach-cmd
Implement `docker compose attach`
2 parents dbe7819 + 5f4b22e commit 24d3404

File tree

9 files changed

+264
-31
lines changed

9 files changed

+264
-31
lines changed

cmd/compose/attach.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
Copyright 2020 Docker Compose CLI authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package compose
18+
19+
import (
20+
"context"
21+
22+
"github.com/docker/cli/cli/command"
23+
"github.com/docker/compose/v2/pkg/api"
24+
"github.com/spf13/cobra"
25+
)
26+
27+
type attachOpts struct {
28+
*composeOptions
29+
30+
service string
31+
index int
32+
33+
detachKeys string
34+
noStdin bool
35+
proxy bool
36+
}
37+
38+
func attachCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
39+
opts := attachOpts{
40+
composeOptions: &composeOptions{
41+
ProjectOptions: p,
42+
},
43+
}
44+
runCmd := &cobra.Command{
45+
Use: "attach [OPTIONS] SERVICE",
46+
Short: "Attach local standard input, output, and error streams to a service's running container.",
47+
Args: cobra.MinimumNArgs(1),
48+
PreRunE: Adapt(func(ctx context.Context, args []string) error {
49+
opts.service = args[0]
50+
return nil
51+
}),
52+
RunE: Adapt(func(ctx context.Context, args []string) error {
53+
return runAttach(ctx, dockerCli, backend, opts)
54+
}),
55+
ValidArgsFunction: completeServiceNames(dockerCli, p),
56+
}
57+
58+
runCmd.Flags().IntVar(&opts.index, "index", 0, "index of the container if service has multiple replicas.")
59+
runCmd.Flags().StringVarP(&opts.detachKeys, "detach-keys", "", "", "Override the key sequence for detaching from a container.")
60+
61+
runCmd.Flags().BoolVar(&opts.noStdin, "no-stdin", false, "Do not attach STDIN")
62+
runCmd.Flags().BoolVar(&opts.proxy, "sig-proxy", true, "Proxy all received signals to the process")
63+
return runCmd
64+
}
65+
66+
func runAttach(ctx context.Context, dockerCli command.Cli, backend api.Service, opts attachOpts) error {
67+
projectName, err := opts.toProjectName(dockerCli)
68+
if err != nil {
69+
return err
70+
}
71+
72+
attachOpts := api.AttachOptions{
73+
Service: opts.service,
74+
Index: opts.index,
75+
DetachKeys: opts.detachKeys,
76+
NoStdin: opts.noStdin,
77+
Proxy: opts.proxy,
78+
}
79+
return backend.Attach(ctx, projectName, attachOpts)
80+
}

cmd/compose/compose.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ func RootCommand(dockerCli command.Cli, backend api.Service) *cobra.Command { //
445445
runCommand(&opts, dockerCli, backend),
446446
removeCommand(&opts, dockerCli, backend),
447447
execCommand(&opts, dockerCli, backend),
448+
attachCommand(&opts, dockerCli, backend),
448449
pauseCommand(&opts, dockerCli, backend),
449450
unpauseCommand(&opts, dockerCli, backend),
450451
topCommand(&opts, dockerCli, backend),

docs/reference/compose.md

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,38 @@ Define and run multi-container applications with Docker.
55

66
### Subcommands
77

8-
| Name | Description |
9-
|:--------------------------------|:--------------------------------------------------------------------------------------|
10-
| [`build`](compose_build.md) | Build or rebuild services |
11-
| [`config`](compose_config.md) | Parse, resolve and render compose file in canonical format |
12-
| [`cp`](compose_cp.md) | Copy files/folders between a service container and the local filesystem |
13-
| [`create`](compose_create.md) | Creates containers for a service. |
14-
| [`down`](compose_down.md) | Stop and remove containers, networks |
15-
| [`events`](compose_events.md) | Receive real time events from containers. |
16-
| [`exec`](compose_exec.md) | Execute a command in a running container. |
17-
| [`images`](compose_images.md) | List images used by the created containers |
18-
| [`kill`](compose_kill.md) | Force stop service containers. |
19-
| [`logs`](compose_logs.md) | View output from containers |
20-
| [`ls`](compose_ls.md) | List running compose projects |
21-
| [`pause`](compose_pause.md) | Pause services |
22-
| [`port`](compose_port.md) | Print the public port for a port binding. |
23-
| [`ps`](compose_ps.md) | List containers |
24-
| [`pull`](compose_pull.md) | Pull service images |
25-
| [`push`](compose_push.md) | Push service images |
26-
| [`restart`](compose_restart.md) | Restart service containers |
27-
| [`rm`](compose_rm.md) | Removes stopped service containers |
28-
| [`run`](compose_run.md) | Run a one-off command on a service. |
29-
| [`scale`](compose_scale.md) | Scale services |
30-
| [`start`](compose_start.md) | Start services |
31-
| [`stats`](compose_stats.md) | Display a live stream of container(s) resource usage statistics |
32-
| [`stop`](compose_stop.md) | Stop services |
33-
| [`top`](compose_top.md) | Display the running processes |
34-
| [`unpause`](compose_unpause.md) | Unpause services |
35-
| [`up`](compose_up.md) | Create and start containers |
36-
| [`version`](compose_version.md) | Show the Docker Compose version information |
37-
| [`wait`](compose_wait.md) | Block until the first service container stops |
38-
| [`watch`](compose_watch.md) | Watch build context for service and rebuild/refresh containers when files are updated |
8+
| Name | Description |
9+
|:--------------------------------|:-----------------------------------------------------------------------------------------|
10+
| [`attach`](compose_attach.md) | Attach local standard input, output, and error streams to a service's running container. |
11+
| [`build`](compose_build.md) | Build or rebuild services |
12+
| [`config`](compose_config.md) | Parse, resolve and render compose file in canonical format |
13+
| [`cp`](compose_cp.md) | Copy files/folders between a service container and the local filesystem |
14+
| [`create`](compose_create.md) | Creates containers for a service. |
15+
| [`down`](compose_down.md) | Stop and remove containers, networks |
16+
| [`events`](compose_events.md) | Receive real time events from containers. |
17+
| [`exec`](compose_exec.md) | Execute a command in a running container. |
18+
| [`images`](compose_images.md) | List images used by the created containers |
19+
| [`kill`](compose_kill.md) | Force stop service containers. |
20+
| [`logs`](compose_logs.md) | View output from containers |
21+
| [`ls`](compose_ls.md) | List running compose projects |
22+
| [`pause`](compose_pause.md) | Pause services |
23+
| [`port`](compose_port.md) | Print the public port for a port binding. |
24+
| [`ps`](compose_ps.md) | List containers |
25+
| [`pull`](compose_pull.md) | Pull service images |
26+
| [`push`](compose_push.md) | Push service images |
27+
| [`restart`](compose_restart.md) | Restart service containers |
28+
| [`rm`](compose_rm.md) | Removes stopped service containers |
29+
| [`run`](compose_run.md) | Run a one-off command on a service. |
30+
| [`scale`](compose_scale.md) | Scale services |
31+
| [`start`](compose_start.md) | Start services |
32+
| [`stats`](compose_stats.md) | Display a live stream of container(s) resource usage statistics |
33+
| [`stop`](compose_stop.md) | Stop services |
34+
| [`top`](compose_top.md) | Display the running processes |
35+
| [`unpause`](compose_unpause.md) | Unpause services |
36+
| [`up`](compose_up.md) | Create and start containers |
37+
| [`version`](compose_version.md) | Show the Docker Compose version information |
38+
| [`wait`](compose_wait.md) | Block until the first service container stops |
39+
| [`watch`](compose_watch.md) | Watch build context for service and rebuild/refresh containers when files are updated |
3940

4041

4142
### Options

docs/reference/compose_attach.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# docker compose attach
2+
3+
<!---MARKER_GEN_START-->
4+
Attach local standard input, output, and error streams to a service's running container.
5+
6+
### Options
7+
8+
| Name | Type | Default | Description |
9+
|:----------------|:---------|:--------|:----------------------------------------------------------|
10+
| `--detach-keys` | `string` | | Override the key sequence for detaching from a container. |
11+
| `--dry-run` | | | Execute command in dry run mode |
12+
| `--index` | `int` | `0` | index of the container if service has multiple replicas. |
13+
| `--no-stdin` | | | Do not attach STDIN |
14+
| `--sig-proxy` | | | Proxy all received signals to the process |
15+
16+
17+
<!---MARKER_GEN_END-->
18+

docs/reference/docker_compose.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ usage: docker compose
146146
pname: docker
147147
plink: docker.yaml
148148
cname:
149+
- docker compose attach
149150
- docker compose build
150151
- docker compose config
151152
- docker compose cp
@@ -176,6 +177,7 @@ cname:
176177
- docker compose wait
177178
- docker compose watch
178179
clink:
180+
- docker_compose_attach.yaml
179181
- docker_compose_build.yaml
180182
- docker_compose_config.yaml
181183
- docker_compose_cp.yaml
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
command: docker compose attach
2+
short: |
3+
Attach local standard input, output, and error streams to a service's running container.
4+
long: |
5+
Attach local standard input, output, and error streams to a service's running container.
6+
usage: docker compose attach [OPTIONS] SERVICE
7+
pname: docker compose
8+
plink: docker_compose.yaml
9+
options:
10+
- option: detach-keys
11+
value_type: string
12+
description: Override the key sequence for detaching from a container.
13+
deprecated: false
14+
hidden: false
15+
experimental: false
16+
experimentalcli: false
17+
kubernetes: false
18+
swarm: false
19+
- option: index
20+
value_type: int
21+
default_value: "0"
22+
description: index of the container if service has multiple replicas.
23+
deprecated: false
24+
hidden: false
25+
experimental: false
26+
experimentalcli: false
27+
kubernetes: false
28+
swarm: false
29+
- option: no-stdin
30+
value_type: bool
31+
default_value: "false"
32+
description: Do not attach STDIN
33+
deprecated: false
34+
hidden: false
35+
experimental: false
36+
experimentalcli: false
37+
kubernetes: false
38+
swarm: false
39+
- option: sig-proxy
40+
value_type: bool
41+
default_value: "true"
42+
description: Proxy all received signals to the process
43+
deprecated: false
44+
hidden: false
45+
experimental: false
46+
experimentalcli: false
47+
kubernetes: false
48+
swarm: false
49+
inherited_options:
50+
- option: dry-run
51+
value_type: bool
52+
default_value: "false"
53+
description: Execute command in dry run mode
54+
deprecated: false
55+
hidden: false
56+
experimental: false
57+
experimentalcli: false
58+
kubernetes: false
59+
swarm: false
60+
deprecated: false
61+
hidden: false
62+
experimental: false
63+
experimentalcli: false
64+
kubernetes: false
65+
swarm: false
66+

pkg/api/api.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ type Service interface {
6262
Remove(ctx context.Context, projectName string, options RemoveOptions) error
6363
// Exec executes a command in a running service container
6464
Exec(ctx context.Context, projectName string, options RunOptions) (int, error)
65+
// Attach STDIN,STDOUT,STDERR to a running service container
66+
Attach(ctx context.Context, projectName string, options AttachOptions) error
6567
// Copy copies a file/folder between a service container and the local filesystem
6668
Copy(ctx context.Context, projectName string, options CopyOptions) error
6769
// Pause executes the equivalent to a `compose pause`
@@ -342,6 +344,16 @@ type RunOptions struct {
342344
Index int
343345
}
344346

347+
// AttachOptions group options of the Attach API
348+
type AttachOptions struct {
349+
Project *types.Project
350+
Service string
351+
Index int
352+
DetachKeys string
353+
NoStdin bool
354+
Proxy bool
355+
}
356+
345357
// EventsOptions group options of the Events API
346358
type EventsOptions struct {
347359
Services []string

pkg/compose/attach_service.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
Copyright 2020 Docker Compose CLI authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package compose
18+
19+
import (
20+
"context"
21+
"strings"
22+
23+
"github.com/docker/cli/cli/command/container"
24+
"github.com/docker/compose/v2/pkg/api"
25+
)
26+
27+
func (s *composeService) Attach(ctx context.Context, projectName string, options api.AttachOptions) error {
28+
projectName = strings.ToLower(projectName)
29+
target, err := s.getSpecifiedContainer(ctx, projectName, oneOffInclude, false, options.Service, options.Index)
30+
if err != nil {
31+
return err
32+
}
33+
34+
var attach container.AttachOptions
35+
attach.DetachKeys = options.DetachKeys
36+
attach.NoStdin = options.NoStdin
37+
attach.Proxy = options.Proxy
38+
return container.RunAttach(ctx, s.dockerCli, target.ID, &attach)
39+
}

pkg/mocks/mock_docker_compose_api.go

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)