Merge pull request #2079 from giuseppe/multiple-runtimes

oci: allow to define multiple OCI runtimes
This commit is contained in:
OpenShift Merge Robot
2019-01-16 12:44:10 +01:00
committed by GitHub
8 changed files with 78 additions and 47 deletions

View File

@ -68,7 +68,7 @@ Default state dir is configured in /etc/containers/storage.conf.
**--runtime**=**value** **--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** **--storage-driver, -s**=**value**

View File

@ -4,17 +4,6 @@
# Default transport method for pulling and pushing for images # Default transport method for pulling and pushing for images
image_default_transport = "docker://" 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 # Paths to look for the Conmon container manager binary
conmon_path = [ conmon_path = [
"/usr/libexec/podman/conmon", "/usr/libexec/podman/conmon",
@ -98,3 +87,15 @@ pause_command = "/pause"
# Default libpod support for container labeling # Default libpod support for container labeling
# label=true # 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"
]

View File

@ -350,6 +350,9 @@ type ContainerConfig struct {
PostConfigureNetNS bool `json:"postConfigureNetNS"` PostConfigureNetNS bool `json:"postConfigureNetNS"`
// OCIRuntime used to create the container
OCIRuntime string `json:"runtime,omitempty"`
// ExitCommand is the container's exit command. // ExitCommand is the container's exit command.
// This Command will be executed when the container exits // This Command will be executed when the container exits
ExitCommand []string `json:"exitCommand,omitempty"` ExitCommand []string `json:"exitCommand,omitempty"`

View File

@ -4,7 +4,6 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"fmt" "fmt"
"github.com/containers/buildah"
"io/ioutil" "io/ioutil"
"os" "os"
"runtime" "runtime"
@ -12,6 +11,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/containers/buildah"
"github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/util" "github.com/containers/libpod/pkg/util"
"github.com/containers/libpod/utils" "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 // GetOCIRuntimePath returns the path to the OCI Runtime Path the runtime is using
func (r *Runtime) GetOCIRuntimePath() string { func (r *Runtime) GetOCIRuntimePath() string {
return r.ociRuntimePath return r.ociRuntimePath.Paths[0]
} }
// GetOCIRuntimeVersion returns a string representation of the oci runtimes version // GetOCIRuntimeVersion returns a string representation of the oci runtimes version
func (r *Runtime) GetOCIRuntimeVersion() (string, error) { 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 { if err != nil {
return "", err return "", err
} }

View File

@ -75,10 +75,10 @@ type syncInfo struct {
} }
// Make a new OCI runtime with provided options // 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 := new(OCIRuntime)
runtime.name = name runtime.name = oruntime.Name
runtime.path = path runtime.path = oruntime.Paths[0]
runtime.conmonPath = conmonPath runtime.conmonPath = conmonPath
runtime.conmonEnv = conmonEnv runtime.conmonEnv = conmonEnv
runtime.cgroupManager = cgroupManager runtime.cgroupManager = cgroupManager

View File

@ -137,17 +137,17 @@ func WithStateType(storeType RuntimeStateStore) RuntimeOption {
} }
// WithOCIRuntime specifies an OCI runtime to use for running containers. // 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 { return func(rt *Runtime) error {
if rt.valid { if rt.valid {
return ErrRuntimeFinalized return ErrRuntimeFinalized
} }
if runtimePath == "" { if runtime == "" {
return errors.Wrapf(ErrInvalidArg, "must provide a valid path") return errors.Wrapf(ErrInvalidArg, "must provide a valid path")
} }
rt.config.RuntimePath = []string{runtimePath} rt.config.OCIRuntime = runtime
return nil return nil
} }

View File

