Enable deleting users and groups on Mac (#253)
* Enable deleting users and groups on Mac * Scaffold user change * Add a warning if it doesn't work in situations we expect it to not work * Scaffold out doing group member ship -- maybe we need an AddGroup action * AddUserToGroup action * Update plans * Improve messaging * Nit in error message * Repair some review nits
This commit is contained in:
parent
7e951a5b6a
commit
689cf84bbf
|
@ -5,4 +5,5 @@ COPY binary-tarball /binary-tarball
|
||||||
RUN mv /binary-tarball/nix-*.tar.xz nix.tar.xz
|
RUN mv /binary-tarball/nix-*.tar.xz nix.tar.xz
|
||||||
RUN /nix-installer/bin/nix-installer install linux --nix-package-url file:///nix.tar.xz --init none --extra-conf "sandbox = false" --channel --no-confirm -vvv
|
RUN /nix-installer/bin/nix-installer install linux --nix-package-url file:///nix.tar.xz --init none --extra-conf "sandbox = false" --channel --no-confirm -vvv
|
||||||
ENV PATH="${PATH}:/nix/var/nix/profiles/default/bin"
|
ENV PATH="${PATH}:/nix/var/nix/profiles/default/bin"
|
||||||
RUN nix-build --no-substitute -E 'derivation { name = "foo"; system = "x86_64-linux"; builder = "/bin/sh"; args = ["-c" "echo foobar > $out"]; }'
|
RUN nix-build --no-substitute -E 'derivation { name = "foo"; system = "x86_64-linux"; builder = "/bin/sh"; args = ["-c" "echo foobar > $out"]; }'
|
||||||
|
RUN /nix/nix-installer uninstall --no-confirm
|
|
@ -236,6 +236,9 @@ let
|
||||||
echo "Testing Nix installation..."
|
echo "Testing Nix installation..."
|
||||||
$ssh "set -eux; $checkScript"
|
$ssh "set -eux; $checkScript"
|
||||||
|
|
||||||
|
echo "Testing Nix installation..."
|
||||||
|
$ssh "set -eux; /nix/nix-installer uninstall --no-confirm"
|
||||||
|
|
||||||
echo "Done!"
|
echo "Done!"
|
||||||
touch $out
|
touch $out
|
||||||
'';
|
'';
|
||||||
|
|
283
src/action/base/add_user_to_group.rs
Normal file
283
src/action/base/add_user_to_group.rs
Normal file
|
@ -0,0 +1,283 @@
|
||||||
|
use std::process::Stdio;
|
||||||
|
|
||||||
|
use nix::unistd::User;
|
||||||
|
use target_lexicon::OperatingSystem;
|
||||||
|
use tokio::process::Command;
|
||||||
|
use tracing::{span, Span};
|
||||||
|
|
||||||
|
use crate::action::ActionError;
|
||||||
|
use crate::execute_command;
|
||||||
|
|
||||||
|
use crate::action::{Action, ActionDescription, StatefulAction};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create an operating system level user in the given group
|
||||||
|
*/
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
|
pub struct AddUserToGroup {
|
||||||
|
name: String,
|
||||||
|
uid: u32,
|
||||||
|
groupname: String,
|
||||||
|
gid: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddUserToGroup {
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
|
pub async fn plan(
|
||||||
|
name: String,
|
||||||
|
uid: u32,
|
||||||
|
groupname: String,
|
||||||
|
gid: u32,
|
||||||
|
) -> Result<StatefulAction<Self>, ActionError> {
|
||||||
|
let this = Self {
|
||||||
|
name: name.clone(),
|
||||||
|
uid,
|
||||||
|
groupname,
|
||||||
|
gid,
|
||||||
|
};
|
||||||
|
// Ensure user does not exists
|
||||||
|
if let Some(user) = User::from_name(name.as_str())
|
||||||
|
.map_err(|e| ActionError::GettingUserId(name.clone(), e))?
|
||||||
|
{
|
||||||
|
if user.uid.as_raw() != uid {
|
||||||
|
return Err(ActionError::UserUidMismatch(
|
||||||
|
name.clone(),
|
||||||
|
user.uid.as_raw(),
|
||||||
|
uid,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if user.gid.as_raw() != gid {
|
||||||
|
return Err(ActionError::UserGidMismatch(
|
||||||
|
name.clone(),
|
||||||
|
user.gid.as_raw(),
|
||||||
|
gid,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if group membership needs to be done
|
||||||
|
match target_lexicon::OperatingSystem::host() {
|
||||||
|
OperatingSystem::MacOSX {
|
||||||
|
major: _,
|
||||||
|
minor: _,
|
||||||
|
patch: _,
|
||||||
|
}
|
||||||
|
| OperatingSystem::Darwin => {
|
||||||
|
let mut command = Command::new("/usr/sbin/dseditgroup");
|
||||||
|
command.process_group(0);
|
||||||
|
command.args(["-o", "checkmember", "-m"]);
|
||||||
|
command.arg(&this.name);
|
||||||
|
command.arg(&this.groupname);
|
||||||
|
command.stdout(Stdio::piped());
|
||||||
|
command.stderr(Stdio::piped());
|
||||||
|
let command_str = format!("{:?}", command.as_std());
|
||||||
|
tracing::trace!("Executing `{command_str}`");
|
||||||
|
let output = command.output().await.map_err(ActionError::Command)?;
|
||||||
|
match output.status.code() {
|
||||||
|
Some(0) => {
|
||||||
|
// yes {user} is a member of {groupname}
|
||||||
|
// Since the user exists, and is already a member of the group, we have truly nothing to do here
|
||||||
|
tracing::debug!(
|
||||||
|
"Adding user `{}` to group `{}` already complete",
|
||||||
|
this.name,
|
||||||
|
this.groupname
|
||||||
|
);
|
||||||
|
return Ok(StatefulAction::completed(this));
|
||||||
|
},
|
||||||
|
Some(64) => {
|
||||||
|
// 64 is the exit code for "Group not found"
|
||||||
|
tracing::trace!(
|
||||||
|
"Will add user `{}` to newly created group `{}`",
|
||||||
|
this.name,
|
||||||
|
this.groupname
|
||||||
|
);
|
||||||
|
// The group will be created by the installer
|
||||||
|
()
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
// Some other issue
|
||||||
|
return Err(ActionError::Command(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::Other,
|
||||||
|
format!(
|
||||||
|
"Command `{command_str}` failed{}, stderr:\n{}\n",
|
||||||
|
if let Some(code) = output.status.code() {
|
||||||
|
format!(" status {code}")
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
},
|
||||||
|
String::from_utf8_lossy(&output.stderr),
|
||||||
|
),
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
let output = execute_command(
|
||||||
|
Command::new("groups")
|
||||||
|
.process_group(0)
|
||||||
|
.arg(&this.name)
|
||||||
|
.stdin(std::process::Stdio::null()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ActionError::Command(e))?;
|
||||||
|
let output_str = String::from_utf8(output.stdout)?;
|
||||||
|
let user_in_group = output_str.split(" ").any(|v| v == &this.groupname);
|
||||||
|
|
||||||
|
if user_in_group {
|
||||||
|
tracing::debug!("Creating user `{}` already complete", this.name);
|
||||||
|
return Ok(StatefulAction::completed(this));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(StatefulAction::uncompleted(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
#[typetag::serde(name = "add_user_to_group")]
|
||||||
|
impl Action for AddUserToGroup {
|
||||||
|
fn tracing_synopsis(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"Add user `{}` (UID {}) to group `{}` (GID {})",
|
||||||
|
self.name, self.uid, self.groupname, self.gid
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tracing_span(&self) -> Span {
|
||||||
|
span!(
|
||||||
|
tracing::Level::DEBUG,
|
||||||
|
"add_user_to_group",
|
||||||
|
user = self.name,
|
||||||
|
uid = self.uid,
|
||||||
|
groupname = self.groupname,
|
||||||
|
gid = self.gid,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||||
|
vec![ActionDescription::new(
|
||||||
|
self.tracing_synopsis(),
|
||||||
|
vec![format!(
|
||||||
|
"The Nix daemon requires the build users to be in a defined group"
|
||||||
|
)],
|
||||||
|
)]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
|
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
uid: _,
|
||||||
|
groupname,
|
||||||
|
gid: _,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
use target_lexicon::OperatingSystem;
|
||||||
|
match OperatingSystem::host() {
|
||||||
|
OperatingSystem::MacOSX {
|
||||||
|
major: _,
|
||||||
|
minor: _,
|
||||||
|
patch: _,
|
||||||
|
}
|
||||||
|
| OperatingSystem::Darwin => {
|
||||||
|
execute_command(
|
||||||
|
Command::new("/usr/bin/dscl")
|
||||||
|
.process_group(0)
|
||||||
|
.args([
|
||||||
|
".",
|
||||||
|
"-append",
|
||||||
|
&format!("/Groups/{groupname}"),
|
||||||
|
"GroupMembership",
|
||||||
|
])
|
||||||
|
.arg(&name)
|
||||||
|
.stdin(std::process::Stdio::null()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ActionError::Command(e))?;
|
||||||
|
execute_command(
|
||||||
|
Command::new("/usr/sbin/dseditgroup")
|
||||||
|
.process_group(0)
|
||||||
|
.args(["-o", "edit"])
|
||||||
|
.arg("-a")
|
||||||
|
.arg(&name)
|
||||||
|
.arg("-t")
|
||||||
|
.arg(&name)
|
||||||
|
.arg(groupname)
|
||||||
|
.stdin(std::process::Stdio::null()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ActionError::Command(e))?;
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
execute_command(
|
||||||
|
Command::new("gpasswd")
|
||||||
|
.process_group(0)
|
||||||
|
.args(["-a"])
|
||||||
|
.args([&name.to_string(), &groupname.to_string()])
|
||||||
|
.stdin(std::process::Stdio::null()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ActionError::Command(e))?;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn revert_description(&self) -> Vec<ActionDescription> {
|
||||||
|
vec![ActionDescription::new(
|
||||||
|
format!(
|
||||||
|
"Remove user `{}` (UID {}) from group {} (GID {})",
|
||||||
|
self.name, self.uid, self.groupname, self.gid
|
||||||
|
),
|
||||||
|
vec![format!(
|
||||||
|
"The Nix daemon requires system users it can act as in order to build"
|
||||||
|
)],
|
||||||
|
)]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
|
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
uid: _,
|
||||||
|
groupname,
|
||||||
|
gid: _,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
use target_lexicon::OperatingSystem;
|
||||||
|
match target_lexicon::OperatingSystem::host() {
|
||||||
|
OperatingSystem::MacOSX {
|
||||||
|
major: _,
|
||||||
|
minor: _,
|
||||||
|
patch: _,
|
||||||
|
}
|
||||||
|
| OperatingSystem::Darwin => {
|
||||||
|
execute_command(
|
||||||
|
Command::new("/usr/bin/dscl")
|
||||||
|
.process_group(0)
|
||||||
|
.args([".", "-delete", &format!("/Groups/{groupname}"), "users"])
|
||||||
|
.arg(&name)
|
||||||
|
.stdin(std::process::Stdio::null()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ActionError::Command(e))?;
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
execute_command(
|
||||||
|
Command::new("gpasswd")
|
||||||
|
.process_group(0)
|
||||||
|
.args(["-d"])
|
||||||
|
.args([&name.to_string(), &groupname.to_string()])
|
||||||
|
.stdin(std::process::Stdio::null()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ActionError::Command(e))?;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -133,16 +133,14 @@ impl Action for CreateGroup {
|
||||||
patch: _,
|
patch: _,
|
||||||
}
|
}
|
||||||
| OperatingSystem::Darwin => {
|
| OperatingSystem::Darwin => {
|
||||||
// TODO(@hoverbear): Make this actually work...
|
let output = execute_command(
|
||||||
// Right now, our test machines do not have a secure token and cannot delete users.
|
Command::new("/usr/bin/dscl")
|
||||||
tracing::warn!("`nix-installer` currently cannot delete groups on Mac due to https://github.com/DeterminateSystems/nix-installer/issues/33. This is a no-op, installing with `nix-installer` again will use the existing group.");
|
.args([".", "-delete", &format!("/Groups/{name}")])
|
||||||
// execute_command(Command::new("/usr/bin/dscl").args([
|
.stdin(std::process::Stdio::null()),
|
||||||
// ".",
|
)
|
||||||
// "-delete",
|
.await
|
||||||
// &format!("/Groups/{name}"),
|
.map_err(|e| ActionError::Command(e))?;
|
||||||
// ]).stdin(std::process::Stdio::null()))
|
if !output.status.success() {}
|
||||||
// .await
|
|
||||||
// .map_err(|e| CreateGroupError::Command(e).boxed())?;
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
execute_command(
|
execute_command(
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub struct CreateUser {
|
||||||
|
|
||||||
impl CreateUser {
|
impl CreateUser {
|
||||||
#[tracing::instrument(level = "debug", skip_all)]
|
#[tracing::instrument(level = "debug", skip_all)]
|
||||||
pub fn plan(
|
pub async fn plan(
|
||||||
name: String,
|
name: String,
|
||||||
uid: u32,
|
uid: u32,
|
||||||
groupname: String,
|
groupname: String,
|
||||||
|
@ -51,9 +51,6 @@ impl CreateUser {
|
||||||
gid,
|
gid,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
tracing::debug!("Creating user `{}` already complete", this.name);
|
|
||||||
return Ok(StatefulAction::completed(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(StatefulAction::uncompleted(this))
|
Ok(StatefulAction::uncompleted(this))
|
||||||
|
@ -95,7 +92,7 @@ impl Action for CreateUser {
|
||||||
let Self {
|
let Self {
|
||||||
name,
|
name,
|
||||||
uid,
|
uid,
|
||||||
groupname,
|
groupname: _,
|
||||||
gid,
|
gid,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
|
@ -171,20 +168,6 @@ impl Action for CreateUser {
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ActionError::Command(e))?;
|
.map_err(|e| ActionError::Command(e))?;
|
||||||
execute_command(
|
|
||||||
Command::new("/usr/bin/dscl")
|
|
||||||
.process_group(0)
|
|
||||||
.args([
|
|
||||||
".",
|
|
||||||
"-append",
|
|
||||||
&format!("/Groups/{groupname}"),
|
|
||||||
"GroupMembership",
|
|
||||||
])
|
|
||||||
.arg(&name)
|
|
||||||
.stdin(std::process::Stdio::null()),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map_err(|e| ActionError::Command(e))?;
|
|
||||||
execute_command(
|
execute_command(
|
||||||
Command::new("/usr/bin/dscl")
|
Command::new("/usr/bin/dscl")
|
||||||
.process_group(0)
|
.process_group(0)
|
||||||
|
@ -193,19 +176,6 @@ impl Action for CreateUser {
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ActionError::Command(e))?;
|
.map_err(|e| ActionError::Command(e))?;
|
||||||
execute_command(
|
|
||||||
Command::new("/usr/sbin/dseditgroup")
|
|
||||||
.process_group(0)
|
|
||||||
.args(["-o", "edit"])
|
|
||||||
.arg("-a")
|
|
||||||
.arg(&name)
|
|
||||||
.arg("-t")
|
|
||||||
.arg(&name)
|
|
||||||
.arg(groupname)
|
|
||||||
.stdin(std::process::Stdio::null()),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map_err(|e| ActionError::Command(e))?;
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
execute_command(
|
execute_command(
|
||||||
|
@ -269,16 +239,44 @@ impl Action for CreateUser {
|
||||||
patch: _,
|
patch: _,
|
||||||
}
|
}
|
||||||
| OperatingSystem::Darwin => {
|
| OperatingSystem::Darwin => {
|
||||||
// TODO(@hoverbear): Make this actually work...
|
// MacOS is a "Special" case
|
||||||
// Right now, our test machines do not have a secure token and cannot delete users.
|
// It's only possible to delete users under certain conditions.
|
||||||
tracing::warn!("`nix-installer` currently cannot delete groups on Mac due to https://github.com/DeterminateSystems/nix-installer/issues/33. This is a no-op, installing with `nix-installer` again will use the existing user.");
|
// Documentation on https://it.megocollector.com/macos/cant-delete-a-macos-user-with-dscl-resolution/ and http://www.aixperts.co.uk/?p=214 suggested it was a secure token
|
||||||
// execute_command(Command::new("/usr/bin/dscl").args([
|
// That is correct, however it's a bit more nuanced. It appears to be that a user must be graphically logged in for some other user on the system to be deleted.
|
||||||
// ".",
|
let mut command = Command::new("/usr/bin/dscl");
|
||||||
// "-delete",
|
command.args([".", "-delete", &format!("/Users/{name}")]);
|
||||||
// &format!("/Users/{name}"),
|
command.process_group(0);
|
||||||
// ]).stdin(std::process::Stdio::null()))
|
command.stdin(std::process::Stdio::null());
|
||||||
// .await
|
|
||||||
// .map_err(|e| CreateUserError::Command(e).boxed())?;
|
let output = command
|
||||||
|
.output()
|
||||||
|
.await
|
||||||
|
.map_err(|e| ActionError::Command(e))?;
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
match output.status.code() {
|
||||||
|
Some(0) => (),
|
||||||
|
Some(40) if stderr.contains("-14120") => {
|
||||||
|
// The user is on an ephemeral Mac, like detsys uses
|
||||||
|
// These Macs cannot always delete users, as sometimes there is no graphical login
|
||||||
|
tracing::warn!("Encountered an exit code 40 with -14120 error while removing user, this is likely because the initial executing user did not have a secure token, or that there was no graphical login session. To delete the user, log in graphically, then run `/usr/bin/dscl . -delete /Users/{name}");
|
||||||
|
},
|
||||||
|
status => {
|
||||||
|
let command_str = format!("{:?}", command.as_std());
|
||||||
|
// Something went wrong
|
||||||
|
return Err(ActionError::Command(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::Other,
|
||||||
|
format!(
|
||||||
|
"Command `{command_str}` failed{}, stderr:\n{}\n",
|
||||||
|
if let Some(status) = status {
|
||||||
|
format!(" {status}")
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
},
|
||||||
|
stderr
|
||||||
|
),
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
execute_command(
|
execute_command(
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//! Base [`Action`](crate::action::Action)s that themselves have no other actions as dependencies
|
//! Base [`Action`](crate::action::Action)s that themselves have no other actions as dependencies
|
||||||
|
|
||||||
|
pub(crate) mod add_user_to_group;
|
||||||
pub(crate) mod create_directory;
|
pub(crate) mod create_directory;
|
||||||
pub(crate) mod create_file;
|
pub(crate) mod create_file;
|
||||||
pub(crate) mod create_group;
|
pub(crate) mod create_group;
|
||||||
|
@ -9,6 +10,7 @@ pub(crate) mod fetch_and_unpack_nix;
|
||||||
pub(crate) mod move_unpacked_nix;
|
pub(crate) mod move_unpacked_nix;
|
||||||
pub(crate) mod setup_default_profile;
|
pub(crate) mod setup_default_profile;
|
||||||
|
|
||||||
|
pub use add_user_to_group::AddUserToGroup;
|
||||||
pub use create_directory::CreateDirectory;
|
pub use create_directory::CreateDirectory;
|
||||||
pub use create_file::CreateFile;
|
pub use create_file::CreateFile;
|
||||||
pub use create_group::CreateGroup;
|
pub use create_group::CreateGroup;
|
||||||
|
|
|
@ -151,9 +151,13 @@ impl Action for SetupDefaultProfile {
|
||||||
return Err(ActionError::Command(std::io::Error::new(
|
return Err(ActionError::Command(std::io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
std::io::ErrorKind::Other,
|
||||||
format!(
|
format!(
|
||||||
"Command `{load_db_command_str}` failed status, stderr:\n{}\n",
|
"Command `{load_db_command_str}` failed{}, stderr:\n{}\n",
|
||||||
String::from_utf8(output.stderr)
|
if let Some(code) = output.status.code() {
|
||||||
.unwrap_or_else(|_e| String::from("<Non-UTF-8>"))
|
format!(" status {code}")
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
},
|
||||||
|
String::from_utf8_lossy(&output.stderr)
|
||||||
),
|
),
|
||||||
)));
|
)));
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
action::{
|
action::{
|
||||||
base::{CreateGroup, CreateUser},
|
base::{AddUserToGroup, CreateGroup, CreateUser},
|
||||||
Action, ActionDescription, ActionError, StatefulAction,
|
Action, ActionDescription, ActionError, StatefulAction,
|
||||||
},
|
},
|
||||||
settings::CommonSettings,
|
settings::CommonSettings,
|
||||||
|
@ -17,6 +17,7 @@ pub struct CreateUsersAndGroups {
|
||||||
nix_build_user_id_base: u32,
|
nix_build_user_id_base: u32,
|
||||||
create_group: StatefulAction<CreateGroup>,
|
create_group: StatefulAction<CreateGroup>,
|
||||||
create_users: Vec<StatefulAction<CreateUser>>,
|
create_users: Vec<StatefulAction<CreateUser>>,
|
||||||
|
add_users_to_groups: Vec<StatefulAction<AddUserToGroup>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CreateUsersAndGroups {
|
impl CreateUsersAndGroups {
|
||||||
|
@ -26,16 +27,28 @@ impl CreateUsersAndGroups {
|
||||||
settings.nix_build_group_name.clone(),
|
settings.nix_build_group_name.clone(),
|
||||||
settings.nix_build_group_id,
|
settings.nix_build_group_id,
|
||||||
)?;
|
)?;
|
||||||
let create_users = (0..settings.nix_build_user_count)
|
let mut create_users = Vec::with_capacity(settings.nix_build_user_count as usize);
|
||||||
.map(|count| {
|
let mut add_users_to_groups = Vec::with_capacity(settings.nix_build_user_count as usize);
|
||||||
|
for index in 0..settings.nix_build_user_count {
|
||||||
|
create_users.push(
|
||||||
CreateUser::plan(
|
CreateUser::plan(
|
||||||
format!("{}{count}", settings.nix_build_user_prefix),
|
format!("{}{index}", settings.nix_build_user_prefix),
|
||||||
settings.nix_build_user_id_base + count,
|
settings.nix_build_user_id_base + index,
|
||||||
settings.nix_build_group_name.clone(),
|
settings.nix_build_group_name.clone(),
|
||||||
settings.nix_build_group_id,
|
settings.nix_build_group_id,
|
||||||
)
|
)
|
||||||
})
|
.await?,
|
||||||
.collect::<Result<_, _>>()?;
|
);
|
||||||
|
add_users_to_groups.push(
|
||||||
|
AddUserToGroup::plan(
|
||||||
|
format!("{}{index}", settings.nix_build_user_prefix),
|
||||||
|
settings.nix_build_user_id_base + index,
|
||||||
|
settings.nix_build_group_name.clone(),
|
||||||
|
settings.nix_build_group_id,
|
||||||
|
)
|
||||||
|
.await?,
|
||||||
|
);
|
||||||
|
}
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
nix_build_user_count: settings.nix_build_user_count,
|
nix_build_user_count: settings.nix_build_user_count,
|
||||||
nix_build_group_name: settings.nix_build_group_name,
|
nix_build_group_name: settings.nix_build_group_name,
|
||||||
|
@ -44,6 +57,7 @@ impl CreateUsersAndGroups {
|
||||||
nix_build_user_id_base: settings.nix_build_user_id_base,
|
nix_build_user_id_base: settings.nix_build_user_id_base,
|
||||||
create_group,
|
create_group,
|
||||||
create_users,
|
create_users,
|
||||||
|
add_users_to_groups,
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
@ -82,6 +96,7 @@ impl Action for CreateUsersAndGroups {
|
||||||
nix_build_user_id_base: _,
|
nix_build_user_id_base: _,
|
||||||
create_group,
|
create_group,
|
||||||
create_users,
|
create_users,
|
||||||
|
add_users_to_groups,
|
||||||
} = &self;
|
} = &self;
|
||||||
|
|
||||||
let mut create_users_descriptions = Vec::new();
|
let mut create_users_descriptions = Vec::new();
|
||||||
|
@ -91,6 +106,13 @@ impl Action for CreateUsersAndGroups {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut add_user_to_group_descriptions = Vec::new();
|
||||||
|
for add_user_to_group in add_users_to_groups {
|
||||||
|
if let Some(val) = add_user_to_group.describe_execute().iter().next() {
|
||||||
|
add_user_to_group_descriptions.push(val.description.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut explanation = vec![
|
let mut explanation = vec![
|
||||||
format!("The Nix daemon requires system users (and a group they share) which it can act as in order to build"),
|
format!("The Nix daemon requires system users (and a group they share) which it can act as in order to build"),
|
||||||
];
|
];
|
||||||
|
@ -98,6 +120,7 @@ impl Action for CreateUsersAndGroups {
|
||||||
explanation.push(val.description.clone())
|
explanation.push(val.description.clone())
|
||||||
}
|
}
|
||||||
explanation.append(&mut create_users_descriptions);
|
explanation.append(&mut create_users_descriptions);
|
||||||
|
explanation.append(&mut add_user_to_group_descriptions);
|
||||||
|
|
||||||
vec![ActionDescription::new(self.tracing_synopsis(), explanation)]
|
vec![ActionDescription::new(self.tracing_synopsis(), explanation)]
|
||||||
}
|
}
|
||||||
|
@ -107,6 +130,7 @@ impl Action for CreateUsersAndGroups {
|
||||||
let Self {
|
let Self {
|
||||||
create_users,
|
create_users,
|
||||||
create_group,
|
create_group,
|
||||||
|
add_users_to_groups,
|
||||||
nix_build_user_count: _,
|
nix_build_user_count: _,
|
||||||
nix_build_group_name: _,
|
nix_build_group_name: _,
|
||||||
nix_build_group_id: _,
|
nix_build_group_id: _,
|
||||||
|
@ -169,6 +193,10 @@ impl Action for CreateUsersAndGroups {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for add_user_to_group in add_users_to_groups.iter_mut() {
|
||||||
|
add_user_to_group.try_execute().await?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,6 +209,7 @@ impl Action for CreateUsersAndGroups {
|
||||||
nix_build_user_id_base: _,
|
nix_build_user_id_base: _,
|
||||||
create_group,
|
create_group,
|
||||||
create_users,
|
create_users,
|
||||||
|
add_users_to_groups,
|
||||||
} = &self;
|
} = &self;
|
||||||
let mut create_users_descriptions = Vec::new();
|
let mut create_users_descriptions = Vec::new();
|
||||||
for create_user in create_users {
|
for create_user in create_users {
|
||||||
|
@ -189,6 +218,13 @@ impl Action for CreateUsersAndGroups {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut add_user_to_group_descriptions = Vec::new();
|
||||||
|
for add_user_to_group in add_users_to_groups {
|
||||||
|
if let Some(val) = add_user_to_group.describe_revert().iter().next() {
|
||||||
|
add_user_to_group_descriptions.push(val.description.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut explanation = vec![
|
let mut explanation = vec![
|
||||||
format!("The Nix daemon requires system users (and a group they share) which it can act as in order to build"),
|
format!("The Nix daemon requires system users (and a group they share) which it can act as in order to build"),
|
||||||
];
|
];
|
||||||
|
@ -196,6 +232,7 @@ impl Action for CreateUsersAndGroups {
|
||||||
explanation.push(val.description.clone())
|
explanation.push(val.description.clone())
|
||||||
}
|
}
|
||||||
explanation.append(&mut create_users_descriptions);
|
explanation.append(&mut create_users_descriptions);
|
||||||
|
explanation.append(&mut add_user_to_group_descriptions);
|
||||||
|
|
||||||
vec![ActionDescription::new(
|
vec![ActionDescription::new(
|
||||||
format!("Remove Nix users and group"),
|
format!("Remove Nix users and group"),
|
||||||
|
@ -208,6 +245,7 @@ impl Action for CreateUsersAndGroups {
|
||||||
let Self {
|
let Self {
|
||||||
create_users,
|
create_users,
|
||||||
create_group,
|
create_group,
|
||||||
|
add_users_to_groups: _,
|
||||||
nix_build_user_count: _,
|
nix_build_user_count: _,
|
||||||
nix_build_group_name: _,
|
nix_build_group_name: _,
|
||||||
nix_build_group_id: _,
|
nix_build_group_id: _,
|
||||||
|
@ -243,6 +281,11 @@ impl Action for CreateUsersAndGroups {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't actually need to do this, when a user is deleted they are removed from groups
|
||||||
|
// for add_user_to_group in add_users_to_groups.iter_mut() {
|
||||||
|
// add_user_to_group.try_revert().await?;
|
||||||
|
// }
|
||||||
|
|
||||||
// Create group
|
// Create group
|
||||||
create_group.try_revert().await?;
|
create_group.try_revert().await?;
|
||||||
|
|
||||||
|
|
|
@ -100,8 +100,13 @@ async fn execute_command(command: &mut Command) -> Result<Output, std::io::Error
|
||||||
false => Err(std::io::Error::new(
|
false => Err(std::io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
std::io::ErrorKind::Other,
|
||||||
format!(
|
format!(
|
||||||
"Command `{command_str}` failed status, stderr:\n{}\n",
|
"Command `{command_str}` failed{}, stderr:\n{}\n",
|
||||||
String::from_utf8(output.stderr).unwrap_or_else(|_e| String::from("<Non-UTF-8>"))
|
if let Some(code) = output.status.code() {
|
||||||
|
format!(" status {code}")
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
},
|
||||||
|
String::from_utf8_lossy(&output.stderr)
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
|
|
290
tests/fixtures/linux/linux.json
vendored
290
tests/fixtures/linux/linux.json
vendored
|
@ -325,6 +325,296 @@
|
||||||
},
|
},
|
||||||
"state": "Uncompleted"
|
"state": "Uncompleted"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"add_users_to_groups": [
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld0",
|
||||||
|
"uid": 3000,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld1",
|
||||||
|
"uid": 3001,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld2",
|
||||||
|
"uid": 3002,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld3",
|
||||||
|
"uid": 3003,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld4",
|
||||||
|
"uid": 3004,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld5",
|
||||||
|
"uid": 3005,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld6",
|
||||||
|
"uid": 3006,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld7",
|
||||||
|
"uid": 3007,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld8",
|
||||||
|
"uid": 3008,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld9",
|
||||||
|
"uid": 3009,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld10",
|
||||||
|
"uid": 3010,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld11",
|
||||||
|
"uid": 3011,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld12",
|
||||||
|
"uid": 3012,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld13",
|
||||||
|
"uid": 3013,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld14",
|
||||||
|
"uid": 3014,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld15",
|
||||||
|
"uid": 3015,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld16",
|
||||||
|
"uid": 3016,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld17",
|
||||||
|
"uid": 3017,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld18",
|
||||||
|
"uid": 3018,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld19",
|
||||||
|
"uid": 3019,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld20",
|
||||||
|
"uid": 3020,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld21",
|
||||||
|
"uid": 3021,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld22",
|
||||||
|
"uid": 3022,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld23",
|
||||||
|
"uid": 3023,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld24",
|
||||||
|
"uid": 3024,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld25",
|
||||||
|
"uid": 3025,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld26",
|
||||||
|
"uid": 3026,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld27",
|
||||||
|
"uid": 3027,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld28",
|
||||||
|
"uid": 3028,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld29",
|
||||||
|
"uid": 3029,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld30",
|
||||||
|
"uid": 3030,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "nixbld31",
|
||||||
|
"uid": 3031,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"state": "Uncompleted"
|
"state": "Uncompleted"
|
||||||
|
|
1549
tests/fixtures/linux/steam-deck.json
vendored
1549
tests/fixtures/linux/steam-deck.json
vendored
File diff suppressed because it is too large
Load diff
304
tests/fixtures/macos/macos.json
vendored
304
tests/fixtures/macos/macos.json
vendored
|
@ -13,7 +13,7 @@
|
||||||
"path": "/etc/synthetic.conf",
|
"path": "/etc/synthetic.conf",
|
||||||
"user": null,
|
"user": null,
|
||||||
"group": null,
|
"group": null,
|
||||||
"mode": 429,
|
"mode": null,
|
||||||
"buf": "nix\n",
|
"buf": "nix\n",
|
||||||
"position": "End"
|
"position": "End"
|
||||||
},
|
},
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
"action": "provision_nix",
|
"action": "provision_nix",
|
||||||
"fetch_nix": {
|
"fetch_nix": {
|
||||||
"action": {
|
"action": {
|
||||||
"url": "https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-aarch64-darwin.tar.xz",
|
"url": "https://releases.nixos.org/nix/nix-2.13.2/nix-2.13.2-aarch64-darwin.tar.xz",
|
||||||
"dest": "/nix/temp-install-dir"
|
"dest": "/nix/temp-install-dir"
|
||||||
},
|
},
|
||||||
"state": "Uncompleted"
|
"state": "Uncompleted"
|
||||||
|
@ -390,6 +390,296 @@
|
||||||
},
|
},
|
||||||
"state": "Uncompleted"
|
"state": "Uncompleted"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"add_users_to_groups": [
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld0",
|
||||||
|
"uid": 300,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld1",
|
||||||
|
"uid": 301,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld2",
|
||||||
|
"uid": 302,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld3",
|
||||||
|
"uid": 303,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld4",
|
||||||
|
"uid": 304,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld5",
|
||||||
|
"uid": 305,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld6",
|
||||||
|
"uid": 306,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld7",
|
||||||
|
"uid": 307,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld8",
|
||||||
|
"uid": 308,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld9",
|
||||||
|
"uid": 309,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld10",
|
||||||
|
"uid": 310,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld11",
|
||||||
|
"uid": 311,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld12",
|
||||||
|
"uid": 312,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld13",
|
||||||
|
"uid": 313,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld14",
|
||||||
|
"uid": 314,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld15",
|
||||||
|
"uid": 315,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld16",
|
||||||
|
"uid": 316,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld17",
|
||||||
|
"uid": 317,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld18",
|
||||||
|
"uid": 318,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld19",
|
||||||
|
"uid": 319,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld20",
|
||||||
|
"uid": 320,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld21",
|
||||||
|
"uid": 321,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld22",
|
||||||
|
"uid": 322,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld23",
|
||||||
|
"uid": 323,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld24",
|
||||||
|
"uid": 324,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld25",
|
||||||
|
"uid": 325,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld26",
|
||||||
|
"uid": 326,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld27",
|
||||||
|
"uid": 327,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld28",
|
||||||
|
"uid": 328,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld29",
|
||||||
|
"uid": 329,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld30",
|
||||||
|
"uid": 330,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": {
|
||||||
|
"name": "_nixbld31",
|
||||||
|
"uid": 331,
|
||||||
|
"groupname": "nixbld",
|
||||||
|
"gid": 3000
|
||||||
|
},
|
||||||
|
"state": "Uncompleted"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"state": "Uncompleted"
|
"state": "Uncompleted"
|
||||||
|
@ -563,7 +853,7 @@
|
||||||
"path": "/etc/bashrc",
|
"path": "/etc/bashrc",
|
||||||
"user": null,
|
"user": null,
|
||||||
"group": null,
|
"group": null,
|
||||||
"mode": 493,
|
"mode": 33060,
|
||||||
"buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
|
"buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
|
||||||
"position": "Beginning"
|
"position": "Beginning"
|
||||||
},
|
},
|
||||||
|
@ -574,7 +864,7 @@
|
||||||
"path": "/etc/zshenv",
|
"path": "/etc/zshenv",
|
||||||
"user": null,
|
"user": null,
|
||||||
"group": null,
|
"group": null,
|
||||||
"mode": 493,
|
"mode": 33060,
|
||||||
"buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
|
"buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
|
||||||
"position": "Beginning"
|
"position": "Beginning"
|
||||||
},
|
},
|
||||||
|
@ -585,7 +875,7 @@
|
||||||
"path": "/etc/bash.bashrc",
|
"path": "/etc/bash.bashrc",
|
||||||
"user": null,
|
"user": null,
|
||||||
"group": null,
|
"group": null,
|
||||||
"mode": 493,
|
"mode": 33060,
|
||||||
"buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
|
"buf": "\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n\n \n",
|
||||||
"position": "Beginning"
|
"position": "Beginning"
|
||||||
},
|
},
|
||||||
|
@ -635,7 +925,7 @@
|
||||||
"user": null,
|
"user": null,
|
||||||
"group": null,
|
"group": null,
|
||||||
"mode": 436,
|
"mode": 436,
|
||||||
"buf": "# Generated by https://github.com/DeterminateSystems/nix-installer, version 0.1.0-unreleased.\n\n\n\nbuild-users-group = nixbld\n\nexperimental-features = nix-command flakes\n\nauto-optimise-store = true\n\nbash-prompt-prefix = (nix:$name)\\040\n",
|
"buf": "# Generated by https://github.com/DeterminateSystems/nix-installer, version 0.3.0.\n\n\n\nbuild-users-group = nixbld\n\nexperimental-features = nix-command flakes\n\nauto-optimise-store = true\n\nbash-prompt-prefix = (nix:$name)\\040\n",
|
||||||
"force": false
|
"force": false
|
||||||
},
|
},
|
||||||
"state": "Uncompleted"
|
"state": "Uncompleted"
|
||||||
|
@ -670,7 +960,7 @@
|
||||||
"nix_build_group_id": 3000,
|
"nix_build_group_id": 3000,
|
||||||
"nix_build_user_prefix": "_nixbld",
|
"nix_build_user_prefix": "_nixbld",
|
||||||
"nix_build_user_id_base": 300,
|
"nix_build_user_id_base": 300,
|
||||||
"nix_package_url": "https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-aarch64-darwin.tar.xz",
|
"nix_package_url": "https://releases.nixos.org/nix/nix-2.13.2/nix-2.13.2-aarch64-darwin.tar.xz",
|
||||||
"extra_conf": [],
|
"extra_conf": [],
|
||||||
"force": false
|
"force": false
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue