Add basic skeleton of libpod runtime
Signed-off-by: Matthew Heon <mheon@redhat.com>
This commit is contained in:
parent
3473e8afed
commit
2a121111b5
5 changed files with 715 additions and 28 deletions
|
@ -4,15 +4,14 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/kubernetes-incubator/cri-o/libpod/ctr"
|
||||
"github.com/kubernetes-incubator/cri-o/libpod/pod"
|
||||
)
|
||||
|
||||
var (
|
||||
runtimeNotImplemented = func(rt *Runtime) error {
|
||||
return fmt.Errorf("NOT IMPLEMENTED")
|
||||
}
|
||||
ctrNotImplemented = func(c *ctr.Container) error {
|
||||
errRuntimeFinalized = fmt.Errorf("runtime has already been finalized")
|
||||
ctrNotImplemented = func(c *ctr.Container) error {
|
||||
return fmt.Errorf("NOT IMPLEMENTED")
|
||||
}
|
||||
)
|
||||
|
@ -37,15 +36,48 @@ const (
|
|||
// WithStorageConfig uses the given configuration to set up container storage
|
||||
// If this is not specified, the system default configuration will be used
|
||||
// instead
|
||||
func WithStorageConfig(config *storage.StoreOptions) RuntimeOption {
|
||||
return runtimeNotImplemented
|
||||
func WithStorageConfig(config storage.StoreOptions) RuntimeOption {
|
||||
return func(rt *Runtime) error {
|
||||
if rt.valid {
|
||||
return errRuntimeFinalized
|
||||
}
|
||||
|
||||
rt.config.StorageConfig.RunRoot = config.RunRoot
|
||||
rt.config.StorageConfig.GraphRoot = config.GraphRoot
|
||||
rt.config.StorageConfig.GraphDriverName = config.GraphDriverName
|
||||
|
||||
rt.config.StorageConfig.GraphDriverOptions = make([]string, len(config.GraphDriverOptions))
|
||||
copy(rt.config.StorageConfig.GraphDriverOptions, config.GraphDriverOptions)
|
||||
|
||||
rt.config.StorageConfig.UIDMap = make([]idtools.IDMap, len(config.UIDMap))
|
||||
copy(rt.config.StorageConfig.UIDMap, config.UIDMap)
|
||||
|
||||
rt.config.StorageConfig.GIDMap = make([]idtools.IDMap, len(config.UIDMap))
|
||||
copy(rt.config.StorageConfig.GIDMap, config.GIDMap)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithImageConfig uses the given configuration to set up image handling
|
||||
// If this is not specified, the system default configuration will be used
|
||||
// instead
|
||||
func WithImageConfig(defaultTransport string, insecureRegistries, registries []string) RuntimeOption {
|
||||
return runtimeNotImplemented
|
||||
return func(rt *Runtime) error {
|
||||
if rt.valid {
|
||||
return errRuntimeFinalized
|
||||
}
|
||||
|
||||
rt.config.ImageDefaultTransport = defaultTransport
|
||||
|
||||
rt.config.InsecureRegistries = make([]string, len(insecureRegistries))
|
||||
copy(rt.config.InsecureRegistries, insecureRegistries)
|
||||
|
||||
rt.config.Registries = make([]string, len(registries))
|
||||
copy(rt.config.Registries, registries)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithSignaturePolicy specifies the path of a file which decides how trust is
|
||||
|
@ -53,52 +85,97 @@ func WithImageConfig(defaultTransport string, insecureRegistries, registries []s
|
|||
// If this is not specified, the system default configuration will be used
|
||||
// instead
|
||||
func WithSignaturePolicy(path string) RuntimeOption {
|
||||
return runtimeNotImplemented
|
||||
return func(rt *Runtime) error {
|
||||
if rt.valid {
|
||||
return errRuntimeFinalized
|
||||
}
|
||||
|
||||
rt.config.SignaturePolicyPath = path
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithOCIRuntime specifies an OCI runtime to use for running containers
|
||||
func WithOCIRuntime(runtimePath string) RuntimeOption {
|
||||
return runtimeNotImplemented
|
||||
return func(rt *Runtime) error {
|
||||
if rt.valid {
|
||||
return errRuntimeFinalized
|
||||
}
|
||||
|
||||
rt.config.RuntimePath = runtimePath
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithConmonPath specifies the path to the conmon binary which manages the
|
||||
// runtime
|
||||
func WithConmonPath(path string) RuntimeOption {
|
||||
return runtimeNotImplemented
|
||||
return func(rt *Runtime) error {
|
||||
if rt.valid {
|
||||
return errRuntimeFinalized
|
||||
}
|
||||
|
||||
rt.config.ConmonPath = path
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithConmonEnv specifies the environment variable list for the conmon process
|
||||
func WithConmonEnv(environment []string) RuntimeOption {
|
||||
return runtimeNotImplemented
|
||||
return func(rt *Runtime) error {
|
||||
if rt.valid {
|
||||
return errRuntimeFinalized
|
||||
}
|
||||
|
||||
rt.config.ConmonEnvVars = make([]string, len(environment))
|
||||
copy(rt.config.ConmonEnvVars, environment)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithCgroupManager specifies the manager implementation name which is used to
|
||||
// handle cgroups for containers
|
||||
func WithCgroupManager(manager string) RuntimeOption {
|
||||
return runtimeNotImplemented
|
||||
return func(rt *Runtime) error {
|
||||
if rt.valid {
|
||||
return errRuntimeFinalized
|
||||
}
|
||||
|
||||
rt.config.CgroupManager = manager
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithSELinux enables SELinux on the container server
|
||||
func WithSELinux() RuntimeOption {
|
||||
return runtimeNotImplemented
|
||||
}
|
||||
return func(rt *Runtime) error {
|
||||
if rt.valid {
|
||||
return errRuntimeFinalized
|
||||
}
|
||||
|
||||
// WithApparmorProfile specifies the apparmor profile name which will be used as
|
||||
// the default for created containers
|
||||
func WithApparmorProfile(profile string) RuntimeOption {
|
||||
return runtimeNotImplemented
|
||||
}
|
||||
rt.config.SelinuxEnabled = true
|
||||
|
||||
// WithSeccompProfile specifies the seccomp profile which will be used as the
|
||||
// default for created containers
|
||||
func WithSeccompProfile(profilePath string) RuntimeOption {
|
||||
return runtimeNotImplemented
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPidsLimit specifies the maximum number of processes each container is
|
||||
// restricted to
|
||||
func WithPidsLimit(limit int64) RuntimeOption {
|
||||
return runtimeNotImplemented
|
||||
return func(rt *Runtime) error {
|
||||
if rt.valid {
|
||||
return errRuntimeFinalized
|
||||
}
|
||||
|
||||
rt.config.PidsLimit = limit
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Container Creation Options
|
||||
|
|
|
@ -1,26 +1,135 @@
|
|||
package libpod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/containers/image/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/kubernetes-incubator/cri-o/libpod/ctr"
|
||||
"github.com/kubernetes-incubator/cri-o/libpod/pod"
|
||||
"github.com/kubernetes-incubator/cri-o/server/apparmor"
|
||||
"github.com/kubernetes-incubator/cri-o/server/seccomp"
|
||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/ulule/deepcopier"
|
||||
)
|
||||
|
||||
// Runtime API
|
||||
|
||||
// A RuntimeOption is a functional option which alters the Runtime created by
|
||||
// NewRuntime
|
||||
type RuntimeOption func(*Runtime) error
|
||||
|
||||
// Runtime is the core libpod runtime
|
||||
type Runtime struct {
|
||||
// TODO populate
|
||||
config *RuntimeConfig
|
||||
store storage.Store
|
||||
imageContext *types.SystemContext
|
||||
apparmorEnabled bool
|
||||
seccompEnabled bool
|
||||
valid bool
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
// RuntimeConfig contains configuration options used to set up the runtime
|
||||
type RuntimeConfig struct {
|
||||
StorageConfig storage.StoreOptions
|
||||
ImageDefaultTransport string
|
||||
InsecureRegistries []string
|
||||
Registries []string
|
||||
SignaturePolicyPath string
|
||||
RuntimePath string
|
||||
ConmonPath string
|
||||
ConmonEnvVars []string
|
||||
CgroupManager string
|
||||
SelinuxEnabled bool
|
||||
PidsLimit int64
|
||||
}
|
||||
|
||||
var (
|
||||
defaultRuntimeConfig = RuntimeConfig{
|
||||
// Leave this empty so containers/storage will use its defaults
|
||||
StorageConfig: storage.StoreOptions{},
|
||||
ImageDefaultTransport: "docker://",
|
||||
RuntimePath: "/usr/bin/runc",
|
||||
ConmonPath: "/usr/local/libexec/crio/conmon",
|
||||
ConmonEnvVars: []string{
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
},
|
||||
CgroupManager: "cgroupfs",
|
||||
SelinuxEnabled: false,
|
||||
PidsLimit: 1024,
|
||||
}
|
||||
)
|
||||
|
||||
// NewRuntime creates a new container runtime
|
||||
// Options can be passed to override the default configuration for the runtime
|
||||
func NewRuntime(options ...RuntimeOption) (*Runtime, error) {
|
||||
return nil, ctr.ErrNotImplemented
|
||||
runtime := new(Runtime)
|
||||
runtime.config = new(RuntimeConfig)
|
||||
|
||||
// Copy the default configuration
|
||||
deepcopier.Copy(defaultRuntimeConfig).To(runtime.config)
|
||||
|
||||
// Overwrite it with user-given configuration options
|
||||
for _, opt := range options {
|
||||
if err := opt(runtime); err != nil {
|
||||
return nil, errors.Wrapf(err, "error configuring runtime")
|
||||
}
|
||||
}
|
||||
|
||||
// Set up containers/storage
|
||||
store, err := storage.GetStore(runtime.config.StorageConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
runtime.store = store
|
||||
|
||||
// Set up containers/image
|
||||
runtime.imageContext = &types.SystemContext{
|
||||
SignaturePolicyPath: runtime.config.SignaturePolicyPath,
|
||||
}
|
||||
|
||||
runtime.seccompEnabled = seccomp.IsEnabled()
|
||||
runtime.apparmorEnabled = apparmor.IsEnabled()
|
||||
|
||||
// Mark the runtime as valid - ready to be used, cannot be modified
|
||||
// further
|
||||
runtime.valid = true
|
||||
|
||||
return runtime, nil
|
||||
}
|
||||
|
||||
// GetConfig returns a copy of the configuration used by the runtime
|
||||
func (r *Runtime) GetConfig() *RuntimeConfig {
|
||||
r.lock.RLock()
|
||||
defer r.lock.RUnlock()
|
||||
|
||||
if !r.valid {
|
||||
return nil
|
||||
}
|
||||
|
||||
config := new(RuntimeConfig)
|
||||
|
||||
// Copy so the caller won't be able to modify the actual config
|
||||
deepcopier.Copy(r.config).To(config)
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
// Shutdown shuts down the runtime and associated containers and storage
|
||||
// If force is true, containers and mounted storage will be shut down before
|
||||
// cleaning up; if force is false, an error will be returned if there are
|
||||
// still containers running or mounted
|
||||
func (r *Runtime) Shutdown(force bool) error {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
if !r.valid {
|
||||
return fmt.Errorf("runtime has already been shut down")
|
||||
}
|
||||
|
||||
_, err := r.store.Shutdown(force)
|
||||
return err
|
||||
}
|
||||
|
||||
// Container API
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue