diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container_api.go | 17 | ||||
-rw-r--r-- | libpod/container_attach_linux.go | 38 | ||||
-rw-r--r-- | libpod/container_attach_unsupported.go | 4 | ||||
-rw-r--r-- | libpod/runtime.go | 7 |
4 files changed, 38 insertions, 28 deletions
diff --git a/libpod/container_api.go b/libpod/container_api.go index 8d1e5751b..3dd84b02c 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -7,7 +7,6 @@ import ( "io/ioutil" "os" "strconv" - "sync" "time" "github.com/containers/libpod/libpod/define" @@ -120,20 +119,24 @@ func (c *Container) StartAndAttach(ctx context.Context, streams *AttachStreams, attachChan := make(chan error) // We need to ensure that we don't return until start() fired in attach. - // Use a WaitGroup to sync this. - wg := new(sync.WaitGroup) - wg.Add(1) + // Use a channel to sync + startedChan := make(chan bool) // Attach to the container before starting it go func() { - if err := c.attach(streams, keys, resize, true, wg); err != nil { + if err := c.attach(streams, keys, resize, true, startedChan); err != nil { attachChan <- err } close(attachChan) }() - wg.Wait() - c.newContainerEvent(events.Attach) + select { + case err := <-attachChan: + return nil, err + case <-startedChan: + c.newContainerEvent(events.Attach) + } + return attachChan, nil } diff --git a/libpod/container_attach_linux.go b/libpod/container_attach_linux.go index 5293480f0..f5aac5794 100644 --- a/libpod/container_attach_linux.go +++ b/libpod/container_attach_linux.go @@ -8,7 +8,6 @@ import ( "net" "os" "path/filepath" - "sync" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/kubeutils" @@ -33,32 +32,35 @@ const ( // Attach to the given container // Does not check if state is appropriate -func (c *Container) attach(streams *AttachStreams, keys string, resize <-chan remotecommand.TerminalSize, startContainer bool, wg *sync.WaitGroup) error { +func (c *Container) attach(streams *AttachStreams, keys string, resize <-chan remotecommand.TerminalSize, startContainer bool, started chan bool) error { if !streams.AttachOutput && !streams.AttachError && !streams.AttachInput { return errors.Wrapf(define.ErrInvalidArg, "must provide at least one stream to attach to") } - // Check the validity of the provided keys first - var err error - detachKeys := []byte{} - if len(keys) > 0 { - detachKeys, err = term.ToBytes(keys) - if err != nil { - return errors.Wrapf(err, "invalid detach keys") - } - } - logrus.Debugf("Attaching to container %s", c.ID()) - return c.attachContainerSocket(resize, detachKeys, streams, startContainer, wg) + return c.attachContainerSocket(resize, keys, streams, startContainer, started) } // attachContainerSocket connects to the container's attach socket and deals with the IO. -// wg is only required if startContainer is true +// started is only required if startContainer is true // TODO add a channel to allow interrupting -func (c *Container) attachContainerSocket(resize <-chan remotecommand.TerminalSize, detachKeys []byte, streams *AttachStreams, startContainer bool, wg *sync.WaitGroup) error { - if startContainer && wg == nil { - return errors.Wrapf(define.ErrInternal, "wait group not passed when startContainer set") +func (c *Container) attachContainerSocket(resize <-chan remotecommand.TerminalSize, keys string, streams *AttachStreams, startContainer bool, started chan bool) error { + if startContainer && started == nil { + return errors.Wrapf(define.ErrInternal, "started chan not passed when startContainer set") + } + + // Use default detach keys when keys aren't passed or specified in libpod.conf + if len(keys) == 0 { + keys = DefaultDetachKeys + } + + // Check the validity of the provided keys + detachKeys := []byte{} + var err error + detachKeys, err = term.ToBytes(keys) + if err != nil { + return errors.Wrapf(err, "invalid detach keys") } kubeutils.HandleResizing(resize, func(size remotecommand.TerminalSize) { @@ -97,7 +99,7 @@ func (c *Container) attachContainerSocket(resize <-chan remotecommand.TerminalSi if err := c.start(); err != nil { return err } - wg.Done() + started <- true } receiveStdoutError := make(chan error) diff --git a/libpod/container_attach_unsupported.go b/libpod/container_attach_unsupported.go index 2c8718c67..c27ce0799 100644 --- a/libpod/container_attach_unsupported.go +++ b/libpod/container_attach_unsupported.go @@ -3,12 +3,10 @@ package libpod import ( - "sync" - "github.com/containers/libpod/libpod/define" "k8s.io/client-go/tools/remotecommand" ) -func (c *Container) attach(streams *AttachStreams, keys string, resize <-chan remotecommand.TerminalSize, startContainer bool, wg *sync.WaitGroup) error { +func (c *Container) attach(streams *AttachStreams, keys string, resize <-chan remotecommand.TerminalSize, startContainer bool, started chan bool) error { return define.ErrNotImplemented } diff --git a/libpod/runtime.go b/libpod/runtime.go index 5a618f592..02aa76731 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -81,6 +81,10 @@ var ( DefaultSHMLockPath = "/libpod_lock" // DefaultRootlessSHMLockPath is the default path for rootless SHM locks DefaultRootlessSHMLockPath = "/libpod_rootless_lock" + + // DefaultDetachKeys is the default keys sequence for detaching a + // container + DefaultDetachKeys = "ctrl-p,ctrl-q" ) // A RuntimeOption is a functional option which alters the Runtime created by @@ -236,6 +240,8 @@ type RuntimeConfig struct { EventsLogger string `toml:"events_logger"` // EventsLogFilePath is where the events log is stored. EventsLogFilePath string `toml:-"events_logfile_path"` + //DetachKeys is the sequence of keys used to detach a container + DetachKeys string `toml:"detach_keys"` } // runtimeConfiguredFrom is a struct used during early runtime init to help @@ -308,6 +314,7 @@ func defaultRuntimeConfig() (RuntimeConfig, error) { EnableLabeling: true, NumLocks: 2048, EventsLogger: events.DefaultEventerType.String(), + DetachKeys: DefaultDetachKeys, }, nil } |