mirror of
				https://github.com/NVIDIA/nvidia-container-toolkit
				synced 2025-06-26 18:18:24 +00:00 
			
		
		
		
	Refactor accepting device lists from volume mounts as a boolean
Also hard code the "root" path where these volume mounts will be looked for rather than making it configurable. Signed-off-by: Kevin Klues <kklues@nvidia.com>
This commit is contained in:
		
							parent
							
								
									928905ce94
								
							
						
					
					
						commit
						7c00385797
					
				| @ -1,7 +1,7 @@ | ||||
| disable-require = false | ||||
| #swarm-resource = "DOCKER_RESOURCE_GPU" | ||||
| #accept-nvidia-visible-devices-envvar-when-unprivileged = true | ||||
| #look-for-nvidia-visible-devices-as-volume-mounts-under = "/var/run/nvidia-container-devices" | ||||
| #accept-nvidia-visible-devices-as-volume-mounts = false | ||||
| 
 | ||||
| [nvidia-container-cli] | ||||
| #root = "/run/nvidia/driver" | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| disable-require = false | ||||
| #swarm-resource = "DOCKER_RESOURCE_GPU" | ||||
| #accept-nvidia-visible-devices-envvar-when-unprivileged = true | ||||
| #look-for-nvidia-visible-devices-as-volume-mounts-under = "/var/run/nvidia-container-devices" | ||||
| #accept-nvidia-visible-devices-as-volume-mounts = false | ||||
| 
 | ||||
| [nvidia-container-cli] | ||||
| #root = "/run/nvidia/driver" | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| disable-require = false | ||||
| #swarm-resource = "DOCKER_RESOURCE_GPU" | ||||
| #accept-nvidia-visible-devices-envvar-when-unprivileged = true | ||||
| #look-for-nvidia-visible-devices-as-volume-mounts-under = "/var/run/nvidia-container-devices" | ||||
| #accept-nvidia-visible-devices-as-volume-mounts = false | ||||
| 
 | ||||
| [nvidia-container-cli] | ||||
| #root = "/run/nvidia/driver" | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| disable-require = false | ||||
| #swarm-resource = "DOCKER_RESOURCE_GPU" | ||||
| #accept-nvidia-visible-devices-envvar-when-unprivileged = true | ||||
| #look-for-nvidia-visible-devices-as-volume-mounts-under = "/var/run/nvidia-container-devices" | ||||
| #accept-nvidia-visible-devices-as-volume-mounts = false | ||||
| 
 | ||||
| [nvidia-container-cli] | ||||
| #root = "/run/nvidia/driver" | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| disable-require = false | ||||
| #swarm-resource = "DOCKER_RESOURCE_GPU" | ||||
| #accept-nvidia-visible-devices-envvar-when-unprivileged = true | ||||
| #look-for-nvidia-visible-devices-as-volume-mounts-under = "/var/run/nvidia-container-devices" | ||||
| #accept-nvidia-visible-devices-as-volume-mounts = false | ||||
| 
 | ||||
| [nvidia-container-cli] | ||||
| #root = "/run/nvidia/driver" | ||||
|  | ||||
| @ -35,6 +35,10 @@ const ( | ||||
| 	capSysAdmin = "CAP_SYS_ADMIN" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	deviceListAsVolumeMountsRoot = "/var/run/nvidia-container-devices" | ||||
| ) | ||||
| 
 | ||||
