improve the output of some errors and plans (#66)

* improve the output of some errors and plans

* speeling
This commit is contained in:
Ana Hobden 2022-11-25 11:50:21 -08:00 committed by GitHub
parent 7cc71f1ccd
commit f1d12149de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 115 additions and 71 deletions

View file

@ -29,7 +29,7 @@ impl CreateGroup {
#[typetag::serde(name = "create_group")] #[typetag::serde(name = "create_group")]
impl Action for CreateGroup { impl Action for CreateGroup {
fn tracing_synopsis(&self) -> String { fn tracing_synopsis(&self) -> String {
format!("Create group `{}` with GID `{}`", self.name, self.gid) format!("Create group `{}` (GID {})", self.name, self.gid)
} }
fn execute_description(&self) -> Vec<ActionDescription> { fn execute_description(&self) -> Vec<ActionDescription> {
let Self { let Self {
@ -111,11 +111,11 @@ impl Action for CreateGroup {
fn revert_description(&self) -> Vec<ActionDescription> { fn revert_description(&self) -> Vec<ActionDescription> {
let Self { let Self {
name, name,
gid: _, gid,
action_state: _, action_state: _,
} = &self; } = &self;
vec![ActionDescription::new( vec![ActionDescription::new(
format!("Delete group {name}"), format!("Delete group `{name}` (GID {gid})"),
vec![format!( vec![format!(
"The nix daemon requires a system user group its system users can be part of" "The nix daemon requires a system user group its system users can be part of"
)], )],

View file

@ -34,7 +34,7 @@ impl CreateUser {
impl Action for CreateUser { impl Action for CreateUser {
fn tracing_synopsis(&self) -> String { fn tracing_synopsis(&self) -> String {
format!( format!(
"Create user `{}` with UID `{}` with group `{}` (GID {})", "Create user `{}` (UID {}) in group `{}` (GID {})",
self.name, self.uid, self.groupname, self.gid self.name, self.uid, self.groupname, self.gid
) )
} }
@ -219,16 +219,11 @@ impl Action for CreateUser {
} }
fn revert_description(&self) -> Vec<ActionDescription> { fn revert_description(&self) -> Vec<ActionDescription> {
let Self {
name,
uid,
groupname: _,
gid,
action_state: _,
} = self;
vec![ActionDescription::new( vec![ActionDescription::new(
format!("Delete user {name} with UID {uid} with group {gid}"), format!(
"Delete user `{}` (UID {}) in group {} (GID {})",
self.name, self.uid, self.groupname, self.gid
),
vec![format!( vec![format!(
"The nix daemon requires system users it can act as in order to build" "The nix daemon requires system users it can act as in order to build"
)], )],

View file

@ -176,7 +176,13 @@ pub enum ConfigureShellProfileError {
#[source] #[source]
CreateOrAppendFileError, CreateOrAppendFileError,
), ),
#[error("Multiple errors: {}", .0.iter().map(|v| format!("{v}")).collect::<Vec<_>>().join(" & "))] #[error("Multiple errors: {}", .0.iter().map(|v| {
if let Some(source) = v.source() {
format!("{v} ({source})")
} else {
format!("{v}")
}
}).collect::<Vec<_>>().join(" & "))]
MultipleCreateOrAppendFile(Vec<Box<dyn std::error::Error + Send + Sync>>), MultipleCreateOrAppendFile(Vec<Box<dyn std::error::Error + Send + Sync>>),
#[error("Joining spawned async task")] #[error("Joining spawned async task")]
Join( Join(

View file

@ -56,31 +56,42 @@ impl CreateUsersAndGroup {
#[typetag::serde(name = "create_users_and_group")] #[typetag::serde(name = "create_users_and_group")]
impl Action for CreateUsersAndGroup { impl Action for CreateUsersAndGroup {
fn tracing_synopsis(&self) -> String { fn tracing_synopsis(&self) -> String {
"Create build users and group".to_string() format!(
"Create build users (UID {}-{}) and group (GID {})",
self.nix_build_user_id_base,
self.nix_build_user_id_base + self.daemon_user_count,
self.nix_build_group_id
)
} }
fn execute_description(&self) -> Vec<ActionDescription> { fn execute_description(&self) -> Vec<ActionDescription> {
let Self { let Self {
daemon_user_count, daemon_user_count: _,
nix_build_group_name, nix_build_group_name: _,
nix_build_group_id, nix_build_group_id: _,
nix_build_user_prefix, nix_build_user_prefix: _,
nix_build_user_id_base, nix_build_user_id_base: _,
create_group: _, create_group,
create_users: _, create_users,
action_state: _, action_state: _,
} = &self; } = &self;
vec![ let mut create_users_descriptions = Vec::new();
ActionDescription::new( for create_user in create_users {
self.tracing_synopsis(), if let Some(val) = create_user.describe_execute().iter().next() {
vec![ create_users_descriptions.push(val.description.clone())
}
}
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"),
format!("Create group `{nix_build_group_name}` with uid `{nix_build_group_id}`"), ];
format!("Create {daemon_user_count} users with prefix `{nix_build_user_prefix}` starting at uid `{nix_build_user_id_base}`"), if let Some(val) = create_group.describe_execute().iter().next() {
], explanation.push(val.description.clone())
) }
] explanation.append(&mut create_users_descriptions);
vec![ActionDescription::new(self.tracing_synopsis(), explanation)]
} }
#[tracing::instrument(skip_all, fields( #[tracing::instrument(skip_all, fields(
@ -106,57 +117,83 @@ impl Action for CreateUsersAndGroup {
create_group.try_execute().await?; create_group.try_execute().await?;
// Mac is apparently not threadsafe here... // Mac is apparently not threadsafe here...
use target_lexicon::OperatingSystem;
match OperatingSystem::host() {
OperatingSystem::MacOSX {
major: _,
minor: _,
patch: _,
}
| OperatingSystem::Darwin => {
for create_user in create_users.iter_mut() { for create_user in create_users.iter_mut() {
// let mut create_user_clone = create_user.clone();
// let _abort_handle = set.spawn(async move {
create_user.try_execute().await?; create_user.try_execute().await?;
// Result::<_, CreateUserError>::Ok((idx, create_user_clone)) }
// }); },
_ => {
let mut set = JoinSet::new();
let mut errors: Vec<Box<dyn std::error::Error + Send + Sync>> = Vec::new();
for (idx, create_user) in create_users.iter_mut().enumerate() {
let mut create_user_clone = create_user.clone();
let _abort_handle = set.spawn(async move {
create_user_clone.try_execute().await?;
Result::<_, _>::Ok((idx, create_user_clone))
});
} }
// while let Some(result) = set.join_next().await { while let Some(result) = set.join_next().await {
// match result { match result {
// Ok(Ok((idx, success))) => create_users[idx] = success, Ok(Ok((idx, success))) => create_users[idx] = success,
// Ok(Err(e)) => errors.push(e), Ok(Err(e)) => errors.push(e),
// Err(e) => return Err(e)?, Err(e) => return Err(e)?,
// }; };
// } }
// if !errors.is_empty() { if !errors.is_empty() {
// if errors.len() == 1 { if errors.len() == 1 {
// return Err(errors.into_iter().next().unwrap().into()); return Err(errors.into_iter().next().unwrap().into());
// } else { } else {
// return Err(CreateUsersAndGroupError::CreateUsers(errors)); return Err(CreateUsersAndGroupError::CreateUsers(errors).boxed());
// } }
// } }
},
};
Ok(()) Ok(())
} }
fn revert_description(&self) -> Vec<ActionDescription> { fn revert_description(&self) -> Vec<ActionDescription> {
let Self { let Self {
daemon_user_count, daemon_user_count: _,
nix_build_group_name, nix_build_group_name: _,
nix_build_group_id, nix_build_group_id: _,
nix_build_user_prefix, nix_build_user_prefix: _,
nix_build_user_id_base, nix_build_user_id_base: _,
create_group: _, create_group,
create_users: _, create_users,
action_state: _, action_state: _,
} = &self; } = &self;
if self.action_state == ActionState::Uncompleted { if self.action_state == ActionState::Uncompleted {
vec![] vec![]
} else { } else {
vec![ let mut create_users_descriptions = Vec::new();
ActionDescription::new( for create_user in create_users {
format!("Remove build users and group"), if let Some(val) = create_user.describe_revert().iter().next() {
vec![ create_users_descriptions.push(val.description.clone())
}
}
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"),
format!("Create group `{nix_build_group_name}` with uid `{nix_build_group_id}`"), ];
format!("Create {daemon_user_count} users with prefix `{nix_build_user_prefix}` starting at uid `{nix_build_user_id_base}`"), if let Some(val) = create_group.describe_revert().iter().next() {
], explanation.push(val.description.clone())
) }
] explanation.append(&mut create_users_descriptions);
vec![ActionDescription::new(
format!("Remove Nix users and group"),
explanation,
)]
} }
} }
@ -229,7 +266,13 @@ pub enum CreateUsersAndGroupError {
#[from] #[from]
CreateUserError, CreateUserError,
), ),
#[error("Multiple errors: {}", .0.iter().map(|v| format!("{v}")).collect::<Vec<_>>().join(" & "))] #[error("Multiple errors: {}", .0.iter().map(|v| {
if let Some(source) = v.source() {
format!("{v} ({source})")
} else {
format!("{v}")
}
}).collect::<Vec<_>>().join(" & "))]
CreateUsers(Vec<Box<dyn std::error::Error + Send + Sync>>), CreateUsers(Vec<Box<dyn std::error::Error + Send + Sync>>),
#[error("Creating group")] #[error("Creating group")]
CreateGroup( CreateGroup(