From 0a85f6e47daab4b5ebd61834f5c4e0190e5210bc Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Thu, 3 Aug 2017 15:19:31 -0400 Subject: [PATCH] Update godoc for client package Signed-off-by: Michael Crosby --- client.go | 24 ++++++++++++++++++- container.go | 16 +++++++++++++ container_unix.go | 6 +++++ image.go | 5 +++- io.go | 28 +++++++++++++++++----- process.go | 10 ++++++++ spec_unix.go | 9 ++++++- task.go | 60 ++++++++++++++++++++++++++++++++++++----------- 8 files changed, 135 insertions(+), 23 deletions(-) diff --git a/client.go b/client.go index 2664abb88..2e21599b0 100644 --- a/client.go +++ b/client.go @@ -64,8 +64,13 @@ type clientOpts struct { dialOptions []grpc.DialOption } +// ClientOpt allows callers to set options on the containerd client type ClientOpt func(c *clientOpts) error +// WithDefaultNamespace sets the default namespace on the client +// +// Any operation that does not have a namespace set on the context will +// be provided the default namespace func WithDefaultNamespace(ns string) ClientOpt { return func(c *clientOpts) error { c.defaultns = ns @@ -132,6 +137,8 @@ type Client struct { runtime string } +// IsServing returns true if the client can successfully connect to the containerd daemon +// and the healthcheck service returns the SERVING response func (c *Client) IsServing(ctx context.Context) (bool, error) { r, err := c.HealthService().Check(ctx, &grpc_health_v1.HealthCheckRequest{}) if err != nil { @@ -153,6 +160,7 @@ func (c *Client) Containers(ctx context.Context, filters ...string) ([]Container return out, nil } +// NewContainerOpts allows the caller to set additional options when creating a container type NewContainerOpts func(ctx context.Context, client *Client, c *containers.Container) error // WithContainerLabels adds the provided labels to the container @@ -220,6 +228,7 @@ func WithRuntime(name string) NewContainerOpts { } } +// WithSnapshotter sets the provided snapshotter for use by the container func WithSnapshotter(name string) NewContainerOpts { return func(ctx context.Context, client *Client, c *containers.Container) error { c.Snapshotter = name @@ -227,6 +236,7 @@ func WithSnapshotter(name string) NewContainerOpts { } } +// WithImage sets the provided image as the base for the container func WithImage(i Image) NewContainerOpts { return func(ctx context.Context, client *Client, c *containers.Container) error { c.Image = i.Name() @@ -255,6 +265,7 @@ func (c *Client) NewContainer(ctx context.Context, id string, opts ...NewContain return containerFromRecord(c, r), nil } +// LoadContainer loads an existing container from metadata func (c *Client) LoadContainer(ctx context.Context, id string) (Container, error) { r, err := c.ContainerService().Get(ctx, id) if err != nil { @@ -263,6 +274,7 @@ func (c *Client) LoadContainer(ctx context.Context, id string) (Container, error return containerFromRecord(c, r), nil } +// RemoteOpts allows the caller to set distribution options for a remote type RemoteOpts func(*Client, *RemoteContext) error // RemoteContext is used to configure object resolutions and transfers with @@ -339,6 +351,7 @@ func WithImageHandler(h images.Handler) RemoteOpts { } } +// Pull downloads the provided content into containerd's content store func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Image, error) { pullCtx := defaultRemoteContext() for _, o := range opts { @@ -414,6 +427,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Imag return img, nil } +// Push uploads the provided content to a remote resource func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, opts ...RemoteOpts) error { pushCtx := defaultRemoteContext() for _, o := range opts { @@ -539,11 +553,15 @@ func (c *Client) VersionService() versionservice.VersionClient { return versionservice.NewVersionClient(c.conn) } +// Version of containerd type Version struct { - Version string + // Version number + Version string + // Revision from git that was built Revision string } +// Version returns the version of containerd that the client is connected to func (c *Client) Version(ctx context.Context) (Version, error) { response, err := c.VersionService().Version(ctx, &pempty.Empty{}) if err != nil { @@ -566,8 +584,10 @@ type importOpts struct { refObject string } +// ImportOpt allows the caller to specify import specific options type ImportOpt func(c *importOpts) error +// WithOCIImportFormat sets the import format for an OCI image format func WithOCIImportFormat() ImportOpt { return func(c *importOpts) error { if c.format != "" { @@ -630,8 +650,10 @@ type exportOpts struct { format imageFormat } +// ExportOpt allows callers to set export options type ExportOpt func(c *exportOpts) error +// WithOCIExportFormat sets the OCI image format as the export target func WithOCIExportFormat() ExportOpt { return func(c *exportOpts) error { if c.format != "" { diff --git a/container.go b/container.go index ccbc5be43..38f88d7dc 100644 --- a/container.go +++ b/container.go @@ -17,17 +17,31 @@ import ( "github.com/pkg/errors" ) +// DeleteOpts allows the caller to set options for the deletion of a container type DeleteOpts func(context.Context, *Client, containers.Container) error +// Container is a metadata object for container resources and task creation type Container interface { + // ID identifies the container ID() string + // Info returns the underlying container record type Info() containers.Container + // Delete removes the container Delete(context.Context, ...DeleteOpts) error + // NewTask creates a new task based on the container metadata NewTask(context.Context, IOCreation, ...NewTaskOpts) (Task, error) + // Spec returns the OCI runtime specification Spec() (*specs.Spec, error) + // Task returns the current task for the container + // + // If IOAttach options are passed the client will reattach to the IO for the running + // task. If no task exists for the container a NotFound error is returned Task(context.Context, IOAttach) (Task, error) + // Image returns the image that the container is based on Image(context.Context) (Image, error) + // Labels returns the labels set on the container Labels(context.Context) (map[string]string, error) + // SetLabels sets the provided labels for the container and returns the final label set SetLabels(context.Context, map[string]string) (map[string]string, error) } @@ -153,8 +167,10 @@ func (c *container) Image(ctx context.Context) (Image, error) { }, nil } +// NewTaskOpts allows the caller to set options on a new task type NewTaskOpts func(context.Context, *Client, *TaskInfo) error +// WithRootFS allows a task to be created without a snapshot being allocated to its container func WithRootFS(mounts []mount.Mount) NewTaskOpts { return func(ctx context.Context, c *Client, ti *TaskInfo) error { ti.RootFS = mounts diff --git a/container_unix.go b/container_unix.go index c3624f79b..d83baf7f5 100644 --- a/container_unix.go +++ b/container_unix.go @@ -20,6 +20,9 @@ import ( "github.com/opencontainers/image-spec/specs-go/v1" ) +// WithCheckpoint allows a container to be created from the checkpointed information +// provided by the descriptor. The image, snapshot, and runtime specifications are +// restored on the container func WithCheckpoint(desc v1.Descriptor, rootfsID string) NewContainerOpts { // set image and rw, and spec return func(ctx context.Context, client *Client, c *containers.Container) error { @@ -82,6 +85,9 @@ func WithCheckpoint(desc v1.Descriptor, rootfsID string) NewContainerOpts { } } +// WithTaskCheckpoint allows a task to be created with live runtime and memory data from a +// previous checkpoint. Additional software such as CRIU may be required to +// restore a task from a checkpoint func WithTaskCheckpoint(desc v1.Descriptor) NewTaskOpts { return func(ctx context.Context, c *Client, info *TaskInfo) error { id := desc.Digest diff --git a/image.go b/image.go index 0057e4dee..d1d241599 100644 --- a/image.go +++ b/image.go @@ -12,10 +12,13 @@ import ( "github.com/pkg/errors" ) +// Image describes an image used by containers type Image interface { + // Name of the image Name() string + // Target descriptor for the image content Target() ocispec.Descriptor - + // Unpack unpacks the image's content into a snapshot Unpack(context.Context, string) error } diff --git a/io.go b/io.go index d144d2879..24d927635 100644 --- a/io.go +++ b/io.go @@ -8,15 +8,21 @@ import ( "sync" ) +// IO holds the io information for a task or process type IO struct { + // Terminal is true if one has been allocated Terminal bool - Stdin string - Stdout string - Stderr string + // Stdin path + Stdin string + // Stdout path + Stdout string + // Stderr path + Stderr string closer *wgCloser } +// Cancel aborts all current io operations func (i *IO) Cancel() { if i.closer == nil { return @@ -24,6 +30,7 @@ func (i *IO) Cancel() { i.closer.Cancel() } +// Wait blocks until all io copy operations have completed func (i *IO) Wait() { if i.closer == nil { return @@ -31,6 +38,7 @@ func (i *IO) Wait() { i.closer.Wait() } +// Close cleans up all open io resources func (i *IO) Close() error { if i.closer == nil { return nil @@ -38,14 +46,18 @@ func (i *IO) Close() error { return i.closer.Close() } +// IOCreation creates new IO sets for a task type IOCreation func(id string) (*IO, error) +// IOAttach allows callers to reattach to running tasks type IOAttach func(*FIFOSet) (*IO, error) +// NewIO returns an IOCreation that will provide IO sets without a terminal func NewIO(stdin io.Reader, stdout, stderr io.Writer) IOCreation { return NewIOWithTerminal(stdin, stdout, stderr, false) } +// NewIOWithTerminal creates a new io set with the provied io.Reader/Writers for use with a terminal func NewIOWithTerminal(stdin io.Reader, stdout, stderr io.Writer, terminal bool) IOCreation { return func(id string) (*IO, error) { paths, err := NewFifos(id) @@ -72,6 +84,7 @@ func NewIOWithTerminal(stdin io.Reader, stdout, stderr io.Writer, terminal bool) } } +// WithAttach attaches the existing io for a task to the provided io.Reader/Writers func WithAttach(stdin io.Reader, stdout, stderr io.Writer) IOAttach { return func(paths *FIFOSet) (*IO, error) { if paths == nil { @@ -97,7 +110,7 @@ func WithAttach(stdin io.Reader, stdout, stderr io.Writer) IOAttach { } } -// Stdio returns an IO implementation to be used for a task +// Stdio returns an IO set to be used for a task // that outputs the container's IO as the current processes Stdio func Stdio(id string) (*IO, error) { return NewIO(os.Stdin, os.Stdout, os.Stderr)(id) @@ -108,11 +121,14 @@ func StdioTerminal(id string) (*IO, error) { return NewIOWithTerminal(os.Stdin, os.Stdout, os.Stderr, true)(id) } +// FIFOSet is a set of fifos for use with tasks type FIFOSet struct { // Dir is the directory holding the task fifos - Dir string + Dir string + // In, Out, and Err fifo paths In, Out, Err string - Terminal bool + // Terminal returns true if a terminal is being used for the task + Terminal bool } type ioSet struct { diff --git a/process.go b/process.go index 4135e0d17..e5b1cf1ad 100644 --- a/process.go +++ b/process.go @@ -13,15 +13,25 @@ import ( specs "github.com/opencontainers/runtime-spec/specs-go" ) +// Process represents a system process type Process interface { + // Pid is the system specific process id Pid() uint32 + // Start starts the process executing the user's defined binary Start(context.Context) error + // Delete removes the process and any resources allocated returning the exit status Delete(context.Context) (uint32, error) + // Kill sends the provided signal to the process Kill(context.Context, syscall.Signal) error + // Wait blocks until the process has exited returning the exit status Wait(context.Context) (uint32, error) + // CloseIO allows various pipes to be closed on the process CloseIO(context.Context, ...IOCloserOpts) error + // Resize changes the width and heigh of the process's terminal Resize(ctx context.Context, w, h uint32) error + // IO returns the io set for the process IO() *IO + // Status returns the executing status of the process Status(context.Context) (Status, error) } diff --git a/spec_unix.go b/spec_unix.go index 0d40bb6e3..e57ec18fa 100644 --- a/spec_unix.go +++ b/spec_unix.go @@ -162,12 +162,15 @@ func createDefaultSpec() (*specs.Spec, error) { return s, nil } +// WithTTY sets the information on the spec as well as the environment variables for +// using a TTY func WithTTY(s *specs.Spec) error { s.Process.Terminal = true s.Process.Env = append(s.Process.Env, "TERM=xterm") return nil } +// WithHostNamespace allows a task to run inside the host's linux namespace func WithHostNamespace(ns specs.LinuxNamespaceType) SpecOpts { return func(s *specs.Spec) error { for i, n := range s.Linux.Namespaces { @@ -198,6 +201,7 @@ func WithLinuxNamespace(ns specs.LinuxNamespace) SpecOpts { } } +// WithImageConfig configures the spec to from the configuration of an Image func WithImageConfig(ctx context.Context, i Image) SpecOpts { return func(s *specs.Spec) error { var ( @@ -304,7 +308,8 @@ func WithNoNewPrivileges(s *specs.Spec) error { return nil } -func WithHostHosts(s *specs.Spec) error { +// WithHostHostsFile bind-mounts the host's /etc/hosts into the container as readonly +func WithHostHostsFile(s *specs.Spec) error { s.Mounts = append(s.Mounts, specs.Mount{ Destination: "/etc/hosts", Type: "bind", @@ -314,6 +319,7 @@ func WithHostHosts(s *specs.Spec) error { return nil } +// WithHostResoveconf bind-mounts the host's /etc/resolv.conf into the container as readonly func WithHostResoveconf(s *specs.Spec) error { s.Mounts = append(s.Mounts, specs.Mount{ Destination: "/etc/resolv.conf", @@ -324,6 +330,7 @@ func WithHostResoveconf(s *specs.Spec) error { return nil } +// WithHostLocaltime bind-mounts the host's /etc/localtime into the container as readonly func WithHostLocaltime(s *specs.Spec) error { s.Mounts = append(s.Mounts, specs.Mount{ Destination: "/etc/localtime", diff --git a/task.go b/task.go index f7cb4bb4d..dc24349f4 100644 --- a/task.go +++ b/task.go @@ -27,61 +27,89 @@ import ( "github.com/pkg/errors" ) +// UnknownExitStatus is returned when containerd is unable to +// determine the exit status of a process. This can happen if the process never starts +// or if an error was encountered when obtaining the exit status, it is set to 255. const UnknownExitStatus = 255 +// Status returns process status and exit information type Status struct { - Status ProcessStatus + // Status of the process + Status ProcessStatus + // ExitStatus returned by the process ExitStatus uint32 } type ProcessStatus string const ( + // Running indicates the process is currently executing Running ProcessStatus = "running" + // Created indicates the process has been created within containerd but the + // user's defined process has not started Created ProcessStatus = "created" + // Stopped indicates that the process has ran and exited Stopped ProcessStatus = "stopped" - Paused ProcessStatus = "paused" + // Paused indicates that the process is currently paused + Paused ProcessStatus = "paused" + // Pausing indicates that the process is currently switching from a + // running state into a paused state Pausing ProcessStatus = "pausing" ) +// IOCloseInfo allows specific io pipes to be closed on a process type IOCloseInfo struct { Stdin bool } +// IOCloserOpts allows the caller to set specific pipes as closed on a process type IOCloserOpts func(*IOCloseInfo) +// WithStdinCloser closes the stdin of a process func WithStdinCloser(r *IOCloseInfo) { r.Stdin = true } +// CheckpointTaskInfo allows specific checkpoint information to be set for the task type CheckpointTaskInfo struct { + // ParentCheckpoint is the digest of a parent checkpoint ParentCheckpoint digest.Digest - Options interface{} + // Options hold runtime specific settings for checkpointing a task + Options interface{} } +// CheckpointTaskOpts allows the caller to set checkpoint options type CheckpointTaskOpts func(*CheckpointTaskInfo) error +// TaskInfo sets options for task creation type TaskInfo struct { + // Checkpoint is the Descriptor for an existing checkpoint that can be used + // to restore a task's runtime and memory state Checkpoint *types.Descriptor - RootFS []mount.Mount - Options interface{} + // RootFS is a list of mounts to use as the task's root filesystem + RootFS []mount.Mount + // Options hold runtime specific settings for task creation + Options interface{} } +// Task is the executable object within containerd type Task interface { - Pid() uint32 - Delete(context.Context) (uint32, error) - Kill(context.Context, syscall.Signal) error + Process + + // Pause suspends the execution of the task Pause(context.Context) error + // Resume the execution of the task Resume(context.Context) error - Start(context.Context) error - Status(context.Context) (Status, error) - Wait(context.Context) (uint32, error) + // Exec creates a new process inside the task Exec(context.Context, string, *specs.Process, IOCreation) (Process, error) + // Pids returns a list of system specific process ids inside the task Pids(context.Context) ([]uint32, error) - CloseIO(context.Context, ...IOCloserOpts) error - Resize(ctx context.Context, w, h uint32) error - IO() *IO + // Checkpoint serializes the runtime and memory information of a task into an + // OCI Index that can be push and pulled from a remote resource. + // + // Additional software like CRIU maybe required to checkpoint and restore tasks Checkpoint(context.Context, ...CheckpointTaskOpts) (v1.Descriptor, error) + // Update modifies executing tasks with updated settings Update(context.Context, ...UpdateTaskOpts) error } @@ -335,10 +363,13 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (d v1 return t.writeIndex(ctx, &index) } +// UpdateTaskInfo allows updated specific settings to be changed on a task type UpdateTaskInfo struct { + // Resources updates a tasks resource constraints Resources interface{} } +// UpdateTaskOpts allows a caller to update task settings type UpdateTaskOpts func(context.Context, *Client, *UpdateTaskInfo) error func (t *task) Update(ctx context.Context, opts ...UpdateTaskOpts) error { @@ -435,6 +466,7 @@ func writeContent(ctx context.Context, store content.Store, mediaType, ref strin }, nil } +// WithExit causes the task to exit after a successful checkpoint func WithExit(r *CheckpointTaskInfo) error { r.Options = &runcopts.CheckpointOptions{ Exit: true,