Skip to content

Commit 0ed757f

Browse files
committed
TOFIX: split auto
Signed-off-by: Evan Lezar <[email protected]>
1 parent d87dddd commit 0ed757f

File tree

3 files changed

+155
-78
lines changed

3 files changed

+155
-78
lines changed

internal/modifier/cdi.go

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,6 @@ import (
2727
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
2828
"github.com/NVIDIA/nvidia-container-toolkit/internal/modifier/cdi"
2929
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
30-
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi"
31-
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/spec"
32-
)
33-
34-
const (
35-
automaticDeviceVendor = "runtime.nvidia.com"
36-
automaticDeviceClass = "gpu"
37-
automaticDeviceKind = automaticDeviceVendor + "/" + automaticDeviceClass
3830
)
3931

4032
// NewCDIModifier creates an OCI spec modifier that determines the modifications to make based on the
@@ -175,73 +167,3 @@ func getAnnotationDevices(prefixes []string, annotations map[string]string) ([]s
175167

176168
return annotationDevices, nil
177169
}
178-
179-
// filterAutomaticDevices searches for "automatic" device names in the input slice.
180-
// "Automatic" devices are a well-defined list of CDI device names which, when requested,
181-
// trigger the generation of a CDI spec at runtime. This removes the need to generate a
182-
// CDI spec on the system a-priori as well as keep it up-to-date.
183-
func filterAutomaticDevices(devices []string) []string {
184-
var automatic []string
185-
for _, device := range devices {
186-
vendor, class, _ := parser.ParseDevice(device)
187-
if vendor == automaticDeviceVendor && class == automaticDeviceClass {
188-
automatic = append(automatic, device)
189-
}
190-
}
191-
return automatic
192-
}
193-
194-
func newAutomaticCDISpecModifier(logger logger.Interface, cfg *config.Config, devices []string) (oci.SpecModifier, error) {
195-
logger.Debugf("Generating in-memory CDI specs for devices %v", devices)
196-
// TODO: We should try to load the kernel modules and create the device nodes here.
197-
// Failures should raise a warning and not error out.
198-
spec, err := generateAutomaticCDISpec(logger, cfg, devices)
199-
if err != nil {
200-
return nil, fmt.Errorf("failed to generate CDI spec: %w", err)
201-
}
202-
cdiModifier, err := cdi.New(
203-
cdi.WithLogger(logger),
204-
cdi.WithSpec(spec.Raw()),
205-
)
206-
if err != nil {
207-
return nil, fmt.Errorf("failed to construct CDI modifier: %w", err)
208-
}
209-
210-
return cdiModifier, nil
211-
}
212-
213-
func generateAutomaticCDISpec(logger logger.Interface, cfg *config.Config, devices []string) (spec.Interface, error) {
214-
cdilib, err := nvcdi.New(
215-
nvcdi.WithLogger(logger),
216-
nvcdi.WithNVIDIACDIHookPath(cfg.NVIDIACTKConfig.Path),
217-
nvcdi.WithDriverRoot(cfg.NVIDIAContainerCLIConfig.Root),
218-
nvcdi.WithVendor("runtime.nvidia.com"),
219-
nvcdi.WithClass("gpu"),
220-
)
221-
if err != nil {
222-
return nil, fmt.Errorf("failed to construct CDI library: %w", err)
223-
}
224-
225-
identifiers := []string{}
226-
for _, device := range devices {
227-
_, _, id := parser.ParseDevice(device)
228-
identifiers = append(identifiers, id)
229-
}
230-
231-
deviceSpecs, err := cdilib.GetDeviceSpecsByID(identifiers...)
232-
if err != nil {
233-
return nil, fmt.Errorf("failed to get CDI device specs: %w", err)
234-
}
235-
236-
commonEdits, err := cdilib.GetCommonEdits()
237-
if err != nil {
238-
return nil, fmt.Errorf("failed to get common CDI spec edits: %w", err)
239-
}
240-
241-
return spec.New(
242-
spec.WithDeviceSpecs(deviceSpecs),
243-
spec.WithEdits(*commonEdits.ContainerEdits),
244-
spec.WithVendor("runtime.nvidia.com"),
245-
spec.WithClass("gpu"),
246-
)
247-
}

