Add NewContainer and Delete container support

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby
2017-05-24 10:42:37 -07:00
parent d0e5732f0b
commit 31a3bda41b
3 changed files with 171 additions and 5 deletions

102
client.go
View File

@@ -2,11 +2,23 @@ package containerd
import (
"context"
"encoding/json"
"io/ioutil"
"log"
"time"
"github.com/containerd/containerd/api/services/containers"
contentapi "github.com/containerd/containerd/api/services/content"
snapshotapi "github.com/containerd/containerd/api/services/snapshot"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/images"
contentservice "github.com/containerd/containerd/services/content"
snapshotservice "github.com/containerd/containerd/services/snapshot"
"github.com/containerd/containerd/snapshot"
protobuf "github.com/gogo/protobuf/types"
"github.com/opencontainers/image-spec/identity"
"github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
@@ -51,6 +63,88 @@ func (c *Client) Containers(ctx context.Context) ([]*Container, error) {
return out, nil
}
type NewContainerOpts func(ctx context.Context, client *Client, c *containers.Container) error
// NewContainerWithLables adds the provided labels to the container
func NewContainerWithLables(labels map[string]string) NewContainerOpts {
return func(_ context.Context, _ *Client, c *containers.Container) error {
c.Labels = labels
return nil
}
}
// NewContainerWithExistingRootFS uses an existing root filesystem for the container
func NewContainerWithExistingRootFS(id string) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
// check that the snapshot exists, if not, fail on creation
if _, err := client.snapshotter().Mounts(ctx, id); err != nil {
return err
}
c.RootFS = id
return nil
}
}
// NewContainerWithNewRootFS allocates a new snapshot to be used by the container as the
// root filesystem in read-write mode
func NewContainerWithNewRootFS(id string, image v1.Descriptor) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
diffIDs, err := images.RootFS(ctx, client.content(), image)
if err != nil {
return err
}
if _, err := client.snapshotter().Prepare(ctx, id, identity.ChainID(diffIDs).String()); err != nil {
return err
}
c.RootFS = id
return nil
}
}
// NewContainerWithNewReadonlyRootFS allocates a new snapshot to be used by the container as the
// root filesystem in read-only mode
func NewContainerWithNewReadonlyRootFS(id string, image v1.Descriptor) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
diffIDs, err := images.RootFS(ctx, client.content(), image)
if err != nil {
return err
}
if _, err := client.snapshotter().View(ctx, id, identity.ChainID(diffIDs).String()); err != nil {
return err
}
c.RootFS = id
return nil
}
}
// NewContainer will create a new container in container with the provided id
// the id must be unique within the namespace
func (c *Client) NewContainer(ctx context.Context, id string, spec *specs.Spec, opts ...NewContainerOpts) (*Container, error) {
data, err := json.Marshal(spec)
if err != nil {
return nil, err
}
container := containers.Container{
ID: id,
Spec: &protobuf.Any{
TypeUrl: specs.Version,
Value: data,
},
}
for _, o := range opts {
if err := o(ctx, c, &container); err != nil {
return nil, err
}
}
r, err := c.containers().Create(ctx, &containers.CreateContainerRequest{
Container: container,
})
if err != nil {
return nil, err
}
return containerFromProto(c, r.Container), nil
}
// Close closes the clients connection to containerd
func (c *Client) Close() error {
return c.conn.Close()
@@ -59,3 +153,11 @@ func (c *Client) Close() error {
func (c *Client) containers() containers.ContainersClient {
return containers.NewContainersClient(c.conn)
}
func (c *Client) content() content.Store {
return contentservice.NewStoreFromClient(contentapi.NewContentClient(c.conn))
}
func (c *Client) snapshotter() snapshot.Snapshotter {
return snapshotservice.NewSnapshotterFromClient(snapshotapi.NewSnapshotClient(c.conn))
}