From 0e4d9da755809ed4a8fbd7d9782d5f89c612612b Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Mon, 17 Sep 2018 11:04:13 -0400 Subject: [PATCH] remove task handling from Restore Signed-off-by: Evan Hazlett --- client.go | 38 +++++++----------- cmd/ctr/commands/containers/containers.go | 31 +++++++++++++-- container_restore_opts.go | 47 ++++++++++------------- 3 files changed, 61 insertions(+), 55 deletions(-) diff --git a/client.go b/client.go index 0301eeb0d..01c1c2441 100644 --- a/client.go +++ b/client.go @@ -38,7 +38,6 @@ import ( snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1" "github.com/containerd/containerd/api/services/tasks/v1" versionservice "github.com/containerd/containerd/api/services/version/v1" - "github.com/containerd/containerd/cio" "github.com/containerd/containerd/containers" "github.com/containerd/containerd/content" 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 -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) if err != nil { if !errdefs.IsNotFound(err) { - return err + return nil, err } ck, err := c.Fetch(ctx, ref) if err != nil { - return err + return nil, err } checkpoint = NewImage(c, ck) } @@ -540,61 +539,50 @@ func (c *Client) Restore(ctx context.Context, id, ref string, opts ...RestoreOpt store := c.ContentStore() index, err := decodeIndex(ctx, store, checkpoint.Target()) if err != nil { - return err + return nil, err } ctx, done, err := c.WithLease(ctx) if err != nil { - return err + return nil, err } defer done(ctx) copts := []NewContainerOpts{} - topts := []NewTaskOpts{} for _, o := range opts { - co, to, err := o(ctx, id, c, checkpoint, index) + co, err := o(ctx, id, c, checkpoint, index) if err != nil { - return err + return nil, err } copts = append(copts, co...) - topts = append(topts, to...) } ctr, err := c.NewContainer(ctx, id, copts...) if err != nil { - return err + return nil, err } // apply rw layer info, err := ctr.Info(ctx) if err != nil { - return err + return nil, err } rw, err := GetIndexByMediaType(index, ocispec.MediaTypeImageLayerGzip) if err != nil { - return err + return nil, err } mounts, err := c.SnapshotService(info.Snapshotter).Mounts(ctx, info.SnapshotKey) if err != nil { - return err + return nil, err } 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...) - if err != nil { - return err - } - - if err := task.Start(ctx); err != nil { - return err - } - - return nil + return ctr, nil } func writeIndex(ctx context.Context, index *ocispec.Index, client *Client, ref string) (d ocispec.Descriptor, err error) { diff --git a/cmd/ctr/commands/containers/containers.go b/cmd/ctr/commands/containers/containers.go index 72b0beae8..44a80b63a 100644 --- a/cmd/ctr/commands/containers/containers.go +++ b/cmd/ctr/commands/containers/containers.go @@ -29,6 +29,7 @@ import ( "github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/containerd/cmd/ctr/commands/run" "github.com/containerd/containerd/containers" + "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" "github.com/containerd/typeurl" "github.com/urfave/cli" @@ -364,15 +365,39 @@ var restoreCommand = cli.Command{ } 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{ containerd.WithRestoreSpec, containerd.WithRestoreSnapshot, 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 } diff --git a/container_restore_opts.go b/container_restore_opts.go index 3b23bc57f..27c1f7ada 100644 --- a/container_restore_opts.go +++ b/container_restore_opts.go @@ -39,26 +39,19 @@ var ( ) // RestoreOpts are options to manage the restore operation -type RestoreOpts func(context.Context, string, *Client, Image, *imagespec.Index) ([]NewContainerOpts, []NewTaskOpts, 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 -} +type RestoreOpts func(context.Context, string, *Client, Image, *imagespec.Index) ([]NewContainerOpts, error) // 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"] if !ok { - return nil, nil, ErrCheckpointIndexRuntimeNameNotFound + return nil, ErrCheckpointIndexRuntimeNameNotFound } // restore options if present m, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointRuntimeOptions) if err != nil { if err != ErrMediaTypeNotFound { - return nil, nil, err + return nil, err } } var options *ptypes.Any @@ -66,64 +59,64 @@ func WithRestoreRuntime(ctx context.Context, id string, client *Client, checkpoi store := client.ContentStore() data, err := content.ReadBlob(ctx, store, *m) 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 { - return nil, nil, err + return nil, err } } return []NewContainerOpts{ WithRuntime(runtimeName, options), - }, nil, nil + }, nil } // 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) if err != nil { - return nil, nil, err + return nil, err } store := client.ContentStore() data, err := content.ReadBlob(ctx, store, *m) 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 if err := proto.Unmarshal(data, &any); err != nil { - return nil, nil, err + return nil, err } v, err := typeurl.UnmarshalAny(&any) if err != nil { - return nil, nil, err + return nil, err } spec := v.(*oci.Spec) return []NewContainerOpts{ 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 imageName, ok := index.Annotations["image.name"] if !ok { - return nil, nil, ErrCheckpointIndexImageNameNotFound + return nil, ErrCheckpointIndexImageNameNotFound } i, err := client.Pull(ctx, imageName, WithPullUnpack) if err != nil { - return nil, nil, err + return nil, err } diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default()) if err != nil { - return nil, nil, err + return nil, err } - //setSnapshotterIfEmpty(client) parent := identity.ChainID(diffIDs).String() if _, err := client.SnapshotService(DefaultSnapshotter).Prepare(ctx, id, parent); err != nil { - return nil, nil, err + return nil, err } return []NewContainerOpts{ WithImage(i), WithSnapshot(id), - }, nil, nil + }, nil }