Merge pull request #7764 from mxpv/config

Pass TOML configuration options for runtimes CRI is not aware of
This commit is contained in:
Maksym Pavlenko 2022-12-08 12:59:13 -08:00 committed by GitHub
commit e1abaeb386
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 91 additions and 40 deletions

View File

@ -348,6 +348,16 @@ func generateRuntimeOptions(r criconfig.Runtime, c criconfig.Config) (interface{
if err := optionsTree.Unmarshal(options); err != nil {
return nil, err
}
// For generic configuration, if no config path specified (preserving old behavior), pass
// the whole TOML configuration section to the runtime.
if runtimeOpts, ok := options.(*runtimeoptions.Options); ok && runtimeOpts.ConfigPath == "" {
runtimeOpts.ConfigBody, err = optionsTree.Marshal()
if err != nil {
return nil, fmt.Errorf("failed to marshal TOML blob for runtime %q: %v", r.Type, err)
}
}
return options, nil
}

View File

@ -32,6 +32,9 @@ type Options struct {
// 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"`
// Blob specifies an in-memory TOML blob passed from containerd's configuration section
// for this runtime. This will be used if config_path is not specified.
ConfigBody []byte `protobuf:"bytes,3,opt,name=config_body,json=configBody,proto3" json:"config_body,omitempty"`
}
func (x *Options) Reset() {
@ -80,6 +83,13 @@ func (x *Options) GetConfigPath() string {
return ""
}
func (x *Options) GetConfigBody() []byte {
if x != nil {
return x.ConfigBody
}
return nil
}
var File_github_com_containerd_containerd_pkg_runtimeoptions_v1_api_proto protoreflect.FileDescriptor
var file_github_com_containerd_containerd_pkg_runtimeoptions_v1_api_proto_rawDesc = []byte{
@ -88,16 +98,19 @@ var file_github_com_containerd_containerd_pkg_runtimeoptions_v1_api_proto_rawDes
0x72, 0x64, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x11, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x2e, 0x76, 0x31, 0x22, 0x45, 0x0a, 0x07, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x6e, 0x73, 0x2e, 0x76, 0x31, 0x22, 0x66, 0x0a, 0x07, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x12, 0x19, 0x0a, 0x08, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x07, 0x74, 0x79, 0x70, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x63,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x61, 0x74, 0x68, 0x42, 0x4a, 0x5a, 0x48,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64,
0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b,
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x6f, 0x64, 0x79, 0x42, 0x4a, 0x5a,
0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74,
0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x64, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6f,
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (

View File

@ -11,4 +11,7 @@ message Options {
// ConfigPath specifies the filesystem location of the config file
// used by the runtime.
string config_path = 2;
// Blob specifies an in-memory TOML blob passed from containerd's configuration section
// for this runtime. This will be used if config_path is not specified.
bytes config_body = 3;
}

View File

@ -20,7 +20,6 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
goruntime "runtime"
@ -35,13 +34,10 @@ import (
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/pkg/process"
"github.com/containerd/containerd/pkg/schedcore"
"github.com/containerd/containerd/protobuf/proto"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/containerd/runtime/v2/runc"
"github.com/containerd/containerd/runtime/v2/runc/options"
"github.com/containerd/containerd/runtime/v2/shim"
runcC "github.com/containerd/go-runc"
"github.com/containerd/typeurl"
exec "golang.org/x/sys/execabs"
"golang.org/x/sys/unix"
)
@ -200,39 +196,29 @@ func (manager) Start(ctx context.Context, id string, opts shim.StartOpts) (_ str
}()
// make sure to wait after start
go cmd.Wait()
if data, err := io.ReadAll(os.Stdin); err == nil {
if len(data) > 0 {
var any ptypes.Any
if err := proto.Unmarshal(data, &any); err != nil {
return "", err
}
v, err := typeurl.UnmarshalAny(&any)
if err != nil {
return "", err
}
if opts, ok := v.(*options.Options); ok {
if opts.ShimCgroup != "" {
if cgroups.Mode() == cgroups.Unified {
cg, err := cgroupsv2.Load(opts.ShimCgroup)
if err != nil {
return "", fmt.Errorf("failed to load cgroup %s: %w", opts.ShimCgroup, err)
}
if err := cg.AddProc(uint64(cmd.Process.Pid)); err != nil {
return "", fmt.Errorf("failed to join cgroup %s: %w", opts.ShimCgroup, err)
}
} else {
cg, err := cgroup1.Load(cgroup1.StaticPath(opts.ShimCgroup))
if err != nil {
return "", fmt.Errorf("failed to load cgroup %s: %w", opts.ShimCgroup, err)
}
if err := cg.AddProc(uint64(cmd.Process.Pid)); err != nil {
return "", fmt.Errorf("failed to join cgroup %s: %w", opts.ShimCgroup, err)
}
}
if opts, err := shim.ReadRuntimeOptions[*options.Options](os.Stdin); err == nil {
if opts.ShimCgroup != "" {
if cgroups.Mode() == cgroups.Unified {
cg, err := cgroupsv2.Load(opts.ShimCgroup)
if err != nil {
return "", fmt.Errorf("failed to load cgroup %s: %w", opts.ShimCgroup, err)
}
if err := cg.AddProc(uint64(cmd.Process.Pid)); err != nil {
return "", fmt.Errorf("failed to join cgroup %s: %w", opts.ShimCgroup, err)
}
} else {
cg, err := cgroup1.Load(cgroup1.StaticPath(opts.ShimCgroup))
if err != nil {
return "", fmt.Errorf("failed to load cgroup %s: %w", opts.ShimCgroup, err)
}
if err := cg.AddProc(uint64(cmd.Process.Pid)); err != nil {
return "", fmt.Errorf("failed to join cgroup %s: %w", opts.ShimCgroup, err)
}
}
}
}
if err := shim.AdjustOOMScore(cmd.Process.Pid); err != nil {
return "", fmt.Errorf("failed to adjust OOM score for shim: %w", err)
}

View File

@ -21,16 +21,20 @@ import (
"context"
"errors"
"fmt"
"io"
"net"
"os"
"path/filepath"
"strings"
"time"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/protobuf/proto"
"github.com/containerd/containerd/protobuf/types"
ptypes "github.com/containerd/containerd/protobuf/types"
"github.com/containerd/ttrpc"
"github.com/containerd/typeurl"
exec "golang.org/x/sys/execabs"
)
@ -169,6 +173,41 @@ func ReadAddress(path string) (string, error) {
return string(data), nil
}
// ReadRuntimeOptions reads config bytes from io.Reader and unmarshals it into the provided type.
// The type must be registered with typeurl.
//
// The function will return ErrNotFound, if the config is not provided.
// And ErrInvalidArgument, if unable to cast the config to the provided type T.
func ReadRuntimeOptions[T any](reader io.Reader) (T, error) {
var config T
data, err := io.ReadAll(reader)
if err != nil {
return config, fmt.Errorf("failed to read config bytes from stdin: %w", err)
}
if len(data) == 0 {
return config, errdefs.ErrNotFound
}
var any ptypes.Any
if err := proto.Unmarshal(data, &any); err != nil {
return config, err
}
v, err := typeurl.UnmarshalAny(&any)
if err != nil {
return config, err
}
config, ok := v.(T)
if !ok {
return config, fmt.Errorf("invalid type %T: %w", v, errdefs.ErrInvalidArgument)
}
return config, nil
}
// chainUnaryServerInterceptors creates a single ttrpc server interceptor from
// a chain of many interceptors executed from first to last.
func chainUnaryServerInterceptors(interceptors ...ttrpc.UnaryServerInterceptor) ttrpc.UnaryServerInterceptor {