Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions cmd/nvidia-validator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/NVIDIA/go-nvlib/pkg/nvmdev"
"github.com/NVIDIA/go-nvlib/pkg/nvpci"
devchar "github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-ctk/system/create-dev-char-symlinks"
"github.com/moby/sys/symlink"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert/yaml"
cli "github.com/urfave/cli/v3"
Expand Down Expand Up @@ -135,6 +136,7 @@ var (
hostRootFlag string
driverInstallDirFlag string
driverInstallDirCtrPathFlag string
hostRootCtrPath = "/host"
)

// defaultGPUWorkloadConfig is "vm-passthrough" unless
Expand Down Expand Up @@ -645,7 +647,7 @@ func validateComponent(ctx context.Context, componentFlag string) error {
}
}

func runCommand(command string, args []string, silent bool) error {
var runCommand = func(command string, args []string, silent bool) error {
cmd := exec.Command(command, args...)
if !silent {
cmd.Stdout = os.Stdout
Expand Down Expand Up @@ -744,20 +746,26 @@ func isDriverManagedByOperator(ctx context.Context) (bool, error) {

func validateHostDriver(silent bool) error {
log.Info("Attempting to validate a pre-installed driver on the host")
if fileInfo, err := os.Lstat(filepath.Join("/host", wslNvidiaSMIPath)); err == nil && fileInfo.Size() != 0 {
if fileInfo, err := os.Lstat(filepath.Join(hostRootCtrPath, wslNvidiaSMIPath)); err == nil && fileInfo.Size() != 0 {
log.Infof("WSL2 system detected, assuming driver is pre-installed")
disableDevCharSymlinkCreation = true
return nil
}
fileInfo, err := os.Lstat("/host/usr/bin/nvidia-smi")

nvidiaSMIPath, err := symlink.FollowSymlinkInScope(filepath.Join(hostRootCtrPath, "usr/bin/nvidia-smi"), hostRootCtrPath)
if err != nil {
return fmt.Errorf("failed to resolve 'nvidia-smi' path on the host: %w", err)
}

fileInfo, err := os.Lstat(nvidiaSMIPath)
if err != nil {
return fmt.Errorf("no 'nvidia-smi' file present on the host: %w", err)
}
if fileInfo.Size() == 0 {
return fmt.Errorf("empty 'nvidia-smi' file found on the host")
}
command := "chroot"
args := []string{"/host", "nvidia-smi"}
args := []string{hostRootCtrPath, "nvidia-smi"}

return runCommand(command, args, silent)
}
Expand Down
58 changes: 58 additions & 0 deletions cmd/nvidia-validator/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,67 @@ package main
import (
"context"
"os"
"path/filepath"
"reflect"
"testing"
)

func Test_validateHostDriverWithAbsoluteUsrBinSymlink(t *testing.T) {
hostRoot := t.TempDir()

targetDir := filepath.Join(hostRoot, "run/current-system/sw/bin")
if err := os.MkdirAll(targetDir, 0755); err != nil {
t.Fatalf("failed to create target directory: %v", err)
}
if err := os.WriteFile(filepath.Join(targetDir, "nvidia-smi"), []byte("fake nvidia-smi"), 0755); err != nil {
t.Fatalf("failed to create nvidia-smi: %v", err)
}

usrDir := filepath.Join(hostRoot, "usr")
if err := os.MkdirAll(usrDir, 0755); err != nil {
t.Fatalf("failed to create usr directory: %v", err)
}
if err := os.Symlink("/run/current-system/sw/bin", filepath.Join(usrDir, "bin")); err != nil {
t.Fatalf("failed to create usr/bin symlink: %v", err)
}

originalHostRootCtrPath := hostRootCtrPath
hostRootCtrPath = hostRoot
defer func() { hostRootCtrPath = originalHostRootCtrPath }()

originalRunCommand := runCommand
defer func() { runCommand = originalRunCommand }()

var gotCommand string
var gotArgs []string
var gotSilent bool
runCommandCalled := false
runCommand = func(command string, args []string, silent bool) error {
runCommandCalled = true
gotCommand = command
gotArgs = append([]string(nil), args...)
gotSilent = silent
return nil
}

if err := validateHostDriver(true); err != nil {
t.Fatalf("validateHostDriver() unexpected error: %v", err)
}
if !runCommandCalled {
t.Fatal("validateHostDriver() did not run nvidia-smi validation command")
}
if gotCommand != "chroot" {
t.Fatalf("command = %q, want %q", gotCommand, "chroot")
}
wantArgs := []string{hostRoot, "nvidia-smi"}
if !reflect.DeepEqual(gotArgs, wantArgs) {
t.Fatalf("args = %v, want %v", gotArgs, wantArgs)
}
if !gotSilent {
t.Fatal("silent = false, want true")
}
}

func Test_isValidComponent(t *testing.T) {
tests := []struct {
name string
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
github.com/go-logr/logr v1.4.3
github.com/go-logr/zapr v1.3.0
github.com/moby/sys/symlink v0.3.0
github.com/onsi/ginkgo/v2 v2.28.3
github.com/onsi/gomega v1.40.0
github.com/openshift/api v0.0.0-20260213204242-d34f11c515b3
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
github.com/moby/sys/symlink v0.3.0 h1:GZX89mEZ9u53f97npBy4Rc3vJKj7JBDj/PN2I22GrNU=
github.com/moby/sys/symlink v0.3.0/go.mod h1:3eNdhduHmYPcgsJtZXW1W4XUJdZGBIkttZ8xKqPUJq0=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand Down
202 changes: 202 additions & 0 deletions vendor/github.com/moby/sys/symlink/LICENSE

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

Loading