diff --git a/cmd/nvidia-container-runtime/modifier/experimental.go b/cmd/nvidia-container-runtime/modifier/experimental.go index b669de40..f8e927c5 100644 --- a/cmd/nvidia-container-runtime/modifier/experimental.go +++ b/cmd/nvidia-container-runtime/modifier/experimental.go @@ -89,12 +89,17 @@ func NewExperimentalModifier(logger *logrus.Logger, cfg *config.Config, ociSpec return nil, fmt.Errorf("failed to create CSV discoverer: %v", err) } - hooks, err := discover.NewLDCacheUpdateHook(logger, csvDiscoverer, config) + ldcacheUpdateHook, err := discover.NewLDCacheUpdateHook(logger, csvDiscoverer, config) if err != nil { - return nil, fmt.Errorf("failed to create hook discoverer: %v", err) + return nil, fmt.Errorf("failed to create ldcach update hook discoverer: %v", err) } - d = discover.NewList(csvDiscoverer, hooks) + createSymlinksHook, err := discover.NewCreateSymlinksHook(logger, csvFiles, config) + if err != nil { + return nil, fmt.Errorf("failed to create symlink hook discoverer: %v", err) + } + + d = discover.NewList(csvDiscoverer, ldcacheUpdateHook, createSymlinksHook) default: return nil, fmt.Errorf("invalid discover mode: %v", cfg.NVIDIAContainerRuntimeConfig.DiscoverMode) } diff --git a/internal/discover/symlinks.go b/internal/discover/symlinks.go new file mode 100644 index 00000000..9547f8ba --- /dev/null +++ b/internal/discover/symlinks.go @@ -0,0 +1,71 @@ +/** +# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +**/ + +package discover + +import ( + "github.com/NVIDIA/nvidia-container-toolkit/internal/lookup" + "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi" + "github.com/sirupsen/logrus" +) + +type symlinks struct { + None + logger *logrus.Logger + lookup lookup.Locator + nvidiaCTKExecutablePath string + csvFiles []string +} + +// NewCreateSymlinksHook creates a discoverer for a hook that creates required symlinks in the container +func NewCreateSymlinksHook(logger *logrus.Logger, csvFiles []string, cfg *Config) (Discover, error) { + d := symlinks{ + logger: logger, + lookup: lookup.NewExecutableLocator(logger, cfg.Root), + nvidiaCTKExecutablePath: cfg.NVIDIAContainerToolkitCLIExecutablePath, + csvFiles: csvFiles, + } + + return &d, nil +} + +// Hooks returns a hook to create the symlinks from the required CSV files +func (d symlinks) Hooks() ([]Hook, error) { + hookPath := nvidiaCTKDefaultFilePath + targets, err := d.lookup.Locate(d.nvidiaCTKExecutablePath) + if err != nil { + d.logger.Warnf("Failed to locate %v: %v", d.nvidiaCTKExecutablePath, err) + } else if len(targets) == 0 { + d.logger.Warnf("%v not found", d.nvidiaCTKExecutablePath) + } else { + d.logger.Debugf("Found %v candidates: %v", d.nvidiaCTKExecutablePath, targets) + hookPath = targets[0] + } + d.logger.Debugf("Using NVIDIA Container Toolkit CLI path %v", hookPath) + + args := []string{hookPath, "hook", "create-symlinks"} + for _, f := range d.csvFiles { + args = append(args, "--csv-filenames", f) + } + + h := Hook{ + Lifecycle: cdi.CreateContainerHook, + Path: hookPath, + Args: args, + } + + return []Hook{h}, nil +}