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

Embedding the Nix installer in the binary. #897

Merged
merged 11 commits into from
May 2, 2024
4 changes: 2 additions & 2 deletions .github/workflows/build-x86_64-darwin.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Build x86_64 Darwin

on:
on:
workflow_call:
inputs:
cache-key:
Expand All @@ -11,7 +11,7 @@ on:
jobs:
build-x86_64-darwin:
name: Build x86_64 Darwin
runs-on: macos-latest-large
runs-on: macos-13-large
concurrency: ${{ inputs.cache-key }}
permissions:
id-token: "write"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ jobs:

run-x86_64-darwin:
name: Run x86_64 Darwin
runs-on: macos-latest
runs-on: macos-13
needs: [lints, build-x86_64-darwin]
permissions:
id-token: "write"
Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ $ NIX_BUILD_GROUP_NAME=nixbuilder ./nix-installer install linux-multi --nix-buil

### Upgrading Nix

You can upgrade Nix to the version described in [`DeterminateSystems/nix-upgrade`][nix-upgrade] by running:
You can upgrade Nix to [our currently recommended version of Nix][recommended-nix] by running:

```
sudo -i nix upgrade-nix
Expand Down Expand Up @@ -389,6 +389,9 @@ You'll also need to edit your `.cargo/config.toml` to use `tokio_unstable` as we
rustflags=["--cfg", "tokio_unstable"]
```

You'll also need to set the `NIX_INSTALLER_TARBALL_PATH` environment variable to point to a target-appropriate Nix installation tarball, like nix-2.21.2-aarch64-darwin.tar.xz.
The contents are embedded in the resulting binary instead of downloaded at installation time.

Then it's possible to review the [documentation](https://docs.rs/nix-installer/latest/nix_installer/):

```bash
Expand Down Expand Up @@ -440,7 +443,7 @@ Differing from the upstream [Nix](https://github.com/NixOS/nix) installer script
+ `auto-optimise-store` is set to `true` (On Linux only)
* `extra-nix-path` is set to `nixpkgs=flake:nixpkgs`
* `max-jobs` is set to `auto`
* `upgrade-nix-store-path-url` is set to `https://install.determinate.systems/nix-upgrade/stable/universal`
* `upgrade-nix-store-path-url` is set to `https://install.determinate.systems/nix-upgrade/stable/universal`, to prevent unintentional downgrades.
* an installation receipt (for uninstalling) is stored at `/nix/receipt.json` as well as a copy of the install binary at `/nix/nix-installer`
* `nix-channel --update` is not run, `~/.nix-channels` is not provisioned
* `ssl-cert-file` is set in `/etc/nix/nix.conf` if the `ssl-cert-file` argument is used.
Expand Down Expand Up @@ -495,8 +498,8 @@ You can read the full privacy policy for [Determinate Systems][detsys], the crea
[detsys]: https://determinate.systems/
[diagnosticdata]: https://github.com/DeterminateSystems/nix-installer/blob/f9f927840d532b71f41670382a30cfcbea2d8a35/src/diagnostics.rs#L29-L43
[privacy]: https://determinate.systems/policies/privacy
[recommended-nix]: https://github.com/DeterminateSystems/nix/releases/latest
[systemd]: https://systemd.io
[wslg]: https://github.com/microsoft/wslg
[nixgl]: https://github.com/guibou/nixGL
[Nix]: https://nixos.org
[nix-upgrade]: https://github.com/DeterminateSystems/nix-upgrade/blob/main/versions.nix
46 changes: 39 additions & 7 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
};

nix = {
url = "https://flakehub.com/f/NixOS/nix/=2.21.2.tar.gz";
url = "https://flakehub.com/f/DeterminateSystems/nix/=2.21.2.tar.gz";
# Omitting `inputs.nixpkgs.follows = "nixpkgs";` on purpose
};

Expand Down Expand Up @@ -87,6 +87,8 @@
RUSTFLAGS = "--cfg tokio_unstable";
cargoTestOptions = f: f ++ [ "--all" ];

NIX_INSTALLER_TARBALL_PATH = inputs.nix.tarballs_direct.${final.stdenv.system};

