mirror of
https://github.com/NVIDIA/nvidia-container-toolkit
synced 2024-11-24 21:14:00 +00:00
Extend fields we inspect in the runc spec to include linux capabilities
This also includes a helper to look through the capabilities contained in the spec to determine if the container is privileged or not. Signed-off-by: Kevin Klues <kklues@nvidia.com>
This commit is contained in:
parent
d4ff0416d8
commit
05012e7b7f
@ -26,6 +26,10 @@ const (
|
|||||||
defaultDriverCapabilities = "utility"
|
defaultDriverCapabilities = "utility"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
capSysAdmin = "CAP_SYS_ADMIN"
|
||||||
|
)
|
||||||
|
|
||||||
type nvidiaConfig struct {
|
type nvidiaConfig struct {
|
||||||
Devices string
|
Devices string
|
||||||
DriverCapabilities string
|
DriverCapabilities string
|
||||||
@ -47,7 +51,17 @@ type Root struct {
|
|||||||
|
|
||||||
// github.com/opencontainers/runtime-spec/blob/v1.0.0/specs-go/config.go#L30-L57
|
// github.com/opencontainers/runtime-spec/blob/v1.0.0/specs-go/config.go#L30-L57
|
||||||
type Process struct {
|
type Process struct {
|
||||||
Env []string `json:"env,omitempty"`
|
Env []string `json:"env,omitempty"`
|
||||||
|
Capabilities *LinuxCapabilities `json:"capabilities,omitempty" platform:"linux"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/opencontainers/runtime-spec/blob/v1.0.0/specs-go/config.go#L61
|
||||||
|
type LinuxCapabilities struct {
|
||||||
|
Bounding []string `json:"bounding,omitempty" platform:"linux"`
|
||||||
|
Effective []string `json:"effective,omitempty" platform:"linux"`
|
||||||
|
Inheritable []string `json:"inheritable,omitempty" platform:"linux"`
|
||||||
|
Permitted []string `json:"permitted,omitempty" platform:"linux"`
|
||||||
|
Ambient []string `json:"ambient,omitempty" platform:"linux"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// We use pointers to structs, similarly to the latest version of runtime-spec:
|
// We use pointers to structs, similarly to the latest version of runtime-spec:
|
||||||
@ -124,6 +138,31 @@ func loadSpec(path string) (spec *Spec) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isPrivileged(caps *LinuxCapabilities) bool {
|
||||||
|
if caps == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
hasCapSysAdmin := func(caps []string) bool {
|
||||||
|
for _, c := range caps {
|
||||||
|
if c == capSysAdmin {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// We only make sure that the bounding capabibility set has
|
||||||
|
// CAP_SYS_ADMIN. This allows us to make sure that the container was
|
||||||
|
// actually started as '--privileged', but also allow non-root users to
|
||||||
|
// access the priviliged NVIDIA capabilities.
|
||||||
|
if !hasCapSysAdmin(caps.Bounding) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func getDevices(env map[string]string) *string {
|
func getDevices(env map[string]string) *string {
|
||||||
gpuVars := []string{envNVVisibleDevices}
|
gpuVars := []string{envNVVisibleDevices}
|
||||||
if envSwarmGPU != nil {
|
if envSwarmGPU != nil {
|
||||||
@ -158,7 +197,7 @@ func getRequirements(env map[string]string) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mimic the new CUDA images if no capabilities or devices are specified.
|
// Mimic the new CUDA images if no capabilities or devices are specified.
|
||||||
func getNvidiaConfigLegacy(env map[string]string) *nvidiaConfig {
|
func getNvidiaConfigLegacy(env map[string]string, privileged bool) *nvidiaConfig {
|
||||||
var devices string
|
var devices string
|
||||||
if d := getDevices(env); d == nil {
|
if d := getDevices(env); d == nil {
|
||||||
// Environment variable unset: default to "all".
|
// Environment variable unset: default to "all".
|
||||||
@ -200,18 +239,20 @@ func getNvidiaConfigLegacy(env map[string]string) *nvidiaConfig {
|
|||||||
|
|
||||||
return &nvidiaConfig{
|
return &nvidiaConfig{
|
||||||
Devices: devices,
|
Devices: devices,
|
||||||
|
MigConfigDevices: migConfigDevices,
|
||||||
|
MigMonitorDevices: migMonitorDevices,
|
||||||
DriverCapabilities: driverCapabilities,
|
DriverCapabilities: driverCapabilities,
|
||||||
Requirements: requirements,
|
Requirements: requirements,
|
||||||
DisableRequire: disableRequire,
|
DisableRequire: disableRequire,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNvidiaConfig(env map[string]string) *nvidiaConfig {
|
func getNvidiaConfig(env map[string]string, privileged bool) *nvidiaConfig {
|
||||||
legacyCudaVersion := env[envCUDAVersion]
|
legacyCudaVersion := env[envCUDAVersion]
|
||||||
cudaRequire := env[envNVRequireCUDA]
|
cudaRequire := env[envNVRequireCUDA]
|
||||||
if len(legacyCudaVersion) > 0 && len(cudaRequire) == 0 {
|
if len(legacyCudaVersion) > 0 && len(cudaRequire) == 0 {
|
||||||
// Legacy CUDA image detected.
|
// Legacy CUDA image detected.
|
||||||
return getNvidiaConfigLegacy(env)
|
return getNvidiaConfigLegacy(env, privileged)
|
||||||
}
|
}
|
||||||
|
|
||||||
var devices string
|
var devices string
|
||||||
@ -266,11 +307,12 @@ func getContainerConfig(hook HookConfig) (config containerConfig) {
|
|||||||
s := loadSpec(path.Join(b, "config.json"))
|
s := loadSpec(path.Join(b, "config.json"))
|
||||||
|
|
||||||
env := getEnvMap(s.Process.Env, hook.NvidiaContainerCLI)
|
env := getEnvMap(s.Process.Env, hook.NvidiaContainerCLI)
|
||||||
|
privileged := isPrivileged(s.Process.Capabilities)
|
||||||
envSwarmGPU = hook.SwarmResource
|
envSwarmGPU = hook.SwarmResource
|
||||||
return containerConfig{
|
return containerConfig{
|
||||||
Pid: h.Pid,
|
Pid: h.Pid,
|
||||||
Rootfs: s.Root.Path,
|
Rootfs: s.Root.Path,
|
||||||
Env: env,
|
Env: env,
|
||||||
Nvidia: getNvidiaConfig(env),
|
Nvidia: getNvidiaConfig(env, privileged),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user