Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions internal/config/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ type RuntimeConfig struct {
Runtimes []string `toml:"runtimes"`
Mode string `toml:"mode"`
Modes modesConfig `toml:"modes"`
// Close to the "no-cgroups" bool when using the legacy mode with the hooks.
MknodOnly bool `toml:"mknod-only"`
}

// modesConfig defines (optional) per-mode configs
Expand Down
2 changes: 2 additions & 0 deletions internal/modifier/cdi.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func NewCDIModifier(logger logger.Interface, cfg *config.Config, image image.CUD
cdi.WithLogger(logger),
cdi.WithDevices(devices...),
cdi.WithSpecDirs(cfg.NVIDIAContainerRuntimeConfig.Modes.CDI.SpecDirs...),
cdi.WithMknodOnly(cfg.NVIDIAContainerRuntimeConfig.MknodOnly),
)
}

Expand Down Expand Up @@ -197,6 +198,7 @@ func newAutomaticCDISpecModifier(logger logger.Interface, cfg *config.Config, de
cdiDeviceRequestor, err := cdi.New(
cdi.WithLogger(logger),
cdi.WithSpec(spec.Raw()),
cdi.WithMknodOnly(cfg.NVIDIAContainerRuntimeConfig.MknodOnly),
)
if err != nil {
return nil, fmt.Errorf("failed to construct CDI modifier for mode %q: %w", mode, err)
Expand Down
20 changes: 15 additions & 5 deletions internal/modifier/cdi/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ import (
)

type builder struct {
logger logger.Interface
specDirs []string
devices []string
cdiSpec *specs.Spec
logger logger.Interface
specDirs []string
devices []string
cdiSpec *specs.Spec
mknodOnly bool
}

// Option represents a functional option for creating a CDI mofifier.
Expand All @@ -56,7 +57,8 @@ func (m builder) build() (oci.SpecModifier, error) {

if m.cdiSpec != nil {
modifier := fromCDISpec{
cdiSpec: &cdi.Spec{Spec: m.cdiSpec},
cdiSpec: &cdi.Spec{Spec: m.cdiSpec},
mknodOnly: m.mknodOnly,
}
return modifier, nil
}
Expand All @@ -69,6 +71,7 @@ func (m builder) build() (oci.SpecModifier, error) {
return nil, fmt.Errorf("failed to create CDI registry: %v", err)
}

// FIXME: cannot edit, vendor lib, mknodOnly has no effect in this case
modifier := fromRegistry{
logger: m.logger,
registry: registry,
Expand Down Expand Up @@ -105,3 +108,10 @@ func WithSpec(spec *specs.Spec) Option {
b.cdiSpec = spec
}
}

// WithSpec sets the mknodOnly for the CDI modifier builder.
func WithMknodOnly(mknodOnly bool) Option {
return func(b *builder) {
b.mknodOnly = mknodOnly
}
}
21 changes: 19 additions & 2 deletions internal/modifier/cdi/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,32 @@ import (

// fromCDISpec represents the modifications performed from a raw CDI spec.
type fromCDISpec struct {
cdiSpec *cdi.Spec
cdiSpec *cdi.Spec
mknodOnly bool
}

var _ oci.SpecModifier = (*fromCDISpec)(nil)

// Modify applies the mofiications defined by the raw CDI spec to the incomming OCI spec.
// Modify applies the mofications defined by the raw CDI spec to the incomming OCI spec.
func (m fromCDISpec) Modify(spec *specs.Spec) error {
for _, device := range m.cdiSpec.Devices {
device := device
if m.mknodOnly {
for i := range device.ContainerEdits.DeviceNodes {
// We cannot set an empty string as this will be translated to rwm in the OCI spec generation
// see here:
// https://github.com/NVIDIA/nvidia-container-toolkit/blob/786aa3baf25bf0acd26ae48b5934fa5d503fa1ec/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits.go#L110
// Since we use the CDI implem above and we can actually pass any arbitrary string, for some oci compatible
// runtimes like runc we could set "_", and this would have the intended effect (no permissions) but
// this relies on two successive flaws in the CDI/OCI specs implems
// (non repect of the CDI spec in the implem above + non respect of the OCI spec in the underlying runtime)
// Let's just add the mknod permission as a trade off:
// container users should not go really far if this is all they are allowed to do (besides runc will end up giving the mknod permission anyway
// https://github.com/opencontainers/runc/blob/ef5e8a5505d6fe022daf016e2535adbda0d89c72/libcontainer/specconv/spec_linux.go#L220-L235)
device.ContainerEdits.DeviceNodes[i].Permissions = "m"
}
}

cdiDevice := cdi.Device{
Device: &device,
}
Expand Down
1 change: 1 addition & 0 deletions internal/modifier/csv.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func NewCSVModifier(logger logger.Interface, cfg *config.Config, container image
return cdi.New(
cdi.WithLogger(logger),
cdi.WithSpec(spec.Raw()),
cdi.WithMknodOnly(cfg.NVIDIAContainerRuntimeConfig.MknodOnly),
)
}

Expand Down