Skip to content

Commit 276b8e8

Browse files
authored
Merge pull request #62 from KCSesh/api-time-slice
feat: add nvidia time-slicing
2 parents ae697ef + cbbaa92 commit 276b8e8

File tree

7 files changed

+82
-6
lines changed

7 files changed

+82
-6
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ bottlerocket-template-helper = { path = "./bottlerocket-template-helper", versio
5757

5858
# Settings Models
5959
bottlerocket-model-derive = { path = "./bottlerocket-settings-models/model-derive", version = "0.1" }
60-
bottlerocket-modeled-types = { path = "./bottlerocket-settings-models/modeled-types", version = "0.5" }
60+
bottlerocket-modeled-types = { path = "./bottlerocket-settings-models/modeled-types", version = "0.6" }
6161
bottlerocket-scalar = { path = "./bottlerocket-settings-models/scalar", version = "0.1" }
6262
bottlerocket-scalar-derive = { path = "./bottlerocket-settings-models/scalar-derive", version = "0.1" }
6363
bottlerocket-string-impls-for = { path = "./bottlerocket-settings-models/string-impls-for", version = "0.1" }
@@ -90,6 +90,7 @@ abi_stable = "0.11.3"
9090
anyhow = "1"
9191
argh = "0.1"
9292
base64 = "0.22"
93+
bounded-integer = "0.5"
9394
ctor = "0.2"
9495
darling = "0.20"
9596
env_logger = "0.11"

bottlerocket-settings-models/CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
- See [unreleased changes here]
1111

12-
[unreleased changes here]: https://github.com/bottlerocket-os/bottlerocket-settings-sdk/compare/bottlerocket-settings-models-v0.5.0...HEAD
12+
[unreleased changes here]: https://github.com/bottlerocket-os/bottlerocket-settings-sdk/compare/bottlerocket-settings-models-v0.6.0...HEAD
13+
14+
## [0.6.0] - 2024-10-02
15+
16+
## Model Changes
17+
18+
### Added
19+
20+
- Added nvidia time-slicing to kubernetes device plugins settings extension ([#62])
21+
22+
[#62]: https://github.com/bottlerocket-os/bottlerocket-settings-sdk/pull/62
23+
24+
[0.6.0]: https://github.com/bottlerocket-os/bottlerocket-settings-sdk/compare/bottlerocket-settings-models-v0.6.0...bottlerocket-settings-models-v0.5.0
1325

1426
## [0.5.0] - 2024-09-10
1527

bottlerocket-settings-models/modeled-types/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bottlerocket-modeled-types"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
authors = []
55
license = "Apache-2.0 OR MIT"
66
edition = "2021"
@@ -13,6 +13,7 @@ bottlerocket-scalar.workspace = true
1313
bottlerocket-scalar-derive.workspace = true
1414
bottlerocket-string-impls-for.workspace = true
1515
bottlerocket-model-derive.workspace = true
16+
bounded-integer = { workspace = true, features = ["types", "serde1"]}
1617
base64.workspace = true
1718
indexmap = { workspace = true, features = ["serde"] }
1819
lazy_static.workspace = true

bottlerocket-settings-models/modeled-types/src/kubernetes.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::error;
22
use bottlerocket_scalar_derive::Scalar;
33
use bottlerocket_string_impls_for::string_impls_for;
4+
use bounded_integer::BoundedI32;
45
use lazy_static::lazy_static;
56
use regex::Regex;
67
use serde::{Deserialize, Deserializer, Serialize, Serializer};
@@ -20,6 +21,10 @@ use crate::SingleLineString;
2021
const IMAGE_GC_THRESHOLD_MAX: i32 = 100;
2122
const IMAGE_GC_THRESHOLD_MIN: i32 = 0;
2223

24+
// Define the bounds for the `time-slicing.replicas` field
25+
const TIME_SLICING_REPLICAS_MIN: i32 = 2;
26+
const TIME_SLICING_REPLICAS_MAX: i32 = i32::MAX;
27+
2328
/// KubernetesName represents a string that contains a valid Kubernetes resource name. It stores
2429
/// the original string and makes it accessible through standard traits.
2530
// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
@@ -1452,6 +1457,8 @@ pub struct NvidiaDevicePluginSettings {
14521457
pass_device_specs: bool,
14531458
device_id_strategy: NvidiaDeviceIdStrategy,
14541459
device_list_strategy: NvidiaDeviceListStrategy,
1460+
device_sharing_strategy: NvidiaDeviceSharingStrategy,
1461+
time_slicing: NvidiaTimeSlicingSettings,
14551462
}
14561463

14571464
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
@@ -1468,6 +1475,20 @@ pub enum NvidiaDeviceListStrategy {
14681475
VolumeMounts,
14691476
}
14701477

1478+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1479+
#[serde(rename_all = "kebab-case")]
1480+
pub enum NvidiaDeviceSharingStrategy {
1481+
None,
1482+
TimeSlicing,
1483+
}
1484+
1485+
#[model(impl_default = true)]
1486+
pub struct NvidiaTimeSlicingSettings {
1487+
replicas: BoundedI32<TIME_SLICING_REPLICAS_MIN, TIME_SLICING_REPLICAS_MAX>,
1488+
rename_by_default: bool,
1489+
fail_requests_greater_than_one: bool,
1490+
}
1491+
14711492
#[cfg(test)]
14721493
mod tests {
14731494
use super::*;
@@ -1483,10 +1504,38 @@ mod tests {
14831504
pass_device_specs: Some(false),
14841505
device_id_strategy: Some(NvidiaDeviceIdStrategy::Uuid),
14851506
device_list_strategy: Some(NvidiaDeviceListStrategy::Envvar),
1507+
device_sharing_strategy: None,
1508+
time_slicing: None
1509+
}
1510+
);
1511+
let results = serde_json::to_string(&nvidia_device_plugins).unwrap();
1512+
assert_eq!(results, test_json);
1513+
}
1514+
1515+
#[test]
1516+
fn test_serde_nvidia_device_plugins_with_time_slicing() {
1517+
let test_json = r#"{"pass-device-specs":false,"device-id-strategy":"uuid","device-list-strategy":"envvar","device-sharing-strategy":"time-slicing"}"#;
1518+
let nvidia_device_plugins: NvidiaDevicePluginSettings =
1519+
serde_json::from_str(test_json).unwrap();
1520+
assert_eq!(
1521+
nvidia_device_plugins,
1522+
NvidiaDevicePluginSettings {
1523+
pass_device_specs: Some(false),
1524+
device_id_strategy: Some(NvidiaDeviceIdStrategy::Uuid),
1525+
device_list_strategy: Some(NvidiaDeviceListStrategy::Envvar),
1526+
device_sharing_strategy: Some(NvidiaDeviceSharingStrategy::TimeSlicing),
1527+
time_slicing: None
14861528
}
14871529
);
14881530

14891531
let results = serde_json::to_string(&nvidia_device_plugins).unwrap();
14901532
assert_eq!(results, test_json);
14911533
}
1534+
1535+
#[test]
1536+
fn test_invalid_time_slicing_replicas() {
1537+
let test_json = r#"{"pass-device-specs":false,"device-id-strategy":"uuid","device-list-strategy":"envvar","device-sharing-strategy":"time-slicing","time-slicing":{"replicas":0}}"#;
1538+
let result: Result<NvidiaDevicePluginSettings, _> = serde_json::from_str(test_json);
1539+
assert!(result.is_err(), "The JSON should not be parsed successfully as it contains an invalid value for 'replicas'.");
1540+
}
14921541
}

bottlerocket-settings-models/settings-extensions/kubelet-device-plugins/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ env_logger.workspace = true
1414
serde = { workspace = true, features = ["derive"] }
1515
serde_json.workspace = true
1616

17+
[dev-dependencies]
18+
bounded-integer = { workspace = true, features = ["types"]}
19+
1720
[lints]
1821
workspace = true

bottlerocket-settings-models/settings-extensions/kubelet-device-plugins/src/lib.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ impl SettingsModel for KubeletDevicePluginsV1 {
4242
#[cfg(test)]
4343
mod test {
4444
use super::*;
45-
use bottlerocket_modeled_types::{NvidiaDeviceIdStrategy, NvidiaDeviceListStrategy};
45+
use bottlerocket_modeled_types::{
46+
NvidiaDeviceIdStrategy, NvidiaDeviceListStrategy, NvidiaDeviceSharingStrategy,
47+
NvidiaTimeSlicingSettings,
48+
};
49+
use bounded_integer::BoundedI32;
4650

4751
#[test]
4852
fn test_generate_kubelet_device_plugins() {
@@ -55,7 +59,7 @@ mod test {
5559

5660
#[test]
5761
fn test_serde_kubelet_device_plugins() {
58-
let test_json = r#"{"nvidia":{"pass-device-specs":true,"device-id-strategy":"index","device-list-strategy":"volume-mounts"}}"#;
62+
let test_json = r#"{"nvidia":{"pass-device-specs":true,"device-id-strategy":"index","device-list-strategy":"volume-mounts","device-sharing-strategy":"time-slicing","time-slicing":{"replicas":2,"rename-by-default":true,"fail-requests-greater-than-one":true}}}"#;
5963

6064
let device_plugins: KubeletDevicePluginsV1 = serde_json::from_str(test_json).unwrap();
6165
assert_eq!(
@@ -65,6 +69,12 @@ mod test {
6569
pass_device_specs: Some(true),
6670
device_id_strategy: Some(NvidiaDeviceIdStrategy::Index),
6771
device_list_strategy: Some(NvidiaDeviceListStrategy::VolumeMounts),
72+
device_sharing_strategy: Some(NvidiaDeviceSharingStrategy::TimeSlicing),
73+
time_slicing: Some(NvidiaTimeSlicingSettings {
74+
replicas: Some(BoundedI32::new(2).unwrap()),
75+
rename_by_default: Some(true),
76+
fail_requests_greater_than_one: Some(true),
77+
}),
6878
}),
6979
}
7080
);

bottlerocket-settings-models/settings-models/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bottlerocket-settings-models"
3-
version = "0.5.0"
3+
version = "0.6.0"
44
authors = ["Tom Kirchner <tjk@amazon.com>"]
55
license = "Apache-2.0 OR MIT"
66
edition = "2021"

0 commit comments

Comments
 (0)