Add create-soname-symlinks hook
Some checks failed
CI Pipeline / code-scanning (push) Has been cancelled
CI Pipeline / variables (push) Has been cancelled
CI Pipeline / golang (push) Has been cancelled
CI Pipeline / image (push) Has been cancelled
CI Pipeline / e2e-test (push) Has been cancelled

This change adds a create-soname-symlinks hook that can be used to ensure
that the soname symlinks for injected libraries exist in a container.

This is done by calling ldconfig -n -N for the folders containing the injected
libraries.

This also ensures that libcuda.so is present in the ldcache when the update-ldcache
hook is run.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
This commit is contained in:
Evan Lezar
2025-02-27 14:38:37 +02:00
parent 15645e6cd5
commit bdfaea4e9e
7 changed files with 238 additions and 25 deletions

View File

@@ -50,16 +50,16 @@ func (d ldconfig) Hooks() ([]Hook, error) {
if err != nil {
return nil, fmt.Errorf("failed to discover mounts for ldcache update: %v", err)
}
h := CreateLDCacheUpdateHook(
hooks := CreateLDCacheUpdateHooks(
d.nvidiaCDIHookPath,
d.ldconfigPath,
getLibraryPaths(mounts),
)
return []Hook{h}, nil
return hooks, nil
}
// CreateLDCacheUpdateHook locates the NVIDIA Container Toolkit CLI and creates a hook for updating the LD Cache
func CreateLDCacheUpdateHook(executable string, ldconfig string, libraries []string) Hook {
// CreateLDCacheUpdateHooks locates the NVIDIA Container Toolkit CLI and creates a hook for updating the LD Cache
func CreateLDCacheUpdateHooks(executable string, ldconfig string, libraries []string) []Hook {
var args []string
if ldconfig != "" {
@@ -70,13 +70,20 @@ func CreateLDCacheUpdateHook(executable string, ldconfig string, libraries []str
args = append(args, "--folder", f)
}
hook := CreateNvidiaCDIHook(
executable,
"update-ldcache",
args...,
)
hooks := []Hook{
CreateNvidiaCDIHook(
executable,
"create-soname-symlinks",
args...,
),
CreateNvidiaCDIHook(
executable,
"update-ldcache",
args...,
),
}
return hook
return hooks
}
// getLibraryPaths extracts the library dirs from the specified mounts

View File

@@ -38,11 +38,22 @@ func TestLDCacheUpdateHook(t *testing.T) {
mounts []Mount
mountError error
expectedError error
expectedArgs []string
expectedHooks []Hook
}{
{
description: "empty mounts",
expectedArgs: []string{"nvidia-cdi-hook", "update-ldcache"},
description: "empty mounts",
expectedHooks: []Hook{
{
Lifecycle: "createContainer",
Path: testNvidiaCDIHookPath,
Args: []string{"nvidia-cdi-hook", "create-soname-symlinks"},
},
{
Lifecycle: "createContainer",
Path: testNvidiaCDIHookPath,
Args: []string{"nvidia-cdi-hook", "update-ldcache"},
},
},
},
{
description: "mount error",
@@ -65,7 +76,18 @@ func TestLDCacheUpdateHook(t *testing.T) {
Path: "/usr/local/lib/libbar.so",
},
},
expectedArgs: []string{"nvidia-cdi-hook", "update-ldcache", "--folder", "/usr/local/lib", "--folder", "/usr/local/libother"},
expectedHooks: []Hook{
{
Lifecycle: "createContainer",
Path: testNvidiaCDIHookPath,
Args: []string{"nvidia-cdi-hook", "create-soname-symlinks", "--folder", "/usr/local/lib", "--folder", "/usr/local/libother"},
},
{
Lifecycle: "createContainer",
Path: testNvidiaCDIHookPath,
Args: []string{"nvidia-cdi-hook", "update-ldcache", "--folder", "/usr/local/lib", "--folder", "/usr/local/libother"},
},
},
},
{
description: "host paths are ignored",
@@ -75,12 +97,34 @@ func TestLDCacheUpdateHook(t *testing.T) {
Path: "/usr/local/lib/libfoo.so",
},
},
expectedArgs: []string{"nvidia-cdi-hook", "update-ldcache", "--folder", "/usr/local/lib"},
expectedHooks: []Hook{
{
Lifecycle: "createContainer",
Path: testNvidiaCDIHookPath,
Args: []string{"nvidia-cdi-hook", "create-soname-symlinks", "--folder", "/usr/local/lib"},
},
{
Lifecycle: "createContainer",
Path: testNvidiaCDIHookPath,
Args: []string{"nvidia-cdi-hook", "update-ldcache", "--folder", "/usr/local/lib"},
},
},
},
{
description: "explicit ldconfig path is passed",
ldconfigPath: testLdconfigPath,
expectedArgs: []string{"nvidia-cdi-hook", "update-ldcache", "--ldconfig-path", testLdconfigPath},
expectedHooks: []Hook{
{
Lifecycle: "createContainer",
Path: testNvidiaCDIHookPath,
Args: []string{"nvidia-cdi-hook", "create-soname-symlinks", "--ldconfig-path", testLdconfigPath},
},
{
Lifecycle: "createContainer",
Path: testNvidiaCDIHookPath,
Args: []string{"nvidia-cdi-hook", "update-ldcache", "--ldconfig-path", testLdconfigPath},
},
},
},
}
@@ -91,12 +135,6 @@ func TestLDCacheUpdateHook(t *testing.T) {
return tc.mounts, tc.mountError
},
}
expectedHook := Hook{
Path: testNvidiaCDIHookPath,
Args: tc.expectedArgs,
Lifecycle: "createContainer",
}
d, err := NewLDCacheUpdateHook(logger, mountMock, testNvidiaCDIHookPath, tc.ldconfigPath)
require.NoError(t, err)
@@ -110,9 +148,7 @@ func TestLDCacheUpdateHook(t *testing.T) {
}
require.NoError(t, err)
require.Len(t, hooks, 1)
require.EqualValues(t, hooks[0], expectedHook)
require.EqualValues(t, tc.expectedHooks, hooks)
devices, err := d.Devices()
require.NoError(t, err)