From 96d887090247bce7a0b8c88b74b2b42c0ad4b7b3 Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Mon, 13 Mar 2023 14:12:33 -0700 Subject: [PATCH] Default to systemd, refer to documentation if systemd is not available (#336) --- README.md | 15 +++++++++++++ src/action/common/configure_init_service.rs | 7 ++++++ src/action/mod.rs | 5 +++++ src/settings.rs | 25 +++++++-------------- 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 39dc07e..c543b3f 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,21 @@ jobs: run: nix build . ``` +## Without systemd (Linux only) + +> **Warning** +> When installed this way, _only_ `root` or users who can elevate to `root` privileges can run Nix: +> +> ```bash +> sudo -i nix run nixpkgs#hello +> ``` + +If you don't use [systemd], you can still install Nix by explicitly specifying the `linux` plan and `--init none`: + +```bash +curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install linux --init none +``` + ## In a container In Docker/Podman containers or WSL2 instances where an init (like `systemd`) is not present, pass `--init none`. diff --git a/src/action/common/configure_init_service.rs b/src/action/common/configure_init_service.rs index af84907..681e4da 100644 --- a/src/action/common/configure_init_service.rs +++ b/src/action/common/configure_init_service.rs @@ -75,6 +75,13 @@ impl ConfigureInitService { }, #[cfg(target_os = "linux")] InitSystem::Systemd => { + // If /run/systemd/system exists, we can be reasonably sure the machine is booted + // with systemd: https://www.freedesktop.org/software/systemd/man/sd_booted.html + if !(Path::new("/run/systemd/system").exists() || which::which("systemctl").is_ok()) + { + return Err(ActionError::SystemdMissing); + } + Self::check_if_systemd_unit_exists(SERVICE_SRC, SERVICE_DEST).await?; Self::check_if_systemd_unit_exists(SOCKET_SRC, SOCKET_DEST).await?; }, diff --git a/src/action/mod.rs b/src/action/mod.rs index c372934..428aeb4 100644 --- a/src/action/mod.rs +++ b/src/action/mod.rs @@ -462,6 +462,11 @@ pub enum ActionError { MissingGroupDeletionCommand, #[error("Could not find a supported command to remove users from groups in PATH; please install `gpasswd` or `deluser`")] MissingRemoveUserFromGroupCommand, + #[error("\ + Could not detect systemd; you may be able to get up and running without systemd with `nix-installer install linux --init none`.\n\ + See https://github.com/DeterminateSystems/nix-installer#without-systemd-linux-only for documentation on usage and drawbacks.\ + ")] + SystemdMissing, } impl ActionError { diff --git a/src/settings.rs b/src/settings.rs index 26045e5..d495bc4 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -339,13 +339,11 @@ impl CommonSettings { } } #[cfg(target_os = "linux")] -async fn linux_detect_init() -> (InitSystem, bool) { +async fn linux_detect_systemd_started() -> bool { use std::process::Stdio; - let mut detected = InitSystem::None; let mut started = false; if std::path::Path::new("/run/systemd/system").exists() { - detected = InitSystem::Systemd; started = if tokio::process::Command::new("systemctl") .arg("status") .stdin(Stdio::null()) @@ -364,7 +362,7 @@ async fn linux_detect_init() -> (InitSystem, bool) { } // TODO: Other inits - (detected, started) + started } // Builder Pattern @@ -464,33 +462,26 @@ pub struct InitSettings { impl InitSettings { /// The default settings for the given Architecture & Operating System pub async fn default() -> Result { - let init; - let start_daemon; - use target_lexicon::{Architecture, OperatingSystem}; - match (Architecture::host(), OperatingSystem::host()) { + let (init, start_daemon) = match (Architecture::host(), OperatingSystem::host()) { #[cfg(target_os = "linux")] (Architecture::X86_64, OperatingSystem::Linux) => { - (init, start_daemon) = linux_detect_init().await; + (InitSystem::Systemd, linux_detect_systemd_started().await) }, #[cfg(target_os = "linux")] (Architecture::X86_32(_), OperatingSystem::Linux) => { - (init, start_daemon) = linux_detect_init().await; + (InitSystem::Systemd, linux_detect_systemd_started().await) }, #[cfg(target_os = "linux")] (Architecture::Aarch64(_), OperatingSystem::Linux) => { - (init, start_daemon) = linux_detect_init().await; + (InitSystem::Systemd, linux_detect_systemd_started().await) }, #[cfg(target_os = "macos")] (Architecture::X86_64, OperatingSystem::MacOSX { .. }) - | (Architecture::X86_64, OperatingSystem::Darwin) => { - (init, start_daemon) = (InitSystem::Launchd, true); - }, + | (Architecture::X86_64, OperatingSystem::Darwin) => (InitSystem::Launchd, true), #[cfg(target_os = "macos")] (Architecture::Aarch64(_), OperatingSystem::MacOSX { .. }) - | (Architecture::Aarch64(_), OperatingSystem::Darwin) => { - (init, start_daemon) = (InitSystem::Launchd, true); - }, + | (Architecture::Aarch64(_), OperatingSystem::Darwin) => (InitSystem::Launchd, true), _ => { return Err(InstallSettingsError::UnsupportedArchitecture( target_lexicon::HOST,