containerd/container_unix.go
Michael Crosby 235869eb1f Rename execution service to tasks
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
2017-06-21 14:39:25 -07:00

116 lines
3.0 KiB
Go

// +build !windows
package containerd
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"github.com/containerd/containerd/api/services/containers"
"github.com/containerd/containerd/api/services/tasks"
"github.com/containerd/containerd/api/types/descriptor"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/snapshot"
protobuf "github.com/gogo/protobuf/types"
digest "github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/identity"
"github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
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 {
id := desc.Digest
store := client.ContentStore()
index, err := decodeIndex(ctx, store, id)
if err != nil {
return err
}
var rw *v1.Descriptor
for _, m := range index.Manifests {
switch m.MediaType {
case v1.MediaTypeImageLayer:
fk := m
rw = &fk
case images.MediaTypeDockerSchema2Manifest:
config, err := images.Config(ctx, store, m)
if err != nil {
return err
}
diffIDs, err := images.RootFS(ctx, store, config)
if err != nil {
return err
}
if _, err := client.SnapshotService().Prepare(ctx, rootfsID, identity.ChainID(diffIDs).String()); err != nil {
if !snapshot.IsExist(err) {
return err
}
}
c.Image = index.Annotations["image.name"]
case images.MediaTypeContainerd1CheckpointConfig:
r, err := store.Reader(ctx, m.Digest)
if err != nil {
return err
}
data, err := ioutil.ReadAll(r)
r.Close()
if err != nil {
return err
}
c.Spec = &protobuf.Any{
TypeUrl: specs.Version,
Value: data,
}
}
}
if rw != nil {
// apply the rw snapshot to the new rw layer
mounts, err := client.SnapshotService().Mounts(ctx, rootfsID)
if err != nil {
return err
}
if _, err := client.DiffService().Apply(ctx, *rw, mounts); err != nil {
return err
}
}
c.RootFS = rootfsID
return nil
}
}
func WithTaskCheckpoint(desc v1.Descriptor) NewTaskOpts {
return func(ctx context.Context, c *Client, r *tasks.CreateTaskRequest) error {
id := desc.Digest
index, err := decodeIndex(ctx, c.ContentStore(), id)
if err != nil {
return err
}
for _, m := range index.Manifests {
if m.MediaType == images.MediaTypeContainerd1Checkpoint {
r.Checkpoint = &descriptor.Descriptor{
MediaType: m.MediaType,
Size_: m.Size,
Digest: m.Digest,
}
return nil
}
}
return fmt.Errorf("checkpoint not found in index %s", id)
}
}
func decodeIndex(ctx context.Context, store content.Store, id digest.Digest) (*v1.Index, error) {
var index v1.Index
r, err := store.Reader(ctx, id)
if err != nil {
return nil, err
}
err = json.NewDecoder(r).Decode(&index)
r.Close()
return &index, err
}