override = { preBuild ? "", ... }: {
preBuild = preBuild + ''
# logRun "cargo clippy --all-targets --all-features -- -D warnings"
Expand Down Expand Up @@ -130,6 +132,7 @@
name = "nix-install-shell";

RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library";
NIX_INSTALLER_TARBALL_PATH = inputs.nix.tarballs_direct.${system};

nativeBuildInputs = with pkgs; [ ];
buildInputs = with pkgs; [
Expand Down
19 changes: 12 additions & 7 deletions src/action/base/fetch_and_unpack_nix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Fetch a URL to the given path
*/
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
pub struct FetchAndUnpackNix {
url_or_path: UrlOrPath,
url_or_path: Option<UrlOrPath>,
dest: PathBuf,
proxy: Option<Url>,
ssl_cert_file: Option<PathBuf>,
Expand All @@ -24,15 +24,15 @@ pub struct FetchAndUnpackNix {
impl FetchAndUnpackNix {
#[tracing::instrument(level = "debug", skip_all)]
pub async fn plan(
url_or_path: UrlOrPath,
url_or_path: Option<UrlOrPath>,
dest: PathBuf,
proxy: Option<Url>,
ssl_cert_file: Option<PathBuf>,
) -> Result<StatefulAction<Self>, ActionError> {
// TODO(@hoverbear): Check URL exists?
// TODO(@hoverbear): Check tempdir exists

if let UrlOrPath::Url(url) = &url_or_path {
if let Some(UrlOrPath::Url(url)) = &url_or_path {
match url.scheme() {
"https" | "http" | "file" => (),
_ => return Err(Self::error(ActionErrorKind::UnknownUrlScheme)),
Expand Down Expand Up @@ -67,14 +67,18 @@ impl Action for FetchAndUnpackNix {
ActionTag("fetch_and_unpack_nix")
}
fn tracing_synopsis(&self) -> String {
format!("Fetch `{}` to `{}`", self.url_or_path, self.dest.display())
if let Some(ref url_or_path) = self.url_or_path {
format!("Fetch `{}` to `{}`", url_or_path, self.dest.display())
} else {
"Extract the bundled Nix".to_string()
}
}

fn tracing_span(&self) -> Span {
let span = span!(
tracing::Level::DEBUG,
"fetch_and_unpack_nix",
url_or_path = tracing::field::display(&self.url_or_path),
url_or_path = self.url_or_path.as_ref().map(tracing::field::display),
proxy = tracing::field::Empty,
ssl_cert_file = tracing::field::Empty,
dest = tracing::field::display(self.dest.display()),
Expand All @@ -98,7 +102,8 @@ impl Action for FetchAndUnpackNix {
#[tracing::instrument(level = "debug", skip_all)]
async fn execute(&mut self) -> Result<(), ActionError> {
let bytes = match &self.url_or_path {
UrlOrPath::Url(url) => {
&None => Bytes::from(crate::settings::NIX_TARBALL),
Some(UrlOrPath::Url(url)) => {
let bytes = match url.scheme() {
"https" | "http" => {
let mut buildable_client = reqwest::Client::builder();
Expand Down Expand Up @@ -144,7 +149,7 @@ impl Action for FetchAndUnpackNix {
};
bytes
},
UrlOrPath::Path(path) => {
Some(UrlOrPath::Path(path)) => {
let buf = tokio::fs::read(path)
.await
.map_err(|e| ActionErrorKind::Read(PathBuf::from(path), e))
Expand Down
61 changes: 7 additions & 54 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,10 @@ use url::Url;

pub const SCRATCH_DIR: &str = "/nix/temp-install-dir";

/// Default [`nix_package_url`](CommonSettings::nix_package_url) for Linux x86_64
pub const NIX_X64_64_LINUX_URL: &str =
"https://releases.nixos.org/nix/nix-2.21.2/nix-2.21.2-x86_64-linux.tar.xz";
/// Default [`nix_package_url`](CommonSettings::nix_package_url) for Linux x86 (32 bit)
pub const NIX_I686_LINUX_URL: &str =
"https://releases.nixos.org/nix/nix-2.21.2/nix-2.21.2-i686-linux.tar.xz";
/// Default [`nix_package_url`](CommonSettings::nix_package_url) for Linux aarch64
pub const NIX_AARCH64_LINUX_URL: &str =
"https://releases.nixos.org/nix/nix-2.21.2/nix-2.21.2-aarch64-linux.tar.xz";
/// Default [`nix_package_url`](CommonSettings::nix_package_url) for Darwin x86_64
pub const NIX_X64_64_DARWIN_URL: &str =
"https://releases.nixos.org/nix/nix-2.21.2/nix-2.21.2-x86_64-darwin.tar.xz";
/// Default [`nix_package_url`](CommonSettings::nix_package_url) for Darwin aarch64
pub const NIX_AARCH64_DARWIN_URL: &str =
"https://releases.nixos.org/nix/nix-2.21.2/nix-2.21.2-aarch64-darwin.tar.xz";
/// The NIX_INSTALLER_TARBALL_PATH environment variable should point to a target-appropriate
/// Nix installation tarball, like nix-2.21.2-aarch64-darwin.tar.xz. The contents are embedded
/// in the resulting binary.
pub const NIX_TARBALL: &[u8] = include_bytes!(env!("NIX_INSTALLER_TARBALL_PATH"));
grahamc marked this conversation as resolved.
Show resolved Hide resolved

#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
Expand Down Expand Up @@ -145,39 +134,9 @@ pub struct CommonSettings {
/// The Nix package URL
#[cfg_attr(
feature = "cli",
clap(long, env = "NIX_INSTALLER_NIX_PACKAGE_URL", global = true, value_parser = clap::value_parser!(UrlOrPath))
clap(long, env = "NIX_INSTALLER_NIX_PACKAGE_URL", global = true, value_parser = clap::value_parser!(UrlOrPath), default_value = None)
)]
#[cfg_attr(
all(target_os = "macos", target_arch = "x86_64", feature = "cli"),
clap(
default_value = NIX_X64_64_DARWIN_URL,
)
)]
#[cfg_attr(
all(target_os = "macos", target_arch = "aarch64", feature = "cli"),
clap(
default_value = NIX_AARCH64_DARWIN_URL,
)
)]
#[cfg_attr(
all(target_os = "linux", target_arch = "x86_64", feature = "cli"),
clap(
default_value = NIX_X64_64_LINUX_URL,
)
)]
#[cfg_attr(
all(target_os = "linux", target_arch = "x86", feature = "cli"),
clap(
default_value = NIX_I686_LINUX_URL,
)
)]
#[cfg_attr(
all(target_os = "linux", target_arch = "aarch64", feature = "cli"),
clap(
default_value = NIX_AARCH64_LINUX_URL,
)
)]
pub nix_package_url: UrlOrPath,
pub nix_package_url: Option<UrlOrPath>,

/// The proxy to use (if any), valid proxy bases are `https://$URL`, `http://$URL` and `socks5://$URL`
#[cfg_attr(feature = "cli", clap(long, env = "NIX_INSTALLER_PROXY"))]
Expand Down Expand Up @@ -250,7 +209,6 @@ pub struct CommonSettings {
impl CommonSettings {
/// The default settings for the given Architecture & Operating System
pub async fn default() -> Result<Self, InstallSettingsError> {
let url;
let nix_build_user_prefix;
let nix_build_user_id_base;
let nix_build_user_count;
Expand All @@ -259,37 +217,32 @@ impl CommonSettings {
match (Architecture::host(), OperatingSystem::host()) {
#[cfg(target_os = "linux")]
(Architecture::X86_64, OperatingSystem::Linux) => {
url = NIX_X64_64_LINUX_URL;
nix_build_user_prefix = "nixbld";
nix_build_user_id_base = 30000;
nix_build_user_count = 32;
},
#[cfg(target_os = "linux")]
(Architecture::X86_32(_), OperatingSystem::Linux) => {
url = NIX_I686_LINUX_URL;
nix_build_user_prefix = "nixbld";
nix_build_user_id_base = 30000;
nix_build_user_count = 32;
},
#[cfg(target_os = "linux")]
(Architecture::Aarch64(_), OperatingSystem::Linux) => {
url = NIX_AARCH64_LINUX_URL;
nix_build_user_prefix = "nixbld";
nix_build_user_id_base = 30000;
nix_build_user_count = 32;
},
#[cfg(target_os = "macos")]
(Architecture::X86_64, OperatingSystem::MacOSX { .. })
| (Architecture::X86_64, OperatingSystem::Darwin) => {
url = NIX_X64_64_DARWIN_URL;
nix_build_user_prefix = "_nixbld";
nix_build_user_id_base = 300;
nix_build_user_count = 32;
},
#[cfg(target_os = "macos")]
(Architecture::Aarch64(_), OperatingSystem::MacOSX { .. })
| (Architecture::Aarch64(_), OperatingSystem::Darwin) => {
url = NIX_AARCH64_DARWIN_URL;
nix_build_user_prefix = "_nixbld";
nix_build_user_id_base = 300;
nix_build_user_count = 32;
Expand All @@ -308,7 +261,7 @@ impl CommonSettings {
nix_build_user_id_base,
nix_build_user_count,
nix_build_user_prefix: nix_build_user_prefix.to_string(),
nix_package_url: url.parse()?,
nix_package_url: None,
proxy: Default::default(),
extra_conf: Default::default(),
force: false,
Expand Down
Loading