Merge pull request #2830 from Ace-Tang/support_cr_without_image
cr: support checkpoint/restore without image
This commit is contained in:
commit
06e04bc5a9
@ -36,6 +36,14 @@ var checkpointCommand = cli.Command{
|
|||||||
Name: "exit",
|
Name: "exit",
|
||||||
Usage: "stop the container after the checkpoint",
|
Usage: "stop the container after the checkpoint",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "image-path",
|
||||||
|
Usage: "path to criu image files",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "work-path",
|
||||||
|
Usage: "path to criu work files and logs",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
id := context.Args().First()
|
id := context.Args().First()
|
||||||
@ -59,40 +67,55 @@ var checkpointCommand = cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var opts []containerd.CheckpointTaskOpts
|
opts := []containerd.CheckpointTaskOpts{withCheckpointOpts(info.Runtime.Name, context)}
|
||||||
if context.Bool("exit") {
|
|
||||||
opts = append(opts, withExit(info.Runtime.Name))
|
|
||||||
}
|
|
||||||
checkpoint, err := task.Checkpoint(ctx, opts...)
|
checkpoint, err := task.Checkpoint(ctx, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Println(checkpoint.Name())
|
if context.String("image-path") == "" {
|
||||||
|
fmt.Println(checkpoint.Name())
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func withExit(rt string) containerd.CheckpointTaskOpts {
|
// withCheckpointOpts only suitable for runc runtime now
|
||||||
|
func withCheckpointOpts(rt string, context *cli.Context) containerd.CheckpointTaskOpts {
|
||||||
return func(r *containerd.CheckpointTaskInfo) error {
|
return func(r *containerd.CheckpointTaskInfo) error {
|
||||||
|
imagePath := context.String("image-path")
|
||||||
|
workPath := context.String("work-path")
|
||||||
|
|
||||||
switch rt {
|
switch rt {
|
||||||
case "io.containerd.runc.v1":
|
case "io.containerd.runc.v1":
|
||||||
if r.Options == nil {
|
if r.Options == nil {
|
||||||
r.Options = &options.CheckpointOptions{
|
r.Options = &options.CheckpointOptions{}
|
||||||
Exit: true,
|
}
|
||||||
}
|
opts, _ := r.Options.(*options.CheckpointOptions)
|
||||||
} else {
|
|
||||||
opts, _ := r.Options.(*options.CheckpointOptions)
|
if context.Bool("exit") {
|
||||||
opts.Exit = true
|
opts.Exit = true
|
||||||
}
|
}
|
||||||
default:
|
if imagePath != "" {
|
||||||
|
opts.ImagePath = imagePath
|
||||||
|
}
|
||||||
|
if workPath != "" {
|
||||||
|
opts.WorkPath = workPath
|
||||||
|
}
|
||||||
|
case "io.containerd.runtime.v1.linux":
|
||||||
if r.Options == nil {
|
if r.Options == nil {
|
||||||
r.Options = &runctypes.CheckpointOptions{
|
r.Options = &runctypes.CheckpointOptions{}
|
||||||
Exit: true,
|
}
|
||||||
}
|
opts, _ := r.Options.(*runctypes.CheckpointOptions)
|
||||||
} else {
|
|
||||||
opts, _ := r.Options.(*runctypes.CheckpointOptions)
|
if context.Bool("exit") {
|
||||||
opts.Exit = true
|
opts.Exit = true
|
||||||
}
|
}
|
||||||
|
if imagePath != "" {
|
||||||
|
opts.ImagePath = imagePath
|
||||||
|
}
|
||||||
|
if workPath != "" {
|
||||||
|
opts.WorkPath = workPath
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -22,16 +22,19 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/cio"
|
||||||
"github.com/containerd/containerd/oci"
|
"github.com/containerd/containerd/oci"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
v1runtime = "io.containerd.runtime.v1.linux"
|
|
||||||
testCheckpointName = "checkpoint-test:latest"
|
testCheckpointName = "checkpoint-test:latest"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -408,3 +411,123 @@ func TestCheckpointLeaveRunning(t *testing.T) {
|
|||||||
|
|
||||||
<-statusC
|
<-statusC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCRWithImagePath(t *testing.T) {
|
||||||
|
if !supportsCriu {
|
||||||
|
t.Skip("system does not have criu installed")
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := newClient(t, address)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
var (
|
||||||
|
ctx, cancel = testContext()
|
||||||
|
id = t.Name() + "-checkpoint"
|
||||||
|
)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
image, err := client.GetImage(ctx, testImage)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), oci.WithProcessArgs("top")))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer container.Delete(ctx, WithSnapshotCleanup)
|
||||||
|
|
||||||
|
task, err := container.NewTask(ctx, empty())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
statusC, err := task.Wait(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := task.Start(ctx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create image path store criu image files
|
||||||
|
crDir, err := ioutil.TempDir("", "test-cr")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(crDir)
|
||||||
|
imagePath := filepath.Join(crDir, "cr")
|
||||||
|
// checkpoint task
|
||||||
|
if _, err := task.Checkpoint(ctx, WithCheckpointImagePath(client.runtime, imagePath)); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := task.Kill(ctx, syscall.SIGKILL); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
<-statusC
|
||||||
|
task.Delete(ctx)
|
||||||
|
|
||||||
|
// check image files have been dumped into image path
|
||||||
|
if files, err := ioutil.ReadDir(imagePath); err != nil || len(files) == 0 {
|
||||||
|
t.Fatal("failed to checkpoint with image path set")
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore task with same container image and checkpoint directory,
|
||||||
|
// the restore process should finish in millisecond level
|
||||||
|
id = t.Name() + "-restore"
|
||||||
|
ncontainer, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image)))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer ncontainer.Delete(ctx, WithSnapshotCleanup)
|
||||||
|
|
||||||
|
ntask, err := ncontainer.NewTask(ctx, empty(), WithRestoreImagePath(client.runtime, imagePath))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
statusC, err = ntask.Wait(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := ntask.Start(ctx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check top process is existed in restored container
|
||||||
|
spec, err := container.Spec(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout := bytes.NewBuffer(nil)
|
||||||
|
spec.Process.Args = []string{"ps", "-ef"}
|
||||||
|
process, err := ntask.Exec(ctx, t.Name()+"_exec", spec.Process, cio.NewCreator(withByteBuffers(stdout)))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
processStatusC, err := process.Wait(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := process.Start(ctx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
<-processStatusC
|
||||||
|
if _, err := process.Delete(ctx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(stdout.String(), "top") {
|
||||||
|
t.Errorf("except top process exists in restored container but not, got output %s", stdout.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// we wrote the same thing after attach
|
||||||
|
if err := ntask.Kill(ctx, syscall.SIGKILL); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
<-statusC
|
||||||
|
ntask.Delete(ctx)
|
||||||
|
}
|
||||||
|
@ -112,6 +112,20 @@ file {
|
|||||||
type: TYPE_UINT32
|
type: TYPE_UINT32
|
||||||
json_name: "ioGid"
|
json_name: "ioGid"
|
||||||
}
|
}
|
||||||
|
field {
|
||||||
|
name: "criu_work_path"
|
||||||
|
number: 12
|
||||||
|
label: LABEL_OPTIONAL
|
||||||
|
type: TYPE_STRING
|
||||||
|
json_name: "criuWorkPath"
|
||||||
|
}
|
||||||
|
field {
|
||||||
|
name: "criu_image_path"
|
||||||
|
number: 13
|
||||||
|
label: LABEL_OPTIONAL
|
||||||
|
type: TYPE_STRING
|
||||||
|
json_name: "criuImagePath"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
message_type {
|
message_type {
|
||||||
name: "CheckpointOptions"
|
name: "CheckpointOptions"
|
||||||
@ -164,6 +178,20 @@ file {
|
|||||||
type: TYPE_STRING
|
type: TYPE_STRING
|
||||||
json_name: "cgroupsMode"
|
json_name: "cgroupsMode"
|
||||||
}
|
}
|
||||||
|
field {
|
||||||
|
name: "work_path"
|
||||||
|
number: 8
|
||||||
|
label: LABEL_OPTIONAL
|
||||||
|
type: TYPE_STRING
|
||||||
|
json_name: "workPath"
|
||||||
|
}
|
||||||
|
field {
|
||||||
|
name: "image_path"
|
||||||
|
number: 9
|
||||||
|
label: LABEL_OPTIONAL
|
||||||
|
type: TYPE_STRING
|
||||||
|
json_name: "imagePath"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
message_type {
|
message_type {
|
||||||
name: "ProcessDetails"
|
name: "ProcessDetails"
|
||||||
|
@ -60,6 +60,8 @@ type CreateOptions struct {
|
|||||||
ShimCgroup string `protobuf:"bytes,9,opt,name=shim_cgroup,json=shimCgroup,proto3" json:"shim_cgroup,omitempty"`
|
ShimCgroup string `protobuf:"bytes,9,opt,name=shim_cgroup,json=shimCgroup,proto3" json:"shim_cgroup,omitempty"`
|
||||||
IoUid uint32 `protobuf:"varint,10,opt,name=io_uid,json=ioUid,proto3" json:"io_uid,omitempty"`
|
IoUid uint32 `protobuf:"varint,10,opt,name=io_uid,json=ioUid,proto3" json:"io_uid,omitempty"`
|
||||||
IoGid uint32 `protobuf:"varint,11,opt,name=io_gid,json=ioGid,proto3" json:"io_gid,omitempty"`
|
IoGid uint32 `protobuf:"varint,11,opt,name=io_gid,json=ioGid,proto3" json:"io_gid,omitempty"`
|
||||||
|
CriuWorkPath string `protobuf:"bytes,12,opt,name=criu_work_path,json=criuWorkPath,proto3" json:"criu_work_path,omitempty"`
|
||||||
|
CriuImagePath string `protobuf:"bytes,13,opt,name=criu_image_path,json=criuImagePath,proto3" json:"criu_image_path,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CreateOptions) Reset() { *m = CreateOptions{} }
|
func (m *CreateOptions) Reset() { *m = CreateOptions{} }
|
||||||
@ -74,6 +76,8 @@ type CheckpointOptions struct {
|
|||||||
FileLocks bool `protobuf:"varint,5,opt,name=file_locks,json=fileLocks,proto3" json:"file_locks,omitempty"`
|
FileLocks bool `protobuf:"varint,5,opt,name=file_locks,json=fileLocks,proto3" json:"file_locks,omitempty"`
|
||||||
EmptyNamespaces []string `protobuf:"bytes,6,rep,name=empty_namespaces,json=emptyNamespaces" json:"empty_namespaces,omitempty"`
|
EmptyNamespaces []string `protobuf:"bytes,6,rep,name=empty_namespaces,json=emptyNamespaces" json:"empty_namespaces,omitempty"`
|
||||||
CgroupsMode string `protobuf:"bytes,7,opt,name=cgroups_mode,json=cgroupsMode,proto3" json:"cgroups_mode,omitempty"`
|
CgroupsMode string `protobuf:"bytes,7,opt,name=cgroups_mode,json=cgroupsMode,proto3" json:"cgroups_mode,omitempty"`
|
||||||
|
WorkPath string `protobuf:"bytes,8,opt,name=work_path,json=workPath,proto3" json:"work_path,omitempty"`
|
||||||
|
ImagePath string `protobuf:"bytes,9,opt,name=image_path,json=imagePath,proto3" json:"image_path,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CheckpointOptions) Reset() { *m = CheckpointOptions{} }
|
func (m *CheckpointOptions) Reset() { *m = CheckpointOptions{} }
|
||||||
@ -252,6 +256,18 @@ func (m *CreateOptions) MarshalTo(dAtA []byte) (int, error) {
|
|||||||
i++
|
i++
|
||||||
i = encodeVarintRunc(dAtA, i, uint64(m.IoGid))
|
i = encodeVarintRunc(dAtA, i, uint64(m.IoGid))
|
||||||
}
|
}
|
||||||
|
if len(m.CriuWorkPath) > 0 {
|
||||||
|
dAtA[i] = 0x62
|
||||||
|
i++
|
||||||
|
i = encodeVarintRunc(dAtA, i, uint64(len(m.CriuWorkPath)))
|
||||||
|
i += copy(dAtA[i:], m.CriuWorkPath)
|
||||||
|
}
|
||||||
|
if len(m.CriuImagePath) > 0 {
|
||||||
|
dAtA[i] = 0x6a
|
||||||
|
i++
|
||||||
|
i = encodeVarintRunc(dAtA, i, uint64(len(m.CriuImagePath)))
|
||||||
|
i += copy(dAtA[i:], m.CriuImagePath)
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,6 +357,18 @@ func (m *CheckpointOptions) MarshalTo(dAtA []byte) (int, error) {
|
|||||||
i = encodeVarintRunc(dAtA, i, uint64(len(m.CgroupsMode)))
|
i = encodeVarintRunc(dAtA, i, uint64(len(m.CgroupsMode)))
|
||||||
i += copy(dAtA[i:], m.CgroupsMode)
|
i += copy(dAtA[i:], m.CgroupsMode)
|
||||||
}
|
}
|
||||||
|
if len(m.WorkPath) > 0 {
|
||||||
|
dAtA[i] = 0x42
|
||||||
|
i++
|
||||||
|
i = encodeVarintRunc(dAtA, i, uint64(len(m.WorkPath)))
|
||||||
|
i += copy(dAtA[i:], m.WorkPath)
|
||||||
|
}
|
||||||
|
if len(m.ImagePath) > 0 {
|
||||||
|
dAtA[i] = 0x4a
|
||||||
|
i++
|
||||||
|
i = encodeVarintRunc(dAtA, i, uint64(len(m.ImagePath)))
|
||||||
|
i += copy(dAtA[i:], m.ImagePath)
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,6 +467,14 @@ func (m *CreateOptions) Size() (n int) {
|
|||||||
if m.IoGid != 0 {
|
if m.IoGid != 0 {
|
||||||
n += 1 + sovRunc(uint64(m.IoGid))
|
n += 1 + sovRunc(uint64(m.IoGid))
|
||||||
}
|
}
|
||||||
|
l = len(m.CriuWorkPath)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovRunc(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.CriuImagePath)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovRunc(uint64(l))
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,6 +506,14 @@ func (m *CheckpointOptions) Size() (n int) {
|
|||||||
if l > 0 {
|
if l > 0 {
|
||||||
n += 1 + l + sovRunc(uint64(l))
|
n += 1 + l + sovRunc(uint64(l))
|
||||||
}
|
}
|
||||||
|
l = len(m.WorkPath)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovRunc(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.ImagePath)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovRunc(uint64(l))
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -525,6 +569,8 @@ func (this *CreateOptions) String() string {
|
|||||||
`ShimCgroup:` + fmt.Sprintf("%v", this.ShimCgroup) + `,`,
|
`ShimCgroup:` + fmt.Sprintf("%v", this.ShimCgroup) + `,`,
|
||||||
`IoUid:` + fmt.Sprintf("%v", this.IoUid) + `,`,
|
`IoUid:` + fmt.Sprintf("%v", this.IoUid) + `,`,
|
||||||
`IoGid:` + fmt.Sprintf("%v", this.IoGid) + `,`,
|
`IoGid:` + fmt.Sprintf("%v", this.IoGid) + `,`,
|
||||||
|
`CriuWorkPath:` + fmt.Sprintf("%v", this.CriuWorkPath) + `,`,
|
||||||
|
`CriuImagePath:` + fmt.Sprintf("%v", this.CriuImagePath) + `,`,
|
||||||
`}`,
|
`}`,
|
||||||
}, "")
|
}, "")
|
||||||
return s
|
return s
|
||||||
@ -541,6 +587,8 @@ func (this *CheckpointOptions) String() string {
|
|||||||
`FileLocks:` + fmt.Sprintf("%v", this.FileLocks) + `,`,
|
`FileLocks:` + fmt.Sprintf("%v", this.FileLocks) + `,`,
|
||||||
`EmptyNamespaces:` + fmt.Sprintf("%v", this.EmptyNamespaces) + `,`,
|
`EmptyNamespaces:` + fmt.Sprintf("%v", this.EmptyNamespaces) + `,`,
|
||||||
`CgroupsMode:` + fmt.Sprintf("%v", this.CgroupsMode) + `,`,
|
`CgroupsMode:` + fmt.Sprintf("%v", this.CgroupsMode) + `,`,
|
||||||
|
`WorkPath:` + fmt.Sprintf("%v", this.WorkPath) + `,`,
|
||||||
|
`ImagePath:` + fmt.Sprintf("%v", this.ImagePath) + `,`,
|
||||||
`}`,
|
`}`,
|
||||||
}, "")
|
}, "")
|
||||||
return s
|
return s
|
||||||
@ -994,6 +1042,64 @@ func (m *CreateOptions) Unmarshal(dAtA []byte) error {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case 12:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field CriuWorkPath", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowRunc
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthRunc
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.CriuWorkPath = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 13:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field CriuImagePath", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowRunc
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthRunc
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.CriuImagePath = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipRunc(dAtA[iNdEx:])
|
skippy, err := skipRunc(dAtA[iNdEx:])
|
||||||
@ -1202,6 +1308,64 @@ func (m *CheckpointOptions) Unmarshal(dAtA []byte) error {
|
|||||||
}
|
}
|
||||||
m.CgroupsMode = string(dAtA[iNdEx:postIndex])
|
m.CgroupsMode = string(dAtA[iNdEx:postIndex])
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
case 8:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field WorkPath", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowRunc
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthRunc
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.WorkPath = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 9:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field ImagePath", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowRunc
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthRunc
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.ImagePath = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipRunc(dAtA[iNdEx:])
|
skippy, err := skipRunc(dAtA[iNdEx:])
|
||||||
@ -1412,39 +1576,43 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptorRunc = []byte{
|
var fileDescriptorRunc = []byte{
|
||||||
// 541 bytes of a gzipped FileDescriptorProto
|
// 604 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x93, 0xc1, 0x6e, 0xd3, 0x40,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x94, 0xcf, 0x6e, 0xd3, 0x40,
|
||||||
0x10, 0x86, 0x6b, 0xda, 0x26, 0xce, 0xa4, 0x29, 0xb0, 0x50, 0xc9, 0x14, 0x91, 0x86, 0x00, 0x52,
|
0x10, 0xc6, 0xeb, 0xfe, 0x49, 0x9c, 0x49, 0xd2, 0xc2, 0x42, 0x25, 0xd3, 0xaa, 0x69, 0x08, 0x7f,
|
||||||
0xb8, 0xa4, 0x12, 0x88, 0x13, 0xb7, 0xa6, 0x08, 0x55, 0x40, 0xa9, 0x0c, 0x95, 0x10, 0x42, 0x5a,
|
0x14, 0x2e, 0xa9, 0x04, 0xe2, 0xc4, 0xad, 0x29, 0x42, 0x15, 0x50, 0x2a, 0x43, 0x05, 0x42, 0x48,
|
||||||
0xb9, 0xeb, 0x21, 0x59, 0xc5, 0xde, 0x59, 0x79, 0xd7, 0xd4, 0xb9, 0xf5, 0x09, 0x78, 0xae, 0x1e,
|
0x2b, 0x77, 0x3d, 0x24, 0xab, 0xc4, 0x3b, 0x96, 0x77, 0x4d, 0x92, 0x1b, 0x4f, 0xc0, 0x0b, 0xf1,
|
||||||
0x39, 0x72, 0x42, 0x34, 0x2f, 0x02, 0xf2, 0xda, 0x0e, 0x9c, 0x39, 0x72, 0xfb, 0xe7, 0xfb, 0xc7,
|
0x02, 0x3d, 0x21, 0x8e, 0x9c, 0x10, 0xcd, 0x93, 0xa0, 0x5d, 0xc7, 0x69, 0xcf, 0x1c, 0xb9, 0xcd,
|
||||||
0x9e, 0xd1, 0xbf, 0x1a, 0x98, 0x4c, 0xa5, 0x9d, 0xe5, 0x67, 0x63, 0x41, 0xe9, 0xbe, 0x20, 0x65,
|
0xfc, 0xe6, 0xb3, 0x67, 0xf4, 0x7d, 0xb2, 0xa1, 0x3f, 0x90, 0x66, 0x98, 0x9f, 0xf7, 0x04, 0x25,
|
||||||
0x23, 0xa9, 0x30, 0x8b, 0xff, 0x96, 0x59, 0xae, 0xac, 0x4c, 0x71, 0x3f, 0x91, 0x2a, 0x2f, 0xca,
|
0x07, 0x82, 0x94, 0x89, 0xa4, 0xc2, 0x2c, 0xbe, 0x5e, 0x66, 0xb9, 0x32, 0x32, 0xc1, 0x83, 0xb1,
|
||||||
0x4a, 0xd8, 0x85, 0x46, 0xe3, 0xd4, 0x58, 0x67, 0x64, 0x89, 0xed, 0xfc, 0x69, 0x1f, 0xbb, 0xb6,
|
0x54, 0xf9, 0xd4, 0x76, 0xc2, 0xcc, 0x52, 0xd4, 0xae, 0xea, 0xa5, 0x19, 0x19, 0x62, 0xdb, 0x57,
|
||||||
0x71, 0x69, 0xee, 0xde, 0x9e, 0xd2, 0x94, 0x5c, 0xc7, 0x7e, 0xa9, 0xaa, 0xe6, 0xe1, 0x57, 0x0f,
|
0xf2, 0x9e, 0x93, 0xf5, 0xec, 0x70, 0xe7, 0xf6, 0x80, 0x06, 0xe4, 0x14, 0x07, 0xb6, 0x2a, 0xc4,
|
||||||
0xba, 0x61, 0xae, 0xc4, 0x5b, 0x6d, 0x25, 0x29, 0xc3, 0x02, 0x68, 0xd7, 0x23, 0x02, 0x6f, 0xe0,
|
0x9d, 0x6f, 0x1e, 0xd4, 0xc3, 0x5c, 0x89, 0x37, 0xa9, 0x91, 0xa4, 0x34, 0x0b, 0xa0, 0xba, 0x58,
|
||||||
0x8d, 0x3a, 0x61, 0x53, 0xb2, 0xfb, 0xb0, 0x55, 0x4b, 0x9e, 0x11, 0xd9, 0xe0, 0x9a, 0xb3, 0xbb,
|
0x11, 0x78, 0x6d, 0xaf, 0x5b, 0x0b, 0xcb, 0x96, 0xdd, 0x85, 0xc6, 0xa2, 0xe4, 0x19, 0x91, 0x09,
|
||||||
0x35, 0x0b, 0x89, 0x2c, 0xbb, 0x0b, 0x1d, 0x91, 0xc9, 0x9c, 0xeb, 0xc8, 0xce, 0x82, 0x75, 0xe7,
|
0x56, 0xdd, 0xb8, 0xbe, 0x60, 0x21, 0x91, 0x61, 0xbb, 0x50, 0x13, 0x99, 0xcc, 0x79, 0x1a, 0x99,
|
||||||
0xfb, 0x25, 0x38, 0x89, 0xec, 0x8c, 0x3d, 0x82, 0x6d, 0xb3, 0x30, 0x16, 0xd3, 0x98, 0x8b, 0x69,
|
0x61, 0xb0, 0xe6, 0xe6, 0xbe, 0x05, 0xa7, 0x91, 0x19, 0xb2, 0x07, 0xb0, 0xa9, 0x67, 0xda, 0x60,
|
||||||
0x46, 0xb9, 0x0e, 0x36, 0x06, 0xde, 0xc8, 0x0f, 0x7b, 0x35, 0x9d, 0x38, 0x38, 0xbc, 0x58, 0x87,
|
0x12, 0x73, 0x31, 0xc8, 0x28, 0x4f, 0x83, 0xf5, 0xb6, 0xd7, 0xf5, 0xc3, 0xe6, 0x82, 0xf6, 0x1d,
|
||||||
0xde, 0x24, 0xc3, 0xc8, 0x62, 0xb3, 0xd2, 0x10, 0x7a, 0x8a, 0xb8, 0x96, 0x5f, 0xc8, 0x56, 0x93,
|
0xec, 0xfc, 0x58, 0x83, 0x66, 0x3f, 0xc3, 0xc8, 0x60, 0x79, 0x52, 0x07, 0x9a, 0x8a, 0x78, 0x2a,
|
||||||
0x3d, 0xf7, 0x5d, 0x57, 0xd1, 0x49, 0xc9, 0xdc, 0xe4, 0x3b, 0xe0, 0x93, 0x46, 0xc5, 0xad, 0xd0,
|
0xbf, 0x90, 0x29, 0x36, 0x7b, 0xee, 0xb9, 0xba, 0xa2, 0x53, 0xcb, 0xdc, 0xe6, 0x3b, 0xe0, 0x53,
|
||||||
0x6e, 0x31, 0x3f, 0x6c, 0x97, 0xf5, 0x7b, 0xa1, 0xd9, 0x13, 0xd8, 0xc1, 0xc2, 0x62, 0xa6, 0xa2,
|
0x8a, 0x8a, 0x1b, 0x91, 0xba, 0xc3, 0xfc, 0xb0, 0x6a, 0xfb, 0x77, 0x22, 0x65, 0x8f, 0x61, 0x1b,
|
||||||
0x84, 0xe7, 0x4a, 0x16, 0xdc, 0x90, 0x98, 0xa3, 0x35, 0x6e, 0x41, 0x3f, 0xbc, 0xd5, 0x98, 0xa7,
|
0xa7, 0x06, 0x33, 0x15, 0x8d, 0x79, 0xae, 0xe4, 0x94, 0x6b, 0x12, 0x23, 0x34, 0xda, 0x1d, 0xe8,
|
||||||
0x4a, 0x16, 0xef, 0x2a, 0x8b, 0xed, 0x82, 0x6f, 0x31, 0x4b, 0xa5, 0x8a, 0x92, 0x7a, 0xcb, 0x55,
|
0x87, 0xb7, 0xca, 0xe1, 0x99, 0x92, 0xd3, 0xb7, 0xc5, 0x88, 0xed, 0x80, 0x6f, 0x30, 0x4b, 0xa4,
|
||||||
0xcd, 0xee, 0x01, 0x7c, 0x96, 0x09, 0xf2, 0x84, 0xc4, 0xdc, 0x04, 0x9b, 0xce, 0xed, 0x94, 0xe4,
|
0x8a, 0xc6, 0x8b, 0x2b, 0x97, 0x3d, 0xdb, 0x03, 0xf8, 0x2c, 0xc7, 0xc8, 0xc7, 0x24, 0x46, 0x3a,
|
||||||
0x75, 0x09, 0xd8, 0x63, 0xb8, 0x81, 0xa9, 0xb6, 0x0b, 0xae, 0xa2, 0x14, 0x8d, 0x8e, 0x04, 0x9a,
|
0xd8, 0x70, 0xd3, 0x9a, 0x25, 0xaf, 0x2c, 0x60, 0x8f, 0xe0, 0x06, 0x26, 0xa9, 0x99, 0x71, 0x15,
|
||||||
0xa0, 0x35, 0x58, 0x1f, 0x75, 0xc2, 0xeb, 0x8e, 0x1f, 0xaf, 0x70, 0x99, 0x68, 0x95, 0x84, 0xe1,
|
0x25, 0xa8, 0xd3, 0x48, 0xa0, 0x0e, 0x2a, 0xed, 0xb5, 0x6e, 0x2d, 0xdc, 0x72, 0xfc, 0x64, 0x89,
|
||||||
0x29, 0xc5, 0x18, 0xb4, 0xab, 0x44, 0x6b, 0xf6, 0x86, 0x62, 0x64, 0x0f, 0x61, 0x5b, 0x11, 0x57,
|
0xad, 0xa3, 0x85, 0x13, 0x9a, 0x27, 0x14, 0x63, 0x50, 0x2d, 0x1c, 0x5d, 0xb0, 0xd7, 0x14, 0x23,
|
||||||
0x78, 0xce, 0xe7, 0xb8, 0xc8, 0xa4, 0x9a, 0x06, 0xbe, 0x1b, 0xb8, 0xa5, 0xe8, 0x18, 0xcf, 0x5f,
|
0xbb, 0x0f, 0x9b, 0x8a, 0xb8, 0xc2, 0x09, 0x1f, 0xe1, 0x2c, 0x93, 0x6a, 0x10, 0xf8, 0x6e, 0x61,
|
||||||
0x55, 0x8c, 0xed, 0x41, 0xd7, 0xcc, 0x64, 0xda, 0xe4, 0xda, 0x71, 0xff, 0x81, 0x12, 0x55, 0xa1,
|
0x43, 0xd1, 0x09, 0x4e, 0x5e, 0x16, 0x8c, 0xed, 0x43, 0x5d, 0x0f, 0x65, 0x52, 0xfa, 0x5a, 0x73,
|
||||||
0xb2, 0x1d, 0x68, 0x49, 0xe2, 0xb9, 0x8c, 0x03, 0x18, 0x78, 0xa3, 0x5e, 0xb8, 0x29, 0xe9, 0x54,
|
0xef, 0x01, 0x8b, 0x0a, 0x53, 0xd9, 0x36, 0x54, 0x24, 0xf1, 0x5c, 0xc6, 0x01, 0xb4, 0xbd, 0x6e,
|
||||||
0xc6, 0x35, 0x9e, 0xca, 0x38, 0xe8, 0x36, 0xf8, 0xa5, 0x8c, 0x87, 0xbf, 0x3c, 0xb8, 0x39, 0x99,
|
0x33, 0xdc, 0x90, 0x74, 0x26, 0xe3, 0x05, 0x1e, 0xc8, 0x38, 0xa8, 0x97, 0xf8, 0x85, 0x8c, 0xed,
|
||||||
0xa1, 0x98, 0x6b, 0x92, 0xca, 0x36, 0xcf, 0xc0, 0x60, 0x03, 0x0b, 0xd9, 0xa4, 0xef, 0xf4, 0xff,
|
0x52, 0x17, 0xe3, 0x84, 0xb2, 0x51, 0x91, 0x65, 0xc3, 0xbd, 0xb1, 0x61, 0xe9, 0x7b, 0xca, 0x46,
|
||||||
0x1a, 0xfb, 0xf0, 0x19, 0x6c, 0x9f, 0x64, 0x24, 0xd0, 0x98, 0x43, 0xb4, 0x91, 0x4c, 0x0c, 0x7b,
|
0x2e, 0xcf, 0x87, 0xb0, 0xe5, 0x54, 0x32, 0x89, 0x06, 0x58, 0xc8, 0x9a, 0x4e, 0xd6, 0xb4, 0xf8,
|
||||||
0x00, 0x6d, 0x2c, 0x50, 0x70, 0x19, 0x57, 0x77, 0x71, 0x00, 0xcb, 0x1f, 0x7b, 0xad, 0x17, 0x05,
|
0xd8, 0x52, 0xab, 0xeb, 0x7c, 0x5f, 0x85, 0x9b, 0xfd, 0x21, 0x8a, 0x51, 0x4a, 0x52, 0x99, 0x32,
|
||||||
0x8a, 0xa3, 0xc3, 0xb0, 0x55, 0x5a, 0x47, 0xf1, 0xc1, 0xa7, 0xcb, 0xab, 0xfe, 0xda, 0xf7, 0xab,
|
0x54, 0x06, 0xeb, 0x38, 0x95, 0x65, 0x96, 0xae, 0xfe, 0x6f, 0x43, 0xdc, 0x85, 0xda, 0x95, 0x95,
|
||||||
0xfe, 0xda, 0xc5, 0xb2, 0xef, 0x5d, 0x2e, 0xfb, 0xde, 0xb7, 0x65, 0xdf, 0xfb, 0xb9, 0xec, 0x7b,
|
0x7e, 0xf1, 0x59, 0x4c, 0x4a, 0x1b, 0xf7, 0x00, 0xae, 0x39, 0x58, 0x44, 0x57, 0x93, 0x4b, 0xf7,
|
||||||
0x1f, 0x0f, 0xfe, 0xf5, 0xb0, 0x9f, 0xaf, 0xd4, 0x87, 0xb5, 0xb3, 0x96, 0xbb, 0xd9, 0xa7, 0xbf,
|
0x9e, 0xc2, 0xe6, 0x69, 0x46, 0x02, 0xb5, 0x3e, 0x42, 0x13, 0xc9, 0xb1, 0x66, 0xf7, 0xa0, 0x8a,
|
||||||
0x03, 0x00, 0x00, 0xff, 0xff, 0x18, 0xa1, 0x4b, 0x5b, 0x27, 0x04, 0x00, 0x00,
|
0x53, 0x14, 0x5c, 0xc6, 0xc5, 0x17, 0x7a, 0x08, 0xf3, 0xdf, 0xfb, 0x95, 0xe7, 0x53, 0x14, 0xc7,
|
||||||
|
0x47, 0x61, 0xc5, 0x8e, 0x8e, 0xe3, 0xc3, 0x4f, 0x17, 0x97, 0xad, 0x95, 0x5f, 0x97, 0xad, 0x95,
|
||||||
|
0xaf, 0xf3, 0x96, 0x77, 0x31, 0x6f, 0x79, 0x3f, 0xe7, 0x2d, 0xef, 0xcf, 0xbc, 0xe5, 0x7d, 0x3c,
|
||||||
|
0xfc, 0xd7, 0x5f, 0xcc, 0xb3, 0x65, 0xf5, 0x61, 0xe5, 0xbc, 0xe2, 0xfe, 0x1e, 0x4f, 0xfe, 0x06,
|
||||||
|
0x00, 0x00, 0xff, 0xff, 0x7f, 0x24, 0x6f, 0x2e, 0xb1, 0x04, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@ message CreateOptions {
|
|||||||
string shim_cgroup = 9;
|
string shim_cgroup = 9;
|
||||||
uint32 io_uid = 10;
|
uint32 io_uid = 10;
|
||||||
uint32 io_gid = 11;
|
uint32 io_gid = 11;
|
||||||
|
string criu_work_path = 12;
|
||||||
|
string criu_image_path = 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CheckpointOptions {
|
message CheckpointOptions {
|
||||||
@ -35,6 +37,8 @@ message CheckpointOptions {
|
|||||||
bool file_locks = 5;
|
bool file_locks = 5;
|
||||||
repeated string empty_namespaces = 6;
|
repeated string empty_namespaces = 6;
|
||||||
string cgroups_mode = 7;
|
string cgroups_mode = 7;
|
||||||
|
string work_path = 8;
|
||||||
|
string image_path = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ProcessDetails {
|
message ProcessDetails {
|
||||||
|
@ -76,6 +76,7 @@ type Init struct {
|
|||||||
IoGID int
|
IoGID int
|
||||||
NoPivotRoot bool
|
NoPivotRoot bool
|
||||||
NoNewKeyring bool
|
NoNewKeyring bool
|
||||||
|
CriuWorkPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRunc returns a new runc instance for a process
|
// NewRunc returns a new runc instance for a process
|
||||||
@ -132,7 +133,7 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
|
|||||||
opts := &runc.RestoreOpts{
|
opts := &runc.RestoreOpts{
|
||||||
CheckpointOpts: runc.CheckpointOpts{
|
CheckpointOpts: runc.CheckpointOpts{
|
||||||
ImagePath: r.Checkpoint,
|
ImagePath: r.Checkpoint,
|
||||||
WorkDir: p.WorkDir,
|
WorkDir: p.CriuWorkPath,
|
||||||
ParentPath: r.ParentCheckpoint,
|
ParentPath: r.ParentCheckpoint,
|
||||||
},
|
},
|
||||||
PidFile: pidFile,
|
PidFile: pidFile,
|
||||||
@ -427,8 +428,12 @@ func (p *Init) checkpoint(ctx context.Context, r *CheckpointConfig) error {
|
|||||||
if !r.Exit {
|
if !r.Exit {
|
||||||
actions = append(actions, runc.LeaveRunning)
|
actions = append(actions, runc.LeaveRunning)
|
||||||
}
|
}
|
||||||
work := filepath.Join(p.WorkDir, "criu-work")
|
// keep criu work directory if criu work dir is set
|
||||||
defer os.RemoveAll(work)
|
work := r.WorkDir
|
||||||
|
if work == "" {
|
||||||
|
work = filepath.Join(p.WorkDir, "criu-work")
|
||||||
|
defer os.RemoveAll(work)
|
||||||
|
}
|
||||||
if err := p.runtime.Checkpoint(ctx, p.id, &runc.CheckpointOpts{
|
if err := p.runtime.Checkpoint(ctx, p.id, &runc.CheckpointOpts{
|
||||||
WorkDir: work,
|
WorkDir: work,
|
||||||
ImagePath: r.Path,
|
ImagePath: r.Path,
|
||||||
|
@ -55,6 +55,7 @@ type ExecConfig struct {
|
|||||||
|
|
||||||
// CheckpointConfig holds task checkpoint configuration
|
// CheckpointConfig holds task checkpoint configuration
|
||||||
type CheckpointConfig struct {
|
type CheckpointConfig struct {
|
||||||
|
WorkDir string
|
||||||
Path string
|
Path string
|
||||||
Exit bool
|
Exit bool
|
||||||
AllowOpenTCP bool
|
AllowOpenTCP bool
|
||||||
|
@ -448,6 +448,7 @@ func (s *Service) Checkpoint(ctx context.Context, r *shimapi.CheckpointTaskReque
|
|||||||
AllowTerminal: options.Terminal,
|
AllowTerminal: options.Terminal,
|
||||||
FileLocks: options.FileLocks,
|
FileLocks: options.FileLocks,
|
||||||
EmptyNamespaces: options.EmptyNamespaces,
|
EmptyNamespaces: options.EmptyNamespaces,
|
||||||
|
WorkDir: options.WorkPath,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, errdefs.ToGRPC(err)
|
return nil, errdefs.ToGRPC(err)
|
||||||
}
|
}
|
||||||
@ -657,5 +658,11 @@ func newInit(ctx context.Context, path, workDir, runtimeRoot, namespace, criu st
|
|||||||
p.IoGID = int(options.IoGid)
|
p.IoGID = int(options.IoGid)
|
||||||
p.NoPivotRoot = options.NoPivotRoot
|
p.NoPivotRoot = options.NoPivotRoot
|
||||||
p.NoNewKeyring = options.NoNewKeyring
|
p.NoNewKeyring = options.NoNewKeyring
|
||||||
|
p.CriuWorkPath = options.CriuWorkPath
|
||||||
|
if p.CriuWorkPath == "" {
|
||||||
|
// if criu work path not set, use container WorkDir
|
||||||
|
p.CriuWorkPath = p.WorkDir
|
||||||
|
}
|
||||||
|
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,20 @@ file {
|
|||||||
type: TYPE_BOOL
|
type: TYPE_BOOL
|
||||||
json_name: "systemdCgroup"
|
json_name: "systemdCgroup"
|
||||||
}
|
}
|
||||||
|
field {
|
||||||
|
name: "criu_image_path"
|
||||||
|
number: 10
|
||||||
|
label: LABEL_OPTIONAL
|
||||||
|
type: TYPE_STRING
|
||||||
|
json_name: "criuImagePath"
|
||||||
|
}
|
||||||
|
field {
|
||||||
|
name: "criu_work_path"
|
||||||
|
number: 11
|
||||||
|
label: LABEL_OPTIONAL
|
||||||
|
type: TYPE_STRING
|
||||||
|
json_name: "criuWorkPath"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
message_type {
|
message_type {
|
||||||
name: "CheckpointOptions"
|
name: "CheckpointOptions"
|
||||||
@ -119,6 +133,20 @@ file {
|
|||||||
type: TYPE_STRING
|
type: TYPE_STRING
|
||||||
json_name: "cgroupsMode"
|
json_name: "cgroupsMode"
|
||||||
}
|
}
|
||||||
|
field {
|
||||||
|
name: "image_path"
|
||||||
|
number: 8
|
||||||
|
label: LABEL_OPTIONAL
|
||||||
|
type: TYPE_STRING
|
||||||
|
json_name: "imagePath"
|
||||||
|
}
|
||||||
|
field {
|
||||||
|
name: "work_path"
|
||||||
|
number: 9
|
||||||
|
label: LABEL_OPTIONAL
|
||||||
|
type: TYPE_STRING
|
||||||
|
json_name: "workPath"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
message_type {
|
message_type {
|
||||||
name: "ProcessDetails"
|
name: "ProcessDetails"
|
||||||
|
@ -55,6 +55,10 @@ type Options struct {
|
|||||||
CriuPath string `protobuf:"bytes,8,opt,name=criu_path,json=criuPath,proto3" json:"criu_path,omitempty"`
|
CriuPath string `protobuf:"bytes,8,opt,name=criu_path,json=criuPath,proto3" json:"criu_path,omitempty"`
|
||||||
// enable systemd cgroups
|
// enable systemd cgroups
|
||||||
SystemdCgroup bool `protobuf:"varint,9,opt,name=systemd_cgroup,json=systemdCgroup,proto3" json:"systemd_cgroup,omitempty"`
|
SystemdCgroup bool `protobuf:"varint,9,opt,name=systemd_cgroup,json=systemdCgroup,proto3" json:"systemd_cgroup,omitempty"`
|
||||||
|
// criu image path
|
||||||
|
CriuImagePath string `protobuf:"bytes,10,opt,name=criu_image_path,json=criuImagePath,proto3" json:"criu_image_path,omitempty"`
|
||||||
|
// criu work path
|
||||||
|
CriuWorkPath string `protobuf:"bytes,11,opt,name=criu_work_path,json=criuWorkPath,proto3" json:"criu_work_path,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Options) Reset() { *m = Options{} }
|
func (m *Options) Reset() { *m = Options{} }
|
||||||
@ -76,6 +80,10 @@ type CheckpointOptions struct {
|
|||||||
EmptyNamespaces []string `protobuf:"bytes,6,rep,name=empty_namespaces,json=emptyNamespaces" json:"empty_namespaces,omitempty"`
|
EmptyNamespaces []string `protobuf:"bytes,6,rep,name=empty_namespaces,json=emptyNamespaces" json:"empty_namespaces,omitempty"`
|
||||||
// set the cgroups mode, soft, full, strict
|
// set the cgroups mode, soft, full, strict
|
||||||
CgroupsMode string `protobuf:"bytes,7,opt,name=cgroups_mode,json=cgroupsMode,proto3" json:"cgroups_mode,omitempty"`
|
CgroupsMode string `protobuf:"bytes,7,opt,name=cgroups_mode,json=cgroupsMode,proto3" json:"cgroups_mode,omitempty"`
|
||||||
|
// checkpoint image path
|
||||||
|
ImagePath string `protobuf:"bytes,8,opt,name=image_path,json=imagePath,proto3" json:"image_path,omitempty"`
|
||||||
|
// checkpoint work path
|
||||||
|
WorkPath string `protobuf:"bytes,9,opt,name=work_path,json=workPath,proto3" json:"work_path,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CheckpointOptions) Reset() { *m = CheckpointOptions{} }
|
func (m *CheckpointOptions) Reset() { *m = CheckpointOptions{} }
|
||||||
@ -175,6 +183,18 @@ func (m *Options) MarshalTo(dAtA []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
if len(m.CriuImagePath) > 0 {
|
||||||
|
dAtA[i] = 0x52
|
||||||
|
i++
|
||||||
|
i = encodeVarintOci(dAtA, i, uint64(len(m.CriuImagePath)))
|
||||||
|
i += copy(dAtA[i:], m.CriuImagePath)
|
||||||
|
}
|
||||||
|
if len(m.CriuWorkPath) > 0 {
|
||||||
|
dAtA[i] = 0x5a
|
||||||
|
i++
|
||||||
|
i = encodeVarintOci(dAtA, i, uint64(len(m.CriuWorkPath)))
|
||||||
|
i += copy(dAtA[i:], m.CriuWorkPath)
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,6 +284,18 @@ func (m *CheckpointOptions) MarshalTo(dAtA []byte) (int, error) {
|
|||||||
i = encodeVarintOci(dAtA, i, uint64(len(m.CgroupsMode)))
|
i = encodeVarintOci(dAtA, i, uint64(len(m.CgroupsMode)))
|
||||||
i += copy(dAtA[i:], m.CgroupsMode)
|
i += copy(dAtA[i:], m.CgroupsMode)
|
||||||
}
|
}
|
||||||
|
if len(m.ImagePath) > 0 {
|
||||||
|
dAtA[i] = 0x42
|
||||||
|
i++
|
||||||
|
i = encodeVarintOci(dAtA, i, uint64(len(m.ImagePath)))
|
||||||
|
i += copy(dAtA[i:], m.ImagePath)
|
||||||
|
}
|
||||||
|
if len(m.WorkPath) > 0 {
|
||||||
|
dAtA[i] = 0x4a
|
||||||
|
i++
|
||||||
|
i = encodeVarintOci(dAtA, i, uint64(len(m.WorkPath)))
|
||||||
|
i += copy(dAtA[i:], m.WorkPath)
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,6 +366,14 @@ func (m *Options) Size() (n int) {
|
|||||||
if m.SystemdCgroup {
|
if m.SystemdCgroup {
|
||||||
n += 2
|
n += 2
|
||||||
}
|
}
|
||||||
|
l = len(m.CriuImagePath)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovOci(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.CriuWorkPath)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovOci(uint64(l))
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,6 +405,14 @@ func (m *CheckpointOptions) Size() (n int) {
|
|||||||
if l > 0 {
|
if l > 0 {
|
||||||
n += 1 + l + sovOci(uint64(l))
|
n += 1 + l + sovOci(uint64(l))
|
||||||
}
|
}
|
||||||
|
l = len(m.ImagePath)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovOci(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.WorkPath)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovOci(uint64(l))
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,6 +453,8 @@ func (this *Options) String() string {
|
|||||||
`Root:` + fmt.Sprintf("%v", this.Root) + `,`,
|
`Root:` + fmt.Sprintf("%v", this.Root) + `,`,
|
||||||
`CriuPath:` + fmt.Sprintf("%v", this.CriuPath) + `,`,
|
`CriuPath:` + fmt.Sprintf("%v", this.CriuPath) + `,`,
|
||||||
`SystemdCgroup:` + fmt.Sprintf("%v", this.SystemdCgroup) + `,`,
|
`SystemdCgroup:` + fmt.Sprintf("%v", this.SystemdCgroup) + `,`,
|
||||||
|
`CriuImagePath:` + fmt.Sprintf("%v", this.CriuImagePath) + `,`,
|
||||||
|
`CriuWorkPath:` + fmt.Sprintf("%v", this.CriuWorkPath) + `,`,
|
||||||
`}`,
|
`}`,
|
||||||
}, "")
|
}, "")
|
||||||
return s
|
return s
|
||||||
@ -421,6 +471,8 @@ func (this *CheckpointOptions) String() string {
|
|||||||
`FileLocks:` + fmt.Sprintf("%v", this.FileLocks) + `,`,
|
`FileLocks:` + fmt.Sprintf("%v", this.FileLocks) + `,`,
|
||||||
`EmptyNamespaces:` + fmt.Sprintf("%v", this.EmptyNamespaces) + `,`,
|
`EmptyNamespaces:` + fmt.Sprintf("%v", this.EmptyNamespaces) + `,`,
|
||||||
`CgroupsMode:` + fmt.Sprintf("%v", this.CgroupsMode) + `,`,
|
`CgroupsMode:` + fmt.Sprintf("%v", this.CgroupsMode) + `,`,
|
||||||
|
`ImagePath:` + fmt.Sprintf("%v", this.ImagePath) + `,`,
|
||||||
|
`WorkPath:` + fmt.Sprintf("%v", this.WorkPath) + `,`,
|
||||||
`}`,
|
`}`,
|
||||||
}, "")
|
}, "")
|
||||||
return s
|
return s
|
||||||
@ -686,6 +738,64 @@ func (m *Options) Unmarshal(dAtA []byte) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.SystemdCgroup = bool(v != 0)
|
m.SystemdCgroup = bool(v != 0)
|
||||||
|
case 10:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field CriuImagePath", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowOci
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthOci
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.CriuImagePath = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 11:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field CriuWorkPath", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowOci
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthOci
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.CriuWorkPath = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipOci(dAtA[iNdEx:])
|
skippy, err := skipOci(dAtA[iNdEx:])
|
||||||
@ -894,6 +1004,64 @@ func (m *CheckpointOptions) Unmarshal(dAtA []byte) error {
|
|||||||
}
|
}
|
||||||
m.CgroupsMode = string(dAtA[iNdEx:postIndex])
|
m.CgroupsMode = string(dAtA[iNdEx:postIndex])
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
case 8:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field ImagePath", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowOci
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthOci
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.ImagePath = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 9:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field WorkPath", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowOci
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthOci
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.WorkPath = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipOci(dAtA[iNdEx:])
|
skippy, err := skipOci(dAtA[iNdEx:])
|
||||||
@ -1104,39 +1272,42 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptorOci = []byte{
|
var fileDescriptorOci = []byte{
|
||||||
// 529 bytes of a gzipped FileDescriptorProto
|
// 587 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0xcd, 0x6e, 0xd3, 0x4c,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0xcf, 0x6e, 0xd3, 0x40,
|
||||||
0x14, 0x86, 0xeb, 0xfe, 0x38, 0xf6, 0xf4, 0xe7, 0xfb, 0x18, 0xa8, 0x64, 0x8a, 0x70, 0x43, 0x00,
|
0x10, 0x87, 0xeb, 0xfe, 0x49, 0xec, 0x4d, 0x93, 0xc2, 0x42, 0x25, 0xd3, 0x8a, 0x34, 0x94, 0x82,
|
||||||
0x29, 0x6c, 0x12, 0x51, 0xc4, 0x8a, 0x0d, 0x6a, 0x8b, 0x50, 0x05, 0x94, 0xca, 0x50, 0x09, 0x75,
|
0xc2, 0x25, 0x11, 0x45, 0x9c, 0xb8, 0xa0, 0xb6, 0x08, 0x55, 0x40, 0xa9, 0x0c, 0x15, 0xa8, 0x97,
|
||||||
0x33, 0x72, 0xc6, 0x07, 0xe7, 0x28, 0xf1, 0x1c, 0xcb, 0x33, 0x4e, 0x9d, 0x1d, 0xf7, 0xc1, 0x0d,
|
0x95, 0xbb, 0x1e, 0x9c, 0x51, 0xe2, 0x1d, 0xcb, 0xbb, 0x69, 0xd2, 0x1b, 0xef, 0xc5, 0x0b, 0xf4,
|
||||||
0x75, 0xc9, 0x92, 0x15, 0xa2, 0xb9, 0x11, 0x90, 0xc7, 0x4e, 0x61, 0xcd, 0xca, 0xef, 0x3c, 0xef,
|
0xc8, 0x91, 0x13, 0xa2, 0xb9, 0xf1, 0x16, 0x68, 0xd7, 0x4e, 0xdb, 0x33, 0x27, 0xcf, 0x7e, 0xf3,
|
||||||
0xf1, 0x68, 0xe6, 0xd1, 0xb0, 0xc3, 0x14, 0xcd, 0xb8, 0x1c, 0x0d, 0x24, 0x65, 0x43, 0x49, 0xca,
|
0xf3, 0x78, 0xfd, 0xad, 0x96, 0xed, 0xa5, 0x68, 0x06, 0xe3, 0xb3, 0x9e, 0xa4, 0xac, 0x2f, 0x49,
|
||||||
0xc4, 0xa8, 0xa0, 0x48, 0xfe, 0x8e, 0x45, 0xa9, 0x0c, 0x66, 0x30, 0x9c, 0x1d, 0xd4, 0x51, 0x0e,
|
0x99, 0x18, 0x15, 0x14, 0xc9, 0xed, 0xb2, 0x18, 0x2b, 0x83, 0x19, 0xf4, 0xcf, 0x77, 0x6d, 0x29,
|
||||||
0x29, 0x37, 0x48, 0x4a, 0x0f, 0x49, 0xe2, 0x20, 0x2f, 0xc8, 0x10, 0xe7, 0x7f, 0xa6, 0x07, 0xf5,
|
0xfb, 0x94, 0x1b, 0x24, 0xa5, 0xfb, 0x24, 0xb1, 0x97, 0x17, 0x64, 0x88, 0xf3, 0x9b, 0x74, 0xcf,
|
||||||
0xc8, 0x60, 0xf6, 0x74, 0xef, 0x4e, 0x4a, 0x29, 0xd9, 0x7a, 0x58, 0xa7, 0x66, 0xb2, 0xf7, 0x75,
|
0x46, 0x7a, 0xe7, 0xcf, 0x37, 0xee, 0xa7, 0x94, 0x92, 0x6b, 0xf7, 0x6d, 0x55, 0x26, 0xb7, 0xff,
|
||||||
0x95, 0x75, 0xde, 0x37, 0xff, 0xf3, 0x1e, 0xdb, 0x56, 0x24, 0x72, 0x9c, 0x91, 0x11, 0x05, 0x91,
|
0x2e, 0xb2, 0xfa, 0xc7, 0xf2, 0x7d, 0xbe, 0xcd, 0x9a, 0x8a, 0x44, 0x8e, 0xe7, 0x64, 0x44, 0x41,
|
||||||
0x09, 0x9c, 0xae, 0xd3, 0xf7, 0xa2, 0x4d, 0x45, 0x67, 0x35, 0x8b, 0x88, 0x0c, 0x7f, 0xc4, 0x76,
|
0x64, 0x42, 0xaf, 0xe3, 0x75, 0xfd, 0xa8, 0xa1, 0xe8, 0xd8, 0xb2, 0x88, 0xc8, 0xf0, 0x1d, 0xd6,
|
||||||
0x14, 0x09, 0x05, 0x97, 0x62, 0x02, 0xf3, 0x02, 0x55, 0x1a, 0xac, 0xda, 0xa1, 0x2d, 0x45, 0xa7,
|
0x52, 0x24, 0x14, 0x4c, 0xc4, 0x10, 0x2e, 0x0a, 0x54, 0x69, 0xb8, 0xe8, 0x42, 0xab, 0x8a, 0x8e,
|
||||||
0x70, 0xf9, 0xa6, 0x61, 0x7c, 0x9f, 0x6d, 0xea, 0x31, 0x66, 0x42, 0xa6, 0x05, 0x95, 0x79, 0xb0,
|
0x60, 0xf2, 0xae, 0x64, 0x7c, 0x8b, 0x35, 0xf4, 0x00, 0x33, 0x21, 0xd3, 0x82, 0xc6, 0x79, 0xb8,
|
||||||
0xd6, 0x75, 0xfa, 0x7e, 0xc4, 0x6a, 0x74, 0x64, 0x09, 0xdf, 0x65, 0x2e, 0x92, 0x28, 0x31, 0x09,
|
0xd4, 0xf1, 0xba, 0x41, 0xc4, 0x2c, 0xda, 0x77, 0x84, 0xaf, 0xb3, 0x1a, 0x92, 0x18, 0x63, 0x12,
|
||||||
0xd6, 0xbb, 0x4e, 0x7f, 0x3b, 0xda, 0x40, 0x3a, 0xc7, 0xa4, 0xc5, 0x29, 0x26, 0xc1, 0xc6, 0x12,
|
0x2e, 0x77, 0xbc, 0x6e, 0x33, 0x5a, 0x41, 0x3a, 0xc1, 0xa4, 0xc2, 0x29, 0x26, 0xe1, 0xca, 0x1c,
|
||||||
0xbf, 0xc6, 0xa4, 0xde, 0x6e, 0x84, 0x2a, 0x2e, 0xe6, 0x42, 0xc5, 0x19, 0x04, 0x6e, 0xb3, 0x5d,
|
0xbf, 0xc5, 0xc4, 0x8e, 0x3b, 0x43, 0x15, 0x17, 0x17, 0x42, 0xc5, 0x19, 0x84, 0xb5, 0x72, 0x5c,
|
||||||
0x83, 0x4e, 0xe3, 0x0c, 0x38, 0x67, 0xeb, 0xf6, 0xc0, 0x1d, 0xdb, 0xd8, 0xcc, 0xef, 0x31, 0x5f,
|
0x89, 0x8e, 0xe2, 0x0c, 0x38, 0x67, 0xcb, 0x6e, 0xc3, 0x75, 0xd7, 0x71, 0x35, 0xdf, 0x64, 0x81,
|
||||||
0x16, 0x58, 0x8a, 0x3c, 0x36, 0xe3, 0xc0, 0xb3, 0x85, 0x57, 0x83, 0xb3, 0xd8, 0x8c, 0xf9, 0x63,
|
0x2c, 0x70, 0x2c, 0xf2, 0xd8, 0x0c, 0x42, 0xdf, 0x35, 0x7c, 0x0b, 0x8e, 0x63, 0x33, 0xe0, 0x4f,
|
||||||
0xb6, 0xa3, 0xe7, 0xda, 0x40, 0x96, 0x2c, 0xcf, 0xe8, 0xdb, 0x6b, 0x6c, 0xb7, 0xb4, 0x39, 0x66,
|
0x58, 0x4b, 0x5f, 0x68, 0x03, 0x59, 0x32, 0xdf, 0x63, 0xe0, 0x7e, 0xa3, 0x59, 0xd1, 0x6a, 0x9b,
|
||||||
0xef, 0x97, 0xc3, 0x6e, 0x1d, 0x8d, 0x41, 0x4e, 0x72, 0x42, 0x65, 0x96, 0x9e, 0x38, 0x5b, 0x87,
|
0x4f, 0xd9, 0x9a, 0x9b, 0x81, 0x59, 0x9c, 0x42, 0x39, 0x89, 0xb9, 0x49, 0x4d, 0x8b, 0x0f, 0x2d,
|
||||||
0x0a, 0x97, 0x7a, 0x6c, 0xe6, 0x77, 0x99, 0x47, 0x39, 0x28, 0x61, 0x64, 0xde, 0x1a, 0xe9, 0xd4,
|
0x75, 0xe3, 0x76, 0x58, 0xcb, 0xe5, 0x26, 0x54, 0x0c, 0xcb, 0x58, 0xc3, 0xc5, 0x56, 0x2d, 0xfd,
|
||||||
0xeb, 0x8f, 0x32, 0xe7, 0x07, 0x6c, 0x17, 0x2a, 0x03, 0x85, 0x8a, 0xa7, 0xa2, 0x54, 0x58, 0x09,
|
0x42, 0xc5, 0xd0, 0xa6, 0xb6, 0x7f, 0x2c, 0xb2, 0xbb, 0xfb, 0x03, 0x90, 0xc3, 0x9c, 0x50, 0x99,
|
||||||
0x4d, 0x72, 0x02, 0x46, 0x5b, 0x2d, 0x5e, 0x74, 0x7b, 0x59, 0x9e, 0x2b, 0xac, 0x3e, 0x34, 0x15,
|
0xb9, 0x75, 0xce, 0x96, 0x61, 0x8a, 0x73, 0xd9, 0xae, 0xe6, 0x0f, 0x98, 0x4f, 0x39, 0x28, 0x61,
|
||||||
0xdf, 0x63, 0x9e, 0x81, 0x22, 0x43, 0x15, 0x4f, 0xad, 0x21, 0x2f, 0xba, 0x59, 0xf3, 0xfb, 0x8c,
|
0x64, 0x5e, 0xf9, 0xad, 0xdb, 0xf5, 0x67, 0x99, 0xf3, 0x5d, 0xb6, 0x0e, 0x53, 0x03, 0x85, 0x8a,
|
||||||
0x7d, 0xc6, 0x29, 0x88, 0x29, 0xc9, 0x89, 0xb6, 0xa2, 0xbc, 0xc8, 0xaf, 0xc9, 0xdb, 0x1a, 0xf0,
|
0x47, 0x62, 0xac, 0x70, 0x2a, 0x34, 0xc9, 0x21, 0x18, 0xed, 0x24, 0xfb, 0xd1, 0xbd, 0x79, 0xf3,
|
||||||
0x27, 0xec, 0x7f, 0xc8, 0x72, 0xd3, 0xb8, 0xd2, 0x79, 0x2c, 0x41, 0x07, 0x6e, 0x77, 0xad, 0xef,
|
0x44, 0xe1, 0xf4, 0x53, 0xd9, 0xe2, 0x1b, 0xcc, 0x37, 0x50, 0x64, 0xa8, 0xe2, 0x91, 0xf3, 0xed,
|
||||||
0x47, 0xff, 0x59, 0x7e, 0x7a, 0x83, 0xf9, 0x03, 0xb6, 0xd5, 0xdc, 0x5e, 0x8b, 0x8c, 0x12, 0x68,
|
0x47, 0xd7, 0x6b, 0xfe, 0x90, 0xb1, 0x6f, 0x38, 0x02, 0x31, 0x22, 0x39, 0xd4, 0x4e, 0xbb, 0x1f,
|
||||||
0xf5, 0x6d, 0xb6, 0xec, 0x1d, 0x25, 0xd0, 0x7b, 0xce, 0x76, 0xce, 0x0a, 0x92, 0xa0, 0xf5, 0x31,
|
0x05, 0x96, 0xbc, 0xb7, 0x80, 0x3f, 0x63, 0x77, 0x20, 0xcb, 0x4d, 0x69, 0x5e, 0xe7, 0xb1, 0x04,
|
||||||
0x98, 0x18, 0xa7, 0x9a, 0x3f, 0x64, 0x1d, 0xa8, 0x40, 0x0a, 0x4c, 0xac, 0x00, 0xff, 0x90, 0x2d,
|
0x1d, 0xd6, 0x3a, 0x4b, 0xdd, 0x20, 0x5a, 0x73, 0xfc, 0xe8, 0x1a, 0xf3, 0x47, 0x6c, 0xb5, 0x74,
|
||||||
0x7e, 0xec, 0xbb, 0xaf, 0x2a, 0x90, 0x27, 0xc7, 0x91, 0x5b, 0x57, 0x27, 0xc9, 0xe1, 0xc5, 0xd5,
|
0xa9, 0x45, 0x46, 0x09, 0x54, 0x87, 0xd1, 0xa8, 0xd8, 0x07, 0x4a, 0xc0, 0x7e, 0xec, 0x96, 0xca,
|
||||||
0x75, 0xb8, 0xf2, 0xfd, 0x3a, 0x5c, 0xf9, 0xb2, 0x08, 0x9d, 0xab, 0x45, 0xe8, 0x7c, 0x5b, 0x84,
|
0xf2, 0x50, 0x02, 0xbc, 0xd6, 0xb8, 0xc9, 0x82, 0x1b, 0x83, 0x41, 0x79, 0x64, 0x93, 0xb9, 0xbd,
|
||||||
0xce, 0xcf, 0x45, 0xe8, 0x5c, 0xbc, 0xfc, 0xd7, 0xe7, 0xfd, 0xa2, 0xfd, 0x7e, 0x5a, 0x19, 0xb9,
|
0x97, 0xac, 0x75, 0x5c, 0x90, 0x04, 0xad, 0x0f, 0xc0, 0xc4, 0x38, 0xd2, 0xfc, 0x31, 0xab, 0xc3,
|
||||||
0xf6, 0xed, 0x3e, 0xfb, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x78, 0xf4, 0x16, 0x4e, 0x2b, 0x03, 0x00,
|
0x14, 0xa4, 0xc0, 0xc4, 0xc9, 0x0b, 0xf6, 0xd8, 0xec, 0xf7, 0x56, 0xed, 0xcd, 0x14, 0xe4, 0xe1,
|
||||||
0x00,
|
0x41, 0x54, 0xb3, 0xad, 0xc3, 0x64, 0xef, 0xf4, 0xf2, 0xaa, 0xbd, 0xf0, 0xeb, 0xaa, 0xbd, 0xf0,
|
||||||
|
0x7d, 0xd6, 0xf6, 0x2e, 0x67, 0x6d, 0xef, 0xe7, 0xac, 0xed, 0xfd, 0x99, 0xb5, 0xbd, 0xd3, 0xd7,
|
||||||
|
0xff, 0x7b, 0xd1, 0x5e, 0x55, 0xcf, 0xaf, 0x0b, 0x67, 0x35, 0x77, 0x8b, 0x5e, 0xfc, 0x0b, 0x00,
|
||||||
|
0x00, 0xff, 0xff, 0x90, 0x50, 0x79, 0xf2, 0xb5, 0x03, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,10 @@ message Options {
|
|||||||
string criu_path = 8;
|
string criu_path = 8;
|
||||||
// enable systemd cgroups
|
// enable systemd cgroups
|
||||||
bool systemd_cgroup = 9;
|
bool systemd_cgroup = 9;
|
||||||
|
// criu image path
|
||||||
|
string criu_image_path = 10;
|
||||||
|
// criu work path
|
||||||
|
string criu_work_path = 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CheckpointOptions {
|
message CheckpointOptions {
|
||||||
@ -42,6 +46,10 @@ message CheckpointOptions {
|
|||||||
repeated string empty_namespaces = 6;
|
repeated string empty_namespaces = 6;
|
||||||
// set the cgroups mode, soft, full, strict
|
// set the cgroups mode, soft, full, strict
|
||||||
string cgroups_mode = 7;
|
string cgroups_mode = 7;
|
||||||
|
// checkpoint image path
|
||||||
|
string image_path = 8;
|
||||||
|
// checkpoint work path
|
||||||
|
string work_path = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ProcessDetails {
|
message ProcessDetails {
|
||||||
|
@ -562,6 +562,7 @@ func (s *service) Checkpoint(ctx context.Context, r *taskAPI.CheckpointTaskReque
|
|||||||
AllowTerminal: opts.Terminal,
|
AllowTerminal: opts.Terminal,
|
||||||
FileLocks: opts.FileLocks,
|
FileLocks: opts.FileLocks,
|
||||||
EmptyNamespaces: opts.EmptyNamespaces,
|
EmptyNamespaces: opts.EmptyNamespaces,
|
||||||
|
WorkDir: opts.WorkPath,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, errdefs.ToGRPC(err)
|
return nil, errdefs.ToGRPC(err)
|
||||||
}
|
}
|
||||||
@ -806,5 +807,11 @@ func newInit(ctx context.Context, path, workDir, namespace string, platform rpro
|
|||||||
p.IoGID = int(options.IoGid)
|
p.IoGID = int(options.IoGid)
|
||||||
p.NoPivotRoot = options.NoPivotRoot
|
p.NoPivotRoot = options.NoPivotRoot
|
||||||
p.NoNewKeyring = options.NoNewKeyring
|
p.NoNewKeyring = options.NoNewKeyring
|
||||||
|
p.CriuWorkPath = options.CriuWorkPath
|
||||||
|
if p.CriuWorkPath == "" {
|
||||||
|
// if criu work path not set, use container WorkDir
|
||||||
|
p.CriuWorkPath = p.WorkDir
|
||||||
|
}
|
||||||
|
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,9 @@ import (
|
|||||||
"github.com/containerd/containerd/mount"
|
"github.com/containerd/containerd/mount"
|
||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
"github.com/containerd/containerd/runtime"
|
"github.com/containerd/containerd/runtime"
|
||||||
|
"github.com/containerd/containerd/runtime/linux/runctypes"
|
||||||
"github.com/containerd/containerd/runtime/v2"
|
"github.com/containerd/containerd/runtime/v2"
|
||||||
|
"github.com/containerd/containerd/runtime/v2/runc/options"
|
||||||
"github.com/containerd/containerd/services"
|
"github.com/containerd/containerd/services"
|
||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
ptypes "github.com/gogo/protobuf/types"
|
ptypes "github.com/gogo/protobuf/types"
|
||||||
@ -123,11 +125,16 @@ type local struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *local) Create(ctx context.Context, r *api.CreateTaskRequest, _ ...grpc.CallOption) (*api.CreateTaskResponse, error) {
|
func (l *local) Create(ctx context.Context, r *api.CreateTaskRequest, _ ...grpc.CallOption) (*api.CreateTaskResponse, error) {
|
||||||
var (
|
container, err := l.getContainer(ctx, r.ContainerID)
|
||||||
checkpointPath string
|
if err != nil {
|
||||||
err error
|
return nil, errdefs.ToGRPC(err)
|
||||||
)
|
}
|
||||||
if r.Checkpoint != nil {
|
checkpointPath, err := getRestorePath(container.Runtime.Name, r.Options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// jump get checkpointPath from checkpoint image
|
||||||
|
if checkpointPath != "" && r.Checkpoint != nil {
|
||||||
checkpointPath, err = ioutil.TempDir(os.Getenv("XDG_RUNTIME_DIR"), "ctrd-checkpoint")
|
checkpointPath, err = ioutil.TempDir(os.Getenv("XDG_RUNTIME_DIR"), "ctrd-checkpoint")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -149,10 +156,6 @@ func (l *local) Create(ctx context.Context, r *api.CreateTaskRequest, _ ...grpc.
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
container, err := l.getContainer(ctx, r.ContainerID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errdefs.ToGRPC(err)
|
|
||||||
}
|
|
||||||
opts := runtime.CreateOpts{
|
opts := runtime.CreateOpts{
|
||||||
Spec: container.Spec,
|
Spec: container.Spec,
|
||||||
IO: runtime.IO{
|
IO: runtime.IO{
|
||||||
@ -478,14 +481,27 @@ func (l *local) Checkpoint(ctx context.Context, r *api.CheckpointTaskRequest, _
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
image, err := ioutil.TempDir(os.Getenv("XDG_RUNTIME_DIR"), "ctd-checkpoint")
|
image, err := getCheckpointPath(container.Runtime.Name, r.Options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errdefs.ToGRPC(err)
|
return nil, err
|
||||||
|
}
|
||||||
|
checkpointImageExists := false
|
||||||
|
if image == "" {
|
||||||
|
checkpointImageExists = true
|
||||||
|
image, err = ioutil.TempDir(os.Getenv("XDG_RUNTIME_DIR"), "ctd-checkpoint")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errdefs.ToGRPC(err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(image)
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(image)
|
|
||||||
if err := t.Checkpoint(ctx, image, r.Options); err != nil {
|
if err := t.Checkpoint(ctx, image, r.Options); err != nil {
|
||||||
return nil, errdefs.ToGRPC(err)
|
return nil, errdefs.ToGRPC(err)
|
||||||
}
|
}
|
||||||
|
// do not commit checkpoint image if checkpoint ImagePath is passed,
|
||||||
|
// return if checkpointImageExists is false
|
||||||
|
if !checkpointImageExists {
|
||||||
|
return &api.CheckpointTaskResponse{}, nil
|
||||||
|
}
|
||||||
// write checkpoint to the content store
|
// write checkpoint to the content store
|
||||||
tar := archive.Diff(ctx, "", image)
|
tar := archive.Diff(ctx, "", image)
|
||||||
cp, err := l.writeContent(ctx, images.MediaTypeContainerd1Checkpoint, image, tar)
|
cp, err := l.writeContent(ctx, images.MediaTypeContainerd1Checkpoint, image, tar)
|
||||||
@ -663,3 +679,71 @@ func (l *local) allRuntimes() (o []runtime.PlatformRuntime) {
|
|||||||
o = append(o, l.v2Runtime)
|
o = append(o, l.v2Runtime)
|
||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getCheckpointPath only suitable for runc runtime now
|
||||||
|
func getCheckpointPath(runtime string, option *ptypes.Any) (string, error) {
|
||||||
|
if option == nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var checkpointPath string
|
||||||
|
switch runtime {
|
||||||
|
case "io.containerd.runc.v1":
|
||||||
|
v, err := typeurl.UnmarshalAny(option)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
opts, ok := v.(*options.CheckpointOptions)
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("invalid task checkpoint option for %s", runtime)
|
||||||
|
}
|
||||||
|
checkpointPath = opts.ImagePath
|
||||||
|
|
||||||
|
case "io.containerd.runtime.v1.linux":
|
||||||
|
v, err := typeurl.UnmarshalAny(option)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
opts, ok := v.(*runctypes.CheckpointOptions)
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("invalid task checkpoint option for %s", runtime)
|
||||||
|
}
|
||||||
|
checkpointPath = opts.ImagePath
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkpointPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getRestorePath only suitable for runc runtime now
|
||||||
|
func getRestorePath(runtime string, option *ptypes.Any) (string, error) {
|
||||||
|
if option == nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var restorePath string
|
||||||
|
switch runtime {
|
||||||
|
case "io.containerd.runc.v1":
|
||||||
|
v, err := typeurl.UnmarshalAny(option)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
opts, ok := v.(*options.Options)
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("invalid task create option for %s", runtime)
|
||||||
|
}
|
||||||
|
restorePath = opts.CriuImagePath
|
||||||
|
|
||||||
|
case "io.containerd.runtime.v1.linux":
|
||||||
|
v, err := typeurl.UnmarshalAny(option)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
opts, ok := v.(*runctypes.CreateOptions)
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("invalid task create option for %s", runtime)
|
||||||
|
}
|
||||||
|
restorePath = opts.CriuImagePath
|
||||||
|
}
|
||||||
|
|
||||||
|
return restorePath, nil
|
||||||
|
}
|
||||||
|
34
task.go
34
task.go
@ -37,6 +37,8 @@ import (
|
|||||||
"github.com/containerd/containerd/mount"
|
"github.com/containerd/containerd/mount"
|
||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
"github.com/containerd/containerd/rootfs"
|
"github.com/containerd/containerd/rootfs"
|
||||||
|
"github.com/containerd/containerd/runtime/linux/runctypes"
|
||||||
|
"github.com/containerd/containerd/runtime/v2/runc/options"
|
||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
google_protobuf "github.com/gogo/protobuf/types"
|
google_protobuf "github.com/gogo/protobuf/types"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
@ -147,6 +149,8 @@ type Task interface {
|
|||||||
// OCI Index that can be push and pulled from a remote resource.
|
// OCI Index that can be push and pulled from a remote resource.
|
||||||
//
|
//
|
||||||
// Additional software like CRIU maybe required to checkpoint and restore tasks
|
// Additional software like CRIU maybe required to checkpoint and restore tasks
|
||||||
|
// NOTE: Checkpoint supports to dump task information to a directory, in this way,
|
||||||
|
// an empty OCI Index will be returned.
|
||||||
Checkpoint(context.Context, ...CheckpointTaskOpts) (Image, error)
|
Checkpoint(context.Context, ...CheckpointTaskOpts) (Image, error)
|
||||||
// Update modifies executing tasks with updated settings
|
// Update modifies executing tasks with updated settings
|
||||||
Update(context.Context, ...UpdateTaskOpts) error
|
Update(context.Context, ...UpdateTaskOpts) error
|
||||||
@ -387,6 +391,8 @@ func (t *task) Resize(ctx context.Context, w, h uint32) error {
|
|||||||
return errdefs.FromGRPC(err)
|
return errdefs.FromGRPC(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Checkpoint supports to dump task information to a directory, in this way, an empty
|
||||||
|
// OCI Index will be returned.
|
||||||
func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Image, error) {
|
func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Image, error) {
|
||||||
ctx, done, err := t.client.WithLease(ctx)
|
ctx, done, err := t.client.WithLease(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -433,6 +439,12 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Imag
|
|||||||
if err := t.checkpointTask(ctx, &index, request); err != nil {
|
if err := t.checkpointTask(ctx, &index, request); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// if checkpoint image path passed, jump checkpoint image,
|
||||||
|
// return an empty image
|
||||||
|
if isCheckpointPathExist(cr.Runtime.Name, i.Options) {
|
||||||
|
return NewImage(t.client, images.Image{}), nil
|
||||||
|
}
|
||||||
|
|
||||||
if cr.Image != "" {
|
if cr.Image != "" {
|
||||||
if err := t.checkpointImage(ctx, &index, cr.Image); err != nil {
|
if err := t.checkpointImage(ctx, &index, cr.Image); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -542,6 +554,7 @@ func (t *task) checkpointTask(ctx context.Context, index *v1.Index, request *tas
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errdefs.FromGRPC(err)
|
return errdefs.FromGRPC(err)
|
||||||
}
|
}
|
||||||
|
// NOTE: response.Descriptors can be an empty slice if checkpoint image is jumped
|
||||||
// add the checkpoint descriptors to the index
|
// add the checkpoint descriptors to the index
|
||||||
for _, d := range response.Descriptors {
|
for _, d := range response.Descriptors {
|
||||||
index.Manifests = append(index.Manifests, v1.Descriptor{
|
index.Manifests = append(index.Manifests, v1.Descriptor{
|
||||||
@ -619,3 +632,24 @@ func writeContent(ctx context.Context, store content.Ingester, mediaType, ref st
|
|||||||
Size: size,
|
Size: size,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isCheckpointPathExist only suitable for runc runtime now
|
||||||
|
func isCheckpointPathExist(runtime string, v interface{}) bool {
|
||||||
|
if v == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch runtime {
|
||||||
|
case "io.containerd.runc.v1":
|
||||||
|
if opts, ok := v.(*options.CheckpointOptions); ok && opts.ImagePath != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
case "io.containerd.runtime.v1.linux":
|
||||||
|
if opts, ok := v.(*runctypes.CheckpointOptions); ok && opts.ImagePath != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
61
task_opts.go
61
task_opts.go
@ -27,11 +27,18 @@ import (
|
|||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/images"
|
"github.com/containerd/containerd/images"
|
||||||
"github.com/containerd/containerd/mount"
|
"github.com/containerd/containerd/mount"
|
||||||
|
"github.com/containerd/containerd/runtime/linux/runctypes"
|
||||||
|
"github.com/containerd/containerd/runtime/v2/runc/options"
|
||||||
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
v1runtime = "io.containerd.runtime.v1.linux"
|
||||||
|
v2runtime = "io.containerd.runc.v1"
|
||||||
|
)
|
||||||
|
|
||||||
// NewTaskOpts allows the caller to set options on a new task
|
// NewTaskOpts allows the caller to set options on a new task
|
||||||
type NewTaskOpts func(context.Context, *Client, *TaskInfo) error
|
type NewTaskOpts func(context.Context, *Client, *TaskInfo) error
|
||||||
|
|
||||||
@ -89,6 +96,60 @@ func WithCheckpointName(name string) CheckpointTaskOpts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithCheckpointImagePath sets image path for checkpoint option
|
||||||
|
func WithCheckpointImagePath(rt, path string) CheckpointTaskOpts {
|
||||||
|
return func(r *CheckpointTaskInfo) error {
|
||||||
|
switch rt {
|
||||||
|
case v1runtime:
|
||||||
|
if r.Options == nil {
|
||||||
|
r.Options = &runctypes.CheckpointOptions{}
|
||||||
|
}
|
||||||
|
opts, ok := r.Options.(*runctypes.CheckpointOptions)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("invalid v1 checkpoint options format")
|
||||||
|
}
|
||||||
|
opts.ImagePath = path
|
||||||
|
case v2runtime:
|
||||||
|
if r.Options == nil {
|
||||||
|
r.Options = &options.CheckpointOptions{}
|
||||||
|
}
|
||||||
|
opts, ok := r.Options.(*options.CheckpointOptions)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("invalid v2 checkpoint options format")
|
||||||
|
}
|
||||||
|
opts.ImagePath = path
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRestoreImagePath sets image path for create option
|
||||||
|
func WithRestoreImagePath(rt, path string) NewTaskOpts {
|
||||||
|
return func(ctx context.Context, c *Client, ti *TaskInfo) error {
|
||||||
|
switch rt {
|
||||||
|
case v1runtime:
|
||||||
|
if ti.Options == nil {
|
||||||
|
ti.Options = &runctypes.CreateOptions{}
|
||||||
|
}
|
||||||
|
opts, ok := ti.Options.(*runctypes.CreateOptions)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("invalid v1 create options format")
|
||||||
|
}
|
||||||
|
opts.CriuImagePath = path
|
||||||
|
case v2runtime:
|
||||||
|
if ti.Options == nil {
|
||||||
|
ti.Options = &options.Options{}
|
||||||
|
}
|
||||||
|
opts, ok := ti.Options.(*options.Options)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("invalid v2 create options format")
|
||||||
|
}
|
||||||
|
opts.CriuImagePath = path
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ProcessDeleteOpts allows the caller to set options for the deletion of a task
|
// ProcessDeleteOpts allows the caller to set options for the deletion of a task
|
||||||
type ProcessDeleteOpts func(context.Context, Process) error
|
type ProcessDeleteOpts func(context.Context, Process) error
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user