forked from lix-project/lix-installer
More fleshing out
This commit is contained in:
parent
da0219deb0
commit
fcc200b9d0
|
@ -61,9 +61,36 @@ impl Actionable for CreateGroup {
|
||||||
}
|
}
|
||||||
tracing::debug!("Creating group");
|
tracing::debug!("Creating group");
|
||||||
|
|
||||||
execute_command(Command::new("groupadd").args(["-g", &gid.to_string(), "--system", &name]))
|
use target_lexicon::OperatingSystem;
|
||||||
.await
|
match target_lexicon::HOST.operating_system {
|
||||||
.map_err(CreateGroupError::Command)?;
|
OperatingSystem::MacOSX {
|
||||||
|
major: _,
|
||||||
|
minor: _,
|
||||||
|
patch: _,
|
||||||
|
} => {
|
||||||
|
execute_command(Command::new("/usr/sbin/dseditgroup").args([
|
||||||
|
"-o",
|
||||||
|
"create",
|
||||||
|
"-r",
|
||||||
|
"Nix build group for nix-daemon",
|
||||||
|
"-i",
|
||||||
|
&format!("{gid}"),
|
||||||
|
name.as_str(),
|
||||||
|
]))
|
||||||
|
.await
|
||||||
|
.map_err(Self::Error::Command)?;
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
execute_command(Command::new("groupadd").args([
|
||||||
|
"-g",
|
||||||
|
&gid.to_string(),
|
||||||
|
"--system",
|
||||||
|
&name,
|
||||||
|
]))
|
||||||
|
.await
|
||||||
|
.map_err(CreateGroupError::Command)?;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
tracing::trace!("Created group");
|
tracing::trace!("Created group");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
|
|
|
@ -67,27 +67,49 @@ impl Actionable for CreateUser {
|
||||||
}
|
}
|
||||||
tracing::debug!("Creating user");
|
tracing::debug!("Creating user");
|
||||||
|
|
||||||
execute_command(Command::new("useradd").args([
|
use target_lexicon::OperatingSystem;
|
||||||
"--home-dir",
|
match target_lexicon::HOST.operating_system {
|
||||||
"/var/empty",
|
OperatingSystem::MacOSX {
|
||||||
"--comment",
|
major: _,
|
||||||
&format!("\"Nix build user\""),
|
minor: _,
|
||||||
"--gid",
|
patch: _,
|
||||||
&gid.to_string(),
|
} => {
|
||||||
"--groups",
|
execute_command(Command::new("/usr/bin/dscl").args([
|
||||||
&gid.to_string(),
|
".",
|
||||||
"--no-user-group",
|
"create",
|
||||||
"--system",
|
&format!("/Users/{name}"),
|
||||||
"--shell",
|
"UniqueId",
|
||||||
"/sbin/nologin",
|
&format!("{uid}"),
|
||||||
"--uid",
|
"PrimaryGroupID",
|
||||||
&uid.to_string(),
|
&format!("{gid}"),
|
||||||
"--password",
|
]))
|
||||||
"\"!\"",
|
.await
|
||||||
&name.to_string(),
|
.map_err(Self::Error::Command)?;
|
||||||
]))
|
},
|
||||||
.await
|
_ => {
|
||||||
.map_err(Self::Error::Command)?;
|
execute_command(Command::new("useradd").args([
|
||||||
|
"--home-dir",
|
||||||
|
"/var/empty",
|
||||||
|
"--comment",
|
||||||
|
&format!("\"Nix build user\""),
|
||||||
|
"--gid",
|
||||||
|
&gid.to_string(),
|
||||||
|
"--groups",
|
||||||
|
&gid.to_string(),
|
||||||
|
"--no-user-group",
|
||||||
|
"--system",
|
||||||
|
"--shell",
|
||||||
|
"/sbin/nologin",
|
||||||
|
"--uid",
|
||||||
|
&uid.to_string(),
|
||||||
|
"--password",
|
||||||
|
"\"!\"",
|
||||||
|
&name.to_string(),
|
||||||
|
]))
|
||||||
|
.await
|
||||||
|
.map_err(Self::Error::Command)?;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
tracing::trace!("Created user");
|
tracing::trace!("Created user");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
|
@ -132,9 +154,21 @@ impl Actionable for CreateUser {
|
||||||
}
|
}
|
||||||
tracing::debug!("Deleting user");
|
tracing::debug!("Deleting user");
|
||||||
|
|
||||||
execute_command(Command::new("userdel").args([&name.to_string()]))
|
use target_lexicon::OperatingSystem;
|
||||||
.await
|
match target_lexicon::HOST.operating_system {
|
||||||
.map_err(Self::Error::Command)?;
|
OperatingSystem::MacOSX {
|
||||||
|
major: _,
|
||||||
|
minor: _,
|
||||||
|
patch: _,
|
||||||
|
} => {
|
||||||
|
todo!()
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
execute_command(Command::new("userdel").args([&name.to_string()]))
|
||||||
|
.await
|
||||||
|
.map_err(Self::Error::Command)?;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
tracing::trace!("Deleted user");
|
tracing::trace!("Deleted user");
|
||||||
*action_state = ActionState::Uncompleted;
|
*action_state = ActionState::Uncompleted;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
|
@ -7,15 +9,15 @@ use crate::actions::{Action, ActionDescription, ActionState, Actionable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct BootstrapVolume {
|
pub struct BootstrapVolume {
|
||||||
unit: String,
|
path: PathBuf,
|
||||||
action_state: ActionState,
|
action_state: ActionState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BootstrapVolume {
|
impl BootstrapVolume {
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub async fn plan(unit: String) -> Result<Self, BootstrapVolumeError> {
|
pub async fn plan(path: impl AsRef<Path>) -> Result<Self, BootstrapVolumeError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
unit,
|
path: path.as_ref().to_path_buf(),
|
||||||
action_state: ActionState::Uncompleted,
|
action_state: ActionState::Uncompleted,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -30,36 +32,35 @@ impl Actionable for BootstrapVolume {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
"Start the systemd Nix service and socket".to_string(),
|
format!("Bootstrap and kickstart `{}`", self.path.display()),
|
||||||
vec![
|
vec![],
|
||||||
"The `nix` command line tool communicates with a running Nix daemon managed by your init system".to_string()
|
|
||||||
]
|
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(
|
#[tracing::instrument(skip_all, fields(
|
||||||
unit = %self.unit,
|
path = %self.path.display(),
|
||||||
))]
|
))]
|
||||||
async fn execute(&mut self) -> Result<(), Self::Error> {
|
async fn execute(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self { unit, action_state } = self;
|
let Self { path, action_state } = self;
|
||||||
if *action_state == ActionState::Completed {
|
if *action_state == ActionState::Completed {
|
||||||
tracing::trace!("Already completed: Starting systemd unit");
|
tracing::trace!("Already completed: Bootstrapping volume");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
tracing::debug!("Starting systemd unit");
|
tracing::debug!("Bootstrapping volume");
|
||||||
|
|
||||||
// TODO(@Hoverbear): Handle proxy vars
|
|
||||||
execute_command(
|
execute_command(
|
||||||
Command::new("systemctl")
|
Command::new("launchctl")
|
||||||
.arg("enable")
|
.args(["bootstrap", "system"])
|
||||||
.arg("--now")
|
.arg(path),
|
||||||
.arg(format!("{unit}")),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(BootstrapVolumeError::Command)?;
|
.map_err(Self::Error::Command)?;
|
||||||
|
execute_command(Command::new("launchctl").args(["-k", "system/org.nixos.darwin-store"]))
|
||||||
|
.await
|
||||||
|
.map_err(Self::Error::Command)?;
|
||||||
|
|
||||||
tracing::trace!("Started systemd unit");
|
tracing::trace!("Bootstrapped volume");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -69,31 +70,32 @@ impl Actionable for BootstrapVolume {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
"Stop the systemd Nix service and socket".to_string(),
|
format!("Stop `{}`", self.path.display()),
|
||||||
vec![
|
vec![],
|
||||||
"The `nix` command line tool communicates with a running Nix daemon managed by your init system".to_string()
|
|
||||||
]
|
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(
|
#[tracing::instrument(skip_all, fields(
|
||||||
unit = %self.unit,
|
path = %self.path.display(),
|
||||||
))]
|
))]
|
||||||
async fn revert(&mut self) -> Result<(), Self::Error> {
|
async fn revert(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self { unit, action_state } = self;
|
let Self { path, action_state } = self;
|
||||||
if *action_state == ActionState::Uncompleted {
|
if *action_state == ActionState::Uncompleted {
|
||||||
tracing::trace!("Already reverted: Stopping systemd unit");
|
tracing::trace!("Already reverted: Stop volume");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
tracing::debug!("Stopping systemd unit");
|
tracing::debug!("Stop volume");
|
||||||
|
|
||||||
// TODO(@Hoverbear): Handle proxy vars
|
execute_command(
|
||||||
execute_command(Command::new("systemctl").arg("stop").arg(format!("{unit}")))
|
Command::new("launchctl")
|
||||||
.await
|
.args(["bootout", "system"])
|
||||||
.map_err(BootstrapVolumeError::Command)?;
|
.arg(path),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(Self::Error::Command)?;
|
||||||
|
|
||||||
tracing::trace!("Stopped systemd unit");
|
tracing::trace!("Stopped volume");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,15 +7,13 @@ use crate::actions::{Action, ActionDescription, ActionState, Actionable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct CreateSyntheticObjects {
|
pub struct CreateSyntheticObjects {
|
||||||
unit: String,
|
|
||||||
action_state: ActionState,
|
action_state: ActionState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CreateSyntheticObjects {
|
impl CreateSyntheticObjects {
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub async fn plan(unit: String) -> Result<Self, CreateSyntheticObjectsError> {
|
pub async fn plan() -> Result<Self, CreateSyntheticObjectsError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
unit,
|
|
||||||
action_state: ActionState::Uncompleted,
|
action_state: ActionState::Uncompleted,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -30,36 +28,36 @@ impl Actionable for CreateSyntheticObjects {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
"Start the systemd Nix service and socket".to_string(),
|
"Create objects defined in `/etc/synthetic.conf`".to_string(),
|
||||||
vec![
|
vec!["Populates the `/nix` path".to_string()],
|
||||||
"The `nix` command line tool communicates with a running Nix daemon managed by your init system".to_string()
|
|
||||||
]
|
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(
|
#[tracing::instrument(skip_all, fields())]
|
||||||
unit = %self.unit,
|
|
||||||
))]
|
|
||||||
async fn execute(&mut self) -> Result<(), Self::Error> {
|
async fn execute(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self { unit, action_state } = self;
|
let Self { action_state } = self;
|
||||||
if *action_state == ActionState::Completed {
|
if *action_state == ActionState::Completed {
|
||||||
tracing::trace!("Already completed: Starting systemd unit");
|
tracing::trace!("Already completed: Creating synthetic objects");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
tracing::debug!("Starting systemd unit");
|
tracing::debug!("Creating synthetic objects");
|
||||||
|
|
||||||
// TODO(@Hoverbear): Handle proxy vars
|
// Yup we literally call both and ignore the error! Reasoning: https://github.com/NixOS/nix/blob/95331cb9c99151cbd790ceb6ddaf49fc1c0da4b3/scripts/create-darwin-volume.sh#L261
|
||||||
execute_command(
|
execute_command(
|
||||||
Command::new("systemctl")
|
Command::new("/System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util")
|
||||||
.arg("enable")
|
.arg("-t"),
|
||||||
.arg("--now")
|
|
||||||
.arg(format!("{unit}")),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(CreateSyntheticObjectsError::Command)?;
|
.ok(); // Deliberate
|
||||||
|
execute_command(
|
||||||
|
Command::new("/System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util")
|
||||||
|
.arg("-B"),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.ok(); // Deliberate
|
||||||
|
|
||||||
tracing::trace!("Started systemd unit");
|
tracing::trace!("Created synthetic objects");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -69,31 +67,36 @@ impl Actionable for CreateSyntheticObjects {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
"Stop the systemd Nix service and socket".to_string(),
|
"Refresh the objects defined in `/etc/synthetic.conf`".to_string(),
|
||||||
vec![
|
vec!["Will remove the `/nix` path".to_string()],
|
||||||
"The `nix` command line tool communicates with a running Nix daemon managed by your init system".to_string()
|
|
||||||
]
|
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(
|
#[tracing::instrument(skip_all, fields())]
|
||||||
unit = %self.unit,
|
|
||||||
))]
|
|
||||||
async fn revert(&mut self) -> Result<(), Self::Error> {
|
async fn revert(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self { unit, action_state } = self;
|
let Self { action_state } = self;
|
||||||
if *action_state == ActionState::Uncompleted {
|
if *action_state == ActionState::Uncompleted {
|
||||||
tracing::trace!("Already reverted: Stopping systemd unit");
|
tracing::trace!("Already reverted: Refreshing synthetic objects");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
tracing::debug!("Stopping systemd unit");
|
tracing::debug!("Refreshing synthetic objects");
|
||||||
|
|
||||||
// TODO(@Hoverbear): Handle proxy vars
|
// Yup we literally call both and ignore the error! Reasoning: https://github.com/NixOS/nix/blob/95331cb9c99151cbd790ceb6ddaf49fc1c0da4b3/scripts/create-darwin-volume.sh#L261
|
||||||
execute_command(Command::new("systemctl").arg("stop").arg(format!("{unit}")))
|
execute_command(
|
||||||
.await
|
Command::new("/System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util")
|
||||||
.map_err(CreateSyntheticObjectsError::Command)?;
|
.arg("-t"),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.ok(); // Deliberate
|
||||||
|
execute_command(
|
||||||
|
Command::new("/System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util")
|
||||||
|
.arg("-B"),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.ok(); // Deliberate
|
||||||
|
|
||||||
tracing::trace!("Stopped systemd unit");
|
tracing::trace!("Refreshed synthetic objects");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
|
@ -7,15 +9,23 @@ use crate::actions::{Action, ActionDescription, ActionState, Actionable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct CreateVolume {
|
pub struct CreateVolume {
|
||||||
unit: String,
|
disk: PathBuf,
|
||||||
|
name: String,
|
||||||
|
case_sensitive: bool,
|
||||||
action_state: ActionState,
|
action_state: ActionState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CreateVolume {
|
impl CreateVolume {
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub async fn plan(unit: String) -> Result<Self, CreateVolumeError> {
|
pub async fn plan(
|
||||||
|
disk: impl AsRef<Path>,
|
||||||
|
name: String,
|
||||||
|
case_sensitive: bool,
|
||||||
|
) -> Result<Self, CreateVolumeError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
unit,
|
disk: disk.as_ref().to_path_buf(),
|
||||||
|
name,
|
||||||
|
case_sensitive,
|
||||||
action_state: ActionState::Uncompleted,
|
action_state: ActionState::Uncompleted,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -30,36 +40,50 @@ impl Actionable for CreateVolume {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
"Start the systemd Nix service and socket".to_string(),
|
format!(
|
||||||
vec![
|
"Create a volumne on `{}` named `{}`",
|
||||||
"The `nix` command line tool communicates with a running Nix daemon managed by your init system".to_string()
|
self.disk.display(),
|
||||||
]
|
self.name
|
||||||
|
),
|
||||||
|
vec![],
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(
|
#[tracing::instrument(skip_all, fields(
|
||||||
unit = %self.unit,
|
disk = %self.disk.display(),
|
||||||
|
name = %self.name,
|
||||||
|
case_sensitive = %self.case_sensitive,
|
||||||
))]
|
))]
|
||||||
async fn execute(&mut self) -> Result<(), Self::Error> {
|
async fn execute(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self { unit, action_state } = self;
|
let Self {
|
||||||
|
disk,
|
||||||
|
name,
|
||||||
|
case_sensitive,
|
||||||
|
action_state,
|
||||||
|
} = self;
|
||||||
if *action_state == ActionState::Completed {
|
if *action_state == ActionState::Completed {
|
||||||
tracing::trace!("Already completed: Starting systemd unit");
|
tracing::trace!("Already completed: Creating volume");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
tracing::debug!("Starting systemd unit");
|
tracing::debug!("Creating volume");
|
||||||
|
|
||||||
// TODO(@Hoverbear): Handle proxy vars
|
execute_command(Command::new("/usr/sbin/diskutil").args([
|
||||||
execute_command(
|
"apfs",
|
||||||
Command::new("systemctl")
|
"addVolume",
|
||||||
.arg("enable")
|
&format!("{}", disk.display()),
|
||||||
.arg("--now")
|
if !*case_sensitive {
|
||||||
.arg(format!("{unit}")),
|
"APFS"
|
||||||
)
|
} else {
|
||||||
|
"Case-sensitive APFS"
|
||||||
|
},
|
||||||
|
name,
|
||||||
|
"-nomount",
|
||||||
|
]))
|
||||||
.await
|
.await
|
||||||
.map_err(CreateVolumeError::Command)?;
|
.map_err(Self::Error::Command)?;
|
||||||
|
|
||||||
tracing::trace!("Started systemd unit");
|
tracing::trace!("Created volume");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -69,31 +93,44 @@ impl Actionable for CreateVolume {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
"Stop the systemd Nix service and socket".to_string(),
|
format!(
|
||||||
vec![
|
"Remove the volume on `{}` named `{}`",
|
||||||
"The `nix` command line tool communicates with a running Nix daemon managed by your init system".to_string()
|
self.disk.display(),
|
||||||
]
|
self.name
|
||||||
|
),
|
||||||
|
vec![],
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(
|
#[tracing::instrument(skip_all, fields(
|
||||||
unit = %self.unit,
|
disk = %self.disk.display(),
|
||||||
|
name = %self.name,
|
||||||
|
case_sensitive = %self.case_sensitive,
|
||||||
))]
|
))]
|
||||||
async fn revert(&mut self) -> Result<(), Self::Error> {
|
async fn revert(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self { unit, action_state } = self;
|
let Self {
|
||||||
|
disk,
|
||||||
|
name,
|
||||||
|
case_sensitive: _,
|
||||||
|
action_state,
|
||||||
|
} = self;
|
||||||
if *action_state == ActionState::Uncompleted {
|
if *action_state == ActionState::Uncompleted {
|
||||||
tracing::trace!("Already reverted: Stopping systemd unit");
|
tracing::trace!("Already reverted: Deleting volume");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
tracing::debug!("Stopping systemd unit");
|
tracing::debug!("Deleting volume");
|
||||||
|
|
||||||
// TODO(@Hoverbear): Handle proxy vars
|
execute_command(Command::new("/usr/sbin/diskutil").args([
|
||||||
execute_command(Command::new("systemctl").arg("stop").arg(format!("{unit}")))
|
"apfs",
|
||||||
.await
|
"deleteVolume",
|
||||||
.map_err(CreateVolumeError::Command)?;
|
&format!("{}", disk.display()),
|
||||||
|
name,
|
||||||
|
]))
|
||||||
|
.await
|
||||||
|
.map_err(Self::Error::Command)?;
|
||||||
|
|
||||||
tracing::trace!("Stopped systemd unit");
|
tracing::trace!("Deleted volume");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
|
@ -7,15 +9,15 @@ use crate::actions::{Action, ActionDescription, ActionState, Actionable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct EnableOwnership {
|
pub struct EnableOwnership {
|
||||||
unit: String,
|
path: PathBuf,
|
||||||
action_state: ActionState,
|
action_state: ActionState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EnableOwnership {
|
impl EnableOwnership {
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub async fn plan(unit: String) -> Result<Self, EnableOwnershipError> {
|
pub async fn plan(path: impl AsRef<Path>) -> Result<Self, EnableOwnershipError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
unit,
|
path: path.as_ref().to_path_buf(),
|
||||||
action_state: ActionState::Uncompleted,
|
action_state: ActionState::Uncompleted,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -30,36 +32,56 @@ impl Actionable for EnableOwnership {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
"Start the systemd Nix service and socket".to_string(),
|
format!("Enable ownership on {}", self.path.display()),
|
||||||
vec![
|
vec![],
|
||||||
"The `nix` command line tool communicates with a running Nix daemon managed by your init system".to_string()
|
|
||||||
]
|
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(
|
#[tracing::instrument(skip_all, fields(
|
||||||
unit = %self.unit,
|
path = %self.path.display(),
|
||||||
))]
|
))]
|
||||||
async fn execute(&mut self) -> Result<(), Self::Error> {
|
async fn execute(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self { unit, action_state } = self;
|
let Self { path, action_state } = self;
|
||||||
if *action_state == ActionState::Completed {
|
if *action_state == ActionState::Completed {
|
||||||
tracing::trace!("Already completed: Starting systemd unit");
|
tracing::trace!("Already completed: Enabling ownership");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
tracing::debug!("Starting systemd unit");
|
tracing::debug!("Enabling ownership");
|
||||||
|
|
||||||
// TODO(@Hoverbear): Handle proxy vars
|
let should_enable_ownership = {
|
||||||
execute_command(
|
let buf = execute_command(
|
||||||
Command::new("systemctl")
|
Command::new("/usr/sbin/diskutil")
|
||||||
.arg("enable")
|
.args(["info", "-plist"])
|
||||||
.arg("--now")
|
.arg(&path),
|
||||||
.arg(format!("{unit}")),
|
)
|
||||||
)
|
.await
|
||||||
.await
|
.unwrap()
|
||||||
.map_err(EnableOwnershipError::Command)?;
|
.stdout;
|
||||||
|
let package = sxd_document::parser::parse(&String::from_utf8(buf).unwrap()).unwrap();
|
||||||
|
|
||||||
tracing::trace!("Started systemd unit");
|
match sxd_xpath::evaluate_xpath(
|
||||||
|
&package.as_document(),
|
||||||
|
"(/plist/dict/key[text()='GlobalPermissionsEnabled'])/following-sibling::*[1]",
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
|
sxd_xpath::Value::Boolean(bool) => bool,
|
||||||
|
_ => panic!("At the other disk i/o!!!"),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if should_enable_ownership {
|
||||||
|
execute_command(
|
||||||
|
Command::new("/usr/sbin/diskutil")
|
||||||
|
.arg("enableOwnership")
|
||||||
|
.arg(path),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(Self::Error::Command)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracing::trace!("Enabled ownership");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -68,32 +90,25 @@ impl Actionable for EnableOwnership {
|
||||||
if self.action_state == ActionState::Uncompleted {
|
if self.action_state == ActionState::Uncompleted {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![ActionDescription::new(
|
vec![]
|
||||||
"Stop the systemd Nix service and socket".to_string(),
|
|
||||||
vec![
|
|
||||||
"The `nix` command line tool communicates with a running Nix daemon managed by your init system".to_string()
|
|
||||||
]
|
|
||||||
)]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(
|
#[tracing::instrument(skip_all, fields(
|
||||||
unit = %self.unit,
|
path = %self.path.display(),
|
||||||
))]
|
))]
|
||||||
async fn revert(&mut self) -> Result<(), Self::Error> {
|
async fn revert(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self { unit, action_state } = self;
|
let Self {
|
||||||
|
path: _,
|
||||||
|
action_state,
|
||||||
|
} = self;
|
||||||
if *action_state == ActionState::Uncompleted {
|
if *action_state == ActionState::Uncompleted {
|
||||||
tracing::trace!("Already reverted: Stopping systemd unit");
|
tracing::trace!("Already reverted: Unenabling ownership (noop)");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
tracing::debug!("Stopping systemd unit");
|
tracing::debug!("Unenabling ownership (noop)");
|
||||||
|
|
||||||
// TODO(@Hoverbear): Handle proxy vars
|
tracing::trace!("Unenabled ownership (noop)");
|
||||||
execute_command(Command::new("systemctl").arg("stop").arg(format!("{unit}")))
|
|
||||||
.await
|
|
||||||
.map_err(EnableOwnershipError::Command)?;
|
|
||||||
|
|
||||||
tracing::trace!("Stopped systemd unit");
|
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
use crate::execute_command;
|
use crate::execute_command;
|
||||||
|
@ -7,15 +8,20 @@ use crate::actions::{Action, ActionDescription, ActionState, Actionable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct EncryptVolume {
|
pub struct EncryptVolume {
|
||||||
unit: String,
|
disk: PathBuf,
|
||||||
|
password: String,
|
||||||
action_state: ActionState,
|
action_state: ActionState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EncryptVolume {
|
impl EncryptVolume {
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub async fn plan(unit: String) -> Result<Self, EncryptVolumeError> {
|
pub async fn plan(
|
||||||
|
disk: impl AsRef<Path>,
|
||||||
|
password: String,
|
||||||
|
) -> Result<Self, EncryptVolumeError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
unit,
|
disk: disk.as_ref().to_path_buf(),
|
||||||
|
password,
|
||||||
action_state: ActionState::Uncompleted,
|
action_state: ActionState::Uncompleted,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -30,36 +36,30 @@ impl Actionable for EncryptVolume {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
"Start the systemd Nix service and socket".to_string(),
|
format!("Encrypt volume `{}`", self.disk.display()),
|
||||||
vec![
|
vec![],
|
||||||
"The `nix` command line tool communicates with a running Nix daemon managed by your init system".to_string()
|
|
||||||
]
|
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(
|
#[tracing::instrument(skip_all, fields(
|
||||||
unit = %self.unit,
|
disk = %self.disk.display(),
|
||||||
))]
|
))]
|
||||||
async fn execute(&mut self) -> Result<(), Self::Error> {
|
async fn execute(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self { unit, action_state } = self;
|
let Self {
|
||||||
|
disk,
|
||||||
|
password,
|
||||||
|
action_state,
|
||||||
|
} = self;
|
||||||
if *action_state == ActionState::Completed {
|
if *action_state == ActionState::Completed {
|
||||||
tracing::trace!("Already completed: Starting systemd unit");
|
tracing::trace!("Already completed: Encrypting volume");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
tracing::debug!("Starting systemd unit");
|
tracing::debug!("Encrypting volume");
|
||||||
|
|
||||||
// TODO(@Hoverbear): Handle proxy vars
|
todo!();
|
||||||
execute_command(
|
|
||||||
Command::new("systemctl")
|
|
||||||
.arg("enable")
|
|
||||||
.arg("--now")
|
|
||||||
.arg(format!("{unit}")),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map_err(EncryptVolumeError::Command)?;
|
|
||||||
|
|
||||||
tracing::trace!("Started systemd unit");
|
tracing::trace!("Encrypted volume");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -68,32 +68,26 @@ impl Actionable for EncryptVolume {
|
||||||
if self.action_state == ActionState::Uncompleted {
|
if self.action_state == ActionState::Uncompleted {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![ActionDescription::new(
|
vec![]
|
||||||
"Stop the systemd Nix service and socket".to_string(),
|
|
||||||
vec![
|
|
||||||
"The `nix` command line tool communicates with a running Nix daemon managed by your init system".to_string()
|
|
||||||
]
|
|
||||||
)]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(
|
#[tracing::instrument(skip_all, fields(
|
||||||
unit = %self.unit,
|
disk = %self.disk.display(),
|
||||||
))]
|
))]
|
||||||
async fn revert(&mut self) -> Result<(), Self::Error> {
|
async fn revert(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self { unit, action_state } = self;
|
let Self {
|
||||||
|
disk,
|
||||||
|
password,
|
||||||
|
action_state,
|
||||||
|
} = self;
|
||||||
if *action_state == ActionState::Uncompleted {
|
if *action_state == ActionState::Uncompleted {
|
||||||
tracing::trace!("Already reverted: Stopping systemd unit");
|
tracing::trace!("Already reverted: Unencrypted volume (noop)");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
tracing::debug!("Stopping systemd unit");
|
tracing::debug!("Unencrypted volume (noop)");
|
||||||
|
|
||||||
// TODO(@Hoverbear): Handle proxy vars
|
tracing::trace!("Unencrypted volume (noop)");
|
||||||
execute_command(Command::new("systemctl").arg("stop").arg(format!("{unit}")))
|
|
||||||
.await
|
|
||||||
.map_err(EncryptVolumeError::Command)?;
|
|
||||||
|
|
||||||
tracing::trace!("Stopped systemd unit");
|
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
|
@ -7,15 +9,18 @@ use crate::actions::{Action, ActionDescription, ActionState, Actionable};
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct UnmountVolume {
|
pub struct UnmountVolume {
|
||||||
unit: String,
|
disk: PathBuf,
|
||||||
|
name: String,
|
||||||
action_state: ActionState,
|
action_state: ActionState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnmountVolume {
|
impl UnmountVolume {
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub async fn plan(unit: String) -> Result<Self, UnmountVolumeError> {
|
pub async fn plan(disk: impl AsRef<Path>, name: String) -> Result<Self, UnmountVolumeError> {
|
||||||
|
let disk = disk.as_ref().to_owned();
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
unit,
|
disk,
|
||||||
|
name,
|
||||||
action_state: ActionState::Uncompleted,
|
action_state: ActionState::Uncompleted,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -39,27 +44,30 @@ impl Actionable for UnmountVolume {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(
|
#[tracing::instrument(skip_all, fields(
|
||||||
unit = %self.unit,
|
disk = %self.disk.display(),
|
||||||
|
name = %self.name,
|
||||||
))]
|
))]
|
||||||
async fn execute(&mut self) -> Result<(), Self::Error> {
|
async fn execute(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self { unit, action_state } = self;
|
let Self {
|
||||||
|
disk,
|
||||||
|
name,
|
||||||
|
action_state,
|
||||||
|
} = self;
|
||||||
if *action_state == ActionState::Completed {
|
if *action_state == ActionState::Completed {
|
||||||
tracing::trace!("Already completed: Starting systemd unit");
|
tracing::trace!("Already completed: Unmounting volume");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
tracing::debug!("Starting systemd unit");
|
tracing::debug!("Unmounting volume");
|
||||||
|
|
||||||
// TODO(@Hoverbear): Handle proxy vars
|
|
||||||
execute_command(
|
execute_command(
|
||||||
Command::new("systemctl")
|
Command::new(" /usr/sbin/diskutil")
|
||||||
.arg("enable")
|
.args(["unmount", "force"])
|
||||||
.arg("--now")
|
.arg(name),
|
||||||
.arg(format!("{unit}")),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(UnmountVolumeError::Command)?;
|
.map_err(Self::Error::Command)?;
|
||||||
|
|
||||||
tracing::trace!("Started systemd unit");
|
tracing::trace!("Unmounted volume");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -78,20 +86,28 @@ impl Actionable for UnmountVolume {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(
|
#[tracing::instrument(skip_all, fields(
|
||||||
unit = %self.unit,
|
disk = %self.disk.display(),
|
||||||
|
name = %self.name,
|
||||||
))]
|
))]
|
||||||
async fn revert(&mut self) -> Result<(), Self::Error> {
|
async fn revert(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self { unit, action_state } = self;
|
let Self {
|
||||||
|
disk,
|
||||||
|
name,
|
||||||
|
action_state,
|
||||||
|
} = self;
|
||||||
if *action_state == ActionState::Uncompleted {
|
if *action_state == ActionState::Uncompleted {
|
||||||
tracing::trace!("Already reverted: Stopping systemd unit");
|
tracing::trace!("Already reverted: Stopping systemd unit");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
tracing::debug!("Stopping systemd unit");
|
tracing::debug!("Stopping systemd unit");
|
||||||
|
|
||||||
// TODO(@Hoverbear): Handle proxy vars
|
execute_command(
|
||||||
execute_command(Command::new("systemctl").arg("stop").arg(format!("{unit}")))
|
Command::new(" /usr/sbin/diskutil")
|
||||||
.await
|
.args(["unmount", "force"])
|
||||||
.map_err(UnmountVolumeError::Command)?;
|
.arg(name),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(Self::Error::Command)?;
|
||||||
|
|
||||||
tracing::trace!("Stopped systemd unit");
|
tracing::trace!("Stopped systemd unit");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
|
|
|
@ -58,7 +58,7 @@ impl Actionable for SystemdSysextMerge {
|
||||||
|
|
||||||
execute_command(Command::new("systemd-sysext").arg("merge").arg(device))
|
execute_command(Command::new("systemd-sysext").arg("merge").arg(device))
|
||||||
.await
|
.await
|
||||||
.map_err(SystemdSysextMergeError::Command)?;
|
.map_err(Self::Error::Command)?;
|
||||||
|
|
||||||
tracing::trace!("Merged systemd-sysext");
|
tracing::trace!("Merged systemd-sysext");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
|
|
|
@ -7,8 +7,7 @@ use crate::actions::base::{
|
||||||
CreateVolume, CreateVolumeError, EnableOwnership, EnableOwnershipError, EncryptVolume,
|
CreateVolume, CreateVolumeError, EnableOwnership, EnableOwnershipError, EncryptVolume,
|
||||||
EncryptVolumeError, UnmountVolume, UnmountVolumeError,
|
EncryptVolumeError, UnmountVolume, UnmountVolumeError,
|
||||||
},
|
},
|
||||||
CreateDirectory, CreateDirectoryError, CreateFile, CreateFileError, CreateOrAppendFile,
|
CreateOrAppendFile, CreateOrAppendFileError,
|
||||||
CreateOrAppendFileError,
|
|
||||||
};
|
};
|
||||||
use crate::actions::{base::darwin, Action, ActionDescription, ActionState, Actionable};
|
use crate::actions::{base::darwin, Action, ActionDescription, ActionState, Actionable};
|
||||||
|
|
||||||
|
@ -51,10 +50,9 @@ impl CreateApfsVolume {
|
||||||
|
|
||||||
let create_synthetic_objects = CreateSyntheticObjects::plan().await?;
|
let create_synthetic_objects = CreateSyntheticObjects::plan().await?;
|
||||||
|
|
||||||
let unmount_volume =
|
let unmount_volume = UnmountVolume::plan(disk, name.clone()).await?;
|
||||||
UnmountVolume::plan(disk, name.clone(), case_sensitive, encrypt).await?;
|
|
||||||
|
|
||||||
let create_volume = CreateVolume::plan(disk, name.clone(), case_sensitive, encrypt).await?;
|
let create_volume = CreateVolume::plan(disk, name.clone(), case_sensitive).await?;
|
||||||
|
|
||||||
let create_or_append_fstab = CreateOrAppendFile::plan(
|
let create_or_append_fstab = CreateOrAppendFile::plan(
|
||||||
"/etc/fstab",
|
"/etc/fstab",
|
||||||
|
@ -65,13 +63,13 @@ impl CreateApfsVolume {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let encrypt_volume = if let Some(password) = encrypt {
|
let encrypt_volume = if let Some(password) = encrypt.as_ref() {
|
||||||
Some(EncryptVolume::plan(disk, password).await)
|
Some(EncryptVolume::plan(disk, password.to_string()).await?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let bootstrap_volume = BootstrapVolume::plan(NIX_VOLUME_MOUNTD_DEST, disk, name).await?;
|
let bootstrap_volume = BootstrapVolume::plan(NIX_VOLUME_MOUNTD_DEST).await?;
|
||||||
let enable_ownership = EnableOwnership::plan("/nix").await?;
|
let enable_ownership = EnableOwnership::plan("/nix").await?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
@ -100,17 +98,8 @@ impl Actionable for CreateApfsVolume {
|
||||||
let Self {
|
let Self {
|
||||||
disk,
|
disk,
|
||||||
name,
|
name,
|
||||||
case_sensitive,
|
|
||||||
encrypt,
|
|
||||||
create_or_append_synthetic_conf,
|
|
||||||
create_synthetic_objects,
|
|
||||||
unmount_volume,
|
|
||||||
create_volume,
|
|
||||||
create_or_append_fstab,
|
|
||||||
encrypt_volume,
|
|
||||||
bootstrap_volume,
|
|
||||||
enable_ownership,
|
|
||||||
action_state: _,
|
action_state: _,
|
||||||
|
..
|
||||||
} = &self;
|
} = &self;
|
||||||
if self.action_state == ActionState::Completed {
|
if self.action_state == ActionState::Completed {
|
||||||
vec![]
|
vec![]
|
||||||
|
@ -127,10 +116,10 @@ impl Actionable for CreateApfsVolume {
|
||||||
#[tracing::instrument(skip_all, fields(destination,))]
|
#[tracing::instrument(skip_all, fields(destination,))]
|
||||||
async fn execute(&mut self) -> Result<(), Self::Error> {
|
async fn execute(&mut self) -> Result<(), Self::Error> {
|
||||||
let Self {
|
let Self {
|
||||||
disk,
|
disk: _,
|
||||||
name,
|
name: _,
|
||||||
case_sensitive,
|
case_sensitive: _,
|
||||||
encrypt,
|
encrypt: _,
|
||||||
create_or_append_synthetic_conf,
|
create_or_append_synthetic_conf,
|
||||||
create_synthetic_objects,
|
create_synthetic_objects,
|
||||||
unmount_volume,
|
unmount_volume,
|
||||||
|
@ -152,7 +141,9 @@ impl Actionable for CreateApfsVolume {
|
||||||
unmount_volume.execute().await?;
|
unmount_volume.execute().await?;
|
||||||
create_volume.execute().await?;
|
create_volume.execute().await?;
|
||||||
create_or_append_fstab.execute().await?;
|
create_or_append_fstab.execute().await?;
|
||||||
encrypt_volume.execute().await?;
|
if let Some(encrypt_volume) = encrypt_volume {
|
||||||
|
encrypt_volume.execute().await?;
|
||||||
|
}
|
||||||
bootstrap_volume.execute().await?;
|
bootstrap_volume.execute().await?;
|
||||||
enable_ownership.execute().await?;
|
enable_ownership.execute().await?;
|
||||||
|
|
||||||
|
@ -165,19 +156,10 @@ impl Actionable for CreateApfsVolume {
|
||||||
let Self {
|
let Self {
|
||||||
disk,
|
disk,
|
||||||
name,
|
name,
|
||||||
case_sensitive,
|
action_state,
|
||||||
encrypt,
|
..
|
||||||
create_or_append_synthetic_conf,
|
|
||||||
create_synthetic_objects,
|
|
||||||
unmount_volume,
|
|
||||||
create_volume,
|
|
||||||
create_or_append_fstab,
|
|
||||||
encrypt_volume,
|
|
||||||
bootstrap_volume,
|
|
||||||
enable_ownership,
|
|
||||||
action_state: _,
|
|
||||||
} = &self;
|
} = &self;
|
||||||
if self.action_state == ActionState::Uncompleted {
|
if *action_state == ActionState::Uncompleted {
|
||||||
vec![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
|
|
Loading…
Reference in a new issue