From e0080d12620bad59dc3f92c6d61522b17f3bdbb8 Mon Sep 17 00:00:00 2001 From: Ana Hobden Date: Fri, 10 Mar 2023 15:28:04 -0800 Subject: [PATCH] Repair /nix removal test (#320) * Repair /nix removal test * Iron out the logic better * Repair nix flake check * Remove extra sandbox=false flag * Add ubuntu 16.04 test --- nix/tests/vm-test/default.nix | 58 +++++--- src/action/common/configure_init_service.rs | 140 ++++++++++++++------ 2 files changed, 145 insertions(+), 53 deletions(-) diff --git a/nix/tests/vm-test/default.nix b/nix/tests/vm-test/default.nix index dcdf2f4..79e165e 100644 --- a/nix/tests/vm-test/default.nix +++ b/nix/tests/vm-test/default.nix @@ -11,14 +11,42 @@ let check = '' set -ex + dir /nix + dir /nix/store + + ls -lah /nix/var/nix/profiles/per-user + ls -lah /nix/var/nix/daemon-socket + if systemctl is-active nix-daemon.socket; then echo "nix-daemon.socket was active" else echo "nix-daemon.socket was not active, should be" exit 1 fi + if systemctl is-failed nix-daemon.socket; then + echo "nix-daemon.socket is failed" + exit 1 + fi + if systemctl is-failed nix-daemon.service; then + echo "nix-daemon.service is failed" + exit 1 + fi + if !(sudo systemctl start nix-daemon.service); then + echo "nix-daemon.service failed to start" + exit 1 + fi + if !(sudo systemctl stop nix-daemon.service); then + echo "nix-daemon.service failed to stop" + exit 1 + fi + + sudo -i nix store ping --store daemon + nix store ping --store daemon + + sudo -i nix-env --version nix-env --version + sudo -i nix --extra-experimental-features nix-command store ping nix --extra-experimental-features nix-command store ping out=$(nix-build --no-substitute -E 'derivation { name = "foo"; system = "x86_64-linux"; builder = "/bin/sh"; args = ["-c" "echo foobar > $out"]; }') @@ -75,16 +103,16 @@ let install = install-default.install; check = install-default.check; }; - # install-preexisting-self-broken-no-nix-path = { - # preinstall = '' - # NIX_PATH=$(readlink -f nix.tar.xz) - # RUST_BACKTRACE="full" ./nix-installer install --nix-package-url "file://$NIX_PATH" --no-confirm - # sudo mv /nix/receipt.json /nix/old-receipt.json - # sudo rm -rf /nix/ - # ''; - # install = install-default.install; - # check = install-default.check; - # }; + install-preexisting-self-broken-no-nix-path = { + preinstall = '' + NIX_PATH=$(readlink -f nix.tar.xz) + RUST_BACKTRACE="full" ./nix-installer install --nix-package-url "file://$NIX_PATH" --no-confirm + sudo mv /nix/receipt.json /nix/old-receipt.json + sudo rm -rf /nix/ + ''; + install = install-default.install; + check = install-default.check; + }; install-preexisting-self-broken-missing-users = { preinstall = '' NIX_PATH=$(readlink -f nix.tar.xz) @@ -367,10 +395,10 @@ vm-tests // rec { name = "all"; constituents = pkgs.lib.mapAttrsToList (name: value: value."x86_64-linux".install-preexisting-self-working) vm-tests; }); - # all."x86_64-linux".install-preexisting-self-broken-no-nix-path = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.releaseTools.aggregate { - # name = "all"; - # constituents = pkgs.lib.mapAttrsToList (name: value: value."x86_64-linux".install-preexisting-self-broken-no-nix-path) vm-tests; - # }); + all."x86_64-linux".install-preexisting-self-broken-no-nix-path = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.releaseTools.aggregate { + name = "all"; + constituents = pkgs.lib.mapAttrsToList (name: value: value."x86_64-linux".install-preexisting-self-broken-no-nix-path) vm-tests; + }); all."x86_64-linux".install-preexisting-self-broken-missing-users = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.releaseTools.aggregate { name = "all"; constituents = pkgs.lib.mapAttrsToList (name: value: value."x86_64-linux".install-preexisting-self-broken-missing-users) vm-tests; @@ -398,7 +426,7 @@ vm-tests // rec { all."x86_64-linux".install-no-start-daemon all."x86_64-linux".install-daemonless all."x86_64-linux".install-preexisting-self-working - # all."x86_64-linux".install-preexisting-self-broken-no-nix-path + all."x86_64-linux".install-preexisting-self-broken-no-nix-path all."x86_64-linux".install-preexisting-self-broken-missing-users all."x86_64-linux".install-preexisting-self-broken-missing-users-and-group all."x86_64-linux".install-preexisting-self-broken-daemon-disabled diff --git a/src/action/common/configure_init_service.rs b/src/action/common/configure_init_service.rs index 489109c..878544f 100644 --- a/src/action/common/configure_init_service.rs +++ b/src/action/common/configure_init_service.rs @@ -184,6 +184,28 @@ impl Action for ConfigureInitService { }, #[cfg(target_os = "linux")] InitSystem::Systemd => { + execute_command( + Command::new("systemctl") + .process_group(0) + .arg("daemon-reload") + .stdin(std::process::Stdio::null()), + ) + .await?; + // The goal state is the `socket` enabled and active, the service not enabled and stopped (it activates via socket activation) + let socket_was_active = if is_enabled("nix-daemon.socket").await? { + disable("nix-daemon.socket", true).await?; + true + } else if is_active("nix-daemon.socket").await? { + stop("nix-daemon.socket").await?; + false + } else { + false + }; + if is_enabled("nix-daemon.service").await? { + let now = is_active("nix-daemon.socket").await?; + disable("nix-daemon.service", now).await?; + }; + tracing::trace!(src = TMPFILES_SRC, dest = TMPFILES_DEST, "Symlinking"); if !Path::new(TMPFILES_DEST).exists() { tokio::fs::symlink(TMPFILES_SRC, TMPFILES_DEST) @@ -210,48 +232,39 @@ impl Action for ConfigureInitService { // cli, interactively ask for permission to remove the file Self::check_if_systemd_unit_exists(SERVICE_SRC, SERVICE_DEST).await?; - if !Path::new(SERVICE_DEST).exists() { - tokio::fs::symlink(SERVICE_SRC, SERVICE_DEST) - .await - .map_err(|e| { - ActionError::Symlink( - PathBuf::from(SERVICE_SRC), - PathBuf::from(SERVICE_DEST), - e, - ) - })?; - } + tokio::fs::symlink(SERVICE_SRC, SERVICE_DEST) + .await + .map_err(|e| { + ActionError::Symlink( + PathBuf::from(SERVICE_SRC), + PathBuf::from(SERVICE_DEST), + e, + ) + })?; Self::check_if_systemd_unit_exists(SOCKET_SRC, SOCKET_DEST).await?; - if !Path::new(SOCKET_DEST).exists() { - tokio::fs::symlink(SOCKET_SRC, SOCKET_DEST) - .await - .map_err(|e| { - ActionError::Symlink( - PathBuf::from(SOCKET_SRC), - PathBuf::from(SOCKET_DEST), - e, - ) - })?; - } + tokio::fs::symlink(SOCKET_SRC, SOCKET_DEST) + .await + .map_err(|e| { + ActionError::Symlink( + PathBuf::from(SOCKET_SRC), + PathBuf::from(SOCKET_DEST), + e, + ) + })?; - if *start_daemon { - execute_command( - Command::new("systemctl") - .process_group(0) - .arg("daemon-reload") - .stdin(std::process::Stdio::null()), - ) - .await?; + execute_command( + Command::new("systemctl") + .process_group(0) + .arg("daemon-reload") + .stdin(std::process::Stdio::null()), + ) + .await?; - execute_command( - Command::new("systemctl") - .process_group(0) - .arg("enable") - .arg("--now") - .arg(SOCKET_SRC), - ) - .await?; + if *start_daemon || socket_was_active { + enable(SOCKET_SRC, true).await?; + } else { + enable(SOCKET_SRC, false).await?; } }, #[cfg(not(target_os = "macos"))] @@ -389,6 +402,57 @@ pub enum ConfigureNixDaemonServiceError { InitNotSupported, } +#[cfg(target_os = "linux")] +async fn stop(unit: &str) -> Result<(), ActionError> { + let mut command = Command::new("systemctl"); + command.arg("stop"); + command.arg(unit); + let output = command + .output() + .await + .map_err(|e| ActionError::command(&command, e))?; + match output.status.success() { + true => Ok(()), + false => Err(ActionError::command_output(&command, output)), + } +} + +#[cfg(target_os = "linux")] +async fn enable(unit: &str, now: bool) -> Result<(), ActionError> { + let mut command = Command::new("systemctl"); + command.arg("enable"); + command.arg(unit); + if now { + command.arg("--now"); + } + let output = command + .output() + .await + .map_err(|e| ActionError::command(&command, e))?; + match output.status.success() { + true => Ok(()), + false => Err(ActionError::command_output(&command, output)), + } +} + +#[cfg(target_os = "linux")] +async fn disable(unit: &str, now: bool) -> Result<(), ActionError> { + let mut command = Command::new("systemctl"); + command.arg("disable"); + command.arg(unit); + if now { + command.arg("--now"); + } + let output = command + .output() + .await + .map_err(|e| ActionError::command(&command, e))?; + match output.status.success() { + true => Ok(()), + false => Err(ActionError::command_output(&command, output)), + } +} + #[cfg(target_os = "linux")] async fn is_active(unit: &str) -> Result { let mut command = Command::new("systemctl");