diff --git a/api/types/types.go b/api/types/types.go index cd5916ae15..0d25ea4c45 100644 --- a/api/types/types.go +++ b/api/types/types.go @@ -653,12 +653,18 @@ type Checkpoint struct { // Runtime describes an OCI runtime type Runtime struct { - Path string `json:"path"` + // "Legacy" runtime configuration for runc-compatible runtimes. + + Path string `json:"path,omitempty"` Args []string `json:"runtimeArgs,omitempty"` + // Shimv2 runtime configuration. Mutually exclusive with the legacy config above. + + Type string `json:"runtimeType,omitempty"` + Options map[string]interface{} `json:"options,omitempty"` + // This is exposed here only for internal use - // It is not currently supported to specify custom shim configs - Shim *ShimConfig `json:"-"` + ShimConfig *ShimConfig `json:"-"` } // ShimConfig is used by runtime to configure containerd shims diff --git a/daemon/container_unix_test.go b/daemon/container_unix_test.go index da85f8f608..dbe7b04b2c 100644 --- a/daemon/container_unix_test.go +++ b/daemon/container_unix_test.go @@ -6,7 +6,6 @@ package daemon import ( "testing" - "github.com/docker/docker/api/types" containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/daemon/config" "github.com/docker/go-connections/nat" @@ -33,9 +32,8 @@ func TestContainerWarningHostAndPublishPorts(t *testing.T) { NetworkMode: "host", PortBindings: tc.ports, } - cs := &config.Config{ - Runtimes: map[string]types.Runtime{"runc": {}}, - } + cs := &config.Config{} + configureRuntimes(cs) d := &Daemon{configStore: cs} wrns, err := d.verifyContainerSettings(hostConfig, &containertypes.Config{}, false) assert.NilError(t, err) diff --git a/daemon/daemon.go b/daemon/daemon.go index eecdd85f33..572bcfb817 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -908,15 +908,17 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S } } - var rt types.Runtime + var ( + shim string + shimOpts interface{} + ) if runtime.GOOS != "windows" { - rtPtr, err := d.getRuntime(config.GetDefaultRuntimeName()) + shim, shimOpts, err = d.getRuntime(config.GetDefaultRuntimeName()) if err != nil { return nil, err } - rt = *rtPtr } - return pluginexec.New(ctx, getPluginExecRoot(config), pluginCli, config.ContainerdPluginNamespace, m, rt) + return pluginexec.New(ctx, getPluginExecRoot(config), pluginCli, config.ContainerdPluginNamespace, m, shim, shimOpts) } // Plugin system initialization should happen before restore. Do not change order. diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index d0bb80fce2..843b44e270 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -705,7 +705,7 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes. hostConfig.Runtime = daemon.configStore.GetDefaultRuntimeName() } - if _, err := daemon.getRuntime(hostConfig.Runtime); err != nil { + if _, _, err := daemon.getRuntime(hostConfig.Runtime); err != nil { return warnings, err } diff --git a/daemon/runtime_unix.go b/daemon/runtime_unix.go index b7ef4ae853..f9cb6bb08b 100644 --- a/daemon/runtime_unix.go +++ b/daemon/runtime_unix.go @@ -14,6 +14,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/daemon/config" "github.com/docker/docker/errdefs" + "github.com/docker/docker/libcontainerd/shimopts" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -31,7 +32,7 @@ func configureRuntimes(conf *config.Config) { if conf.Runtimes == nil { conf.Runtimes = make(map[string]types.Runtime) } - conf.Runtimes[config.LinuxV2RuntimeName] = types.Runtime{Path: defaultRuntimeName, Shim: defaultV2ShimConfig(conf, defaultRuntimeName)} + conf.Runtimes[config.LinuxV2RuntimeName] = types.Runtime{Path: defaultRuntimeName, ShimConfig: defaultV2ShimConfig(conf, defaultRuntimeName)} conf.Runtimes[config.StockRuntimeName] = conf.Runtimes[config.LinuxV2RuntimeName] } @@ -88,17 +89,42 @@ func (daemon *Daemon) initRuntimes(runtimes map[string]types.Runtime) (err error } }() - for name, rt := range runtimes { - if len(rt.Args) > 0 { - script := filepath.Join(tmpDir, name) - content := fmt.Sprintf("#!/bin/sh\n%s %s $@\n", rt.Path, strings.Join(rt.Args, " ")) - if err := os.WriteFile(script, []byte(content), 0700); err != nil { - return err + for name := range runtimes { + rt := runtimes[name] + if rt.Path == "" && rt.Type == "" { + return errors.Errorf("runtime %s: either a runtimeType or a path must be configured", name) + } + if rt.Path != "" { + if rt.Type != "" { + return errors.Errorf("runtime %s: cannot configure both path and runtimeType for the same runtime", name) + } + if len(rt.Options) > 0 { + return errors.Errorf("runtime %s: options cannot be used with a path runtime", name) + } + + if len(rt.Args) > 0 { + script := filepath.Join(tmpDir, name) + content := fmt.Sprintf("#!/bin/sh\n%s %s $@\n", rt.Path, strings.Join(rt.Args, " ")) + if err := os.WriteFile(script, []byte(content), 0700); err != nil { + return err + } + } + rt.ShimConfig = defaultV2ShimConfig(daemon.configStore, daemon.rewriteRuntimePath(name, rt.Path, rt.Args)) + } else { + if len(rt.Args) > 0 { + return errors.Errorf("runtime %s: args cannot be used with a runtimeType runtime", name) + } + // Unlike implicit runtimes, there is no restriction on configuring a shim by path. + rt.ShimConfig = &types.ShimConfig{Binary: rt.Type} + if len(rt.Options) > 0 { + // It has to be a pointer type or there'll be a panic in containerd/typeurl when we try to start the container. + rt.ShimConfig.Opts, err = shimopts.Generate(rt.Type, rt.Options) + if err != nil { + return errors.Wrapf(err, "runtime %v", name) + } } } - if rt.Shim == nil { - rt.Shim = defaultV2ShimConfig(daemon.configStore, rt.Path) - } + runtimes[name] = rt } return nil } @@ -106,40 +132,39 @@ func (daemon *Daemon) initRuntimes(runtimes map[string]types.Runtime) (err error // rewriteRuntimePath is used for runtimes which have custom arguments supplied. // This is needed because the containerd API only calls the OCI runtime binary, there is no options for extra arguments. // To support this case, the daemon wraps the specified runtime in a script that passes through those arguments. -func (daemon *Daemon) rewriteRuntimePath(name, p string, args []string) (string, error) { +func (daemon *Daemon) rewriteRuntimePath(name, p string, args []string) string { if len(args) == 0 { - return p, nil + return p } - // Check that the runtime path actually exists here so that we can return a well known error. - if _, err := exec.LookPath(p); err != nil { - return "", errors.Wrap(err, "error while looking up the specified runtime path") - } - - return filepath.Join(daemon.configStore.Root, "runtimes", name), nil + return filepath.Join(daemon.configStore.Root, "runtimes", name) } -func (daemon *Daemon) getRuntime(name string) (*types.Runtime, error) { +func (daemon *Daemon) getRuntime(name string) (shim string, opts interface{}, err error) { rt := daemon.configStore.GetRuntime(name) if rt == nil { if !config.IsPermissibleC8dRuntimeName(name) { - return nil, errdefs.InvalidParameter(errors.Errorf("unknown or invalid runtime name: %s", name)) + return "", nil, errdefs.InvalidParameter(errors.Errorf("unknown or invalid runtime name: %s", name)) } - return &types.Runtime{Shim: &types.ShimConfig{Binary: name}}, nil + return name, nil, nil } if len(rt.Args) > 0 { - p, err := daemon.rewriteRuntimePath(name, rt.Path, rt.Args) - if err != nil { - return nil, err + // Check that the path of the runtime which the script wraps actually exists so + // that we can return a well known error which references the configured path + // instead of the wrapper script's. + if _, err := exec.LookPath(rt.Path); err != nil { + return "", nil, errors.Wrap(err, "error while looking up the specified runtime path") } - rt.Path = p - rt.Args = nil } - if rt.Shim == nil { - rt.Shim = defaultV2ShimConfig(daemon.configStore, rt.Path) + if rt.ShimConfig == nil { + // Should never happen as daemon.initRuntimes always sets + // ShimConfig and config reloading is synchronized. + err := errdefs.System(errors.Errorf("BUG: runtime %s: rt.ShimConfig == nil", name)) + logrus.Error(err) + return "", nil, err } - return rt, nil + return rt.ShimConfig.Binary, rt.ShimConfig.Opts, nil } diff --git a/daemon/runtime_unix_test.go b/daemon/runtime_unix_test.go index f4b55ac6e4..570d353650 100644 --- a/daemon/runtime_unix_test.go +++ b/daemon/runtime_unix_test.go @@ -8,6 +8,7 @@ import ( "path/filepath" "testing" + "github.com/containerd/containerd/plugin" v2runcoptions "github.com/containerd/containerd/runtime/v2/runc/options" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -17,13 +18,110 @@ import ( "github.com/docker/docker/errdefs" ) +func TestInitRuntimes_InvalidConfigs(t *testing.T) { + cases := []struct { + name string + runtime types.Runtime + expectErr string + }{ + { + name: "Empty", + expectErr: "either a runtimeType or a path must be configured", + }, + { + name: "ArgsOnly", + runtime: types.Runtime{Args: []string{"foo", "bar"}}, + expectErr: "either a runtimeType or a path must be configured", + }, + { + name: "OptionsOnly", + runtime: types.Runtime{Options: map[string]interface{}{"hello": "world"}}, + expectErr: "either a runtimeType or a path must be configured", + }, + { + name: "PathAndType", + runtime: types.Runtime{Path: "/bin/true", Type: "io.containerd.runsc.v1"}, + expectErr: "cannot configure both", + }, + { + name: "PathAndOptions", + runtime: types.Runtime{Path: "/bin/true", Options: map[string]interface{}{"a": "b"}}, + expectErr: "options cannot be used with a path runtime", + }, + { + name: "TypeAndArgs", + runtime: types.Runtime{Type: "io.containerd.runsc.v1", Args: []string{"--version"}}, + expectErr: "args cannot be used with a runtimeType runtime", + }, + { + name: "PathArgsOptions", + runtime: types.Runtime{ + Path: "/bin/true", + Args: []string{"--version"}, + Options: map[string]interface{}{"hmm": 3}, + }, + expectErr: "options cannot be used with a path runtime", + }, + { + name: "TypeOptionsArgs", + runtime: types.Runtime{ + Type: "io.containerd.kata.v2", + Options: map[string]interface{}{"a": "b"}, + Args: []string{"--help"}, + }, + expectErr: "args cannot be used with a runtimeType runtime", + }, + { + name: "PathArgsTypeOptions", + runtime: types.Runtime{ + Path: "/bin/true", + Args: []string{"foo"}, + Type: "io.containerd.runsc.v1", + Options: map[string]interface{}{"a": "b"}, + }, + expectErr: "cannot configure both", + }, + } + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + cfg, err := config.New() + assert.NilError(t, err) + d := &Daemon{configStore: cfg} + d.configStore.Root = t.TempDir() + assert.Assert(t, os.Mkdir(filepath.Join(d.configStore.Root, "runtimes"), 0700)) + + err = d.initRuntimes(map[string]types.Runtime{"myruntime": tt.runtime}) + assert.Check(t, is.ErrorContains(err, tt.expectErr)) + }) + } +} + func TestGetRuntime(t *testing.T) { // Configured runtimes can have any arbitrary name, including names // which would not be allowed as implicit runtime names. Explicit takes // precedence over implicit. - const configuredRtName = "my/custom.shim.v1" + const configuredRtName = "my/custom.runtime.v1" configuredRuntime := types.Runtime{Path: "/bin/true"} + const rtWithArgsName = "withargs" + rtWithArgs := types.Runtime{ + Path: "/bin/false", + Args: []string{"--version"}, + } + + const shimWithOptsName = "shimwithopts" + shimWithOpts := types.Runtime{ + Type: plugin.RuntimeRuncV2, + Options: map[string]interface{}{"IoUid": 42}, + } + + const shimAliasName = "wasmedge" + shimAlias := types.Runtime{Type: "io.containerd.wasmedge.v1"} + + const configuredShimByPathName = "shimwithpath" + configuredShimByPath := types.Runtime{Type: "/path/to/my/shim"} + cfg, err := config.New() assert.NilError(t, err) @@ -31,7 +129,11 @@ func TestGetRuntime(t *testing.T) { d.configStore.Root = t.TempDir() assert.Assert(t, os.Mkdir(filepath.Join(d.configStore.Root, "runtimes"), 0700)) d.configStore.Runtimes = map[string]types.Runtime{ - configuredRtName: configuredRuntime, + configuredRtName: configuredRuntime, + rtWithArgsName: rtWithArgs, + shimWithOptsName: shimWithOpts, + shimAliasName: shimAlias, + configuredShimByPathName: configuredShimByPath, } configureRuntimes(d.configStore) assert.Assert(t, d.loadRuntimes()) @@ -39,36 +141,33 @@ func TestGetRuntime(t *testing.T) { stockRuntime, ok := d.configStore.Runtimes[config.StockRuntimeName] assert.Assert(t, ok, "stock runtime could not be found (test needs to be updated)") - configdOpts := *stockRuntime.Shim.Opts.(*v2runcoptions.Options) + configdOpts := *stockRuntime.ShimConfig.Opts.(*v2runcoptions.Options) configdOpts.BinaryName = configuredRuntime.Path - wantConfigdRuntime := configuredRuntime - wantConfigdRuntime.Shim = &types.ShimConfig{ - Binary: stockRuntime.Shim.Binary, - Opts: &configdOpts, - } for _, tt := range []struct { name, runtime string - want *types.Runtime + wantShim string + wantOpts interface{} }{ { - name: "StockRuntime", - runtime: config.StockRuntimeName, - want: &stockRuntime, + name: "StockRuntime", + runtime: config.StockRuntimeName, + wantShim: stockRuntime.ShimConfig.Binary, + wantOpts: stockRuntime.ShimConfig.Opts, }, { - name: "ShimName", - runtime: "io.containerd.my-shim.v42", - want: &types.Runtime{Shim: &types.ShimConfig{Binary: "io.containerd.my-shim.v42"}}, + name: "ShimName", + runtime: "io.containerd.my-shim.v42", + wantShim: "io.containerd.my-shim.v42", }, { // containerd is pretty loose about the format of runtime names. Perhaps too // loose. The only requirements are that the name contain a dot and (depending // on the containerd version) not start with a dot. It does not enforce any // particular format of the dot-delimited components of the name. - name: "VersionlessShimName", - runtime: "io.containerd.my-shim", - want: &types.Runtime{Shim: &types.ShimConfig{Binary: "io.containerd.my-shim"}}, + name: "VersionlessShimName", + runtime: "io.containerd.my-shim", + wantShim: "io.containerd.my-shim", }, { name: "IllformedShimName", @@ -91,16 +190,45 @@ func TestGetRuntime(t *testing.T) { runtime: "my/io.containerd.runc.v2", }, { - name: "ConfiguredRuntime", - runtime: configuredRtName, - want: &wantConfigdRuntime, + name: "ConfiguredRuntime", + runtime: configuredRtName, + wantShim: stockRuntime.ShimConfig.Binary, + wantOpts: &configdOpts, + }, + { + name: "RuntimeWithArgs", + runtime: rtWithArgsName, + wantShim: stockRuntime.ShimConfig.Binary, + wantOpts: defaultV2ShimConfig( + d.configStore, + d.rewriteRuntimePath( + rtWithArgsName, + rtWithArgs.Path, + rtWithArgs.Args)).Opts, + }, + { + name: "ShimWithOpts", + runtime: shimWithOptsName, + wantShim: shimWithOpts.Type, + wantOpts: &v2runcoptions.Options{IoUid: 42}, + }, + { + name: "ShimAlias", + runtime: shimAliasName, + wantShim: shimAlias.Type, + }, + { + name: "ConfiguredShimByPath", + runtime: configuredShimByPathName, + wantShim: configuredShimByPath.Type, }, } { tt := tt t.Run(tt.name, func(t *testing.T) { - got, err := d.getRuntime(tt.runtime) - assert.Check(t, is.DeepEqual(got, tt.want)) - if tt.want != nil { + gotShim, gotOpts, err := d.getRuntime(tt.runtime) + assert.Check(t, is.Equal(gotShim, tt.wantShim)) + assert.Check(t, is.DeepEqual(gotOpts, tt.wantOpts)) + if tt.wantShim != "" { assert.Check(t, err) } else { assert.Check(t, errdefs.IsInvalidParameter(err)) diff --git a/daemon/runtime_windows.go b/daemon/runtime_windows.go index 0787cb1155..83b1a41441 100644 --- a/daemon/runtime_windows.go +++ b/daemon/runtime_windows.go @@ -1,10 +1,9 @@ package daemon import ( - "github.com/docker/docker/api/types" - "github.com/pkg/errors" + "errors" ) -func (daemon *Daemon) getRuntime(name string) (*types.Runtime, error) { - return nil, errors.New("not implemented") +func (daemon *Daemon) getRuntime(name string) (shim string, opts interface{}, err error) { + return "", nil, errors.New("not implemented") } diff --git a/daemon/start_unix.go b/daemon/start_unix.go index 9edf9fbd80..bfa187c80f 100644 --- a/daemon/start_unix.go +++ b/daemon/start_unix.go @@ -15,10 +15,10 @@ func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Contain container.CheckpointTo(daemon.containersReplica) } - rt, err := daemon.getRuntime(container.HostConfig.Runtime) + binary, opts, err := daemon.getRuntime(container.HostConfig.Runtime) if err != nil { return "", nil, setExitCodeFromError(container.SetExitCode, err) } - return rt.Shim.Binary, rt.Shim.Opts, nil + return binary, opts, nil } diff --git a/libcontainerd/shimopts/convert.go b/libcontainerd/shimopts/convert.go new file mode 100644 index 0000000000..b5ef8f52a9 --- /dev/null +++ b/libcontainerd/shimopts/convert.go @@ -0,0 +1,38 @@ +package shimopts + +import ( + runhcsoptions "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options" + runtimeoptions "github.com/containerd/containerd/pkg/runtimeoptions/v1" + "github.com/containerd/containerd/plugin" + runcoptions "github.com/containerd/containerd/runtime/v2/runc/options" + "github.com/pelletier/go-toml" +) + +// Generate converts opts into a runtime options value for the runtimeType which +// can be passed into containerd. +func Generate(runtimeType string, opts map[string]interface{}) (interface{}, error) { + // This is horrible, but we have no other choice. The containerd client + // can only handle options values which can be marshaled into a + // typeurl.Any. And we're in good company: cri-containerd handles shim + // options in the same way. + var out interface{} + switch runtimeType { + case plugin.RuntimeRuncV1, plugin.RuntimeRuncV2: + out = &runcoptions.Options{} + case "io.containerd.runhcs.v1": + out = &runhcsoptions.Options{} + default: + out = &runtimeoptions.Options{} + } + + // We can't use mergo.Map as it is too strict about type-assignability + // with numeric types. + tree, err := toml.TreeFromMap(opts) + if err != nil { + return nil, err + } + if err := tree.Unmarshal(out); err != nil { + return nil, err + } + return out, nil +} diff --git a/plugin/executor/containerd/containerd.go b/plugin/executor/containerd/containerd.go index 474e7774f6..cb874cab38 100644 --- a/plugin/executor/containerd/containerd.go +++ b/plugin/executor/containerd/containerd.go @@ -9,7 +9,6 @@ import ( "github.com/containerd/containerd" "github.com/containerd/containerd/cio" - "github.com/docker/docker/api/types" "github.com/docker/docker/errdefs" "github.com/docker/docker/libcontainerd" libcontainerdtypes "github.com/docker/docker/libcontainerd/types" @@ -24,11 +23,12 @@ type ExitHandler interface { } // New creates a new containerd plugin executor -func New(ctx context.Context, rootDir string, cli *containerd.Client, ns string, exitHandler ExitHandler, runtime types.Runtime) (*Executor, error) { +func New(ctx context.Context, rootDir string, cli *containerd.Client, ns string, exitHandler ExitHandler, shim string, shimOpts interface{}) (*Executor, error) { e := &Executor{ rootDir: rootDir, exitHandler: exitHandler, - runtime: runtime, + shim: shim, + shimOpts: shimOpts, plugins: make(map[string]*c8dPlugin), } @@ -45,7 +45,8 @@ type Executor struct { rootDir string client libcontainerdtypes.Client exitHandler ExitHandler - runtime types.Runtime + shim string + shimOpts interface{} mu sync.Mutex // Guards plugins map plugins map[string]*c8dPlugin @@ -75,7 +76,7 @@ func (p c8dPlugin) deleteTaskAndContainer(ctx context.Context) { func (e *Executor) Create(id string, spec specs.Spec, stdout, stderr io.WriteCloser) error { ctx := context.Background() log := logrus.WithField("plugin", id) - ctr, err := libcontainerd.ReplaceContainer(ctx, e.client, id, &spec, e.runtime.Shim.Binary, e.runtime.Shim.Opts) + ctr, err := libcontainerd.ReplaceContainer(ctx, e.client, id, &spec, e.shim, e.shimOpts) if err != nil { return errors.Wrap(err, "error creating containerd container for plugin") } diff --git a/vendor/github.com/containerd/containerd/pkg/runtimeoptions/v1/api.pb.go b/vendor/github.com/containerd/containerd/pkg/runtimeoptions/v1/api.pb.go new file mode 100644 index 0000000000..a224dc6f21 --- /dev/null +++ b/vendor/github.com/containerd/containerd/pkg/runtimeoptions/v1/api.pb.go @@ -0,0 +1,397 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: github.com/containerd/containerd/pkg/runtimeoptions/v1/api.proto + +package runtimeoptions_v1 + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type Options struct { + // TypeUrl specifies the type of the content inside the config file. + TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"` + // ConfigPath specifies the filesystem location of the config file + // used by the runtime. + ConfigPath string `protobuf:"bytes,2,opt,name=config_path,json=configPath,proto3" json:"config_path,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Options) Reset() { *m = Options{} } +func (*Options) ProtoMessage() {} +func (*Options) Descriptor() ([]byte, []int) { + return fileDescriptor_7700dd27e3487aa6, []int{0} +} +func (m *Options) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Options) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Options.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Options) XXX_Merge(src proto.Message) { + xxx_messageInfo_Options.Merge(m, src) +} +func (m *Options) XXX_Size() int { + return m.Size() +} +func (m *Options) XXX_DiscardUnknown() { + xxx_messageInfo_Options.DiscardUnknown(m) +} + +var xxx_messageInfo_Options proto.InternalMessageInfo + +func (m *Options) GetTypeUrl() string { + if m != nil { + return m.TypeUrl + } + return "" +} + +func (m *Options) GetConfigPath() string { + if m != nil { + return m.ConfigPath + } + return "" +} + +func init() { + proto.RegisterType((*Options)(nil), "runtimeoptions.v1.Options") +} + +func init() { + proto.RegisterFile("github.com/containerd/containerd/pkg/runtimeoptions/v1/api.proto", fileDescriptor_7700dd27e3487aa6) +} + +var fileDescriptor_7700dd27e3487aa6 = []byte{ + // 214 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x72, 0x48, 0xcf, 0x2c, 0xc9, + 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0xcf, 0x2b, 0x49, 0xcc, 0xcc, 0x4b, 0x2d, + 0x4a, 0x41, 0x66, 0x16, 0x64, 0xa7, 0xeb, 0x17, 0x95, 0xe6, 0x95, 0x64, 0xe6, 0xa6, 0xe6, 0x17, + 0x94, 0x64, 0xe6, 0xe7, 0x15, 0xeb, 0x97, 0x19, 0xea, 0x27, 0x16, 0x64, 0xea, 0x15, 0x14, 0xe5, + 0x97, 0xe4, 0x0b, 0x09, 0xa2, 0x4a, 0xea, 0x95, 0x19, 0x4a, 0xe9, 0x22, 0x19, 0x9a, 0x9e, 0x9f, + 0x9e, 0xaf, 0x0f, 0x56, 0x99, 0x54, 0x9a, 0x06, 0xe6, 0x81, 0x39, 0x60, 0x16, 0xc4, 0x04, 0x25, + 0x57, 0x2e, 0x76, 0x7f, 0x88, 0x66, 0x21, 0x49, 0x2e, 0x8e, 0x92, 0xca, 0x82, 0xd4, 0xf8, 0xd2, + 0xa2, 0x1c, 0x09, 0x46, 0x05, 0x46, 0x0d, 0xce, 0x20, 0x76, 0x10, 0x3f, 0xb4, 0x28, 0x47, 0x48, + 0x9e, 0x8b, 0x3b, 0x39, 0x3f, 0x2f, 0x2d, 0x33, 0x3d, 0xbe, 0x20, 0xb1, 0x24, 0x43, 0x82, 0x09, + 0x2c, 0xcb, 0x05, 0x11, 0x0a, 0x48, 0x2c, 0xc9, 0x70, 0x4a, 0x3b, 0xf1, 0x50, 0x8e, 0xf1, 0xc6, + 0x43, 0x39, 0x86, 0x86, 0x47, 0x72, 0x8c, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, + 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x51, 0x1e, 0xe4, 0x79, 0xd4, 0x1a, 0x55, 0x24, + 0xbe, 0xcc, 0x30, 0x89, 0x0d, 0xec, 0x6a, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x91, 0x3c, + 0x3e, 0x79, 0x3b, 0x01, 0x00, 0x00, +} + +func (m *Options) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Options) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Options) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ConfigPath) > 0 { + i -= len(m.ConfigPath) + copy(dAtA[i:], m.ConfigPath) + i = encodeVarintApi(dAtA, i, uint64(len(m.ConfigPath))) + i-- + dAtA[i] = 0x12 + } + if len(m.TypeUrl) > 0 { + i -= len(m.TypeUrl) + copy(dAtA[i:], m.TypeUrl) + i = encodeVarintApi(dAtA, i, uint64(len(m.TypeUrl))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintApi(dAtA []byte, offset int, v uint64) int { + offset -= sovApi(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Options) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.TypeUrl) + if l > 0 { + n += 1 + l + sovApi(uint64(l)) + } + l = len(m.ConfigPath) + if l > 0 { + n += 1 + l + sovApi(uint64(l)) + } + return n +} + +func sovApi(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozApi(x uint64) (n int) { + return sovApi(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *Options) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Options{`, + `TypeUrl:` + fmt.Sprintf("%v", this.TypeUrl) + `,`, + `ConfigPath:` + fmt.Sprintf("%v", this.ConfigPath) + `,`, + `}`, + }, "") + return s +} +func valueToStringApi(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *Options) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Options: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Options: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TypeUrl", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApi + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TypeUrl = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConfigPath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApi + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConfigPath = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApi(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApi + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipApi(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowApi + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowApi + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowApi + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthApi + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupApi + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthApi + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthApi = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowApi = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupApi = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vendor/github.com/containerd/containerd/pkg/runtimeoptions/v1/api.proto b/vendor/github.com/containerd/containerd/pkg/runtimeoptions/v1/api.proto new file mode 100644 index 0000000000..c771ea10ee --- /dev/null +++ b/vendor/github.com/containerd/containerd/pkg/runtimeoptions/v1/api.proto @@ -0,0 +1,25 @@ +// To regenerate api.pb.go run `make protos` +syntax = "proto3"; + +package runtimeoptions.v1; + +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; + +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.stringer_all) = true; +option (gogoproto.goproto_getters_all) = true; +option (gogoproto.marshaler_all) = true; +option (gogoproto.sizer_all) = true; +option (gogoproto.unmarshaler_all) = true; +option (gogoproto.goproto_unrecognized_all) = false; + + +option go_package = "github.com/containerd/containerd/pkg/runtimeoptions/v1;runtimeoptions_v1"; + +message Options { + // TypeUrl specifies the type of the content inside the config file. + string type_url = 1; + // ConfigPath specifies the filesystem location of the config file + // used by the runtime. + string config_path = 2; +} diff --git a/vendor/github.com/containerd/containerd/pkg/runtimeoptions/v1/doc.go b/vendor/github.com/containerd/containerd/pkg/runtimeoptions/v1/doc.go new file mode 100644 index 0000000000..62525652f1 --- /dev/null +++ b/vendor/github.com/containerd/containerd/pkg/runtimeoptions/v1/doc.go @@ -0,0 +1,17 @@ +/* + 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 runtimeoptions_v1 //nolint diff --git a/vendor/modules.txt b/vendor/modules.txt index 62fffe33b2..24d3e12ab0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -259,6 +259,7 @@ github.com/containerd/containerd/pkg/apparmor github.com/containerd/containerd/pkg/cap github.com/containerd/containerd/pkg/dialer github.com/containerd/containerd/pkg/kmutex +github.com/containerd/containerd/pkg/runtimeoptions/v1 github.com/containerd/containerd/pkg/seccomp github.com/containerd/containerd/pkg/shutdown github.com/containerd/containerd/pkg/ttrpcutil