mirror of
https://github.com/NVIDIA/nvidia-container-toolkit
synced 2025-06-26 18:18:24 +00:00
fetch current container runtime config through the command line
Signed-off-by: Tariq Ibrahim <tibrahim@nvidia.com> add default runtime binary path to runtimes field of toolkit config toml Signed-off-by: Tariq Ibrahim <tibrahim@nvidia.com> [no-relnote] Get low-level runtimes consistently We ensure that we use the same low-level runtimes regardless of the runtime engine being configured. This ensures consistent behaviour. Signed-off-by: Evan Lezar <elezar@nvidia.com> Co-authored-by: Evan Lezar <elezar@nvidia.com> address review comment Signed-off-by: Tariq Ibrahim <tibrahim@nvidia.com>
This commit is contained in:
@@ -19,9 +19,8 @@ package containerd
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pelletier/go-toml"
|
||||
|
||||
"github.com/NVIDIA/nvidia-container-toolkit/pkg/config/engine"
|
||||
"github.com/NVIDIA/nvidia-container-toolkit/pkg/config/toml"
|
||||
)
|
||||
|
||||
// ConfigV1 represents a version 1 containerd config
|
||||
@@ -39,11 +38,7 @@ func (c *ConfigV1) AddRuntime(name string, path string, setAsDefault bool) error
|
||||
|
||||
config.Set("version", int64(1))
|
||||
|
||||
// By default we extract the runtime options from the runc settings; if this does not exist we get the options from the default runtime specified in the config.
|
||||
runtimeNamesForConfig := []string{"runc"}
|
||||
if name, ok := config.GetPath([]string{"plugins", "cri", "containerd", "default_runtime_name"}).(string); ok && name != "" {
|
||||
runtimeNamesForConfig = append(runtimeNamesForConfig, name)
|
||||
}
|
||||
runtimeNamesForConfig := engine.GetLowLevelRuntimes(c)
|
||||
for _, r := range runtimeNamesForConfig {
|
||||
options := config.GetSubtreeByPath([]string{"plugins", "cri", "containerd", "runtimes", r})
|
||||
if options == nil {
|
||||
@@ -157,3 +152,14 @@ func (c *ConfigV1) Set(key string, value interface{}) {
|
||||
func (c ConfigV1) Save(path string) (int64, error) {
|
||||
return (Config)(c).Save(path)
|
||||
}
|
||||
|
||||
func (c *ConfigV1) GetRuntimeConfig(name string) (engine.RuntimeConfig, error) {
|
||||
if c == nil || c.Tree == nil {
|
||||
return nil, fmt.Errorf("config is nil")
|
||||
}
|
||||
runtimeData := c.GetSubtreeByPath([]string{"plugins", "cri", "containerd", "runtimes", name})
|
||||
|
||||
return &containerdCfgRuntime{
|
||||
tree: runtimeData,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ func TestAddRuntimeV1(t *testing.T) {
|
||||
`,
|
||||
},
|
||||
{
|
||||
description: "options from runc take precedence over default runtime",
|
||||
description: "options from the default runtime take precedence over runc",
|
||||
config: `
|
||||
[plugins]
|
||||
[plugins.cri]
|
||||
@@ -186,14 +186,14 @@ func TestAddRuntimeV1(t *testing.T) {
|
||||
BinaryName = "/usr/bin/default"
|
||||
SystemdCgroup = false
|
||||
[plugins.cri.containerd.runtimes.test]
|
||||
privileged_without_host_devices = true
|
||||
runtime_engine = "engine"
|
||||
runtime_root = "root"
|
||||
runtime_type = "type"
|
||||
privileged_without_host_devices = false
|
||||
runtime_engine = "defaultengine"
|
||||
runtime_root = "defaultroot"
|
||||
runtime_type = "defaulttype"
|
||||
[plugins.cri.containerd.runtimes.test.options]
|
||||
BinaryName = "/usr/bin/test"
|
||||
Runtime = "/usr/bin/test"
|
||||
SystemdCgroup = true
|
||||
SystemdCgroup = false
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package containerd
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/NVIDIA/nvidia-container-toolkit/pkg/config/engine"
|
||||
"github.com/NVIDIA/nvidia-container-toolkit/pkg/config/toml"
|
||||
)
|
||||
|
||||
@@ -31,11 +32,7 @@ func (c *Config) AddRuntime(name string, path string, setAsDefault bool) error {
|
||||
|
||||
config.Set("version", int64(2))
|
||||
|
||||
// By default we extract the runtime options from the runc settings; if this does not exist we get the options from the default runtime specified in the config.
|
||||
runtimeNamesForConfig := []string{"runc"}
|
||||
if name, ok := config.GetPath([]string{"plugins", "io.containerd.grpc.v1.cri", "containerd", "default_runtime_name"}).(string); ok && name != "" {
|
||||
runtimeNamesForConfig = append(runtimeNamesForConfig, name)
|
||||
}
|
||||
runtimeNamesForConfig := engine.GetLowLevelRuntimes(c)
|
||||
for _, r := range runtimeNamesForConfig {
|
||||
options := config.GetSubtreeByPath([]string{"plugins", "io.containerd.grpc.v1.cri", "containerd", "runtimes", r})
|
||||
if options == nil {
|
||||
|
||||
@@ -137,7 +137,7 @@ func TestAddRuntime(t *testing.T) {
|
||||
`,
|
||||
},
|
||||
{
|
||||
description: "options from runc take precedence over default runtime",
|
||||
description: "options from the default runtime take precedence over runc",
|
||||
config: `
|
||||
version = 2
|
||||
[plugins]
|
||||
@@ -186,13 +186,13 @@ func TestAddRuntime(t *testing.T) {
|
||||
BinaryName = "/usr/bin/default"
|
||||
SystemdCgroup = false
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test]
|
||||
privileged_without_host_devices = true
|
||||
runtime_engine = "engine"
|
||||
runtime_root = "root"
|
||||
runtime_type = "type"
|
||||
privileged_without_host_devices = false
|
||||
runtime_engine = "defaultengine"
|
||||
runtime_root = "defaultroot"
|
||||
runtime_type = "defaulttype"
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test.options]
|
||||
BinaryName = "/usr/bin/test"
|
||||
SystemdCgroup = true
|
||||
SystemdCgroup = false
|
||||
`,
|
||||
},
|
||||
}
|
||||
@@ -216,3 +216,99 @@ func TestAddRuntime(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRuntimeConfig(t *testing.T) {
|
||||
logger, _ := testlog.NewNullLogger()
|
||||
config := `
|
||||
version = 2
|
||||
[plugins]
|
||||
[plugins."io.containerd.grpc.v1.cri"]
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd]
|
||||
default_runtime_name = "nvidia"
|
||||
disable_snapshot_annotations = true
|
||||
discard_unpacked_layers = false
|
||||
ignore_blockio_not_enabled_errors = false
|
||||
ignore_rdt_not_enabled_errors = false
|
||||
no_pivot = false
|
||||
snapshotter = "overlayfs"
|
||||
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
|
||||
base_runtime_spec = ""
|
||||
cni_conf_dir = ""
|
||||
cni_max_conf_num = 0
|
||||
container_annotations = []
|
||||
pod_annotations = []
|
||||
privileged_without_host_devices = false
|
||||
privileged_without_host_devices_all_devices_allowed = false
|
||||
runtime_engine = ""
|
||||
runtime_path = ""
|
||||
runtime_root = ""
|
||||
runtime_type = ""
|
||||
sandbox_mode = ""
|
||||
snapshotter = ""
|
||||
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
|
||||
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
|
||||
base_runtime_spec = ""
|
||||
cni_conf_dir = ""
|
||||
cni_max_conf_num = 0
|
||||
container_annotations = []
|
||||
pod_annotations = []
|
||||
privileged_without_host_devices = false
|
||||
privileged_without_host_devices_all_devices_allowed = false
|
||||
runtime_engine = ""
|
||||
runtime_path = ""
|
||||
runtime_root = ""
|
||||
runtime_type = "io.containerd.runc.v2"
|
||||
sandbox_mode = "podsandbox"
|
||||
snapshotter = ""
|
||||
|
||||
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
|
||||
BinaryName = "/usr/bin/runc"
|
||||
CriuImagePath = ""
|
||||
CriuPath = ""
|
||||
CriuWorkPath = ""
|
||||
IoGid = 0
|
||||
IoUid = 0
|
||||
NoNewKeyring = false
|
||||
NoPivotRoot = false
|
||||
Root = ""
|
||||
ShimCgroup = ""
|
||||
SystemdCgroup = false
|
||||
`
|
||||
testCases := []struct {
|
||||
description string
|
||||
runtime string
|
||||
expected string
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
description: "valid runtime config, existing runtime",
|
||||
runtime: "runc",
|
||||
expected: "/usr/bin/runc",
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
description: "valid runtime config, non-existing runtime",
|
||||
runtime: "some-other-runtime",
|
||||
expected: "",
|
||||
expectedError: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
cfg, err := toml.Load(config)
|
||||
require.NoError(t, err)
|
||||
|
||||
c := &Config{
|
||||
Logger: logger,
|
||||
Tree: cfg,
|
||||
}
|
||||
rc, err := c.GetRuntimeConfig(tc.runtime)
|
||||
require.Equal(t, tc.expectedError, err)
|
||||
require.Equal(t, tc.expected, rc.GetBinaryPath())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,22 @@ type Config struct {
|
||||
|
||||
var _ engine.Interface = (*Config)(nil)
|
||||
|
||||
type containerdCfgRuntime struct {
|
||||
tree *toml.Tree
|
||||
}
|
||||
|
||||
var _ engine.RuntimeConfig = (*containerdCfgRuntime)(nil)
|
||||
|
||||
// GetBinaryPath retrieves the path to the actual low-level runtime binary invoked by the runtime handler
|
||||
func (c *containerdCfgRuntime) GetBinaryPath() string {
|
||||
if c == nil || c.tree == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
binPath, _ := c.tree.GetPath([]string{"options", "BinaryName"}).(string)
|
||||
return binPath
|
||||
}
|
||||
|
||||
// New creates a containerd config with the specified options
|
||||
func New(opts ...Option) (engine.Interface, error) {
|
||||
b := &builder{
|
||||
@@ -98,3 +114,27 @@ func (c *Config) parseVersion(useLegacyConfig bool) (int, error) {
|
||||
return -1, fmt.Errorf("unsupported type for version field: %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Config) GetRuntimeConfig(name string) (engine.RuntimeConfig, error) {
|
||||
if c == nil || c.Tree == nil {
|
||||
return nil, fmt.Errorf("config is nil")
|
||||
}
|
||||
runtimeData := c.GetSubtreeByPath([]string{"plugins", "io.containerd.grpc.v1.cri", "containerd", "runtimes", name})
|
||||
return &containerdCfgRuntime{
|
||||
tree: runtimeData,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CommandLineSource returns the CLI-based containerd config loader
|
||||
func CommandLineSource(hostRoot string) toml.Loader {
|
||||
commandLine := chrootIfRequired(hostRoot, "containerd", "config", "dump")
|
||||
return toml.FromCommandLine(commandLine[0], commandLine[1:]...)
|
||||
}
|
||||
|
||||
func chrootIfRequired(hostRoot string, commandLine ...string) []string {
|
||||
if hostRoot == "" || hostRoot == "/" {
|
||||
return commandLine
|
||||
}
|
||||
|
||||
return append([]string{"chroot", hostRoot}, commandLine...)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user