cmd/initContainer, test/system: Handle NVIDIA's create-symlinks CDI hook

NVIDIA Container Toolkit 0.16.0 started using create-symlinks hooks in
the Container Device Interface specification generated by it [1].  For
example:
  "hookName": "createContainer",
  "path": "/usr/bin/nvidia-cdi-hook",
  "args": [
    "nvidia-cdi-hook",
    "create-symlinks",
    "--link",
    "libnvidia-allocator.so.560.35.03::/usr/lib64/libnvidia-allocator.so.1",
    "--link",
    "../libnvidia-allocator.so.1::/usr/lib64/gbm/nvidia-drm_gbm.so"
  ]

Fallout from 649d02f8a6

[1] NVIDIA Container Toolkit commit aae3da88c33d9cf2
    https://github.com/NVIDIA/nvidia-container-toolkit/commit/aae3da88c33d9cf2
    https://github.com/NVIDIA/nvidia-container-toolkit/pull/548

https://github.com/containers/toolbox/pull/1545
This commit is contained in:
Debarshi Ray 2024-09-17 19:09:53 +02:00
parent c399243b46
commit dd23baa29a
19 changed files with 1342 additions and 0 deletions

View File

@ -475,6 +475,16 @@ func applyCDISpecForNvidia(spec *specs.Spec) error {
}
if len(hook.Args) >= 2 &&
hook.Args[0] == "nvidia-cdi-hook" &&
hook.Args[1] == "create-symlinks" {
hookArgs := hook.Args[2:]
if err := applyCDISpecForNvidiaHookCreateSymlinks(hookArgs); err != nil {
logrus.Debugf("Applying Container Device Interface for NVIDIA: %s", err)
return errors.New("failed to create symlinks for Container Device Interface for NVIDIA")
}
continue
} else if len(hook.Args) >= 2 &&
hook.Args[0] == "nvidia-cdi-hook" &&
hook.Args[1] == "update-ldcache" {
hookArgs := hook.Args[2:]
@ -495,6 +505,43 @@ func applyCDISpecForNvidia(spec *specs.Spec) error {
return nil
}
func applyCDISpecForNvidiaHookCreateSymlinks(hookArgs []string) error {
var linkFlag bool
for _, hookArg := range hookArgs {
if hookArg == "--link" {
linkFlag = true
continue
}
if linkFlag {
linkFlag = false
if linkParts := strings.Split(hookArg, "::"); len(linkParts) == 2 {
existingTarget := linkParts[0]
newLink := linkParts[1]
if !filepath.IsAbs(newLink) {
return fmt.Errorf("invalid --link argument: link %s is not an absolute path",
newLink)
}
if err := createSymbolicLink(existingTarget, newLink); err != nil {
return err
}
} else {
return fmt.Errorf("invalid --link argument: %s not in '<target>::<link>' format",
hookArg)
}
}
}
if linkFlag {
return errors.New("missing --link argument")
}
return nil
}
func applyCDISpecForNvidiaHookUpdateLDCache(hookArgs []string) error {
var folderFlag bool
var folders []string
@ -587,6 +634,29 @@ func configureUsers(targetUserUid int, targetUser, targetUserHome, targetUserShe
return nil
}
func createSymbolicLink(existingTarget, newLink string) error {
logrus.Debugf("Creating symbolic link with target %s and link %s", existingTarget, newLink)
newLinkDir := filepath.Dir(newLink)
if err := os.MkdirAll(newLinkDir, 0755); err != nil {
return fmt.Errorf("failed to create directory %s: %w", newLinkDir, err)
}
if err := os.Symlink(existingTarget, newLink); err != nil {
var errLink *os.LinkError
if errors.As(err, &errLink) {
if errors.Is(err, os.ErrExist) {
logrus.Debugf("Creating symbolic link: file %s already exists", newLink)
return nil
}
}
return fmt.Errorf("failed to create symbolic link: %w", err)
}
return nil
}
func getDelayEntryPoint() (time.Duration, bool) {
valueString := os.Getenv("TOOLBX_DELAY_ENTRY_POINT")
if valueString == "" {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link",
"/usr/bin/toolbox::/run/toolbox.1"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link",
"/usr/bin/toolbox::/opt/bin/toolbox"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link",
"/usr/bin/toolbox::/usr/bin/toolbox.1"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,20 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link",
"/usr/bin/toolbox::/run/toolbox.1",
"--link",
"/usr/bin/toolbox::/opt/bin/toolbox",
"--link",
"/usr/bin/toolbox::/usr/bin/toolbox.1"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link",
"../usr/bin/toolbox::/run/toolbox.1"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link",
"../../usr/bin/toolbox::/opt/bin/toolbox"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link",
"toolbox::/usr/bin/toolbox.1"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,20 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link",
"../usr/bin/toolbox::/run/toolbox.1",
"--link",
"../../usr/bin/toolbox::/opt/bin/toolbox",
"--link",
"toolbox::/usr/bin/toolbox.1"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,14 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks"
],
"hookName": "createContainer",
"path": ""
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"unknown",
"create-symlinks",
"--link",
"toolbox::/usr/bin/toolbox.1"
],
"hookName": "createContainer",
"path": "/usr/bin/unknown"
}
]
}
}

View File

@ -0,0 +1,15 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link",
"toolbox::toolbox.1"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link",
"foo"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link",
"foo::bar::baz"
],
"hookName": "createContainer",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,14 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks"
],
"hookName": "invalid",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"containerEdits": {
"hooks": [
{
"args": [
"nvidia-cdi-hook",
"create-symlinks",
"--link",
"toolbox::/usr/bin/toolbox.1"
],
"hookName": "createRuntime",
"path": "/usr/bin/nvidia-cdi-hook"
}
]
}
}