From d17c1b46f21fba2dc577c571d0e775b2bcde1ebb Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Sat, 11 Nov 2023 22:22:23 -0500 Subject: [PATCH 1/5] Remove the writable flag, don't set too many permission bits Making everything 0o555 is too much, since many files in the store are not supposed to be executable. Those should be 0o444. Instead of splatting 0o555 out, take a more measured approach and remove the writable flag from the on-disk mode. --- src/action/base/move_unpacked_nix.rs | 13 ++++++++++--- src/action/mod.rs | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) 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}`")] From c2d7059b31e551a2c429ac3edc3b711aecf2a01c Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Sat, 11 Nov 2023 23:40:29 -0500 Subject: [PATCH 2/5] Nix config: add extra newlines after the initial comment Otherwise the extra-config option will get swallowed. Closes #717 --- src/action/base/create_or_merge_nix_config.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/action/base/create_or_merge_nix_config.rs b/src/action/base/create_or_merge_nix_config.rs index 1f69ddb41..28cbc5939 100644 --- a/src/action/base/create_or_merge_nix_config.rs +++ b/src/action/base/create_or_merge_nix_config.rs @@ -413,6 +413,8 @@ impl Action for CreateOrMergeNixConfig { &[ "# Generated by https://github.com/DeterminateSystems/nix-installer.", "# See `/nix/nix-installer --version` for the version details.", + "", + "", ] .join("\n"), ); From 60d19b20790886f09831f85a2dcdfd9a30befcd3 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Sun, 12 Nov 2023 14:13:47 -0500 Subject: [PATCH 3/5] Push individual strs --- src/action/base/create_or_merge_nix_config.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/action/base/create_or_merge_nix_config.rs b/src/action/base/create_or_merge_nix_config.rs index 28cbc5939..4a0239cf8 100644 --- a/src/action/base/create_or_merge_nix_config.rs +++ b/src/action/base/create_or_merge_nix_config.rs @@ -409,15 +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); From abd6c300041af1747614cf9ccb6d2279375bc64f Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Sun, 12 Nov 2023 16:19:28 -0500 Subject: [PATCH 4/5] Compile in a tarball --- flake.lock | 65 +++++++++++++++++++++++++ flake.nix | 23 +++++++++ src/action/base/fetch_and_unpack_nix.rs | 19 +++++--- src/settings.rs | 58 ++-------------------- 4 files changed, 104 insertions(+), 61 deletions(-) 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..1f3033acd 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 = @@ -89,6 +110,7 @@ override = { preBuild ? "", ... }: { preBuild = preBuild + '' + NIX_INSTALLER_TARBALL=${inputs."nix_tar_${final.stdenv.system}"} # logRun "cargo clippy --all-targets --all-features -- -D warnings" ''; }; @@ -130,6 +152,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/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/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, From 016f6cb19354b34185846cadb52fc2c75d28fad4 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Sun, 12 Nov 2023 16:23:06 -0500 Subject: [PATCH 5/5] fixup --- flake.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 1f3033acd..87a914cf2 100644 --- a/flake.nix +++ b/flake.nix @@ -108,9 +108,10 @@ RUSTFLAGS = "--cfg tokio_unstable"; cargoTestOptions = f: f ++ [ "--all" ]; + NIX_INSTALLER_TARBALL = inputs."nix_tar_${final.stdenv.system}"; + override = { preBuild ? "", ... }: { preBuild = preBuild + '' - NIX_INSTALLER_TARBALL=${inputs."nix_tar_${final.stdenv.system}"} # logRun "cargo clippy --all-targets --all-features -- -D warnings" ''; };