summaryrefslogtreecommitdiff
path: root/cmd/podman/containers/attach.go
blob: ee4d811d71790b33e1ffb10ce5d2d3bf204c7acc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package containers

import (
	"os"

	"github.com/containers/libpod/cmd/podman/registry"
	"github.com/containers/libpod/pkg/domain/entities"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
)

var (
	attachDescription = "The podman attach command allows you to attach to a running container using the container's ID or name, either to view its ongoing output or to control it interactively."
	attachCommand     = &cobra.Command{
		Use:   "attach [flags] CONTAINER",
		Short: "Attach to a running container",
		Long:  attachDescription,
		RunE:  attach,
		Args: func(cmd *cobra.Command, args []string) error {
			if len(args) > 1 || (len(args) == 0 && !cmd.Flag("latest").Changed) {
				return errors.Errorf("attach requires the name or id of one running container or the latest flag")
			}
			return nil
		},
		Example: `podman attach ctrID
  podman attach 1234
  podman attach --no-stdin foobar`,
	}

	containerAttachCommand = &cobra.Command{
		Use:   attachCommand.Use,
		Short: attachCommand.Short,
		Long:  attachCommand.Long,
		RunE:  attachCommand.RunE,
		Example: `podman container attach ctrID
	podman container attach 1234
	podman container attach --no-stdin foobar`,
	}
)

var (
	attachOpts entities.AttachOptions
)

func attachFlags(flags *pflag.FlagSet) {
	flags.StringVar(&attachOpts.DetachKeys, "detach-keys", containerConfig.DetachKeys(), "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`")
	flags.BoolVar(&attachOpts.NoStdin, "no-stdin", false, "Do not attach STDIN. The default is false")
	flags.BoolVar(&attachOpts.SigProxy, "sig-proxy", true, "Proxy received signals to the process")
	flags.BoolVarP(&attachOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
	if registry.IsRemote() {
		_ = flags.MarkHidden("latest")
	}
}

func init() {
	registry.Commands = append(registry.Commands, registry.CliCommand{
		Mode:    []entities.EngineMode{entities.ABIMode},
		Command: attachCommand,
	})
	flags := attachCommand.Flags()
	attachFlags(flags)

	registry.Commands = append(registry.Commands, registry.CliCommand{
		Mode:    []entities.EngineMode{entities.ABIMode},
		Command: containerAttachCommand,
		Parent:  containerCmd,
	})
	containerAttachFlags := containerAttachCommand.Flags()
	attachFlags(containerAttachFlags)
}

func attach(cmd *cobra.Command, args []string) error {
	if len(args) > 1 || (len(args) == 0 && !attachOpts.Latest) {
		return errors.Errorf("attach requires the name or id of one running container or the latest flag")
	}
	var name string
	if len(args) > 0 {
		name = args[0]
	}
	attachOpts.Stdin = os.Stdin
	if attachOpts.NoStdin {
		attachOpts.Stdin = nil
	}
	attachOpts.Stdout = os.Stdout
	attachOpts.Stderr = os.Stderr
	return registry.ContainerEngine().ContainerAttach(registry.GetContext(), name, attachOpts)
}