2019-10-22 21:36:22 +00:00
package main
import (
2023-03-13 13:22:18 +00:00
"fmt"
2019-10-22 21:36:22 +00:00
"log"
"os"
"path"
2021-01-22 14:33:23 +00:00
"reflect"
2022-09-30 03:05:56 +00:00
"strings"
2019-10-22 21:36:22 +00:00
2022-04-06 14:05:26 +00:00
"github.com/NVIDIA/nvidia-container-toolkit/internal/config"
2023-08-10 12:15:24 +00:00
"github.com/NVIDIA/nvidia-container-toolkit/internal/config/image"
2019-10-22 21:36:22 +00:00
)
const (
configPath = "/etc/nvidia-container-runtime/config.toml"
driverPath = "/run/nvidia/driver"
)
2021-09-06 09:52:23 +00:00
// HookConfig : options for the nvidia-container-runtime-hook.
2023-08-10 12:15:24 +00:00
type HookConfig config . Config
2019-10-22 21:36:22 +00:00
2023-03-13 13:22:18 +00:00
func getDefaultHookConfig ( ) ( HookConfig , error ) {
2023-08-10 08:49:46 +00:00
defaultCfg , err := config . GetDefault ( )
2023-03-13 13:22:18 +00:00
if err != nil {
return HookConfig { } , err
}
2023-08-10 12:15:24 +00:00
return * ( * HookConfig ) ( defaultCfg ) , nil
2019-10-22 21:36:22 +00:00
}
2023-08-10 13:11:01 +00:00
// loadConfig loads the required paths for the hook config.
func loadConfig ( ) ( * config . Config , error ) {
var configPaths [ ] string
var required bool
if len ( * configflag ) != 0 {
configPaths = append ( configPaths , * configflag )
required = true
2019-10-22 21:36:22 +00:00
} else {
2023-08-10 13:11:01 +00:00
configPaths = append ( configPaths , path . Join ( driverPath , configPath ) , configPath )
}
for _ , p := range configPaths {
2023-08-04 15:56:15 +00:00
cfg , err := config . New (
config . WithConfigFile ( p ) ,
2023-09-06 15:24:36 +00:00
config . WithRequired ( true ) ,
2023-08-04 15:56:15 +00:00
)
2023-08-10 13:11:01 +00:00
if err == nil {
2023-08-04 15:56:15 +00:00
return cfg . Config ( )
2023-08-10 13:11:01 +00:00
} else if os . IsNotExist ( err ) && ! required {
continue
2019-10-22 21:36:22 +00:00
}
2023-08-04 15:56:15 +00:00
return nil , fmt . Errorf ( "couldn't open required configuration file: %v" , err )
2023-08-10 13:11:01 +00:00
}
return config . GetDefault ( )
}
func getHookConfig ( ) ( * HookConfig , error ) {
cfg , err := loadConfig ( )
if err != nil {
return nil , fmt . Errorf ( "failed to load config: %v" , err )
2019-10-22 21:36:22 +00:00
}
2023-08-10 13:11:01 +00:00
config := ( * HookConfig ) ( cfg )
2019-10-22 21:36:22 +00:00
2023-08-10 12:15:24 +00:00
allSupportedDriverCapabilities := image . SupportedDriverCapabilities
if config . SupportedDriverCapabilities == "all" {
config . SupportedDriverCapabilities = allSupportedDriverCapabilities . String ( )
2021-11-09 19:19:56 +00:00
}
2023-08-10 12:15:24 +00:00
configuredCapabilities := image . NewDriverCapabilities ( config . SupportedDriverCapabilities )
// We ensure that the configured value is a subset of all supported capabilities
if ! allSupportedDriverCapabilities . IsSuperset ( configuredCapabilities ) {
2021-11-09 19:19:56 +00:00
configName := config . getConfigOption ( "SupportedDriverCapabilities" )
2023-08-10 12:15:24 +00:00
log . Panicf ( "Invalid value for config option '%v'; %v (supported: %v)\n" , configName , config . SupportedDriverCapabilities , allSupportedDriverCapabilities . String ( ) )
2021-11-09 19:19:56 +00:00
}
2023-08-10 13:11:01 +00:00
return config , nil
2019-10-22 21:36:22 +00:00
}
2021-01-22 14:33:23 +00:00
// getConfigOption returns the toml config option associated with the
// specified struct field.
func ( c HookConfig ) getConfigOption ( fieldName string ) string {
t := reflect . TypeOf ( c )
f , ok := t . FieldByName ( fieldName )
if ! ok {
return fieldName
}
v , ok := f . Tag . Lookup ( "toml" )
if ! ok {
return fieldName
}
return v
}
2022-09-30 03:05:56 +00:00
// getSwarmResourceEnvvars returns the swarm resource envvars for the config.
func ( c * HookConfig ) getSwarmResourceEnvvars ( ) [ ] string {
2023-08-10 08:49:46 +00:00
if c . SwarmResource == "" {
2022-09-30 03:05:56 +00:00
return nil
}
2023-08-10 08:49:46 +00:00
candidates := strings . Split ( c . SwarmResource , "," )
2022-09-30 03:05:56 +00:00
var envvars [ ] string
for _ , c := range candidates {
trimmed := strings . TrimSpace ( c )
if len ( trimmed ) > 0 {
envvars = append ( envvars , trimmed )
}
}
return envvars
}