From 89e611a7385da7e52d99211ce8f9a0d068803059 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Thu, 21 Mar 2024 15:48:51 -0400 Subject: [PATCH] Embed the Nix tarball into the binary This improves built-in offline support, and improves install time reliability. --- flake.lock | 46 +++++++++++++++++--- flake.nix | 5 ++- src/action/base/fetch_and_unpack_nix.rs | 19 +++++--- src/settings.rs | 58 ++----------------------- 4 files changed, 59 insertions(+), 69 deletions(-) diff --git a/flake.lock b/flake.lock index 8f04146f9..9a7c2077e 100644 --- a/flake.lock +++ b/flake.lock @@ -87,6 +87,24 @@ } }, "nix": { + "inputs": { + "nix": "nix_2", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1713457987, + "narHash": "sha256-HNt+ocnqVlwGzYx+3DQRlfv06iSv2I7Ch5kuRH7W7m4=", + "rev": "f59b936e273bc761648b45a9f822693f0424da4d", + "revCount": 56, + "type": "tarball", + "url": "https://api.flakehub.com/f/pinned/DeterminateSystems/nix/2.21.2/018ef218-45b2-731b-8c3b-a9fc57c55fd1/source.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://flakehub.com/f/DeterminateSystems/nix/%3D2.21.2.tar.gz" + } + }, + "nix_2": { "inputs": { "flake-compat": "flake-compat_2", "libgit2": "libgit2", @@ -103,7 +121,7 @@ }, "original": { "type": "tarball", - "url": "https://flakehub.com/f/NixOS/nix/%3D2.21.2.tar.gz" + "url": "https://flakehub.com/f/NixOS/nix/%3D2.21.2" } }, "nixpkgs": { @@ -140,12 +158,26 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1712963716, - "narHash": "sha256-WKm9CvgCldeIVvRz87iOMi8CFVB1apJlkUT4GGvA0iM=", - "rev": "cfd6b5fc90b15709b780a5a1619695a88505a176", - "revCount": 611350, + "lastModified": 1714531828, + "narHash": "sha256-ILsf3bdY/hNNI/Hu5bSt2/KbmHaAVhBbNUOdGztTHEg=", + "rev": "0638fe2715d998fa81d173aad264eb671ce2ebc1", + "revCount": 558121, "type": "tarball", - "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.611350%2Brev-cfd6b5fc90b15709b780a5a1619695a88505a176/018eddfc-e6d9-74bb-a823-20f2ae60079b/source.tar.gz" + "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.2311.558121%2Brev-0638fe2715d998fa81d173aad264eb671ce2ebc1/018f3583-6e0d-7f3d-9871-ca7b6c8c73df/source.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://flakehub.com/f/NixOS/nixpkgs/%2A" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1710806803, + "narHash": "sha256-qrxvLS888pNJFwJdK+hf1wpRCSQcqA6W5+Ox202NDa0=", + "rev": "b06025f1533a1e07b6db3e75151caa155d1c7eb3", + "revCount": 598982, + "type": "tarball", + "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.598982%2Brev-b06025f1533a1e07b6db3e75151caa155d1c7eb3/018e577a-86bd-7b2f-b434-442e9ada5378/source.tar.gz" }, "original": { "type": "tarball", @@ -158,7 +190,7 @@ "flake-compat": "flake-compat", "naersk": "naersk", "nix": "nix", - "nixpkgs": "nixpkgs_2" + "nixpkgs": "nixpkgs_3" } }, "rust-analyzer-src": { diff --git a/flake.nix b/flake.nix index 32cc7448e..9c3e829a7 100644 --- a/flake.nix +++ b/flake.nix @@ -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 }; @@ -87,6 +87,8 @@ RUSTFLAGS = "--cfg tokio_unstable"; cargoTestOptions = f: f ++ [ "--all" ]; + NIX_INSTALLER_TARBALL = inputs.nix.tarballs_direct.${final.stdenv.system}; + override = { preBuild ? "", ... }: { preBuild = preBuild + '' # logRun "cargo clippy --all-targets --all-features -- -D warnings" @@ -130,6 +132,7 @@ name = "nix-install-shell"; RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library"; + NIX_INSTALLER_TARBALL = inputs.nix.tarballs_direct.${system}; nativeBuildInputs = with pkgs; [ ]; buildInputs = with pkgs; [ diff --git a/src/action/base/fetch_and_unpack_nix.rs b/src/action/base/fetch_and_unpack_nix.rs index 280982300..9123ca26a 100644 --- a/src/action/base/fetch_and_unpack_nix.rs +++ b/src/action/base/fetch_and_unpack_nix.rs @@ -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, dest: PathBuf, proxy: Option, ssl_cert_file: Option, @@ -24,7 +24,7 @@ pub struct FetchAndUnpackNix { impl FetchAndUnpackNix { #[tracing::instrument(level = "debug", skip_all)] pub async fn plan( - url_or_path: UrlOrPath, + url_or_path: Option, dest: PathBuf, proxy: Option, ssl_cert_file: Option, @@ -32,7 +32,7 @@ impl FetchAndUnpackNix { // 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)), @@ -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()), @@ -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(); @@ -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)) diff --git a/src/settings.rs b/src/settings.rs index 82735434d..ed69a6361 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -11,21 +11,7 @@ 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"; +pub const NIX_TARBALL: &[u8] = include_bytes!(env!("NIX_INSTALLER_TARBALL")); #[derive(Debug, serde::Deserialize, serde::Serialize, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "cli", derive(clap::ValueEnum))] @@ -145,39 +131,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, /// 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"))] @@ -250,7 +206,6 @@ pub struct CommonSettings { impl CommonSettings { /// The default settings for the given Architecture & Operating System pub async fn default() -> Result { - let url; let nix_build_user_prefix; let nix_build_user_id_base; let nix_build_user_count; @@ -259,21 +214,18 @@ 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; @@ -281,7 +233,6 @@ impl CommonSettings { #[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; @@ -289,7 +240,6 @@ impl CommonSettings { #[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; @@ -308,7 +258,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,