From 8042ac5131ec296ae4c4c5250810203056555102 Mon Sep 17 00:00:00 2001 From: Ana Hobden Date: Wed, 1 Feb 2023 10:40:56 -0800 Subject: [PATCH] Add plist use to the CreateFstabEntry action (#221) --- Cargo.lock | 3 ++ Cargo.toml | 2 +- src/action/darwin/create_fstab_entry.rs | 54 +++++++------------------ 3 files changed, 18 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6c4fd53..cc623d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1868,6 +1868,9 @@ name = "uuid" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +dependencies = [ + "serde", +] [[package]] name = "valuable" diff --git a/Cargo.toml b/Cargo.toml index f9e3bb5..6e7a573 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,7 @@ dyn-clone = { version = "1.0.9", default-features = false } rand = { version = "0.8.5", default-features = false, features = [ "std", "std_rng" ] } semver = { version = "1.0.14", default-features = false, features = ["serde", "std"] } term = { version = "0.7.0", default-features = false } -uuid = "1.2.2" +uuid = { version = "1.2.2", features = ["serde"] } [dev-dependencies] eyre = { version = "0.6.8", default-features = false, features = [ "track-caller" ] } diff --git a/src/action/darwin/create_fstab_entry.rs b/src/action/darwin/create_fstab_entry.rs index 5fc2184..240c5b1 100644 --- a/src/action/darwin/create_fstab_entry.rs +++ b/src/action/darwin/create_fstab_entry.rs @@ -6,9 +6,9 @@ use crate::{ execute_command, }; use rand::Rng; +use serde::Deserialize; use std::{ io::SeekFrom, - os::unix::prelude::PermissionsExt, path::{Path, PathBuf}, str::FromStr, }; @@ -82,13 +82,7 @@ impl Action for CreateFstabEntry { async fn execute(&mut self) -> Result<(), ActionError> { let Self { apfs_volume_label } = self; let fstab_path = Path::new(FSTAB_PATH); - let uuid = get_uuid_for_label(&apfs_volume_label) - .await? - .ok_or_else(|| { - ActionError::Custom(Box::new(CreateFstabEntryError::NoVolume( - apfs_volume_label.clone(), - ))) - })?; + let uuid = get_uuid_for_label(&apfs_volume_label).await?; let fstab_entry = fstab_entry(&uuid, apfs_volume_label); let mut fstab = tokio::fs::OpenOptions::new() @@ -133,13 +127,7 @@ impl Action for CreateFstabEntry { async fn revert(&mut self) -> Result<(), ActionError> { let Self { apfs_volume_label } = self; let fstab_path = Path::new(FSTAB_PATH); - let uuid = get_uuid_for_label(&apfs_volume_label) - .await? - .ok_or_else(|| { - ActionError::Custom(Box::new(CreateFstabEntryError::NoVolume( - apfs_volume_label.clone(), - ))) - })?; + let uuid = get_uuid_for_label(&apfs_volume_label).await?; let fstab_entry = fstab_entry(&uuid, apfs_volume_label); let mut file = OpenOptions::new() @@ -177,11 +165,12 @@ impl Action for CreateFstabEntry { } } -async fn get_uuid_for_label(apfs_volume_label: &str) -> Result, ActionError> { +async fn get_uuid_for_label(apfs_volume_label: &str) -> Result { let output = execute_command( Command::new("/usr/sbin/diskutil") .process_group(0) .arg("info") + .arg("-plist") .arg(apfs_volume_label) .stdin(std::process::Stdio::null()) .stdout(std::process::Stdio::piped()), @@ -189,27 +178,9 @@ async fn get_uuid_for_label(apfs_volume_label: &str) -> Result, Act .await .map_err(|e| ActionError::Command(e))?; - let stdout = String::from_utf8(output.stdout)?; + let parsed: DiskUtilApfsInfoOutput = plist::from_bytes(&output.stdout)?; - let mut found = None; - for line in stdout.lines() { - let prefix = "Volume UUID:"; - let trimmed = line.trim(); - if let Some(index) = trimmed.find(prefix) { - let maybe_uuid = trimmed[(index + prefix.len())..].trim(); - let uuid = Uuid::parse_str(maybe_uuid).map_err(|err| { - ActionError::Custom(Box::new(CreateFstabEntryError::Uuid( - maybe_uuid.to_string(), - err, - ))) - })?; - - found = Some(uuid); - break; - } - } - - Ok(found) + Ok(parsed.volume_uuid) } fn fstab_prelude_comment(apfs_volume_label: &str) -> String { @@ -228,10 +199,13 @@ fn fstab_entry(uuid: &Uuid, apfs_volume_label: &str) -> String { #[derive(thiserror::Error, Debug)] pub enum CreateFstabEntryError { - #[error("UUID error: {0}")] - Uuid(String, #[source] uuid::Error), - #[error("No volume labelled `{0}` present, cannot get UUID to add to /etc/fstab")] - NoVolume(String), #[error("An `/etc/fstab` entry for the volume labelled `{0}` already exists. If a Nix Store already exists it may need to be deleted with `diskutil apfs deleteVolume \"{0}\") and should be removed from `/etc/fstab`")] EntryExists(String), } + +#[derive(Deserialize, Clone, Debug)] +#[serde(rename_all = "PascalCase")] +struct DiskUtilApfsInfoOutput { + #[serde(rename = "VolumeUUID")] + volume_uuid: Uuid, +}