From 6e4ce54d33df0c43392fd247d42106802ca556df Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 12 Jun 2019 22:35:25 +0200 Subject: oci: use json formatted errors from the runtime request json formatted error messages from the OCI runtime so that we can nicely print them. Signed-off-by: Giuseppe Scrivano --- libpod/oci.go | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'libpod/oci.go') diff --git a/libpod/oci.go b/libpod/oci.go index 7138108c5..0a730b799 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -66,6 +66,14 @@ type syncInfo struct { Message string `json:"message,omitempty"` } +// ociError is used to parse the OCI runtime JSON log. It is not part of the +// OCI runtime specifications, it follows what runc does +type ociError struct { + Level string `json:"level,omitempty"` + Time string `json:"time,omitempty"` + Msg string `json:"msg,omitempty"` +} + // Make a new OCI runtime with provided options func newOCIRuntime(oruntime OCIRuntimePath, conmonPath string, conmonEnv []string, cgroupManager string, tmpDir string, logSizeMax int64, noPivotRoot bool, reservePorts bool) (*OCIRuntime, error) { runtime := new(OCIRuntime) -- cgit v1.2.3-54-g00ecf From 13e1afdb02592ab4b0e4e7fb936c76f5c7dda20a Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Thu, 13 Jun 2019 14:21:13 +0200 Subject: oci: allow to specify what runtimes support JSON add a new configuration `runtime_supports_json` to list what OCI runtimes support the --log-format=json option. If the runtime is not listed here, libpod will redirect stdout/stderr from the runtime process. Signed-off-by: Giuseppe Scrivano --- libpod.conf | 4 ++++ libpod/oci.go | 4 +++- libpod/oci_linux.go | 14 ++++++++------ libpod/runtime.go | 13 ++++++++++++- 4 files changed, 27 insertions(+), 8 deletions(-) (limited to 'libpod/oci.go') diff --git a/libpod.conf b/libpod.conf index ce6b95cda..45e955c36 100644 --- a/libpod.conf +++ b/libpod.conf @@ -106,6 +106,10 @@ num_locks = 2048 # Default OCI runtime runtime = "runc" +# List of the OCI runtimes that support --format=json. When json is supported +# libpod will use it for reporting nicer errors. +runtime_supports_json = ["runc"] + # Paths to look for a valid OCI runtime (runc, runv, etc) [runtimes] runc = [ diff --git a/libpod/oci.go b/libpod/oci.go index 0a730b799..dcb72fc1b 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -58,6 +58,7 @@ type OCIRuntime struct { logSizeMax int64 noPivot bool reservePorts bool + supportsJSON bool } // syncInfo is used to return data from monitor process to daemon @@ -75,7 +76,7 @@ type ociError struct { } // Make a new OCI runtime with provided options -func newOCIRuntime(oruntime OCIRuntimePath, conmonPath string, conmonEnv []string, cgroupManager string, tmpDir string, logSizeMax int64, noPivotRoot bool, reservePorts bool) (*OCIRuntime, error) { +func newOCIRuntime(oruntime OCIRuntimePath, conmonPath string, conmonEnv []string, cgroupManager string, tmpDir string, logSizeMax int64, noPivotRoot bool, reservePorts bool, supportsJSON bool) (*OCIRuntime, error) { runtime := new(OCIRuntime) runtime.name = oruntime.Name runtime.path = oruntime.Paths[0] @@ -86,6 +87,7 @@ func newOCIRuntime(oruntime OCIRuntimePath, conmonPath string, conmonEnv []strin runtime.logSizeMax = logSizeMax runtime.noPivot = noPivotRoot runtime.reservePorts = reservePorts + runtime.supportsJSON = supportsJSON runtime.exitsDir = filepath.Join(runtime.tmpDir, "exits") runtime.socketsDir = filepath.Join(runtime.tmpDir, "socket") diff --git a/libpod/oci_linux.go b/libpod/oci_linux.go index b9820ce9f..9bbefdb06 100644 --- a/libpod/oci_linux.go +++ b/libpod/oci_linux.go @@ -223,7 +223,7 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string, res args = append(args, "-b", ctr.bundlePath()) args = append(args, "-p", filepath.Join(ctr.state.RunDir, "pidfile")) args = append(args, "--exit-dir", r.exitsDir) - if logLevel != logrus.DebugLevel { + if logLevel != logrus.DebugLevel && r.supportsJSON { args = append(args, "--runtime-arg", "--log-format=json", "--runtime-arg", "--log", fmt.Sprintf("--runtime-arg=%s", ociLog)) } if ctr.config.ConmonPidFile != "" { @@ -423,11 +423,13 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string, res } logrus.Debugf("Received container pid: %d", ss.si.Pid) if ss.si.Pid == -1 { - data, err := ioutil.ReadFile(ociLog) - if err == nil { - var ociErr ociError - if err := json.Unmarshal(data, &ociErr); err == nil { - return errors.Wrapf(ErrOCIRuntime, "%s", strings.Trim(ociErr.Msg, "\n")) + if r.supportsJSON { + data, err := ioutil.ReadFile(ociLog) + if err == nil { + var ociErr ociError + if err := json.Unmarshal(data, &ociErr); err == nil { + return errors.Wrapf(ErrOCIRuntime, "%s", strings.Trim(ociErr.Msg, "\n")) + } } } // If we failed to parse the JSON errors, then print the output as it is diff --git a/libpod/runtime.go b/libpod/runtime.go index 098607b63..24bb5f61c 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -151,6 +151,8 @@ type RuntimeConfig struct { OCIRuntime string `toml:"runtime"` // OCIRuntimes are the set of configured OCI runtimes (default is runc) OCIRuntimes map[string][]string `toml:"runtimes"` + // RuntimeSupportsJSON is the list of the OCI runtimes that support --format=json + RuntimeSupportsJSON []string `toml:"runtime_supports_json"` // RuntimePath is the path to OCI runtime binary for launching // containers. // The first path pointing to a valid file will be used @@ -830,12 +832,21 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (err error) { } } + supportsJSON := false + for _, r := range runtime.config.RuntimeSupportsJSON { + if r == runtime.config.OCIRuntime { + supportsJSON = true + break + } + } + // Make an OCI runtime to perform container operations ociRuntime, err := newOCIRuntime(runtime.ociRuntimePath, runtime.conmonPath, runtime.config.ConmonEnvVars, runtime.config.CgroupManager, runtime.config.TmpDir, runtime.config.MaxLogSize, runtime.config.NoPivotRoot, - runtime.config.EnablePortReservation) + runtime.config.EnablePortReservation, + supportsJSON) if err != nil { return err } -- cgit v1.2.3-54-g00ecf