diff --git a/client.go b/client.go index 148e6445f..f8b4b904d 100644 --- a/client.go +++ b/client.go @@ -11,7 +11,7 @@ import ( "sync" "time" - "github.com/containerd/containerd/api/services/containers/v1" + containersapi "github.com/containerd/containerd/api/services/containers/v1" contentapi "github.com/containerd/containerd/api/services/content/v1" diffapi "github.com/containerd/containerd/api/services/diff/v1" eventsapi "github.com/containerd/containerd/api/services/events/v1" @@ -20,6 +20,7 @@ import ( snapshotapi "github.com/containerd/containerd/api/services/snapshot/v1" "github.com/containerd/containerd/api/services/tasks/v1" versionservice "github.com/containerd/containerd/api/services/version/v1" + "github.com/containerd/containerd/containers" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" @@ -139,15 +140,13 @@ func (c *Client) IsServing(ctx context.Context) (bool, error) { // Containers returns all containers created in containerd func (c *Client) Containers(ctx context.Context, filters ...string) ([]Container, error) { - r, err := c.ContainerService().List(ctx, &containers.ListContainersRequest{ - Filters: filters, - }) + r, err := c.ContainerService().List(ctx, filters...) if err != nil { return nil, err } var out []Container - for _, container := range r.Containers { - out = append(out, containerFromProto(c, container)) + for _, container := range r { + out = append(out, containerFromRecord(c, container)) } return out, nil } @@ -212,7 +211,7 @@ func WithNewReadonlyRootFS(id string, i Image) NewContainerOpts { // be used to create tasks for the container func WithRuntime(name string) NewContainerOpts { return func(ctx context.Context, client *Client, c *containers.Container) error { - c.Runtime = &containers.Container_Runtime{ + c.Runtime = containers.RuntimeInfo{ Name: name, } return nil @@ -238,7 +237,7 @@ func WithImage(i Image) NewContainerOpts { func (c *Client) NewContainer(ctx context.Context, id string, opts ...NewContainerOpts) (Container, error) { container := containers.Container{ ID: id, - Runtime: &containers.Container_Runtime{ + Runtime: containers.RuntimeInfo{ Name: c.runtime, }, } @@ -247,23 +246,19 @@ func (c *Client) NewContainer(ctx context.Context, id string, opts ...NewContain return nil, err } } - r, err := c.ContainerService().Create(ctx, &containers.CreateContainerRequest{ - Container: container, - }) + r, err := c.ContainerService().Create(ctx, container) if err != nil { return nil, err } - return containerFromProto(c, r.Container), nil + return containerFromRecord(c, r), nil } func (c *Client) LoadContainer(ctx context.Context, id string) (Container, error) { - response, err := c.ContainerService().Get(ctx, &containers.GetContainerRequest{ - ID: id, - }) + r, err := c.ContainerService().Get(ctx, id) if err != nil { return nil, err } - return containerFromProto(c, response.Container), nil + return containerFromRecord(c, r), nil } type RemoteOpts func(*Client, *RemoteContext) error @@ -506,8 +501,8 @@ func (c *Client) NamespaceService() namespacesapi.NamespacesClient { return namespacesapi.NewNamespacesClient(c.conn) } -func (c *Client) ContainerService() containers.ContainersClient { - return containers.NewContainersClient(c.conn) +func (c *Client) ContainerService() containers.Store { + return NewRemoteContainerStore(containersapi.NewContainersClient(c.conn)) } func (c *Client) ContentStore() content.Store { diff --git a/cmd/ctr/info.go b/cmd/ctr/info.go index e3a1323f4..37a7400fa 100644 --- a/cmd/ctr/info.go +++ b/cmd/ctr/info.go @@ -31,7 +31,7 @@ var infoCommand = cli.Command{ if err != nil { return err } - cjson, err := json.MarshalIndent(container.Proto(), "", " ") + cjson, err := json.MarshalIndent(container.Info(), "", " ") if err != nil { return err } diff --git a/cmd/ctr/list.go b/cmd/ctr/list.go index 29893bbff..6315442cc 100644 --- a/cmd/ctr/list.go +++ b/cmd/ctr/list.go @@ -110,7 +110,7 @@ func containerListFn(context *cli.Context) error { fmt.Fprintln(w, "CONTAINER\tIMAGE\tRUNTIME\tLABELS\t") for _, c := range containers { var labelStrings []string - for k, v := range c.Proto().Labels { + for k, v := range c.Info().Labels { labelStrings = append(labelStrings, strings.Join([]string{k, v}, "=")) } labels := strings.Join(labelStrings, ",") @@ -128,11 +128,11 @@ func containerListFn(context *cli.Context) error { imageName = image.Name() } - proto := c.Proto() + record := c.Info() if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%v\t\n", c.ID(), imageName, - proto.Runtime.Name, + record.Runtime.Name, labels, ); err != nil { return err diff --git a/container.go b/container.go index c98039f4d..fd7cfe2a2 100644 --- a/container.go +++ b/container.go @@ -10,11 +10,10 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" - "github.com/containerd/containerd/api/services/containers/v1" "github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/api/types" + "github.com/containerd/containerd/containers" "github.com/containerd/containerd/typeurl" - ptypes "github.com/gogo/protobuf/types" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" ) @@ -31,7 +30,7 @@ type DeleteOpts func(context.Context, *Client, containers.Container) error type Container interface { ID() string - Proto() containers.Container + Info() containers.Container Delete(context.Context, ...DeleteOpts) error NewTask(context.Context, IOCreation, ...NewTaskOpts) (Task, error) Spec() (*specs.Spec, error) @@ -41,7 +40,7 @@ type Container interface { SetLabels(context.Context, map[string]string) (map[string]string, error) } -func containerFromProto(client *Client, c containers.Container) *container { +func containerFromRecord(client *Client, c containers.Container) *container { return &container{ client: client, c: c, @@ -62,21 +61,19 @@ func (c *container) ID() string { return c.c.ID } -func (c *container) Proto() containers.Container { +func (c *container) Info() containers.Container { return c.c } func (c *container) Labels(ctx context.Context) (map[string]string, error) { - resp, err := c.client.ContainerService().Get(ctx, &containers.GetContainerRequest{ - ID: c.ID(), - }) + r, err := c.client.ContainerService().Get(ctx, c.ID()) if err != nil { return nil, err } - c.c = resp.Container + c.c = r - m := make(map[string]string, len(resp.Container.Labels)) + m := make(map[string]string, len(r.Labels)) for k, v := range c.c.Labels { m[k] = v } @@ -85,28 +82,26 @@ func (c *container) Labels(ctx context.Context) (map[string]string, error) { } func (c *container) SetLabels(ctx context.Context, labels map[string]string) (map[string]string, error) { - var req containers.UpdateContainerRequest - - req.Container.ID = c.ID() - req.Container.Labels = labels - - req.UpdateMask = &ptypes.FieldMask{ - Paths: make([]string, 0, len(labels)), + container := containers.Container{ + ID: c.ID(), + Labels: labels, } + + var paths []string // mask off paths so we only muck with the labels encountered in labels. // Labels not in the passed in argument will be left alone. for k := range labels { - req.UpdateMask.Paths = append(req.UpdateMask.Paths, strings.Join([]string{"labels", k}, ".")) + paths = append(paths, strings.Join([]string{"labels", k}, ".")) } - resp, err := c.client.ContainerService().Update(ctx, &req) + r, err := c.client.ContainerService().Update(ctx, container, paths...) if err != nil { return nil, err } - c.c = resp.Container // update our local container + c.c = r // update our local container - m := make(map[string]string, len(resp.Container.Labels)) + m := make(map[string]string, len(r.Labels)) for k, v := range c.c.Labels { m[k] = v } @@ -141,9 +136,8 @@ func (c *container) Delete(ctx context.Context, opts ...DeleteOpts) (err error) return err } } - if _, cerr := c.client.ContainerService().Delete(ctx, &containers.DeleteContainerRequest{ - ID: c.c.ID, - }); err == nil { + + if cerr := c.client.ContainerService().Delete(ctx, c.ID()); err == nil { err = cerr } return err diff --git a/container_unix.go b/container_unix.go index c19aa4955..c3624f79b 100644 --- a/container_unix.go +++ b/container_unix.go @@ -8,8 +8,8 @@ import ( "fmt" "io/ioutil" - "github.com/containerd/containerd/api/services/containers/v1" "github.com/containerd/containerd/api/types" + "github.com/containerd/containerd/containers" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" diff --git a/containerstore.go b/containerstore.go new file mode 100644 index 000000000..9ab8ca162 --- /dev/null +++ b/containerstore.go @@ -0,0 +1,130 @@ +package containerd + +import ( + "context" + + containersapi "github.com/containerd/containerd/api/services/containers/v1" + "github.com/containerd/containerd/containers" + "github.com/containerd/containerd/errdefs" + ptypes "github.com/gogo/protobuf/types" +) + +type remoteContainers struct { + client containersapi.ContainersClient +} + +var _ containers.Store = &remoteContainers{} + +func NewRemoteContainerStore(client containersapi.ContainersClient) containers.Store { + return &remoteContainers{ + client: client, + } +} + +func (r *remoteContainers) Get(ctx context.Context, id string) (containers.Container, error) { + resp, err := r.client.Get(ctx, &containersapi.GetContainerRequest{ + ID: id, + }) + if err != nil { + return containers.Container{}, errdefs.FromGRPC(err) + } + + return containerFromProto(&resp.Container), nil +} + +func (r *remoteContainers) List(ctx context.Context, filters ...string) ([]containers.Container, error) { + resp, err := r.client.List(ctx, &containersapi.ListContainersRequest{ + Filters: filters, + }) + if err != nil { + return nil, errdefs.FromGRPC(err) + } + + return containersFromProto(resp.Containers), nil + +} + +func (r *remoteContainers) Create(ctx context.Context, container containers.Container) (containers.Container, error) { + created, err := r.client.Create(ctx, &containersapi.CreateContainerRequest{ + Container: containerToProto(&container), + }) + if err != nil { + return containers.Container{}, errdefs.FromGRPC(err) + } + + return containerFromProto(&created.Container), nil + +} + +func (r *remoteContainers) Update(ctx context.Context, container containers.Container, fieldpaths ...string) (containers.Container, error) { + var updateMask *ptypes.FieldMask + if len(fieldpaths) > 0 { + updateMask = &ptypes.FieldMask{ + Paths: fieldpaths, + } + } + + updated, err := r.client.Update(ctx, &containersapi.UpdateContainerRequest{ + Container: containerToProto(&container), + UpdateMask: updateMask, + }) + if err != nil { + return containers.Container{}, errdefs.FromGRPC(err) + } + + return containerFromProto(&updated.Container), nil + +} + +func (r *remoteContainers) Delete(ctx context.Context, id string) error { + _, err := r.client.Delete(ctx, &containersapi.DeleteContainerRequest{ + ID: id, + }) + + return errdefs.FromGRPC(err) + +} + +func containerToProto(container *containers.Container) containersapi.Container { + return containersapi.Container{ + ID: container.ID, + Labels: container.Labels, + Image: container.Image, + Runtime: &containersapi.Container_Runtime{ + Name: container.Runtime.Name, + Options: container.Runtime.Options, + }, + Spec: container.Spec, + Snapshotter: container.Snapshotter, + RootFS: container.RootFS, + } +} + +func containerFromProto(containerpb *containersapi.Container) containers.Container { + var runtime containers.RuntimeInfo + if containerpb.Runtime != nil { + runtime = containers.RuntimeInfo{ + Name: containerpb.Runtime.Name, + Options: containerpb.Runtime.Options, + } + } + return containers.Container{ + ID: containerpb.ID, + Labels: containerpb.Labels, + Image: containerpb.Image, + Runtime: runtime, + Spec: containerpb.Spec, + Snapshotter: containerpb.Snapshotter, + RootFS: containerpb.RootFS, + } +} + +func containersFromProto(containerspb []containersapi.Container) []containers.Container { + var containers []containers.Container + + for _, container := range containerspb { + containers = append(containers, containerFromProto(&container)) + } + + return containers +} diff --git a/spec_unix.go b/spec_unix.go index e3109fdb0..b8e1171b6 100644 --- a/spec_unix.go +++ b/spec_unix.go @@ -9,7 +9,7 @@ import ( "strconv" "strings" - "github.com/containerd/containerd/api/services/containers/v1" + "github.com/containerd/containerd/containers" "github.com/containerd/containerd/images" "github.com/containerd/containerd/typeurl" "github.com/opencontainers/image-spec/specs-go/v1" diff --git a/spec_windows.go b/spec_windows.go index 709c504c6..9341384b1 100644 --- a/spec_windows.go +++ b/spec_windows.go @@ -5,7 +5,7 @@ import ( "encoding/json" "fmt" - "github.com/containerd/containerd/api/services/containers/v1" + "github.com/containerd/containerd/containers" "github.com/containerd/containerd/images" "github.com/containerd/containerd/typeurl" "github.com/opencontainers/image-spec/specs-go/v1" diff --git a/task.go b/task.go index ff32c4af7..ab247dfb0 100644 --- a/task.go +++ b/task.go @@ -10,7 +10,6 @@ import ( "strings" "syscall" - "github.com/containerd/containerd/api/services/containers/v1" eventsapi "github.com/containerd/containerd/api/services/events/v1" "github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/api/types" @@ -279,9 +278,7 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (d v1 return d, err } defer t.Resume(ctx) - cr, err := t.client.ContainerService().Get(ctx, &containers.GetContainerRequest{ - ID: t.id, - }) + cr, err := t.client.ContainerService().Get(ctx, t.id) if err != nil { return d, err } @@ -289,14 +286,14 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (d v1 if err := t.checkpointTask(ctx, &index, request); err != nil { return d, err } - if err := t.checkpointImage(ctx, &index, cr.Container.Image); err != nil { + if err := t.checkpointImage(ctx, &index, cr.Image); err != nil { return d, err } - if err := t.checkpointRWSnapshot(ctx, &index, cr.Container.Snapshotter, cr.Container.RootFS); err != nil { + if err := t.checkpointRWSnapshot(ctx, &index, cr.Snapshotter, cr.RootFS); err != nil { return d, err } index.Annotations = make(map[string]string) - index.Annotations["image.name"] = cr.Container.Image + index.Annotations["image.name"] = cr.Image return t.writeIndex(ctx, &index) }