api/services/instrospection: add PluginInfo
The new `PlunginInfo()` call can be used for instrospecting the details
of the runtime plugin.
```console
$ ctr plugins inspect-runtime --runtime=io.containerd.runc.v2 --runc-binary=runc
{
"Name": "io.containerd.runc.v2",
"Version": {
"Version": "v2.0.0-beta.0-XX-gXXXXXXXXX.m",
"Revision": "v2.0.0-beta.0-XX-gXXXXXXXXX.m"
},
"Options": {
"binary_name": "runc"
},
"Features": {
"ociVersionMin": "1.0.0",
"ociVersionMax": "1.1.0-rc.2",
...,
},
"Annotations": null
}
```
The shim binary has to support `-info` flag, see `runtime/v2/README.md`
Replaces PR 8509 (`api/services/task: add RuntimeInfo()`)
Co-authored-by: Derek McGowan <derek@mcg.dev>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
@@ -96,6 +96,19 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
// RuntimeFlags are cli flags specifying runtime
|
||||
RuntimeFlags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "runtime",
|
||||
Usage: "Runtime name or absolute path to runtime binary",
|
||||
Value: defaults.DefaultRuntime,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "runtime-config-path",
|
||||
Usage: "Optional runtime config path",
|
||||
},
|
||||
}
|
||||
|
||||
// ContainerFlags are cli flags specifying container options
|
||||
ContainerFlags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
@@ -138,19 +151,10 @@ var (
|
||||
Name: "read-only",
|
||||
Usage: "Set the containers filesystem as readonly",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "runtime",
|
||||
Usage: "Runtime name or absolute path to runtime binary",
|
||||
Value: defaults.DefaultRuntime,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "sandbox",
|
||||
Usage: "Create the container in the given sandbox",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "runtime-config-path",
|
||||
Usage: "Optional runtime config path",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "tty,t",
|
||||
Usage: "Allocate a TTY for the container",
|
||||
|
||||
@@ -19,10 +19,24 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/containerd/containerd/v2/core/runtime/v2/runc/options"
|
||||
runtimeoptions "github.com/containerd/containerd/v2/pkg/runtimeoptions/v1"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func init() {
|
||||
RuntimeFlags = append(RuntimeFlags, cli.StringFlag{
|
||||
Name: "runc-binary",
|
||||
Usage: "Specify runc-compatible binary",
|
||||
}, cli.StringFlag{
|
||||
Name: "runc-root",
|
||||
Usage: "Specify runc-compatible root",
|
||||
}, cli.BoolFlag{
|
||||
Name: "runc-systemd-cgroup",
|
||||
Usage: "Start runc with systemd cgroup manager",
|
||||
})
|
||||
ContainerFlags = append(ContainerFlags, cli.BoolFlag{
|
||||
Name: "rootfs",
|
||||
Usage: "Use custom rootfs that is not managed by containerd snapshotter",
|
||||
@@ -44,3 +58,42 @@ func init() {
|
||||
Usage: "File path to a device to add to the container; or a path to a directory tree of devices to add to the container",
|
||||
})
|
||||
}
|
||||
|
||||
func getRuncOptions(context *cli.Context) (*options.Options, error) {
|
||||
runtimeOpts := &options.Options{}
|
||||
if runcBinary := context.String("runc-binary"); runcBinary != "" {
|
||||
runtimeOpts.BinaryName = runcBinary
|
||||
}
|
||||
if context.Bool("runc-systemd-cgroup") {
|
||||
if context.String("cgroup") == "" {
|
||||
// runc maps "machine.slice:foo:deadbeef" to "/machine.slice/foo-deadbeef.scope"
|
||||
return nil, errors.New("option --runc-systemd-cgroup requires --cgroup to be set, e.g. \"machine.slice:foo:deadbeef\"")
|
||||
}
|
||||
runtimeOpts.SystemdCgroup = true
|
||||
}
|
||||
if root := context.String("runc-root"); root != "" {
|
||||
runtimeOpts.Root = root
|
||||
}
|
||||
|
||||
return runtimeOpts, nil
|
||||
}
|
||||
|
||||
func RuntimeOptions(context *cli.Context) (interface{}, error) {
|
||||
// validate first
|
||||
if (context.String("runc-binary") != "" || context.Bool("runc-systemd-cgroup")) &&
|
||||
context.String("runtime") != "io.containerd.runc.v2" {
|
||||
return nil, errors.New("specifying runc-binary and runc-systemd-cgroup is only supported for \"io.containerd.runc.v2\" runtime")
|
||||
}
|
||||
|
||||
if context.String("runtime") == "io.containerd.runc.v2" {
|
||||
return getRuncOptions(context)
|
||||
}
|
||||
|
||||
if configPath := context.String("runtime-config-path"); configPath != "" {
|
||||
return &runtimeoptions.Options{
|
||||
ConfigPath: configPath,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -38,3 +38,7 @@ func init() {
|
||||
Usage: "Identifier of a device to add to the container (e.g. class://5B45201D-F2F2-4F3B-85BB-30FF1F953599)",
|
||||
})
|
||||
}
|
||||
|
||||
func RuntimeOptions(context *cli.Context) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ var createCommand = cli.Command{
|
||||
Usage: "Create container",
|
||||
ArgsUsage: "[flags] Image|RootFS CONTAINER [COMMAND] [ARG...]",
|
||||
SkipArgReorder: true,
|
||||
Flags: append(append(commands.SnapshotterFlags, []cli.Flag{commands.SnapshotterLabels}...), commands.ContainerFlags...),
|
||||
Flags: append(commands.RuntimeFlags, append(append(commands.SnapshotterFlags, []cli.Flag{commands.SnapshotterLabels}...), commands.ContainerFlags...)...),
|
||||
Action: func(context *cli.Context) error {
|
||||
var (
|
||||
id string
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
@@ -39,6 +40,7 @@ var Command = cli.Command{
|
||||
Usage: "Provides information about containerd plugins",
|
||||
Subcommands: []cli.Command{
|
||||
listCommand,
|
||||
inspectRuntimeCommand,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -162,3 +164,32 @@ func prettyPlatforms(pspb []*types.Platform) string {
|
||||
sort.Stable(sort.StringSlice(ps))
|
||||
return strings.Join(ps, ",")
|
||||
}
|
||||
|
||||
var inspectRuntimeCommand = cli.Command{
|
||||
Name: "inspect-runtime",
|
||||
Usage: "Display runtime info",
|
||||
ArgsUsage: "[flags]",
|
||||
Flags: commands.RuntimeFlags,
|
||||
Action: func(context *cli.Context) error {
|
||||
rt := context.String("runtime")
|
||||
rtOptions, err := commands.RuntimeOptions(context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, ctx, cancel, err := commands.NewClient(context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cancel()
|
||||
rtInfo, err := client.RuntimeInfo(ctx, rt, rtOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
j, err := json.MarshalIndent(rtInfo, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprintln(context.App.Writer, string(j))
|
||||
return err
|
||||
},
|
||||
}
|
||||
|
||||
@@ -128,8 +128,9 @@ var Command = cli.Command{
|
||||
Usage: "Enable cni networking for the container",
|
||||
},
|
||||
}, append(platformRunFlags,
|
||||
append(append(commands.SnapshotterFlags, []cli.Flag{commands.SnapshotterLabels}...),
|
||||
commands.ContainerFlags...)...)...),
|
||||
append(commands.RuntimeFlags,
|
||||
append(append(commands.SnapshotterFlags, []cli.Flag{commands.SnapshotterLabels}...),
|
||||
commands.ContainerFlags...)...)...)...),
|
||||
Action: func(context *cli.Context) error {
|
||||
var (
|
||||
err error
|
||||
|
||||
@@ -34,10 +34,8 @@ import (
|
||||
"github.com/containerd/containerd/v2/contrib/nvidia"
|
||||
"github.com/containerd/containerd/v2/contrib/seccomp"
|
||||
"github.com/containerd/containerd/v2/core/containers"
|
||||
"github.com/containerd/containerd/v2/core/runtime/v2/runc/options"
|
||||
"github.com/containerd/containerd/v2/core/snapshots"
|
||||
"github.com/containerd/containerd/v2/pkg/oci"
|
||||
runtimeoptions "github.com/containerd/containerd/v2/pkg/runtimeoptions/v1"
|
||||
"github.com/containerd/log"
|
||||
"github.com/containerd/platforms"
|
||||
"github.com/intel/goresctrl/pkg/blockio"
|
||||
@@ -48,18 +46,6 @@ import (
|
||||
)
|
||||
|
||||
var platformRunFlags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "runc-binary",
|
||||
Usage: "Specify runc-compatible binary",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "runc-root",
|
||||
Usage: "Specify runc-compatible root",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "runc-systemd-cgroup",
|
||||
Usage: "Start runc with systemd cgroup manager",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "uidmap",
|
||||
Usage: "Run inside a user namespace with the specified UID mapping range; specified with the format `container-uid:host-uid:length`",
|
||||
@@ -413,7 +399,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
||||
cOpts = append(cOpts, containerd.WithContainerExtension(commands.CtrCniMetadataExtension, cniMeta))
|
||||
}
|
||||
|
||||
runtimeOpts, err := getRuntimeOptions(context)
|
||||
runtimeOpts, err := commands.RuntimeOptions(context)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -430,45 +416,6 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
||||
return client.NewContainer(ctx, id, cOpts...)
|
||||
}
|
||||
|
||||
func getRuncOptions(context *cli.Context) (*options.Options, error) {
|
||||
runtimeOpts := &options.Options{}
|
||||
if runcBinary := context.String("runc-binary"); runcBinary != "" {
|
||||
runtimeOpts.BinaryName = runcBinary
|
||||
}
|
||||
if context.Bool("runc-systemd-cgroup") {
|
||||
if context.String("cgroup") == "" {
|
||||
// runc maps "machine.slice:foo:deadbeef" to "/machine.slice/foo-deadbeef.scope"
|
||||
return nil, errors.New("option --runc-systemd-cgroup requires --cgroup to be set, e.g. \"machine.slice:foo:deadbeef\"")
|
||||
}
|
||||
runtimeOpts.SystemdCgroup = true
|
||||
}
|
||||
if root := context.String("runc-root"); root != "" {
|
||||
runtimeOpts.Root = root
|
||||
}
|
||||
|
||||
return runtimeOpts, nil
|
||||
}
|
||||
|
||||
func getRuntimeOptions(context *cli.Context) (interface{}, error) {
|
||||
// validate first
|
||||
if (context.String("runc-binary") != "" || context.Bool("runc-systemd-cgroup")) &&
|
||||
context.String("runtime") != "io.containerd.runc.v2" {
|
||||
return nil, errors.New("specifying runc-binary and runc-systemd-cgroup is only supported for \"io.containerd.runc.v2\" runtime")
|
||||
}
|
||||
|
||||
if context.String("runtime") == "io.containerd.runc.v2" {
|
||||
return getRuncOptions(context)
|
||||
}
|
||||
|
||||
if configPath := context.String("runtime-config-path"); configPath != "" {
|
||||
return &runtimeoptions.Options{
|
||||
ConfigPath: configPath,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func parseIDMapping(mapping string) (specs.LinuxIDMapping, error) {
|
||||
// We expect 3 parts, but limit to 4 to allow detection of invalid values.
|
||||
parts := strings.SplitN(mapping, ":", 4)
|
||||
|
||||
Reference in New Issue
Block a user