From 9d56fd844310a457151ceeec39b53689abaaf970 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Fri, 11 Aug 2017 12:42:25 -0400 Subject: [PATCH 1/4] Add skeleton of new libpod API Signed-off-by: Matthew Heon --- libpod/ctr/container.go | 61 ++++++++++++++++ libpod/options.go | 151 ++++++++++++++++++++++++++++++++++++++++ libpod/pod/pod.go | 36 ++++++++++ libpod/runtime.go | 100 ++++++++++++++++++++++++++ 4 files changed, 348 insertions(+) create mode 100644 libpod/ctr/container.go create mode 100644 libpod/options.go create mode 100644 libpod/pod/pod.go create mode 100644 libpod/runtime.go diff --git a/libpod/ctr/container.go b/libpod/ctr/container.go new file mode 100644 index 00000000..bba91ca5 --- /dev/null +++ b/libpod/ctr/container.go @@ -0,0 +1,61 @@ +package ctr + +import ( + "fmt" +) + +var ( + // ErrNotImplemented indicates that functionality is not yet implemented + ErrNotImplemented = fmt.Errorf("NOT IMPLEMENTED") +) + +// Container is a single OCI container +type Container struct { + // TODO populate +} + +// Create creates a container in the OCI runtime +func (c *Container) Create() error { + return ErrNotImplemented +} + +// Start starts a container +func (c *Container) Start() error { + return ErrNotImplemented +} + +// Stop stops a container +func (c *Container) Stop() error { + return ErrNotImplemented +} + +// Kill sends a signal to a container +func (c *Container) Kill(signal uint) error { + return ErrNotImplemented +} + +// Exec starts a new process inside the container +// TODO does this need arguments? +// TODO should this return anything besides error? +func (c *Container) Exec() error { + return ErrNotImplemented +} + +// Attach attaches to a container +// TODO does this need arguments? +// TODO should this return anything besides error? +func (c *Container) Attach() error { + return ErrNotImplemented +} + +// Mount mounts a container's filesystem on the host +// The path where the container has been mounted is returned +func (c *Container) Mount() (string, error) { + return "", ErrNotImplemented +} + +// Status gets a container's status +// TODO this should return relevant information about container state +func (c *Container) Status() error { + return ErrNotImplemented +} diff --git a/libpod/options.go b/libpod/options.go new file mode 100644 index 00000000..cbc20cba --- /dev/null +++ b/libpod/options.go @@ -0,0 +1,151 @@ +package libpod + +import ( + "fmt" + + "github.com/containers/storage" + "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 { + return fmt.Errorf("NOT IMPLEMENTED") + } +) + +const ( + // IPCNamespace represents the IPC namespace + IPCNamespace = "ipc" + // MountNamespace represents the mount namespace + MountNamespace = "mount" + // NetNamespace represents the network namespace + NetNamespace = "net" + // PIDNamespace represents the PID namespace + PIDNamespace = "pid" + // UserNamespace represents the user namespace + UserNamespace = "user" + // UTSNamespace represents the UTS namespace + UTSNamespace = "uts" +) + +// Runtime Creation Options + +// 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 +} + +// 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 +} + +// WithSignaturePolicy specifies the path of a file which decides how trust is +// managed for images we've pulled. +// If this is not specified, the system default configuration will be used +// instead +func WithSignaturePolicy(path string) RuntimeOption { + return runtimeNotImplemented +} + +// WithOCIRuntime specifies an OCI runtime to use for running containers +func WithOCIRuntime(runtimePath string) RuntimeOption { + return runtimeNotImplemented +} + +// WithConmonPath specifies the path to the conmon binary which manages the +// runtime +func WithConmonPath(path string) RuntimeOption { + return runtimeNotImplemented +} + +// WithConmonEnv specifies the environment variable list for the conmon process +func WithConmonEnv(environment []string) RuntimeOption { + return runtimeNotImplemented +} + +// WithCgroupManager specifies the manager implementation name which is used to +// handle cgroups for containers +func WithCgroupManager(manager string) RuntimeOption { + return runtimeNotImplemented +} + +// WithSELinux enables SELinux on the container server +func WithSELinux() RuntimeOption { + return runtimeNotImplemented +} + +// WithApparmorProfile specifies the apparmor profile name which will be used as +// the default for created containers +func WithApparmorProfile(profile string) RuntimeOption { + return runtimeNotImplemented +} + +// WithSeccompProfile specifies the seccomp profile which will be used as the +// default for created containers +func WithSeccompProfile(profilePath string) RuntimeOption { + return runtimeNotImplemented +} + +// WithPidsLimit specifies the maximum number of processes each container is +// restricted to +func WithPidsLimit(limit int64) RuntimeOption { + return runtimeNotImplemented +} + +// Container Creation Options + +// WithRootFSFromPath uses the given path as a container's root filesystem +// No further setup is performed on this path +func WithRootFSFromPath(path string) CtrCreateOption { + return ctrNotImplemented +} + +// WithRootFSFromImage sets up a fresh root filesystem using the given image +// If useImageConfig is specified, image volumes, environment variables, and +// other configuration from the image will be added to the config +func WithRootFSFromImage(image string, useImageConfig bool) CtrCreateOption { + return ctrNotImplemented +} + +// WithSharedNamespaces sets a container to share namespaces with another +// container. If the from container belongs to a pod, the new container will +// be added to the pod. +// By default no namespaces are shared. To share a namespace, add the Namespace +// string constant to the map as a key +func WithSharedNamespaces(from *ctr.Container, namespaces map[string]string) CtrCreateOption { + return ctrNotImplemented +} + +// WithPod adds the container to a pod +func WithPod(pod *pod.Pod) CtrCreateOption { + return ctrNotImplemented +} + +// WithLabels adds labels to the pod +func WithLabels(labels map[string]string) CtrCreateOption { + return ctrNotImplemented +} + +// WithAnnotations adds annotations to the pod +func WithAnnotations(annotations map[string]string) CtrCreateOption { + return ctrNotImplemented +} + +// WithName sets the container's name +func WithName(name string) CtrCreateOption { + return ctrNotImplemented +} + +// WithStopSignal sets the signal that will be sent to stop the container +func WithStopSignal(signal uint) CtrCreateOption { + return ctrNotImplemented +} diff --git a/libpod/pod/pod.go b/libpod/pod/pod.go new file mode 100644 index 00000000..b552fefe --- /dev/null +++ b/libpod/pod/pod.go @@ -0,0 +1,36 @@ +package pod + +import ( + "github.com/kubernetes-incubator/cri-o/libpod/ctr" +) + +// Pod represents a group of containers that may share namespaces +type Pod struct { + // TODO populate +} + +// Start starts all containers within a pod that are not already running +func (p *Pod) Start() error { + return ctr.ErrNotImplemented +} + +// Stop stops all containers within a pod that are not already stopped +func (p *Pod) Stop() error { + return ctr.ErrNotImplemented +} + +// Kill sends a signal to all running containers within a pod +func (p *Pod) Kill(signal uint) error { + return ctr.ErrNotImplemented +} + +// GetContainers retrieves the containers in the pod +func (p *Pod) GetContainers() ([]*ctr.Container, error) { + return nil, ctr.ErrNotImplemented +} + +// Status gets the status of all containers in the pod +// TODO This should return a summary of the states of all containers in the pod +func (p *Pod) Status() error { + return ctr.ErrNotImplemented +} diff --git a/libpod/runtime.go b/libpod/runtime.go new file mode 100644 index 00000000..9e5d0f54 --- /dev/null +++ b/libpod/runtime.go @@ -0,0 +1,100 @@ +package libpod + +import ( + "github.com/kubernetes-incubator/cri-o/libpod/ctr" + "github.com/kubernetes-incubator/cri-o/libpod/pod" + spec "github.com/opencontainers/runtime-spec/specs-go" +) + +// 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 + +// 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 + +// A RuntimeOption is a functional option which alters the Runtime created by +// NewRuntime +type RuntimeOption func(*Runtime) error + +// A CtrCreateOption is a functional option which alters the Container created +// by NewContainer +type CtrCreateOption func(*ctr.Container) error + +// Runtime is the core libpod runtime +type Runtime struct { + // TODO populate +} + +// NewRuntime creates a new container runtime +func NewRuntime(options ...RuntimeOption) (*Runtime, error) { + return nil, ctr.ErrNotImplemented +} + +// 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 +} + +// 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 +} + +// TODO Add image API From bdddb3d36b6628eb3d63105a8a373b68aacb4f51 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Tue, 15 Aug 2017 11:25:35 -0400 Subject: [PATCH 2/4] Add preliminary libpod image API Signed-off-by: Matthew Heon --- libpod/runtime.go | 95 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 14 deletions(-) diff --git a/libpod/runtime.go b/libpod/runtime.go index 9e5d0f54..763974ce 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -1,29 +1,18 @@ package libpod import ( + "github.com/containers/storage" "github.com/kubernetes-incubator/cri-o/libpod/ctr" "github.com/kubernetes-incubator/cri-o/libpod/pod" spec "github.com/opencontainers/runtime-spec/specs-go" ) -// 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 - -// 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 +// Runtime API // A RuntimeOption is a functional option which alters the Runtime created by // NewRuntime type RuntimeOption func(*Runtime) error -// A CtrCreateOption is a functional option which alters the Container created -// by NewContainer -type CtrCreateOption func(*ctr.Container) error - // Runtime is the core libpod runtime type Runtime struct { // TODO populate @@ -34,6 +23,17 @@ func NewRuntime(options ...RuntimeOption) (*Runtime, error) { return nil, ctr.ErrNotImplemented } +// 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 + // 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 @@ -65,6 +65,13 @@ func (r *Runtime) GetContainers(filters ...ContainerFilter) ([]*ctr.Container, e return nil, ctr.ErrNotImplemented } +// 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 + // NewPod makes a new, empty pod func (r *Runtime) NewPod() (*pod.Pod, error) { return nil, ctr.ErrNotImplemented @@ -97,4 +104,64 @@ func (r *Runtime) GetPods(filters ...PodFilter) ([]*pod.Pod, error) { return nil, ctr.ErrNotImplemented } -// TODO Add image API +// 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 +} + +// CommitContainer commits the changes between a container and its image, +// creating a new image +// If the container was not created from an image (for example, +// WithRootFSFromPath will create a container from a directory on the system), +// a new base image will be created from the contents of the container's +// filesystem +func (r *Runtime) CommitContainer(c *ctr.Container) (*storage.Image, error) { + return nil, ctr.ErrNotImplemented +} From 6be525b9f0b32a6e03c8e8063eda6d330d5c596e Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Tue, 15 Aug 2017 14:33:40 -0400 Subject: [PATCH 3/4] Modify container exec and attach, add image import/export Signed-off-by: Matthew Heon --- libpod/ctr/container.go | 14 ++++++-------- libpod/runtime.go | 10 ++++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/libpod/ctr/container.go b/libpod/ctr/container.go index bba91ca5..66a95278 100644 --- a/libpod/ctr/container.go +++ b/libpod/ctr/container.go @@ -35,17 +35,15 @@ func (c *Container) Kill(signal uint) error { } // Exec starts a new process inside the container -// TODO does this need arguments? -// TODO should this return anything besides error? -func (c *Container) Exec() error { - return ErrNotImplemented +// Returns fully qualified URL of streaming server for executed process +func (c *Container) Exec(cmd []string, tty bool, stdin bool) (string, error) { + return "", ErrNotImplemented } // Attach attaches to a container -// TODO does this need arguments? -// TODO should this return anything besides error? -func (c *Container) Attach() error { - return ErrNotImplemented +// Returns fully qualified URL of streaming server for the container +func (c *Container) Attach(stdin, tty bool) (string, error) { + return "", ErrNotImplemented } // Mount mounts a container's filesystem on the host diff --git a/libpod/runtime.go b/libpod/runtime.go index 763974ce..53d4535f 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -156,6 +156,16 @@ func (r *Runtime) GetImages(filter ...ImageFilter) ([]*storage.Image, error) { return nil, ctr.ErrNotImplemented } +// 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 +} + +// ExportImage exports an image to an OCI archive, saving it at the given path +func (r *Runtime) ExportImage(image *storage.Image, path string) error { + return ctr.ErrNotImplemented +} + // CommitContainer commits the changes between a container and its image, // creating a new image // If the container was not created from an image (for example, From d6eb9430759a6af918b434a1331ec6bf9311c1ea Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 17 Aug 2017 10:43:02 -0400 Subject: [PATCH 4/4] Move some image functions around Signed-off-by: Matthew Heon --- libpod/ctr/container.go | 18 ++++++++++++++++++ libpod/runtime.go | 15 --------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/libpod/ctr/container.go b/libpod/ctr/container.go index 66a95278..3e5ed146 100644 --- a/libpod/ctr/container.go +++ b/libpod/ctr/container.go @@ -2,6 +2,8 @@ package ctr import ( "fmt" + + "github.com/containers/storage" ) var ( @@ -57,3 +59,19 @@ func (c *Container) Mount() (string, error) { func (c *Container) Status() error { return ErrNotImplemented } + +// Export exports a container's root filesystem as a tar archive +// The archive will be saved as a file at the given path +func (c *Container) Export(path string) error { + return ErrNotImplemented +} + +// Commit commits the changes between a container and its image, creating a new +// image +// If the container was not created from an image (for example, +// WithRootFSFromPath will create a container from a directory on the system), +// a new base image will be created from the contents of the container's +// filesystem +func (c *Container) Commit() (*storage.Image, error) { + return nil, ErrNotImplemented +} diff --git a/libpod/runtime.go b/libpod/runtime.go index 53d4535f..8e7125e5 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -160,18 +160,3 @@ func (r *Runtime) GetImages(filter ...ImageFilter) ([]*storage.Image, error) { func (r *Runtime) ImportImage(path string) (*storage.Image, error) { return nil, ctr.ErrNotImplemented } - -// ExportImage exports an image to an OCI archive, saving it at the given path -func (r *Runtime) ExportImage(image *storage.Image, path string) error { - return ctr.ErrNotImplemented -} - -// CommitContainer commits the changes between a container and its image, -// creating a new image -// If the container was not created from an image (for example, -// WithRootFSFromPath will create a container from a directory on the system), -// a new base image will be created from the contents of the container's -// filesystem -func (r *Runtime) CommitContainer(c *ctr.Container) (*storage.Image, error) { - return nil, ctr.ErrNotImplemented -}