Merge pull request #6965 from adrianreber/2022-05-20-checkpoint-cri-rpc
Wire through CRI checkpoint RPC
This commit is contained in:
commit
3c34e2c87d
2
go.mod
2
go.mod
@ -8,6 +8,8 @@ require (
|
|||||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0
|
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0
|
||||||
github.com/Microsoft/go-winio v0.6.1
|
github.com/Microsoft/go-winio v0.6.1
|
||||||
github.com/Microsoft/hcsshim v0.12.0
|
github.com/Microsoft/hcsshim v0.12.0
|
||||||
|
github.com/checkpoint-restore/checkpointctl v1.1.0
|
||||||
|
github.com/checkpoint-restore/go-criu/v7 v7.0.0
|
||||||
github.com/containerd/btrfs/v2 v2.0.0
|
github.com/containerd/btrfs/v2 v2.0.0
|
||||||
github.com/containerd/cgroups/v3 v3.0.3
|
github.com/containerd/cgroups/v3 v3.0.3
|
||||||
github.com/containerd/console v1.0.4
|
github.com/containerd/console v1.0.4
|
||||||
|
4
go.sum
4
go.sum
@ -63,6 +63,10 @@ github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY
|
|||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/checkpoint-restore/checkpointctl v1.1.0 h1:plS/2zBzbAXO6DH/H+TqD7ZGhz8iQVb+NLgsOJSTWaw=
|
||||||
|
github.com/checkpoint-restore/checkpointctl v1.1.0/go.mod h1:DtPd9M4bt/jdt+7DodFxm0lrzdevabk3cbni/FL4BY0=
|
||||||
|
github.com/checkpoint-restore/go-criu/v7 v7.0.0 h1:R4UF/njKOuq8ooG7naFGsCeKsjv5j+rIhgFgSSeC2KY=
|
||||||
|
github.com/checkpoint-restore/go-criu/v7 v7.0.0/go.mod h1:xD1v3cPww1QYpJR3+XTTdC8hYubPnptIPsT1daXhbr4=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
|
@ -565,7 +565,7 @@ func (in *instrumentedService) CheckpointContainer(ctx context.Context, r *runti
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
res, err = in.c.CheckpointContainer(ctx, r)
|
res, err = in.c.CheckpointContainer(ctrdutil.WithNamespace(ctx), r)
|
||||||
return res, errdefs.ToGRPC(err)
|
return res, errdefs.ToGRPC(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build !linux
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright The containerd Authors.
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
@ -18,6 +20,7 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
@ -25,5 +28,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *criService) CheckpointContainer(ctx context.Context, r *runtime.CheckpointContainerRequest) (res *runtime.CheckpointContainerResponse, err error) {
|
func (c *criService) CheckpointContainer(ctx context.Context, r *runtime.CheckpointContainerRequest) (res *runtime.CheckpointContainerResponse, err error) {
|
||||||
|
// The next line is just needed to make the linter happy.
|
||||||
|
containerCheckpointTimer.WithValues("no-runtime").UpdateSince(time.Now())
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method CheckpointContainer not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method CheckpointContainer not implemented")
|
||||||
}
|
}
|
||||||
|
306
internal/cri/server/container_checkpoint_linux.go
Normal file
306
internal/cri/server/container_checkpoint_linux.go
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
//go:build linux
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
crmetadata "github.com/checkpoint-restore/checkpointctl/lib"
|
||||||
|
"github.com/checkpoint-restore/go-criu/v7"
|
||||||
|
"github.com/containerd/containerd/v2/core/content"
|
||||||
|
"github.com/containerd/containerd/v2/core/images"
|
||||||
|
"github.com/containerd/containerd/v2/core/runtime/v2/runc/options"
|
||||||
|
"github.com/containerd/containerd/v2/pkg/archive"
|
||||||
|
"github.com/containerd/containerd/v2/plugins"
|
||||||
|
"github.com/containerd/containerd/v2/protobuf/proto"
|
||||||
|
ptypes "github.com/containerd/containerd/v2/protobuf/types"
|
||||||
|
"github.com/containerd/log"
|
||||||
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/v2/client"
|
||||||
|
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PodCriuVersion is the version of CRIU needed for
|
||||||
|
// checkpointing and restoring containers out of and into Pods.
|
||||||
|
const podCriuVersion = 31600
|
||||||
|
|
||||||
|
// CheckForCriu uses CRIU's go bindings to check if the CRIU
|
||||||
|
// binary exists and if it at least the version Podman needs.
|
||||||
|
func checkForCriu(version int) error {
|
||||||
|
c := criu.MakeCriu()
|
||||||
|
criuVersion, err := c.GetCriuVersion()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to check for criu version: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if criuVersion >= version {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("checkpoint/restore requires at least CRIU %d, current version is %d", version, criuVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *criService) CheckpointContainer(ctx context.Context, r *runtime.CheckpointContainerRequest) (*runtime.CheckpointContainerResponse, error) {
|
||||||
|
start := time.Now()
|
||||||
|
if err := checkForCriu(podCriuVersion); err != nil {
|
||||||
|
// This is the wrong error message and needs to be adapted once
|
||||||
|
// Kubernetes (the e2e_node/checkpoint) test has been changed to
|
||||||
|
// handle too old or missing CRIU error messages.
|
||||||
|
log.G(ctx).WithError(err).Errorf("Failed to checkpoint container %q", r.GetContainerId())
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method CheckpointContainer not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
container, err := c.containerStore.Get(r.GetContainerId())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("an error occurred when try to find container %q: %w", r.GetContainerId(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
state := container.Status.Get().State()
|
||||||
|
if state != runtime.ContainerState_CONTAINER_RUNNING {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"container %q is in %s state. only %s containers can be checkpointed",
|
||||||
|
r.GetContainerId(),
|
||||||
|
criContainerStateToString(state),
|
||||||
|
criContainerStateToString(runtime.ContainerState_CONTAINER_RUNNING),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
imageRef := container.ImageRef
|
||||||
|
image, err := c.GetImage(imageRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("getting container image failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
i, err := container.Container.Info(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get container info: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
configJSON, err := json.Marshal(&crmetadata.ContainerConfig{
|
||||||
|
ID: container.ID,
|
||||||
|
Name: container.Name,
|
||||||
|
RootfsImageName: func() string {
|
||||||
|
if len(image.References) > 0 {
|
||||||
|
return image.References[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}(),
|
||||||
|
RootfsImageRef: imageRef,
|
||||||
|
OCIRuntime: i.Runtime.Name,
|
||||||
|
RootfsImage: container.Config.GetImage().UserSpecifiedImage,
|
||||||
|
CheckpointedAt: time.Now(),
|
||||||
|
CreatedTime: i.CreatedAt,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("generating container config JSON failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
task, err := container.Container.Task(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get task for container %q: %w", r.GetContainerId(), err)
|
||||||
|
}
|
||||||
|
img, err := task.Checkpoint(ctx, []client.CheckpointTaskOpts{withCheckpointOpts(i.Runtime.Name, c.getContainerRootDir(r.GetContainerId()))}...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("checkpointing container %q failed: %w", r.GetContainerId(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// the checkpoint image has been provided as an index with manifests representing the tar of criu data, the rw layer, and the config
|
||||||
|
var (
|
||||||
|
index v1.Index
|
||||||
|
rawIndex []byte
|
||||||
|
targetDesc = img.Target()
|
||||||
|
contentStore = img.ContentStore()
|
||||||
|
)
|
||||||
|
|
||||||
|
rawIndex, err = content.ReadBlob(ctx, contentStore, targetDesc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to retrieve checkpoint index blob from content store: %w", err)
|
||||||
|
}
|
||||||
|
if err = json.Unmarshal(rawIndex, &index); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to unmarshall blob into checkpoint data OCI index: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cpPath := filepath.Join(c.getContainerRootDir(r.GetContainerId()), "ctrd-checkpoint")
|
||||||
|
if err := os.MkdirAll(cpPath, 0o700); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(cpPath)
|
||||||
|
|
||||||
|
if err := os.WriteFile(filepath.Join(cpPath, crmetadata.ConfigDumpFile), configJSON, 0o600); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// walk the manifests and pull out the blobs that we need to save in the checkpoint tarball:
|
||||||
|
// - the checkpoint criu data
|
||||||
|
// - the rw diff tarball
|
||||||
|
// - the spec blob
|
||||||
|
for _, manifest := range index.Manifests {
|
||||||
|
switch manifest.MediaType {
|
||||||
|
case images.MediaTypeContainerd1Checkpoint:
|
||||||
|
if err := writeCriuCheckpointData(ctx, contentStore, manifest, cpPath); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to copy CRIU checkpoint blob to checkpoint dir: %w", err)
|
||||||
|
}
|
||||||
|
case v1.MediaTypeImageLayerGzip:
|
||||||
|
if err := writeRootFsDiffTar(ctx, contentStore, manifest, cpPath); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to copy rw filesystem layer blob to checkpoint dir: %w", err)
|
||||||
|
}
|
||||||
|
case images.MediaTypeContainerd1CheckpointConfig:
|
||||||
|
if err := writeSpecDumpFile(ctx, contentStore, manifest, cpPath); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to copy container spec blob to checkpoint dir: %w", err)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write final tarball of all content
|
||||||
|
tar := archive.Diff(ctx, "", cpPath)
|
||||||
|
|
||||||
|
outFile, err := os.OpenFile(r.Location, os.O_RDWR|os.O_CREATE, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer outFile.Close()
|
||||||
|
_, err = io.Copy(outFile, tar)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := tar.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
containerCheckpointTimer.WithValues(i.Runtime.Name).UpdateSince(start)
|
||||||
|
|
||||||
|
return &runtime.CheckpointContainerResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func withCheckpointOpts(rt, rootDir string) client.CheckpointTaskOpts {
|
||||||
|
return func(r *client.CheckpointTaskInfo) error {
|
||||||
|
// Kubernetes currently supports checkpointing of container
|
||||||
|
// as part of the Forensic Container Checkpointing KEP.
|
||||||
|
// This implies that the container is never stopped
|
||||||
|
leaveRunning := true
|
||||||
|
|
||||||
|
switch rt {
|
||||||
|
case plugins.RuntimeRuncV2:
|
||||||
|
if r.Options == nil {
|
||||||
|
r.Options = &options.CheckpointOptions{}
|
||||||
|
}
|
||||||
|
opts, _ := r.Options.(*options.CheckpointOptions)
|
||||||
|
|
||||||
|
opts.Exit = !leaveRunning
|
||||||
|
opts.WorkPath = rootDir
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeCriuCheckpointData(ctx context.Context, store content.Store, desc v1.Descriptor, cpPath string) error {
|
||||||
|
ra, err := store.ReaderAt(ctx, desc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer ra.Close()
|
||||||
|
|
||||||
|
checkpointDirectory := filepath.Join(cpPath, crmetadata.CheckpointDirectory)
|
||||||
|
// This is the criu data tarball. Let's unpack it
|
||||||
|
// and put it into the crmetadata.CheckpointDirectory directory.
|
||||||
|
if err := os.MkdirAll(checkpointDirectory, 0o700); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tr := tar.NewReader(content.NewReader(ra))
|
||||||
|
for {
|
||||||
|
header, err := tr.Next()
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, io.EOF) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if strings.Contains(header.Name, "..") {
|
||||||
|
return fmt.Errorf("found illegal string '..' in checkpoint archive")
|
||||||
|
}
|
||||||
|
destFile, err := os.Create(filepath.Join(checkpointDirectory, header.Name))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer destFile.Close()
|
||||||
|
|
||||||
|
_, err = io.CopyN(destFile, tr, header.Size)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeRootFsDiffTar(ctx context.Context, store content.Store, desc v1.Descriptor, cpPath string) error {
|
||||||
|
ra, err := store.ReaderAt(ctx, desc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer ra.Close()
|
||||||
|
|
||||||
|
// the rw layer tarball
|
||||||
|
f, err := os.Create(filepath.Join(cpPath, crmetadata.RootFsDiffTar))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(f, content.NewReader(ra))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeSpecDumpFile(ctx context.Context, store content.Store, desc v1.Descriptor, cpPath string) error {
|
||||||
|
// this is the container spec
|
||||||
|
f, err := os.Create(filepath.Join(cpPath, crmetadata.SpecDumpFile))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
data, err := content.ReadBlob(ctx, store, desc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var any ptypes.Any
|
||||||
|
if err := proto.Unmarshal(data, &any); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = f.Write(any.Value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -35,6 +35,7 @@ var (
|
|||||||
containerStopTimer metrics.LabeledTimer
|
containerStopTimer metrics.LabeledTimer
|
||||||
containerStartTimer metrics.LabeledTimer
|
containerStartTimer metrics.LabeledTimer
|
||||||
containerEventsDroppedCount metrics.Counter
|
containerEventsDroppedCount metrics.Counter
|
||||||
|
containerCheckpointTimer metrics.LabeledTimer
|
||||||
|
|
||||||
networkPluginOperations metrics.LabeledCounter
|
networkPluginOperations metrics.LabeledCounter
|
||||||
networkPluginOperationsErrors metrics.LabeledCounter
|
networkPluginOperationsErrors metrics.LabeledCounter
|
||||||
@ -59,6 +60,7 @@ func init() {
|
|||||||
containerStopTimer = ns.NewLabeledTimer("container_stop", "time to stop a container", "runtime")
|
containerStopTimer = ns.NewLabeledTimer("container_stop", "time to stop a container", "runtime")
|
||||||
containerStartTimer = ns.NewLabeledTimer("container_start", "time to start a container", "runtime")
|
containerStartTimer = ns.NewLabeledTimer("container_start", "time to start a container", "runtime")
|
||||||
containerEventsDroppedCount = ns.NewCounter("container_events_dropped", "count container discarding event total from server start")
|
containerEventsDroppedCount = ns.NewCounter("container_events_dropped", "count container discarding event total from server start")
|
||||||
|
containerCheckpointTimer = ns.NewLabeledTimer("container_checkpoint", "time to checkpoint a container", "runtime")
|
||||||
|
|
||||||
networkPluginOperations = ns.NewLabeledCounter("network_plugin_operations_total", "cumulative number of network plugin operations by operation type", "operation_type")
|
networkPluginOperations = ns.NewLabeledCounter("network_plugin_operations_total", "cumulative number of network plugin operations by operation type", "operation_type")
|
||||||
networkPluginOperationsErrors = ns.NewLabeledCounter("network_plugin_operations_errors_total", "cumulative number of network plugin operations by operation type", "operation_type")
|
networkPluginOperationsErrors = ns.NewLabeledCounter("network_plugin_operations_errors_total", "cumulative number of network plugin operations by operation type", "operation_type")
|
||||||
|
201
vendor/github.com/checkpoint-restore/checkpointctl/LICENSE
generated
vendored
Normal file
201
vendor/github.com/checkpoint-restore/checkpointctl/LICENSE
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
145
vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata.go
generated
vendored
Normal file
145
vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata.go
generated
vendored
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// container archive
|
||||||
|
ConfigDumpFile = "config.dump"
|
||||||
|
SpecDumpFile = "spec.dump"
|
||||||
|
NetworkStatusFile = "network.status"
|
||||||
|
CheckpointDirectory = "checkpoint"
|
||||||
|
CheckpointVolumesDirectory = "volumes"
|
||||||
|
DevShmCheckpointTar = "devshm-checkpoint.tar"
|
||||||
|
RootFsDiffTar = "rootfs-diff.tar"
|
||||||
|
DeletedFilesFile = "deleted.files"
|
||||||
|
DumpLogFile = "dump.log"
|
||||||
|
RestoreLogFile = "restore.log"
|
||||||
|
// pod archive
|
||||||
|
PodOptionsFile = "pod.options"
|
||||||
|
PodDumpFile = "pod.dump"
|
||||||
|
// containerd only
|
||||||
|
StatusFile = "status"
|
||||||
|
// CRIU Images
|
||||||
|
PagesPrefix = "pages-"
|
||||||
|
AmdgpuPagesPrefix = "amdgpu-pages-"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This is a reduced copy of what Podman uses to store checkpoint metadata
|
||||||
|
type ContainerConfig struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
RootfsImage string `json:"rootfsImage,omitempty"`
|
||||||
|
RootfsImageRef string `json:"rootfsImageRef,omitempty"`
|
||||||
|
RootfsImageName string `json:"rootfsImageName,omitempty"`
|
||||||
|
OCIRuntime string `json:"runtime,omitempty"`
|
||||||
|
CreatedTime time.Time `json:"createdTime"`
|
||||||
|
CheckpointedAt time.Time `json:"checkpointedTime"`
|
||||||
|
RestoredAt time.Time `json:"restoredTime"`
|
||||||
|
Restored bool `json:"restored"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ContainerdStatus struct {
|
||||||
|
CreatedAt int64
|
||||||
|
StartedAt int64
|
||||||
|
FinishedAt int64
|
||||||
|
ExitCode int32
|
||||||
|
Pid uint32
|
||||||
|
Reason string
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
// This structure is used by the KubernetesContainerCheckpointMetadata structure
|
||||||
|
type KubernetesCheckpoint struct {
|
||||||
|
Archive string `json:"archive,omitempty"`
|
||||||
|
Size int64 `json:"size,omitempty"`
|
||||||
|
Timestamp int64 `json:"timestamp,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// This structure is the basis for Kubernetes to track how many checkpoints
|
||||||
|
// for a certain container have been created.
|
||||||
|
type KubernetesContainerCheckpointMetadata struct {
|
||||||
|
PodFullName string `json:"podFullName,omitempty"`
|
||||||
|
ContainerName string `json:"containerName,omitempty"`
|
||||||
|
TotalSize int64 `json:"totalSize,omitempty"`
|
||||||
|
Checkpoints []KubernetesCheckpoint `json:"checkpoints"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadContainerCheckpointSpecDump(checkpointDirectory string) (*spec.Spec, string, error) {
|
||||||
|
var specDump spec.Spec
|
||||||
|
specDumpFile, err := ReadJSONFile(&specDump, checkpointDirectory, SpecDumpFile)
|
||||||
|
|
||||||
|
return &specDump, specDumpFile, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadContainerCheckpointConfigDump(checkpointDirectory string) (*ContainerConfig, string, error) {
|
||||||
|
var containerConfig ContainerConfig
|
||||||
|
configDumpFile, err := ReadJSONFile(&containerConfig, checkpointDirectory, ConfigDumpFile)
|
||||||
|
|
||||||
|
return &containerConfig, configDumpFile, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadContainerCheckpointDeletedFiles(checkpointDirectory string) ([]string, string, error) {
|
||||||
|
var deletedFiles []string
|
||||||
|
deletedFilesFile, err := ReadJSONFile(&deletedFiles, checkpointDirectory, DeletedFilesFile)
|
||||||
|
|
||||||
|
return deletedFiles, deletedFilesFile, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadContainerCheckpointStatusFile(checkpointDirectory string) (*ContainerdStatus, string, error) {
|
||||||
|
var containerdStatus ContainerdStatus
|
||||||
|
statusFile, err := ReadJSONFile(&containerdStatus, checkpointDirectory, StatusFile)
|
||||||
|
|
||||||
|
return &containerdStatus, statusFile, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteJSONFile marshalls and writes the given data to a JSON file
|
||||||
|
func WriteJSONFile(v interface{}, dir, file string) (string, error) {
|
||||||
|
fileJSON, err := json.MarshalIndent(v, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error marshalling JSON: %w", err)
|
||||||
|
}
|
||||||
|
file = filepath.Join(dir, file)
|
||||||
|
if err := os.WriteFile(file, fileJSON, 0o600); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadJSONFile(v interface{}, dir, file string) (string, error) {
|
||||||
|
file = filepath.Join(dir, file)
|
||||||
|
content, err := os.ReadFile(file)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err = json.Unmarshal(content, v); err != nil {
|
||||||
|
return "", fmt.Errorf("failed to unmarshal %s: %w", file, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ByteToString(b int64) string {
|
||||||
|
const unit = 1024
|
||||||
|
if b < unit {
|
||||||
|
return fmt.Sprintf("%d B", b)
|
||||||
|
}
|
||||||
|
div, exp := int64(unit), 0
|
||||||
|
for n := b / unit; n >= unit; n /= unit {
|
||||||
|
div *= unit
|
||||||
|
exp++
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%.1f %ciB",
|
||||||
|
float64(b)/float64(div), "KMGTPE"[exp])
|
||||||
|
}
|
17
vendor/github.com/checkpoint-restore/go-criu/v7/.gitignore
generated
vendored
Normal file
17
vendor/github.com/checkpoint-restore/go-criu/v7/.gitignore
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
test/test
|
||||||
|
test/test.coverage
|
||||||
|
test/piggie/piggie
|
||||||
|
test/phaul/phaul
|
||||||
|
test/phaul/phaul.coverage
|
||||||
|
test/loop/loop
|
||||||
|
test/mmapper/mmapper
|
||||||
|
test/crit/crit-test
|
||||||
|
test/crit/test-imgs
|
||||||
|
test/crit/crit-test.coverage
|
||||||
|
test/.coverage/
|
||||||
|
image
|
||||||
|
scripts/magic-gen/*.h
|
||||||
|
scripts/magic-gen/expected.go
|
||||||
|
scripts/magic-gen/output.go
|
||||||
|
crit/bin
|
||||||
|
crit/test-imgs/
|
18
vendor/github.com/checkpoint-restore/go-criu/v7/.golangci.yml
generated
vendored
Normal file
18
vendor/github.com/checkpoint-restore/go-criu/v7/.golangci.yml
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
linters:
|
||||||
|
presets:
|
||||||
|
- bugs
|
||||||
|
- performance
|
||||||
|
- unused
|
||||||
|
- format
|
||||||
|
disable:
|
||||||
|
- musttag
|
||||||
|
enable:
|
||||||
|
- whitespace
|
||||||
|
- misspell
|
||||||
|
- dupl
|
||||||
|
- gosimple
|
||||||
|
- stylecheck
|
||||||
|
|
||||||
|
linters-settings:
|
||||||
|
exhaustive:
|
||||||
|
default-signifies-exhaustive: true
|
201
vendor/github.com/checkpoint-restore/go-criu/v7/LICENSE
generated
vendored
Normal file
201
vendor/github.com/checkpoint-restore/go-criu/v7/LICENSE
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
4
vendor/github.com/checkpoint-restore/go-criu/v7/MAINTAINERS
generated
vendored
Normal file
4
vendor/github.com/checkpoint-restore/go-criu/v7/MAINTAINERS
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Adrian Reber <areber@redhat.com>
|
||||||
|
Kir Kolyshkin <kolyshkin@gmail.com>
|
||||||
|
Prajwal S N <prajwalnadig21@gmail.com>
|
||||||
|
Radostin Stoyanov <rstoyanov@fedoraproject.org>
|
45
vendor/github.com/checkpoint-restore/go-criu/v7/Makefile
generated
vendored
Normal file
45
vendor/github.com/checkpoint-restore/go-criu/v7/Makefile
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
SHELL = /bin/bash
|
||||||
|
GO ?= go
|
||||||
|
CC ?= gcc
|
||||||
|
|
||||||
|
all: build
|
||||||
|
|
||||||
|
lint:
|
||||||
|
golangci-lint run ./...
|
||||||
|
|
||||||
|
build: rpc/rpc.pb.go stats/stats.pb.go
|
||||||
|
$(GO) build -v ./...
|
||||||
|
# Build crit binary
|
||||||
|
$(MAKE) -C crit bin/crit
|
||||||
|
|
||||||
|
test: build
|
||||||
|
$(MAKE) -C test
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
$(MAKE) -C test coverage
|
||||||
|
|
||||||
|
codecov:
|
||||||
|
$(MAKE) -C test codecov
|
||||||
|
|
||||||
|
rpc/rpc.proto:
|
||||||
|
curl -sSL https://raw.githubusercontent.com/checkpoint-restore/criu/master/images/rpc.proto -o $@
|
||||||
|
|
||||||
|
rpc/rpc.pb.go: rpc/rpc.proto
|
||||||
|
protoc --go_out=. --go_opt=M$^=rpc/ $^
|
||||||
|
|
||||||
|
stats/stats.proto:
|
||||||
|
curl -sSL https://raw.githubusercontent.com/checkpoint-restore/criu/master/images/stats.proto -o $@
|
||||||
|
|
||||||
|
stats/stats.pb.go: stats/stats.proto
|
||||||
|
protoc --go_out=. --go_opt=M$^=stats/ $^
|
||||||
|
|
||||||
|
vendor:
|
||||||
|
$(GO) mod tidy
|
||||||
|
$(GO) mod vendor
|
||||||
|
$(GO) mod verify
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C crit/ clean
|
||||||
|
$(MAKE) -C test/ clean
|
||||||
|
|
||||||
|
.PHONY: build test lint vendor coverage codecov clean
|
111
vendor/github.com/checkpoint-restore/go-criu/v7/README.md
generated
vendored
Normal file
111
vendor/github.com/checkpoint-restore/go-criu/v7/README.md
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<!-- markdownlint-configure-file { "no-hard-tabs": { "code_blocks": false } } -->
|
||||||
|
# go-criu -- Go bindings for CRIU
|
||||||
|
|
||||||
|
[](https://github.com/checkpoint-restore/go-criu/actions?query=workflow%3Aci)
|
||||||
|
[](https://github.com/checkpoint-restore/go-criu/actions?query=workflow%3Averify)
|
||||||
|
[](https://pkg.go.dev/github.com/checkpoint-restore/go-criu)
|
||||||
|
|
||||||
|
This repository provides Go bindings for [CRIU](https://criu.org/).
|
||||||
|
The code is based on the Go-based PHaul implementation from the CRIU repository.
|
||||||
|
For easier inclusion into other Go projects, the CRIU Go bindings have been
|
||||||
|
moved to this repository.
|
||||||
|
|
||||||
|
## CRIU
|
||||||
|
|
||||||
|
The Go bindings provide an easy way to use the CRIU RPC calls from Go without
|
||||||
|
the need to set up all the infrastructure to make the actual RPC connection to CRIU.
|
||||||
|
|
||||||
|
The following example would print the version of CRIU:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/checkpoint-restore/go-criu/v7"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c := criu.MakeCriu()
|
||||||
|
version, err := c.GetCriuVersion()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
log.Println(version)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
or to just check if at least a certain CRIU version is installed:
|
||||||
|
|
||||||
|
```go
|
||||||
|
c := criu.MakeCriu()
|
||||||
|
result, err := c.IsCriuAtLeast(31100)
|
||||||
|
```
|
||||||
|
|
||||||
|
## CRIT
|
||||||
|
|
||||||
|
The `crit` package provides bindings to decode, encode, and manipulate
|
||||||
|
CRIU image files natively within Go. It also provides a CLI tool similar
|
||||||
|
to the original CRIT Python tool. To get started with this, see the docs
|
||||||
|
at [CRIT (Go library)](https://criu.org/CRIT_%28Go_library%29).
|
||||||
|
|
||||||
|
## Releases
|
||||||
|
|
||||||
|
The first go-criu release was 3.11 based on CRIU 3.11. The initial plan
|
||||||
|
was to follow CRIU so that go-criu would carry the same version number as
|
||||||
|
CRIU.
|
||||||
|
|
||||||
|
As go-criu is imported in other projects and as Go modules are expected
|
||||||
|
to follow Semantic Versioning go-criu will also follow Semantic Versioning
|
||||||
|
starting with the 4.0.0 release.
|
||||||
|
|
||||||
|
The following table shows the relation between go-criu and criu versions:
|
||||||
|
|
||||||
|
| Major version | Latest release | CRIU version |
|
||||||
|
| -------------- | -------------- | ------------ |
|
||||||
|
| v7 | 7.0.0 | 3.18 |
|
||||||
|
| v6 | 6.3.0 | 3.17 |
|
||||||
|
| v5 | 5.3.0 | 3.16 |
|
||||||
|
| v5 | 5.0.0 | 3.15 |
|
||||||
|
| v4 | 4.1.0 | 3.14 |
|
||||||
|
|
||||||
|
## How to contribute
|
||||||
|
|
||||||
|
While bug fixes can first be identified via an "issue", that is not required.
|
||||||
|
It's ok to just open up a PR with the fix, but make sure you include the same
|
||||||
|
information you would have included in an issue - like how to reproduce it.
|
||||||
|
|
||||||
|
PRs for new features should include some background on what use cases the
|
||||||
|
new code is trying to address. When possible and when it makes sense, try to
|
||||||
|
break-up larger PRs into smaller ones - it's easier to review smaller
|
||||||
|
code changes. But only if those smaller ones make sense as stand-alone PRs.
|
||||||
|
|
||||||
|
Regardless of the type of PR, all PRs should include:
|
||||||
|
|
||||||
|
* well documented code changes
|
||||||
|
* additional testcases. Ideally, they should fail w/o your code change applied
|
||||||
|
* documentation changes
|
||||||
|
|
||||||
|
Squash your commits into logical pieces of work that might want to be reviewed
|
||||||
|
separate from the rest of the PRs. Ideally, each commit should implement a
|
||||||
|
single idea, and the PR branch should pass the tests at every commit. GitHub
|
||||||
|
makes it easy to review the cumulative effect of many commits; so, when in
|
||||||
|
doubt, use smaller commits.
|
||||||
|
|
||||||
|
PRs that fix issues should include a reference like `Closes #XXXX` in the
|
||||||
|
commit message so that github will automatically close the referenced issue
|
||||||
|
when the PR is merged.
|
||||||
|
|
||||||
|
Contributors must assert that they are in compliance with the [Developer
|
||||||
|
Certificate of Origin 1.1](http://developercertificate.org/). This is achieved
|
||||||
|
by adding a "Signed-off-by" line containing the contributor's name and e-mail
|
||||||
|
to every commit message. Your signature certifies that you wrote the patch or
|
||||||
|
otherwise have the right to pass it on as an open-source patch.
|
||||||
|
|
||||||
|
## License and copyright
|
||||||
|
|
||||||
|
Unless mentioned otherwise in a specific file's header, all code in
|
||||||
|
this project is released under the Apache 2.0 license.
|
||||||
|
|
||||||
|
The author of a change remains the copyright holder of their code
|
||||||
|
(no copyright assignment). The list of authors and contributors can be
|
||||||
|
retrieved from the git commit history and in some cases, the file headers.
|
45
vendor/github.com/checkpoint-restore/go-criu/v7/features.go
generated
vendored
Normal file
45
vendor/github.com/checkpoint-restore/go-criu/v7/features.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package criu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/checkpoint-restore/go-criu/v7/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Feature checking in go-criu is based on the libcriu feature checking function.
|
||||||
|
|
||||||
|
// Feature checking allows the user to check if CRIU supports
|
||||||
|
// certain features. There are CRIU features which do not depend
|
||||||
|
// on the version of CRIU but on kernel features or architecture.
|
||||||
|
//
|
||||||
|
// One example is memory tracking. Memory tracking can be disabled
|
||||||
|
// in the kernel or there are architectures which do not support
|
||||||
|
// it (aarch64 for example). By using the feature check a libcriu
|
||||||
|
// user can easily query CRIU if a certain feature is available.
|
||||||
|
//
|
||||||
|
// The features which should be checked can be marked in the
|
||||||
|
// structure 'struct criu_feature_check'. Each structure member
|
||||||
|
// that is set to true will result in CRIU checking for the
|
||||||
|
// availability of that feature in the current combination of
|
||||||
|
// CRIU/kernel/architecture.
|
||||||
|
//
|
||||||
|
// Available features will be set to true when the function
|
||||||
|
// returns successfully. Missing features will be set to false.
|
||||||
|
|
||||||
|
func (c *Criu) FeatureCheck(features *rpc.CriuFeatures) (*rpc.CriuFeatures, error) {
|
||||||
|
resp, err := c.doSwrkWithResp(
|
||||||
|
rpc.CriuReqType_FEATURE_CHECK,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
features,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.GetType() != rpc.CriuReqType_FEATURE_CHECK {
|
||||||
|
return nil, fmt.Errorf("unexpected CRIU RPC response")
|
||||||
|
}
|
||||||
|
|
||||||
|
return features, nil
|
||||||
|
}
|
264
vendor/github.com/checkpoint-restore/go-criu/v7/main.go
generated
vendored
Normal file
264
vendor/github.com/checkpoint-restore/go-criu/v7/main.go
generated
vendored
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
package criu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/checkpoint-restore/go-criu/v7/rpc"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Criu struct
|
||||||
|
type Criu struct {
|
||||||
|
swrkCmd *exec.Cmd
|
||||||
|
swrkSk *os.File
|
||||||
|
swrkPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeCriu returns the Criu object required for most operations
|
||||||
|
func MakeCriu() *Criu {
|
||||||
|
return &Criu{
|
||||||
|
swrkPath: "criu",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCriuPath allows setting the path to the CRIU binary
|
||||||
|
// if it is in a non standard location
|
||||||
|
func (c *Criu) SetCriuPath(path string) {
|
||||||
|
c.swrkPath = path
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare sets up everything for the RPC communication to CRIU
|
||||||
|
func (c *Criu) Prepare() error {
|
||||||
|
fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_SEQPACKET, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cln := os.NewFile(uintptr(fds[0]), "criu-xprt-cln")
|
||||||
|
syscall.CloseOnExec(fds[0])
|
||||||
|
srv := os.NewFile(uintptr(fds[1]), "criu-xprt-srv")
|
||||||
|
defer srv.Close()
|
||||||
|
|
||||||
|
args := []string{"swrk", strconv.Itoa(fds[1])}
|
||||||
|
// #nosec G204
|
||||||
|
cmd := exec.Command(c.swrkPath, args...)
|
||||||
|
|
||||||
|
err = cmd.Start()
|
||||||
|
if err != nil {
|
||||||
|
cln.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.swrkCmd = cmd
|
||||||
|
c.swrkSk = cln
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup cleans up
|
||||||
|
func (c *Criu) Cleanup() {
|
||||||
|
if c.swrkCmd != nil {
|
||||||
|
c.swrkSk.Close()
|
||||||
|
c.swrkSk = nil
|
||||||
|
_ = c.swrkCmd.Wait()
|
||||||
|
c.swrkCmd = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Criu) sendAndRecv(reqB []byte) ([]byte, int, error) {
|
||||||
|
cln := c.swrkSk
|
||||||
|
_, err := cln.Write(reqB)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
respB := make([]byte, 2*4096)
|
||||||
|
n, err := cln.Read(respB)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return respB, n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Criu) doSwrk(reqType rpc.CriuReqType, opts *rpc.CriuOpts, nfy Notify) error {
|
||||||
|
resp, err := c.doSwrkWithResp(reqType, opts, nfy, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
respType := resp.GetType()
|
||||||
|
if respType != reqType {
|
||||||
|
return errors.New("unexpected CRIU RPC response")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Criu) doSwrkWithResp(reqType rpc.CriuReqType, opts *rpc.CriuOpts, nfy Notify, features *rpc.CriuFeatures) (*rpc.CriuResp, error) {
|
||||||
|
var resp *rpc.CriuResp
|
||||||
|
|
||||||
|
req := rpc.CriuReq{
|
||||||
|
Type: &reqType,
|
||||||
|
Opts: opts,
|
||||||
|
}
|
||||||
|
|
||||||
|
if nfy != nil {
|
||||||
|
opts.NotifyScripts = proto.Bool(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if features != nil {
|
||||||
|
req.Features = features
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.swrkCmd == nil {
|
||||||
|
err := c.Prepare()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer c.Cleanup()
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
reqB, err := proto.Marshal(&req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
respB, respS, err := c.sendAndRecv(reqB)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp = &rpc.CriuResp{}
|
||||||
|
err = proto.Unmarshal(respB[:respS], resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !resp.GetSuccess() {
|
||||||
|
return resp, fmt.Errorf("operation failed (msg:%s err:%d)",
|
||||||
|
resp.GetCrErrmsg(), resp.GetCrErrno())
|
||||||
|
}
|
||||||
|
|
||||||
|
respType := resp.GetType()
|
||||||
|
if respType != rpc.CriuReqType_NOTIFY {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if nfy == nil {
|
||||||
|
return resp, errors.New("unexpected notify")
|
||||||
|
}
|
||||||
|
|
||||||
|
notify := resp.GetNotify()
|
||||||
|
switch notify.GetScript() {
|
||||||
|
case "pre-dump":
|
||||||
|
err = nfy.PreDump()
|
||||||
|
case "post-dump":
|
||||||
|
err = nfy.PostDump()
|
||||||
|
case "pre-restore":
|
||||||
|
err = nfy.PreRestore()
|
||||||
|
case "post-restore":
|
||||||
|
err = nfy.PostRestore(notify.GetPid())
|
||||||
|
case "network-lock":
|
||||||
|
err = nfy.NetworkLock()
|
||||||
|
case "network-unlock":
|
||||||
|
err = nfy.NetworkUnlock()
|
||||||
|
case "setup-namespaces":
|
||||||
|
err = nfy.SetupNamespaces(notify.GetPid())
|
||||||
|
case "post-setup-namespaces":
|
||||||
|
err = nfy.PostSetupNamespaces()
|
||||||
|
case "post-resume":
|
||||||
|
err = nfy.PostResume()
|
||||||
|
default:
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req = rpc.CriuReq{
|
||||||
|
Type: &respType,
|
||||||
|
NotifySuccess: proto.Bool(true),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump dumps a process
|
||||||
|
func (c *Criu) Dump(opts *rpc.CriuOpts, nfy Notify) error {
|
||||||
|
return c.doSwrk(rpc.CriuReqType_DUMP, opts, nfy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore restores a process
|
||||||
|
func (c *Criu) Restore(opts *rpc.CriuOpts, nfy Notify) error {
|
||||||
|
return c.doSwrk(rpc.CriuReqType_RESTORE, opts, nfy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PreDump does a pre-dump
|
||||||
|
func (c *Criu) PreDump(opts *rpc.CriuOpts, nfy Notify) error {
|
||||||
|
return c.doSwrk(rpc.CriuReqType_PRE_DUMP, opts, nfy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartPageServer starts the page server
|
||||||
|
func (c *Criu) StartPageServer(opts *rpc.CriuOpts) error {
|
||||||
|
return c.doSwrk(rpc.CriuReqType_PAGE_SERVER, opts, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartPageServerChld starts the page server and returns PID and port
|
||||||
|
func (c *Criu) StartPageServerChld(opts *rpc.CriuOpts) (int, int, error) {
|
||||||
|
resp, err := c.doSwrkWithResp(rpc.CriuReqType_PAGE_SERVER_CHLD, opts, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(resp.Ps.GetPid()), int(resp.Ps.GetPort()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCriuVersion executes the VERSION RPC call and returns the version
|
||||||
|
// as an integer. Major * 10000 + Minor * 100 + SubLevel
|
||||||
|
func (c *Criu) GetCriuVersion() (int, error) {
|
||||||
|
resp, err := c.doSwrkWithResp(rpc.CriuReqType_VERSION, nil, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.GetType() != rpc.CriuReqType_VERSION {
|
||||||
|
return 0, fmt.Errorf("unexpected CRIU RPC response")
|
||||||
|
}
|
||||||
|
|
||||||
|
version := int(*resp.GetVersion().MajorNumber) * 10000
|
||||||
|
version += int(*resp.GetVersion().MinorNumber) * 100
|
||||||
|
if resp.GetVersion().Sublevel != nil {
|
||||||
|
version += int(*resp.GetVersion().Sublevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.GetVersion().Gitid != nil {
|
||||||
|
// taken from runc: if it is a git release -> increase minor by 1
|
||||||
|
version -= (version % 100)
|
||||||
|
version += 100
|
||||||
|
}
|
||||||
|
|
||||||
|
return version, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCriuAtLeast checks if the version is at least the same
|
||||||
|
// as the parameter version
|
||||||
|
func (c *Criu) IsCriuAtLeast(version int) (bool, error) {
|
||||||
|
criuVersion, err := c.GetCriuVersion()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if criuVersion >= version {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
62
vendor/github.com/checkpoint-restore/go-criu/v7/notify.go
generated
vendored
Normal file
62
vendor/github.com/checkpoint-restore/go-criu/v7/notify.go
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package criu
|
||||||
|
|
||||||
|
// Notify interface
|
||||||
|
type Notify interface {
|
||||||
|
PreDump() error
|
||||||
|
PostDump() error
|
||||||
|
PreRestore() error
|
||||||
|
PostRestore(pid int32) error
|
||||||
|
NetworkLock() error
|
||||||
|
NetworkUnlock() error
|
||||||
|
SetupNamespaces(pid int32) error
|
||||||
|
PostSetupNamespaces() error
|
||||||
|
PostResume() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoNotify struct
|
||||||
|
type NoNotify struct{}
|
||||||
|
|
||||||
|
// PreDump NoNotify
|
||||||
|
func (c NoNotify) PreDump() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostDump NoNotify
|
||||||
|
func (c NoNotify) PostDump() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PreRestore NoNotify
|
||||||
|
func (c NoNotify) PreRestore() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostRestore NoNotify
|
||||||
|
func (c NoNotify) PostRestore(pid int32) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkLock NoNotify
|
||||||
|
func (c NoNotify) NetworkLock() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkUnlock NoNotify
|
||||||
|
func (c NoNotify) NetworkUnlock() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetupNamespaces NoNotify
|
||||||
|
func (c NoNotify) SetupNamespaces(pid int32) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostSetupNamespaces NoNotify
|
||||||
|
func (c NoNotify) PostSetupNamespaces() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostResume NoNotify
|
||||||
|
func (c NoNotify) PostResume() error {
|
||||||
|
return nil
|
||||||
|
}
|
2390
vendor/github.com/checkpoint-restore/go-criu/v7/rpc/rpc.pb.go
generated
vendored
Normal file
2390
vendor/github.com/checkpoint-restore/go-criu/v7/rpc/rpc.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
255
vendor/github.com/checkpoint-restore/go-criu/v7/rpc/rpc.proto
generated
vendored
Normal file
255
vendor/github.com/checkpoint-restore/go-criu/v7/rpc/rpc.proto
generated
vendored
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
message criu_page_server_info {
|
||||||
|
optional string address = 1;
|
||||||
|
optional int32 port = 2;
|
||||||
|
optional int32 pid = 3;
|
||||||
|
optional int32 fd = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message criu_veth_pair {
|
||||||
|
required string if_in = 1;
|
||||||
|
required string if_out = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
message ext_mount_map {
|
||||||
|
required string key = 1;
|
||||||
|
required string val = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
message join_namespace {
|
||||||
|
required string ns = 1;
|
||||||
|
required string ns_file = 2;
|
||||||
|
optional string extra_opt = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message inherit_fd {
|
||||||
|
required string key = 1;
|
||||||
|
required int32 fd = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
message cgroup_root {
|
||||||
|
optional string ctrl = 1;
|
||||||
|
required string path = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
message unix_sk {
|
||||||
|
required uint32 inode = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum criu_cg_mode {
|
||||||
|
IGNORE = 0;
|
||||||
|
CG_NONE = 1;
|
||||||
|
PROPS = 2;
|
||||||
|
SOFT = 3;
|
||||||
|
FULL = 4;
|
||||||
|
STRICT = 5;
|
||||||
|
DEFAULT = 6;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum criu_network_lock_method {
|
||||||
|
IPTABLES = 1;
|
||||||
|
NFTABLES = 2;
|
||||||
|
SKIP = 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum criu_pre_dump_mode {
|
||||||
|
SPLICE = 1;
|
||||||
|
VM_READ = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
message criu_opts {
|
||||||
|
required int32 images_dir_fd = 1 [default = -1];
|
||||||
|
optional string images_dir = 68; /* used only if images_dir_fd == -1 */
|
||||||
|
optional int32 pid = 2; /* if not set on dump, will dump requesting process */
|
||||||
|
|
||||||
|
optional bool leave_running = 3;
|
||||||
|
optional bool ext_unix_sk = 4;
|
||||||
|
optional bool tcp_established = 5;
|
||||||
|
optional bool evasive_devices = 6;
|
||||||
|
optional bool shell_job = 7;
|
||||||
|
optional bool file_locks = 8;
|
||||||
|
optional int32 log_level = 9 [default = 2];
|
||||||
|
optional string log_file = 10; /* No subdirs are allowed. Consider using work-dir */
|
||||||
|
|
||||||
|
optional criu_page_server_info ps = 11;
|
||||||
|
|
||||||
|
optional bool notify_scripts = 12;
|
||||||
|
|
||||||
|
optional string root = 13;
|
||||||
|
optional string parent_img = 14;
|
||||||
|
optional bool track_mem = 15;
|
||||||
|
optional bool auto_dedup = 16;
|
||||||
|
|
||||||
|
optional int32 work_dir_fd = 17;
|
||||||
|
optional bool link_remap = 18;
|
||||||
|
repeated criu_veth_pair veths = 19; /* DEPRECATED, use external instead */
|
||||||
|
|
||||||
|
optional uint32 cpu_cap = 20 [default = 0xffffffff];
|
||||||
|
optional bool force_irmap = 21;
|
||||||
|
repeated string exec_cmd = 22;
|
||||||
|
|
||||||
|
repeated ext_mount_map ext_mnt = 23; /* DEPRECATED, use external instead */
|
||||||
|
optional bool manage_cgroups = 24; /* backward compatibility */
|
||||||
|
repeated cgroup_root cg_root = 25;
|
||||||
|
|
||||||
|
optional bool rst_sibling = 26; /* swrk only */
|
||||||
|
repeated inherit_fd inherit_fd = 27; /* swrk only */
|
||||||
|
|
||||||
|
optional bool auto_ext_mnt = 28;
|
||||||
|
optional bool ext_sharing = 29;
|
||||||
|
optional bool ext_masters = 30;
|
||||||
|
|
||||||
|
repeated string skip_mnt = 31;
|
||||||
|
repeated string enable_fs = 32;
|
||||||
|
|
||||||
|
repeated unix_sk unix_sk_ino = 33; /* DEPRECATED, use external instead */
|
||||||
|
|
||||||
|
optional criu_cg_mode manage_cgroups_mode = 34;
|
||||||
|
optional uint32 ghost_limit = 35 [default = 0x100000];
|
||||||
|
repeated string irmap_scan_paths = 36;
|
||||||
|
repeated string external = 37;
|
||||||
|
optional uint32 empty_ns = 38;
|
||||||
|
repeated join_namespace join_ns = 39;
|
||||||
|
|
||||||
|
optional string cgroup_props = 41;
|
||||||
|
optional string cgroup_props_file = 42;
|
||||||
|
repeated string cgroup_dump_controller = 43;
|
||||||
|
|
||||||
|
optional string freeze_cgroup = 44;
|
||||||
|
optional uint32 timeout = 45;
|
||||||
|
optional bool tcp_skip_in_flight = 46;
|
||||||
|
optional bool weak_sysctls = 47;
|
||||||
|
optional bool lazy_pages = 48;
|
||||||
|
optional int32 status_fd = 49;
|
||||||
|
optional bool orphan_pts_master = 50;
|
||||||
|
optional string config_file = 51;
|
||||||
|
optional bool tcp_close = 52;
|
||||||
|
optional string lsm_profile = 53;
|
||||||
|
optional string tls_cacert = 54;
|
||||||
|
optional string tls_cacrl = 55;
|
||||||
|
optional string tls_cert = 56;
|
||||||
|
optional string tls_key = 57;
|
||||||
|
optional bool tls = 58;
|
||||||
|
optional bool tls_no_cn_verify = 59;
|
||||||
|
optional string cgroup_yard = 60;
|
||||||
|
optional criu_pre_dump_mode pre_dump_mode = 61 [default = SPLICE];
|
||||||
|
optional int32 pidfd_store_sk = 62;
|
||||||
|
optional string lsm_mount_context = 63;
|
||||||
|
optional criu_network_lock_method network_lock = 64 [default = IPTABLES];
|
||||||
|
optional bool mntns_compat_mode = 65;
|
||||||
|
optional bool skip_file_rwx_check = 66;
|
||||||
|
optional bool unprivileged = 67;
|
||||||
|
optional bool leave_stopped = 69;
|
||||||
|
optional bool display_stats = 70;
|
||||||
|
optional bool log_to_stderr = 71;
|
||||||
|
/* optional bool check_mounts = 128; */
|
||||||
|
}
|
||||||
|
|
||||||
|
message criu_dump_resp {
|
||||||
|
optional bool restored = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message criu_restore_resp {
|
||||||
|
required int32 pid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message criu_notify {
|
||||||
|
optional string script = 1;
|
||||||
|
optional int32 pid = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum criu_req_type {
|
||||||
|
EMPTY = 0;
|
||||||
|
DUMP = 1;
|
||||||
|
RESTORE = 2;
|
||||||
|
CHECK = 3;
|
||||||
|
PRE_DUMP = 4;
|
||||||
|
PAGE_SERVER = 5;
|
||||||
|
|
||||||
|
NOTIFY = 6;
|
||||||
|
|
||||||
|
CPUINFO_DUMP = 7;
|
||||||
|
CPUINFO_CHECK = 8;
|
||||||
|
|
||||||
|
FEATURE_CHECK = 9;
|
||||||
|
|
||||||
|
VERSION = 10;
|
||||||
|
|
||||||
|
WAIT_PID = 11;
|
||||||
|
PAGE_SERVER_CHLD = 12;
|
||||||
|
|
||||||
|
SINGLE_PRE_DUMP = 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List of features which can queried via
|
||||||
|
* CRIU_REQ_TYPE__FEATURE_CHECK
|
||||||
|
*/
|
||||||
|
message criu_features {
|
||||||
|
optional bool mem_track = 1;
|
||||||
|
optional bool lazy_pages = 2;
|
||||||
|
optional bool pidfd_store = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Request -- each type corresponds to must-be-there
|
||||||
|
* request arguments of respective type
|
||||||
|
*/
|
||||||
|
|
||||||
|
message criu_req {
|
||||||
|
required criu_req_type type = 1;
|
||||||
|
|
||||||
|
optional criu_opts opts = 2;
|
||||||
|
optional bool notify_success = 3;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When set service won't close the connection but
|
||||||
|
* will wait for more req-s to appear. Works not
|
||||||
|
* for all request types.
|
||||||
|
*/
|
||||||
|
optional bool keep_open = 4;
|
||||||
|
/*
|
||||||
|
* 'features' can be used to query which features
|
||||||
|
* are supported by the installed criu/kernel
|
||||||
|
* via RPC.
|
||||||
|
*/
|
||||||
|
optional criu_features features = 5;
|
||||||
|
|
||||||
|
/* 'pid' is used for WAIT_PID */
|
||||||
|
optional uint32 pid = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Response -- it states whether the request was served
|
||||||
|
* and additional request-specific information
|
||||||
|
*/
|
||||||
|
|
||||||
|
message criu_resp {
|
||||||
|
required criu_req_type type = 1;
|
||||||
|
required bool success = 2;
|
||||||
|
|
||||||
|
optional criu_dump_resp dump = 3;
|
||||||
|
optional criu_restore_resp restore = 4;
|
||||||
|
optional criu_notify notify = 5;
|
||||||
|
optional criu_page_server_info ps = 6;
|
||||||
|
|
||||||
|
optional int32 cr_errno = 7;
|
||||||
|
optional criu_features features = 8;
|
||||||
|
optional string cr_errmsg = 9;
|
||||||
|
optional criu_version version = 10;
|
||||||
|
|
||||||
|
optional int32 status = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Answer for criu_req_type.VERSION requests */
|
||||||
|
message criu_version {
|
||||||
|
required int32 major_number = 1;
|
||||||
|
required int32 minor_number = 2;
|
||||||
|
optional string gitid = 3;
|
||||||
|
optional int32 sublevel = 4;
|
||||||
|
optional int32 extra = 5;
|
||||||
|
optional string name = 6;
|
||||||
|
}
|
7
vendor/modules.txt
vendored
7
vendor/modules.txt
vendored
@ -76,6 +76,13 @@ github.com/cenkalti/backoff/v4
|
|||||||
# github.com/cespare/xxhash/v2 v2.2.0
|
# github.com/cespare/xxhash/v2 v2.2.0
|
||||||
## explicit; go 1.11
|
## explicit; go 1.11
|
||||||
github.com/cespare/xxhash/v2
|
github.com/cespare/xxhash/v2
|
||||||
|
# github.com/checkpoint-restore/checkpointctl v1.1.0
|
||||||
|
## explicit; go 1.18
|
||||||
|
github.com/checkpoint-restore/checkpointctl/lib
|
||||||
|
# github.com/checkpoint-restore/go-criu/v7 v7.0.0
|
||||||
|
## explicit; go 1.18
|
||||||
|
github.com/checkpoint-restore/go-criu/v7
|
||||||
|
github.com/checkpoint-restore/go-criu/v7/rpc
|
||||||
# github.com/cilium/ebpf v0.11.0
|
# github.com/cilium/ebpf v0.11.0
|
||||||
## explicit; go 1.19
|
## explicit; go 1.19
|
||||||
github.com/cilium/ebpf
|
github.com/cilium/ebpf
|
||||||
|
Loading…
Reference in New Issue
Block a user