internal/modifier/jit-cdi.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/**
2+
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
**/
16+
17+
package modifier
18+
19+
import (
20+
"fmt"
21+
22+
"tags.cncf.io/container-device-interface/pkg/parser"
23+
24+
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
25+
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
26+
"github.com/NVIDIA/nvidia-container-toolkit/internal/modifier/cdi"
27+
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
28+
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi"
29+
"github.com/NVIDIA/nvidia-container-toolkit/pkg/nvcdi/spec"
30+
)
31+
32+
const (
33+
automaticDeviceVendor = "runtime.nvidia.com"
34+
automaticDeviceClass = "gpu"
35+
automaticDeviceKind = automaticDeviceVendor + "/" + automaticDeviceClass
36+
)
37+
38+
func newAutomaticCDISpecModifier(logger logger.Interface, cfg *config.Config, devices []string) (oci.SpecModifier, error) {
39+
logger.Debugf("Generating in-memory CDI specs for devices %v", devices)
40+
// TODO: We should try to load the kernel modules and create the device nodes here.
41+
// Failures should raise a warning and not error out.
42+
spec, err := generateAutomaticCDISpec(logger, cfg, devices)
43+
if err != nil {
44+
return nil, fmt.Errorf("failed to generate CDI spec: %w", err)
45+
}
46+
cdiModifier, err := cdi.New(
47+
cdi.WithLogger(logger),
48+
cdi.WithSpec(spec.Raw()),
49+
)
50+
if err != nil {
51+
return nil, fmt.Errorf("failed to construct CDI modifier: %w", err)
52+
}
53+
54+
return cdiModifier, nil
55+
}
56+
57+
func generateAutomaticCDISpec(logger logger.Interface, cfg *config.Config, devices []string) (spec.Interface, error) {
58+
cdilib, err := nvcdi.New(
59+
nvcdi.WithLogger(logger),
60+
nvcdi.WithNVIDIACDIHookPath(cfg.NVIDIACTKConfig.Path),
61+
nvcdi.WithDriverRoot(cfg.NVIDIAContainerCLIConfig.Root),
62+
nvcdi.WithVendor("runtime.nvidia.com"),
63+
nvcdi.WithClass("gpu"),
64+
)
65+
if err != nil {
66+
return nil, fmt.Errorf("failed to construct CDI library: %w", err)
67+
}
68+
69+
identifiers := []string{}
70+
for _, device := range devices {
71+
_, _, id := parser.ParseDevice(device)
72+
identifiers = append(identifiers, id)
73+
}
74+
75+
deviceSpecs, err := cdilib.GetDeviceSpecsByID(identifiers...)
76+
if err != nil {
77+
return nil, fmt.Errorf("failed to get CDI device specs: %w", err)
78+
}
79+
80+
commonEdits, err := cdilib.GetCommonEdits()
81+
if err != nil {
82+
return nil, fmt.Errorf("failed to get common CDI spec edits: %w", err)
83+
}
84+
85+
return spec.New(
86+
spec.WithDeviceSpecs(deviceSpecs),
87+
spec.WithEdits(*commonEdits.ContainerEdits),
88+
spec.WithVendor("runtime.nvidia.com"),
89+
spec.WithClass("gpu"),
90+
)
91+
}
92+
93+
// filterAutomaticDevices searches for "automatic" device names in the input slice.
94+
// "Automatic" devices are a well-defined list of CDI device names which, when requested,
95+
// trigger the generation of a CDI spec at runtime. This removes the need to generate a
96+
// CDI spec on the system a-priori as well as keep it up-to-date.
97+
func filterAutomaticDevices(devices []string) []string {
98+
var automatic []string
99+
for _, device := range devices {
100+
vendor, class, _ := parser.ParseDevice(device)
101+
if vendor == automaticDeviceVendor && class == automaticDeviceClass {
102+
automatic = append(automatic, device)
103+
}
104+
}
105+
return automatic
106+
}

internal/modifier/options.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
**/
16+
17+
package modifier
18+
19+
import (
20+
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
21+
"github.com/NVIDIA/nvidia-container-toolkit/internal/info"
22+
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
23+
)
24+
25+
type options struct {
26+
logger logger.Interface
27+
config *config.Config
28+
runtimeMode info.RuntimeMode
29+
}
30+
31+
type Option func(*options)
32+
33+
func WithConfig(config *config.Config) Option {
34+
return func(o *options) {
35+
o.config = config
36+
}
37+
}
38+
39+
func WithLogger(logger logger.Interface) Option {
40+
return func(o *options) {
41+
o.logger = logger
42+
}
43+
}
44+
45+
func WithRuntimeMode(runtimeMode info.RuntimeMode) Option {
46+
return func(o *options) {
47+
o.runtimeMode = runtimeMode
48+
}
49+
}

0 commit comments

Comments
 (0)