diff --git a/.gitignore b/.gitignore index e0c78c39..fb410e1d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,11 @@ dist +artifacts *.swp *.swo /coverage.out* /test/output/ /nvidia-container-runtime +/nvidia-container-runtime.* /nvidia-container-runtime-hook /nvidia-container-toolkit /nvidia-ctk diff --git a/cmd/nvidia-container-runtime.cdi/main.go b/cmd/nvidia-container-runtime.cdi/main.go new file mode 100644 index 00000000..f5a125a1 --- /dev/null +++ b/cmd/nvidia-container-runtime.cdi/main.go @@ -0,0 +1,34 @@ +/** +# 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 main + +import ( + "os" + + "github.com/NVIDIA/nvidia-container-toolkit/internal/runtime" +) + +func main() { + rt := runtime.New( + runtime.WithModeOverride("cdi"), + ) + + err := rt.Run(os.Args) + if err != nil { + os.Exit(1) + } +} diff --git a/cmd/nvidia-container-runtime.legacy/main.go b/cmd/nvidia-container-runtime.legacy/main.go new file mode 100644 index 00000000..7ea71de2 --- /dev/null +++ b/cmd/nvidia-container-runtime.legacy/main.go @@ -0,0 +1,34 @@ +/** +# 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 main + +import ( + "os" + + "github.com/NVIDIA/nvidia-container-toolkit/internal/runtime" +) + +func main() { + rt := runtime.New( + runtime.WithModeOverride("legacy"), + ) + + err := rt.Run(os.Args) + if err != nil { + os.Exit(1) + } +} diff --git a/cmd/nvidia-container-runtime/main.go b/cmd/nvidia-container-runtime/main.go index 9859d910..c11c0a6a 100644 --- a/cmd/nvidia-container-runtime/main.go +++ b/cmd/nvidia-container-runtime/main.go @@ -1,89 +1,15 @@ package main import ( - "fmt" "os" - "strings" - "github.com/NVIDIA/nvidia-container-toolkit/internal/config" - "github.com/NVIDIA/nvidia-container-toolkit/internal/info" - "github.com/opencontainers/runtime-spec/specs-go" + "github.com/NVIDIA/nvidia-container-toolkit/internal/runtime" ) -// version must be set by go build's -X main.version= option in the Makefile. -var version = "unknown" - -// gitCommit will be the hash that the binary was built from -// and will be populated by the Makefile -var gitCommit = "" - -var logger = NewLogger() - func main() { - err := run(os.Args) + r := runtime.New() + err := r.Run(os.Args) if err != nil { - logger.Errorf("%v", err) os.Exit(1) } } - -// run is an entry point that allows for idiomatic handling of errors -// when calling from the main function. -func run(argv []string) (rerr error) { - printVersion := hasVersionFlag(argv) - if printVersion { - fmt.Printf("%v version %v\n", "NVIDIA Container Runtime", info.GetVersionString(fmt.Sprintf("spec: %v", specs.Version))) - } - - cfg, err := config.GetConfig() - if err != nil { - return fmt.Errorf("error loading config: %v", err) - } - - logger, err = UpdateLogger( - cfg.NVIDIAContainerRuntimeConfig.DebugFilePath, - cfg.NVIDIAContainerRuntimeConfig.LogLevel, - argv, - ) - if err != nil { - return fmt.Errorf("failed to set up logger: %v", err) - } - defer func() { - if rerr != nil { - logger.Errorf("%v", rerr) - } - logger.Reset() - }() - - logger.Debugf("Command line arguments: %v", argv) - runtime, err := newNVIDIAContainerRuntime(logger.Logger, cfg, argv) - if err != nil { - return fmt.Errorf("failed to create NVIDIA Container Runtime: %v", err) - } - - if printVersion { - fmt.Print("\n") - } - return runtime.Exec(argv) -} - -// TODO: This should be refactored / combined with parseArgs in logger. -func hasVersionFlag(args []string) bool { - for i := 0; i < len(args); i++ { - param := args[i] - - parts := strings.SplitN(param, "=", 2) - trimmed := strings.TrimLeft(parts[0], "-") - // If this is not a flag we continue - if parts[0] == trimmed { - continue - } - - // Check the version flag - if trimmed == "version" { - return true - } - } - - return false -} diff --git a/cmd/nvidia-container-runtime/main_test.go b/cmd/nvidia-container-runtime/main_test.go index 218c6d40..05809aee 100644 --- a/cmd/nvidia-container-runtime/main_test.go +++ b/cmd/nvidia-container-runtime/main_test.go @@ -13,6 +13,7 @@ import ( "github.com/NVIDIA/nvidia-container-toolkit/internal/modifier" "github.com/NVIDIA/nvidia-container-toolkit/internal/test" "github.com/opencontainers/runtime-spec/specs-go" + "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" ) @@ -41,7 +42,7 @@ func TestMain(m *testing.M) { var err error moduleRoot, err := test.GetModuleRoot() if err != nil { - logger.Fatalf("error in test setup: could not get module root: %v", err) + logrus.Fatalf("error in test setup: could not get module root: %v", err) } testBinPath := filepath.Join(moduleRoot, "test", "bin") testInputPath := filepath.Join(moduleRoot, "test", "input") @@ -53,11 +54,11 @@ func TestMain(m *testing.M) { // Confirm that the environment is configured correctly runcPath, err := exec.LookPath(runcExecutableName) if err != nil || filepath.Join(testBinPath, runcExecutableName) != runcPath { - logger.Fatalf("error in test setup: mock runc path set incorrectly in TestMain(): %v", err) + logrus.Fatalf("error in test setup: mock runc path set incorrectly in TestMain(): %v", err) } hookPath, err := exec.LookPath(nvidiaHook) if err != nil || filepath.Join(testBinPath, nvidiaHook) != hookPath { - logger.Fatalf("error in test setup: mock hook path set incorrectly in TestMain(): %v", err) + logrus.Fatalf("error in test setup: mock hook path set incorrectly in TestMain(): %v", err) } // Store the root and binary paths in the test Config @@ -77,7 +78,7 @@ func TestMain(m *testing.M) { // case 1) nvidia-container-runtime run --bundle // case 2) nvidia-container-runtime create --bundle -// - Confirm the runtime handles bad input correctly +// - Confirm the runtime handles bad input correctly func TestBadInput(t *testing.T) { err := cfg.generateNewRuntimeSpec() if err != nil { @@ -91,9 +92,10 @@ func TestBadInput(t *testing.T) { } // case 1) nvidia-container-runtime run --bundle -// - Confirm the runtime runs with no errors +// - Confirm the runtime runs with no errors +// // case 2) nvidia-container-runtime create --bundle -// - Confirm the runtime inserts the NVIDIA prestart hook correctly +// - Confirm the runtime inserts the NVIDIA prestart hook correctly func TestGoodInput(t *testing.T) { err := cfg.generateNewRuntimeSpec() if err != nil { @@ -170,7 +172,7 @@ func TestDuplicateHook(t *testing.T) { // addNVIDIAHook is a basic wrapper for an addHookModifier that is used for // testing. func addNVIDIAHook(spec *specs.Spec) error { - m := modifier.NewStableRuntimeModifier(logger.Logger) + m := modifier.NewStableRuntimeModifier(logrus.StandardLogger()) return m.Modify(spec) } diff --git a/internal/runtime/runtime_modifier.go b/internal/oci/runtime_modifier.go similarity index 86% rename from internal/runtime/runtime_modifier.go rename to internal/oci/runtime_modifier.go index d11fda82..2a61445d 100644 --- a/internal/runtime/runtime_modifier.go +++ b/internal/oci/runtime_modifier.go @@ -14,27 +14,26 @@ # limitations under the License. */ -package runtime +package oci import ( "fmt" - "github.com/NVIDIA/nvidia-container-toolkit/internal/oci" log "github.com/sirupsen/logrus" ) type modifyingRuntimeWrapper struct { logger *log.Logger - runtime oci.Runtime - ociSpec oci.Spec - modifier oci.SpecModifier + runtime Runtime + ociSpec Spec + modifier SpecModifier } -var _ oci.Runtime = (*modifyingRuntimeWrapper)(nil) +var _ Runtime = (*modifyingRuntimeWrapper)(nil) // NewModifyingRuntimeWrapper creates a runtime wrapper that applies the specified modifier to the OCI specification // before invoking the wrapped runtime. If the modifier is nil, the input runtime is returned. -func NewModifyingRuntimeWrapper(logger *log.Logger, runtime oci.Runtime, spec oci.Spec, modifier oci.SpecModifier) oci.Runtime { +func NewModifyingRuntimeWrapper(logger *log.Logger, runtime Runtime, spec Spec, modifier SpecModifier) Runtime { if modifier == nil { logger.Infof("Using low-level runtime with no modification") return runtime @@ -52,7 +51,7 @@ func NewModifyingRuntimeWrapper(logger *log.Logger, runtime oci.Runtime, spec oc // Exec checks whether a modification of the OCI specification is required and modifies it accordingly before exec-ing // into the wrapped runtime. func (r *modifyingRuntimeWrapper) Exec(args []string) error { - if oci.HasCreateSubcommand(args) { + if HasCreateSubcommand(args) { err := r.modify() if err != nil { return fmt.Errorf("could not apply required modification to OCI specification: %v", err) diff --git a/internal/runtime/runtime_modifier_test.go b/internal/oci/runtime_modifier_test.go similarity index 92% rename from internal/runtime/runtime_modifier_test.go rename to internal/oci/runtime_modifier_test.go index bd07bf24..47aebc8d 100644 --- a/internal/runtime/runtime_modifier_test.go +++ b/internal/oci/runtime_modifier_test.go @@ -14,13 +14,12 @@ # limitations under the License. */ -package runtime +package oci import ( "fmt" "testing" - "github.com/NVIDIA/nvidia-container-toolkit/internal/oci" "github.com/opencontainers/runtime-spec/specs-go" testlog "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" @@ -38,7 +37,7 @@ func TestExec(t *testing.T) { args []string modifyError error writeError error - modifer oci.SpecModifier + modifer SpecModifier }{ { description: "no args forwards", @@ -92,9 +91,9 @@ func TestExec(t *testing.T) { hook.Reset() t.Run(tc.description, func(t *testing.T) { - runtimeMock := &oci.RuntimeMock{} - specMock := &oci.SpecMock{ - ModifyFunc: func(specModifier oci.SpecModifier) error { + runtimeMock := &RuntimeMock{} + specMock := &SpecMock{ + ModifyFunc: func(specModifier SpecModifier) error { return tc.modifyError }, FlushFunc: func() error { @@ -144,8 +143,8 @@ func TestExec(t *testing.T) { func TestNilModiferReturnsRuntime(t *testing.T) { logger, _ := testlog.NewNullLogger() - runtimeMock := &oci.RuntimeMock{} - specMock := &oci.SpecMock{} + runtimeMock := &RuntimeMock{} + specMock := &SpecMock{} shim := NewModifyingRuntimeWrapper( logger, diff --git a/internal/runtime/api.go b/internal/runtime/api.go new file mode 100644 index 00000000..233583b8 --- /dev/null +++ b/internal/runtime/api.go @@ -0,0 +1,33 @@ +package runtime + +type rt struct { + logger *Logger + modeOverride string +} + +// Interface is the interface for the runtime library. +type Interface interface { + Run([]string) error +} + +// Option is a function that configures the runtime. +type Option func(*rt) + +// New creates a runtime with the specified options. +func New(opts ...Option) Interface { + r := rt{} + for _, opt := range opts { + opt(&r) + } + if r.logger == nil { + r.logger = NewLogger() + } + return &r +} + +// WithModeOverride allows for overriding the mode specified in the config. +func WithModeOverride(mode string) Option { + return func(r *rt) { + r.modeOverride = mode + } +} diff --git a/cmd/nvidia-container-runtime/logger.go b/internal/runtime/logger.go similarity index 93% rename from cmd/nvidia-container-runtime/logger.go rename to internal/runtime/logger.go index e886a020..2b5c9730 100644 --- a/cmd/nvidia-container-runtime/logger.go +++ b/internal/runtime/logger.go @@ -14,7 +14,7 @@ # limitations under the License. */ -package main +package runtime import ( "fmt" @@ -42,8 +42,8 @@ func NewLogger() *Logger { } } -// UpdateLogger constructs a Logger with a preddefined formatter -func UpdateLogger(filename string, logLevel string, argv []string) (*Logger, error) { +// Update constructs a Logger with a preddefined formatter +func (l *Logger) Update(filename string, logLevel string, argv []string) error { configFromArgs := parseArgs(argv) level, logLevelError := configFromArgs.getLevel(logLevel) @@ -55,7 +55,7 @@ func UpdateLogger(filename string, logLevel string, argv []string) (*Logger, err if !configFromArgs.version { configLogFile, err := createLogFile(filename) if err != nil { - return logger, fmt.Errorf("error opening debug log file: %v", err) + return fmt.Errorf("error opening debug log file: %v", err) } if configLogFile != nil { logFiles = append(logFiles, configLogFile) @@ -68,9 +68,10 @@ func UpdateLogger(filename string, logLevel string, argv []string) (*Logger, err argLogFileError = err } - l := &Logger{ + previous := l.Logger + l = &Logger{ Logger: logrus.New(), - previousLogger: logger.Logger, + previousLogger: previous, logFiles: logFiles, } @@ -115,7 +116,7 @@ func UpdateLogger(filename string, logLevel string, argv []string) (*Logger, err l.Warnf("Failed to open log file: %v", argLogFileError) } - return l, nil + return nil } // Reset closes the log file (if any) and resets the logger output to what it @@ -126,7 +127,7 @@ func (l *Logger) Reset() error { if previous == nil { previous = logrus.New() } - logger = &Logger{Logger: previous} + l = &Logger{Logger: previous} }() var errs []error diff --git a/internal/runtime/runtime.go b/internal/runtime/runtime.go new file mode 100644 index 00000000..5634e75a --- /dev/null +++ b/internal/runtime/runtime.go @@ -0,0 +1,109 @@ +/** +# 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 runtime + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/NVIDIA/nvidia-container-toolkit/internal/config" + "github.com/NVIDIA/nvidia-container-toolkit/internal/info" + "github.com/opencontainers/runtime-spec/specs-go" +) + +// Run is an entry point that allows for idiomatic handling of errors +// when calling from the main function. +func (r rt) Run(argv []string) (rerr error) { + defer func() { + if rerr != nil { + r.logger.Errorf("%v", rerr) + } + }() + + printVersion := hasVersionFlag(argv) + if printVersion { + fmt.Printf("%v version %v\n", "NVIDIA Container Runtime", info.GetVersionString(fmt.Sprintf("spec: %v", specs.Version))) + } + + cfg, err := config.GetConfig() + if err != nil { + return fmt.Errorf("error loading config: %v", err) + } + if r.modeOverride != "" { + cfg.NVIDIAContainerRuntimeConfig.Mode = r.modeOverride + } + + err = r.logger.Update( + cfg.NVIDIAContainerRuntimeConfig.DebugFilePath, + cfg.NVIDIAContainerRuntimeConfig.LogLevel, + argv, + ) + if err != nil { + return fmt.Errorf("failed to set up logger: %v", err) + } + defer func() { + if rerr != nil { + r.logger.Errorf("%v", rerr) + } + r.logger.Reset() + }() + + // Print the config to the output. + configJSON, err := json.MarshalIndent(cfg, "", " ") + if err == nil { + r.logger.Infof("Running with config:\n%v", string(configJSON)) + } else { + r.logger.Infof("Running with config:\n%+v", cfg) + } + + r.logger.Debugf("Command line arguments: %v", argv) + runtime, err := newNVIDIAContainerRuntime(r.logger.Logger, cfg, argv) + if err != nil { + return fmt.Errorf("failed to create NVIDIA Container Runtime: %v", err) + } + + if printVersion { + fmt.Print("\n") + } + return runtime.Exec(argv) +} + +func (r rt) Errorf(format string, args ...interface{}) { + r.logger.Errorf(format, args...) +} + +// TODO: This should be refactored / combined with parseArgs in logger. +func hasVersionFlag(args []string) bool { + for i := 0; i < len(args); i++ { + param := args[i] + + parts := strings.SplitN(param, "=", 2) + trimmed := strings.TrimLeft(parts[0], "-") + // If this is not a flag we continue + if parts[0] == trimmed { + continue + } + + // Check the version flag + if trimmed == "version" { + return true + } + } + + return false +} diff --git a/cmd/nvidia-container-runtime/runtime_factory.go b/internal/runtime/runtime_factory.go similarity index 96% rename from cmd/nvidia-container-runtime/runtime_factory.go rename to internal/runtime/runtime_factory.go index 1754e525..29219ab8 100644 --- a/cmd/nvidia-container-runtime/runtime_factory.go +++ b/internal/runtime/runtime_factory.go @@ -14,7 +14,7 @@ # limitations under the License. */ -package main +package runtime import ( "fmt" @@ -23,7 +23,6 @@ import ( "github.com/NVIDIA/nvidia-container-toolkit/internal/info" "github.com/NVIDIA/nvidia-container-toolkit/internal/modifier" "github.com/NVIDIA/nvidia-container-toolkit/internal/oci" - "github.com/NVIDIA/nvidia-container-toolkit/internal/runtime" "github.com/sirupsen/logrus" ) @@ -50,7 +49,7 @@ func newNVIDIAContainerRuntime(logger *logrus.Logger, cfg *config.Config, argv [ } // Create the wrapping runtime with the specified modifier - r := runtime.NewModifyingRuntimeWrapper( + r := oci.NewModifyingRuntimeWrapper( logger, lowLevelRuntime, ociSpec, diff --git a/cmd/nvidia-container-runtime/runtime_factory_test.go b/internal/runtime/runtime_factory_test.go similarity index 77% rename from cmd/nvidia-container-runtime/runtime_factory_test.go rename to internal/runtime/runtime_factory_test.go index 88d4ddb5..7f443e82 100644 --- a/cmd/nvidia-container-runtime/runtime_factory_test.go +++ b/internal/runtime/runtime_factory_test.go @@ -14,20 +14,52 @@ # limitations under the License. */ -package main +package runtime import ( "encoding/json" "os" + "os/exec" "path/filepath" "testing" "github.com/NVIDIA/nvidia-container-toolkit/internal/config" + "github.com/NVIDIA/nvidia-container-toolkit/internal/test" "github.com/opencontainers/runtime-spec/specs-go" + "github.com/sirupsen/logrus" testlog "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" ) +const ( + runcExecutableName = "runc" +) + +func TestMain(m *testing.M) { + // TEST SETUP + // Determine the module root and the test binary path + var err error + moduleRoot, err := test.GetModuleRoot() + if err != nil { + logrus.Fatalf("error in test setup: could not get module root: %v", err) + } + testBinPath := filepath.Join(moduleRoot, "test", "bin") + + // Set the environment variables for the test + os.Setenv("PATH", test.PrependToPath(testBinPath, moduleRoot)) + + // Confirm that the environment is configured correctly + runcPath, err := exec.LookPath(runcExecutableName) + if err != nil || filepath.Join(testBinPath, runcExecutableName) != runcPath { + logrus.Fatalf("error in test setup: mock runc path set incorrectly in TestMain(): %v", err) + } + + // RUN TESTS + exitCode := m.Run() + + os.Exit(exitCode) +} + func TestFactoryMethod(t *testing.T) { logger, _ := testlog.NewNullLogger() diff --git a/packaging/debian/control b/packaging/debian/control index fe42428b..c43cbcbd 100644 --- a/packaging/debian/control +++ b/packaging/debian/control @@ -23,3 +23,9 @@ Breaks: nvidia-container-runtime (<= 3.5.0-1), nvidia-container-runtime-hook, nv Replaces: nvidia-container-runtime (<= 3.5.0-1), nvidia-container-runtime-hook Description: NVIDIA Container Toolkit Base Provides tools such as the NVIDIA Container Runtime and NVIDIA Container Toolkit CLI to enable GPU support in containers. + +Package: nvidia-container-toolkit-operator-extensions +Architecture: any +Depends: ${misc:Depends}, nvidia-container-toolkit-base (= @VERSION@) +Description: NVIDIA Container Toolkit Operator Extensions + Provides tools for using the NVIDIA Container Toolkit with the GPU Operator diff --git a/packaging/debian/nvidia-container-toolkit-operator-extensions.install b/packaging/debian/nvidia-container-toolkit-operator-extensions.install new file mode 100644 index 00000000..4c4729ef --- /dev/null +++ b/packaging/debian/nvidia-container-toolkit-operator-extensions.install @@ -0,0 +1,2 @@ +nvidia-container-runtime.cdi /usr/bin +nvidia-container-runtime.legacy /usr/bin \ No newline at end of file diff --git a/packaging/rpm/SPECS/nvidia-container-toolkit.spec b/packaging/rpm/SPECS/nvidia-container-toolkit.spec index f206f632..a4ea15bf 100644 --- a/packaging/rpm/SPECS/nvidia-container-toolkit.spec +++ b/packaging/rpm/SPECS/nvidia-container-toolkit.spec @@ -11,12 +11,14 @@ URL: https://github.com/NVIDIA/nvidia-container-toolkit License: Apache-2.0 Source0: nvidia-container-runtime-hook -Source1: nvidia-container-runtime -Source2: nvidia-ctk -Source3: config.toml -Source4: oci-nvidia-hook -Source5: oci-nvidia-hook.json -Source6: LICENSE +Source1: nvidia-ctk +Source2: config.toml +Source3: oci-nvidia-hook +Source4: oci-nvidia-hook.json +Source5: LICENSE +Source6: nvidia-container-runtime +Source7: nvidia-container-runtime.cdi +Source8: nvidia-container-runtime.legacy Obsoletes: nvidia-container-runtime <= 3.5.0-1, nvidia-container-runtime-hook <= 1.4.0-2 Provides: nvidia-container-runtime @@ -35,12 +37,14 @@ Requires: libseccomp Provides tools and utilities to enable GPU support in containers. %prep -cp %{SOURCE0} %{SOURCE1} %{SOURCE2} %{SOURCE3} %{SOURCE4} %{SOURCE5} %{SOURCE6} . +cp %{SOURCE0} %{SOURCE1} %{SOURCE2} %{SOURCE3} %{SOURCE4} %{SOURCE5} %{SOURCE6} %{SOURCE7} %{SOURCE8} . %install mkdir -p %{buildroot}%{_bindir} install -m 755 -t %{buildroot}%{_bindir} nvidia-container-runtime-hook install -m 755 -t %{buildroot}%{_bindir} nvidia-container-runtime +install -m 755 -t %{buildroot}%{_bindir} nvidia-container-runtime.cdi +install -m 755 -t %{buildroot}%{_bindir} nvidia-container-runtime.legacy install -m 755 -t %{buildroot}%{_bindir} nvidia-ctk mkdir -p %{buildroot}/etc/nvidia-container-runtime @@ -57,10 +61,10 @@ mkdir -p %{_localstatedir}/lib/rpm-state/nvidia-container-toolkit cp -af %{_bindir}/nvidia-container-runtime-hook %{_localstatedir}/lib/rpm-state/nvidia-container-toolkit %posttrans -if [ ! -e %{_bindir}/nvidia-container-runtime-hook ]; then +if [ ! -e %{_bindir}/nvidia-container-runtime-hook ]; then # reparing lost file nvidia-container-runtime-hook - cp -avf %{_localstatedir}/lib/rpm-state/nvidia-container-toolkit/nvidia-container-runtime-hook %{_bindir} -fi + cp -avf %{_localstatedir}/lib/rpm-state/nvidia-container-toolkit/nvidia-container-runtime-hook %{_bindir} +fi rm -rf %{_localstatedir}/lib/rpm-state/nvidia-container-toolkit ln -sf %{_bindir}/nvidia-container-runtime-hook %{_bindir}/nvidia-container-toolkit @@ -97,3 +101,17 @@ Provides tools such as the NVIDIA Container Runtime and NVIDIA Container Toolkit %config /etc/nvidia-container-runtime/config.toml %{_bindir}/nvidia-container-runtime %{_bindir}/nvidia-ctk + +# The OPERATOR EXTENSIONS package consists of components that are required to enable GPU support in Kubernetes. +# This package is not distributed as part of the NVIDIA Container Toolkit RPMs. +%package operator-extensions +Summary: NVIDIA Container Toolkit Operator Extensions +Requires: nvidia-container-toolkit-base == %{version}-%{release} + +%description operator-extensions +Provides tools for using the NVIDIA Container Toolkit with the GPU Operator + +%files operator-extensions +%license LICENSE +%{_bindir}/nvidia-container-runtime.cdi +%{_bindir}/nvidia-container-runtime.legacy diff --git a/scripts/extract-packages.sh b/scripts/extract-packages.sh index 9cc326b4..a3e8bf90 100755 --- a/scripts/extract-packages.sh +++ b/scripts/extract-packages.sh @@ -40,6 +40,12 @@ PACKAGE_IMAGE=$1 # For example, we don't release release candidates of nvidia-container-runtime and nvidia-docker2 # since these only bump the nvidia-container-toolkit dependency. function skip-for-release-candidate() { + # We always skip nvidia-container-toolkit-operator-extensions packages + if [[ "${package_name/"nvidia-container-toolkit-operator-extensions"/}" != "${package_name}" ]]; then + return 0 + fi + + # We allow all other packages for non-rc versions. if [[ "${VERSION/rc./}" == "${VERSION}" ]]; then return 1 fi diff --git a/scripts/release-packages.sh b/scripts/release-packages.sh index d15e2ae6..253df007 100755 --- a/scripts/release-packages.sh +++ b/scripts/release-packages.sh @@ -120,6 +120,12 @@ function sync() { mkdir -p ${dst} for f in $(ls ${src}/libnvidia-container*.${pkg_type} ${src}/nvidia-container-toolkit*.${pkg_type}); do + # We never release nvidia-container-toolkit-operator-extensions packages + if [[ "${f/"nvidia-container-toolkit-operator-extensions"/}" != "${f}" ]]; then + echo "Skipping ${f}" + continue + fi + df=${dst}/$(basename ${f}) df_stable=${df//"/experimental/"/"/stable/"} if [[ -f "${df}" ]]; then