From 3ce98a5ec28840f2d7836a002a156974f37f6c0e Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 1 Sep 2021 11:36:26 +0200 Subject: logging: new mode -l passthrough it allows to pass the current std streams down to the container. conmon support: https://github.com/containers/conmon/pull/289 [NO TESTS NEEDED] it needs a new conmon. Signed-off-by: Giuseppe Scrivano --- libpod/container_api.go | 4 ++++ libpod/container_log.go | 4 +++- libpod/define/config.go | 3 +++ libpod/oci_attach_linux.go | 39 ++++++++++++++++++++++++--------------- libpod/oci_conmon_linux.go | 2 ++ libpod/options.go | 2 +- libpod/runtime_ctr.go | 2 +- 7 files changed, 38 insertions(+), 18 deletions(-) (limited to 'libpod') diff --git a/libpod/container_api.go b/libpod/container_api.go index 2d5b07a35..50be0eea4 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -229,6 +229,10 @@ func (c *Container) Kill(signal uint) error { // This function returns when the attach finishes. It does not hold the lock for // the duration of its runtime, only using it at the beginning to verify state. func (c *Container) Attach(streams *define.AttachStreams, keys string, resize <-chan define.TerminalSize) error { + switch c.LogDriver() { + case define.PassthroughLogging: + return errors.Wrapf(define.ErrNoLogs, "this container is using the 'passthrough' log driver, cannot attach") + } if !c.batched { c.lock.Lock() if err := c.syncContainer(); err != nil { diff --git a/libpod/container_log.go b/libpod/container_log.go index a65b2a44f..18840bff2 100644 --- a/libpod/container_log.go +++ b/libpod/container_log.go @@ -18,7 +18,7 @@ import ( var logDrivers []string func init() { - logDrivers = append(logDrivers, define.KubernetesLogging, define.NoLogging) + logDrivers = append(logDrivers, define.KubernetesLogging, define.NoLogging, define.PassthroughLogging) } // Log is a runtime function that can read one or more container logs. @@ -34,6 +34,8 @@ func (r *Runtime) Log(ctx context.Context, containers []*Container, options *log // ReadLog reads a containers log based on the input options and returns log lines over a channel. func (c *Container) ReadLog(ctx context.Context, options *logs.LogOptions, logChannel chan *logs.LogLine) error { switch c.LogDriver() { + case define.PassthroughLogging: + return errors.Wrapf(define.ErrNoLogs, "this container is using the 'passthrough' log driver, cannot read logs") case define.NoLogging: return errors.Wrapf(define.ErrNoLogs, "this container is using the 'none' log driver, cannot read logs") case define.JournaldLogging: diff --git a/libpod/define/config.go b/libpod/define/config.go index 6c426f2ec..7a0d39e42 100644 --- a/libpod/define/config.go +++ b/libpod/define/config.go @@ -78,6 +78,9 @@ const JSONLogging = "json-file" // NoLogging is the string conmon expects when specifying to use no log driver whatsoever const NoLogging = "none" +// PassthroughLogging is the string conmon expects when specifying to use the passthrough driver +const PassthroughLogging = "passthrough" + // Strings used for --sdnotify option to podman const ( SdNotifyModeContainer = "container" diff --git a/libpod/oci_attach_linux.go b/libpod/oci_attach_linux.go index 9ae46eeda..d4d4a1076 100644 --- a/libpod/oci_attach_linux.go +++ b/libpod/oci_attach_linux.go @@ -40,7 +40,9 @@ func openUnixSocket(path string) (*net.UnixConn, error) { // Does not check if state is appropriate // 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 { - if !streams.AttachOutput && !streams.AttachError && !streams.AttachInput { + passthrough := c.LogDriver() == define.PassthroughLogging + + if !streams.AttachOutput && !streams.AttachError && !streams.AttachInput && !passthrough { return errors.Wrapf(define.ErrInvalidArg, "must provide at least one stream to attach to") } if startContainer && started == nil { @@ -52,24 +54,27 @@ func (c *Container) attach(streams *define.AttachStreams, keys string, resize <- return err } - logrus.Debugf("Attaching to container %s", c.ID()) + var conn *net.UnixConn + if !passthrough { + logrus.Debugf("Attaching to container %s", c.ID()) - registerResizeFunc(resize, c.bundlePath()) + registerResizeFunc(resize, c.bundlePath()) - attachSock, err := c.AttachSocketPath() - if err != nil { - return err - } + attachSock, err := c.AttachSocketPath() + if err != nil { + return err + } - conn, err := openUnixSocket(attachSock) - if err != nil { - return errors.Wrapf(err, "failed to connect to container's attach socket: %v", attachSock) - } - defer func() { - if err := conn.Close(); err != nil { - logrus.Errorf("Unable to close socket: %q", err) + conn, err = openUnixSocket(attachSock) + if err != nil { + return errors.Wrapf(err, "failed to connect to container's attach socket: %v", attachSock) } - }() + defer func() { + if err := conn.Close(); err != nil { + logrus.Errorf("unable to close socket: %q", err) + } + }() + } // If starting was requested, start the container and notify when that's // done. @@ -80,6 +85,10 @@ func (c *Container) attach(streams *define.AttachStreams, keys string, resize <- started <- true } + if passthrough { + return nil + } + receiveStdoutError, stdinDone := setupStdioChannels(streams, conn, detachKeys) if attachRdy != nil { attachRdy <- true diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index 56c7a90aa..b7b5d09cd 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -1288,6 +1288,8 @@ func (r *ConmonOCIRuntime) sharedConmonArgs(ctr *Container, cuuid, bundlePath, p logDriverArg = define.JournaldLogging case define.NoLogging: logDriverArg = define.NoLogging + case define.PassthroughLogging: + logDriverArg = define.PassthroughLogging case define.JSONLogging: fallthrough //lint:ignore ST1015 the default case has to be here diff --git a/libpod/options.go b/libpod/options.go index a80f51c6a..553af43fd 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1114,7 +1114,7 @@ func WithLogDriver(driver string) CtrCreateOption { switch driver { case "": return errors.Wrapf(define.ErrInvalidArg, "log driver must be set") - case define.JournaldLogging, define.KubernetesLogging, define.JSONLogging, define.NoLogging: + case define.JournaldLogging, define.KubernetesLogging, define.JSONLogging, define.NoLogging, define.PassthroughLogging: break default: return errors.Wrapf(define.ErrInvalidArg, "invalid log driver") diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 9a4dbf626..3494fa8f2 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -473,7 +473,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai } switch ctr.config.LogDriver { - case define.NoLogging: + case define.NoLogging, define.PassthroughLogging: break case define.JournaldLogging: ctr.initializeJournal(ctx) -- cgit v1.2.3-54-g00ecf