remove task handling from Restore

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
This commit is contained in:
Evan Hazlett 2018-09-17 11:04:13 -04:00
parent 2d3db08daf
commit 0e4d9da755
3 changed files with 61 additions and 55 deletions

View File

@ -38,7 +38,6 @@ import (
snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1" snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1"
"github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/api/services/tasks/v1"
versionservice "github.com/containerd/containerd/api/services/version/v1" versionservice "github.com/containerd/containerd/api/services/version/v1"
"github.com/containerd/containerd/cio"
"github.com/containerd/containerd/containers" "github.com/containerd/containerd/containers"
"github.com/containerd/containerd/content" "github.com/containerd/containerd/content"
contentproxy "github.com/containerd/containerd/content/proxy" contentproxy "github.com/containerd/containerd/content/proxy"
@ -524,15 +523,15 @@ func (c *Client) ListImages(ctx context.Context, filters ...string) ([]Image, er
} }
// Restore restores a container from a checkpoint // Restore restores a container from a checkpoint
func (c *Client) Restore(ctx context.Context, id, ref string, opts ...RestoreOpts) error { func (c *Client) Restore(ctx context.Context, id, ref string, opts ...RestoreOpts) (Container, error) {
checkpoint, err := c.GetImage(ctx, ref) checkpoint, err := c.GetImage(ctx, ref)
if err != nil { if err != nil {
if !errdefs.IsNotFound(err) { if !errdefs.IsNotFound(err) {
return err return nil, err
} }
ck, err := c.Fetch(ctx, ref) ck, err := c.Fetch(ctx, ref)
if err != nil { if err != nil {
return err return nil, err
} }
checkpoint = NewImage(c, ck) checkpoint = NewImage(c, ck)
} }
@ -540,61 +539,50 @@ func (c *Client) Restore(ctx context.Context, id, ref string, opts ...RestoreOpt
store := c.ContentStore() store := c.ContentStore()
index, err := decodeIndex(ctx, store, checkpoint.Target()) index, err := decodeIndex(ctx, store, checkpoint.Target())
if err != nil { if err != nil {
return err return nil, err
} }
ctx, done, err := c.WithLease(ctx) ctx, done, err := c.WithLease(ctx)
if err != nil { if err != nil {
return err return nil, err
} }
defer done(ctx) defer done(ctx)
copts := []NewContainerOpts{} copts := []NewContainerOpts{}
topts := []NewTaskOpts{}
for _, o := range opts { for _, o := range opts {
co, to, err := o(ctx, id, c, checkpoint, index) co, err := o(ctx, id, c, checkpoint, index)
if err != nil { if err != nil {
return err return nil, err
} }
copts = append(copts, co...) copts = append(copts, co...)
topts = append(topts, to...)
} }
ctr, err := c.NewContainer(ctx, id, copts...) ctr, err := c.NewContainer(ctx, id, copts...)
if err != nil { if err != nil {
return err return nil, err
} }
// apply rw layer // apply rw layer
info, err := ctr.Info(ctx) info, err := ctr.Info(ctx)
if err != nil { if err != nil {
return err return nil, err
} }
rw, err := GetIndexByMediaType(index, ocispec.MediaTypeImageLayerGzip) rw, err := GetIndexByMediaType(index, ocispec.MediaTypeImageLayerGzip)
if err != nil { if err != nil {
return err return nil, err
} }
mounts, err := c.SnapshotService(info.Snapshotter).Mounts(ctx, info.SnapshotKey) mounts, err := c.SnapshotService(info.Snapshotter).Mounts(ctx, info.SnapshotKey)
if err != nil { if err != nil {
return err return nil, err
} }
if _, err := c.DiffService().Apply(ctx, *rw, mounts); err != nil { if _, err := c.DiffService().Apply(ctx, *rw, mounts); err != nil {
return err return nil, err
} }
task, err := ctr.NewTask(ctx, cio.NewCreator(cio.WithStdio), topts...) return ctr, nil
if err != nil {
return err
}
if err := task.Start(ctx); err != nil {
return err
}
return nil
} }
func writeIndex(ctx context.Context, index *ocispec.Index, client *Client, ref string) (d ocispec.Descriptor, err error) { func writeIndex(ctx context.Context, index *ocispec.Index, client *Client, ref string) (d ocispec.Descriptor, err error) {

View File

@ -29,6 +29,7 @@ import (
"github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/containerd/cmd/ctr/commands"
"github.com/containerd/containerd/cmd/ctr/commands/run" "github.com/containerd/containerd/cmd/ctr/commands/run"
"github.com/containerd/containerd/containers" "github.com/containerd/containerd/containers"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -364,15 +365,39 @@ var restoreCommand = cli.Command{
} }
defer cancel() defer cancel()
checkpoint, err := client.GetImage(ctx, ref)
if err != nil {
if !errdefs.IsNotFound(err) {
return err
}
ck, err := client.Fetch(ctx, ref)
if err != nil {
return err
}
checkpoint = containerd.NewImage(client, ck)
}
opts := []containerd.RestoreOpts{ opts := []containerd.RestoreOpts{
containerd.WithRestoreSpec, containerd.WithRestoreSpec,
containerd.WithRestoreSnapshot, containerd.WithRestoreSnapshot,
containerd.WithRestoreRuntime, containerd.WithRestoreRuntime,
} }
if context.Bool("live") {
opts = append(opts, containerd.WithRestoreLive) ctr, err := client.Restore(ctx, id, ref, opts...)
if err != nil {
return err
} }
if err := client.Restore(ctx, id, ref, opts...); err != nil {
topts := []containerd.NewTaskOpts{}
if context.Bool("live") {
topts = append(topts, containerd.WithTaskCheckpoint(checkpoint))
}
task, err := ctr.NewTask(ctx, cio.NewCreator(cio.WithStdio), topts...)
if err != nil {
return err
}
if err := task.Start(ctx); err != nil {
return err return err
} }

View File

@ -39,26 +39,19 @@ var (
) )
// RestoreOpts are options to manage the restore operation // RestoreOpts are options to manage the restore operation
type RestoreOpts func(context.Context, string, *Client, Image, *imagespec.Index) ([]NewContainerOpts, []NewTaskOpts, error) type RestoreOpts func(context.Context, string, *Client, Image, *imagespec.Index) ([]NewContainerOpts, error)
// WithRestoreLive restores the runtime and memory data for the container
func WithRestoreLive(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) ([]NewContainerOpts, []NewTaskOpts, error) {
return nil, []NewTaskOpts{
WithTaskCheckpoint(checkpoint),
}, nil
}
// WithRestoreRuntime restores the runtime for the container // WithRestoreRuntime restores the runtime for the container
func WithRestoreRuntime(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) ([]NewContainerOpts, []NewTaskOpts, error) { func WithRestoreRuntime(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) ([]NewContainerOpts, error) {
runtimeName, ok := index.Annotations["runtime.name"] runtimeName, ok := index.Annotations["runtime.name"]
if !ok { if !ok {
return nil, nil, ErrCheckpointIndexRuntimeNameNotFound return nil, ErrCheckpointIndexRuntimeNameNotFound
} }
// restore options if present // restore options if present
m, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointRuntimeOptions) m, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointRuntimeOptions)
if err != nil { if err != nil {
if err != ErrMediaTypeNotFound { if err != ErrMediaTypeNotFound {
return nil, nil, err return nil, err
} }
} }
var options *ptypes.Any var options *ptypes.Any
@ -66,64 +59,64 @@ func WithRestoreRuntime(ctx context.Context, id string, client *Client, checkpoi
store := client.ContentStore() store := client.ContentStore()
data, err := content.ReadBlob(ctx, store, *m) data, err := content.ReadBlob(ctx, store, *m)
if err != nil { if err != nil {
return nil, nil, errors.Wrap(err, "unable to read checkpoint runtime") return nil, errors.Wrap(err, "unable to read checkpoint runtime")
} }
if err := proto.Unmarshal(data, options); err != nil { if err := proto.Unmarshal(data, options); err != nil {
return nil, nil, err return nil, err
} }
} }
return []NewContainerOpts{ return []NewContainerOpts{
WithRuntime(runtimeName, options), WithRuntime(runtimeName, options),
}, nil, nil }, nil
} }
// WithRestoreSpec restores the spec from the checkpoint for the container // WithRestoreSpec restores the spec from the checkpoint for the container
func WithRestoreSpec(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) ([]NewContainerOpts, []NewTaskOpts, error) { func WithRestoreSpec(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) ([]NewContainerOpts, error) {
m, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointConfig) m, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointConfig)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
store := client.ContentStore() store := client.ContentStore()
data, err := content.ReadBlob(ctx, store, *m) data, err := content.ReadBlob(ctx, store, *m)
if err != nil { if err != nil {
return nil, nil, errors.Wrap(err, "unable to read checkpoint config") return nil, errors.Wrap(err, "unable to read checkpoint config")
} }
var any ptypes.Any var any ptypes.Any
if err := proto.Unmarshal(data, &any); err != nil { if err := proto.Unmarshal(data, &any); err != nil {
return nil, nil, err return nil, err
} }
v, err := typeurl.UnmarshalAny(&any) v, err := typeurl.UnmarshalAny(&any)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
spec := v.(*oci.Spec) spec := v.(*oci.Spec)
return []NewContainerOpts{ return []NewContainerOpts{
WithSpec(spec), WithSpec(spec),
}, nil, nil }, nil
} }
func WithRestoreSnapshot(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) ([]NewContainerOpts, []NewTaskOpts, error) { // 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 // get image from annotation
imageName, ok := index.Annotations["image.name"] imageName, ok := index.Annotations["image.name"]
if !ok { if !ok {
return nil, nil, ErrCheckpointIndexImageNameNotFound return nil, ErrCheckpointIndexImageNameNotFound
} }
i, err := client.Pull(ctx, imageName, WithPullUnpack) i, err := client.Pull(ctx, imageName, WithPullUnpack)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default()) diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default())
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
//setSnapshotterIfEmpty(client)
parent := identity.ChainID(diffIDs).String() parent := identity.ChainID(diffIDs).String()
if _, err := client.SnapshotService(DefaultSnapshotter).Prepare(ctx, id, parent); err != nil { if _, err := client.SnapshotService(DefaultSnapshotter).Prepare(ctx, id, parent); err != nil {
return nil, nil, err return nil, err
} }
return []NewContainerOpts{ return []NewContainerOpts{
WithImage(i), WithImage(i),
WithSnapshot(id), WithSnapshot(id),
}, nil, nil }, nil
} }