Skip to content

Commit

Permalink
feat: add nvidia shared GPU settings to k8s model
Browse files Browse the repository at this point in the history
Signed-off-by: Monirul Islam <[email protected]>
  • Loading branch information
monirul committed Aug 12, 2024
1 parent 291f07d commit b0c371f
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 3 deletions.
17 changes: 15 additions & 2 deletions bottlerocket-settings-models/modeled-types/src/kubernetes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::convert::TryFrom;
use std::fmt::{self, Display, Formatter};
use std::net::IpAddr;

use crate::PositiveInteger;
use crate::SingleLineString;

// Declare constant values usable by any type
Expand Down Expand Up @@ -1455,6 +1456,8 @@ pub struct NvidiaDevicePluginSettings {
pass_device_specs: bool,
device_id_strategy: NvidiaDeviceIdStrategy,
device_list_strategy: NvidiaDeviceListStrategy,
max_sharing_per_gpu: PositiveInteger,
rename_shared_gpu: bool,
}

#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
Expand All @@ -1477,7 +1480,7 @@ mod tests {

#[test]
fn test_serde_k8s_device_plugins() {
let test_json = r#"{"nvidia":{"pass-device-specs":true,"device-id-strategy":"index","device-list-strategy":"volume-mounts"}}"#;
let test_json = r#"{"nvidia":{"pass-device-specs":true,"device-id-strategy":"index","device-list-strategy":"volume-mounts","max-sharing-per-gpu":10,"rename-shared-gpu":true}}"#;

let device_plugins: K8sDevicePluginsSettings = serde_json::from_str(test_json).unwrap();
assert_eq!(
Expand All @@ -1487,6 +1490,8 @@ mod tests {
pass_device_specs: Some(true),
device_id_strategy: Some(NvidiaDeviceIdStrategy::Index),
device_list_strategy: Some(NvidiaDeviceListStrategy::VolumeMounts),
max_sharing_per_gpu: Some(PositiveInteger::try_from(10).unwrap()),
rename_shared_gpu: Some(true),
}),
}
);
Expand All @@ -1497,7 +1502,7 @@ mod tests {

#[test]
fn test_serde_nvidia_device_plugins() {
let test_json = r#"{"pass-device-specs":false,"device-id-strategy":"uuid","device-list-strategy":"envvar"}"#;
let test_json = r#"{"pass-device-specs":false,"device-id-strategy":"uuid","device-list-strategy":"envvar","max-sharing-per-gpu":10,"rename-shared-gpu":false}"#;
let nvidia_device_plugins: NvidiaDevicePluginSettings =
serde_json::from_str(test_json).unwrap();
assert_eq!(
Expand All @@ -1506,10 +1511,18 @@ mod tests {
pass_device_specs: Some(false),
device_id_strategy: Some(NvidiaDeviceIdStrategy::Uuid),
device_list_strategy: Some(NvidiaDeviceListStrategy::Envvar),
max_sharing_per_gpu: Some(PositiveInteger::try_from(10).unwrap()),
rename_shared_gpu: Some(false),
}
);

let results = serde_json::to_string(&nvidia_device_plugins).unwrap();
assert_eq!(results, test_json);
}
#[test]
fn test_invalid_max_sharing_per_gpu() {
let test_json = r#"{"pass-device-specs":false,"device-id-strategy":"uuid","device-list-strategy":"envvar","max-sharing-per-gpu":0,"rename-shared-gpu":false}"#;
let result: Result<NvidiaDevicePluginSettings, _> = serde_json::from_str(test_json);
assert!(result.is_err(), "The JSON should not be parsed successfully as it contains an invalid value for 'max-sharing-per-gpu'.");
}
}
41 changes: 41 additions & 0 deletions bottlerocket-settings-models/modeled-types/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,47 @@ mod test_positive_integer {

// =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^=

/// Input value that needs to be a positive integer, but should not be greater
/// than an i32::MAX.
#[derive(Clone, Debug, PartialEq, Scalar)]
pub struct PositiveInteger {
inner: i32,
}

impl Validate for PositiveInteger {
fn validate<I: Into<i32>>(input: I) -> Result<PositiveInteger, ValidationError> {
let inner: i32 = input.into();
if inner < 1 {
Err(ValidationError::new(
"number must be great than or equal to 1",
))
} else {
Ok(Self { inner })
}
}
}

#[cfg(test)]
mod test_nonzero_integer {
use super::PositiveInteger;
use std::convert::TryFrom;

#[test]
fn valid_positive_integer() {
assert!(PositiveInteger::try_from(1).is_ok());
assert!(PositiveInteger::try_from(i32::MAX).is_ok());
assert!(PositiveInteger::try_from(42).is_ok());
}

#[test]
fn invalid_positive_integer() {
assert!(PositiveInteger::try_from(i32::MIN).is_err());
assert!(PositiveInteger::try_from(-1).is_err());
assert!(PositiveInteger::try_from(0).is_err());
}
}
// =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^=

/// KernelCpuSetValue represents a string that contains a valid Kernel CpuSet Value from
/// here: https://man7.org/linux/man-pages/man7/cpuset.7.html#FORMATS. This matches the
/// logic from https://github.com/kubernetes/utils/blob/d93618cff8a22d3aea7bf78d9d528fd859720c2d/cpuset/cpuset.go#L203
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ use bottlerocket_modeled_types::{
TopologyManagerScope, Url, ValidBase64, ValidLinuxHostname,
};

// Feature flags
#[cfg(feature = "nvidia-device-plugin")]
pub const NVIDIA_DEVICE_PLUGIN_FEATURE_ENABLED: bool = true;
#[cfg(not(feature = "nvidia-device-plugin"))]
pub const NVIDIA_DEVICE_PLUGIN_FEATURE_ENABLED: bool = false;

// Kubernetes static pod manifest settings
#[model]
pub struct StaticPod {
Expand Down
2 changes: 1 addition & 1 deletion bottlerocket-settings-models/settings-models/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ settings structures that helpfully validate inputs on deserialize.
*/

mod boot;
mod kubernetes;
pub mod kubernetes;

// Expose types for creating new settings structs
pub use bottlerocket_model_derive as model_derive;
Expand Down

0 comments on commit b0c371f

Please sign in to comment.