Skip to content

Commit

Permalink
add image name and runtime name media types; remove task operation on…
Browse files Browse the repository at this point in the history
… checkpoint

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
  • Loading branch information
ehazlett committed Nov 12, 2018
1 parent ce0673f commit 1472080
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 57 deletions.
12 changes: 12 additions & 0 deletions cmd/ctr/commands/containers/containers.go
Expand Up @@ -332,6 +332,17 @@ var checkpointCommand = cli.Command{
if err != nil {
return err
}
task, err := container.Task(ctx, nil)
if err != nil {
if !errdefs.IsNotFound(err) {
return err
}
}
if err := task.Pause(ctx); err != nil {
return err
}
defer task.Resume(ctx)

if _, err := container.Checkpoint(ctx, ref, opts...); err != nil {
return err
}
Expand Down Expand Up @@ -378,6 +389,7 @@ var restoreCommand = cli.Command{
}

opts := []containerd.RestoreOpts{
containerd.WithRestoreImage,
containerd.WithRestoreSpec,
containerd.WithRestoreSnapshot,
containerd.WithRestoreRuntime,
Expand Down
85 changes: 44 additions & 41 deletions container.go
Expand Up @@ -295,65 +295,68 @@ func (c *container) Checkpoint(ctx context.Context, ref string, opts ...Checkpoi
FileLocks: true,
EmptyNamespaces: nil,
}
info, err := c.Info(ctx)
if err != nil {
return nil, err
}

img, err := c.Image(ctx)
if err != nil {
return nil, err
}
index.Annotations["image.name"] = img.Name()

ctx, done, err := c.client.WithLease(ctx)
if err != nil {
return nil, err
}
defer done(ctx)

// pause task to checkpoint
if err := func(ctx context.Context) error {
task, err := c.Task(ctx, nil)
// add image name to manifest
ir := bytes.NewReader([]byte(img.Name()))
idesc, err := writeContent(ctx, c.client.ContentStore(), images.MediaTypeContainerd1CheckpointImageName, info.ID+"-image-name", ir)
if err != nil {
return nil, err
}
idesc.Platform = &ocispec.Platform{
OS: runtime.GOOS,
Architecture: runtime.GOARCH,
}
index.Manifests = append(index.Manifests, idesc)

// add runtime info to index
rr := bytes.NewReader([]byte(info.Runtime.Name))
rdesc, err := writeContent(ctx, c.client.ContentStore(), images.MediaTypeContainerd1CheckpointRuntimeName, info.ID+"-runtime-name", rr)
if err != nil {
return nil, err
}
rdesc.Platform = &ocispec.Platform{
OS: runtime.GOOS,
Architecture: runtime.GOARCH,
}
index.Manifests = append(index.Manifests, rdesc)

if info.Runtime.Options != nil {
data, err := info.Runtime.Options.Marshal()
if err != nil {
if errdefs.IsNotFound(err) {
return nil
}
return err
}
if err := task.Pause(ctx); err != nil {
return err
return nil, err
}
defer task.Resume(ctx)

info, err := c.Info(ctx)
r := bytes.NewReader(data)
desc, err := writeContent(ctx, c.client.ContentStore(), images.MediaTypeContainerd1CheckpointRuntimeOptions, info.ID+"-runtime-options", r)
if err != nil {
return err
return nil, err
}

// add runtime info to index
index.Annotations["runtime.name"] = info.Runtime.Name
if info.Runtime.Options != nil {
data, err := info.Runtime.Options.Marshal()
if err != nil {
return err
}
r := bytes.NewReader(data)
desc, err := writeContent(ctx, c.client.ContentStore(), images.MediaTypeContainerd1CheckpointRuntimeOptions, info.ID+"-runtime-options", r)
if err != nil {
return err
}
desc.Platform = &ocispec.Platform{
OS: runtime.GOOS,
Architecture: runtime.GOARCH,
}
index.Manifests = append(index.Manifests, desc)
desc.Platform = &ocispec.Platform{
OS: runtime.GOOS,
Architecture: runtime.GOARCH,
}
index.Manifests = append(index.Manifests, desc)
}

// process remaining opts
for _, o := range opts {
if err := o(ctx, c.client, &info, index, copts); err != nil {
return err
}
// process remaining opts
for _, o := range opts {
if err := o(ctx, c.client, &info, index, copts); err != nil {
return nil, err
}
return nil
}(ctx); err != nil {
return nil, err
}

desc, err := writeIndex(ctx, index, c.client, c.ID()+"index")
Expand Down
75 changes: 59 additions & 16 deletions container_restore_opts.go
Expand Up @@ -31,32 +31,64 @@ import (
"github.com/pkg/errors"
)

var (
// ErrCheckpointIndexImageNameNotFound is returned when the checkpoint image name is not present in the index
ErrCheckpointIndexImageNameNotFound = errors.New("image name not present in index")
// ErrCheckpointIndexRuntimeNameNotFound is returned when the checkpoint runtime name is not present in the index
ErrCheckpointIndexRuntimeNameNotFound = errors.New("runtime name not present in index")
)

// RestoreOpts are options to manage the restore operation
type RestoreOpts func(context.Context, string, *Client, Image, *imagespec.Index) ([]NewContainerOpts, error)

// WithRestoreImage restores the image for the container
func WithRestoreImage(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) ([]NewContainerOpts, error) {
store := client.ContentStore()
m, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointImageName)
if err != nil {
if err != ErrMediaTypeNotFound {
return nil, err
}
}
imageName := ""
if m != nil {
data, err := content.ReadBlob(ctx, store, *m)
if err != nil {
return nil, err
}
imageName = string(data)
}
i, err := client.GetImage(ctx, imageName)
if err != nil {
return nil, err
}

return []NewContainerOpts{
WithImage(i),
}, nil
}

// WithRestoreRuntime restores the runtime for the container
func WithRestoreRuntime(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) ([]NewContainerOpts, error) {
runtimeName, ok := index.Annotations["runtime.name"]
if !ok {
return nil, ErrCheckpointIndexRuntimeNameNotFound
store := client.ContentStore()
n, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointRuntimeName)
if err != nil {
if err != ErrMediaTypeNotFound {
return nil, err
}
}
runtimeName := ""
if n != nil {
data, err := content.ReadBlob(ctx, store, *n)
if err != nil {
return nil, err
}
runtimeName = string(data)
}

// restore options if present
m, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointRuntimeOptions)
if err != nil {
if err != ErrMediaTypeNotFound {
return nil, err
}
}

var options *ptypes.Any
if m != nil {
store := client.ContentStore()
data, err := content.ReadBlob(ctx, store, *m)
if err != nil {
return nil, errors.Wrap(err, "unable to read checkpoint runtime")
Expand Down Expand Up @@ -98,15 +130,26 @@ func WithRestoreSpec(ctx context.Context, id string, client *Client, checkpoint

// WithRestoreSnapshot restores the snapshot from the checkpoint for the container
func WithRestoreSnapshot(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) ([]NewContainerOpts, error) {
// get image from annotation
imageName, ok := index.Annotations["image.name"]
if !ok {
return nil, ErrCheckpointIndexImageNameNotFound
imageName := ""
store := client.ContentStore()
m, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointImageName)
if err != nil {
if err != ErrMediaTypeNotFound {
return nil, err
}
}
i, err := client.Pull(ctx, imageName, WithPullUnpack)
if m != nil {
data, err := content.ReadBlob(ctx, store, *m)
if err != nil {
return nil, err
}
imageName = string(data)
}
i, err := client.GetImage(ctx, imageName)
if err != nil {
return nil, err
}

diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default())
if err != nil {
return nil, err
Expand Down
2 changes: 2 additions & 0 deletions images/mediatypes.go
Expand Up @@ -34,6 +34,8 @@ const (
MediaTypeContainerd1Resource = "application/vnd.containerd.container.resource.tar"
MediaTypeContainerd1RW = "application/vnd.containerd.container.rw.tar"
MediaTypeContainerd1CheckpointConfig = "application/vnd.containerd.container.checkpoint.config.v1+proto"
MediaTypeContainerd1CheckpointImageName = "application/vnd.containerd.container.checkpoint.image.name"
MediaTypeContainerd1CheckpointRuntimeName = "application/vnd.containerd.container.checkpoint.runtime.name"
MediaTypeContainerd1CheckpointRuntimeOptions = "application/vnd.containerd.container.checkpoint.runtime.options+proto"
// Legacy Docker schema1 manifest
MediaTypeDockerSchema1Manifest = "application/vnd.docker.distribution.manifest.v1+prettyjws"
Expand Down

0 comments on commit 1472080

Please sign in to comment.