mirror of https://github.com/docker/compose.git
Merge pull request #11181 from g0t4/11153-compose-attach-override-container-attach-cmd
Implement `docker compose attach`
This commit is contained in:
commit
24d34040e3
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 Docker Compose CLI authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package compose
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/docker/cli/cli/command"
|
||||||
|
"github.com/docker/compose/v2/pkg/api"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
type attachOpts struct {
|
||||||
|
*composeOptions
|
||||||
|
|
||||||
|
service string
|
||||||
|
index int
|
||||||
|
|
||||||
|
detachKeys string
|
||||||
|
noStdin bool
|
||||||
|
proxy bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func attachCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
|
||||||
|
opts := attachOpts{
|
||||||
|
composeOptions: &composeOptions{
|
||||||
|
ProjectOptions: p,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
runCmd := &cobra.Command{
|
||||||
|
Use: "attach [OPTIONS] SERVICE",
|
||||||
|
Short: "Attach local standard input, output, and error streams to a service's running container.",
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
PreRunE: Adapt(func(ctx context.Context, args []string) error {
|
||||||
|
opts.service = args[0]
|
||||||
|
return nil
|
||||||
|
}),
|
||||||
|
RunE: Adapt(func(ctx context.Context, args []string) error {
|
||||||
|
return runAttach(ctx, dockerCli, backend, opts)
|
||||||
|
}),
|
||||||
|
ValidArgsFunction: completeServiceNames(dockerCli, p),
|
||||||
|
}
|
||||||
|
|
||||||
|
runCmd.Flags().IntVar(&opts.index, "index", 0, "index of the container if service has multiple replicas.")
|
||||||
|
runCmd.Flags().StringVarP(&opts.detachKeys, "detach-keys", "", "", "Override the key sequence for detaching from a container.")
|
||||||
|
|
||||||
|
runCmd.Flags().BoolVar(&opts.noStdin, "no-stdin", false, "Do not attach STDIN")
|
||||||
|
runCmd.Flags().BoolVar(&opts.proxy, "sig-proxy", true, "Proxy all received signals to the process")
|
||||||
|
return runCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func runAttach(ctx context.Context, dockerCli command.Cli, backend api.Service, opts attachOpts) error {
|
||||||
|
projectName, err := opts.toProjectName(dockerCli)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
attachOpts := api.AttachOptions{
|
||||||
|
Service: opts.service,
|
||||||
|
Index: opts.index,
|
||||||
|
DetachKeys: opts.detachKeys,
|
||||||
|
NoStdin: opts.noStdin,
|
||||||
|
Proxy: opts.proxy,
|
||||||
|
}
|
||||||
|
return backend.Attach(ctx, projectName, attachOpts)
|
||||||
|
}
|
|
@ -445,6 +445,7 @@ func RootCommand(dockerCli command.Cli, backend api.Service) *cobra.Command { //
|
||||||
runCommand(&opts, dockerCli, backend),
|
runCommand(&opts, dockerCli, backend),
|
||||||
removeCommand(&opts, dockerCli, backend),
|
removeCommand(&opts, dockerCli, backend),
|
||||||
execCommand(&opts, dockerCli, backend),
|
execCommand(&opts, dockerCli, backend),
|
||||||
|
attachCommand(&opts, dockerCli, backend),
|
||||||
pauseCommand(&opts, dockerCli, backend),
|
pauseCommand(&opts, dockerCli, backend),
|
||||||
unpauseCommand(&opts, dockerCli, backend),
|
unpauseCommand(&opts, dockerCli, backend),
|
||||||
topCommand(&opts, dockerCli, backend),
|
topCommand(&opts, dockerCli, backend),
|
||||||
|
|
|
@ -6,7 +6,8 @@ Define and run multi-container applications with Docker.
|
||||||
### Subcommands
|
### Subcommands
|
||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
|:--------------------------------|:--------------------------------------------------------------------------------------|
|
|:--------------------------------|:-----------------------------------------------------------------------------------------|
|
||||||
|
| [`attach`](compose_attach.md) | Attach local standard input, output, and error streams to a service's running container. |
|
||||||
| [`build`](compose_build.md) | Build or rebuild services |
|
| [`build`](compose_build.md) | Build or rebuild services |
|
||||||
| [`config`](compose_config.md) | Parse, resolve and render compose file in canonical format |
|
| [`config`](compose_config.md) | Parse, resolve and render compose file in canonical format |
|
||||||
| [`cp`](compose_cp.md) | Copy files/folders between a service container and the local filesystem |
|
| [`cp`](compose_cp.md) | Copy files/folders between a service container and the local filesystem |
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# docker compose attach
|
||||||
|
|
||||||
|
<!---MARKER_GEN_START-->
|
||||||
|
Attach local standard input, output, and error streams to a service's running container.
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
| Name | Type | Default | Description |
|
||||||
|
|:----------------|:---------|:--------|:----------------------------------------------------------|
|
||||||
|
| `--detach-keys` | `string` | | Override the key sequence for detaching from a container. |
|
||||||
|
| `--dry-run` | | | Execute command in dry run mode |
|
||||||
|
| `--index` | `int` | `0` | index of the container if service has multiple replicas. |
|
||||||
|
| `--no-stdin` | | | Do not attach STDIN |
|
||||||
|
| `--sig-proxy` | | | Proxy all received signals to the process |
|
||||||
|
|
||||||
|
|
||||||
|
<!---MARKER_GEN_END-->
|
||||||
|
|
|
@ -146,6 +146,7 @@ usage: docker compose
|
||||||
pname: docker
|
pname: docker
|
||||||
plink: docker.yaml
|
plink: docker.yaml
|
||||||
cname:
|
cname:
|
||||||
|
- docker compose attach
|
||||||
- docker compose build
|
- docker compose build
|
||||||
- docker compose config
|
- docker compose config
|
||||||
- docker compose cp
|
- docker compose cp
|
||||||
|
@ -176,6 +177,7 @@ cname:
|
||||||
- docker compose wait
|
- docker compose wait
|
||||||
- docker compose watch
|
- docker compose watch
|
||||||
clink:
|
clink:
|
||||||
|
- docker_compose_attach.yaml
|
||||||
- docker_compose_build.yaml
|
- docker_compose_build.yaml
|
||||||
- docker_compose_config.yaml
|
- docker_compose_config.yaml
|
||||||
- docker_compose_cp.yaml
|
- docker_compose_cp.yaml
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
command: docker compose attach
|
||||||
|
short: |
|
||||||
|
Attach local standard input, output, and error streams to a service's running container.
|
||||||
|
long: |
|
||||||
|
Attach local standard input, output, and error streams to a service's running container.
|
||||||
|
usage: docker compose attach [OPTIONS] SERVICE
|
||||||
|
pname: docker compose
|
||||||
|
plink: docker_compose.yaml
|
||||||
|
options:
|
||||||
|
- option: detach-keys
|
||||||
|
value_type: string
|
||||||
|
description: Override the key sequence for detaching from a container.
|
||||||
|
deprecated: false
|
||||||
|
hidden: false
|
||||||
|
experimental: false
|
||||||
|
experimentalcli: false
|
||||||
|
kubernetes: false
|
||||||
|
swarm: false
|
||||||
|
- option: index
|
||||||
|
value_type: int
|
||||||
|
default_value: "0"
|
||||||
|
description: index of the container if service has multiple replicas.
|
||||||
|
deprecated: false
|
||||||
|
hidden: false
|
||||||
|
experimental: false
|
||||||
|
experimentalcli: false
|
||||||
|
kubernetes: false
|
||||||
|
swarm: false
|
||||||
|
- option: no-stdin
|
||||||
|
value_type: bool
|
||||||
|
default_value: "false"
|
||||||
|
description: Do not attach STDIN
|
||||||
|
deprecated: false
|
||||||
|
hidden: false
|
||||||
|
experimental: false
|
||||||
|
experimentalcli: false
|
||||||
|
kubernetes: false
|
||||||
|
swarm: false
|
||||||
|
- option: sig-proxy
|
||||||
|
value_type: bool
|
||||||
|
default_value: "true"
|
||||||
|
description: Proxy all received signals to the process
|
||||||
|
deprecated: false
|
||||||
|
hidden: false
|
||||||
|
experimental: false
|
||||||
|
experimentalcli: false
|
||||||
|
kubernetes: false
|
||||||
|
swarm: false
|
||||||
|
inherited_options:
|
||||||
|
- option: dry-run
|
||||||
|
value_type: bool
|
||||||
|
default_value: "false"
|
||||||
|
description: Execute command in dry run mode
|
||||||
|
deprecated: false
|
||||||
|
hidden: false
|
||||||
|
experimental: false
|
||||||
|
experimentalcli: false
|
||||||
|
kubernetes: false
|
||||||
|
swarm: false
|
||||||
|
deprecated: false
|
||||||
|
hidden: false
|
||||||
|
experimental: false
|
||||||
|
experimentalcli: false
|
||||||
|
kubernetes: false
|
||||||
|
swarm: false
|
||||||
|
|
|
@ -62,6 +62,8 @@ type Service interface {
|
||||||
Remove(ctx context.Context, projectName string, options RemoveOptions) error
|
Remove(ctx context.Context, projectName string, options RemoveOptions) error
|
||||||
// Exec executes a command in a running service container
|
// Exec executes a command in a running service container
|
||||||
Exec(ctx context.Context, projectName string, options RunOptions) (int, error)
|
Exec(ctx context.Context, projectName string, options RunOptions) (int, error)
|
||||||
|
// Attach STDIN,STDOUT,STDERR to a running service container
|
||||||
|
Attach(ctx context.Context, projectName string, options AttachOptions) error
|
||||||
// Copy copies a file/folder between a service container and the local filesystem
|
// Copy copies a file/folder between a service container and the local filesystem
|
||||||
Copy(ctx context.Context, projectName string, options CopyOptions) error
|
Copy(ctx context.Context, projectName string, options CopyOptions) error
|
||||||
// Pause executes the equivalent to a `compose pause`
|
// Pause executes the equivalent to a `compose pause`
|
||||||
|
@ -342,6 +344,16 @@ type RunOptions struct {
|
||||||
Index int
|
Index int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AttachOptions group options of the Attach API
|
||||||
|
type AttachOptions struct {
|
||||||
|
Project *types.Project
|
||||||
|
Service string
|
||||||
|
Index int
|
||||||
|
DetachKeys string
|
||||||
|
NoStdin bool
|
||||||
|
Proxy bool
|
||||||
|
}
|
||||||
|
|
||||||
// EventsOptions group options of the Events API
|
// EventsOptions group options of the Events API
|
||||||
type EventsOptions struct {
|
type EventsOptions struct {
|
||||||
Services []string
|
Services []string
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 Docker Compose CLI authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package compose
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/docker/cli/cli/command/container"
|
||||||
|
"github.com/docker/compose/v2/pkg/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *composeService) Attach(ctx context.Context, projectName string, options api.AttachOptions) error {
|
||||||
|
projectName = strings.ToLower(projectName)
|
||||||
|
target, err := s.getSpecifiedContainer(ctx, projectName, oneOffInclude, false, options.Service, options.Index)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var attach container.AttachOptions
|
||||||
|
attach.DetachKeys = options.DetachKeys
|
||||||
|
attach.NoStdin = options.NoStdin
|
||||||
|
attach.Proxy = options.Proxy
|
||||||
|
return container.RunAttach(ctx, s.dockerCli, target.ID, &attach)
|
||||||
|
}
|
|
@ -40,6 +40,20 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder {
|
||||||
return m.recorder
|
return m.recorder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attach mocks base method.
|
||||||
|
func (m *MockService) Attach(ctx context.Context, projectName string, options api.AttachOptions) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "Attach", ctx, projectName, options)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach indicates an expected call of Attach.
|
||||||
|
func (mr *MockServiceMockRecorder) Attach(ctx, projectName, options any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Attach", reflect.TypeOf((*MockService)(nil).Attach), ctx, projectName, options)
|
||||||
|
}
|
||||||
|
|
||||||
// Build mocks base method.
|
// Build mocks base method.
|
||||||
func (m *MockService) Build(ctx context.Context, project *types.Project, options api.BuildOptions) error {
|
func (m *MockService) Build(ctx context.Context, project *types.Project, options api.BuildOptions) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
|
Loading…
Reference in New Issue