Add plist use to the CreateFstabEntry action (#221)
This commit is contained in:
parent
fd149eef47
commit
8042ac5131
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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" ] }
|
||||
|
|
|
@ -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<Option<Uuid>, ActionError> {
|
||||
async fn get_uuid_for_label(apfs_volume_label: &str) -> Result<Uuid, ActionError> {
|
||||
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<Option<Uuid>, 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,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue