Skip to content

Commit ba2d2b3

Browse files
authored
Merge pull request #83 from sky1122/k8s-device-stradegy-to-list
add: change K8s device list strategy from a single value to a list
2 parents faa12ae + e4d113a commit ba2d2b3

File tree

7 files changed

+191
-16
lines changed

7 files changed

+191
-16
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
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.8" }
60+
bottlerocket-modeled-types = { path = "./bottlerocket-settings-models/modeled-types", version = "0.9" }
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" }
@@ -75,7 +75,7 @@ settings-extension-ecs = { path = "./bottlerocket-settings-models/settings-exten
7575
settings-extension-host-containers = { path = "./bottlerocket-settings-models/settings-extensions/host-containers", version = "0.1" }
7676
settings-extension-kernel = { path = "./bottlerocket-settings-models/settings-extensions/kernel", version = "0.1" }
7777
settings-extension-kubernetes = { path = "./bottlerocket-settings-models/settings-extensions/kubernetes", version = "0.3" }
78-
settings-extension-kubelet-device-plugins = { path = "./bottlerocket-settings-models/settings-extensions/kubelet-device-plugins", version = "0.2" }
78+
settings-extension-kubelet-device-plugins = { path = "./bottlerocket-settings-models/settings-extensions/kubelet-device-plugins", version = "0.3" }
7979
settings-extension-metrics = { path = "./bottlerocket-settings-models/settings-extensions/metrics", version = "0.1" }
8080
settings-extension-motd = { path = "./bottlerocket-settings-models/settings-extensions/motd", version = "0.1" }
8181
settings-extension-network = { path = "./bottlerocket-settings-models/settings-extensions/network", version = "0.1" }

bottlerocket-settings-models/modeled-types/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-modeled-types"
3-
version = "0.8.0"
3+
version = "0.9.0"
44
authors = []
55
license = "Apache-2.0 OR MIT"
66
edition = "2021"

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

Lines changed: 142 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,10 +1481,40 @@ pub enum NvidiaDeviceIdStrategy {
14811481
}
14821482

14831483
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
1484-
#[serde(rename_all = "kebab-case")]
1484+
#[serde(untagged)]
14851485
pub enum NvidiaDeviceListStrategy {
1486+
Scalar(NvidiaDeviceListStrategyValues),
1487+
Vector(Vec<NvidiaDeviceListStrategyValues>),
1488+
}
1489+
1490+
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
1491+
#[serde(rename_all = "kebab-case")]
1492+
pub enum NvidiaDeviceListStrategyValues {
14861493
Envvar,
14871494
VolumeMounts,
1495+
CdiCri,
1496+
}
1497+
1498+
impl NvidiaDeviceListStrategy {
1499+
pub fn iter(&self) -> Box<dyn Iterator<Item = &NvidiaDeviceListStrategyValues> + '_> {
1500+
match self {
1501+
Self::Scalar(inner) => Box::new(std::iter::once(inner)),
1502+
Self::Vector(inner) => Box::new(inner.iter()),
1503+
}
1504+
}
1505+
}
1506+
1507+
impl IntoIterator for NvidiaDeviceListStrategy {
1508+
type Item = NvidiaDeviceListStrategyValues;
1509+
type IntoIter = std::vec::IntoIter<Self::Item>;
1510+
1511+
fn into_iter(self) -> Self::IntoIter {
1512+
match self {
1513+
Self::Scalar(inner) => vec![inner],
1514+
Self::Vector(inner) => inner,
1515+
}
1516+
.into_iter()
1517+
}
14881518
}
14891519

