Skip to content

Commit

Permalink
Merge pull request #7764 from mxpv/config
Browse files Browse the repository at this point in the history
Pass TOML configuration options for runtimes CRI is not aware of
  • Loading branch information
mxpv committed Dec 8, 2022
2 parents 34513f9 + 8ab1d44 commit e1abaeb
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 40 deletions.
10 changes: 10 additions & 0 deletions pkg/cri/sbserver/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
27 changes: 20 additions & 7 deletions pkg/runtimeoptions/v1/api.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions pkg/runtimeoptions/v1/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
52 changes: 19 additions & 33 deletions runtime/v2/runc/manager/manager_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
goruntime "runtime"
Expand All @@ -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"
)
Expand Down Expand Up @@ -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)
}
Expand Down
39 changes: 39 additions & 0 deletions runtime/v2/shim/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit e1abaeb

Please sign in to comment.