Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various fixups #1329

Merged
merged 5 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions src/action/base/add_user_to_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ impl AddUserToGroup {
.await
.map_err(|e| ActionErrorKind::command(&command, e))
.map_err(Self::error)?;
let stderr = String::from_utf8_lossy(&output.stderr);
match output.status.code() {
Some(0) => {
// yes {user} is a member of {groupname}
Expand All @@ -104,15 +105,27 @@ impl AddUserToGroup {
);
return Ok(StatefulAction::completed(this));
},
Some(64) => {
// 64 is the exit code for "Group not found"
// 64 is the exit code for "Group not found" or "Unable to find the user
// record", so we have to disambiguate by checking stderr for this string
Some(64) if stderr.contains("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(67) => {
// 67 is the exit code for "user is not a member of the group", i.e.:
//
// no _nixbld1 is NOT a member of nixbld
tracing::trace!(
"Will add existing user `{}` to existing group `{}`",
this.name,
this.groupname
);
// The user will be added to this group
},
_ => {
// Some other issue
return Err(Self::error(ActionErrorKind::command_output(
Expand Down Expand Up @@ -212,8 +225,6 @@ impl Action for AddUserToGroup {
.args(["-o", "edit"])
.arg("-a")
.arg(&self.name)
.arg("-t")
.arg(&self.name)
.arg(&self.groupname)
.stdin(std::process::Stdio::null()),
)
Expand Down
38 changes: 20 additions & 18 deletions src/action/base/create_user.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::os::unix::process::ExitStatusExt;

use nix::unistd::User;
use target_lexicon::OperatingSystem;
use tokio::process::Command;
Expand Down Expand Up @@ -240,9 +242,7 @@ impl Action for CreateUser {
}

#[tracing::instrument]
pub(crate) async fn execute_command_retry_on_enotyetimplemented(
dscl_args: &[&str],
) -> Result<(), ActionErrorKind> {
async fn execute_dscl_retry_on_specific_errors(dscl_args: &[&str]) -> Result<(), ActionErrorKind> {
let mut retry_tokens: usize = 10;
loop {
let mut command = Command::new("/usr/bin/dscl");
Expand All @@ -267,13 +267,16 @@ pub(crate) async fn execute_command_retry_on_enotyetimplemented(
} else if retry_tokens == 0 {
return Err(ActionErrorKind::command_output(&command, output))?;
} else {
match output.status.code() {
Some(140) if stderr.contains("-14988 (eNotYetImplemented)") => {
// Retry due to buggy macOS user behavior?
// https://github.com/DeterminateSystems/nix-installer/issues/1300
// https://github.com/ansible/ansible/issues/73505
},
_ => return Err(ActionErrorKind::command_output(&command, output)),
if output.status.code() == Some(140) && stderr.contains("-14988 (eNotYetImplemented)") {
// Retry due to buggy macOS user behavior?
// https://github.com/DeterminateSystems/nix-installer/issues/1300
// https://github.com/ansible/ansible/issues/73505
} else if output.status.signal() == Some(9) {
// If the command was SIGKILLed, let's retry and hope it doesn't happen again.
} else {
// If the command failed for a reason that we weren't "expecting", return that as an
// error.
return Err(ActionErrorKind::command_output(&command, output));
}

retry_tokens = retry_tokens.saturating_sub(1);
Expand All @@ -287,50 +290,49 @@ pub(crate) async fn execute_command_retry_on_enotyetimplemented(

#[tracing::instrument(level = "debug", skip_all)]
async fn create_user_macos(name: &str, uid: u32, gid: u32) -> Result<(), ActionErrorKind> {
execute_command_retry_on_enotyetimplemented(&[".", "-create", &format!("/Users/{name}")])
.await?;
execute_dscl_retry_on_specific_errors(&[".", "-create", &format!("/Users/{name}")]).await?;

execute_command_retry_on_enotyetimplemented(&[
execute_dscl_retry_on_specific_errors(&[
".",
"-create",
&format!("/Users/{name}"),
"UniqueID",
&format!("{uid}"),
])
.await?;
execute_command_retry_on_enotyetimplemented(&[
execute_dscl_retry_on_specific_errors(&[
".",
"-create",
&format!("/Users/{name}"),
"PrimaryGroupID",
&format!("{gid}"),
])
.await?;
execute_command_retry_on_enotyetimplemented(&[
execute_dscl_retry_on_specific_errors(&[
".",
"-create",
&format!("/Users/{name}"),
"NFSHomeDirectory",
"/var/empty",
])
.await?;
execute_command_retry_on_enotyetimplemented(&[
execute_dscl_retry_on_specific_errors(&[
".",
"-create",
&format!("/Users/{name}"),
"UserShell",
"/sbin/nologin",
])
.await?;
execute_command_retry_on_enotyetimplemented(&[
execute_dscl_retry_on_specific_errors(&[
".",
"-create",
&format!("/Users/{name}"),
"IsHidden",
"1",
])
.await?;
execute_command_retry_on_enotyetimplemented(&[
execute_dscl_retry_on_specific_errors(&[
".",
"-create",
&format!("/Users/{name}"),
Expand Down
2 changes: 2 additions & 0 deletions src/action/base/setup_default_profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ impl Action for SetupDefaultProfile {
Command::new(nix_pkg.join("bin/nix-env"))
.process_group(0)
.args(["--option", "substitute", "false"])
.args(["--option", "post-build-hook", ""])
.arg("-i")
.arg(&nix_pkg)
.stdin(std::process::Stdio::null())
Expand All @@ -140,6 +141,7 @@ impl Action for SetupDefaultProfile {
Command::new(nix_pkg.join("bin/nix-env"))
.process_group(0)
.args(["--option", "substitute", "false"])
.args(["--option", "post-build-hook", ""])
.arg("-i")
.arg(&nss_ca_cert_pkg)
.stdin(std::process::Stdio::null())
Expand Down
Loading