refactor spec and snapshot restore into opts
Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
This commit is contained in:
parent
45c700a955
commit
2d3db08daf
20
client.go
20
client.go
@ -49,7 +49,6 @@ import (
|
|||||||
"github.com/containerd/containerd/leases"
|
"github.com/containerd/containerd/leases"
|
||||||
leasesproxy "github.com/containerd/containerd/leases/proxy"
|
leasesproxy "github.com/containerd/containerd/leases/proxy"
|
||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
"github.com/containerd/containerd/oci"
|
|
||||||
"github.com/containerd/containerd/pkg/dialer"
|
"github.com/containerd/containerd/pkg/dialer"
|
||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
@ -544,31 +543,16 @@ func (c *Client) Restore(ctx context.Context, id, ref string, opts ...RestoreOpt
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// get image from annotation
|
|
||||||
imageName, ok := index.Annotations["image.name"]
|
|
||||||
if !ok {
|
|
||||||
return ErrCheckpointIndexImageNameNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
image, err := c.Pull(ctx, imageName, WithPullUnpack)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, done, err := c.WithLease(ctx)
|
ctx, done, err := c.WithLease(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer done(ctx)
|
defer done(ctx)
|
||||||
|
|
||||||
// container options
|
copts := []NewContainerOpts{}
|
||||||
copts := []NewContainerOpts{
|
|
||||||
WithNewSpec(oci.WithImageConfig(image)),
|
|
||||||
WithNewSnapshot(id, image),
|
|
||||||
}
|
|
||||||
topts := []NewTaskOpts{}
|
topts := []NewTaskOpts{}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
co, to, err := o(ctx, c, checkpoint, index)
|
co, to, err := o(ctx, id, c, checkpoint, index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,7 @@ var infoCommand = cli.Command{
|
|||||||
var checkpointCommand = cli.Command{
|
var checkpointCommand = cli.Command{
|
||||||
Name: "checkpoint",
|
Name: "checkpoint",
|
||||||
Usage: "checkpoint a container",
|
Usage: "checkpoint a container",
|
||||||
ArgsUsage: "CONTAINER REF [flags]",
|
ArgsUsage: "CONTAINER REF",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "rw",
|
Name: "rw",
|
||||||
@ -342,7 +342,7 @@ var checkpointCommand = cli.Command{
|
|||||||
var restoreCommand = cli.Command{
|
var restoreCommand = cli.Command{
|
||||||
Name: "restore",
|
Name: "restore",
|
||||||
Usage: "restore a container from checkpoint",
|
Usage: "restore a container from checkpoint",
|
||||||
ArgsUsage: "CONTAINER REF [flags]",
|
ArgsUsage: "CONTAINER REF",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "live",
|
Name: "live",
|
||||||
@ -358,18 +358,20 @@ var restoreCommand = cli.Command{
|
|||||||
if ref == "" {
|
if ref == "" {
|
||||||
return errors.New("ref must be provided")
|
return errors.New("ref must be provided")
|
||||||
}
|
}
|
||||||
opts := []containerd.RestoreOpts{
|
|
||||||
containerd.WithRestoreSpec,
|
|
||||||
containerd.WithRestoreRuntime,
|
|
||||||
}
|
|
||||||
if context.Bool("live") {
|
|
||||||
opts = append(opts, containerd.WithRestoreLive)
|
|
||||||
}
|
|
||||||
client, ctx, cancel, err := commands.NewClient(context)
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
opts := []containerd.RestoreOpts{
|
||||||
|
containerd.WithRestoreSpec,
|
||||||
|
containerd.WithRestoreSnapshot,
|
||||||
|
containerd.WithRestoreRuntime,
|
||||||
|
}
|
||||||
|
if context.Bool("live") {
|
||||||
|
opts = append(opts, containerd.WithRestoreLive)
|
||||||
|
}
|
||||||
if err := client.Restore(ctx, id, ref, opts...); err != nil {
|
if err := client.Restore(ctx, id, ref, opts...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -36,10 +36,6 @@ var (
|
|||||||
ErrCheckpointRWUnsupported = errors.New("rw checkpoint is only supported on v2 runtimes")
|
ErrCheckpointRWUnsupported = errors.New("rw checkpoint is only supported on v2 runtimes")
|
||||||
// ErrMediaTypeNotFound returns an error when a media type in the manifest is unknown
|
// ErrMediaTypeNotFound returns an error when a media type in the manifest is unknown
|
||||||
ErrMediaTypeNotFound = errors.New("media type not found")
|
ErrMediaTypeNotFound = errors.New("media type not found")
|
||||||
// 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")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckpointOpts are options to manage the checkpoint operation
|
// CheckpointOpts are options to manage the checkpoint operation
|
||||||
|
@ -22,25 +22,34 @@ import (
|
|||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/images"
|
"github.com/containerd/containerd/images"
|
||||||
"github.com/containerd/containerd/oci"
|
"github.com/containerd/containerd/oci"
|
||||||
|
"github.com/containerd/containerd/platforms"
|
||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
ptypes "github.com/gogo/protobuf/types"
|
ptypes "github.com/gogo/protobuf/types"
|
||||||
|
"github.com/opencontainers/image-spec/identity"
|
||||||
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
"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
|
// RestoreOpts are options to manage the restore operation
|
||||||
type RestoreOpts func(context.Context, *Client, Image, *imagespec.Index) ([]NewContainerOpts, []NewTaskOpts, error)
|
type RestoreOpts func(context.Context, string, *Client, Image, *imagespec.Index) ([]NewContainerOpts, []NewTaskOpts, error)
|
||||||
|
|
||||||
// WithRestoreLive restores the runtime and memory data for the container
|
// WithRestoreLive restores the runtime and memory data for the container
|
||||||
func WithRestoreLive(ctx context.Context, client *Client, checkpoint Image, index *imagespec.Index) ([]NewContainerOpts, []NewTaskOpts, error) {
|
func WithRestoreLive(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) ([]NewContainerOpts, []NewTaskOpts, error) {
|
||||||
return nil, []NewTaskOpts{
|
return nil, []NewTaskOpts{
|
||||||
WithTaskCheckpoint(checkpoint),
|
WithTaskCheckpoint(checkpoint),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithRestoreRuntime restores the runtime for the container
|
// WithRestoreRuntime restores the runtime for the container
|
||||||
func WithRestoreRuntime(ctx context.Context, 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, []NewTaskOpts, error) {
|
||||||
runtimeName, ok := index.Annotations["runtime.name"]
|
runtimeName, ok := index.Annotations["runtime.name"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, ErrCheckpointIndexRuntimeNameNotFound
|
return nil, nil, ErrCheckpointIndexRuntimeNameNotFound
|
||||||
@ -69,7 +78,7 @@ func WithRestoreRuntime(ctx context.Context, client *Client, checkpoint Image, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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, 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, []NewTaskOpts, 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, nil, err
|
||||||
@ -93,3 +102,28 @@ func WithRestoreSpec(ctx context.Context, client *Client, checkpoint Image, inde
|
|||||||
WithSpec(spec),
|
WithSpec(spec),
|
||||||
}, nil, nil
|
}, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithRestoreSnapshot(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) ([]NewContainerOpts, []NewTaskOpts, error) {
|
||||||
|
// get image from annotation
|
||||||
|
imageName, ok := index.Annotations["image.name"]
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, ErrCheckpointIndexImageNameNotFound
|
||||||
|
}
|
||||||
|
i, err := client.Pull(ctx, imageName, WithPullUnpack)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default())
|
||||||
|
if err != nil {
|
||||||
|
return nil, 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 []NewContainerOpts{
|
||||||
|
WithImage(i),
|
||||||
|
WithSnapshot(id),
|
||||||
|
}, nil, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user