Skip to content

Commit

Permalink
Embed the Nix tarball into the binary
Browse files Browse the repository at this point in the history
This improves built-in offline support, and improves install time reliability.
  • Loading branch information
grahamc committed May 2, 2024
1 parent 1b6195b commit 89e611a
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 69 deletions.
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 = 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 = 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
58 changes: 4 additions & 54 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand Down Expand Up @@ -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<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 +206,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 +214,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 +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,
Expand Down

0 comments on commit 89e611a

Please sign in to comment.