Update api proposal

Move concepts into specific files for easy management
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@docker.com> (github: crosbymichael)

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@docker.com> (github: vmarmol)
This commit is contained in:
Michael Crosby 2014-07-08 10:17:05 -07:00 committed by Victor Marmol
parent 173642ab0b
commit dbb515f01f
7 changed files with 190 additions and 232 deletions

150
api.go
View File

@ -1,150 +0,0 @@
/*
API for libcontainer.
NOTE: The API is in flux and mainly not implemented. Proceed with caution until further notice.
*/
package libcontainer
import (
"io"
)
// Name of a container.
//
// Allowable characters for container names are:
// - Alpha numeric ([a-zA-Z0-9])
// - Underscores (_)
type Name string
// The running state of the container.
type RunState int
const (
// The container exists and is running.
RUNNING RunState = iota
// The container exists, it is in the process of being paused.
PAUSING RunState = iota
// The container exists, but all its processes are paused.
PAUSED RunState = iota
// The container does not exist.
DESTROYED RunState = iota
)
// Configuration for a process to be run inside a container.
type ProcessConfig struct {
// The command to be run followed by any arguments.
Args []string
// Map of environment variables to their values.
Env []string
// Stdin is a pointer to a reader which provides the standard input stream.
// Stdout is a pointer to a writer which receives the standard output stream.
// Stderr is a pointer to a writer which receives the standard error stream.
//
// If a reader or writer is nil, the input stream is assumed to be empty and the output is
// discarded.
//
// The readers and writers, if supplied, are closed when the process terminates. Their Close
// methods should be idempotent.
//
// Stdout and Stderr may refer to the same writer in which case the output is interspersed.
Stdin *io.ReadCloser
Stdout *io.WriteCloser
Stderr *io.WriteCloser
// TODO(vmarmol): Complete.
// ProcessConfig take over some of the runtime config from Config.
// This is anything that can be set per-process that enters the container and its namespaces.
//
// Things like:
// - Namespaces
// - Capabilities
// - User/Groups
// - Working directory
}
// Factory of libcontainer containers.
type Factory interface {
// Creates a new container as specified, and starts an init process inside.
//
// The container and PID of the init process is returned. The init must be reaped by the caller.
//
// Errors: name already exists,
// config or initialConfig invalid,
// system error.
//
// Arguments:
// name: The user-provided name of the container. Used to identify this container, must be unique
// in this machine.
// config: The configuration of the new container.
// initialProcess: The configuration of the init to run inside the container.
//
// On error, any partially created container parts are cleaned up (the operation is atomic).
Create(name Name, config *Config, initialProcess *ProcessConfig) (*Container, int, error)
}
// A libcontainer container object. Must be created by the Factory above.
//
// Each container is thread-safe within the same process. Since a container can
// be destroyed by a separate process, any function may return that the container
// was not found.
type Container interface {
// Returns the name of this container.
Name() Name
// Returns the current run state of the container.
//
// Errors: container no longer exists,
// system error.
RunState() (RunState, error)
// Returns the current config of the container.
//
// Errors: container no longer exists,
// system error.
Config() (*Config, error)
// Destroys the container after killing all running processes.
//
// Any event registrations are removed before the container is destroyed.
// No error is returned if the container is already destroyed.
//
// Errors: system error.
Destroy() error
// Returns the PIDs inside this container. The PIDs are in the namespace of the calling process.
//
// Errors: container no longer exists,
// system error.
//
// Some of the returned PIDs may no longer refer to processes in the Container, unless
// the Container state is PAUSED in which case every PID in the slice is valid.
Processes() ([]int, error)
// Returns statistics for the container.
//
// Errors: container no longer exists,
// system error.
Stats() (*ContainerStats, error)
// If the Container state is RUNNING or PAUSING, sets the Container state to PAUSING and pauses
// the execution of any user processes. Asynchronously, when the container finished being paused the
// state is changed to PAUSED.
// If the Container state is PAUSED, do nothing.
//
// Errors: container no longer exists,
// system error.
Pause() error
// If the Container state is PAUSED, resumes the execution of any user processes in the
// Container before setting the Container state to RUNNING.
// If the Container state is RUNNING, do nothing.
//
// Errors: container no longer exists,
// system error.
Resume() error
}

View File

