From f8504baad9b985a53537472716acf1f53c161383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Wed, 2 Oct 2024 16:12:17 +0200 Subject: [PATCH] bios: Handle empty pttype from lsblk output zram, sr0 (CD/DVD) and LUKS devices generally don't use partitions, thus don't have a partition table and thus don't have a partition table type so this field may be null. Fixes: https://github.com/coreos/bootupd/issues/739 Signed-off-by: Colin Walters --- src/bios.rs | 23 ++++++++++++++--- tests/fixtures/example-lsblk-output.json | 33 ++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/example-lsblk-output.json diff --git a/src/bios.rs b/src/bios.rs index 11609d28..96d00741 100644 --- a/src/bios.rs +++ b/src/bios.rs @@ -16,7 +16,7 @@ pub(crate) const GRUB_BIN: &str = "usr/sbin/grub2-install"; #[derive(Serialize, Deserialize, Debug)] struct BlockDevice { path: String, - pttype: String, + pttype: Option, parttypename: Option, } @@ -113,12 +113,14 @@ impl Bios { let output = String::from_utf8(output.stdout)?; // Parse the JSON string into the `Devices` struct - let devices: Devices = serde_json::from_str(&output).expect("JSON was not well-formatted"); + let Ok(devices) = serde_json::from_str::(&output) else { + bail!("Could not deserialize JSON output from lsblk"); + }; // Find the device with the parttypename "BIOS boot" for device in devices.blockdevices { if let Some(parttypename) = &device.parttypename { - if parttypename == "BIOS boot" && device.pttype == "gpt" { + if parttypename == "BIOS boot" && device.pttype.as_deref() == Some("gpt") { return Ok(Some(device.path)); } } @@ -213,3 +215,18 @@ impl Component for Bios { Ok(None) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_deserialize_lsblk_output() { + let data = include_str!("../tests/fixtures/example-lsblk-output.json"); + let devices: Devices = serde_json::from_str(&data).expect("JSON was not well-formatted"); + assert_eq!(devices.blockdevices.len(), 7); + assert_eq!(devices.blockdevices[0].path, "/dev/sr0"); + assert!(devices.blockdevices[0].pttype.is_none()); + assert!(devices.blockdevices[0].parttypename.is_none()); + } +} diff --git a/tests/fixtures/example-lsblk-output.json b/tests/fixtures/example-lsblk-output.json new file mode 100644 index 00000000..f0aac3e0 --- /dev/null +++ b/tests/fixtures/example-lsblk-output.json @@ -0,0 +1,33 @@ +{ + "blockdevices": [ + { + "path": "/dev/sr0", + "pttype": null, + "parttypename": null + },{ + "path": "/dev/zram0", + "pttype": null, + "parttypename": null + },{ + "path": "/dev/vda", + "pttype": "gpt", + "parttypename": null + },{ + "path": "/dev/vda1", + "pttype": "gpt", + "parttypename": "EFI System" + },{ + "path": "/dev/vda2", + "pttype": "gpt", + "parttypename": "Linux extended boot" + },{ + "path": "/dev/vda3", + "pttype": "gpt", + "parttypename": "Linux filesystem" + },{ + "path": "/dev/mapper/luks-df2d5f95-5725-44dd-83e1-81bc4cdc49b8", + "pttype": null, + "parttypename": null + } + ] +}