Skip to content

Commit

Permalink
Setup channels
Browse files Browse the repository at this point in the history
Add a SetupChannels field to ConfigureNix that:
- Creates $ROOT_HOME/.nix-channels
- Runs `nix-channels --update nixpkgs`

Setting up channels can be disabled with a command line flag or
NIX_INSTALLER_NO_CHANNEL_ADD.
  • Loading branch information
mkenigs committed Jan 18, 2024
1 parent 8a19975 commit 7cbb629
Show file tree
Hide file tree
Showing 7 changed files with 289 additions and 87 deletions.
16 changes: 0 additions & 16 deletions .github/workflows/kiteless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,6 @@ jobs:
- name: Test `nix` with `$GITHUB_PATH`
if: success() || failure()
run: |
# TODO this should be part of the installation process
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$HOME/.nix-channels"
nix-channel --update nixpkgs
nix-shell -p hello --command hello
nix-env --install hello
hello
Expand Down Expand Up @@ -251,10 +247,6 @@ jobs:
- name: Test `nix` with `$GITHUB_PATH`
if: success() || failure()
run: |
# TODO this should be part of the installation process
sudo -i sh -c 'echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$HOME/.nix-channels"'
sudo -i nix-channel --update nixpkgs
sudo -i nix-shell -p hello --command hello
sudo -i nix-env --install hello
sudo -i hello
Expand Down Expand Up @@ -370,10 +362,6 @@ jobs:
- name: Test `nix` with `$GITHUB_PATH`
if: success() || failure()
run: |
# TODO this should be part of the installation process
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$HOME/.nix-channels"
nix-channel --update nixpkgs
nix-shell -p hello --command hello
nix-env --install hello
hello
Expand Down Expand Up @@ -487,10 +475,6 @@ jobs:
- name: Test `nix` with `$GITHUB_PATH`
if: success() || failure()
run: |
# TODO this should be part of the installation process
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$HOME/.nix-channels"
nix-channel --update nixpkgs
nix-shell -p hello --command hello
nix-env --install hello
hello
Expand Down
71 changes: 3 additions & 68 deletions src/action/base/setup_default_profile.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use std::path::PathBuf;

use crate::{
action::{ActionError, ActionErrorKind, ActionTag, StatefulAction},
action::{common::ConfigureNix, ActionError, ActionErrorKind, ActionTag, StatefulAction},
execute_command, set_env,
};

use glob::glob;

use tokio::{io::AsyncWriteExt, process::Command};
use tracing::{span, Span};

