mirror of
https://github.com/NVIDIA/nvidia-container-toolkit
synced 2025-05-07 13:35:20 +00:00
Merge branch 'cdi-executable' into 'main'
Add nvidia-container-runtime.{{MODE}} executable that overrides runtime mode See merge request nvidia/container-toolkit/container-toolkit!288
This commit is contained in:
commit
dc4887cd44
.gitignore
cmd
nvidia-container-runtime.cdi
nvidia-container-runtime.legacy
nvidia-container-runtime
internal
oci
runtime
packaging
debian
rpm/SPECS
scripts
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,9 +1,11 @@
|
|||||||
dist
|
dist
|
||||||
|
artifacts
|
||||||
*.swp
|
*.swp
|
||||||
*.swo
|
*.swo
|
||||||
/coverage.out*
|
/coverage.out*
|
||||||
/test/output/
|
/test/output/
|
||||||
/nvidia-container-runtime
|
/nvidia-container-runtime
|
||||||
|
/nvidia-container-runtime.*
|
||||||
/nvidia-container-runtime-hook
|
/nvidia-container-runtime-hook
|
||||||
/nvidia-container-toolkit
|
/nvidia-container-toolkit
|
||||||
/nvidia-ctk
|
/nvidia-ctk
|
||||||
|
34
cmd/nvidia-container-runtime.cdi/main.go
Normal file
34
cmd/nvidia-container-runtime.cdi/main.go
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
34
cmd/nvidia-container-runtime.legacy/main.go
Normal file
34
cmd/nvidia-container-runtime.legacy/main.go
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
@ -1,89 +1,15 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/runtime"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/info"
|
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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() {
|
func main() {
|
||||||
err := run(os.Args)
|
r := runtime.New()
|
||||||
|
err := r.Run(os.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("%v", err)
|
|
||||||
os.Exit(1)
|
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
|
|
||||||
}
|
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/modifier"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/modifier"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/test"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/test"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ func TestMain(m *testing.M) {
|
|||||||
var err error
|
var err error
|
||||||
moduleRoot, err := test.GetModuleRoot()
|
moduleRoot, err := test.GetModuleRoot()
|
||||||
if err != nil {
|
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")
|
testBinPath := filepath.Join(moduleRoot, "test", "bin")
|
||||||
testInputPath := filepath.Join(moduleRoot, "test", "input")
|
testInputPath := filepath.Join(moduleRoot, "test", "input")
|
||||||
@ -53,11 +54,11 @@ func TestMain(m *testing.M) {
|
|||||||
// Confirm that the environment is configured correctly
|
// Confirm that the environment is configured correctly
|
||||||
runcPath, err := exec.LookPath(runcExecutableName)
|
runcPath, err := exec.LookPath(runcExecutableName)
|
||||||
if err != nil || filepath.Join(testBinPath, runcExecutableName) != runcPath {
|
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)
|
hookPath, err := exec.LookPath(nvidiaHook)
|
||||||
if err != nil || filepath.Join(testBinPath, nvidiaHook) != hookPath {
|
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
|
// Store the root and binary paths in the test Config
|
||||||
@ -92,6 +93,7 @@ func TestBadInput(t *testing.T) {
|
|||||||
|
|
||||||
// case 1) nvidia-container-runtime run --bundle <bundle-name> <ctr-name>
|
// case 1) nvidia-container-runtime run --bundle <bundle-name> <ctr-name>
|
||||||
// - Confirm the runtime runs with no errors
|
// - Confirm the runtime runs with no errors
|
||||||
|
//
|
||||||
// case 2) nvidia-container-runtime create --bundle <bundle-name> <ctr-name>
|
// case 2) nvidia-container-runtime create --bundle <bundle-name> <ctr-name>
|
||||||
// - Confirm the runtime inserts the NVIDIA prestart hook correctly
|
// - Confirm the runtime inserts the NVIDIA prestart hook correctly
|
||||||
func TestGoodInput(t *testing.T) {
|
func TestGoodInput(t *testing.T) {
|
||||||
@ -170,7 +172,7 @@ func TestDuplicateHook(t *testing.T) {
|
|||||||
// addNVIDIAHook is a basic wrapper for an addHookModifier that is used for
|
// addNVIDIAHook is a basic wrapper for an addHookModifier that is used for
|
||||||
// testing.
|
// testing.
|
||||||
func addNVIDIAHook(spec *specs.Spec) error {
|
func addNVIDIAHook(spec *specs.Spec) error {
|
||||||
m := modifier.NewStableRuntimeModifier(logger.Logger)
|
m := modifier.NewStableRuntimeModifier(logrus.StandardLogger())
|
||||||
return m.Modify(spec)
|
return m.Modify(spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,27 +14,26 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package runtime
|
package oci
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type modifyingRuntimeWrapper struct {
|
type modifyingRuntimeWrapper struct {
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
runtime oci.Runtime
|
runtime Runtime
|
||||||
ociSpec oci.Spec
|
ociSpec Spec
|
||||||
modifier oci.SpecModifier
|
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
|
// 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.
|
// 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 {
|
if modifier == nil {
|
||||||
logger.Infof("Using low-level runtime with no modification")
|
logger.Infof("Using low-level runtime with no modification")
|
||||||
return runtime
|
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
|
// Exec checks whether a modification of the OCI specification is required and modifies it accordingly before exec-ing
|
||||||
// into the wrapped runtime.
|
// into the wrapped runtime.
|
||||||
func (r *modifyingRuntimeWrapper) Exec(args []string) error {
|
func (r *modifyingRuntimeWrapper) Exec(args []string) error {
|
||||||
if oci.HasCreateSubcommand(args) {
|
if HasCreateSubcommand(args) {
|
||||||
err := r.modify()
|
err := r.modify()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not apply required modification to OCI specification: %v", err)
|
return fmt.Errorf("could not apply required modification to OCI specification: %v", err)
|
@ -14,13 +14,12 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package runtime
|
package oci
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
testlog "github.com/sirupsen/logrus/hooks/test"
|
testlog "github.com/sirupsen/logrus/hooks/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -38,7 +37,7 @@ func TestExec(t *testing.T) {
|
|||||||
args []string
|
args []string
|
||||||
modifyError error
|
modifyError error
|
||||||
writeError error
|
writeError error
|
||||||
modifer oci.SpecModifier
|
modifer SpecModifier
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
description: "no args forwards",
|
description: "no args forwards",
|
||||||
@ -92,9 +91,9 @@ func TestExec(t *testing.T) {
|
|||||||
hook.Reset()
|
hook.Reset()
|
||||||
|
|
||||||
t.Run(tc.description, func(t *testing.T) {
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
runtimeMock := &oci.RuntimeMock{}
|
runtimeMock := &RuntimeMock{}
|
||||||
specMock := &oci.SpecMock{
|
specMock := &SpecMock{
|
||||||
ModifyFunc: func(specModifier oci.SpecModifier) error {
|
ModifyFunc: func(specModifier SpecModifier) error {
|
||||||
return tc.modifyError
|
return tc.modifyError
|
||||||
},
|
},
|
||||||
FlushFunc: func() error {
|
FlushFunc: func() error {
|
||||||
@ -144,8 +143,8 @@ func TestExec(t *testing.T) {
|
|||||||
func TestNilModiferReturnsRuntime(t *testing.T) {
|
func TestNilModiferReturnsRuntime(t *testing.T) {
|
||||||
logger, _ := testlog.NewNullLogger()
|
logger, _ := testlog.NewNullLogger()
|
||||||
|
|
||||||
runtimeMock := &oci.RuntimeMock{}
|
runtimeMock := &RuntimeMock{}
|
||||||
specMock := &oci.SpecMock{}
|
specMock := &SpecMock{}
|
||||||
|
|
||||||
shim := NewModifyingRuntimeWrapper(
|
shim := NewModifyingRuntimeWrapper(
|
||||||
logger,
|
logger,
|
33
internal/runtime/api.go
Normal file
33
internal/runtime/api.go
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package runtime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -42,8 +42,8 @@ func NewLogger() *Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateLogger constructs a Logger with a preddefined formatter
|
// Update constructs a Logger with a preddefined formatter
|
||||||
func UpdateLogger(filename string, logLevel string, argv []string) (*Logger, error) {
|
func (l *Logger) Update(filename string, logLevel string, argv []string) error {
|
||||||
configFromArgs := parseArgs(argv)
|
configFromArgs := parseArgs(argv)
|
||||||
|
|
||||||
level, logLevelError := configFromArgs.getLevel(logLevel)
|
level, logLevelError := configFromArgs.getLevel(logLevel)
|
||||||
@ -55,7 +55,7 @@ func UpdateLogger(filename string, logLevel string, argv []string) (*Logger, err
|
|||||||
if !configFromArgs.version {
|
if !configFromArgs.version {
|
||||||
configLogFile, err := createLogFile(filename)
|
configLogFile, err := createLogFile(filename)
|
||||||
if err != nil {
|
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 {
|
if configLogFile != nil {
|
||||||
logFiles = append(logFiles, configLogFile)
|
logFiles = append(logFiles, configLogFile)
|
||||||
@ -68,9 +68,10 @@ func UpdateLogger(filename string, logLevel string, argv []string) (*Logger, err
|
|||||||
argLogFileError = err
|
argLogFileError = err
|
||||||
}
|
}
|
||||||
|
|
||||||
l := &Logger{
|
previous := l.Logger
|
||||||
|
l = &Logger{
|
||||||
Logger: logrus.New(),
|
Logger: logrus.New(),
|
||||||
previousLogger: logger.Logger,
|
previousLogger: previous,
|
||||||
logFiles: logFiles,
|
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)
|
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
|
// 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 {
|
if previous == nil {
|
||||||
previous = logrus.New()
|
previous = logrus.New()
|
||||||
}
|
}
|
||||||
logger = &Logger{Logger: previous}
|
l = &Logger{Logger: previous}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var errs []error
|
var errs []error
|
109
internal/runtime/runtime.go
Normal file
109
internal/runtime/runtime.go
Normal file
@ -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
|
||||||
|
}
|
@ -14,7 +14,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package runtime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -23,7 +23,6 @@ import (
|
|||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/info"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/info"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/modifier"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/modifier"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
"github.com/NVIDIA/nvidia-container-toolkit/internal/oci"
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/runtime"
|
|
||||||
"github.com/sirupsen/logrus"
|
"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
|
// Create the wrapping runtime with the specified modifier
|
||||||
r := runtime.NewModifyingRuntimeWrapper(
|
r := oci.NewModifyingRuntimeWrapper(
|
||||||
logger,
|
logger,
|
||||||
lowLevelRuntime,
|
lowLevelRuntime,
|
||||||
ociSpec,
|
ociSpec,
|
@ -14,20 +14,52 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package runtime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
|
"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/opencontainers/runtime-spec/specs-go"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
testlog "github.com/sirupsen/logrus/hooks/test"
|
testlog "github.com/sirupsen/logrus/hooks/test"
|
||||||
"github.com/stretchr/testify/require"
|
"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) {
|
func TestFactoryMethod(t *testing.T) {
|
||||||
logger, _ := testlog.NewNullLogger()
|
logger, _ := testlog.NewNullLogger()
|
||||||
|
|
@ -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
|
Replaces: nvidia-container-runtime (<= 3.5.0-1), nvidia-container-runtime-hook
|
||||||
Description: NVIDIA Container Toolkit Base
|
Description: NVIDIA Container Toolkit Base
|
||||||
Provides tools such as the NVIDIA Container Runtime and NVIDIA Container Toolkit CLI to enable GPU support in containers.
|
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
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
nvidia-container-runtime.cdi /usr/bin
|
||||||
|
nvidia-container-runtime.legacy /usr/bin
|
@ -11,12 +11,14 @@ URL: https://github.com/NVIDIA/nvidia-container-toolkit
|
|||||||
License: Apache-2.0
|
License: Apache-2.0
|
||||||
|
|
||||||
Source0: nvidia-container-runtime-hook
|
Source0: nvidia-container-runtime-hook
|
||||||
Source1: nvidia-container-runtime
|
Source1: nvidia-ctk
|
||||||
Source2: nvidia-ctk
|
Source2: config.toml
|
||||||
Source3: config.toml
|
Source3: oci-nvidia-hook
|
||||||
Source4: oci-nvidia-hook
|
Source4: oci-nvidia-hook.json
|
||||||
Source5: oci-nvidia-hook.json
|
Source5: LICENSE
|
||||||
Source6: 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
|
Obsoletes: nvidia-container-runtime <= 3.5.0-1, nvidia-container-runtime-hook <= 1.4.0-2
|
||||||
Provides: nvidia-container-runtime
|
Provides: nvidia-container-runtime
|
||||||
@ -35,12 +37,14 @@ Requires: libseccomp
|
|||||||
Provides tools and utilities to enable GPU support in containers.
|
Provides tools and utilities to enable GPU support in containers.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
cp %{SOURCE0} %{SOURCE1} %{SOURCE2} %{SOURCE3} %{SOURCE4} %{SOURCE5} %{SOURCE6} .
|
cp %{SOURCE0} %{SOURCE1} %{SOURCE2} %{SOURCE3} %{SOURCE4} %{SOURCE5} %{SOURCE6} %{SOURCE7} %{SOURCE8} .
|
||||||
|
|
||||||
%install
|
%install
|
||||||
mkdir -p %{buildroot}%{_bindir}
|
mkdir -p %{buildroot}%{_bindir}
|
||||||
install -m 755 -t %{buildroot}%{_bindir} nvidia-container-runtime-hook
|
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
|
||||||
|
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
|
install -m 755 -t %{buildroot}%{_bindir} nvidia-ctk
|
||||||
|
|
||||||
mkdir -p %{buildroot}/etc/nvidia-container-runtime
|
mkdir -p %{buildroot}/etc/nvidia-container-runtime
|
||||||
@ -97,3 +101,17 @@ Provides tools such as the NVIDIA Container Runtime and NVIDIA Container Toolkit
|
|||||||
%config /etc/nvidia-container-runtime/config.toml
|
%config /etc/nvidia-container-runtime/config.toml
|
||||||
%{_bindir}/nvidia-container-runtime
|
%{_bindir}/nvidia-container-runtime
|
||||||
%{_bindir}/nvidia-ctk
|
%{_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
|
||||||
|
@ -40,6 +40,12 @@ PACKAGE_IMAGE=$1
|
|||||||
# For example, we don't release release candidates of nvidia-container-runtime and nvidia-docker2
|
# For example, we don't release release candidates of nvidia-container-runtime and nvidia-docker2
|
||||||
# since these only bump the nvidia-container-toolkit dependency.
|
# since these only bump the nvidia-container-toolkit dependency.
|
||||||
function skip-for-release-candidate() {
|
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
|
if [[ "${VERSION/rc./}" == "${VERSION}" ]]; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
@ -120,6 +120,12 @@ function sync() {
|
|||||||
mkdir -p ${dst}
|
mkdir -p ${dst}
|
||||||
|
|
||||||
for f in $(ls ${src}/libnvidia-container*.${pkg_type} ${src}/nvidia-container-toolkit*.${pkg_type}); do
|
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=${dst}/$(basename ${f})
|
||||||
df_stable=${df//"/experimental/"/"/stable/"}
|
df_stable=${df//"/experimental/"/"/stable/"}
|
||||||
if [[ -f "${df}" ]]; then
|
if [[ -f "${df}" ]]; then
|
||||||
|
Loading…
Reference in New Issue
Block a user