mirror of
https://github.com/NVIDIA/nvidia-container-toolkit
synced 2025-05-06 04:55:02 +00:00
Merge branch 'add-options-to-mounts' into 'main'
Add Options to mounts to refactor IPC CDI spec generation See merge request nvidia/container-toolkit/container-toolkit!287
This commit is contained in:
commit
1c05f2fb9a
@ -41,12 +41,18 @@ func NewDriverDiscoverer(logger *logrus.Logger, driverRoot string, nvidiaCTKPath
|
|||||||
return nil, fmt.Errorf("failed to create discoverer for driver libraries: %v", err)
|
return nil, fmt.Errorf("failed to create discoverer for driver libraries: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipcs, err := discover.NewIPCDiscoverer(logger, driverRoot)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create discoverer for IPC sockets: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
firmwares := NewDriverFirmwareDiscoverer(logger, driverRoot, version)
|
firmwares := NewDriverFirmwareDiscoverer(logger, driverRoot, version)
|
||||||
|
|
||||||
binaries := NewDriverBinariesDiscoverer(logger, driverRoot)
|
binaries := NewDriverBinariesDiscoverer(logger, driverRoot)
|
||||||
|
|
||||||
d := discover.Merge(
|
d := discover.Merge(
|
||||||
libraries,
|
libraries,
|
||||||
|
ipcs,
|
||||||
firmwares,
|
firmwares,
|
||||||
binaries,
|
binaries,
|
||||||
)
|
)
|
||||||
|
@ -232,24 +232,6 @@ func (m command) generateSpec(driverRoot string, nvidiaCTKPath string, namer dev
|
|||||||
|
|
||||||
deviceSpecs = append(deviceSpecs, allDevice)
|
deviceSpecs = append(deviceSpecs, allDevice)
|
||||||
|
|
||||||
allEdits := edits.NewContainerEdits()
|
|
||||||
|
|
||||||
ipcs, err := NewIPCDiscoverer(m.logger, driverRoot)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to create discoverer for IPC sockets: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ipcEdits, err := edits.FromDiscoverer(ipcs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to create container edits for IPC sockets: %v", err)
|
|
||||||
}
|
|
||||||
// TODO: We should not have to update this after the fact
|
|
||||||
for _, s := range ipcEdits.Mounts {
|
|
||||||
s.Options = append(s.Options, "noexec")
|
|
||||||
}
|
|
||||||
|
|
||||||
allEdits.Append(ipcEdits)
|
|
||||||
|
|
||||||
common, err := NewCommonDiscoverer(m.logger, driverRoot, nvidiaCTKPath, nvmllib)
|
common, err := NewCommonDiscoverer(m.logger, driverRoot, nvidiaCTKPath, nvmllib)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create discoverer for common entities: %v", err)
|
return nil, fmt.Errorf("failed to create discoverer for common entities: %v", err)
|
||||||
@ -265,14 +247,12 @@ func (m command) generateSpec(driverRoot string, nvidiaCTKPath string, namer dev
|
|||||||
return nil, fmt.Errorf("failed to create container edits for common entities: %v", err)
|
return nil, fmt.Errorf("failed to create container edits for common entities: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
allEdits.Append(commonEdits)
|
|
||||||
|
|
||||||
// We construct the spec and determine the minimum required version based on the specification.
|
// We construct the spec and determine the minimum required version based on the specification.
|
||||||
spec := specs.Spec{
|
spec := specs.Spec{
|
||||||
Version: "NOT_SET",
|
Version: "NOT_SET",
|
||||||
Kind: "nvidia.com/gpu",
|
Kind: "nvidia.com/gpu",
|
||||||
Devices: deviceSpecs,
|
Devices: deviceSpecs,
|
||||||
ContainerEdits: *allEdits.ContainerEdits,
|
ContainerEdits: *commonEdits.ContainerEdits,
|
||||||
}
|
}
|
||||||
|
|
||||||
minVersion, err := cdi.MinimumRequiredVersion(&spec)
|
minVersion, err := cdi.MinimumRequiredVersion(&spec)
|
||||||
|
@ -58,7 +58,11 @@ func (d *charDevices) Devices() ([]Device, error) {
|
|||||||
}
|
}
|
||||||
var devices []Device
|
var devices []Device
|
||||||
for _, mount := range devicesAsMounts {
|
for _, mount := range devicesAsMounts {
|
||||||
devices = append(devices, Device(mount))
|
device := Device{
|
||||||
|
HostPath: mount.HostPath,
|
||||||
|
Path: mount.Path,
|
||||||
|
}
|
||||||
|
devices = append(devices, device)
|
||||||
}
|
}
|
||||||
|
|
||||||
return devices, nil
|
return devices, nil
|
||||||
|
@ -32,6 +32,7 @@ type Device struct {
|
|||||||
type Mount struct {
|
type Mount struct {
|
||||||
HostPath string
|
HostPath string
|
||||||
Path string
|
Path string
|
||||||
|
Options []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hook represents a discovered hook.
|
// Hook represents a discovered hook.
|
||||||
|
60
internal/discover/icp_test.go
Normal file
60
internal/discover/icp_test.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
# Copyright (c) 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 (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIPCMounts(t *testing.T) {
|
||||||
|
l := ipcMounts(
|
||||||
|
mounts{
|
||||||
|
logger: logrus.New(),
|
||||||
|
lookup: &lookup.LocatorMock{
|
||||||
|
LocateFunc: func(path string) ([]string, error) {
|
||||||
|
return []string{"/host/path"}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: []string{"target"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
mounts, err := l.Mounts()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.EqualValues(
|
||||||
|
t,
|
||||||
|
[]Mount{
|
||||||
|
{
|
||||||
|
HostPath: "/host/path",
|
||||||
|
Path: "/host/path",
|
||||||
|
Options: []string{
|
||||||
|
"ro",
|
||||||
|
"nosuid",
|
||||||
|
"nodev",
|
||||||
|
"bind",
|
||||||
|
"noexec",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounts,
|
||||||
|
)
|
||||||
|
}
|
@ -14,17 +14,18 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
package generate
|
package discover
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/discover"
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ipcMounts mounts
|
||||||
|
|
||||||
// NewIPCDiscoverer creats a discoverer for NVIDIA IPC sockets.
|
// NewIPCDiscoverer creats a discoverer for NVIDIA IPC sockets.
|
||||||
func NewIPCDiscoverer(logger *logrus.Logger, driverRoot string) (discover.Discover, error) {
|
func NewIPCDiscoverer(logger *logrus.Logger, driverRoot string) (Discover, error) {
|
||||||
d := discover.NewMounts(
|
d := newMounts(
|
||||||
logger,
|
logger,
|
||||||
lookup.NewFileLocator(
|
lookup.NewFileLocator(
|
||||||
lookup.WithLogger(logger),
|
lookup.WithLogger(logger),
|
||||||
@ -38,5 +39,22 @@ func NewIPCDiscoverer(logger *logrus.Logger, driverRoot string) (discover.Discov
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
return d, nil
|
return (*ipcMounts)(d), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mounts returns the discovered mounts with "noexec" added to the mount options.
|
||||||
|
func (d *ipcMounts) Mounts() ([]Mount, error) {
|
||||||
|
mounts, err := (*mounts)(d).Mounts()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var modifiedMounts []Mount
|
||||||
|
for _, m := range mounts {
|
||||||
|
mount := m
|
||||||
|
mount.Options = append(m.Options, "noexec")
|
||||||
|
modifiedMounts = append(modifiedMounts, mount)
|
||||||
|
}
|
||||||
|
|
||||||
|
return modifiedMounts, nil
|
||||||
}
|
}
|
@ -43,6 +43,11 @@ var _ Discover = (*mounts)(nil)
|
|||||||
|
|
||||||
// NewMounts creates a discoverer for the required mounts using the specified locator.
|
// NewMounts creates a discoverer for the required mounts using the specified locator.
|
||||||
func NewMounts(logger *logrus.Logger, lookup lookup.Locator, root string, required []string) Discover {
|
func NewMounts(logger *logrus.Logger, lookup lookup.Locator, root string, required []string) Discover {
|
||||||
|
return newMounts(logger, lookup, root, required)
|
||||||
|
}
|
||||||
|
|
||||||
|
// newMounts creates a discoverer for the required mounts using the specified locator.
|
||||||
|
func newMounts(logger *logrus.Logger, lookup lookup.Locator, root string, required []string) *mounts {
|
||||||
return &mounts{
|
return &mounts{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
lookup: lookup,
|
lookup: lookup,
|
||||||
@ -93,6 +98,12 @@ func (d *mounts) Mounts() ([]Mount, error) {
|
|||||||
uniqueMounts[p] = Mount{
|
uniqueMounts[p] = Mount{
|
||||||
HostPath: p,
|
HostPath: p,
|
||||||
Path: r,
|
Path: r,
|
||||||
|
Options: []string{
|
||||||
|
"ro",
|
||||||
|
"nosuid",
|
||||||
|
"nodev",
|
||||||
|
"bind",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,14 @@ func TestMountsReturnsEmptyDevices(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMounts(t *testing.T) {
|
func TestMounts(t *testing.T) {
|
||||||
|
|
||||||
|
mountOptions := []string{
|
||||||
|
"ro",
|
||||||
|
"nosuid",
|
||||||
|
"nodev",
|
||||||
|
"bind",
|
||||||
|
}
|
||||||
|
|
||||||
logger, logHook := testlog.NewNullLogger()
|
logger, logHook := testlog.NewNullLogger()
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
@ -70,7 +78,7 @@ func TestMounts(t *testing.T) {
|
|||||||
},
|
},
|
||||||
required: []string{"required"},
|
required: []string{"required"},
|
||||||
},
|
},
|
||||||
expectedMounts: []Mount{{Path: "located", HostPath: "located"}},
|
expectedMounts: []Mount{{Path: "located", HostPath: "located", Options: mountOptions}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "mounts removes located duplicates",
|
description: "mounts removes located duplicates",
|
||||||
@ -83,7 +91,7 @@ func TestMounts(t *testing.T) {
|
|||||||
},
|
},
|
||||||
required: []string{"required0", "required1"},
|
required: []string{"required0", "required1"},
|
||||||
},
|
},
|
||||||
expectedMounts: []Mount{{Path: "located", HostPath: "located"}},
|
expectedMounts: []Mount{{Path: "located", HostPath: "located", Options: mountOptions}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "mounts skips located errors",
|
description: "mounts skips located errors",
|
||||||
@ -98,7 +106,7 @@ func TestMounts(t *testing.T) {
|
|||||||
},
|
},
|
||||||
required: []string{"required0", "error", "required1"},
|
required: []string{"required0", "error", "required1"},
|
||||||
},
|
},
|
||||||
expectedMounts: []Mount{{Path: "required0", HostPath: "required0"}, {Path: "required1", HostPath: "required1"}},
|
expectedMounts: []Mount{{Path: "required0", HostPath: "required0", Options: mountOptions}, {Path: "required1", HostPath: "required1", Options: mountOptions}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "mounts skips unlocated",
|
description: "mounts skips unlocated",
|
||||||
@ -113,7 +121,7 @@ func TestMounts(t *testing.T) {
|
|||||||
},
|
},
|
||||||
required: []string{"required0", "empty", "required1"},
|
required: []string{"required0", "empty", "required1"},
|
||||||
},
|
},
|
||||||
expectedMounts: []Mount{{Path: "required0", HostPath: "required0"}, {Path: "required1", HostPath: "required1"}},
|
expectedMounts: []Mount{{Path: "required0", HostPath: "required0", Options: mountOptions}, {Path: "required1", HostPath: "required1", Options: mountOptions}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "mounts adds multiple",
|
description: "mounts adds multiple",
|
||||||
@ -129,10 +137,10 @@ func TestMounts(t *testing.T) {
|
|||||||
required: []string{"required0", "multiple", "required1"},
|
required: []string{"required0", "multiple", "required1"},
|
||||||
},
|
},
|
||||||
expectedMounts: []Mount{
|
expectedMounts: []Mount{
|
||||||
{Path: "required0", HostPath: "required0"},
|
{Path: "required0", HostPath: "required0", Options: mountOptions},
|
||||||
{Path: "multiple0", HostPath: "multiple0"},
|
{Path: "multiple0", HostPath: "multiple0", Options: mountOptions},
|
||||||
{Path: "multiple1", HostPath: "multiple1"},
|
{Path: "multiple1", HostPath: "multiple1", Options: mountOptions},
|
||||||
{Path: "required1", HostPath: "required1"},
|
{Path: "required1", HostPath: "required1", Options: mountOptions},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -147,7 +155,7 @@ func TestMounts(t *testing.T) {
|
|||||||
required: []string{"required0", "multiple", "required1"},
|
required: []string{"required0", "multiple", "required1"},
|
||||||
},
|
},
|
||||||
expectedMounts: []Mount{
|
expectedMounts: []Mount{
|
||||||
{Path: "/located", HostPath: "/some/root/located"},
|
{Path: "/located", HostPath: "/some/root/located", Options: mountOptions},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -40,12 +40,7 @@ func (d mount) toSpec() *specs.Mount {
|
|||||||
s := specs.Mount{
|
s := specs.Mount{
|
||||||
HostPath: d.HostPath,
|
HostPath: d.HostPath,
|
||||||
ContainerPath: d.Path,
|
ContainerPath: d.Path,
|
||||||
Options: []string{
|
Options: d.Options,
|
||||||
"ro",
|
|
||||||
"nosuid",
|
|
||||||
"nodev",
|
|
||||||
"bind",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &s
|
return &s
|
||||||
|
Loading…
Reference in New Issue
Block a user