Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: nix-community/NixOS-WSL
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: bff8253b76d471c57bff63b80dbb1fecfdb45675
Choose a base ref
..
head repository: nix-community/NixOS-WSL
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: c54283ceba4881ea309ce188e1fa4f72d1dfc88d
Choose a head ref
Showing with 70 additions and 2 deletions.
  1. +14 −0 tests/slow-activation/delay-activation.nix
  2. +22 −0 tests/slow-activation/slow-activation.Tests.ps1
  3. +1 −1 utils/Cargo.toml
  4. +33 −1 utils/src/shell_wrapper.rs
14 changes: 14 additions & 0 deletions tests/slow-activation/delay-activation.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{ pkgs, lib, ... }:

{
imports = [
<nixos-wsl/modules>
];

wsl.enable = true;

system.activationScripts."00-delay" = ''
echo "Delaying activation for 15 seconds..."
sleep 15s
'';
}
22 changes: 22 additions & 0 deletions tests/slow-activation/slow-activation.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
BeforeAll {
. $PSScriptRoot/../lib/lib.ps1
}

Describe "Slow Activation Script" {
BeforeAll {
$distro = [Distro]::new()
}

It "should not cause starting a shell to fail" {
$distro.InstallConfig("$PSScriptRoot/delay-activation.nix", "boot")
$distro.Shutdown()

$distro.Launch("echo 'TEST'") | Select-Object -Last 1 | Tee-Object -Variable output
$output | Should -BeExactly "TEST"
$LASTEXITCODE | Should -Be 0
}

AfterAll {
$distro.Uninstall()
}
}
2 changes: 1 addition & 1 deletion utils/Cargo.toml
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ rust-version = "1.69.0"

[dependencies]
anyhow = { version = "1.0.82", features = ["backtrace"] }
nix = { version = "0.29.0", features = ["mount", "process"] }
nix = { version = "0.29.0", features = ["mount", "process", "user", "inotify"] }
log = "0.4.21"
kernlog = "0.3.1"
systemd-journal-logger = "2.1.1"
34 changes: 33 additions & 1 deletion utils/src/shell_wrapper.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use anyhow::{anyhow, Context};
use log::{error, info, warn, LevelFilter};
use nix::libc::{sigaction, PT_NULL, SIGCHLD, SIG_IGN};
use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify};
use std::mem::MaybeUninit;
use std::os::unix::process::CommandExt;
use std::path::Path;
use std::process::Command;
use std::{env, fs::read_link};
use systemd_journal_logger::JournalLog;
@@ -17,6 +19,28 @@ fn real_main() -> anyhow::Result<()> {
// Therefore we dereference our symlink to get whatever it was originally.
let shell = read_link(exe_dir.join("shell")).context("when locating the wrapped shell")?;

if shell.starts_with("/run/current-system/sw/bin/")
&& !Path::new("/run/current-system").exists()
{
let inotify = Inotify::init(InitFlags::empty()).context("When initializing inotify")?;

// Watch changes in /run to re-check if the activation script has finished
let wd = inotify.add_watch("/run", AddWatchFlags::IN_CREATE).unwrap();

let mut warning = false;

// Check if the activation script has finished by now
while !Path::new("/run/current-system").exists() {
if (!warning) {
warning = true;
warn!("Activation script has not finished! Waiting for /run/current-system/sw/bin to exist");
}
let events = inotify
.read_events()
.context("When reading inotify events")?;
}
}

// Set the SHELL environment variable to the wrapped shell instead of the wrapper
let shell_env = env::var_os("SHELL");
if shell_env == Some(exe.into()) {
@@ -112,7 +136,15 @@ fn main() {
.context("When installing journal logger")
})
{
warn!("Error while setting up journal logger: {:?}", err);
if nix::unistd::geteuid().is_root() {
// Journal isn't available during early boot. Try to use kmsg instead
if let Err(err) = kernlog::init().context("When initializing kernel logger") {
warn!("Error while setting up kernel logger: {:?}", err);
}
} else {
// Users can't access the kernel log
warn!("Error while setting up journal logger: {:?}", err);
}
}

log::set_max_level(LevelFilter::Info);