@ -86,7 +86,7 @@ type Runtime struct {
imageContext *types.SystemContext imageContext *types.SystemContext
ociRuntime *OCIRuntime ociRuntime *OCIRuntime
netPlugin ocicni.CNIPlugin netPlugin ocicni.CNIPlugin
ociRuntimePath string ociRuntimePath OCIRuntimePath
conmonPath string conmonPath string
valid bool valid bool
lock sync.RWMutex lock sync.RWMutex
@ -96,6 +96,14 @@ type Runtime struct {
configuredFrom *runtimeConfiguredFrom 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 `toml:"name"`
// Paths to check for this executable
Paths []string `toml:"paths"`
}
// RuntimeConfig contains configuration options used to set up the runtime // RuntimeConfig contains configuration options used to set up the runtime
type RuntimeConfig struct { type RuntimeConfig struct {
// StorageConfig is the configuration used by containers/storage // StorageConfig is the configuration used by containers/storage
@ -118,10 +126,10 @@ type RuntimeConfig struct {
// cause conflicts in containers/storage // cause conflicts in containers/storage
// As such this is not exposed via the config file // As such this is not exposed via the config file
StateType RuntimeStateStore `toml:"-"` StateType RuntimeStateStore `toml:"-"`
// RuntimePath is the path to OCI runtime binary for launching // OCIRuntime is the OCI runtime to use.
// containers OCIRuntime string `toml:"runtime"`
// The first path pointing to a valid file will be used // OCIRuntimes are the set of configured OCI runtimes (default is runc)
RuntimePath []string `toml:"runtime_path"` OCIRuntimes map[string][]string `toml:"runtimes"`
// ConmonPath is the path to the Conmon binary used for managing // ConmonPath is the path to the Conmon binary used for managing
// containers // containers
// The first path pointing to a valid file will be used // The first path pointing to a valid file will be used
@ -213,14 +221,17 @@ var (
StorageConfig: storage.StoreOptions{}, StorageConfig: storage.StoreOptions{},
ImageDefaultTransport: DefaultTransport, ImageDefaultTransport: DefaultTransport,
StateType: BoltDBStateStore, StateType: BoltDBStateStore,
RuntimePath: []string{ OCIRuntime: "runc",
"/usr/bin/runc", OCIRuntimes: map[string][]string{
"/usr/sbin/runc", "runc": {
"/usr/local/bin/runc", "/usr/bin/runc",
"/usr/local/sbin/runc", "/usr/sbin/runc",
"/sbin/runc", "/usr/local/bin/runc",
"/bin/runc", "/usr/local/sbin/runc",
"/usr/lib/cri-o-runc/sbin/runc", "/sbin/runc",
"/bin/runc",
"/usr/lib/cri-o-runc/sbin/runc",
},
}, },
ConmonPath: []string{ ConmonPath: []string{
"/usr/libexec/podman/conmon", "/usr/libexec/podman/conmon",
@ -414,8 +425,9 @@ func NewRuntimeFromConfig(configPath string, options ...RuntimeOption) (runtime
runtime.config = new(RuntimeConfig) runtime.config = new(RuntimeConfig)
runtime.configuredFrom = new(runtimeConfiguredFrom) 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.StateType = defaultRuntimeConfig.StateType
runtime.config.OCIRuntime = defaultRuntimeConfig.OCIRuntime
runtime.config.StorageConfig = storage.StoreOptions{} runtime.config.StorageConfig = storage.StoreOptions{}
// Check to see if the given configuration file exists // Check to see if the given configuration file exists
@ -453,22 +465,35 @@ func NewRuntimeFromConfig(configPath string, options ...RuntimeOption) (runtime
func makeRuntime(runtime *Runtime) (err error) { func makeRuntime(runtime *Runtime) (err error) {
// Find a working OCI runtime binary // Find a working OCI runtime binary
foundRuntime := false foundRuntime := false
for _, path := range runtime.config.RuntimePath { // If runtime is an absolute path, then use it as it is.
stat, err := os.Stat(path) if runtime.config.OCIRuntime[0] == '/' {
if err != nil {
continue
}
if stat.IsDir() {
continue
}
foundRuntime = true foundRuntime = true
runtime.ociRuntimePath = path runtime.ociRuntimePath = OCIRuntimePath{Name: filepath.Base(runtime.config.OCIRuntime), Paths: []string{runtime.config.OCIRuntime}}
break } 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
}
}
} }
if !foundRuntime { if !foundRuntime {
return errors.Wrapf(ErrInvalidArg, return errors.Wrapf(ErrInvalidArg,
"could not find a working binary (configured options: %v)", "could not find a working binary (configured options: %v)",
runtime.config.RuntimePath) runtime.config.OCIRuntimes)
} }
// Find a working conmon binary // Find a working conmon binary
@ -619,7 +644,7 @@ func makeRuntime(runtime *Runtime) (err error) {
} }
// Make an OCI runtime to perform container operations // 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.conmonPath, runtime.config.ConmonEnvVars,
runtime.config.CgroupManager, runtime.config.TmpDir, runtime.config.CgroupManager, runtime.config.TmpDir,
runtime.config.MaxLogSize, runtime.config.NoPivotRoot, runtime.config.MaxLogSize, runtime.config.NoPivotRoot,

View File

@ -62,6 +62,8 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ..
ctr.config.StopTimeout = CtrRemoveTimeout ctr.config.StopTimeout = CtrRemoveTimeout
ctr.config.OCIRuntime = r.config.OCIRuntime
// Set namespace based on current runtime namespace // Set namespace based on current runtime namespace
// Do so before options run so they can override it // Do so before options run so they can override it
if r.config.Namespace != "" { if r.config.Namespace != "" {