forked from lix-project/lix-installer
Integrate nix-config-parser (#263)
Co-authored-by: Ana Hobden <operator@hoverbear.org>
This commit is contained in:
parent
d9dfb3c063
commit
2594316750
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -932,6 +932,16 @@ dependencies = [
|
|||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix-config-parser"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfd0a73a9c5f1f960f435be5ade7dd728d5039e6e92dbd5764f8c3d701491fc1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix-installer"
|
||||
version = "0.4.0"
|
||||
|
@ -947,6 +957,7 @@ dependencies = [
|
|||
"glob",
|
||||
"is_ci",
|
||||
"nix",
|
||||
"nix-config-parser",
|
||||
"os-release",
|
||||
"owo-colors",
|
||||
"plist",
|
||||
|
|
|
@ -57,6 +57,7 @@ uuid = { version = "1.2.2", features = ["serde"] }
|
|||
os-release = { version = "0.1.0", default-features = false, optional = true }
|
||||
is_ci = { version = "1.1.1", default-features = false, optional = true }
|
||||
strum = { version = "0.24.1", features = ["derive"] }
|
||||
nix-config-parser = { version = "0.1.2", features = ["serde"] }
|
||||
|
||||
[dev-dependencies]
|
||||
eyre = { version = "0.6.8", default-features = false, features = [ "track-caller" ] }
|
||||
|
|
685
src/action/base/create_or_merge_nix_config.rs
Normal file
685
src/action/base/create_or_merge_nix_config.rs
Normal file
|
@ -0,0 +1,685 @@
|
|||
use std::{
|
||||
os::unix::fs::PermissionsExt,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use nix_config_parser::NixConfig;
|
||||
use rand::Rng;
|
||||
use tokio::{
|
||||
fs::{remove_file, OpenOptions},
|
||||
io::AsyncWriteExt,
|
||||
};
|
||||
use tracing::{span, Span};
|
||||
|
||||
use crate::action::{Action, ActionDescription, ActionError, ActionTag, StatefulAction};
|
||||
|
||||
/// The `nix.conf` configuration names that are safe to merge.
|
||||
// FIXME(@cole-h): make configurable by downstream users?
|
||||
const MERGEABLE_CONF_NAMES: &[&str] = &["experimental-features"];
|
||||
const NIX_CONF_MODE: u32 = 0o644;
|
||||
const NIX_CONF_COMMENT_CHAR: char = '#';
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum CreateOrMergeNixConfigError {
|
||||
#[error(transparent)]
|
||||
ParseNixConfig(#[from] nix_config_parser::ParseError),
|
||||
#[error("Could not merge Nix configuration for key(s) {}; consider removing them from `{1}` in your editor, or removing your existing configuration with `rm {1}`",
|
||||
.0
|
||||
.iter()
|
||||
.map(|v| format!("`{v}`"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "))]
|
||||
UnmergeableConfig(Vec<String>, std::path::PathBuf),
|
||||
}
|
||||
|
||||
/// Create or merge an existing `nix.conf` at the specified path.
|
||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct CreateOrMergeNixConfig {
|
||||
pub(crate) path: PathBuf,
|
||||
pending_nix_config: NixConfig,
|
||||
}
|
||||
|
||||
impl CreateOrMergeNixConfig {
|
||||
#[tracing::instrument(level = "debug", skip_all)]
|
||||
pub async fn plan(
|
||||
path: impl AsRef<Path>,
|
||||
pending_nix_config: NixConfig,
|
||||
) -> Result<StatefulAction<Self>, ActionError> {
|
||||
let path = path.as_ref().to_path_buf();
|
||||
|
||||
let this = Self {
|
||||
path,
|
||||
pending_nix_config,
|
||||
};
|
||||
|
||||
if this.path.exists() {
|
||||
let (merged_nix_config, _) =
|
||||
Self::validate_existing_nix_config(&this.pending_nix_config, &this.path)?;
|
||||
|
||||
if !merged_nix_config.settings().is_empty() {
|
||||
return Ok(StatefulAction::uncompleted(this));
|
||||
} else {
|
||||
tracing::debug!(
|
||||
"Setting Nix configurations in `{}` already complete",
|
||||
this.path.display()
|
||||
);
|
||||
return Ok(StatefulAction::completed(this));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(StatefulAction::uncompleted(this))
|
||||
}
|
||||
|
||||
fn merge_pending_and_existing_nix_config(
|
||||
pending_nix_config: &NixConfig,
|
||||
existing_nix_config: &NixConfig,
|
||||
path: &Path,
|
||||
) -> Result<(NixConfig, NixConfig), CreateOrMergeNixConfigError> {
|
||||
let mut merged_nix_config = NixConfig::new();
|
||||
let mut unmergeable_config_names = Vec::new();
|
||||
|
||||
for (pending_conf_name, pending_conf_value) in pending_nix_config.settings() {
|
||||
if let Some(existing_conf_value) = existing_nix_config.settings().get(pending_conf_name)
|
||||
{
|
||||
let pending_conf_value = pending_conf_value.split(' ').collect::<Vec<_>>();
|
||||
let existing_conf_value = existing_conf_value.split(' ').collect::<Vec<_>>();
|
||||
|
||||
if pending_conf_value
|
||||
.iter()
|
||||
.all(|e| existing_conf_value.contains(e))
|
||||
{
|
||||
// If _all_ the values we want are present in the existing config,
|
||||
// merged_nix_config will be empty and this will be marked as completed. We
|
||||
// don't return early here because there may be more config options to
|
||||
// check.
|
||||
} else if MERGEABLE_CONF_NAMES.contains(&pending_conf_name.as_str()) {
|
||||
let mut merged_conf_value =
|
||||
Vec::with_capacity(pending_conf_value.len() + existing_conf_value.len());
|
||||
merged_conf_value.extend(pending_conf_value);
|
||||
merged_conf_value.extend(existing_conf_value);
|
||||
merged_conf_value.dedup();
|
||||
let merged_conf_value = merged_conf_value.join(" ");
|
||||
let merged_conf_value = merged_conf_value.trim();
|
||||
|
||||
merged_nix_config
|
||||
.settings_mut()
|
||||
.insert(pending_conf_name.to_owned(), merged_conf_value.to_owned());
|
||||
} else {
|
||||
unmergeable_config_names.push(pending_conf_name.to_owned());
|
||||
}
|
||||
} else {
|
||||
merged_nix_config
|
||||
.settings_mut()
|
||||
.insert(pending_conf_name.to_owned(), pending_conf_value.to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
if !unmergeable_config_names.is_empty() {
|
||||
return Err(CreateOrMergeNixConfigError::UnmergeableConfig(
|
||||
unmergeable_config_names,
|
||||
path.to_path_buf(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok((merged_nix_config, existing_nix_config.clone()))
|
||||
}
|
||||
|
||||
fn validate_existing_nix_config(
|
||||
pending_nix_config: &NixConfig,
|
||||
path: &Path,
|
||||
) -> Result<(NixConfig, NixConfig), ActionError> {
|
||||
let path = path.to_path_buf();
|
||||
let metadata = path
|
||||
.metadata()
|
||||
.map_err(|e| ActionError::GettingMetadata(path.clone(), e))?;
|
||||
|
||||
if !metadata.is_file() {
|
||||
return Err(ActionError::PathWasNotFile(path));
|
||||
}
|
||||
|
||||
// Does the file have the right permissions?
|
||||
let discovered_mode = metadata.permissions().mode();
|
||||
// We only care about user-group-other permissions
|
||||
let discovered_mode = discovered_mode & 0o777;
|
||||
|
||||
if discovered_mode != NIX_CONF_MODE {
|
||||
return Err(ActionError::PathModeMismatch(
|
||||
path,
|
||||
discovered_mode,
|
||||
NIX_CONF_MODE,
|
||||
));
|
||||
}
|
||||
|
||||
let existing_nix_config = NixConfig::parse_file(&path)
|
||||
.map_err(CreateOrMergeNixConfigError::ParseNixConfig)
|
||||
.map_err(|e| ActionError::Custom(Box::new(e)))?;
|
||||
|
||||
let (merged_nix_config, existing_nix_config) = Self::merge_pending_and_existing_nix_config(
|
||||
&pending_nix_config,
|
||||
&existing_nix_config,
|
||||
&path,
|
||||
)
|
||||
.map_err(|e| ActionError::Custom(Box::new(e)))?;
|
||||
|
||||
Ok((merged_nix_config, existing_nix_config))
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
#[typetag::serde(name = "create_or_merge_nix_config")]
|
||||
impl Action for CreateOrMergeNixConfig {
|
||||
fn action_tag() -> ActionTag {
|
||||
ActionTag("create_or_merge_nix_config")
|
||||
}
|
||||
fn tracing_synopsis(&self) -> String {
|
||||
format!(
|
||||
"Merge or create nix.conf file `{path}`",
|
||||
path = self.path.display(),
|
||||
)
|
||||
}
|
||||
|
||||
fn tracing_span(&self) -> Span {
|
||||
let span = span!(
|
||||
tracing::Level::DEBUG,
|
||||
"create_or_merge_nix_config",
|
||||
path = tracing::field::display(self.path.display()),
|
||||
mode = tracing::field::display(format!("{:#o}", NIX_CONF_MODE)),
|
||||
pending_nix_config = tracing::field::Empty,
|
||||
);
|
||||
|
||||
if tracing::enabled!(tracing::Level::TRACE) {
|
||||
span.record(
|
||||
"pending_nix_config",
|
||||
&self
|
||||
.pending_nix_config
|
||||
.settings()
|
||||
.iter()
|
||||
.map(|(k, v)| format!("{k}=\"{v}\""))
|
||||
.collect::<Vec<_>>()
|
||||
.join(","),
|
||||
);
|
||||
}
|
||||
span
|
||||
}
|
||||
|
||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||
vec![ActionDescription::new(
|
||||
self.tracing_synopsis(),
|
||||
vec![format!(
|
||||
"Added settings: {settings}",
|
||||
settings = self
|
||||
.pending_nix_config
|
||||
.settings()
|
||||
.iter()
|
||||
.map(|(k, v)| format!("{k}=\"{v}\""))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
)],
|
||||
)]
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all)]
|
||||
async fn execute(&mut self) -> Result<(), ActionError> {
|
||||
let Self {
|
||||
path,
|
||||
pending_nix_config,
|
||||
} = self;
|
||||
|
||||
if tracing::enabled!(tracing::Level::TRACE) {
|
||||
let span = tracing::Span::current();
|
||||
span.record(
|
||||
"pending_nix_config",
|
||||
pending_nix_config
|
||||
.settings()
|
||||
.iter()
|
||||
.map(|(k, v)| format!("{k}='{v}'"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" "),
|
||||
);
|
||||
}
|
||||
|
||||
// Create a temporary file in the same directory as the one
|
||||
// that the final file goes in, so that we can rename it
|
||||
// atomically
|
||||
let parent_dir = path.parent().expect("File must be in a directory");
|
||||
let mut temp_file_path = parent_dir.to_owned();
|
||||
{
|
||||
let mut rng = rand::thread_rng();
|
||||
temp_file_path.push(format!("nix-installer-tmp.{}", rng.gen::<u32>()));
|
||||
}
|
||||
let mut temp_file = OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
// If the file is created, ensure that it has harmless
|
||||
// permissions regardless of whether the mode will be
|
||||
// changed later (if we ever create setuid executables,
|
||||
// they should only become setuid once they are owned by
|
||||
// the appropriate user)
|
||||
.mode(0o600)
|
||||
.open(&temp_file_path)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
ActionError::Open(temp_file_path.clone(), e)
|
||||
})?;
|
||||
|
||||
let (mut merged_nix_config, mut existing_nix_config) = if path.exists() {
|
||||
let (merged_nix_config, existing_nix_config) =
|
||||
Self::validate_existing_nix_config(&pending_nix_config, &path)?;
|
||||
(merged_nix_config, Some(existing_nix_config))
|
||||
} else {
|
||||
(pending_nix_config.clone(), None)
|
||||
};
|
||||
|
||||
let mut new_config = String::new();
|
||||
|
||||
if let Some(existing_nix_config) = existing_nix_config.as_mut() {
|
||||
let mut discovered_buf = tokio::fs::read_to_string(&path)
|
||||
.await
|
||||
.map_err(|e| ActionError::Read(path.to_path_buf(), e))?;
|
||||
|
||||
// We append a newline to ensure that, in the case there are comments at the end of the
|
||||
// file and _NO_ trailing newline, we still preserve the entire block of comments.
|
||||
discovered_buf.push('\n');
|
||||
|
||||
let (associated_lines, _, _) = discovered_buf.split('\n').fold(
|
||||
(Vec::new(), Vec::new(), false),
|
||||
|(mut all_assoc, mut current_assoc, mut associating): (
|
||||
Vec<Vec<String>>,
|
||||
Vec<String>,
|
||||
bool,
|
||||
),
|
||||
line| {
|
||||
let line = line.trim();
|
||||
|
||||
// Don't associate our "Generated by" comment if it appears
|
||||
if line.starts_with("# Generated by") {
|
||||
return (all_assoc, current_assoc, associating);
|
||||
}
|
||||
|
||||
if line.starts_with(NIX_CONF_COMMENT_CHAR) {
|
||||
associating = true;
|
||||
} else if line.is_empty() || !line.starts_with(NIX_CONF_COMMENT_CHAR) {
|
||||
associating = false;
|
||||
}
|
||||
|
||||
current_assoc.push(line.to_string());
|
||||
|
||||
if !associating {
|
||||
all_assoc.push(current_assoc);
|
||||
current_assoc = Vec::new();
|
||||
}
|
||||
|
||||
(all_assoc, current_assoc, associating)
|
||||
},
|
||||
);
|
||||
|
||||
for line_group in associated_lines {
|
||||
if line_group.is_empty() || line_group.iter().all(|line| line.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// This expect should never reasonably panic, because we would need a line group
|
||||
// consisting solely of a comment and nothing else, but unconditionally appending a
|
||||
// newline to the config string before grouping above prevents this from occurring.
|
||||
let line_idx = line_group
|
||||
.iter()
|
||||
.position(|line| !line.starts_with(NIX_CONF_COMMENT_CHAR))
|
||||
.expect("There should always be one line without a comment character");
|
||||
|
||||
let setting_line = &line_group[line_idx];
|
||||
let comments = line_group[..line_idx].join("\n");
|
||||
|
||||
// If we're here, but the line without a comment char is empty, we have
|
||||
// standalone comments to preserve, but no settings with inline comments.
|
||||
if setting_line.is_empty() {
|
||||
for line in &line_group {
|
||||
new_config.push_str(&line);
|
||||
new_config.push('\n');
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Preserve inline comments for settings we've merged
|
||||
let to_remove = if let Some((name, value)) = existing_nix_config
|
||||
.settings()
|
||||
.iter()
|
||||
.find(|(name, _value)| setting_line.starts_with(*name))
|
||||
{
|
||||
let inline_comment_idx =
|
||||
if let Some(idx) = setting_line.find(NIX_CONF_COMMENT_CHAR) {
|
||||
idx
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let inline_comment = &setting_line[inline_comment_idx..];
|
||||
|
||||
new_config.push_str(&comments);
|
||||
new_config.push('\n');
|
||||
new_config.push_str(name);
|
||||
new_config.push_str(" = ");
|
||||
|
||||
if let Some(merged_value) = merged_nix_config.settings_mut().remove(name) {
|
||||
new_config.push_str(&merged_value);
|
||||
new_config.push(' ');
|
||||
} else {
|
||||
new_config.push_str(value);
|
||||
}
|
||||
|
||||
new_config.push_str(inline_comment);
|
||||
new_config.push('\n');
|
||||
|
||||
Some(name.clone())
|
||||
} else {
|
||||
new_config.push_str(&comments);
|
||||
new_config.push('\n');
|
||||
new_config.push_str(setting_line);
|
||||
new_config.push('\n');
|
||||
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(to_remove) = to_remove {
|
||||
existing_nix_config.settings_mut().remove(&to_remove);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the leftover existing nix config
|
||||
for (name, value) in existing_nix_config.settings() {
|
||||
if merged_nix_config.settings().get(name).is_some() {
|
||||
continue;
|
||||
}
|
||||
|
||||
new_config.push_str(name);
|
||||
new_config.push_str(" = ");
|
||||
new_config.push_str(value);
|
||||
new_config.push('\n');
|
||||
}
|
||||
|
||||
new_config.push('\n');
|
||||
}
|
||||
|
||||
new_config.push_str(&format!(
|
||||
"# Generated by https://github.com/DeterminateSystems/nix-installer, version {version}.\n",
|
||||
version = env!("CARGO_PKG_VERSION"),
|
||||
));
|
||||
|
||||
for (name, value) in merged_nix_config.settings() {
|
||||
new_config.push_str(name);
|
||||
new_config.push_str(" = ");
|
||||
new_config.push_str(value);
|
||||
new_config.push('\n');
|
||||
}
|
||||
|
||||
temp_file
|
||||
.write_all(new_config.as_bytes())
|
||||
.await
|
||||
.map_err(|e| ActionError::Write(temp_file_path.clone(), e))?;
|
||||
tokio::fs::set_permissions(&temp_file_path, PermissionsExt::from_mode(NIX_CONF_MODE))
|
||||
.await
|
||||
.map_err(|e| ActionError::SetPermissions(NIX_CONF_MODE, path.to_owned(), e))?;
|
||||
tokio::fs::rename(&temp_file_path, &path)
|
||||
.await
|
||||
.map_err(|e| ActionError::Rename(temp_file_path.to_owned(), path.to_owned(), e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn revert_description(&self) -> Vec<ActionDescription> {
|
||||
let Self {
|
||||
path,
|
||||
pending_nix_config: _,
|
||||
} = &self;
|
||||
|
||||
vec![ActionDescription::new(
|
||||
format!("Delete file `{}`", path.display()),
|
||||
vec![format!("Delete file `{}`", path.display())],
|
||||
)]
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all)]
|
||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||
let Self {
|
||||
path,
|
||||
pending_nix_config: _,
|
||||
} = self;
|
||||
|
||||
remove_file(&path)
|
||||
.await
|
||||
.map_err(|e| ActionError::Remove(path.to_owned(), e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use eyre::eyre;
|
||||
use tokio::fs::write;
|
||||
|
||||
#[tokio::test]
|
||||
async fn creates_and_deletes_file() -> eyre::Result<()> {
|
||||
let temp_dir = tempfile::TempDir::new()?;
|
||||
let test_file = temp_dir.path().join("creates_and_deletes_file");
|
||||
let mut nix_config = NixConfig::new();
|
||||
nix_config
|
||||
.settings_mut()
|
||||
.insert("experimental-features".into(), "ca-references".into());
|
||||
let mut action = CreateOrMergeNixConfig::plan(&test_file, nix_config).await?;
|
||||
|
||||
action.try_execute().await?;
|
||||
|
||||
let s = std::fs::read_to_string(&test_file)?;
|
||||
assert!(s.contains("# Generated by"));
|
||||
assert!(s.contains("ca-references"));
|
||||
assert!(NixConfig::parse_file(&test_file).is_ok());
|
||||
|
||||
action.try_revert().await?;
|
||||
|
||||
assert!(!test_file.exists(), "File should have been deleted");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn creates_and_deletes_file_even_if_edited() -> eyre::Result<()> {
|
||||
let temp_dir = tempfile::TempDir::new()?;
|
||||
let test_file = temp_dir
|
||||
.path()
|
||||
.join("creates_and_deletes_file_even_if_edited");
|
||||
let mut nix_config = NixConfig::new();
|
||||
nix_config
|
||||
.settings_mut()
|
||||
.insert("experimental-features".into(), "ca-references".into());
|
||||
let mut action = CreateOrMergeNixConfig::plan(&test_file, nix_config).await?;
|
||||
|
||||
action.try_execute().await?;
|
||||
|
||||
write(test_file.as_path(), "More content").await?;
|
||||
|
||||
action.try_revert().await?;
|
||||
|
||||
assert!(!test_file.exists(), "File should have been deleted");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn recognizes_existing_exact_files_and_reverts_them() -> eyre::Result<()> {
|
||||
let temp_dir = tempfile::TempDir::new()?;
|
||||
let test_file = temp_dir
|
||||
.path()
|
||||
.join("recognizes_existing_exact_files_and_reverts_them");
|
||||
|
||||
let test_content = "experimental-features = flakes";
|
||||
write(test_file.as_path(), test_content).await?;
|
||||
tokio::fs::set_permissions(&test_file, PermissionsExt::from_mode(NIX_CONF_MODE)).await?;
|
||||
|
||||
let mut nix_config = NixConfig::new();
|
||||
nix_config
|
||||
.settings_mut()
|
||||
.insert("experimental-features".into(), "flakes".into());
|
||||
let mut action = CreateOrMergeNixConfig::plan(&test_file, nix_config).await?;
|
||||
|
||||
action.try_execute().await?;
|
||||
|
||||
action.try_revert().await?;
|
||||
|
||||
assert!(!test_file.exists(), "File should have been deleted");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn recognizes_existing_different_files_and_merges() -> eyre::Result<()> {
|
||||
let temp_dir = tempfile::TempDir::new()?;
|
||||
let test_file = temp_dir
|
||||
.path()
|
||||
.join("recognizes_existing_different_files_and_merges");
|
||||
|
||||
write(
|
||||
test_file.as_path(),
|
||||
"experimental-features = flakes\nwarn-dirty = true\n",
|
||||
)
|
||||
.await?;
|
||||
tokio::fs::set_permissions(&test_file, PermissionsExt::from_mode(NIX_CONF_MODE)).await?;
|
||||
|
||||
let mut nix_config = NixConfig::new();
|
||||
nix_config
|
||||
.settings_mut()
|
||||
.insert("experimental-features".into(), "nix-command flakes".into());
|
||||
nix_config
|
||||
.settings_mut()
|
||||
.insert("allow-dirty".into(), "false".into());
|
||||
let mut action = CreateOrMergeNixConfig::plan(&test_file, nix_config).await?;
|
||||
|
||||
action.try_execute().await?;
|
||||
|
||||
let s = std::fs::read_to_string(&test_file)?;
|
||||
assert!(s.contains("# Generated by"));
|
||||
assert!(s.contains("flakes"));
|
||||
assert!(s.contains("nix-command"));
|
||||
assert_eq!(
|
||||
s.matches("flakes").count(),
|
||||
1,
|
||||
"we should not duplicate strings"
|
||||
);
|
||||
assert!(s.contains("allow-dirty = false"));
|
||||
assert!(s.contains("warn-dirty = true"));
|
||||
assert!(NixConfig::parse_file(&test_file).is_ok());
|
||||
|
||||
action.try_revert().await?;
|
||||
|
||||
assert!(!test_file.exists(), "File should have been deleted");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn recognizes_existing_different_files_and_fails_to_merge() -> eyre::Result<()> {
|
||||
let temp_dir = tempfile::TempDir::new()?;
|
||||
let test_file = temp_dir
|
||||
.path()
|
||||
.join("recognizes_existing_different_files_and_fails_to_merge");
|
||||
|
||||
write(
|
||||
test_file.as_path(),
|
||||
"experimental-features = flakes\nwarn-dirty = true\n",
|
||||
)
|
||||
.await?;
|
||||
|
||||
let mut nix_config = NixConfig::new();
|
||||
nix_config
|
||||
.settings_mut()
|
||||
.insert("experimental-features".into(), "nix-command flakes".into());
|
||||
nix_config
|
||||
.settings_mut()
|
||||
.insert("warn-dirty".into(), "false".into());
|
||||
match CreateOrMergeNixConfig::plan(&test_file, nix_config).await {
|
||||
Err(ActionError::Custom(e)) => match e.downcast_ref::<CreateOrMergeNixConfigError>() {
|
||||
Some(CreateOrMergeNixConfigError::UnmergeableConfig(_, path)) => {
|
||||
assert_eq!(path, test_file.as_path())
|
||||
},
|
||||
_ => {
|
||||
return Err(eyre!(
|
||||
"Should have returned CreateOrMergeNixConfigError::UnmergeableConfig"
|
||||
))
|
||||
},
|
||||
},
|
||||
_ => {
|
||||
return Err(eyre!(
|
||||
"Should have returned CreateOrMergeNixConfigError::UnmergeableConfig"
|
||||
))
|
||||
},
|
||||
}
|
||||
|
||||
assert!(test_file.exists(), "File should not have been deleted");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn preserves_comments() -> eyre::Result<()> {
|
||||
let temp_dir = tempfile::TempDir::new()?;
|
||||
let test_file = temp_dir.path().join("preserves_comments");
|
||||
|
||||
write(
|
||||
test_file.as_path(),
|
||||
"# test 2\n# test\nexperimental-features = flakes # some inline comment about experimental-features\n# the following line should be warn-dirty = true\nwarn-dirty = true # this is an inline comment\n# this is an ungrouped comment\n# this too",
|
||||
)
|
||||
.await?;
|
||||
let mut nix_config = NixConfig::new();
|
||||
nix_config
|
||||
.settings_mut()
|
||||
.insert("experimental-features".into(), "ca-references".into());
|
||||
let mut action = CreateOrMergeNixConfig::plan(&test_file, nix_config).await?;
|
||||
|
||||
action.try_execute().await?;
|
||||
|
||||
let s = std::fs::read_to_string(&test_file)?;
|
||||
assert!(s.contains("# the following line should be warn-dirty = true\nwarn-dirty = true"));
|
||||
assert!(s.contains("# test 2\n# test\nexperimental-features"));
|
||||
assert!(s.contains("# this is an inline comment"));
|
||||
assert!(s.contains("# some inline comment about experimental-features"));
|
||||
assert!(s.contains("# Generated by"));
|
||||
assert!(s.contains("# this is an ungrouped comment\n# this too"));
|
||||
assert!(s.contains("ca-references"));
|
||||
assert!(NixConfig::parse_file(&test_file).is_ok());
|
||||
|
||||
action.try_revert().await?;
|
||||
|
||||
assert!(!test_file.exists(), "File should have been deleted");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn preserves_comments_edge_case() -> eyre::Result<()> {
|
||||
let temp_dir = tempfile::TempDir::new()?;
|
||||
let test_file = temp_dir.path().join("preserves_comments");
|
||||
|
||||
write(test_file.as_path(), " a = b\n c = d# lol\n# e = f").await?;
|
||||
let mut nix_config = NixConfig::new();
|
||||
nix_config
|
||||
.settings_mut()
|
||||
.insert("experimental-features".into(), "ca-references".into());
|
||||
let mut action = CreateOrMergeNixConfig::plan(&test_file, nix_config).await?;
|
||||
|
||||
action.try_execute().await?;
|
||||
|
||||
let s = std::fs::read_to_string(&test_file)?;
|
||||
assert!(s.contains("# Generated by"));
|
||||
assert!(s.contains("ca-references"));
|
||||
assert_eq!(s.matches("a = b").count(), 1);
|
||||
assert!(NixConfig::parse_file(&test_file).is_ok());
|
||||
|
||||
action.try_revert().await?;
|
||||
|
||||
assert!(!test_file.exists(), "File should have been deleted");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ pub(crate) mod create_directory;
|
|||
pub(crate) mod create_file;
|
||||
pub(crate) mod create_group;
|
||||
pub(crate) mod create_or_insert_into_file;
|
||||
pub(crate) mod create_or_merge_nix_config;
|
||||
pub(crate) mod create_user;
|
||||
pub(crate) mod fetch_and_unpack_nix;
|
||||
pub(crate) mod move_unpacked_nix;
|
||||
|
@ -15,6 +16,7 @@ pub use create_directory::CreateDirectory;
|
|||
pub use create_file::CreateFile;
|
||||
pub use create_group::CreateGroup;
|
||||
pub use create_or_insert_into_file::CreateOrInsertIntoFile;
|
||||
pub use create_or_merge_nix_config::CreateOrMergeNixConfig;
|
||||
pub use create_user::CreateUser;
|
||||
pub use fetch_and_unpack_nix::{FetchAndUnpackNix, FetchUrlError};
|
||||
pub use move_unpacked_nix::{MoveUnpackedNix, MoveUnpackedNixError};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use tracing::{span, Span};
|
||||
|
||||
use crate::action::base::{CreateDirectory, CreateFile};
|
||||
use crate::action::base::create_or_merge_nix_config::CreateOrMergeNixConfigError;
|
||||
use crate::action::base::{CreateDirectory, CreateOrMergeNixConfig};
|
||||
use crate::action::{Action, ActionDescription, ActionError, ActionTag, StatefulAction};
|
||||
|
||||
const NIX_CONF_FOLDER: &str = "/etc/nix";
|
||||
|
@ -12,7 +13,7 @@ Place the `/etc/nix.conf` file
|
|||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||
pub struct PlaceNixConfiguration {
|
||||
create_directory: StatefulAction<CreateDirectory>,
|
||||
create_file: StatefulAction<CreateFile>,
|
||||
create_or_merge_nix_config: StatefulAction<CreateOrMergeNixConfig>,
|
||||
}
|
||||
|
||||
impl PlaceNixConfiguration {
|
||||
|
@ -22,34 +23,38 @@ impl PlaceNixConfiguration {
|
|||
extra_conf: Vec<String>,
|
||||
force: bool,
|
||||
) -> Result<StatefulAction<Self>, ActionError> {
|
||||
let buf = format!(
|
||||
"\
|
||||
# Generated by https://github.com/DeterminateSystems/nix-installer, version {version}.\n\
|
||||
\n\
|
||||
{extra_conf}\n\
|
||||
\n\
|
||||
build-users-group = {nix_build_group_name}\n\
|
||||
\n\
|
||||
experimental-features = nix-command flakes\n\
|
||||
\n\
|
||||
auto-optimise-store = true\n\
|
||||
\n\
|
||||
bash-prompt-prefix = (nix:$name)\\040\n\
|
||||
\n\
|
||||
extra-nix-path = nixpkgs=flake:nixpkgs\n\
|
||||
",
|
||||
extra_conf = extra_conf.join("\n"),
|
||||
version = env!("CARGO_PKG_VERSION"),
|
||||
let extra_conf = extra_conf.join("\n");
|
||||
let mut nix_config = nix_config_parser::NixConfig::parse_string(extra_conf, None)
|
||||
.map_err(CreateOrMergeNixConfigError::ParseNixConfig)
|
||||
.map_err(|e| ActionError::Custom(Box::new(e)))?;
|
||||
let settings = nix_config.settings_mut();
|
||||
|
||||
settings.insert("build-users-group".to_string(), nix_build_group_name);
|
||||
settings.insert(
|
||||
"experimental-features".to_string(),
|
||||
"nix-command flakes".to_string(),
|
||||
);
|
||||
settings.insert("auto-optimise-store".to_string(), "true".to_string());
|
||||
settings.insert(
|
||||
"bash-prompt-prefix".to_string(),
|
||||
"(nix:$name)\\040".to_string(),
|
||||
);
|
||||
settings.insert(
|
||||
"extra-nix-path".to_string(),
|
||||
"nixpkgs=flake:nixpkgs".to_string(),
|
||||
);
|
||||
|
||||
let create_directory = CreateDirectory::plan(NIX_CONF_FOLDER, None, None, 0o0755, force)
|
||||
.await
|
||||
.map_err(|e| ActionError::Child(CreateDirectory::action_tag(), Box::new(e)))?;
|
||||
let create_file = CreateFile::plan(NIX_CONF, None, None, 0o0664, buf, force)
|
||||
let create_or_merge_nix_config = CreateOrMergeNixConfig::plan(NIX_CONF, nix_config)
|
||||
.await
|
||||
.map_err(|e| ActionError::Child(CreateFile::action_tag(), Box::new(e)))?;
|
||||
.map_err(|e| {
|
||||
ActionError::Child(CreateOrMergeNixConfig::action_tag(), Box::new(e))
|
||||
})?;
|
||||
Ok(Self {
|
||||
create_directory,
|
||||
create_file,
|
||||
create_or_merge_nix_config,
|
||||
}
|
||||
.into())
|
||||
}
|
||||
|
@ -70,13 +75,24 @@ impl Action for PlaceNixConfiguration {
|
|||
}
|
||||
|
||||
fn execute_description(&self) -> Vec<ActionDescription> {
|
||||
vec![ActionDescription::new(
|
||||
self.tracing_synopsis(),
|
||||
vec![
|
||||
"This file is read by the Nix daemon to set its configuration options at runtime."
|
||||
.to_string(),
|
||||
],
|
||||
)]
|
||||
let Self {
|
||||
create_or_merge_nix_config,
|
||||
create_directory,
|
||||
} = self;
|
||||
|
||||
let mut explanation = vec![
|
||||
"This file is read by the Nix daemon to set its configuration options at runtime."
|
||||
.to_string(),
|
||||
];
|
||||
|
||||
if let Some(val) = create_directory.describe_execute().iter().next() {
|
||||
explanation.push(val.description.clone())
|
||||
}
|
||||
for val in create_or_merge_nix_config.describe_execute().iter() {
|
||||
explanation.push(val.description.clone())
|
||||
}
|
||||
|
||||
vec![ActionDescription::new(self.tracing_synopsis(), explanation)]
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all)]
|
||||
|
@ -85,10 +101,12 @@ impl Action for PlaceNixConfiguration {
|
|||
.try_execute()
|
||||
.await
|
||||
.map_err(|e| ActionError::Child(self.create_directory.action_tag(), Box::new(e)))?;
|
||||
self.create_file
|
||||
self.create_or_merge_nix_config
|
||||
.try_execute()
|
||||
.await
|
||||
.map_err(|e| ActionError::Child(self.create_file.action_tag(), Box::new(e)))?;
|
||||
.map_err(|e| {
|
||||
ActionError::Child(self.create_or_merge_nix_config.action_tag(), Box::new(e))
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -105,10 +123,12 @@ impl Action for PlaceNixConfiguration {
|
|||
|
||||
#[tracing::instrument(level = "debug", skip_all)]
|
||||
async fn revert(&mut self) -> Result<(), ActionError> {
|
||||
self.create_file
|
||||
self.create_or_merge_nix_config
|
||||
.try_revert()
|
||||
.await
|
||||
.map_err(|e| ActionError::Child(self.create_file.action_tag(), Box::new(e)))?;
|
||||
.map_err(|e| {
|
||||
ActionError::Child(self.create_or_merge_nix_config.action_tag(), Box::new(e))
|
||||
})?;
|
||||
self.create_directory
|
||||
.try_revert()
|
||||
.await
|
||||
|
|
29
tests/fixtures/linux/linux.json
vendored
29
tests/fixtures/linux/linux.json
vendored
|
@ -17,7 +17,7 @@
|
|||
"action": "provision_nix",
|
||||
"fetch_nix": {
|
||||
"action": {
|
||||
"url": "https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-x86_64-linux.tar.xz",
|
||||
"url": "https://releases.nixos.org/nix/nix-2.13.2/nix-2.13.2-x86_64-linux.tar.xz",
|
||||
"dest": "/nix/temp-install-dir"
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
|
@ -788,7 +788,7 @@
|
|||
"path": "/etc/bashrc",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 493,
|
||||
"mode": 33188,
|
||||
"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"
|
||||
},
|
||||
|
@ -799,7 +799,7 @@
|
|||
"path": "/etc/profile.d/nix.sh",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 493,
|
||||
"mode": 33188,
|
||||
"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"
|
||||
},
|
||||
|
@ -810,7 +810,7 @@
|
|||
"path": "/etc/zshenv",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 493,
|
||||
"mode": 33188,
|
||||
"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"
|
||||
},
|
||||
|
@ -821,7 +821,7 @@
|
|||
"path": "/etc/bash.bashrc",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 493,
|
||||
"mode": 33188,
|
||||
"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"
|
||||
},
|
||||
|
@ -841,7 +841,7 @@
|
|||
],
|
||||
"create_file": {
|
||||
"action": {
|
||||
"path": "/home/ana/.nix-channels",
|
||||
"path": "/root/.nix-channels",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 436,
|
||||
|
@ -865,14 +865,17 @@
|
|||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
"create_file": {
|
||||
"create_or_merge_nix_config": {
|
||||
"action": {
|
||||
"path": "/etc/nix/nix.conf",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"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",
|
||||
"force": false
|
||||
"pending_nix_config": {
|
||||
"settings": {
|
||||
"bash-prompt-prefix": "(nix:$name)\\040",
|
||||
"build-users-group": "nixbld",
|
||||
"auto-optimise-store": "true",
|
||||
"experimental-features": "nix-command flakes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
}
|
||||
|
@ -906,7 +909,7 @@
|
|||
"nix_build_group_id": 3000,
|
||||
"nix_build_user_prefix": "nixbld",
|
||||
"nix_build_user_id_base": 3000,
|
||||
"nix_package_url": "https://releases.nixos.org/nix/nix-2.12.0/nix-2.12.0-x86_64-linux.tar.xz",
|
||||
"nix_package_url": "https://releases.nixos.org/nix/nix-2.13.2/nix-2.13.2-x86_64-linux.tar.xz",
|
||||
"extra_conf": [],
|
||||
"force": false
|
||||
},
|
||||
|
|
368
tests/fixtures/linux/steam-deck.json
vendored
368
tests/fixtures/linux/steam-deck.json
vendored
|
@ -4,7 +4,7 @@
|
|||
{
|
||||
"action": {
|
||||
"action": "create_directory",
|
||||
"path": "/nix",
|
||||
"path": "/home/nix",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 493,
|
||||
|
@ -12,6 +12,50 @@
|
|||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"action": "create_file",
|
||||
"path": "/etc/systemd/system/nix-directory.service",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 420,
|
||||
"buf": "[Unit]\nDescription=Create a `/nix` directory to be used for bind mounting\nPropagatesStopTo=nix-daemon.service\nPropagatesStopTo=nix.mount\nDefaultDependencies=no\nAfter=grub-recordfail.service\nAfter=steamos-finish-oobe-migration.service\n\n[Service]\nType=oneshot\nExecStart=steamos-readonly disable\nExecStart=mkdir -vp /nix\nExecStart=chmod -v 0755 /nix\nExecStart=chown -v root /nix\nExecStart=chgrp -v root /nix\nExecStart=steamos-readonly enable\nExecStop=steamos-readonly disable\nExecStop=rmdir /nix\nExecStop=steamos-readonly enable\nRemainAfterExit=true\n",
|
||||
"force": false
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"action": "create_file",
|
||||
"path": "/etc/systemd/system/nix.mount",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 420,
|
||||
"buf": "[Unit]\nDescription=Mount `/home/nix` on `/nix`\nPropagatesStopTo=nix-daemon.service\nPropagatesStopTo=nix-directory.service\nAfter=nix-directory.service\nRequires=nix-directory.service\nConditionPathIsDirectory=/nix\nDefaultDependencies=no\nRequiredBy=nix-daemon.service\nRequiredBy=nix-daemon.socket\n\n[Mount]\nWhat=/home/nix\nWhere=/nix\nType=none\nDirectoryMode=0755\nOptions=bind\n",
|
||||
"force": false
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"action": "create_file",
|
||||
"path": "/etc/systemd/system/ensure-symlinked-units-resolve.service",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 420,
|
||||
"buf": "[Unit]\nDescription=Ensure Nix related units which are symlinked resolve\nAfter=nix.mount\nRequires=nix-directory.service\nRequires=nix.mount\nDefaultDependencies=no\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStart=/usr/bin/systemctl daemon-reload\nExecStart=/usr/bin/systemctl restart --no-block nix-daemon.socket\n\n[Install]\nWantedBy=sysinit.target\n",
|
||||
"force": false
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"action": "start_systemd_unit",
|
||||
"unit": "nix.mount",
|
||||
"enable": false
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"action": "provision_nix",
|
||||
|
@ -26,13 +70,13 @@
|
|||
"action": {
|
||||
"nix_build_user_count": 32,
|
||||
"nix_build_group_name": "nixbld",
|
||||
"nix_build_group_id": 3000,
|
||||
"nix_build_group_id": 30000,
|
||||
"nix_build_user_prefix": "nixbld",
|
||||
"nix_build_user_id_base": 3000,
|
||||
"nix_build_user_id_base": 30000,
|
||||
"create_group": {
|
||||
"action": {
|
||||
"name": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
|
@ -40,288 +84,288 @@
|
|||
{
|
||||
"action": {
|
||||
"name": "nixbld0",
|
||||
"uid": 3000,
|
||||
"uid": 30000,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld1",
|
||||
"uid": 3001,
|
||||
"uid": 30001,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld2",
|
||||
"uid": 3002,
|
||||
"uid": 30002,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld3",
|
||||
"uid": 3003,
|
||||
"uid": 30003,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld4",
|
||||
"uid": 3004,
|
||||
"uid": 30004,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld5",
|
||||
"uid": 3005,
|
||||
"uid": 30005,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld6",
|
||||
"uid": 3006,
|
||||
"uid": 30006,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld7",
|
||||
"uid": 3007,
|
||||
"uid": 30007,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld8",
|
||||
"uid": 3008,
|
||||
"uid": 30008,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld9",
|
||||
"uid": 3009,
|
||||
"uid": 30009,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld10",
|
||||
"uid": 3010,
|
||||
"uid": 30010,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld11",
|
||||
"uid": 3011,
|
||||
"uid": 30011,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld12",
|
||||
"uid": 3012,
|
||||
"uid": 30012,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld13",
|
||||
"uid": 3013,
|
||||
"uid": 30013,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld14",
|
||||
"uid": 3014,
|
||||
"uid": 30014,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld15",
|
||||
"uid": 3015,
|
||||
"uid": 30015,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld16",
|
||||
"uid": 3016,
|
||||
"uid": 30016,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld17",
|
||||
"uid": 3017,
|
||||
"uid": 30017,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld18",
|
||||
"uid": 3018,
|
||||
"uid": 30018,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld19",
|
||||
"uid": 3019,
|
||||
"uid": 30019,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld20",
|
||||
"uid": 3020,
|
||||
"uid": 30020,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld21",
|
||||
"uid": 3021,
|
||||
"uid": 30021,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld22",
|
||||
"uid": 3022,
|
||||
"uid": 30022,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld23",
|
||||
"uid": 3023,
|
||||
"uid": 30023,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld24",
|
||||
"uid": 3024,
|
||||
"uid": 30024,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld25",
|
||||
"uid": 3025,
|
||||
"uid": 30025,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld26",
|
||||
"uid": 3026,
|
||||
"uid": 30026,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld27",
|
||||
"uid": 3027,
|
||||
"uid": 30027,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld28",
|
||||
"uid": 3028,
|
||||
"uid": 30028,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld29",
|
||||
"uid": 3029,
|
||||
"uid": 30029,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld30",
|
||||
"uid": 3030,
|
||||
"uid": 30030,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld31",
|
||||
"uid": 3031,
|
||||
"uid": 30031,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
}
|
||||
|
@ -330,288 +374,288 @@
|
|||
{
|
||||
"action": {
|
||||
"name": "nixbld0",
|
||||
"uid": 3000,
|
||||
"uid": 30000,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld1",
|
||||
"uid": 3001,
|
||||
"uid": 30001,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld2",
|
||||
"uid": 3002,
|
||||
"uid": 30002,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld3",
|
||||
"uid": 3003,
|
||||
"uid": 30003,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld4",
|
||||
"uid": 3004,
|
||||
"uid": 30004,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld5",
|
||||
"uid": 3005,
|
||||
"uid": 30005,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld6",
|
||||
"uid": 3006,
|
||||
"uid": 30006,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld7",
|
||||
"uid": 3007,
|
||||
"uid": 30007,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld8",
|
||||
"uid": 3008,
|
||||
"uid": 30008,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld9",
|
||||
"uid": 3009,
|
||||
"uid": 30009,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld10",
|
||||
"uid": 3010,
|
||||
"uid": 30010,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld11",
|
||||
"uid": 3011,
|
||||
"uid": 30011,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld12",
|
||||
"uid": 3012,
|
||||
"uid": 30012,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld13",
|
||||
"uid": 3013,
|
||||
"uid": 30013,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld14",
|
||||
"uid": 3014,
|
||||
"uid": 30014,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld15",
|
||||
"uid": 3015,
|
||||
"uid": 30015,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld16",
|
||||
"uid": 3016,
|
||||
"uid": 30016,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld17",
|
||||
"uid": 3017,
|
||||
"uid": 30017,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld18",
|
||||
"uid": 3018,
|
||||
"uid": 30018,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld19",
|
||||
"uid": 3019,
|
||||
"uid": 30019,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld20",
|
||||
"uid": 3020,
|
||||
"uid": 30020,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld21",
|
||||
"uid": 3021,
|
||||
"uid": 30021,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld22",
|
||||
"uid": 3022,
|
||||
"uid": 30022,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld23",
|
||||
"uid": 3023,
|
||||
"uid": 30023,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld24",
|
||||
"uid": 3024,
|
||||
"uid": 30024,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld25",
|
||||
"uid": 3025,
|
||||
"uid": 30025,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld26",
|
||||
"uid": 3026,
|
||||
"uid": 30026,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld27",
|
||||
"uid": 3027,
|
||||
"uid": 30027,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld28",
|
||||
"uid": 3028,
|
||||
"uid": 30028,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld29",
|
||||
"uid": 3029,
|
||||
"uid": 30029,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld30",
|
||||
"uid": 3030,
|
||||
"uid": 30030,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"name": "nixbld31",
|
||||
"uid": 3031,
|
||||
"uid": 30031,
|
||||
"groupname": "nixbld",
|
||||
"gid": 3000
|
||||
"gid": 30000
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
}
|
||||
|
@ -781,18 +825,7 @@
|
|||
},
|
||||
"configure_shell_profile": {
|
||||
"action": {
|
||||
"create_directories": [
|
||||
{
|
||||
"action": {
|
||||
"path": "/etc/fish/conf.d",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 420,
|
||||
"force_prune_on_revert": false
|
||||
},
|
||||
"state": "Skipped"
|
||||
}
|
||||
],
|
||||
"create_directories": [],
|
||||
"create_or_insert_into_files": [
|
||||
{
|
||||
"action": {
|
||||
|
@ -837,17 +870,6 @@
|
|||
"position": "Beginning"
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"path": "/etc/fish/conf.d/nix.fish",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 33188,
|
||||
"buf": "\n# Nix\nif test -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.fish'\n . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.fish'\nend\n# End Nix\n\n",
|
||||
"position": "Beginning"
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -863,7 +885,7 @@
|
|||
],
|
||||
"create_file": {
|
||||
"action": {
|
||||
"path": "/home/deck/.nix-channels",
|
||||
"path": "/home/ubuntu/.nix-channels",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 436,
|
||||
|
@ -887,14 +909,17 @@
|
|||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
"create_file": {
|
||||
"create_or_merge_nix_config": {
|
||||
"action": {
|
||||
"path": "/etc/nix/nix.conf",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 436,
|
||||
"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
|
||||
"pending_nix_config": {
|
||||
"settings": {
|
||||
"bash-prompt-prefix": "(nix:$name)\\040",
|
||||
"build-users-group": "nixbld",
|
||||
"auto-optimise-store": "true",
|
||||
"experimental-features": "nix-command flakes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
}
|
||||
|
@ -911,10 +936,19 @@
|
|||
"start_daemon": true
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
{
|
||||
"action": {
|
||||
"action": "start_systemd_unit",
|
||||
"unit": "ensure-symlinked-units-resolve.service",
|
||||
"enable": true
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
}
|
||||
],
|
||||
"planner": {
|
||||
"planner": "linux",
|
||||
"planner": "steam-deck",
|
||||
"persistence": "/home/nix",
|
||||
"settings": {
|
||||
"channels": [
|
||||
[
|
||||
|
@ -925,16 +959,12 @@
|
|||
"modify_profile": true,
|
||||
"nix_build_user_count": 32,
|
||||
"nix_build_group_name": "nixbld",
|
||||
"nix_build_group_id": 3000,
|
||||
"nix_build_group_id": 30000,
|
||||
"nix_build_user_prefix": "nixbld",
|
||||
"nix_build_user_id_base": 3000,
|
||||
"nix_build_user_id_base": 30000,
|
||||
"nix_package_url": "https://releases.nixos.org/nix/nix-2.13.2/nix-2.13.2-x86_64-linux.tar.xz",
|
||||
"extra_conf": [],
|
||||
"force": false
|
||||
},
|
||||
"init": {
|
||||
"init": "Systemd",
|
||||
"start_daemon": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
29
tests/fixtures/macos/macos.json
vendored
29
tests/fixtures/macos/macos.json
vendored
|
@ -4,7 +4,7 @@
|
|||
{
|
||||
"action": {
|
||||
"action": "create_apfs_volume",
|
||||
"disk": "disk3",
|
||||
"disk": "disk1",
|
||||
"name": "Nix Store",
|
||||
"case_sensitive": false,
|
||||
"encrypt": true,
|
||||
|
@ -25,14 +25,14 @@
|
|||
},
|
||||
"unmount_volume": {
|
||||
"action": {
|
||||
"disk": "disk3",
|
||||
"disk": "disk1",
|
||||
"name": "Nix Store"
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
"create_volume": {
|
||||
"action": {
|
||||
"disk": "disk3",
|
||||
"disk": "disk1",
|
||||
"name": "Nix Store",
|
||||
"case_sensitive": false
|
||||
},
|
||||
|
@ -46,7 +46,7 @@
|
|||
},
|
||||
"encrypt_volume": {
|
||||
"action": {
|
||||
"disk": "disk3",
|
||||
"disk": "disk1",
|
||||
"name": "Nix Store"
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
|
@ -82,7 +82,7 @@
|
|||
"action": "provision_nix",
|
||||
"fetch_nix": {
|
||||
"action": {
|
||||
"url": "https://releases.nixos.org/nix/nix-2.13.2/nix-2.13.2-aarch64-darwin.tar.xz",
|
||||
"url": "https://releases.nixos.org/nix/nix-2.13.2/nix-2.13.2-x86_64-darwin.tar.xz",
|
||||
"dest": "/nix/temp-install-dir"
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
|
@ -919,14 +919,17 @@
|
|||
},
|
||||
"state": "Uncompleted"
|
||||
},
|
||||
"create_file": {
|
||||
"create_or_merge_nix_config": {
|
||||
"action": {
|
||||
"path": "/etc/nix/nix.conf",
|
||||
"user": null,
|
||||
"group": null,
|
||||
"mode": 436,
|
||||
"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
|
||||
"pending_nix_config": {
|
||||
"settings": {
|
||||
"bash-prompt-prefix": "(nix:$name)\\040",
|
||||
"auto-optimise-store": "true",
|
||||
"build-users-group": "nixbld",
|
||||
"experimental-features": "nix-command flakes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"state": "Uncompleted"
|
||||
}
|
||||
|
@ -960,13 +963,13 @@
|
|||
"nix_build_group_id": 3000,
|
||||
"nix_build_user_prefix": "_nixbld",
|
||||
"nix_build_user_id_base": 300,
|
||||
"nix_package_url": "https://releases.nixos.org/nix/nix-2.13.2/nix-2.13.2-aarch64-darwin.tar.xz",
|
||||
"nix_package_url": "https://releases.nixos.org/nix/nix-2.13.2/nix-2.13.2-x86_64-darwin.tar.xz",
|
||||
"extra_conf": [],
|
||||
"force": false
|
||||
},
|
||||
"encrypt": null,
|
||||
"case_sensitive": false,
|
||||
"volume_label": "Nix Store",
|
||||
"root_disk": "disk3"
|
||||
"root_disk": "disk1"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue