Skip to content

Commit 44cbd03

Browse files
committed
feat(mmds): Add flag for making MMDS operate like EC2 IMDS
While EC2 IMDS only supports text/plain and ignores Accept header, Firecracker MMDS supports not only text/plain but also application/json. If users don't have the control of libraries that set "Accept: application/json" but expect MMDS to behave like EC2 IMDS, the above difference becomes a problem. Not to break existing workloads, add a new flag `imds_compat` (default to false) to PUT /mmds/config API. Signed-off-by: Takahiro Itazuri <[email protected]>
1 parent b3b8c05 commit 44cbd03

File tree

14 files changed

+312
-289
lines changed

14 files changed

+312
-289
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ and this project adheres to
3030
version 2. These metrics also count requests that would be rejected in MMDS
3131
version 2 when MMDS version 1 is configured. They helps users assess readiness
3232
for migrating to MMDS version 2.
33+
- [#5310](https://github.com/firecracker-microvm/firecracker/pull/5310): Added
34+
an optional `imds_compat` field (default to false if not provided) to PUT
35+
requests to `/mmds/config` to enforce MMDS to always respond plain text
36+
contents in the IMDS format regardless of the `Accept` header in requests.
37+
Users need to regenerate snapshots.
3338

3439
### Changed
3540

docs/device-api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ specification:
7676
| `MmdsConfig` | network_interfaces | O | O | O | O | **R** | O | O |
7777
| | version | O | O | O | O | **R** | O | O |
7878
| | ipv4_address | O | O | O | O | **R** | O | O |
79+
| | imds_compat | O | O | O | O | O | O | O |
7980
| `NetworkInterface` | guest_mac | O | O | O | O | **R** | O | O |
8081
| | host_dev_name | O | O | O | O | **R** | O | O |
8182
| | iface_id | O | O | O | O | **R** | O | O |

docs/mmds/mmds-user-guide.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,10 @@ The response format can be JSON or IMDS. The IMDS documentation can be found
308308
The output format can be selected by specifying the optional `Accept` header.
309309
Using `Accept: application/json` will format the output to JSON, while using
310310
`Accept: plain/text` or not specifying this optional header at all will format
311-
the output to IMDS.
311+
the output to IMDS. Setting `imds_compat` to `true` through PUT request to
312+
`/mmds/config` enforces MMDS to always respond in IMDS format regardless of the
313+
`Accept` header. This allows code written to work on EC2 IMDS to also work on
314+
Firecracker MMDS.
312315

313316
Retrieving MMDS resources in IMDS format, other than JSON `string` and `object`
314317
types, is not supported.

src/firecracker/swagger/firecracker.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,7 @@ definitions:
888888
is_read_only:
889889
type: boolean
890890
description:
891-
Is block read only.
891+
Is block read only.
892892
This field is required for virtio-block config and should be omitted for vhost-user-block configuration.
893893
path_on_host:
894894
type: string
@@ -1125,6 +1125,12 @@ definitions:
11251125
format: "169.254.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4]).([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"
11261126
default: "169.254.169.254"
11271127
description: A valid IPv4 link-local address.
1128+
imds_comat:
1129+
type: boolean
1130+
description:
1131+
MMDS operates compatibly with EC2 IMDS (i.e. reponds "text/plain"
1132+
content regardless of Accept header in requests).
1133+
default: false
11281134

11291135
MmdsContentsObject:
11301136
type: object

src/vmm/src/device_manager/persist.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ pub struct ConnectedLegacyState {
154154
#[derive(Debug, Clone, Serialize, Deserialize)]
155155
pub struct MmdsState {
156156
version: MmdsVersion,
157+
imds_compat: bool,
157158
}
158159

159160
/// Holds the device states.
@@ -326,8 +327,10 @@ impl<'a> Persist<'a> for MMIODeviceManager {
326327
TYPE_NET => {
327328
let net = locked_device.as_any().downcast_ref::<Net>().unwrap();
328329
if let (Some(mmds_ns), None) = (net.mmds_ns.as_ref(), states.mmds.as_ref()) {
330+
let mmds_guard = mmds_ns.mmds.lock().expect("Poisoned lock");
329331
states.mmds = Some(MmdsState {
330-
version: mmds_ns.mmds.lock().expect("Poisoned lock").version(),
332+
version: mmds_guard.version(),
333+
imds_compat: mmds_guard.imds_compat(),
331334
});
332335
}
333336

@@ -537,9 +540,11 @@ impl<'a> Persist<'a> for MMIODeviceManager {
537540

538541
// Initialize MMDS if MMDS state is included.
539542
if let Some(mmds) = &state.mmds {
540-
constructor_args
541-
.vm_resources
542-
.set_mmds_basic_config(mmds.version, constructor_args.instance_id)?;
543+
constructor_args.vm_resources.set_mmds_basic_config(
544+
mmds.version,
545+
mmds.imds_compat,
546+
constructor_args.instance_id,
547+
)?;
543548
}
544549

545550
for net_state in &state.net_devices {
@@ -826,7 +831,8 @@ mod tests {
826831
"network_interfaces": [
827832
"netif"
828833
],
829-
"ipv4_address": "169.254.169.254"
834+
"ipv4_address": "169.254.169.254",
835+
"imds_compat": false
830836
}},
831837
"network-interfaces": [
832838
{{
@@ -859,7 +865,7 @@ mod tests {
859865
.version(),
860866
MmdsVersion::V2
861867
);
862-
assert_eq!(device_states.mmds.unwrap().version, MmdsVersion::V2.into());
868+
assert_eq!(device_states.mmds.unwrap().version, MmdsVersion::V2);
863869

864870
assert_eq!(restored_dev_manager, original_mmio_device_manager);
865871
assert_eq!(

0 commit comments

Comments
 (0)