Unverified Commit ba5fcf13 authored by Flavio Castelli's avatar Flavio Castelli Committed by GitHub

Wasm shims and runtimes detection

Create a generic helper function that finds extra containerd runtimes. The code was originally inside of the nvidia container discovery file. Signed-off-by: 's avatarFlavio Castelli <fcastelli@suse.com> Discover the containerd shims based on runwasi that are already available on the node. The runtimes could have been installed either by a package manager or by the kwasm operator. Signed-off-by: 's avatarFlavio Castelli <fcastelli@suse.com> The containerd configuration on a Linux system now handles the nvidia and the WebAssembly runtimes. Signed-off-by: 's avatarFlavio Castelli <fcastelli@suse.com> --------- Signed-off-by: 's avatarFlavio Castelli <fcastelli@suse.com>
parent 875a9d19
...@@ -60,6 +60,10 @@ func setupContainerdConfig(ctx context.Context, cfg *config.Node) error { ...@@ -60,6 +60,10 @@ func setupContainerdConfig(ctx context.Context, cfg *config.Node) error {
cfg.AgentConfig.Systemd = !isRunningInUserNS && controllers["cpuset"] && os.Getenv("INVOCATION_ID") != "" cfg.AgentConfig.Systemd = !isRunningInUserNS && controllers["cpuset"] && os.Getenv("INVOCATION_ID") != ""
} }
extraRuntimes := runtimeConfigs{}
findNvidiaContainerRuntimes(os.DirFS(string(os.PathSeparator)), extraRuntimes)
findWasiRuntimes(os.DirFS(string(os.PathSeparator)), extraRuntimes)
var containerdTemplate string var containerdTemplate string
containerdConfig := templates.ContainerdConfig{ containerdConfig := templates.ContainerdConfig{
NodeConfig: cfg, NodeConfig: cfg,
...@@ -68,7 +72,7 @@ func setupContainerdConfig(ctx context.Context, cfg *config.Node) error { ...@@ -68,7 +72,7 @@ func setupContainerdConfig(ctx context.Context, cfg *config.Node) error {
IsRunningInUserNS: isRunningInUserNS, IsRunningInUserNS: isRunningInUserNS,
EnableUnprivileged: kernel.CheckKernelVersion(4, 11, 0), EnableUnprivileged: kernel.CheckKernelVersion(4, 11, 0),
PrivateRegistryConfig: privRegistries.Registry, PrivateRegistryConfig: privRegistries.Registry,
ExtraRuntimes: findNvidiaContainerRuntimes(os.DirFS(string(os.PathSeparator))), ExtraRuntimes: extraRuntimes,
Program: version.Program, Program: version.Program,
} }
......
...@@ -4,12 +4,7 @@ ...@@ -4,12 +4,7 @@
package containerd package containerd
import ( import (
"errors"
"io/fs" "io/fs"
"path/filepath"
"github.com/k3s-io/k3s/pkg/agent/templates"
"github.com/sirupsen/logrus"
) )
// findNvidiaContainerRuntimes returns a list of nvidia container runtimes that // findNvidiaContainerRuntimes returns a list of nvidia container runtimes that
...@@ -17,7 +12,7 @@ import ( ...@@ -17,7 +12,7 @@ import (
// gpu operator and by system package managers. The gpu operator installation // gpu operator and by system package managers. The gpu operator installation
// takes precedence over the system package manager installation. // takes precedence over the system package manager installation.
// The given fs.FS should represent the filesystem root directory to search in. // The given fs.FS should represent the filesystem root directory to search in.
func findNvidiaContainerRuntimes(root fs.FS) map[string]templates.ContainerdRuntimeConfig { func findNvidiaContainerRuntimes(root fs.FS, foundRuntimes runtimeConfigs) {
// Check these locations in order. The GPU operator's installation should // Check these locations in order. The GPU operator's installation should
// take precedence over the package manager's installation. // take precedence over the package manager's installation.
locationsToCheck := []string{ locationsToCheck := []string{
...@@ -28,7 +23,7 @@ func findNvidiaContainerRuntimes(root fs.FS) map[string]templates.ContainerdRunt ...@@ -28,7 +23,7 @@ func findNvidiaContainerRuntimes(root fs.FS) map[string]templates.ContainerdRunt
// Fill in the binary location with just the name of the binary, // Fill in the binary location with just the name of the binary,
// and check against each of the possible locations. If a match is found, // and check against each of the possible locations. If a match is found,
// set the location to the full path. // set the location to the full path.
potentialRuntimes := map[string]templates.ContainerdRuntimeConfig{ potentialRuntimes := runtimeConfigs{
"nvidia": { "nvidia": {
RuntimeType: "io.containerd.runc.v2", RuntimeType: "io.containerd.runc.v2",
BinaryName: "nvidia-container-runtime", BinaryName: "nvidia-container-runtime",
...@@ -38,30 +33,5 @@ func findNvidiaContainerRuntimes(root fs.FS) map[string]templates.ContainerdRunt ...@@ -38,30 +33,5 @@ func findNvidiaContainerRuntimes(root fs.FS) map[string]templates.ContainerdRunt
BinaryName: "nvidia-container-runtime-experimental", BinaryName: "nvidia-container-runtime-experimental",
}, },
} }
foundRuntimes := map[string]templates.ContainerdRuntimeConfig{} findContainerRuntimes(root, potentialRuntimes, locationsToCheck, foundRuntimes)
RUNTIME:
for runtimeName, runtimeConfig := range potentialRuntimes {
for _, location := range locationsToCheck {
binaryPath := filepath.Join(location, runtimeConfig.BinaryName)
logrus.Debugf("Searching for %s container runtime at /%s", runtimeName, binaryPath)
if info, err := fs.Stat(root, binaryPath); err == nil {
if info.IsDir() {
logrus.Debugf("Found %s container runtime at /%s, but it is a directory. Skipping.", runtimeName, binaryPath)
continue
}
runtimeConfig.BinaryName = filepath.Join("/", binaryPath)
logrus.Infof("Found %s container runtime at %s", runtimeName, runtimeConfig.BinaryName)
foundRuntimes[runtimeName] = runtimeConfig
// Skip to the next runtime to enforce precedence.
continue RUNTIME
} else {
if errors.Is(err, fs.ErrNotExist) {
logrus.Debugf("%s container runtime not found at /%s", runtimeName, binaryPath)
} else {
logrus.Errorf("Error searching for %s container runtime at /%s: %v", runtimeName, binaryPath, err)
}
}
}
}
return foundRuntimes
} }
...@@ -8,26 +8,26 @@ import ( ...@@ -8,26 +8,26 @@ import (
"reflect" "reflect"
"testing" "testing"
"testing/fstest" "testing/fstest"
"github.com/k3s-io/k3s/pkg/agent/templates"
) )
func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
executable := &fstest.MapFile{Mode: 0755} executable := &fstest.MapFile{Mode: 0755}
type args struct { type args struct {
root fs.FS root fs.FS
alreadyFoundRuntimes runtimeConfigs
} }
tests := []struct { tests := []struct {
name string name string
args args args args
want map[string]templates.ContainerdRuntimeConfig want runtimeConfigs
}{ }{
{ {
name: "No runtimes", name: "No runtimes",
args: args{ args: args{
root: fstest.MapFS{}, root: fstest.MapFS{},
alreadyFoundRuntimes: runtimeConfigs{},
}, },
want: map[string]templates.ContainerdRuntimeConfig{}, want: runtimeConfigs{},
}, },
{ {
name: "Nvidia runtime in /usr/bin", name: "Nvidia runtime in /usr/bin",
...@@ -35,8 +35,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { ...@@ -35,8 +35,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
root: fstest.MapFS{ root: fstest.MapFS{
"usr/bin/nvidia-container-runtime": executable, "usr/bin/nvidia-container-runtime": executable,
}, },
alreadyFoundRuntimes: runtimeConfigs{},
}, },
want: map[string]templates.ContainerdRuntimeConfig{ want: runtimeConfigs{
"nvidia": { "nvidia": {
RuntimeType: "io.containerd.runc.v2", RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/bin/nvidia-container-runtime", BinaryName: "/usr/bin/nvidia-container-runtime",
...@@ -49,8 +50,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { ...@@ -49,8 +50,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
root: fstest.MapFS{ root: fstest.MapFS{
"usr/local/nvidia/toolkit/nvidia-container-runtime": executable, "usr/local/nvidia/toolkit/nvidia-container-runtime": executable,
}, },
alreadyFoundRuntimes: runtimeConfigs{},
}, },
want: map[string]templates.ContainerdRuntimeConfig{ want: runtimeConfigs{
"nvidia": { "nvidia": {
RuntimeType: "io.containerd.runc.v2", RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/local/nvidia/toolkit/nvidia-container-runtime", BinaryName: "/usr/local/nvidia/toolkit/nvidia-container-runtime",
...@@ -64,8 +66,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { ...@@ -64,8 +66,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
"usr/bin/nvidia-container-runtime": executable, "usr/bin/nvidia-container-runtime": executable,
"usr/local/nvidia/toolkit/nvidia-container-runtime": executable, "usr/local/nvidia/toolkit/nvidia-container-runtime": executable,
}, },
alreadyFoundRuntimes: runtimeConfigs{},
}, },
want: map[string]templates.ContainerdRuntimeConfig{ want: runtimeConfigs{
"nvidia": { "nvidia": {
RuntimeType: "io.containerd.runc.v2", RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/local/nvidia/toolkit/nvidia-container-runtime", BinaryName: "/usr/local/nvidia/toolkit/nvidia-container-runtime",
...@@ -78,8 +81,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { ...@@ -78,8 +81,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
root: fstest.MapFS{ root: fstest.MapFS{
"usr/bin/nvidia-container-runtime-experimental": executable, "usr/bin/nvidia-container-runtime-experimental": executable,
}, },
alreadyFoundRuntimes: runtimeConfigs{},
}, },
want: map[string]templates.ContainerdRuntimeConfig{ want: runtimeConfigs{
"nvidia-experimental": { "nvidia-experimental": {
RuntimeType: "io.containerd.runc.v2", RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/bin/nvidia-container-runtime-experimental", BinaryName: "/usr/bin/nvidia-container-runtime-experimental",
...@@ -93,8 +97,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { ...@@ -93,8 +97,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
"usr/bin/nvidia-container-runtime-experimental": executable, "usr/bin/nvidia-container-runtime-experimental": executable,
"usr/local/nvidia/toolkit/nvidia-container-runtime-experimental": executable, "usr/local/nvidia/toolkit/nvidia-container-runtime-experimental": executable,
}, },
alreadyFoundRuntimes: runtimeConfigs{},
}, },
want: map[string]templates.ContainerdRuntimeConfig{ want: runtimeConfigs{
"nvidia-experimental": { "nvidia-experimental": {
RuntimeType: "io.containerd.runc.v2", RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/local/nvidia/toolkit/nvidia-container-runtime-experimental", BinaryName: "/usr/local/nvidia/toolkit/nvidia-container-runtime-experimental",
...@@ -108,8 +113,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { ...@@ -108,8 +113,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
"usr/bin/nvidia-container-runtime-experimental": executable, "usr/bin/nvidia-container-runtime-experimental": executable,
"usr/bin/nvidia-container-runtime": executable, "usr/bin/nvidia-container-runtime": executable,
}, },
alreadyFoundRuntimes: runtimeConfigs{},
}, },
want: map[string]templates.ContainerdRuntimeConfig{ want: runtimeConfigs{
"nvidia": { "nvidia": {
RuntimeType: "io.containerd.runc.v2", RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/bin/nvidia-container-runtime", BinaryName: "/usr/bin/nvidia-container-runtime",
...@@ -129,8 +135,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { ...@@ -129,8 +135,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
"usr/bin/nvidia-container-runtime": executable, "usr/bin/nvidia-container-runtime": executable,
"usr/bin/nvidia-container-runtime-experimental": executable, "usr/bin/nvidia-container-runtime-experimental": executable,
}, },
alreadyFoundRuntimes: runtimeConfigs{},
}, },
want: map[string]templates.ContainerdRuntimeConfig{ want: runtimeConfigs{
"nvidia": { "nvidia": {
RuntimeType: "io.containerd.runc.v2", RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/local/nvidia/toolkit/nvidia-container-runtime", BinaryName: "/usr/local/nvidia/toolkit/nvidia-container-runtime",
...@@ -148,8 +155,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { ...@@ -148,8 +155,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
"usr/local/nvidia/toolkit/nvidia-container-runtime": executable, "usr/local/nvidia/toolkit/nvidia-container-runtime": executable,
"usr/local/nvidia/toolkit/nvidia-container-runtime-experimental": executable, "usr/local/nvidia/toolkit/nvidia-container-runtime-experimental": executable,
}, },
alreadyFoundRuntimes: runtimeConfigs{},
}, },
want: map[string]templates.ContainerdRuntimeConfig{ want: runtimeConfigs{
"nvidia": { "nvidia": {
RuntimeType: "io.containerd.runc.v2", RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/local/nvidia/toolkit/nvidia-container-runtime", BinaryName: "/usr/local/nvidia/toolkit/nvidia-container-runtime",
...@@ -168,8 +176,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { ...@@ -168,8 +176,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
"usr/bin/nvidia-container-runtime-experimental": executable, "usr/bin/nvidia-container-runtime-experimental": executable,
"usr/local/nvidia/toolkit/nvidia-container-runtime-experimental": executable, "usr/local/nvidia/toolkit/nvidia-container-runtime-experimental": executable,
}, },
alreadyFoundRuntimes: runtimeConfigs{},
}, },
want: map[string]templates.ContainerdRuntimeConfig{ want: runtimeConfigs{
"nvidia": { "nvidia": {
RuntimeType: "io.containerd.runc.v2", RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/bin/nvidia-container-runtime", BinaryName: "/usr/bin/nvidia-container-runtime",
...@@ -188,8 +197,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { ...@@ -188,8 +197,9 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
Mode: fs.ModeDir, Mode: fs.ModeDir,
}, },
}, },
alreadyFoundRuntimes: runtimeConfigs{},
}, },
want: map[string]templates.ContainerdRuntimeConfig{}, want: runtimeConfigs{},
}, },
{ {
name: "Runtime in both directories, but one is a directory", name: "Runtime in both directories, but one is a directory",
...@@ -200,8 +210,44 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { ...@@ -200,8 +210,44 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
Mode: fs.ModeDir, Mode: fs.ModeDir,
}, },
}, },
alreadyFoundRuntimes: runtimeConfigs{},
},
want: runtimeConfigs{
"nvidia": {
RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/bin/nvidia-container-runtime",
},
}, },
want: map[string]templates.ContainerdRuntimeConfig{ },
{
name: "Preserve already found runtimes",
args: args{
root: fstest.MapFS{
"usr/bin/nvidia-container-runtime": executable,
"usr/local/nvidia/toolkit/nvidia-container-runtime": &fstest.MapFile{
Mode: fs.ModeDir,
},
},
alreadyFoundRuntimes: runtimeConfigs{
"slight": {
RuntimeType: "io.containerd.slight.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-slight-v1",
},
"wasmtime": {
RuntimeType: "io.containerd.wasmtime.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-wasmtime-v1",
},
},
},
want: runtimeConfigs{
"slight": {
RuntimeType: "io.containerd.slight.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-slight-v1",
},
"wasmtime": {
RuntimeType: "io.containerd.wasmtime.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-wasmtime-v1",
},
"nvidia": { "nvidia": {
RuntimeType: "io.containerd.runc.v2", RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/bin/nvidia-container-runtime", BinaryName: "/usr/bin/nvidia-container-runtime",
...@@ -211,8 +257,10 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) { ...@@ -211,8 +257,10 @@ func Test_UnitFindNvidiaContainerRuntimes(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if got := findNvidiaContainerRuntimes(tt.args.root); !reflect.DeepEqual(got, tt.want) { foundRuntimes := tt.args.alreadyFoundRuntimes
t.Errorf("findNvidiaContainerRuntimes() = %+v\nWant = %+v", got, tt.want) findNvidiaContainerRuntimes(tt.args.root, foundRuntimes)
if !reflect.DeepEqual(foundRuntimes, tt.want) {
t.Errorf("findNvidiaContainerRuntimes() = %+v\nWant = %+v", foundRuntimes, tt.want)
} }
}) })
} }
......
//go:build linux
// +build linux
package containerd
import (
"errors"
"io/fs"
"path/filepath"
"github.com/k3s-io/k3s/pkg/agent/templates"
"github.com/sirupsen/logrus"
)
// A map with string as value and `templates.ContainerdRuntimeConfig` as values.
// The key holds the name of the runtime
type runtimeConfigs map[string]templates.ContainerdRuntimeConfig
// findContainerRuntimes returns a list of container runtimes that
// are available on the system. It checks install locations provided via
// the potentialRuntimes variable.
// The binaries are searched at the locations specivied by locationsToCheck.
// Note: check the given locations in order.
// The given fs.FS should represent the filesystem root directory to search in.
func findContainerRuntimes(root fs.FS, potentialRuntimes runtimeConfigs, locationsToCheck []string, foundRuntimes runtimeConfigs) {
// Check these locations in order. The GPU operator's installation should
// take precedence over the package manager's installation.
// Fill in the binary location with just the name of the binary,
// and check against each of the possible locations. If a match is found,
// set the location to the full path.
RUNTIME:
for runtimeName, runtimeConfig := range potentialRuntimes {
for _, location := range locationsToCheck {
binaryPath := filepath.Join(location, runtimeConfig.BinaryName)
logrus.Debugf("Searching for %s container runtime at /%s", runtimeName, binaryPath)
if info, err := fs.Stat(root, binaryPath); err == nil {
if info.IsDir() {
logrus.Debugf("Found %s container runtime at /%s, but it is a directory. Skipping.", runtimeName, binaryPath)
continue
}
runtimeConfig.BinaryName = filepath.Join("/", binaryPath)
logrus.Infof("Found %s container runtime at %s", runtimeName, runtimeConfig.BinaryName)
foundRuntimes[runtimeName] = runtimeConfig
// Skip to the next runtime to enforce precedence.
continue RUNTIME
} else {
if errors.Is(err, fs.ErrNotExist) {
logrus.Debugf("%s container runtime not found at /%s", runtimeName, binaryPath)
} else {
logrus.Errorf("Error searching for %s container runtime at /%s: %v", runtimeName, binaryPath, err)
}
}
}
}
}
//go:build linux
// +build linux
package containerd
import (
"io/fs"
"reflect"
"testing"
"testing/fstest"
)
func Test_UnitFindContainerRuntimes(t *testing.T) {
executable := &fstest.MapFile{Mode: 0755}
locationsToCheck := []string{
"usr/local/nvidia/toolkit", // Path for nvidia shim when installing via GPU Operator
"opt/kwasm/bin", // Path for wasm shim when installing via the kwasm operator
"usr/bin", // Path when installing via package manager
"usr/sbin", // Path when installing via package manager
}
potentialRuntimes := runtimeConfigs{
"nvidia": {
RuntimeType: "io.containerd.runc.v2",
BinaryName: "nvidia-container-runtime",
},
"spin": {
RuntimeType: "io.containerd.spin.v2",
BinaryName: "containerd-shim-spin-v1",
},
}
type args struct {
root fs.FS
potentialRuntimes runtimeConfigs
locationsToCheck []string
}
tests := []struct {
name string
args args
want runtimeConfigs
}{
{
name: "No runtimes",
args: args{
root: fstest.MapFS{},
locationsToCheck: locationsToCheck,
potentialRuntimes: potentialRuntimes,
},
want: runtimeConfigs{},
},
{
name: "Nvidia runtime in /usr/bin",
args: args{
root: fstest.MapFS{
"usr/bin/nvidia-container-runtime": executable,
},
locationsToCheck: locationsToCheck,
potentialRuntimes: potentialRuntimes,
},
want: runtimeConfigs{
"nvidia": {
RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/bin/nvidia-container-runtime",
},
},
},
{
name: "Two runtimes in separate directories",
args: args{
root: fstest.MapFS{
"usr/bin/nvidia-container-runtime": executable,
"opt/kwasm/bin/containerd-shim-spin-v1": executable,
},
locationsToCheck: locationsToCheck,
potentialRuntimes: potentialRuntimes,
},
want: runtimeConfigs{
"nvidia": {
RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/bin/nvidia-container-runtime",
},
"spin": {
RuntimeType: "io.containerd.spin.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-spin-v1",
},
},
},
{
name: "Same runtime in two directories",
args: args{
root: fstest.MapFS{
"usr/bin/containerd-shim-spin-v1": executable,
"opt/kwasm/bin/containerd-shim-spin-v1": executable,
},
locationsToCheck: locationsToCheck,
potentialRuntimes: potentialRuntimes,
},
want: runtimeConfigs{
"spin": {
RuntimeType: "io.containerd.spin.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-spin-v1",
},
},
},
{
name: "Both runtimes in /usr/bin",
args: args{
root: fstest.MapFS{
"usr/bin/containerd-shim-spin-v1": executable,
"usr/bin/nvidia-container-runtime": executable,
},
locationsToCheck: locationsToCheck,
potentialRuntimes: potentialRuntimes,
},
want: runtimeConfigs{
"nvidia": {
RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/bin/nvidia-container-runtime",
},
"spin": {
RuntimeType: "io.containerd.spin.v2",
BinaryName: "/usr/bin/containerd-shim-spin-v1",
},
},
},
{
name: "Both runtimes in both directories",
args: args{
root: fstest.MapFS{
"usr/local/nvidia/toolkit/nvidia-container-runtime": executable,
"usr/bin/nvidia-container-runtime": executable,
"usr/bin/containerd-shim-spin-v1": executable,
"opt/kwasm/bin/containerd-shim-spin-v1": executable,
},
locationsToCheck: locationsToCheck,
potentialRuntimes: potentialRuntimes,
},
want: runtimeConfigs{
"nvidia": {
RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/local/nvidia/toolkit/nvidia-container-runtime",
},
"spin": {
RuntimeType: "io.containerd.spin.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-spin-v1",
},
},
},
{
name: "Both runtimes in /usr/bin and one duplicate in /usr/local/nvidia/toolkit",
args: args{
root: fstest.MapFS{
"usr/bin/nvidia-container-runtime": executable,
"usr/bin/containerd-shim-spin-v1": executable,
"usr/local/nvidia/toolkit/nvidia-container-runtime": executable,
},
locationsToCheck: locationsToCheck,
potentialRuntimes: potentialRuntimes,
},
want: runtimeConfigs{
"spin": {
RuntimeType: "io.containerd.spin.v2",
BinaryName: "/usr/bin/containerd-shim-spin-v1",
},
"nvidia": {
RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/local/nvidia/toolkit/nvidia-container-runtime",
},
},
},
{
name: "Runtime is a directory",
args: args{
root: fstest.MapFS{
"usr/bin/nvidia-container-runtime": &fstest.MapFile{
Mode: fs.ModeDir,
},
},
locationsToCheck: locationsToCheck,
potentialRuntimes: potentialRuntimes,
},
want: runtimeConfigs{},
},
{
name: "Runtime in both directories, but one is a directory",
args: args{
root: fstest.MapFS{
"usr/bin/nvidia-container-runtime": executable,
"usr/local/nvidia/toolkit/nvidia-container-runtime": &fstest.MapFile{
Mode: fs.ModeDir,
},
},
locationsToCheck: locationsToCheck,
potentialRuntimes: potentialRuntimes,
},
want: runtimeConfigs{
"nvidia": {
RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/bin/nvidia-container-runtime",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
foundRuntimes := runtimeConfigs{}
findContainerRuntimes(tt.args.root, tt.args.potentialRuntimes, tt.args.locationsToCheck, foundRuntimes)
if !reflect.DeepEqual(foundRuntimes, tt.want) {
t.Errorf("findContainerRuntimes() = %+v\nWant = %+v", foundRuntimes, tt.want)
}
})
}
}
//go:build linux
// +build linux
package containerd
import (
"io/fs"
)
// findWasiRuntimes returns a list of WebAssembly (WASI) container runtimes that
// are available on the system. It checks install locations used by the kwasm
// operator and by system package managers. The kwasm operator installation
// takes precedence over the system package manager installation.
// The given fs.FS should represent the filesystem root directory to search in.
func findWasiRuntimes(root fs.FS,
foundRuntimes runtimeConfigs,
) {
// Check these locations in order. The GPU operator's installation should
// take precedence over the package manager's installation.
locationsToCheck := []string{
"opt/kwasm/bin", // Path when installing via kwasm Operator
"usr/bin", // Path when installing via package manager
"usr/sbin", // Path when installing via package manager
}
// Fill in the binary location with just the name of the binary,
// and check against each of the possible locations. If a match is found,
// set the location to the full path.
potentialRuntimes := runtimeConfigs{
"lunatic": {
RuntimeType: "io.containerd.lunatic.v2",
BinaryName: "containerd-shim-lunatic-v1",
},
"slight": {
RuntimeType: "io.containerd.slight.v2",
BinaryName: "containerd-shim-slight-v1",
},
"spin": {
RuntimeType: "io.containerd.spin.v2",
BinaryName: "containerd-shim-spin-v1",
},
"wws": {
RuntimeType: "io.containerd.wws.v2",
BinaryName: "containerd-shim-wws-v1",
},
"wasmedge": {
RuntimeType: "io.containerd.wasmedge.v2",
BinaryName: "containerd-shim-wasmedge-v1",
},
"wasmer": {
RuntimeType: "io.containerd.wasmer.v2",
BinaryName: "containerd-shim-wasmer-v1",
},
"wasmtime": {
RuntimeType: "io.containerd.wasmtime.v2",
BinaryName: "containerd-shim-wasmtime-v1",
},
}
findContainerRuntimes(root, potentialRuntimes, locationsToCheck, foundRuntimes)
}
//go:build linux
// +build linux
package containerd
import (
"io/fs"
"reflect"
"testing"
"testing/fstest"
)
func Test_UnitFindWasiRuntimes(t *testing.T) {
executable := &fstest.MapFile{Mode: 0755}
type args struct {
root fs.FS
alreadyFoundRuntimes runtimeConfigs
}
tests := []struct {
name string
args args
want runtimeConfigs
}{
{
name: "No runtimes",
args: args{
root: fstest.MapFS{},
alreadyFoundRuntimes: runtimeConfigs{},
},
want: runtimeConfigs{},
},
{
name: "wasmtime runtime in /usr/sbin",
args: args{
root: fstest.MapFS{
"usr/sbin/containerd-shim-wasmtime-v1": executable,
},
alreadyFoundRuntimes: runtimeConfigs{},
},
want: runtimeConfigs{
"wasmtime": {
RuntimeType: "io.containerd.wasmtime.v2",
BinaryName: "/usr/sbin/containerd-shim-wasmtime-v1",
},
},
},
{
name: "lunatic runtime in /opt/kwasm/bin/",
args: args{
root: fstest.MapFS{
"opt/kwasm/bin/containerd-shim-lunatic-v1": executable,
},
alreadyFoundRuntimes: runtimeConfigs{},
},
want: runtimeConfigs{
"lunatic": {
RuntimeType: "io.containerd.lunatic.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-lunatic-v1",
},
},
},
{
name: "Two runtimes in separate directories",
args: args{
root: fstest.MapFS{
"usr/bin/containerd-shim-wasmer-v1": executable,
"opt/kwasm/bin/containerd-shim-slight-v1": executable,
},
alreadyFoundRuntimes: runtimeConfigs{},
},
want: runtimeConfigs{
"slight": {
RuntimeType: "io.containerd.slight.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-slight-v1",
},
"wasmer": {
RuntimeType: "io.containerd.wasmer.v2",
BinaryName: "/usr/bin/containerd-shim-wasmer-v1",
},
},
},
{
name: "Same runtime in two directories",
args: args{
root: fstest.MapFS{
"usr/bin/containerd-shim-wasmedge-v1": executable,
"opt/kwasm/bin/containerd-shim-wasmedge-v1": executable,
},
alreadyFoundRuntimes: runtimeConfigs{},
},
want: runtimeConfigs{
"wasmedge": {
RuntimeType: "io.containerd.wasmedge.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-wasmedge-v1",
},
},
},
{
name: "All runtimes in /usr/bin",
args: args{
root: fstest.MapFS{
"usr/bin/containerd-shim-lunatic-v1": executable,
"usr/bin/containerd-shim-slight-v1": executable,
"usr/bin/containerd-shim-spin-v1": executable,
"usr/bin/containerd-shim-wws-v1": executable,
"usr/bin/containerd-shim-wasmedge-v1": executable,
"usr/bin/containerd-shim-wasmer-v1": executable,
"usr/bin/containerd-shim-wasmtime-v1": executable,
},
alreadyFoundRuntimes: runtimeConfigs{},
},
want: runtimeConfigs{
"lunatic": {
RuntimeType: "io.containerd.lunatic.v2",
BinaryName: "/usr/bin/containerd-shim-lunatic-v1",
},
"slight": {
RuntimeType: "io.containerd.slight.v2",
BinaryName: "/usr/bin/containerd-shim-slight-v1",
},
"spin": {
RuntimeType: "io.containerd.spin.v2",
BinaryName: "/usr/bin/containerd-shim-spin-v1",
},
"wws": {
RuntimeType: "io.containerd.wws.v2",
BinaryName: "/usr/bin/containerd-shim-wws-v1",
},
"wasmedge": {
RuntimeType: "io.containerd.wasmedge.v2",
BinaryName: "/usr/bin/containerd-shim-wasmedge-v1",
},
"wasmer": {
RuntimeType: "io.containerd.wasmer.v2",
BinaryName: "/usr/bin/containerd-shim-wasmer-v1",
},
"wasmtime": {
RuntimeType: "io.containerd.wasmtime.v2",
BinaryName: "/usr/bin/containerd-shim-wasmtime-v1",
},
},
},
{
name: "Both runtimes in both directories",
args: args{
root: fstest.MapFS{
"opt/kwasm/bin/containerd-shim-slight-v1": executable,
"opt/kwasm/bin/containerd-shim-wasmtime-v1": executable,
"usr/bin/containerd-shim-slight-v1": executable,
"usr/bin/containerd-shim-wasmtime-v1": executable,
},
alreadyFoundRuntimes: runtimeConfigs{},
},
want: runtimeConfigs{
"slight": {
RuntimeType: "io.containerd.slight.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-slight-v1",
},
"wasmtime": {
RuntimeType: "io.containerd.wasmtime.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-wasmtime-v1",
},
},
},
{
name: "Preserve already found runtimes",
args: args{
root: fstest.MapFS{
"opt/kwasm/bin/containerd-shim-wasmtime-v1": executable,
},
alreadyFoundRuntimes: runtimeConfigs{
"nvidia": {
RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/bin/nvidia-container-runtime",
},
},
},
want: runtimeConfigs{
"nvidia": {
RuntimeType: "io.containerd.runc.v2",
BinaryName: "/usr/bin/nvidia-container-runtime",
},
"wasmtime": {
RuntimeType: "io.containerd.wasmtime.v2",
BinaryName: "/opt/kwasm/bin/containerd-shim-wasmtime-v1",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
foundRuntimes := tt.args.alreadyFoundRuntimes
findWasiRuntimes(tt.args.root, foundRuntimes)
if !reflect.DeepEqual(foundRuntimes, tt.want) {
t.Errorf("findWasiRuntimes() = %+v\nWant = %+v", foundRuntimes, tt.want)
}
})
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment