summaryrefslogtreecommitdiff
path: root/libpod/network/netavark/exec.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/network/netavark/exec.go')
-rw-r--r--libpod/network/netavark/exec.go159
1 files changed, 0 insertions, 159 deletions
diff --git a/libpod/network/netavark/exec.go b/libpod/network/netavark/exec.go
deleted file mode 100644
index 01dea8489..000000000
--- a/libpod/network/netavark/exec.go
+++ /dev/null
@@ -1,159 +0,0 @@
-package netavark
-
-import (
- "encoding/json"
- "errors"
- "io"
- "os"
- "os/exec"
- "strconv"
-
- "github.com/sirupsen/logrus"
-)
-
-type netavarkError struct {
- exitCode int
- // Set the json key to "error" so we can directly unmarshal into this struct
- Msg string `json:"error"`
- err error
-}
-
-func (e *netavarkError) Error() string {
- ec := ""
- // only add the exit code the the error message if we have at least info log level
- // the normal user does not need to care about the number
- if e.exitCode > 0 && logrus.IsLevelEnabled(logrus.InfoLevel) {
- ec = " (exit code " + strconv.Itoa(e.exitCode) + ")"
- }
- msg := "netavark" + ec
- if len(msg) > 0 {
- msg += ": " + e.Msg
- }
- if e.err != nil {
- msg += ": " + e.err.Error()
- }
- return msg
-}
-
-func (e *netavarkError) Unwrap() error {
- return e.err
-}
-
-func newNetavarkError(msg string, err error) error {
- return &netavarkError{
- Msg: msg,
- err: err,
- }
-}
-
-// 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()
- // rust env_log uses warn instead of warning
- if level == "warning" {
- level = "warn"
- }
- // the rust netlink library is very verbose
- // make sure to only log netavark logs
- return "RUST_LOG=netavark=" + level
-}
-
-// execNetavark will execute netavark with the following arguments
-// It takes the path to the binary, the list of args and an interface which is
-// marshaled to json and send via stdin to netavark. The result interface is
-// 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 (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)
- }
- 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)
- }
- stdoutWClosed := false
- defer func() {
- stdoutR.Close()
- if !stdoutWClosed {
- stdoutW.Close()
- }
- }()
-
- // 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
- 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
- if logrus.IsLevelEnabled(logrus.DebugLevel) {
- cmd.Env = append(cmd.Env, "RUST_BACKTRACE=1")
- }
-
- err = cmd.Start()
- if err != nil {
- 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)
- }
-
- 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) {
- ne := &netavarkError{}
- // lets disallow unknown fields to make sure we do not get some unexpected stuff
- dec.DisallowUnknownFields()
- // this will unmarshal the error message into the error struct
- ne.err = dec.Decode(ne)
- ne.exitCode = exitError.ExitCode()
- return ne
- }
- return newNetavarkError("unexpected failure during execution", err)
- }
-
- if result != nil {
- err = dec.Decode(result)
- if err != nil {
- return newNetavarkError("failed to decode result", err)
- }
- }
- return nil
-}