Skip to content

Commit b264d55

Browse files
committed
vmm: Deprecate static CPU templates
Deprecate the `cpu_template` field in the `/machine-config` API, which is used to set static CPU templates. Users can use custom CPU templates as an alternative. To differentiate between explicitly specifying `None` and not specifying anything, wrap the `cpu_template` of the `MachineConfig` with `Option`. With this, it can notify the deprecation of only users using the field. Signed-off-by: Takahiro Itazuri <[email protected]>
1 parent f68396b commit b264d55

File tree

6 files changed

+125
-13
lines changed

6 files changed

+125
-13
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@
4242
- Changed the dump feature of `cpu-template-helper` tool not to enumerate program
4343
counter (PC) on ARM because it is determined by the given kernel image and
4444
it is useless in the custom CPU template context.
45+
- Deprecated `cpu_template` field in `PUT` and `PATCH` request of `/machine-config`
46+
API, which is used to set static CPU templates. Users can use custom CPU templates
47+
as an alternative. For more details, please refer here (link to GitHub discussion
48+
to be added).
4549

4650
### Fixed
4751

docs/cpu_templates/cpu-templates.md

+6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ Firecracker supports two types of CPU templates:
3434
- Custom CPU templates - users can create their own CPU templates in json
3535
format and pass them to Firecracker
3636

37+
> **Note**
38+
Staitc CPU templates are deprecated starting with v1.5.0. It will be removed in
39+
accordance with our policy. Even after dropping the support, users can use
40+
custom CPU templates as an alternative. For more details, please refer here (
41+
link to the GitHub discussion to be added).
42+
3743
> **Note**
3844
CPU templates for ARM (both static and custom) require the following patch
3945
to be available in the host kernel: [Support writable CPU ID registers from userspace](https://lore.kernel.org/kvm/[email protected]/#t).

src/api_server/src/request/machine_configuration.rs

+100-9
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,25 @@ pub(crate) fn parse_put_machine_config(body: &Body) -> Result<ParsedRequest, Err
2020
err
2121
})?;
2222

23+
// Check for the presence of deprecated `cpu_template` field.
24+
let mut deprecation_message = None;
25+
if config.cpu_template.is_some() {
26+
// `cpu_template` field in request is deprecated.
27+
METRICS.deprecated_api.deprecated_http_api_calls.inc();
28+
deprecation_message = Some("PUT /machine-config: cpu_template field is deprecated.");
29+
}
30+
31+
// Convert `MachineConfig` to `MachineConfigUpdate`.
2332
let config_update = MachineConfigUpdate::from(config);
2433

25-
Ok(ParsedRequest::new_sync(VmmAction::UpdateVmConfiguration(
26-
config_update,
27-
)))
34+
// Construct the `ParsedRequest` object.
35+
let mut parsed_req = ParsedRequest::new_sync(VmmAction::UpdateVmConfiguration(config_update));
36+
// If `cpu_template` was present, set the deprecation message in `parsing_info`.
37+
if let Some(msg) = deprecation_message {
38+
parsed_req.parsing_info().append_deprecation_message(msg);
39+
}
40+
41+
Ok(parsed_req)
2842
}
2943

3044
pub(crate) fn parse_patch_machine_config(body: &Body) -> Result<ParsedRequest, Error> {
@@ -39,17 +53,30 @@ pub(crate) fn parse_patch_machine_config(body: &Body) -> Result<ParsedRequest, E
3953
return method_to_error(Method::Patch);
4054
}
4155

42-
Ok(ParsedRequest::new_sync(VmmAction::UpdateVmConfiguration(
43-
config_update,
44-
)))
56+
// Check for the presence of deprecated `cpu_template` field.
57+
let mut deprecation_message = None;
58+
if config_update.cpu_template.is_some() {
59+
// `cpu_template` field in request is deprecated.
60+
METRICS.deprecated_api.deprecated_http_api_calls.inc();
61+
deprecation_message = Some("PATCH /machine-config: cpu_template is deprecated.");
62+
}
63+
64+
// Construct the `ParsedRequest` object.
65+
let mut parsed_req = ParsedRequest::new_sync(VmmAction::UpdateVmConfiguration(config_update));
66+
// If `cpu_template` was present, set the deprecation message in `parsing_info`.
67+
if let Some(msg) = deprecation_message {
68+
parsed_req.parsing_info().append_deprecation_message(msg);
69+
}
70+
71+
Ok(parsed_req)
4572
}
4673