@ -10,7 +10,6 @@ import (
// TODO(vmarmol): Complete Stats() in final libcontainer API and move users to that.
// DEPRECATED: The below portions are only to be used during the transition to the official API.
// Returns all available stats for the given container.
func GetStats(container *Config, state *State) (*ContainerStats, error) {
var containerStats ContainerStats

86
config.go Normal file
View File

@ -0,0 +1,86 @@
package libcontainer
import (
"github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/mount"
"github.com/docker/libcontainer/network"
)
type MountConfig mount.MountConfig
type Network network.Network
// Config defines configuration options for executing a process inside a contained environment.
type Config struct {
// Mount specific options.
MountConfig *MountConfig `json:"mount_config,omitempty"`
// Hostname optionally sets the container's hostname if provided
Hostname string `json:"hostname,omitempty"`
// User will set the uid and gid of the executing process running inside the container
User string `json:"user,omitempty"`
// WorkingDir will change the processes current working directory inside the container's rootfs
WorkingDir string `json:"working_dir,omitempty"`
// Env will populate the processes environment with the provided values
// Any values from the parent processes will be cleared before the values
// provided in Env are provided to the process
Env []string `json:"environment,omitempty"`
// Tty when true will allocate a pty slave on the host for access by the container's process
// and ensure that it is mounted inside the container's rootfs
Tty bool `json:"tty,omitempty"`
// Namespaces specifies the container's namespaces that it should setup when cloning the init process
// If a namespace is not provided that namespace is shared from the container's parent process
Namespaces map[string]bool `json:"namespaces,omitempty"`
// Capabilities specify the capabilities to keep when executing the process inside the container
// All capbilities not specified will be dropped from the processes capability mask
Capabilities []string `json:"capabilities,omitempty"`
// Networks specifies the container's network setup to be created
Networks []*Network `json:"networks,omitempty"`
// Routes can be specified to create entries in the route table as the container is started
Routes []*Route `json:"routes,omitempty"`
// Cgroups specifies specific cgroup settings for the various subsystems that the container is
// placed into to limit the resources the container has available
Cgroups *cgroups.Cgroup `json:"cgroups,omitempty"`
// AppArmorProfile specifies the profile to apply to the process running in the container and is
// change at the time the process is execed
AppArmorProfile string `json:"apparmor_profile,omitempty"`
// ProcessLabel specifies the label to apply to the process running in the container. It is
// commonly used by selinux
ProcessLabel string `json:"process_label,omitempty"`
// RestrictSys will remount /proc/sys, /sys, and mask over sysrq-trigger as well as /proc/irq and
// /proc/bus
RestrictSys bool `json:"restrict_sys,omitempty"`
}
// Routes can be specified to create entries in the route table as the container is started
//
// All of destination, source, and gateway should be either IPv4 or IPv6.
// One of the three options must be present, and ommitted entries will use their
// IP family default for the route table. For IPv4 for example, setting the
// gateway to 1.2.3.4 and the interface to eth0 will set up a standard
// destination of 0.0.0.0(or *) when viewed in the route table.
type Route struct {
// Sets the destination and mask, should be a CIDR. Accepts IPv4 and IPv6
Destination string `json:"destination,omitempty"`
// Sets the source and mask, should be a CIDR. Accepts IPv4 and IPv6
Source string `json:"source,omitempty"`
// Sets the gateway. Accepts IPv4 and IPv6
Gateway string `json:"gateway,omitempty"`
// The device to set this route up for, for example: eth0
InterfaceName string `json:"interface_name,omitempty"`
}

View File

@ -1,86 +1,63 @@
/*
NOTE: The API is in flux and mainly not implemented. Proceed with caution until further notice.
*/
package libcontainer
import (
"github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/mount"
"github.com/docker/libcontainer/network"
)
type MountConfig mount.MountConfig
type Network network.Network
// Config defines configuration options for executing a process inside a contained environment.
type Config struct {
// Mount specific options.
MountConfig *MountConfig `json:"mount_config,omitempty"`
// Hostname optionally sets the container's hostname if provided
Hostname string `json:"hostname,omitempty"`
// User will set the uid and gid of the executing process running inside the container
User string `json:"user,omitempty"`
// WorkingDir will change the processes current working directory inside the container's rootfs
WorkingDir string `json:"working_dir,omitempty"`
// Env will populate the processes environment with the provided values
// Any values from the parent processes will be cleared before the values
// provided in Env are provided to the process
Env []string `json:"environment,omitempty"`
// Tty when true will allocate a pty slave on the host for access by the container's process
// and ensure that it is mounted inside the container's rootfs
Tty bool `json:"tty,omitempty"`
// Namespaces specifies the container's namespaces that it should setup when cloning the init process
// If a namespace is not provided that namespace is shared from the container's parent process
Namespaces map[string]bool `json:"namespaces,omitempty"`
// Capabilities specify the capabilities to keep when executing the process inside the container
// All capbilities not specified will be dropped from the processes capability mask
Capabilities []string `json:"capabilities,omitempty"`
// Networks specifies the container's network setup to be created
Networks []*Network `json:"networks,omitempty"`
// Routes can be specified to create entries in the route table as the container is started
Routes []*Route `json:"routes,omitempty"`
// Cgroups specifies specific cgroup settings for the various subsystems that the container is
// placed into to limit the resources the container has available
Cgroups *cgroups.Cgroup `json:"cgroups,omitempty"`
// AppArmorProfile specifies the profile to apply to the process running in the container and is
// change at the time the process is execed
AppArmorProfile string `json:"apparmor_profile,omitempty"`
// ProcessLabel specifies the label to apply to the process running in the container. It is
// commonly used by selinux
ProcessLabel string `json:"process_label,omitempty"`
// RestrictSys will remount /proc/sys, /sys, and mask over sysrq-trigger as well as /proc/irq and
// /proc/bus
RestrictSys bool `json:"restrict_sys,omitempty"`
}
// Routes can be specified to create entries in the route table as the container is started
// A libcontainer container object.
//
// All of destination, source, and gateway should be either IPv4 or IPv6.
// One of the three options must be present, and ommitted entries will use their
// IP family default for the route table. For IPv4 for example, setting the
// gateway to 1.2.3.4 and the interface to eth0 will set up a standard
// destination of 0.0.0.0(or *) when viewed in the route table.
type Route struct {
// Sets the destination and mask, should be a CIDR. Accepts IPv4 and IPv6
Destination string `json:"destination,omitempty"`
// Each container is thread-safe within the same process. Since a container can
// be destroyed by a separate process, any function may return that the container
// was not found.
type Container interface {
// Returns the ID of this container.
ID() string
// Sets the source and mask, should be a CIDR. Accepts IPv4 and IPv6
Source string `json:"source,omitempty"`
// Returns the current run state of the container.
//
// Errors: container no longer exists,
// system error.
RunState() (*RunState, error)
// Sets the gateway. Accepts IPv4 and IPv6
Gateway string `json:"gateway,omitempty"`
// Returns the current config of the container.
Config() *Config
// The device to set this route up for, for example: eth0
InterfaceName string `json:"interface_name,omitempty"`
// Destroys the container after killing all running processes.
//
// Any event registrations are removed before the container is destroyed.
// No error is returned if the container is already destroyed.
//
// Errors: system error.
Destroy() error
// Returns the PIDs inside this container. The PIDs are in the namespace of the calling process.
//
// Errors: container no longer exists,
// system error.
//
// Some of the returned PIDs may no longer refer to processes in the Container, unless
// the Container state is PAUSED in which case every PID in the slice is valid.
Processes() ([]int, error)
// Returns statistics for the container.
//
// Errors: container no longer exists,
// system error.
Stats() (*ContainerStats, error)
// If the Container state is RUNNING or PAUSING, sets the Container state to PAUSING and pauses
// the execution of any user processes. Asynchronously, when the container finished being paused the
// state is changed to PAUSED.
// If the Container state is PAUSED, do nothing.
//
// Errors: container no longer exists,
// system error.
Pause() error
// If the Container state is PAUSED, resumes the execution of any user processes in the
// Container before setting the Container state to RUNNING.
// If the Container state is RUNNING, do nothing.
//
// Errors: container no longer exists,
// system error.
Resume() error
}

27
process.go Normal file
View File

@ -0,0 +1,27 @@
package libcontainer
import "io"
// Configuration for a process to be run inside a container.
type ProcessConfig struct {
// The command to be run followed by any arguments.
Args []string
// Map of environment variables to their values.
Env []string
// Stdin is a pointer to a reader which provides the standard input stream.
// Stdout is a pointer to a writer which receives the standard output stream.
// Stderr is a pointer to a writer which receives the standard error stream.
//
// If a reader or writer is nil, the input stream is assumed to be empty and the output is
// discarded.
//
// The readers and writers, if supplied, are closed when the process terminates. Their Close
// methods should be idempotent.
//
// Stdout and Stderr may refer to the same writer in which case the output is interspersed.
Stdin io.ReadCloser
Stdout io.WriteCloser
Stderr io.WriteCloser
}

View File

@ -12,14 +12,33 @@ import (
type State struct {
// InitPid is the init process id in the parent namespace
InitPid int `json:"init_pid,omitempty"`
// InitStartTime is the init process start time
InitStartTime string `json:"init_start_time,omitempty"`
// Network runtime state.
NetworkState network.NetworkState `json:"network_state,omitempty"`
}
// The name of the runtime state file
const stateFile = "state.json"
// The running state of the container.
type RunState int
const (
// The name of the runtime state file
stateFile = "state.json"
// The container exists and is running.
Running RunState = iota
// The container exists, it is in the process of being paused.
Pausing
// The container exists, but all its processes are paused.
Paused
// The container does not exist.
Destroyed
)
// SaveState writes the container's runtime state to a state.json file
// in the specified path