diff --git a/Protobuild.toml b/Protobuild.toml index b9150f94d..28f310707 100644 --- a/Protobuild.toml +++ b/Protobuild.toml @@ -58,6 +58,14 @@ ignore_files = [ "gogoproto/gogo.proto" ] +[[descriptors]] +prefix = "github.com/containerd/containerd/runtime/v2/runc/options" +target = "runtime/v2/runc/options/next.pb.txt" +ignore_files = [ + "google/protobuf/descriptor.proto", + "gogoproto/gogo.proto" +] + [[descriptors]] prefix = "github.com/containerd/containerd/windows/hcsshimtypes" target = "windows/hcsshimtypes/next.pb.txt" diff --git a/cmd/containerd-shim-runc-v1/main.go b/cmd/containerd-shim-runc-v1/main.go index 9b4ba328a..e9042d696 100644 --- a/cmd/containerd-shim-runc-v1/main.go +++ b/cmd/containerd-shim-runc-v1/main.go @@ -24,12 +24,10 @@ import ( "github.com/containerd/containerd/runtime/v2/runc" "github.com/containerd/containerd/runtime/v2/shim" - "github.com/sirupsen/logrus" ) func main() { if err := shim.Run(runc.New); err != nil { - logrus.WithError(err).Error("shim run") fmt.Fprintf(os.Stderr, "containerd-shim-run-v1: %s\n", err) os.Exit(1) } diff --git a/cmd/containerd/builtins_linux.go b/cmd/containerd/builtins_linux.go index 6ab4af0a8..6c56744df 100644 --- a/cmd/containerd/builtins_linux.go +++ b/cmd/containerd/builtins_linux.go @@ -21,6 +21,7 @@ import ( _ "github.com/containerd/containerd/metrics/cgroups" _ "github.com/containerd/containerd/runtime/v1/linux" _ "github.com/containerd/containerd/runtime/v2" + _ "github.com/containerd/containerd/runtime/v2/runc/options" _ "github.com/containerd/containerd/snapshots/native" _ "github.com/containerd/containerd/snapshots/overlay" _ "github.com/containerd/zfs" diff --git a/cmd/ctr/commands/client.go b/cmd/ctr/commands/client.go index e940aea66..b436186b2 100644 --- a/cmd/ctr/commands/client.go +++ b/cmd/ctr/commands/client.go @@ -46,8 +46,8 @@ func AppContext(context *cli.Context) (gocontext.Context, gocontext.CancelFunc) } // NewClient returns a new containerd client -func NewClient(context *cli.Context) (*containerd.Client, gocontext.Context, gocontext.CancelFunc, error) { - client, err := containerd.New(context.GlobalString("address")) +func NewClient(context *cli.Context, opts ...containerd.ClientOpt) (*containerd.Client, gocontext.Context, gocontext.CancelFunc, error) { + client, err := containerd.New(context.GlobalString("address"), opts...) if err != nil { return nil, nil, nil, err } diff --git a/cmd/ctr/commands/run/run_unix.go b/cmd/ctr/commands/run/run_unix.go index e2f730722..a6ec1a637 100644 --- a/cmd/ctr/commands/run/run_unix.go +++ b/cmd/ctr/commands/run/run_unix.go @@ -44,7 +44,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli if err != nil { return nil, err } - return client.NewContainer(ctx, id, containerd.WithCheckpoint(im, id)) + return client.NewContainer(ctx, id, containerd.WithCheckpoint(im, id), containerd.WithRuntime(context.String("runtime"), nil)) } var ( diff --git a/cmd/ctr/commands/tasks/checkpoint.go b/cmd/ctr/commands/tasks/checkpoint.go index e8a7727e8..33946720d 100644 --- a/cmd/ctr/commands/tasks/checkpoint.go +++ b/cmd/ctr/commands/tasks/checkpoint.go @@ -48,7 +48,7 @@ var checkpointCommand = cli.Command{ if id == "" { return errors.New("container id must be provided") } - client, ctx, cancel, err := commands.NewClient(context) + client, ctx, cancel, err := commands.NewClient(context, containerd.WithDefaultRuntime(context.String("runtime"))) if err != nil { return err } diff --git a/runtime/v2/binary.go b/runtime/v2/binary.go index 3727ba08b..d3eb2ac53 100644 --- a/runtime/v2/binary.go +++ b/runtime/v2/binary.go @@ -17,11 +17,13 @@ package v2 import ( + "bytes" "context" "strings" eventstypes "github.com/containerd/containerd/api/events" "github.com/containerd/containerd/events/exchange" + "github.com/containerd/containerd/log" "github.com/containerd/containerd/runtime" client "github.com/containerd/containerd/runtime/v2/shim" "github.com/containerd/containerd/runtime/v2/task" @@ -73,16 +75,26 @@ func (b *binary) Start(ctx context.Context) (*shim, error) { } func (b *binary) Delete(ctx context.Context) (*runtime.Exit, error) { + log.G(ctx).Info("cleaning up dead shim") cmd, err := client.Command(ctx, b.runtime, b.containerdAddress, b.bundle.Path, "-id", b.bundle.ID, "delete") if err != nil { return nil, err } - out, err := cmd.CombinedOutput() - if err != nil { - return nil, errors.Wrapf(err, "%s", out) + var ( + out = bytes.NewBuffer(nil) + errb = bytes.NewBuffer(nil) + ) + cmd.Stdout = out + cmd.Stderr = errb + if err := cmd.Run(); err != nil { + return nil, errors.Wrapf(err, "%s", errb.String()) + } + s := errb.String() + if s != "" { + log.G(ctx).Warnf("cleanup warnings %s", s) } var response task.DeleteResponse - if err := response.Unmarshal(out); err != nil { + if err := response.Unmarshal(out.Bytes()); err != nil { return nil, err } if err := b.bundle.Delete(); err != nil { diff --git a/runtime/v2/runc/options/next.pb.txt b/runtime/v2/runc/options/next.pb.txt new file mode 100755 index 000000000..622159c4a --- /dev/null +++ b/runtime/v2/runc/options/next.pb.txt @@ -0,0 +1,138 @@ +file { + name: "github.com/containerd/containerd/runtime/v2/runc/options/oci.proto" + package: "containerd.runc.v1" + dependency: "gogoproto/gogo.proto" + message_type { + name: "Options" + field { + name: "no_pivot_root" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_BOOL + json_name: "noPivotRoot" + } + field { + name: "no_new_keyring" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_BOOL + json_name: "noNewKeyring" + } + field { + name: "shim_cgroup" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "shimCgroup" + } + field { + name: "io_uid" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_UINT32 + json_name: "ioUid" + } + field { + name: "io_gid" + number: 5 + label: LABEL_OPTIONAL + type: TYPE_UINT32 + json_name: "ioGid" + } + field { + name: "binary_name" + number: 6 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "binaryName" + } + field { + name: "root" + number: 7 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "root" + } + field { + name: "criu_path" + number: 8 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "criuPath" + } + field { + name: "systemd_cgroup" + number: 9 + label: LABEL_OPTIONAL + type: TYPE_BOOL + json_name: "systemdCgroup" + } + } + message_type { + name: "CheckpointOptions" + field { + name: "exit" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_BOOL + json_name: "exit" + } + field { + name: "open_tcp" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_BOOL + json_name: "openTcp" + } + field { + name: "external_unix_sockets" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_BOOL + json_name: "externalUnixSockets" + } + field { + name: "terminal" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_BOOL + json_name: "terminal" + } + field { + name: "file_locks" + number: 5 + label: LABEL_OPTIONAL + type: TYPE_BOOL + json_name: "fileLocks" + } + field { + name: "empty_namespaces" + number: 6 + label: LABEL_REPEATED + type: TYPE_STRING + json_name: "emptyNamespaces" + } + field { + name: "cgroups_mode" + number: 7 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "cgroupsMode" + } + } + message_type { + name: "ProcessDetails" + field { + name: "exec_id" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "execId" + } + } + options { + go_package: "github.com/containerd/containerd/runtime/v2/runc/options;options" + } + weak_dependency: 0 + syntax: "proto3" +} diff --git a/runtime/v2/runc/service.go b/runtime/v2/runc/service.go index 91a248f6f..f9d7e4413 100644 --- a/runtime/v2/runc/service.go +++ b/runtime/v2/runc/service.go @@ -184,14 +184,15 @@ func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error) if err != nil { return nil, err } - runtime, _ := s.readRuntime(path) - if runtime != "" { - r := proc.NewRunc(proc.RuncRoot, path, ns, runtime, "", false) - if err := r.Delete(ctx, s.id, &runcC.DeleteOpts{ - Force: true, - }); err != nil { - logrus.WithError(err).Warn("runc delete") - } + runtime, err := s.readRuntime(path) + if err != nil { + return nil, err + } + r := proc.NewRunc(proc.RuncRoot, path, ns, runtime, "", false) + if err := r.Delete(ctx, s.id, &runcC.DeleteOpts{ + Force: true, + }); err != nil { + logrus.WithError(err).Warn("failed to remove runc container") } if err := mount.UnmountAll(filepath.Join(path, "rootfs"), 0); err != nil { logrus.WithError(err).Warn("failed to cleanup rootfs mount") diff --git a/runtime/v2/shim/shim.go b/runtime/v2/shim/shim.go index 93a1ab6a4..7592cf4ef 100644 --- a/runtime/v2/shim/shim.go +++ b/runtime/v2/shim/shim.go @@ -38,6 +38,7 @@ import ( shimapi "github.com/containerd/containerd/runtime/v2/task" "github.com/containerd/ttrpc" "github.com/containerd/typeurl" + "github.com/gogo/protobuf/proto" "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" @@ -141,7 +142,7 @@ func Run(initFunc Init) error { if err != nil { return err } - data, err := response.Marshal() + data, err := proto.Marshal(response) if err != nil { return err } diff --git a/task.go b/task.go index 2ea53ed02..c9a86ffcd 100644 --- a/task.go +++ b/task.go @@ -40,6 +40,7 @@ import ( "github.com/containerd/typeurl" google_protobuf "github.com/gogo/protobuf/types" digest "github.com/opencontainers/go-digest" + is "github.com/opencontainers/image-spec/specs-go" "github.com/opencontainers/image-spec/specs-go/v1" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -424,6 +425,9 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Imag return nil, err } index := v1.Index{ + Versioned: is.Versioned{ + SchemaVersion: 2, + }, Annotations: make(map[string]string), } if err := t.checkpointTask(ctx, &index, request); err != nil {