From 650cf122e1b33f4d8f4426ee1cc1a4bf00c14798 Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Fri, 2 Nov 2018 10:18:28 -0400 Subject: libpod: allow multiple oci runtimes This deprecates the libpod.conf variable of `runtime_path=`, and now has `runtimes=`, like a map for naming the runtime, preparing for a `--runtime` flag to `podman run` (i.e. runc, kata, etc.) Reference: https://github.com/containers/libpod/issues/1750 Signed-off-by: Vincent Batts --- libpod/info.go | 6 +++--- libpod/oci.go | 6 +++--- libpod/options.go | 6 +++++- libpod/runtime.go | 64 +++++++++++++++++++++++++++++++++---------------------- 4 files changed, 50 insertions(+), 32 deletions(-) diff --git a/libpod/info.go b/libpod/info.go index a98f93897..191ce6810 100644 --- a/libpod/info.go +++ b/libpod/info.go @@ -4,7 +4,6 @@ import ( "bufio" "bytes" "fmt" - "github.com/containers/buildah" "io/ioutil" "os" "runtime" @@ -12,6 +11,7 @@ import ( "strings" "time" + "github.com/containers/buildah" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/util" "github.com/containers/libpod/utils" @@ -184,12 +184,12 @@ func (r *Runtime) GetConmonVersion() (string, error) { // GetOCIRuntimePath returns the path to the OCI Runtime Path the runtime is using func (r *Runtime) GetOCIRuntimePath() string { - return r.ociRuntimePath + return r.ociRuntimePath.Paths[0] } // GetOCIRuntimeVersion returns a string representation of the oci runtimes version func (r *Runtime) GetOCIRuntimeVersion() (string, error) { - output, err := utils.ExecCmd(r.ociRuntimePath, "--version") + output, err := utils.ExecCmd(r.ociRuntimePath.Paths[0], "--version") if err != nil { return "", err } diff --git a/libpod/oci.go b/libpod/oci.go index 7a908db2e..4092657f8 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -75,10 +75,10 @@ type syncInfo struct { } // Make a new OCI runtime with provided options -func newOCIRuntime(name string, path string, 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) (*OCIRuntime, error) { runtime := new(OCIRuntime) - runtime.name = name - runtime.path = path + runtime.name = oruntime.Name + runtime.path = oruntime.Paths[0] runtime.conmonPath = conmonPath runtime.conmonEnv = conmonEnv runtime.cgroupManager = cgroupManager diff --git a/libpod/options.go b/libpod/options.go index 319e1f6c6..65a8a91d3 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -147,7 +147,11 @@ func WithOCIRuntime(runtimePath string) RuntimeOption { return errors.Wrapf(ErrInvalidArg, "must provide a valid path") } - rt.config.RuntimePath = []string{runtimePath} + rt.config.OCIRuntimes = []OCIRuntimePath{ + { + Paths: []string{runtimePath}, + }, + } return nil } diff --git a/libpod/runtime.go b/libpod/runtime.go index c9471247c..81d4cf3e3 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -86,7 +86,7 @@ type Runtime struct { imageContext *types.SystemContext ociRuntime *OCIRuntime netPlugin ocicni.CNIPlugin - ociRuntimePath string + ociRuntimePath OCIRuntimePath conmonPath string valid bool lock sync.RWMutex @@ -96,6 +96,14 @@ type Runtime struct { configuredFrom *runtimeConfiguredFrom } +// OCIRuntimePath contains information about an OCI runtime. +type OCIRuntimePath struct { + // Name of the runtime to refer to by the --runtime flag + Name string + // Paths to check for this executable + Paths []string +} + // RuntimeConfig contains configuration options used to set up the runtime type RuntimeConfig struct { // StorageConfig is the configuration used by containers/storage @@ -118,10 +126,8 @@ type RuntimeConfig struct { // cause conflicts in containers/storage // As such this is not exposed via the config file StateType RuntimeStateStore `toml:"-"` - // RuntimePath is the path to OCI runtime binary for launching - // containers - // The first path pointing to a valid file will be used - RuntimePath []string `toml:"runtime_path"` + // OCIRuntimes are the set of configured OCI runtimes (default is runc) + OCIRuntimes []OCIRuntimePath `toml:"runtimes"` // ConmonPath is the path to the Conmon binary used for managing // containers // The first path pointing to a valid file will be used @@ -213,14 +219,19 @@ var ( StorageConfig: storage.StoreOptions{}, ImageDefaultTransport: DefaultTransport, StateType: BoltDBStateStore, - RuntimePath: []string{ - "/usr/bin/runc", - "/usr/sbin/runc", - "/usr/local/bin/runc", - "/usr/local/sbin/runc", - "/sbin/runc", - "/bin/runc", - "/usr/lib/cri-o-runc/sbin/runc", + OCIRuntimes: []OCIRuntimePath{ + { + Name: "runc", + Paths: []string{ + "/usr/bin/runc", + "/usr/sbin/runc", + "/usr/local/bin/runc", + "/usr/local/sbin/runc", + "/sbin/runc", + "/bin/runc", + "/usr/lib/cri-o-runc/sbin/runc", + }, + }, }, ConmonPath: []string{ "/usr/libexec/podman/conmon", @@ -453,22 +464,25 @@ func NewRuntimeFromConfig(configPath string, options ...RuntimeOption) (runtime func makeRuntime(runtime *Runtime) (err error) { // Find a working OCI runtime binary foundRuntime := false - for _, path := range runtime.config.RuntimePath { - stat, err := os.Stat(path) - if err != nil { - continue - } - if stat.IsDir() { - continue +outer: + for _, oruntime := range runtime.config.OCIRuntimes { + for _, path := range oruntime.Paths { + stat, err := os.Stat(path) + if err != nil { + continue + } + if stat.IsDir() { + continue + } + foundRuntime = true + runtime.ociRuntimePath = OCIRuntimePath{Name: oruntime.Name, Paths: []string{path}} + break outer } - foundRuntime = true - runtime.ociRuntimePath = path - break } if !foundRuntime { return errors.Wrapf(ErrInvalidArg, "could not find a working binary (configured options: %v)", - runtime.config.RuntimePath) + runtime.config.OCIRuntimes) } // Find a working conmon binary @@ -619,7 +633,7 @@ func makeRuntime(runtime *Runtime) (err error) { } // Make an OCI runtime to perform container operations - ociRuntime, err := newOCIRuntime("runc", runtime.ociRuntimePath, + ociRuntime, err := newOCIRuntime(runtime.ociRuntimePath, runtime.conmonPath, runtime.config.ConmonEnvVars, runtime.config.CgroupManager, runtime.config.TmpDir, runtime.config.MaxLogSize, runtime.config.NoPivotRoot, -- cgit v1.2.3-54-g00ecf From 50c86ae3892a3708afb00189fea52547cb60572f Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 4 Jan 2019 11:16:40 +0100 Subject: oci: allow to define multiple OCI runtimes we can define multiple OCI runtimes that can be chosen with --runtime. in libpod.conf is possible to specify them with: [runtimes] foo = [ "/usr/bin/foo", "/usr/sbin/foo", ] bar = [ "/usr/bin/foo", "/usr/sbin/foo", ] If the argument to --runtime is an absolute path then it is used directly without any lookup in the configuration. Closes: https://github.com/containers/libpod/issues/1750 Signed-off-by: Giuseppe Scrivano --- docs/podman.1.md | 2 +- libpod.conf | 23 ++++++++++--------- libpod/options.go | 10 +++------ libpod/runtime.go | 67 ++++++++++++++++++++++++++++++++----------------------- 4 files changed, 55 insertions(+), 47 deletions(-) diff --git a/docs/podman.1.md b/docs/podman.1.md index a73ebb55e..74e700fac 100644 --- a/docs/podman.1.md +++ b/docs/podman.1.md @@ -68,7 +68,7 @@ Default state dir is configured in /etc/containers/storage.conf. **--runtime**=**value** -Path to the OCI compatible binary used to run containers +Name of the OCI runtime as specified in libpod.conf or absolute path to the OCI compatible binary used to run containers. **--storage-driver, -s**=**value** diff --git a/libpod.conf b/libpod.conf index cfdf83775..acd6c8982 100644 --- a/libpod.conf +++ b/libpod.conf @@ -4,17 +4,6 @@ # Default transport method for pulling and pushing for images image_default_transport = "docker://" -# Paths to look for a valid OCI runtime (runc, runv, etc) -runtime_path = [ - "/usr/bin/runc", - "/usr/sbin/runc", - "/usr/local/bin/runc", - "/usr/local/sbin/runc", - "/sbin/runc", - "/bin/runc", - "/usr/lib/cri-o-runc/sbin/runc" -] - # Paths to look for the Conmon container manager binary conmon_path = [ "/usr/libexec/podman/conmon", @@ -98,3 +87,15 @@ pause_command = "/pause" # Default libpod support for container labeling # label=true + +# Paths to look for a valid OCI runtime (runc, runv, etc) +[runtimes] +runc = [ + "/usr/bin/runc", + "/usr/sbin/runc", + "/usr/local/bin/runc", + "/usr/local/sbin/runc", + "/sbin/runc", + "/bin/runc", + "/usr/lib/cri-o-runc/sbin/runc" +] diff --git a/libpod/options.go b/libpod/options.go index 65a8a91d3..d965c058e 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -137,21 +137,17 @@ func WithStateType(storeType RuntimeStateStore) RuntimeOption { } // WithOCIRuntime specifies an OCI runtime to use for running containers. -func WithOCIRuntime(runtimePath string) RuntimeOption { +func WithOCIRuntime(runtime string) RuntimeOption { return func(rt *Runtime) error { if rt.valid { return ErrRuntimeFinalized } - if runtimePath == "" { + if runtime == "" { return errors.Wrapf(ErrInvalidArg, "must provide a valid path") } - rt.config.OCIRuntimes = []OCIRuntimePath{ - { - Paths: []string{runtimePath}, - }, - } + rt.config.OCIRuntime = runtime return nil } diff --git a/libpod/runtime.go b/libpod/runtime.go index 81d4cf3e3..5ff8b30f6 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -99,9 +99,9 @@ type Runtime struct { // OCIRuntimePath contains information about an OCI runtime. type OCIRuntimePath struct { // Name of the runtime to refer to by the --runtime flag - Name string + Name string `toml:"name"` // Paths to check for this executable - Paths []string + Paths []string `toml:"paths"` } // RuntimeConfig contains configuration options used to set up the runtime @@ -126,8 +126,10 @@ type RuntimeConfig struct { // cause conflicts in containers/storage // As such this is not exposed via the config file StateType RuntimeStateStore `toml:"-"` + // OCIRuntime is the OCI runtime to use. + OCIRuntime string `toml:"runtime"` // OCIRuntimes are the set of configured OCI runtimes (default is runc) - OCIRuntimes []OCIRuntimePath `toml:"runtimes"` + OCIRuntimes map[string][]string `toml:"runtimes"` // ConmonPath is the path to the Conmon binary used for managing // containers // The first path pointing to a valid file will be used @@ -219,18 +221,16 @@ var ( StorageConfig: storage.StoreOptions{}, ImageDefaultTransport: DefaultTransport, StateType: BoltDBStateStore, - OCIRuntimes: []OCIRuntimePath{ - { - Name: "runc", - Paths: []string{ - "/usr/bin/runc", - "/usr/sbin/runc", - "/usr/local/bin/runc", - "/usr/local/sbin/runc", - "/sbin/runc", - "/bin/runc", - "/usr/lib/cri-o-runc/sbin/runc", - }, + OCIRuntime: "runc", + OCIRuntimes: map[string][]string{ + "runc": { + "/usr/bin/runc", + "/usr/sbin/runc", + "/usr/local/bin/runc", + "/usr/local/sbin/runc", + "/sbin/runc", + "/bin/runc", + "/usr/lib/cri-o-runc/sbin/runc", }, }, ConmonPath: []string{ @@ -425,8 +425,9 @@ func NewRuntimeFromConfig(configPath string, options ...RuntimeOption) (runtime runtime.config = new(RuntimeConfig) runtime.configuredFrom = new(runtimeConfiguredFrom) - // Set two fields not in the TOML config + // Set three fields not in the TOML config runtime.config.StateType = defaultRuntimeConfig.StateType + runtime.config.OCIRuntime = defaultRuntimeConfig.OCIRuntime runtime.config.StorageConfig = storage.StoreOptions{} // Check to see if the given configuration file exists @@ -464,19 +465,29 @@ func NewRuntimeFromConfig(configPath string, options ...RuntimeOption) (runtime func makeRuntime(runtime *Runtime) (err error) { // Find a working OCI runtime binary foundRuntime := false -outer: - for _, oruntime := range runtime.config.OCIRuntimes { - for _, path := range oruntime.Paths { - stat, err := os.Stat(path) - if err != nil { - continue - } - if stat.IsDir() { - continue + // If runtime is an absolute path, then use it as it is. + if runtime.config.OCIRuntime[0] == '/' { + foundRuntime = true + runtime.ociRuntimePath = OCIRuntimePath{Name: filepath.Base(runtime.config.OCIRuntime), Paths: []string{runtime.config.OCIRuntime}} + } else { + // If not, look it up in the configuration. + paths := runtime.config.OCIRuntimes[runtime.config.OCIRuntime] + if paths != nil { + for _, path := range paths { + stat, err := os.Stat(path) + if err != nil { + if os.IsNotExist(err) { + continue + } + return errors.Wrapf(err, "cannot stat %s", path) + } + if !stat.Mode().IsRegular() { + continue + } + foundRuntime = true + runtime.ociRuntimePath = OCIRuntimePath{Name: runtime.config.OCIRuntime, Paths: []string{path}} + break } - foundRuntime = true - runtime.ociRuntimePath = OCIRuntimePath{Name: oruntime.Name, Paths: []string{path}} - break outer } } if !foundRuntime { -- cgit v1.2.3-54-g00ecf From 3b37101c6e3679399a5ed05bb2e109df0e0032e8 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 7 Jan 2019 08:46:13 +0100 Subject: config: store the runtime used to create each container Signed-off-by: Giuseppe Scrivano --- libpod/container.go | 3 +++ libpod/runtime_ctr.go | 2 ++ 2 files changed, 5 insertions(+) diff --git a/libpod/container.go b/libpod/container.go index ca83bbffe..95f7a2972 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -350,6 +350,9 @@ type ContainerConfig struct { PostConfigureNetNS bool `json:"postConfigureNetNS"` + // OCIRuntime used to create the container + OCIRuntime string `json:"runtime,omitempty"` + // ExitCommand is the container's exit command. // This Command will be executed when the container exits ExitCommand []string `json:"exitCommand,omitempty"` diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index ab79fe5fb..68599fe6d 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -62,6 +62,8 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options .. ctr.config.StopTimeout = CtrRemoveTimeout + ctr.config.OCIRuntime = r.config.OCIRuntime + // Set namespace based on current runtime namespace // Do so before options run so they can override it if r.config.Namespace != "" { -- cgit v1.2.3-54-g00ecf