4774
#[cfg(test)]
4875
mod tests {
4976
use vmm::cpu_config::templates::StaticCpuTemplate;
5077

5178
use super::*;
52-
use crate::parsed_request::tests::vmm_action_from_request;
79+
use crate::parsed_request::tests::{depr_action_from_req, vmm_action_from_request};
5380

5481
#[test]
5582
fn test_parse_get_machine_config_request() {
@@ -79,6 +106,24 @@ mod tests {
79106
"vcpu_count": 8,
80107
"mem_size_mib": 1024
81108
}"#;
109+
let expected_config = MachineConfigUpdate {
110+
vcpu_count: Some(8),
111+
mem_size_mib: Some(1024),
112+
smt: Some(false),
113+
cpu_template: None,
114+
track_dirty_pages: Some(false),
115+
};
116+
117+
match vmm_action_from_request(parse_put_machine_config(&Body::new(body)).unwrap()) {
118+
VmmAction::UpdateVmConfiguration(config) => assert_eq!(config, expected_config),
119+
_ => panic!("Test failed."),
120+
}
121+
122+
let body = r#"{
123+
"vcpu_count": 8,
124+
"mem_size_mib": 1024,
125+
"cpu_template": "None"
126+
}"#;
82127
let expected_config = MachineConfigUpdate {
83128
vcpu_count: Some(8),
84129
mem_size_mib: Some(1024),
@@ -102,7 +147,7 @@ mod tests {
102147
vcpu_count: Some(8),
103148
mem_size_mib: Some(1024),
104149
smt: Some(false),
105-
cpu_template: Some(StaticCpuTemplate::None),
150+
cpu_template: None,
106151
track_dirty_pages: Some(true),
107152
};
108153

@@ -155,7 +200,7 @@ mod tests {
155200
vcpu_count: Some(8),
156201
mem_size_mib: Some(1024),
157202
smt: Some(true),
158-
cpu_template: Some(StaticCpuTemplate::None),
203+
cpu_template: None,
159204
track_dirty_pages: Some(true),
160205
};
161206

@@ -209,4 +254,50 @@ mod tests {
209254
let body = r#"{}"#;
210255
assert!(parse_patch_machine_config(&Body::new(body)).is_err());
211256
}
257+
258+
#[test]
259+
fn test_depr_cpu_template_in_put_req() {
260+
// Test that the deprecation message is shown when `cpu_template` is specified.
261+
let body = r#"{
262+
"vcpu_count": 8,
263+
"mem_size_mib": 1024,
264+
"cpu_template": "None"
265+
}"#;
266+
depr_action_from_req(
267+
parse_put_machine_config(&Body::new(body)).unwrap(),
268+
Some("PUT /machine-config: cpu_template field is deprecated.".to_string()),
269+
);
270+
271+
// Test that the deprecation message is not shown when `cpu_template` is not specified.
272+
let body = r#"{
273+
"vcpu_count": 8,
274+
"mem_size_mib": 1024
275+
}"#;
276+
let (_, mut parsing_info) = parse_put_machine_config(&Body::new(body))
277+
.unwrap()
278+
.into_parts();
279+
assert!(parsing_info.take_deprecation_message().is_none());
280+
}
281+
282+
#[test]
283+
fn test_depr_cpu_template_in_patch_req() {
284+
// Test that the deprecation message is shown when `cpu_template` is specified.
285+
let body = r#"{
286+
"vcpu_count": 8,
287+
"cpu_template": "None"
288+
}"#;
289+
depr_action_from_req(
290+
parse_patch_machine_config(&Body::new(body)).unwrap(),
291+
Some("PATCH /machine-config: cpu_template is deprecated.".to_string()),
292+
);
293+
294+
// Test that the deprecation message is not shown when `cpu_template` is not specified.
295+
let body = r#"{
296+
"vcpu_count": 8
297+
}"#;
298+
let (_, mut parsing_info) = parse_patch_machine_config(&Body::new(body))
299+
.unwrap()
300+
.into_parts();
301+
assert!(parsing_info.take_deprecation_message().is_none());
302+
}
212303
}

src/api_server/swagger/firecracker.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,8 @@ definitions:
826826
description:
827827
The CPU Template defines a set of flags to be disabled from the microvm so that
828828
the features exposed to the guest are the same as in the selected instance type.
829+
This parameter has been deprecated and it will be removed in accordance with our
830+
policy.
829831
enum:
830832
- C3
831833
- T2

src/vmm/src/cpu_config/templates.rs

+9
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ impl From<&Option<CpuTemplateType>> for StaticCpuTemplate {
7272
}
7373
}
7474

75+
impl From<&CpuTemplateType> for StaticCpuTemplate {
76+
fn from(value: &CpuTemplateType) -> Self {
77+
match value {
78+
CpuTemplateType::Static(template) => *template,
79+
CpuTemplateType::Custom(_) => StaticCpuTemplate::None,
80+
}
81+
}
82+
}
83+
7584
impl<'a> TryFrom<&'a [u8]> for CustomCpuTemplate {
7685
type Error = serde_json::Error;
7786

src/vmm/src/vmm_config/machine_config.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ pub struct MachineConfig {
4040
#[serde(default, deserialize_with = "deserialize_smt")]
4141
pub smt: bool,
4242
/// A CPU template that it is used to filter the CPU features exposed to the guest.
43-
#[serde(default, skip_serializing_if = "StaticCpuTemplate::is_none")]
44-
pub cpu_template: StaticCpuTemplate,
43+
#[serde(default, skip_serializing_if = "Option::is_none")]
44+
pub cpu_template: Option<StaticCpuTemplate>,
4545
/// Enables or disables dirty page tracking. Enabling allows incremental snapshots.
4646
#[serde(default)]
4747
pub track_dirty_pages: bool,
@@ -122,7 +122,7 @@ impl From<MachineConfig> for MachineConfigUpdate {
122122
vcpu_count: Some(cfg.vcpu_count),
123123
mem_size_mib: Some(cfg.mem_size_mib),
124124
smt: Some(cfg.smt),
125-
cpu_template: Some(cfg.cpu_template),
125+
cpu_template: cfg.cpu_template,
126126
track_dirty_pages: Some(cfg.track_dirty_pages),
127127
}
128128
}
@@ -212,7 +212,7 @@ impl From<&VmConfig> for MachineConfig {
212212
vcpu_count: value.vcpu_count,
213213
mem_size_mib: value.mem_size_mib,
214214
smt: value.smt,
215-
cpu_template: (&value.cpu_template).into(),
215+
cpu_template: value.cpu_template.as_ref().map(|template| template.into()),
216216
track_dirty_pages: value.track_dirty_pages,
217217
}
218218
}

0 commit comments

Comments
 (0)