Skip to content

Commit

Permalink
Verify the apfs volume doesn't already exist before trying to create …
Browse files Browse the repository at this point in the history
…it (#217)

* Verify the apfs volume doesn't already exist before trying to create it

* Use plist instead of raw parsing

* Remove an unwrap
  • Loading branch information
Hoverbear authored Feb 1, 2023
1 parent 6b3a840 commit fd149ee
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 5 deletions.
41 changes: 38 additions & 3 deletions src/action/darwin/create_apfs_volume.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use tracing::{span, Span};

use crate::action::{ActionError, StatefulAction};
use crate::execute_command;
use serde::Deserialize;

use crate::action::{Action, ActionDescription};

Expand All @@ -22,6 +23,22 @@ impl CreateApfsVolume {
name: String,
case_sensitive: bool,
) -> Result<StatefulAction<Self>, ActionError> {
let output =
execute_command(Command::new("/usr/sbin/diskutil").args(["apfs", "list", "-plist"]))
.await
.map_err(ActionError::Command)?;

let parsed: DiskUtilApfsListOutput = plist::from_bytes(&output.stdout)?;
for container in parsed.containers {
for volume in container.volumes {
if volume.name == name {
return Err(ActionError::Custom(Box::new(
CreateApfsVolumeError::ExistingVolume(name),
)));
}
}
}

Ok(Self {
disk: disk.as_ref().to_path_buf(),
name,
Expand Down Expand Up @@ -120,7 +137,25 @@ impl Action for CreateApfsVolume {
}

#[derive(Debug, thiserror::Error)]
pub enum CreateVolumeError {
#[error("Failed to execute command")]
Command(#[source] std::io::Error),
pub enum CreateApfsVolumeError {
#[error("Existing volume called `{0}` found in `diskutil apfs list`, delete it with `diskutil apfs deleteVolume \"{0}\"`")]
ExistingVolume(String),
}

#[derive(Deserialize, Clone, Debug)]
#[serde(rename_all = "PascalCase")]
struct DiskUtilApfsListOutput {
containers: Vec<DiskUtilApfsContainer>,
}

#[derive(Deserialize, Clone, Debug)]
#[serde(rename_all = "PascalCase")]
struct DiskUtilApfsContainer {
volumes: Vec<DiskUtilApfsListVolume>,
}

#[derive(Deserialize, Clone, Debug)]
#[serde(rename_all = "PascalCase")]
struct DiskUtilApfsListVolume {
name: String,
}
2 changes: 1 addition & 1 deletion src/action/darwin/enable_ownership.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl Action for EnableOwnership {
.await
.map_err(ActionError::Command)?
.stdout;
let the_plist: DiskUtilOutput = plist::from_reader(Cursor::new(buf)).unwrap();
let the_plist: DiskUtilOutput = plist::from_reader(Cursor::new(buf))?;

the_plist.global_permissions_enabled
};
Expand Down
2 changes: 1 addition & 1 deletion src/action/darwin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub(crate) mod kickstart_launchctl_service;
pub(crate) mod unmount_apfs_volume;

pub use bootstrap_apfs_volume::{BootstrapApfsVolume, BootstrapVolumeError};
pub use create_apfs_volume::{CreateApfsVolume, CreateVolumeError};
pub use create_apfs_volume::{CreateApfsVolume, CreateApfsVolumeError};
pub use create_nix_volume::{CreateNixVolume, NIX_VOLUME_MOUNTD_DEST};
pub use create_synthetic_objects::{CreateSyntheticObjects, CreateSyntheticObjectsError};
pub use enable_ownership::{EnableOwnership, EnableOwnershipError};
Expand Down
3 changes: 3 additions & 0 deletions src/action/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,9 @@ pub enum ActionError {
#[from]
std::string::FromUtf8Error,
),
/// A MacOS (Darwin) plist related error
#[error(transparent)]
Plist(#[from] plist::Error),
}

impl HasExpectedErrors for ActionError {
Expand Down
1 change: 1 addition & 0 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ pub struct CommonSettings {
feature = "cli",
clap(long, env = "NIX_INSTALLER_NIX_BUILD_USER_ID_BASE", global = true)
)]
// Service users on Mac should be between 200-400
#[cfg_attr(all(target_os = "macos", feature = "cli"), clap(default_value_t = 300))]
#[cfg_attr(
all(target_os = "linux", feature = "cli"),
Expand Down

0 comments on commit fd149ee

Please sign in to comment.