14901520
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@@ -1580,6 +1610,15 @@ string_impls_for!(MigProfile, "MigProfile");
15801610
mod test_nvidia_device_plugins {
15811611
use super::*;
15821612

1613+
fn helper_with_device_list_strategy(
1614+
device_list_strategy: Option<NvidiaDeviceListStrategy>,
1615+
) -> NvidiaDevicePluginSettings {
1616+
NvidiaDevicePluginSettings {
1617+
device_list_strategy: device_list_strategy,
1618+
..NvidiaDevicePluginSettings::default()
1619+
}
1620+
}
1621+
15831622
#[test]
15841623
fn valid_gpu_model() {
15851624
for ok in &["a100.40gb", "a100.80gb", "h100.80gb", "h100.141gb"] {
@@ -1628,7 +1667,9 @@ mod test_nvidia_device_plugins {
16281667
NvidiaDevicePluginSettings {
16291668
pass_device_specs: Some(false),
16301669
device_id_strategy: Some(NvidiaDeviceIdStrategy::Uuid),
1631-
device_list_strategy: Some(NvidiaDeviceListStrategy::Envvar),
1670+
device_list_strategy: Some(NvidiaDeviceListStrategy::Scalar(
1671+
NvidiaDeviceListStrategyValues::Envvar
1672+
),),
16321673
device_sharing_strategy: None,
16331674
time_slicing: None,
16341675
device_partitioning_strategy: None,
@@ -1649,7 +1690,9 @@ mod test_nvidia_device_plugins {
16491690
NvidiaDevicePluginSettings {
16501691
pass_device_specs: Some(false),
16511692
device_id_strategy: Some(NvidiaDeviceIdStrategy::Uuid),
1652-
device_list_strategy: Some(NvidiaDeviceListStrategy::Envvar),
1693+
device_list_strategy: Some(NvidiaDeviceListStrategy::Scalar(
1694+
NvidiaDeviceListStrategyValues::Envvar
1695+
),),
16531696
device_sharing_strategy: Some(NvidiaDeviceSharingStrategy::TimeSlicing),
16541697
time_slicing: None,
16551698
device_partitioning_strategy: None,
@@ -1678,7 +1721,9 @@ mod test_nvidia_device_plugins {
16781721
NvidiaDevicePluginSettings {
16791722
pass_device_specs: Some(false),
16801723
device_id_strategy: Some(NvidiaDeviceIdStrategy::Uuid),
1681-
device_list_strategy: Some(NvidiaDeviceListStrategy::Envvar),
1724+
device_list_strategy: Some(NvidiaDeviceListStrategy::Scalar(
1725+
NvidiaDeviceListStrategyValues::Envvar
1726+
),),
16821727
device_sharing_strategy: None,
16831728
time_slicing: None,
16841729
device_partitioning_strategy: Some(NvidiaDevicePartitioningStrategy::MIG),
@@ -1700,7 +1745,9 @@ mod test_nvidia_device_plugins {
17001745
NvidiaDevicePluginSettings {
17011746
pass_device_specs: Some(false),
17021747
device_id_strategy: Some(NvidiaDeviceIdStrategy::Uuid),
1703-
device_list_strategy: Some(NvidiaDeviceListStrategy::Envvar),
1748+
device_list_strategy: Some(NvidiaDeviceListStrategy::Scalar(
1749+
NvidiaDeviceListStrategyValues::Envvar
1750+
),),
17041751
device_sharing_strategy: None,
17051752
time_slicing: None,
17061753
device_partitioning_strategy: Some(NvidiaDevicePartitioningStrategy::MIG),
@@ -1716,4 +1763,94 @@ mod test_nvidia_device_plugins {
17161763
let results = serde_json::to_string(&nvidia_device_plugins).unwrap();
17171764
assert_eq!(results, test_json);
17181765
}
1766+
1767+
#[test]
1768+
fn test_serde_nvidia_device_plugins_with_list_shape_nvidia_list_stradegy() {
1769+
let test_json_1 = r#"{"device-list-strategy":["volume-mounts","envvar","cdi-cri"]}"#;
1770+
let test_json_2 = r#"{"device-list-strategy":["volume-mounts","cdi-cri","envvar"]}"#;
1771+
let test_json_3 = r#"{"device-list-strategy":["envvar","volume-mounts","cdi-cri"]}"#;
1772+
let test_json_4 = r#"{"device-list-strategy":["envvar","cdi-cri","volume-mounts"]}"#;
1773+
let test_json_5 = r#"{"device-list-strategy":["cdi-cri","volume-mounts","envvar"]}"#;
1774+
let test_json_6 = r#"{"device-list-strategy":["cdi-cri","envvar","volume-mounts"]}"#;
1775+
1776+
let device_plugins_1: NvidiaDevicePluginSettings =
1777+
serde_json::from_str(test_json_1).unwrap();
1778+
assert_eq!(
1779+
device_plugins_1,
1780+
helper_with_device_list_strategy(Some(NvidiaDeviceListStrategy::Vector(vec![
1781+
NvidiaDeviceListStrategyValues::VolumeMounts,
1782+
NvidiaDeviceListStrategyValues::Envvar,
1783+
NvidiaDeviceListStrategyValues::CdiCri,
1784+
])))
1785+
);
1786+
1787+
let device_plugins_2: NvidiaDevicePluginSettings =
1788+
serde_json::from_str(test_json_2).unwrap();
1789+
assert_eq!(
1790+
device_plugins_2,
1791+
helper_with_device_list_strategy(Some(NvidiaDeviceListStrategy::Vector(vec![
1792+
NvidiaDeviceListStrategyValues::VolumeMounts,
1793+
NvidiaDeviceListStrategyValues::CdiCri,
1794+
NvidiaDeviceListStrategyValues::Envvar,
1795+
]))),
1796+
);
1797+
1798+
let device_plugins_3: NvidiaDevicePluginSettings =
1799+
serde_json::from_str(test_json_3).unwrap();
1800+
assert_eq!(
1801+
device_plugins_3,
1802+
helper_with_device_list_strategy(Some(NvidiaDeviceListStrategy::Vector(vec![
1803+
NvidiaDeviceListStrategyValues::Envvar,
1804+
NvidiaDeviceListStrategyValues::VolumeMounts,
1805+
NvidiaDeviceListStrategyValues::CdiCri,
1806+
]))),
1807+
);
1808+
1809+
let device_plugins_4: NvidiaDevicePluginSettings =
1810+
serde_json::from_str(test_json_4).unwrap();
1811+
assert_eq!(
1812+
device_plugins_4,
1813+
helper_with_device_list_strategy(Some(NvidiaDeviceListStrategy::Vector(vec![
1814+
NvidiaDeviceListStrategyValues::Envvar,
1815+
NvidiaDeviceListStrategyValues::CdiCri,
1816+
NvidiaDeviceListStrategyValues::VolumeMounts,
1817+
]))),
1818+
);
1819+
1820+
let device_plugins_5: NvidiaDevicePluginSettings =
1821+
serde_json::from_str(test_json_5).unwrap();
1822+
assert_eq!(
1823+
device_plugins_5,
1824+
helper_with_device_list_strategy(Some(NvidiaDeviceListStrategy::Vector(vec![
1825+
NvidiaDeviceListStrategyValues::CdiCri,
1826+
NvidiaDeviceListStrategyValues::VolumeMounts,
1827+
NvidiaDeviceListStrategyValues::Envvar,
1828+
]))),
1829+
);
1830+
1831+
let device_plugins_6: NvidiaDevicePluginSettings =
1832+
serde_json::from_str(test_json_6).unwrap();
1833+
assert_eq!(
1834+
device_plugins_6,
1835+
helper_with_device_list_strategy(Some(NvidiaDeviceListStrategy::Vector(vec![
1836+
NvidiaDeviceListStrategyValues::CdiCri,
1837+
NvidiaDeviceListStrategyValues::Envvar,
1838+
NvidiaDeviceListStrategyValues::VolumeMounts,
1839+
]))),
1840+
);
1841+
1842+
let results_1 = serde_json::to_string(&device_plugins_1).unwrap();
1843+
let results_2 = serde_json::to_string(&device_plugins_2).unwrap();
1844+
let results_3 = serde_json::to_string(&device_plugins_3).unwrap();
1845+
let results_4 = serde_json::to_string(&device_plugins_4).unwrap();
1846+
let results_5 = serde_json::to_string(&device_plugins_5).unwrap();
1847+
let results_6 = serde_json::to_string(&device_plugins_6).unwrap();
1848+
1849+
assert_eq!(results_1, test_json_1);
1850+
assert_eq!(results_2, test_json_2);
1851+
assert_eq!(results_3, test_json_3);
1852+
assert_eq!(results_4, test_json_4);
1853+
assert_eq!(results_5, test_json_5);
1854+
assert_eq!(results_6, test_json_6);
1855+
}
17191856
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "settings-extension-kubelet-device-plugins"
3-
version = "0.2.0"
3+
version = "0.3.0"
44
authors = ["Arnaldo Garcia Rincon <[email protected]>"]
55
license = "Apache-2.0 OR MIT"
66
edition = "2021"

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

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ mod test {
4444
use super::*;
4545
use bottlerocket_modeled_types::{
4646
MigProfile, NvidiaDeviceIdStrategy, NvidiaDeviceListStrategy,
47-
NvidiaDevicePartitioningStrategy, NvidiaDeviceSharingStrategy, NvidiaGpuModel,
48-
NvidiaMigSettings, NvidiaTimeSlicingSettings,
47+
NvidiaDeviceListStrategyValues, NvidiaDevicePartitioningStrategy,
48+
NvidiaDeviceSharingStrategy, NvidiaGpuModel, NvidiaMigSettings, NvidiaTimeSlicingSettings,
4949
};
5050
use bounded_integer::BoundedI32;
5151
use std::collections::HashMap;
@@ -60,7 +60,43 @@ mod test {
6060
}
6161

6262
#[test]
63-
fn test_serde_kubelet_device_plugins() {
63+
fn test_serde_kubelet_device_plugins_vec() {
64+
let test_json = r#"{"nvidia":{"pass-device-specs":true,"device-id-strategy":"index","device-list-strategy":["volume-mounts","envvar"],"device-sharing-strategy":"time-slicing","time-slicing":{"replicas":2,"rename-by-default":true,"fail-requests-greater-than-one":true},"device-partitioning-strategy":"mig","mig":{"profile":{"a100.40gb":"1g.5gb"}}}}"#;
65+
66+
let device_plugins: KubeletDevicePluginsV1 = serde_json::from_str(test_json).unwrap();
67+
assert_eq!(
68+
device_plugins,
69+
KubeletDevicePluginsV1 {
70+
nvidia: Some(NvidiaDevicePluginSettings {
71+
pass_device_specs: Some(true),
72+
device_id_strategy: Some(NvidiaDeviceIdStrategy::Index),
73+
device_list_strategy: Some(NvidiaDeviceListStrategy::Vector(vec![
74+
NvidiaDeviceListStrategyValues::VolumeMounts,
75+
NvidiaDeviceListStrategyValues::Envvar,
76+
])),
77+
device_sharing_strategy: Some(NvidiaDeviceSharingStrategy::TimeSlicing),
78+
time_slicing: Some(NvidiaTimeSlicingSettings {
79+
replicas: Some(BoundedI32::new(2).unwrap()),
80+
rename_by_default: Some(true),
81+
fail_requests_greater_than_one: Some(true),
82+
}),
83+
device_partitioning_strategy: Some(NvidiaDevicePartitioningStrategy::MIG),
84+
mig: Some(NvidiaMigSettings {
85+
profile: Some(HashMap::from([(
86+
NvidiaGpuModel::try_from("a100.40gb").unwrap(),
87+
MigProfile::try_from("1g.5gb").unwrap()
88+
)]))
89+
}),
90+
})
91+
}
92+
);
93+
94+
let results = serde_json::to_string(&device_plugins).unwrap();
95+
assert_eq!(results, test_json);
96+
}
97+
98+
#[test]
99+
fn test_serde_kubelet_device_plugins_scalar() {
64100
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},"device-partitioning-strategy":"mig","mig":{"profile":{"a100.40gb":"1g.5gb"}}}}"#;
65101

66102
let device_plugins: KubeletDevicePluginsV1 = serde_json::from_str(test_json).unwrap();
@@ -70,7 +106,9 @@ mod test {
70106
nvidia: Some(NvidiaDevicePluginSettings {
71107
pass_device_specs: Some(true),
72108
device_id_strategy: Some(NvidiaDeviceIdStrategy::Index),
73-
device_list_strategy: Some(NvidiaDeviceListStrategy::VolumeMounts),
109+
device_list_strategy: Some(NvidiaDeviceListStrategy::Scalar(
110+
NvidiaDeviceListStrategyValues::VolumeMounts
111+
)),
74112
device_sharing_strategy: Some(NvidiaDeviceSharingStrategy::TimeSlicing),
75113
time_slicing: Some(NvidiaTimeSlicingSettings {
76114
replicas: Some(BoundedI32::new(2).unwrap()),
@@ -84,7 +122,7 @@ mod test {
84122
MigProfile::try_from("1g.5gb").unwrap()
85123
)]))
86124
}),
87-
}),
125+
})
88126
}
89127
);
90128

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.9.0"
3+
version = "0.10.0"
44
authors = ["Tom Kirchner <[email protected]>"]
55
license = "Apache-2.0 OR MIT"
66
edition = "2021"

bottlerocket-settings-plugin/src/settings.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ functions.
1010
#![expect(non_local_definitions)]
1111
// Avoid `elide the lifetimes` warnings by clippy. The suggested changes do not make the code more
1212
// readable
13-
#![expect(clippy::needless_lifetimes)]
13+
#![allow(clippy::needless_lifetimes)]
1414
use serde::{Deserialize, Deserializer, Serialize, Serializer};
1515
use serde_json::Value as JsonValue;
1616
use std::path::PathBuf;

0 commit comments

Comments
 (0)