summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorPaul Holzinger <pholzing@redhat.com>2021-11-19 18:15:53 +0100
committerPaul Holzinger <pholzing@redhat.com>2021-11-19 18:15:53 +0100
commit501643c8bde591fcb8e4c42564f1b854128ad2f7 (patch)
tree741fc6b48d1d5fb5e9eeba2d314c06605a324c11 /libpod
parent671e5ee42d4eb71fc0238e8b0b1e4a68b1def156 (diff)
downloadpodman-501643c8bde591fcb8e4c42564f1b854128ad2f7.tar.gz
podman-501643c8bde591fcb8e4c42564f1b854128ad2f7.tar.bz2
podman-501643c8bde591fcb8e4c42564f1b854128ad2f7.zip
Make sure netavark output is logged to the syslog
Create a custom writer which logs the netavark output to logrus. This will log to the syslog when it is enabled. Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/network/netavark/exec.go45
-rw-r--r--libpod/network/netavark/network.go9
-rw-r--r--libpod/network/netavark/run.go4
-rw-r--r--libpod/options.go8
-rw-r--r--libpod/runtime.go6
5 files changed, 63 insertions, 9 deletions
diff --git a/libpod/network/netavark/exec.go b/libpod/network/netavark/exec.go
index d6458eeb4..01dea8489 100644
--- a/libpod/network/netavark/exec.go
+++ b/libpod/network/netavark/exec.go
@@ -3,6 +3,7 @@ package netavark
import (
"encoding/json"
"errors"
+ "io"
"os"
"os/exec"
"strconv"
@@ -45,6 +46,15 @@ func newNetavarkError(msg string, err error) error {
}
}
+// Type to implement io.Writer interface
+// This will write the logrus at info level
+type logrusNetavarkWriter struct{}
+
+func (l *logrusNetavarkWriter) Write(b []byte) (int, error) {
+ logrus.Info("netavark: ", string(b))
+ return len(b), nil
+}
+
// getRustLogEnv returns the RUST_LOG env var based on the current logrus level
func getRustLogEnv() string {
level := logrus.GetLevel().String()
@@ -63,26 +73,43 @@ func getRustLogEnv() string {
// used to marshal the netavark output into it. This can be nil.
// All errors return by this function should be of the type netavarkError
// to provide a helpful error message.
-func execNetavark(binary string, args []string, stdin, result interface{}) error {
+func (n *netavarkNetwork) execNetavark(args []string, stdin, result interface{}) error {
stdinR, stdinW, err := os.Pipe()
if err != nil {
return newNetavarkError("failed to create stdin pipe", err)
}
- defer stdinR.Close()
+ stdinWClosed := false
+ defer func() {
+ stdinR.Close()
+ if !stdinWClosed {
+ stdinW.Close()
+ }
+ }()
stdoutR, stdoutW, err := os.Pipe()
if err != nil {
return newNetavarkError("failed to create stdout pipe", err)
}
- defer stdoutR.Close()
- defer stdoutW.Close()
+ stdoutWClosed := false
+ defer func() {
+ stdoutR.Close()
+ if !stdoutWClosed {
+ stdoutW.Close()
+ }
+ }()
- cmd := exec.Command(binary, args...)
+ // connect stderr to the podman stderr for logging
+ var logWriter io.Writer = os.Stderr
+ if n.syslog {
+ // connect logrus to stderr as well so that the logs will be written to the syslog as well
+ logWriter = io.MultiWriter(logWriter, &logrusNetavarkWriter{})
+ }
+
+ cmd := exec.Command(n.netavarkBinary, args...)
// connect the pipes to stdin and stdout
cmd.Stdin = stdinR
cmd.Stdout = stdoutW
- // connect stderr to the podman stderr for logging
- cmd.Stderr = os.Stderr
+ cmd.Stderr = logWriter
// set the netavark log level to the same as the podman
cmd.Env = append(os.Environ(), getRustLogEnv())
// if we run with debug log level lets also set RUST_BACKTRACE=1 so we can get the full stack trace in case of panics
@@ -95,7 +122,9 @@ func execNetavark(binary string, args []string, stdin, result interface{}) error
return newNetavarkError("failed to start process", err)
}
err = json.NewEncoder(stdinW).Encode(stdin)
+ // we have to close stdinW so netavark gets the EOF and does not hang forever
stdinW.Close()
+ stdinWClosed = true
if err != nil {
return newNetavarkError("failed to encode stdin data", err)
}
@@ -103,7 +132,9 @@ func execNetavark(binary string, args []string, stdin, result interface{}) error
dec := json.NewDecoder(stdoutR)
err = cmd.Wait()
+ // we have to close stdoutW so we can decode the json without hanging forever
stdoutW.Close()
+ stdoutWClosed = true
if err != nil {
exitError := &exec.ExitError{}
if errors.As(err, &exitError) {
diff --git a/libpod/network/netavark/network.go b/libpod/network/netavark/network.go
index cc6fb423c..540d8d6e5 100644
--- a/libpod/network/netavark/network.go
+++ b/libpod/network/netavark/network.go
@@ -37,6 +37,10 @@ type netavarkNetwork struct {
// isMachine describes whenever podman runs in a podman machine environment.
isMachine bool
+ // syslog describes whenever the netavark debbug output should be log to the syslog as well.
+ // This will use logrus to do so, make sure logrus is set up to log to the syslog.
+ syslog bool
+
// lock is a internal lock for critical operations
lock lockfile.Locker
@@ -68,6 +72,10 @@ type InitConfig struct {
// LockFile is the path to lock file.
LockFile string
+
+ // Syslog describes whenever the netavark debbug output should be log to the syslog as well.
+ // This will use logrus to do so, make sure logrus is set up to log to the syslog.
+ Syslog bool
}
// NewNetworkInterface creates the ContainerNetwork interface for the netavark backend.
@@ -122,6 +130,7 @@ func NewNetworkInterface(conf InitConfig) (types.ContainerNetwork, error) {
defaultSubnet: defaultNet,
isMachine: conf.IsMachine,
lock: lock,
+ syslog: conf.Syslog,
}
return n, nil
diff --git a/libpod/network/netavark/run.go b/libpod/network/netavark/run.go
index 2f839151e..54917a981 100644
--- a/libpod/network/netavark/run.go
+++ b/libpod/network/netavark/run.go
@@ -54,7 +54,7 @@ func (n *netavarkNetwork) Setup(namespacePath string, options types.SetupOptions
}
result := map[string]types.StatusBlock{}
- err = execNetavark(n.netavarkBinary, []string{"setup", namespacePath}, netavarkOpts, &result)
+ err = n.execNetavark([]string{"setup", namespacePath}, netavarkOpts, &result)
if len(result) != len(options.Networks) {
logrus.Errorf("unexpected netavark result: %v", result)
@@ -86,7 +86,7 @@ func (n *netavarkNetwork) Teardown(namespacePath string, options types.TeardownO
return errors.Wrap(err, "failed to convert net opts")
}
- retErr := execNetavark(n.netavarkBinary, []string{"teardown", namespacePath}, netavarkOpts, nil)
+ retErr := n.execNetavark([]string{"teardown", namespacePath}, netavarkOpts, nil)
// when netavark returned an error we still free the used ips
// otherwise we could end up in a state where block the ips forever
diff --git a/libpod/options.go b/libpod/options.go
index 3f0f9fbe0..8f2d5cb15 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -578,6 +578,14 @@ func WithEnableSDNotify() RuntimeOption {
}
}
+// WithSyslog sets a runtime option so we know that we have to log to the syslog as well
+func WithSyslog() RuntimeOption {
+ return func(rt *Runtime) error {
+ rt.syslog = true
+ return nil
+ }
+}
+
// WithRuntimeFlags adds the global runtime flags to the container config
func WithRuntimeFlags(runtimeFlags []string) RuntimeOption {
return func(rt *Runtime) error {
diff --git a/libpod/runtime.go b/libpod/runtime.go
index c751df79b..1a22cd09a 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -88,6 +88,11 @@ type Runtime struct {
libimageEventsShutdown chan bool
lockManager lock.Manager
+ // syslog describes whenever logrus should log to the syslog as well.
+ // Note that the syslog hook will be enabled early in cmd/podman/syslog_linux.go
+ // This bool is just needed so that we can set it for netavark interface.
+ syslog bool
+
// doRenumber indicates that the runtime should perform a lock renumber
// during initialization.
// Once the runtime has been initialized and returned, this variable is
@@ -517,6 +522,7 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
DefaultSubnet: runtime.config.Network.DefaultSubnet,
IsMachine: runtime.config.Engine.MachineEnabled,
LockFile: filepath.Join(runtime.config.Network.NetworkConfigDir, "netavark.lock"),
+ Syslog: runtime.syslog,
})
if err != nil {
return errors.Wrapf(err, "could not create network interface")