| type nvidiaConfig struct { | ||||
| 	Devices            string | ||||
| 	MigConfigDevices   string | ||||
| @ -236,10 +240,10 @@ func getDevicesFromEnvvar(env map[string]string, legacyImage bool) *string { | ||||
| 	return devices | ||||
| } | ||||
| 
 | ||||
| func getDevicesFromMounts(root string, mounts []Mount) *string { | ||||
| func getDevicesFromMounts(mounts []Mount) *string { | ||||
| 	var devices []string | ||||
| 	for _, m := range mounts { | ||||
| 		root := filepath.Clean(root) | ||||
| 		root := filepath.Clean(deviceListAsVolumeMountsRoot) | ||||
| 		source := filepath.Clean(m.Source) | ||||
| 		destination := filepath.Clean(m.Destination) | ||||
| 
 | ||||
| @ -274,14 +278,16 @@ func getDevicesFromMounts(root string, mounts []Mount) *string { | ||||
| } | ||||
| 
 | ||||
| func getDevices(hookConfig *HookConfig, env map[string]string, mounts []Mount, privileged bool, legacyImage bool) *string { | ||||
| 	// Try and get the device list from mount volumes first
 | ||||
| 	devices := getDevicesFromMounts(*hookConfig.DeviceListVolumeMount, mounts) | ||||
| 	// If enabled, try and get the device list from volume mounts first
 | ||||
| 	if hookConfig.AcceptDeviceListAsVolumeMounts { | ||||
| 		devices := getDevicesFromMounts(mounts) | ||||
| 		if devices != nil { | ||||
| 			return devices | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Fallback to reading from the environment variable if privileges are correct
 | ||||
| 	devices = getDevicesFromEnvvar(env, legacyImage) | ||||
| 	devices := getDevicesFromEnvvar(env, legacyImage) | ||||
| 	if devices == nil { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| @ -454,30 +454,26 @@ func TestGetNvidiaConfig(t *testing.T) { | ||||
| func TestGetDevicesFromMounts(t *testing.T) { | ||||
| 	var tests = []struct { | ||||
| 		description     string | ||||
| 		root            string | ||||
| 		mounts          []Mount | ||||
| 		expectedDevices *string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			description:     "No mounts", | ||||
| 			root:            defaultDeviceListVolumeMount, | ||||
| 			mounts:          nil, | ||||
| 			expectedDevices: nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			description: "Host path is not /dev/null", | ||||
| 			root:        defaultDeviceListVolumeMount, | ||||
| 			mounts: []Mount{ | ||||
| 				{ | ||||
| 					Source:      "/not/dev/null", | ||||
| 					Destination: filepath.Join(defaultDeviceListVolumeMount, "GPU0"), | ||||
| 					Destination: filepath.Join(deviceListAsVolumeMountsRoot, "GPU0"), | ||||
| 				}, | ||||
| 			}, | ||||
| 			expectedDevices: nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			description: "Container path is not prefixed by 'root'", | ||||
| 			root:        defaultDeviceListVolumeMount, | ||||
| 			mounts: []Mount{ | ||||
| 				{ | ||||
| 					Source:      "/dev/null", | ||||
| @ -488,41 +484,38 @@ func TestGetDevicesFromMounts(t *testing.T) { | ||||
| 		}, | ||||
| 		{ | ||||
| 			description: "Container path is only 'root'", | ||||
| 			root:        defaultDeviceListVolumeMount, | ||||
| 			mounts: []Mount{ | ||||
| 				{ | ||||
| 					Source:      "/dev/null", | ||||
| 					Destination: defaultDeviceListVolumeMount, | ||||
| 					Destination: deviceListAsVolumeMountsRoot, | ||||
| 				}, | ||||
| 			}, | ||||
| 			expectedDevices: nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			description: "Discover 2 devices", | ||||
| 			root:        defaultDeviceListVolumeMount, | ||||
| 			mounts: []Mount{ | ||||
| 				{ | ||||
| 					Source:      "/dev/null", | ||||
| 					Destination: filepath.Join(defaultDeviceListVolumeMount, "GPU0"), | ||||
| 					Destination: filepath.Join(deviceListAsVolumeMountsRoot, "GPU0"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					Source:      "/dev/null", | ||||
| 					Destination: filepath.Join(defaultDeviceListVolumeMount, "GPU1"), | ||||
| 					Destination: filepath.Join(deviceListAsVolumeMountsRoot, "GPU1"), | ||||
| 				}, | ||||
| 			}, | ||||
| 			expectedDevices: &[]string{"GPU0,GPU1"}[0], | ||||
| 		}, | ||||
| 		{ | ||||
| 			description: "Discover 2 devices with slashes in the name", | ||||
| 			root:        defaultDeviceListVolumeMount, | ||||
| 			mounts: []Mount{ | ||||
| 				{ | ||||
| 					Source:      "/dev/null", | ||||
| 					Destination: filepath.Join(defaultDeviceListVolumeMount, "GPU0-MIG0/0/1"), | ||||
| 					Destination: filepath.Join(deviceListAsVolumeMountsRoot, "GPU0-MIG0/0/1"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					Source:      "/dev/null", | ||||
| 					Destination: filepath.Join(defaultDeviceListVolumeMount, "GPU1-MIG0/0/1"), | ||||
| 					Destination: filepath.Join(deviceListAsVolumeMountsRoot, "GPU1-MIG0/0/1"), | ||||
| 				}, | ||||
| 			}, | ||||
| 			expectedDevices: &[]string{"GPU0-MIG0/0/1,GPU1-MIG0/0/1"}[0], | ||||
| @ -530,7 +523,7 @@ func TestGetDevicesFromMounts(t *testing.T) { | ||||
| 	} | ||||
| 	for _, tc := range tests { | ||||
| 		t.Run(tc.description, func(t *testing.T) { | ||||
| 			devices := getDevicesFromMounts(tc.root, tc.mounts) | ||||
| 			devices := getDevicesFromMounts(tc.mounts) | ||||
| 			if !reflect.DeepEqual(devices, tc.expectedDevices) { | ||||
| 				t.Errorf("Unexpected devices (got: %v, wanted: %v)", *devices, *tc.expectedDevices) | ||||
| 			} | ||||
| @ -545,6 +538,7 @@ func TestDeviceListSourcePriority(t *testing.T) { | ||||
| 		envvarDevices      string | ||||
| 		privileged         bool | ||||
| 		acceptUnprivileged bool | ||||
| 		acceptMounts       bool | ||||
| 		expectedDevices    *string | ||||
| 		expectedPanic      bool | ||||
| 	}{ | ||||
| @ -553,16 +547,17 @@ func TestDeviceListSourcePriority(t *testing.T) { | ||||
| 			mountDevices: []Mount{ | ||||
| 				{ | ||||
| 					Source:      "/dev/null", | ||||
| 					Destination: filepath.Join(defaultDeviceListVolumeMount, "GPU0"), | ||||
| 					Destination: filepath.Join(deviceListAsVolumeMountsRoot, "GPU0"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					Source:      "/dev/null", | ||||
| 					Destination: filepath.Join(defaultDeviceListVolumeMount, "GPU1"), | ||||
| 					Destination: filepath.Join(deviceListAsVolumeMountsRoot, "GPU1"), | ||||
| 				}, | ||||
| 			}, | ||||
| 			envvarDevices:      "GPU2,GPU3", | ||||
| 			privileged:         false, | ||||
| 			acceptUnprivileged: false, | ||||
| 			acceptMounts:       true, | ||||
| 			expectedDevices:    &[]string{"GPU0,GPU1"}[0], | ||||
| 		}, | ||||
| 		{ | ||||
| @ -571,6 +566,7 @@ func TestDeviceListSourcePriority(t *testing.T) { | ||||
| 			envvarDevices:      "GPU0,GPU1", | ||||
| 			privileged:         false, | ||||
| 			acceptUnprivileged: false, | ||||
| 			acceptMounts:       true, | ||||
| 			expectedPanic:      true, | ||||
| 		}, | ||||
| 		{ | ||||
| @ -579,6 +575,7 @@ func TestDeviceListSourcePriority(t *testing.T) { | ||||
| 			envvarDevices:      "GPU0,GPU1", | ||||
| 			privileged:         true, | ||||
| 			acceptUnprivileged: false, | ||||
| 			acceptMounts:       true, | ||||
| 			expectedDevices:    &[]string{"GPU0,GPU1"}[0], | ||||
| 		}, | ||||
| 		{ | ||||
| @ -587,6 +584,7 @@ func TestDeviceListSourcePriority(t *testing.T) { | ||||
| 			envvarDevices:      "GPU0,GPU1", | ||||
| 			privileged:         false, | ||||
| 			acceptUnprivileged: true, | ||||
| 			acceptMounts:       true, | ||||
| 			expectedDevices:    &[]string{"GPU0,GPU1"}[0], | ||||
| 		}, | ||||
| 	} | ||||
| @ -600,6 +598,7 @@ func TestDeviceListSourcePriority(t *testing.T) { | ||||
| 				} | ||||
| 				hookConfig := getDefaultHookConfig() | ||||
| 				hookConfig.AcceptEnvvarUnprivileged = tc.acceptUnprivileged | ||||
| 				hookConfig.AcceptDeviceListAsVolumeMounts = tc.acceptMounts | ||||
| 				devices = getDevices(&hookConfig, env, tc.mountDevices, tc.privileged, false) | ||||
| 			} | ||||
| 
 | ||||
|  | ||||
| @ -13,10 +13,6 @@ const ( | ||||
| 	driverPath = "/run/nvidia/driver" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	defaultDeviceListVolumeMount = "/var/run/nvidia-container-devices" | ||||
| ) | ||||
| 
 | ||||
| var defaultPaths = [...]string{ | ||||
| 	path.Join(driverPath, configPath), | ||||
| 	configPath, | ||||
| @ -41,7 +37,7 @@ type HookConfig struct { | ||||
| 	DisableRequire                 bool    `toml:"disable-require"` | ||||
| 	SwarmResource                  *string `toml:"swarm-resource"` | ||||
| 	AcceptEnvvarUnprivileged       bool    `toml:"accept-nvidia-visible-devices-envvar-when-unprivileged"` | ||||
| 	DeviceListVolumeMount    *string `toml:"look-for-nvidia-visible-devices-as-volume-mounts-under"` | ||||
| 	AcceptDeviceListAsVolumeMounts bool    `toml:"accept-nvidia-visible-devices-as-volume-mounts"` | ||||
| 
 | ||||
| 	NvidiaContainerCLI CLIConfig `toml:"nvidia-container-cli"` | ||||
| } | ||||
| @ -51,7 +47,7 @@ func getDefaultHookConfig() (config HookConfig) { | ||||
| 		DisableRequire:                 false, | ||||
| 		SwarmResource:                  nil, | ||||
| 		AcceptEnvvarUnprivileged:       true, | ||||
| 		DeviceListVolumeMount:    &[]string{defaultDeviceListVolumeMount}[0], | ||||
| 		AcceptDeviceListAsVolumeMounts: false, | ||||
| 		NvidiaContainerCLI: CLIConfig{ | ||||
| 			Root:        nil, | ||||
| 			Path:        nil, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user