diff --git a/flake.lock b/flake.lock index c4849219d..0e0cb5734 100644 --- a/flake.lock +++ b/flake.lock @@ -103,6 +103,66 @@ "url": "https://flakehub.com/f/NixOS/nix/2.18.0.tar.gz" } }, + "nix_tar_aarch64-darwin": { + "flake": false, + "locked": { + "narHash": "sha256-ry+/834XrHJV7VEtFZV1nZGtalfnHlhGQZK7o5f6fUo=", + "type": "file", + "url": "https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-aarch64-darwin.tar.xz" + }, + "original": { + "type": "file", + "url": "https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-aarch64-darwin.tar.xz" + } + }, + "nix_tar_aarch64-linux": { + "flake": false, + "locked": { + "narHash": "sha256-vDOZhjRXCrbncgJ8qxaJhTQ0jWhHI/iGo9eLd8L08Oc=", + "type": "file", + "url": "https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-aarch64-linux.tar.xz" + }, + "original": { + "type": "file", + "url": "https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-aarch64-linux.tar.xz" + } + }, + "nix_tar_i686-linux": { + "flake": false, + "locked": { + "narHash": "sha256-j7dZNFdF9dXl/L7gZFFukQlE4uNqLDhPivabaw33u4o=", + "type": "file", + "url": "https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-i686-linux.tar.xz" + }, + "original": { + "type": "file", + "url": "https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-i686-linux.tar.xz" + } + }, + "nix_tar_x86_64-darwin": { + "flake": false, + "locked": { + "narHash": "sha256-bTgXHZSa6dqeH92kfTXfH15Aas2PbT5trwweCD9qqug=", + "type": "file", + "url": "https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-x86_64-darwin.tar.xz" + }, + "original": { + "type": "file", + "url": "https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-x86_64-darwin.tar.xz" + } + }, + "nix_tar_x86_64-linux": { + "flake": false, + "locked": { + "narHash": "sha256-vAfcV2ISMJBZ9dstj3hejHM7XYrIXByIjw6bHxre774=", + "type": "file", + "url": "https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-x86_64-linux.tar.xz" + }, + "original": { + "type": "file", + "url": "https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-x86_64-linux.tar.xz" + } + }, "nixpkgs": { "locked": { "lastModified": 1695283060, @@ -154,6 +214,11 @@ "flake-compat": "flake-compat", "naersk": "naersk", "nix": "nix", + "nix_tar_aarch64-darwin": "nix_tar_aarch64-darwin", + "nix_tar_aarch64-linux": "nix_tar_aarch64-linux", + "nix_tar_i686-linux": "nix_tar_i686-linux", + "nix_tar_x86_64-darwin": "nix_tar_x86_64-darwin", + "nix_tar_x86_64-linux": "nix_tar_x86_64-linux", "nixpkgs": "nixpkgs_2" } }, diff --git a/flake.nix b/flake.nix index 3ca2b263d..87a914cf2 100644 --- a/flake.nix +++ b/flake.nix @@ -20,6 +20,27 @@ }; flake-compat.url = "https://flakehub.com/f/edolstra/flake-compat/1.0.0.tar.gz"; + + nix_tar_x86_64-linux = { + url = "file+https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-x86_64-linux.tar.xz"; + flake = false; + }; + nix_tar_i686-linux = { + url = "file+https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-i686-linux.tar.xz"; + flake = false; + }; + nix_tar_aarch64-linux = { + url = "file+https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-aarch64-linux.tar.xz"; + flake = false; + }; + nix_tar_x86_64-darwin = { + url = "file+https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-x86_64-darwin.tar.xz"; + flake = false; + }; + nix_tar_aarch64-darwin = { + url = "file+https://releases.nixos.org/nix/nix-2.18.1/nix-2.18.1-aarch64-darwin.tar.xz"; + flake = false; + }; }; outputs = @@ -87,6 +108,8 @@ RUSTFLAGS = "--cfg tokio_unstable"; cargoTestOptions = f: f ++ [ "--all" ]; + NIX_INSTALLER_TARBALL = inputs."nix_tar_${final.stdenv.system}"; + override = { preBuild ? "", ... }: { preBuild = preBuild + '' # logRun "cargo clippy --all-targets --all-features -- -D warnings" @@ -130,6 +153,7 @@ name = "nix-install-shell"; RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library"; + NIX_INSTALLER_TARBALL = inputs."nix_tar_${system}"; nativeBuildInputs = with pkgs; [ ]; buildInputs = with pkgs; [ diff --git a/src/action/base/create_or_merge_nix_config.rs b/src/action/base/create_or_merge_nix_config.rs index 1f69ddb41..4a0239cf8 100644 --- a/src/action/base/create_or_merge_nix_config.rs +++ b/src/action/base/create_or_merge_nix_config.rs @@ -409,13 +409,10 @@ impl Action for CreateOrMergeNixConfig { new_config.push('\n'); } - new_config.push_str( - &[ - "# Generated by https://github.com/DeterminateSystems/nix-installer.", - "# See `/nix/nix-installer --version` for the version details.", - ] - .join("\n"), - ); + new_config + .push_str("# Generated by https://github.com/DeterminateSystems/nix-installer.\n"); + new_config.push_str("# See `/nix/nix-installer --version` for the version details.\n"); + new_config.push_str("\n"); for (name, value) in merged_nix_config.settings() { new_config.push_str(name); diff --git a/src/action/base/fetch_and_unpack_nix.rs b/src/action/base/fetch_and_unpack_nix.rs index 280982300..b3ca22a7b 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 { + format!("Extract the bundled Nix") + } } 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/action/base/move_unpacked_nix.rs b/src/action/base/move_unpacked_nix.rs index 875e3903e..37e034ff8 100644 --- a/src/action/base/move_unpacked_nix.rs +++ b/src/action/base/move_unpacked_nix.rs @@ -1,5 +1,4 @@ use std::{ - fs::Permissions, os::unix::prelude::PermissionsExt, path::{Path, PathBuf}, }; @@ -110,13 +109,21 @@ impl Action for MoveUnpackedNix { .map_err(|e| ActionErrorKind::Rename(entry.path(), entry_dest.to_owned(), e)) .map_err(Self::error)?; - let perms: Permissions = PermissionsExt::from_mode(0o555); for entry_item in WalkDir::new(&entry_dest) .into_iter() .filter_map(Result::ok) .filter(|e| !e.file_type().is_symlink()) { - tokio::fs::set_permissions(&entry_item.path(), perms.clone()) + let path = entry_item.path(); + + let mut perms = path + .metadata() + .map_err(|e| ActionErrorKind::GetMetadata(path.to_owned(), e)) + .map_err(Self::error)? + .permissions(); + perms.set_readonly(true); + + tokio::fs::set_permissions(path, perms.clone()) .await .map_err(|e| { ActionErrorKind::SetPermissions( diff --git a/src/action/mod.rs b/src/action/mod.rs index 885665109..c9ef0998a 100644 --- a/src/action/mod.rs +++ b/src/action/mod.rs @@ -422,6 +422,8 @@ pub enum ActionErrorKind { std::path::PathBuf, #[source] std::io::Error, ), + #[error("Getting filesystem metadata for `{0}` on `{1}`")] + GetMetadata(std::path::PathBuf, #[source] std::io::Error), #[error("Set mode `{0:#o}` on `{1}`")] SetPermissions(u32, std::path::PathBuf, #[source] std::io::Error), #[error("Remove file `{0}`")] diff --git a/src/settings.rs b/src/settings.rs index 31529c61e..a78d3bbe7 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.18.1/nix-2.18.1-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.18.1/nix-2.18.1-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.18.1/nix-2.18.1-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.18.1/nix-2.18.1-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.18.1/nix-2.18.1-aarch64-darwin.tar.xz"; +pub const NIX_TARBALL: &'static [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,