mirror of
https://github.com/containers/podman.git
synced 2025-05-21 09:05:56 +08:00
Merge pull request #14384 from mheon/move_attach
Move Attach under the OCI Runtime interface
This commit is contained in:
@ -123,7 +123,18 @@ func (c *Container) StartAndAttach(ctx context.Context, streams *define.AttachSt
|
|||||||
|
|
||||||
// Attach to the container before starting it
|
// Attach to the container before starting it
|
||||||
go func() {
|
go func() {
|
||||||
if err := c.attach(streams, keys, resize, true, startedChan, nil); err != nil {
|
// Start resizing
|
||||||
|
if c.LogDriver() != define.PassthroughLogging {
|
||||||
|
registerResizeFunc(resize, c.bundlePath())
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := new(AttachOptions)
|
||||||
|
opts.Streams = streams
|
||||||
|
opts.DetachKeys = &keys
|
||||||
|
opts.Start = true
|
||||||
|
opts.Started = startedChan
|
||||||
|
|
||||||
|
if err := c.ociRuntime.Attach(c, opts); err != nil {
|
||||||
attachChan <- err
|
attachChan <- err
|
||||||
}
|
}
|
||||||
close(attachChan)
|
close(attachChan)
|
||||||
@ -260,8 +271,18 @@ func (c *Container) Attach(streams *define.AttachStreams, keys string, resize <-
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start resizing
|
||||||
|
if c.LogDriver() != define.PassthroughLogging {
|
||||||
|
registerResizeFunc(resize, c.bundlePath())
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := new(AttachOptions)
|
||||||
|
opts.Streams = streams
|
||||||
|
opts.DetachKeys = &keys
|
||||||
|
opts.AttachReady = attachRdy
|
||||||
|
|
||||||
c.newContainerEvent(events.Attach)
|
c.newContainerEvent(events.Attach)
|
||||||
return c.attach(streams, keys, resize, false, nil, attachRdy)
|
return c.ociRuntime.Attach(c, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPAttach forwards an attach session over a hijacked HTTP session.
|
// HTTPAttach forwards an attach session over a hijacked HTTP session.
|
||||||
|
@ -12,9 +12,7 @@ import (
|
|||||||
// management logic - e.g., we do not expect it to determine on its own that
|
// management logic - e.g., we do not expect it to determine on its own that
|
||||||
// calling 'UnpauseContainer()' on a container that is not paused is an error.
|
// calling 'UnpauseContainer()' on a container that is not paused is an error.
|
||||||
// The code calling the OCIRuntime will manage this.
|
// The code calling the OCIRuntime will manage this.
|
||||||
// TODO: May want to move the Attach() code under this umbrella. It's highly OCI
|
// TODO: May want to move the conmon cleanup code here - it depends on
|
||||||
// runtime dependent.
|
|
||||||
// TODO: May want to move the conmon cleanup code here too - it depends on
|
|
||||||
// Conmon being in use.
|
// Conmon being in use.
|
||||||
type OCIRuntime interface {
|
type OCIRuntime interface {
|
||||||
// Name returns the name of the runtime.
|
// Name returns the name of the runtime.
|
||||||
@ -52,6 +50,8 @@ type OCIRuntime interface {
|
|||||||
// UnpauseContainer unpauses the given container.
|
// UnpauseContainer unpauses the given container.
|
||||||
UnpauseContainer(ctr *Container) error
|
UnpauseContainer(ctr *Container) error
|
||||||
|
|
||||||
|
// Attach to a container.
|
||||||
|
Attach(ctr *Container, params *AttachOptions) error
|
||||||
// HTTPAttach performs an attach intended to be transported over HTTP.
|
// HTTPAttach performs an attach intended to be transported over HTTP.
|
||||||
// For terminal attach, the container's output will be directly streamed
|
// For terminal attach, the container's output will be directly streamed
|
||||||
// to output; otherwise, STDOUT and STDERR will be multiplexed, with
|
// to output; otherwise, STDOUT and STDERR will be multiplexed, with
|
||||||
@ -149,6 +149,30 @@ type OCIRuntime interface {
|
|||||||
RuntimeInfo() (*define.ConmonInfo, *define.OCIRuntimeInfo, error)
|
RuntimeInfo() (*define.ConmonInfo, *define.OCIRuntimeInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AttachOptions are options used when attached to a container or an exec
|
||||||
|
// session.
|
||||||
|
type AttachOptions struct {
|
||||||
|
// Streams are the streams to attach to.
|
||||||
|
Streams *define.AttachStreams
|
||||||
|
// DetachKeys containers the key combination that will detach from the
|
||||||
|
// attach session. Empty string is assumed as no detach keys - user
|
||||||
|
// detach is impossible. If unset, defaults from containers.conf will be
|
||||||
|
// used.
|
||||||
|
DetachKeys *string
|
||||||
|
// InitialSize is the initial size of the terminal. Set before the
|
||||||
|
// attach begins.
|
||||||
|
InitialSize *define.TerminalSize
|
||||||
|
// AttachReady signals when the attach has successfully completed and
|
||||||
|
// streaming has begun.
|
||||||
|
AttachReady chan<- bool
|
||||||
|
// Start indicates that the container should be started if it is not
|
||||||
|
// already running.
|
||||||
|
Start bool
|
||||||
|
// Started signals when the container has been successfully started.
|
||||||
|
// Required if Start is true, unused otherwise.
|
||||||
|
Started chan<- bool
|
||||||
|
}
|
||||||
|
|
||||||
// ExecOptions are options passed into ExecContainer. They control the command
|
// ExecOptions are options passed into ExecContainer. They control the command
|
||||||
// that will be executed and how the exec will proceed.
|
// that will be executed and how the exec will proceed.
|
||||||
type ExecOptions struct {
|
type ExecOptions struct {
|
||||||
|
@ -38,19 +38,28 @@ func openUnixSocket(path string) (*net.UnixConn, error) {
|
|||||||
return net.DialUnix("unixpacket", nil, &net.UnixAddr{Name: fmt.Sprintf("/proc/self/fd/%d", fd), Net: "unixpacket"})
|
return net.DialUnix("unixpacket", nil, &net.UnixAddr{Name: fmt.Sprintf("/proc/self/fd/%d", fd), Net: "unixpacket"})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach to the given container
|
// Attach to the given container.
|
||||||
// Does not check if state is appropriate
|
// Does not check if state is appropriate.
|
||||||
// started is only required if startContainer is true
|
// started is only required if startContainer is true.
|
||||||
func (c *Container) attach(streams *define.AttachStreams, keys string, resize <-chan define.TerminalSize, startContainer bool, started chan bool, attachRdy chan<- bool) error {
|
func (r *ConmonOCIRuntime) Attach(c *Container, params *AttachOptions) error {
|
||||||
passthrough := c.LogDriver() == define.PassthroughLogging
|
passthrough := c.LogDriver() == define.PassthroughLogging
|
||||||
|
|
||||||
if !streams.AttachOutput && !streams.AttachError && !streams.AttachInput && !passthrough {
|
if params == nil || params.Streams == nil {
|
||||||
|
return errors.Wrapf(define.ErrInternal, "must provide parameters to Attach")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !params.Streams.AttachOutput && !params.Streams.AttachError && !params.Streams.AttachInput && !passthrough {
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "must provide at least one stream to attach to")
|
return errors.Wrapf(define.ErrInvalidArg, "must provide at least one stream to attach to")
|
||||||
}
|
}
|
||||||
if startContainer && started == nil {
|
if params.Start && params.Started == nil {
|
||||||
return errors.Wrapf(define.ErrInternal, "started chan not passed when startContainer set")
|
return errors.Wrapf(define.ErrInternal, "started chan not passed when startContainer set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keys := config.DefaultDetachKeys
|
||||||
|
if params.DetachKeys != nil {
|
||||||
|
keys = *params.DetachKeys
|
||||||
|
}
|
||||||
|
|
||||||
detachKeys, err := processDetachKeys(keys)
|
detachKeys, err := processDetachKeys(keys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -60,7 +69,12 @@ func (c *Container) attach(streams *define.AttachStreams, keys string, resize <-
|
|||||||
if !passthrough {
|
if !passthrough {
|
||||||
logrus.Debugf("Attaching to container %s", c.ID())
|
logrus.Debugf("Attaching to container %s", c.ID())
|
||||||
|
|
||||||
registerResizeFunc(resize, c.bundlePath())
|
// If we have a resize, do it.
|
||||||
|
if params.InitialSize != nil {
|
||||||
|
if err := r.AttachResize(c, *params.InitialSize); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
attachSock, err := c.AttachSocketPath()
|
attachSock, err := c.AttachSocketPath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -80,22 +94,22 @@ func (c *Container) attach(streams *define.AttachStreams, keys string, resize <-
|
|||||||
|
|
||||||
// If starting was requested, start the container and notify when that's
|
// If starting was requested, start the container and notify when that's
|
||||||
// done.
|
// done.
|
||||||
if startContainer {
|
if params.Start {
|
||||||
if err := c.start(); err != nil {
|
if err := c.start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
started <- true
|
params.Started <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
if passthrough {
|
if passthrough {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
receiveStdoutError, stdinDone := setupStdioChannels(streams, conn, detachKeys)
|
receiveStdoutError, stdinDone := setupStdioChannels(params.Streams, conn, detachKeys)
|
||||||
if attachRdy != nil {
|
if params.AttachReady != nil {
|
||||||
attachRdy <- true
|
params.AttachReady <- true
|
||||||
}
|
}
|
||||||
return readStdio(conn, streams, receiveStdoutError, stdinDone)
|
return readStdio(conn, params.Streams, receiveStdoutError, stdinDone)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach to the given container's exec session
|
// Attach to the given container's exec session
|
@ -108,6 +108,11 @@ func (r *MissingRuntime) UnpauseContainer(ctr *Container) error {
|
|||||||
return r.printError()
|
return r.printError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attach is not available as the runtime is missing
|
||||||
|
func (r *MissingRuntime) Attach(ctr *Container, params *AttachOptions) error {
|
||||||
|
return r.printError()
|
||||||
|
}
|
||||||
|
|
||||||
// HTTPAttach is not available as the runtime is missing
|
// HTTPAttach is not available as the runtime is missing
|
||||||
func (r *MissingRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, detachKeys *string, cancel <-chan bool, hijackDone chan<- bool, streamAttach, streamLogs bool) error {
|
func (r *MissingRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.ResponseWriter, streams *HTTPAttachStreams, detachKeys *string, cancel <-chan bool, hijackDone chan<- bool, streamAttach, streamLogs bool) error {
|
||||||
return r.printError()
|
return r.printError()
|
||||||
|
Reference in New Issue
Block a user