Expand Down Expand Up @@ -51,63 +49,8 @@ impl Action for SetupDefaultProfile {

#[tracing::instrument(level = "debug", skip_all)]
async fn execute(&mut self) -> Result<(), ActionError> {
// Find an `nix` package
let nix_pkg_glob = format!("{}/nix-*/store/*-nix-*.*.*", self.unpacked_path.display());
let mut found_nix_pkg = None;
for entry in glob(&nix_pkg_glob).map_err(Self::error)? {
match entry {
Ok(path) => {
// If we are curing, the user may have multiple of these installed
if let Some(_existing) = found_nix_pkg {
return Err(Self::error(SetupDefaultProfileError::MultipleNixPackages))?;
} else {
found_nix_pkg = Some(path);
}
break;
},
Err(_) => continue, /* Ignore it */
};
}
let nix_pkg = if let Some(nix_pkg) = found_nix_pkg {
tokio::fs::read_link(&nix_pkg)
.await
.map_err(|e| ActionErrorKind::ReadSymlink(nix_pkg, e))
.map_err(Self::error)?
} else {
return Err(Self::error(SetupDefaultProfileError::NoNix));
};

// Find an `nss-cacert` package, add it too.
let nss_ca_cert_pkg_glob = format!(
"{}/nix-*/store/*-nss-cacert-*.*",
self.unpacked_path.display()
);
let mut found_nss_ca_cert_pkg = None;
for entry in glob(&nss_ca_cert_pkg_glob).map_err(Self::error)? {
match entry {
Ok(path) => {
// If we are curing, the user may have multiple of these installed
if let Some(_existing) = found_nss_ca_cert_pkg {
return Err(Self::error(
SetupDefaultProfileError::MultipleNssCaCertPackages,
))?;
} else {
found_nss_ca_cert_pkg = Some(path);
}
break;
},
Err(_) => continue, /* Ignore it */
};
}
let nss_ca_cert_pkg = if let Some(nss_ca_cert_pkg) = found_nss_ca_cert_pkg {
tokio::fs::read_link(&nss_ca_cert_pkg)
.await
.map_err(|e| ActionErrorKind::ReadSymlink(nss_ca_cert_pkg, e))
.map_err(Self::error)?
} else {
return Err(Self::error(SetupDefaultProfileError::NoNssCacert));
};

let (nix_pkg, nss_ca_cert_pkg) =
ConfigureNix::find_nix_and_ca_cert(&self.unpacked_path).await?;
let found_nix_paths = glob::glob(&format!("{}/nix-*", self.unpacked_path.display()))
.map_err(Self::error)?
.collect::<Result<Vec<_>, _>>()
Expand Down Expand Up @@ -236,16 +179,8 @@ impl Action for SetupDefaultProfile {
#[non_exhaustive]
#[derive(Debug, thiserror::Error)]
pub enum SetupDefaultProfileError {
#[error("Unarchived Nix store did not appear to include a `nss-cacert` location")]
NoNssCacert,
#[error("Unarchived Nix store did not appear to include a `nix` location")]
NoNix,
#[error("No root home found to place channel configuration in")]
NoRootHome,
#[error("Unarchived Nix store appears to contain multiple `nss-ca-cert` packages, cannot select one")]
MultipleNssCaCertPackages,
#[error("Unarchived Nix store appears to contain multiple `nix` packages, cannot select one")]
MultipleNixPackages,
}

impl From<SetupDefaultProfileError> for ActionErrorKind {
Expand Down
128 changes: 125 additions & 3 deletions src/action/common/configure_nix.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::path::PathBuf;
use std::path::{Path, PathBuf};

use crate::{
action::{
Expand All @@ -9,6 +9,9 @@ use crate::{
planner::ShellProfileLocations,
settings::{CommonSettings, SCRATCH_DIR},
};
use glob::glob;

use crate::action::common::SetupChannels;

use tracing::{span, Instrument, Span};

Expand All @@ -20,6 +23,7 @@ pub struct ConfigureNix {
setup_default_profile: StatefulAction<SetupDefaultProfile>,
configure_shell_profile: Option<StatefulAction<ConfigureShellProfile>>,
place_nix_configuration: StatefulAction<PlaceNixConfiguration>,
setup_channels: Option<StatefulAction<SetupChannels>>,
}

impl ConfigureNix {
Expand Down Expand Up @@ -51,13 +55,83 @@ impl ConfigureNix {
.await
.map_err(Self::error)?;

let setup_channels = if settings.no_channel_add {
None
} else {
Some(
SetupChannels::plan(PathBuf::from(SCRATCH_DIR))
.await
.map_err(Self::error)?,
)
};

Ok(Self {
place_nix_configuration,
setup_default_profile,
configure_shell_profile,
setup_channels,
}
.into())
}

pub async fn find_nix_and_ca_cert(
unpacked_path: &Path,
) -> Result<(PathBuf, PathBuf), ActionError> {
// Find a `nix` package
let nix_pkg_glob = format!("{}/nix-*/store/*-nix-*.*.*", unpacked_path.display());
let mut found_nix_pkg = None;
for entry in glob(&nix_pkg_glob).map_err(Self::error)? {
match entry {
Ok(path) => {
// If we are curing, the user may have multiple of these installed
if let Some(_existing) = found_nix_pkg {
return Err(Self::error(ConfigureNixError::MultipleNixPackages))?;
} else {
found_nix_pkg = Some(path);
}
break;
},
Err(_) => continue, /* Ignore it */
};
}
let nix_pkg = if let Some(nix_pkg) = found_nix_pkg {
tokio::fs::read_link(&nix_pkg)
.await
.map_err(|e| ActionErrorKind::ReadSymlink(nix_pkg, e))
.map_err(Self::error)?
} else {
return Err(Self::error(ConfigureNixError::NoNix));
};

// Find an `nss-cacert` package
let nss_ca_cert_pkg_glob =
format!("{}/nix-*/store/*-nss-cacert-*.*", unpacked_path.display());
let mut found_nss_ca_cert_pkg = None;
for entry in glob(&nss_ca_cert_pkg_glob).map_err(Self::error)? {
match entry {
Ok(path) => {
// If we are curing, the user may have multiple of these installed
if let Some(_existing) = found_nss_ca_cert_pkg {
return Err(Self::error(ConfigureNixError::MultipleNssCaCertPackages))?;
} else {
found_nss_ca_cert_pkg = Some(path);
}
break;
},
Err(_) => continue, /* Ignore it */
};
}
let nss_ca_cert_pkg = if let Some(nss_ca_cert_pkg) = found_nss_ca_cert_pkg {
tokio::fs::read_link(&nss_ca_cert_pkg)
.await
.map_err(|e| ActionErrorKind::ReadSymlink(nss_ca_cert_pkg, e))
.map_err(Self::error)?
} else {
return Err(Self::error(ConfigureNixError::NoNssCacert));
};

Ok((nix_pkg, nss_ca_cert_pkg))
}
}

#[async_trait::async_trait]
Expand All @@ -79,10 +153,14 @@ impl Action for ConfigureNix {
setup_default_profile,
place_nix_configuration,
configure_shell_profile,
setup_channels,
} = &self;

let mut buf = setup_default_profile.describe_execute();
buf.append(&mut place_nix_configuration.describe_execute());
if let Some(setup_channels) = setup_channels {
buf.append(&mut setup_channels.describe_execute());
}
if let Some(configure_shell_profile) = configure_shell_profile {
buf.append(&mut configure_shell_profile.describe_execute());
}
Expand All @@ -95,10 +173,15 @@ impl Action for ConfigureNix {
setup_default_profile,
place_nix_configuration,
configure_shell_profile,
setup_channels,
} = self;

let setup_default_profile_span = tracing::Span::current().clone();
let setup_channels_span = setup_channels
.is_some()
.then(|| setup_default_profile_span.clone());

if let Some(configure_shell_profile) = configure_shell_profile {
let setup_default_profile_span = tracing::Span::current().clone();
let (place_nix_configuration_span, configure_shell_profile_span) = (
setup_default_profile_span.clone(),
setup_default_profile_span.clone(),
Expand Down Expand Up @@ -127,7 +210,6 @@ impl Action for ConfigureNix {
},
)?;
} else {
let setup_default_profile_span = tracing::Span::current().clone();
let place_nix_configuration_span = setup_default_profile_span.clone();
tokio::try_join!(
async move {
Expand All @@ -147,6 +229,18 @@ impl Action for ConfigureNix {
)?;
};

// Keep setup_channels outside try_join to avoid the error:
// SQLite database '/nix/var/nix/db/db.sqlite' is busy
// Presumably there are conflicts with nix commands run in
// setup_default_profile.
if let Some(setup_channels) = setup_channels {
setup_channels
.try_execute()
.instrument(setup_channels_span.unwrap())
.await
.map_err(Self::error)?
}

Ok(())
}

Expand All @@ -155,6 +249,7 @@ impl Action for ConfigureNix {
setup_default_profile,
place_nix_configuration,
configure_shell_profile,
setup_channels,
} = &self;

let mut buf = Vec::default();
Expand All @@ -163,6 +258,9 @@ impl Action for ConfigureNix {
}
buf.append(&mut place_nix_configuration.describe_revert());
buf.append(&mut setup_default_profile.describe_revert());
if let Some(setup_channels) = setup_channels {
buf.append(&mut setup_channels.describe_revert());
}

buf
}
Expand All @@ -181,6 +279,11 @@ impl Action for ConfigureNix {
if let Err(err) = self.setup_default_profile.try_revert().await {
errors.push(err);
}
if let Some(setup_channels) = &mut self.setup_channels {
if let Err(err) = setup_channels.try_revert().await {
errors.push(err);
}
}

if errors.is_empty() {
Ok(())
Expand All @@ -194,3 +297,22 @@ impl Action for ConfigureNix {
}
}
}

#[non_exhaustive]
#[derive(Debug, thiserror::Error)]
pub enum ConfigureNixError {
#[error("Unarchived Nix store did not appear to include a `nss-cacert` location")]
NoNssCacert,
#[error("Unarchived Nix store did not appear to include a `nix` location")]
NoNix,
#[error("Unarchived Nix store appears to contain multiple `nss-ca-cert` packages, cannot select one")]
MultipleNssCaCertPackages,
#[error("Unarchived Nix store appears to contain multiple `nix` packages, cannot select one")]
MultipleNixPackages,
}

impl From<ConfigureNixError> for ActionErrorKind {
fn from(val: ConfigureNixError) -> Self {
ActionErrorKind::Custom(Box::new(val))
}
}
2 changes: 2 additions & 0 deletions src/action/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub(crate) mod create_users_and_groups;
pub(crate) mod delete_users;
pub(crate) mod place_nix_configuration;
pub(crate) mod provision_nix;
pub(crate) mod setup_channels;

pub use configure_init_service::{ConfigureInitService, ConfigureNixDaemonServiceError};
pub use configure_nix::ConfigureNix;
Expand All @@ -17,3 +18,4 @@ pub use create_users_and_groups::CreateUsersAndGroups;
pub use delete_users::DeleteUsersInGroup;
pub use place_nix_configuration::PlaceNixConfiguration;
pub use provision_nix::ProvisionNix;
pub use setup_channels::SetupChannels;
Loading

0 comments on commit 7cbb629

Please sign in to comment.