Use common code to construct ldconfig hook

Signed-off-by: Evan Lezar <elezar@nvidia.com>
This commit is contained in:
Evan Lezar 2022-09-29 11:48:08 +02:00
parent d37c17857e
commit 8c1b9b33c1
2 changed files with 54 additions and 76 deletions

View File

@ -23,9 +23,9 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/NVIDIA/nvidia-container-toolkit/internal/discover"
"github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache" "github.com/NVIDIA/nvidia-container-toolkit/internal/ldcache"
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup" "github.com/NVIDIA/nvidia-container-toolkit/internal/lookup"
"github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
specs "github.com/container-orchestrated-devices/container-device-interface/specs-go" specs "github.com/container-orchestrated-devices/container-device-interface/specs-go"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
@ -327,50 +327,18 @@ func generateMountsForPaths(pathSets ...[]string) []*specs.Mount {
} }
func (m command) generateUpdateLdCacheHook(libraries []string) *specs.Hook { func (m command) generateUpdateLdCacheHook(libraries []string) *specs.Hook {
locator := lookup.NewExecutableLocator(m.logger, "") locator := lookup.NewExecutableLocator(m.logger, "")
hookPath := nvidiaCTKDefaultFilePath hook := discover.CreateLDCacheUpdateHook(
targets, err := locator.Locate(nvidiaCTKExecutable) m.logger,
if err != nil { locator,
m.logger.Warnf("Failed to locate %v: %v", nvidiaCTKExecutable, err) nvidiaCTKExecutable,
} else { nvidiaCTKDefaultFilePath,
m.logger.Debugf("Found %v candidates: %v", nvidiaCTKExecutable, targets) libraries,
hookPath = targets[0] )
return &specs.Hook{
HookName: hook.Lifecycle,
Path: hook.Path,
Args: hook.Args,
} }
m.logger.Debugf("Using NVIDIA Container Toolkit CLI path %v", hookPath)
folders := getLibraryPaths(libraries)
args := []string{hookPath, "hook", "update-ldcache"}
for _, f := range folders {
args = append(args, "--folder", f)
}
hook := specs.Hook{
HookName: cdi.CreateContainerHook,
Path: hookPath,
Args: args,
}
return &hook
}
// getLibraryPaths returns the directories in which the libraries can be found
func getLibraryPaths(libraries []string) []string {
var paths []string
checked := make(map[string]bool)
for _, l := range libraries {
dir := filepath.Dir(l)
if dir == "" {
continue
}
if checked[dir] {
continue
}
checked[dir] = true
paths = append(paths, dir)
}
return paths
} }

View File

@ -19,7 +19,6 @@ package discover
import ( import (
"fmt" "fmt"
"path/filepath" "path/filepath"
"sort"
"strings" "strings"
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup" "github.com/NVIDIA/nvidia-container-toolkit/internal/lookup"
@ -57,58 +56,50 @@ func (d ldconfig) Hooks() ([]Hook, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to discover mounts for ldcache update: %v", err) return nil, fmt.Errorf("failed to discover mounts for ldcache update: %v", err)
} }
h := CreateLDCacheUpdateHook(
d.logger,
d.lookup,
d.nvidiaCTKExecutablePath,
nvidiaCTKDefaultFilePath,
getLibraryPaths(mounts),
)
return []Hook{h}, nil
}
libDirs := getLibDirs(mounts) // CreateLDCacheUpdateHook locates the NVIDIA Container Toolkit CLI and creates a hook for updating the LD Cache
func CreateLDCacheUpdateHook(logger *logrus.Logger, lookup lookup.Locator, execuable string, defaultPath string, libraries []string) Hook {
hookPath := nvidiaCTKDefaultFilePath hookPath := defaultPath
targets, err := d.lookup.Locate(d.nvidiaCTKExecutablePath) targets, err := lookup.Locate(execuable)
if err != nil { if err != nil {
d.logger.Warnf("Failed to locate %v: %v", d.nvidiaCTKExecutablePath, err) logger.Warnf("Failed to locate %v: %v", execuable, err)
} else if len(targets) == 0 { } else if len(targets) == 0 {
d.logger.Warnf("%v not found", d.nvidiaCTKExecutablePath) logger.Warnf("%v not found", execuable)
} else { } else {
d.logger.Debugf("Found %v candidates: %v", d.nvidiaCTKExecutablePath, targets) logger.Debugf("Found %v candidates: %v", execuable, targets)
hookPath = targets[0] hookPath = targets[0]
} }
d.logger.Debugf("Using NVIDIA Container Toolkit CLI path %v", hookPath) logger.Debugf("Using NVIDIA Container Toolkit CLI path %v", hookPath)
args := []string{hookPath, "hook", "update-ldcache"} args := []string{hookPath, "hook", "update-ldcache"}
for _, f := range libDirs { for _, f := range uniqueFolders(libraries) {
args = append(args, "--folder", f) args = append(args, "--folder", f)
} }
h := Hook{ return Hook{
Lifecycle: cdi.CreateContainerHook, Lifecycle: cdi.CreateContainerHook,
Path: hookPath, Path: hookPath,
Args: args, Args: args,
} }
return []Hook{h}, nil
} }
// getLibDirs extracts the library dirs from the specified mounts // getLibraryPaths extracts the library dirs from the specified mounts
func getLibDirs(mounts []Mount) []string { func getLibraryPaths(mounts []Mount) []string {
var paths []string var paths []string
checked := make(map[string]bool)
for _, m := range mounts { for _, m := range mounts {
dir := filepath.Dir(m.Path) if !isLibName(m.Path) {
if dir == "" {
continue continue
} }
paths = append(paths, m.Path)
_, exists := checked[dir]
if exists {
continue
}
checked[dir] = isLibName(m.Path)
if checked[dir] {
paths = append(paths, dir)
}
} }
sort.Strings(paths)
return paths return paths
} }
@ -129,3 +120,22 @@ func isLibName(filename string) bool {
return parts[len(parts)-1] == "" || strings.HasPrefix(parts[len(parts)-1], ".") return parts[len(parts)-1] == "" || strings.HasPrefix(parts[len(parts)-1], ".")
} }
// uniqueFolders returns the unique set of folders for the specified files
func uniqueFolders(libraries []string) []string {
var paths []string
checked := make(map[string]bool)
for _, l := range libraries {
dir := filepath.Dir(l)
if dir == "" {
continue
}
if checked[dir] {
continue
}
checked[dir] = true
paths = append(paths, dir)
}
return paths
}