Skip to content

Commit

Permalink
Temporarily write trusted-users specified in --extra-conf to nix.co…
Browse files Browse the repository at this point in the history
…nf _AND_ nix.custom.conf

Cachix relies on the presence of this setting in the system
`/etc/nix/nix.conf` so that it can provide users with a helpful error if
`cachix use`ing a cache would not actually work for them (because only
trusted users can modify the trusted caches and trusted cache signing
keys in their user-specific configuration).
  • Loading branch information
cole-h committed Jan 15, 2025
1 parent 850c2d6 commit 26e34cb
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/action/base/create_or_merge_nix_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::action::{
Action, ActionDescription, ActionError, ActionErrorKind, ActionTag, StatefulAction,
};

pub(crate) const TRUSTED_USERS_CONF_NAME: &str = "trusted-users";
pub(crate) const EXPERIMENTAL_FEATURES_CONF_NAME: &str = "experimental-features";
pub(crate) const EXTRA_EXPERIMENTAL_FEATURES_CONF_NAME: &str = "extra-experimental-features";
/// The `nix.conf` configuration names that are safe to merge.
Expand Down
60 changes: 48 additions & 12 deletions src/action/common/place_nix_configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use url::Url;

use crate::action::base::create_or_merge_nix_config::{
CreateOrMergeNixConfigError, EXPERIMENTAL_FEATURES_CONF_NAME,
EXTRA_EXPERIMENTAL_FEATURES_CONF_NAME,
EXTRA_EXPERIMENTAL_FEATURES_CONF_NAME, TRUSTED_USERS_CONF_NAME,
};
use crate::action::base::{CreateDirectory, CreateOrMergeNixConfig};
use crate::action::{
Expand Down Expand Up @@ -49,14 +49,18 @@ impl PlaceNixConfiguration {
force: bool,
determinate_nix: bool,
) -> Result<StatefulAction<Self>, ActionError> {
let extra_conf = Self::parse_extra_conf(proxy, ssl_cert_file.as_ref(), extra_conf).await?;

let standard_nix_config = if !determinate_nix {
Some(Self::setup_standard_config().await?)
let maybe_trusted_users = extra_conf.settings().get(TRUSTED_USERS_CONF_NAME);

Some(Self::setup_standard_config(maybe_trusted_users).await?)
} else {
None
};

let custom_nix_config =
Self::setup_extra_config(nix_build_group_name, proxy, ssl_cert_file, extra_conf)
Self::setup_extra_config(extra_conf, nix_build_group_name, ssl_cert_file.as_ref())
.await?;

let create_directory = CreateDirectory::plan(NIX_CONF_FOLDER, None, None, 0o0755, force)
Expand Down Expand Up @@ -95,7 +99,9 @@ impl PlaceNixConfiguration {
.into())
}

async fn setup_standard_config() -> Result<nix_config_parser::NixConfig, ActionError> {
async fn setup_standard_config(
maybe_trusted_users: Option<&String>,
) -> Result<nix_config_parser::NixConfig, ActionError> {
let mut nix_config = nix_config_parser::NixConfig::new();
let settings = nix_config.settings_mut();

Expand Down Expand Up @@ -154,13 +160,32 @@ impl PlaceNixConfiguration {
"https://install.determinate.systems/nix-upgrade/stable/universal".to_string(),
);

// NOTE(cole-h): This is a workaround to hopefully unbreak users of Cachix.
// When `cachix use`ing a cache, the Cachix CLI will sanity-check the system configuration
// at `/etc/nix/nix.conf` to ensure that the user doing this will actually be able to
// configure trusted settings (such as `trusted-public-keys`).
// However, because we now write the `--extra-conf` into the `nix.custom.conf` (which is how
// users, including our first-party DeterminateSystems/nix-installer-action, would configure
// the `trusted-users` setting), and Cachix does not currently handle `include`s
// properly[1][2], Cachix bails out thinking that the user is not a trusted user[3] even
// though it is (it's just configured in another file).
//
// [1]: https://github.com/cachix/cachix/issues/680
// [2]: https://github.com/cachix/cachix/pull/681
// [3]: https://github.com/DeterminateSystems/nix-installer/issues/1389
if let Some(trusted_users) = maybe_trusted_users {
settings.insert(
TRUSTED_USERS_CONF_NAME.to_string(),
trusted_users.to_owned(),
);
}

Ok(nix_config)
}

async fn setup_extra_config(
nix_build_group_name: String,
async fn parse_extra_conf(
proxy: Option<Url>,
ssl_cert_file: Option<PathBuf>,
ssl_cert_file: Option<&PathBuf>,
extra_conf: Vec<UrlOrPathOrString>,
) -> Result<nix_config_parser::NixConfig, ActionError> {
let mut extra_conf_text = vec![];
Expand Down Expand Up @@ -216,11 +241,19 @@ impl PlaceNixConfiguration {
}

let extra_conf = extra_conf_text.join("\n");
let mut nix_config = nix_config_parser::NixConfig::parse_string(extra_conf, None)
let nix_config = nix_config_parser::NixConfig::parse_string(extra_conf, None)
.map_err(CreateOrMergeNixConfigError::ParseNixConfig)
.map_err(Self::error)?;

let settings = nix_config.settings_mut();
Ok(nix_config)
}

async fn setup_extra_config(
mut extra_conf: nix_config_parser::NixConfig,
nix_build_group_name: String,
ssl_cert_file: Option<&PathBuf>,
) -> Result<nix_config_parser::NixConfig, ActionError> {
let settings = extra_conf.settings_mut();

if nix_build_group_name != crate::settings::DEFAULT_NIX_BUILD_USER_GROUP_NAME {
settings.insert("build-users-group".to_string(), nix_build_group_name);
Expand Down Expand Up @@ -256,7 +289,7 @@ impl PlaceNixConfiguration {
indexmap::map::Entry::Vacant(_) => {},
}

Ok(nix_config)
Ok(extra_conf)
}
}

Expand Down Expand Up @@ -379,8 +412,7 @@ mod tests {

#[tokio::test]
async fn extra_trusted_no_error() -> eyre::Result<()> {
let nix_config = PlaceNixConfiguration::setup_extra_config(
String::from("foo"),
let extra_conf = PlaceNixConfiguration::parse_extra_conf(
None,
None,
vec![
Expand All @@ -390,6 +422,10 @@ mod tests {
)
.await?;

let nix_config =
PlaceNixConfiguration::setup_extra_config(extra_conf, String::from("foo"), None)
.await?;

assert!(
nix_config
.settings()
Expand Down

0 comments on commit 26e34cb

Please sign in to comment.