2017-08-11 16:42:25 +00:00
|
|
|
package libpod
|
|
|
|
|
|
|
|
import (
|
2017-08-28 21:33:02 +00:00
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/containers/image/types"
|
2017-08-15 15:25:35 +00:00
|
|
|
"github.com/containers/storage"
|
2017-08-11 16:42:25 +00:00
|
|
|
"github.com/kubernetes-incubator/cri-o/libpod/ctr"
|
|
|
|
"github.com/kubernetes-incubator/cri-o/libpod/pod"
|
2017-08-28 21:33:02 +00:00
|
|
|
"github.com/kubernetes-incubator/cri-o/server/apparmor"
|
|
|
|
"github.com/kubernetes-incubator/cri-o/server/seccomp"
|
2017-08-11 16:42:25 +00:00
|
|
|
spec "github.com/opencontainers/runtime-spec/specs-go"
|
2017-08-28 21:33:02 +00:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/ulule/deepcopier"
|
2017-08-11 16:42:25 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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 {
|
2017-08-28 21:33:02 +00:00
|
|
|
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
|
2017-08-11 16:42:25 +00:00
|
|
|
}
|
|
|
|
|
2017-08-28 21:33:02 +00:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2017-08-11 16:42:25 +00:00
|
|
|
// NewRuntime creates a new container runtime
|
2017-08-28 21:33:02 +00:00
|
|
|
// Options can be passed to override the default configuration for the runtime
|
2017-08-11 16:42:25 +00:00
|
|
|
func NewRuntime(options ...RuntimeOption) (*Runtime, error) {
|
2017-08-28 21:33:02 +00:00
|
|
|
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
|
2017-08-11 16:42:25 +00:00
|
|
|
}
|
|
|
|
|
2017-08-15 15:25:35 +00:00
|
|
|
// Container API
|
|
|
|
|
|
|
|
// A CtrCreateOption is a functional option which alters the Container created
|
|
|
|
// by NewContainer
|
|
|
|
type CtrCreateOption func(*ctr.Container) error
|
|
|
|
|
|
|
|
// ContainerFilter is a function to determine whether a container is included
|
|
|
|
// in command output. Containers to be outputted are tested using the function.
|
|
|
|
// A true return will include the container, a false return will exclude it.
|
|
|
|
type ContainerFilter func(*ctr.Container) bool
|
|
|
|
|
2017-08-11 16:42:25 +00:00
|
|
|
// NewContainer creates a new container from a given OCI config
|
|
|
|
func (r *Runtime) NewContainer(spec *spec.Spec, options ...CtrCreateOption) (*ctr.Container, error) {
|
|
|
|
return nil, ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemoveContainer removes the given container
|
|
|
|
// If force is specified, the container will be stopped first
|
|
|
|
// Otherwise, RemoveContainer will return an error if the container is running
|
|
|
|
func (r *Runtime) RemoveContainer(c *ctr.Container, force bool) error {
|
|
|
|
return ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetContainer retrieves a container by its ID
|
|
|
|
func (r *Runtime) GetContainer(id string) (*ctr.Container, error) {
|
|
|
|
return nil, ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// LookupContainer looks up a container by its name or a partial ID
|
|
|
|
// If a partial ID is not unique, an error will be returned
|
|
|
|
func (r *Runtime) LookupContainer(idOrName string) (*ctr.Container, error) {
|
|
|
|
return nil, ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetContainers retrieves all containers from the state
|
|
|
|
// Filters can be provided which will determine what containers are included in
|
|
|
|
// the output. Multiple filters are handled by ANDing their output, so only
|
|
|
|
// containers matching all filters are returned
|
|
|
|
func (r *Runtime) GetContainers(filters ...ContainerFilter) ([]*ctr.Container, error) {
|
|
|
|
return nil, ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
2017-08-15 15:25:35 +00:00
|
|
|
// Pod API
|
|
|
|
|
|
|
|
// PodFilter is a function to determine whether a pod is included in command
|
|
|
|
// output. Pods to be outputted are tested using the function. A true return
|
|
|
|
// will include the pod, a false return will exclude it.
|
|
|
|
type PodFilter func(*pod.Pod) bool
|
|
|
|
|
2017-08-11 16:42:25 +00:00
|
|
|
// NewPod makes a new, empty pod
|
|
|
|
func (r *Runtime) NewPod() (*pod.Pod, error) {
|
|
|
|
return nil, ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemovePod removes a pod and all containers in it
|
|
|
|
// If force is specified, all containers in the pod will be stopped first
|
|
|
|
// Otherwise, RemovePod will return an error if any container in the pod is running
|
|
|
|
// Remove acts atomically, removing all containers or no containers
|
|
|
|
func (r *Runtime) RemovePod(p *pod.Pod, force bool) error {
|
|
|
|
return ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetPod retrieves a pod by its ID
|
|
|
|
func (r *Runtime) GetPod(id string) (*pod.Pod, error) {
|
|
|
|
return nil, ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// LookupPod retrieves a pod by its name or a partial ID
|
|
|
|
// If a partial ID is not unique, an error will be returned
|
|
|
|
func (r *Runtime) LookupPod(idOrName string) (*pod.Pod, error) {
|
|
|
|
return nil, ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetPods retrieves all pods
|
|
|
|
// Filters can be provided which will determine which pods are included in the
|
|
|
|
// output. Multiple filters are handled by ANDing their output, so only pods
|
|
|
|
// matching all filters are returned
|
|
|
|
func (r *Runtime) GetPods(filters ...PodFilter) ([]*pod.Pod, error) {
|
|
|
|
return nil, ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
2017-08-15 15:25:35 +00:00
|
|
|
// Image API
|
|
|
|
|
|
|
|
// ImageFilter is a function to determine whether an image is included in
|
|
|
|
// command output. Images to be outputted are tested using the function. A true
|
|
|
|
// return will include the image, a false return will exclude it.
|
|
|
|
type ImageFilter func(*storage.Image) bool
|
|
|
|
|
|
|
|
// PullImage pulls an image from configured registries
|
|
|
|
// By default, only the latest tag (or a specific tag if requested) will be
|
|
|
|
// pulled. If allTags is true, all tags for the requested image will be pulled.
|
|
|
|
// Signature validation will be performed if the Runtime has been appropriately
|
|
|
|
// configured
|
|
|
|
func (r *Runtime) PullImage(image string, allTags bool) (*storage.Image, error) {
|
|
|
|
return nil, ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// PushImage pushes the given image to a location described by the given path
|
|
|
|
func (r *Runtime) PushImage(image *storage.Image, destination string) error {
|
|
|
|
return ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// TagImage adds a tag to the given image
|
|
|
|
func (r *Runtime) TagImage(image *storage.Image, tag string) error {
|
|
|
|
return ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// UntagImage removes a tag from the given image
|
|
|
|
func (r *Runtime) UntagImage(image *storage.Image, tag string) error {
|
|
|
|
return ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemoveImage deletes an image from local storage
|
|
|
|
// Images being used by running containers cannot be removed
|
|
|
|
func (r *Runtime) RemoveImage(image *storage.Image) error {
|
|
|
|
return ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetImage retrieves an image matching the given name or hash from system
|
|
|
|
// storage
|
|
|
|
// If no matching image can be found, an error is returned
|
|
|
|
func (r *Runtime) GetImage(image string) (*storage.Image, error) {
|
|
|
|
return nil, ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetImages retrieves all images present in storage
|
|
|
|
// Filters can be provided which will determine which images are included in the
|
|
|
|
// output. Multiple filters are handled by ANDing their output, so only images
|
|
|
|
// matching all filters are included
|
|
|
|
func (r *Runtime) GetImages(filter ...ImageFilter) ([]*storage.Image, error) {
|
|
|
|
return nil, ctr.ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
2017-08-15 18:33:40 +00:00
|
|
|
// ImportImage imports an OCI format image archive into storage as an image
|
|
|
|
func (r *Runtime) ImportImage(path string) (*storage.Image, error) {
|
|
|
|
return nil, ctr.ErrNotImplemented
|
|
|
|
}
|