systemd: prepare the removal of some patches (#488523)
This commit is contained in:
@@ -742,6 +742,8 @@ in
|
||||
};
|
||||
|
||||
systemd = {
|
||||
generatorPath = [ cfg.package ];
|
||||
|
||||
sockets.sshd = lib.mkIf cfg.startWhenNeeded {
|
||||
description = "SSH Socket";
|
||||
wantedBy = [ "sockets.target" ];
|
||||
|
||||
@@ -233,6 +233,8 @@ let
|
||||
|
||||
proxy_env = config.networking.proxy.envVars;
|
||||
|
||||
json = pkgs.formats.json { };
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@@ -356,6 +358,30 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
generatorEnvironment = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
example = {
|
||||
MY_VAR = "my-value";
|
||||
};
|
||||
description = ''
|
||||
Environment variables for systemd generators.
|
||||
|
||||
The `PATH` environment variable is populated via `systemd.generatorPath`.
|
||||
'';
|
||||
};
|
||||
|
||||
generatorPath = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [ ];
|
||||
example = [
|
||||
pkgs.hello
|
||||
];
|
||||
description = ''
|
||||
Packages added to the `PATH` environment variable of all systemd generators.
|
||||
'';
|
||||
};
|
||||
|
||||
shutdown = mkOption {
|
||||
type = types.attrsOf types.path;
|
||||
default = { };
|
||||
@@ -636,6 +662,12 @@ in
|
||||
"systemd/user-preset/00-nixos.preset".text = ''
|
||||
ignore *
|
||||
'';
|
||||
|
||||
"systemd/generator-environment.json".source =
|
||||
json.generate "systemd-generator-environment.json" cfg.generatorEnvironment;
|
||||
|
||||
"systemd/system-environment-generators/env-generator".source =
|
||||
"${config.system.nixos-init.package}/bin/env-generator";
|
||||
};
|
||||
|
||||
services.dbus.enable = true;
|
||||
@@ -683,12 +715,7 @@ in
|
||||
systemd.managerEnvironment = {
|
||||
# Doesn't contain systemd itself - everything works so it seems to use the compiled-in value for its tools
|
||||
# util-linux is needed for the main fsck utility wrapping the fs-specific ones
|
||||
PATH = lib.makeBinPath (
|
||||
config.system.fsPackages
|
||||
++ [ cfg.package.util-linux ]
|
||||
# systemd-ssh-generator needs sshd in PATH
|
||||
++ lib.optional config.services.openssh.enable config.services.openssh.package
|
||||
);
|
||||
PATH = lib.makeBinPath (config.system.fsPackages ++ [ cfg.package.util-linux ]);
|
||||
LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
|
||||
TZDIR = "/etc/zoneinfo";
|
||||
# If SYSTEMD_UNIT_PATH ends with an empty component (":"), the usual unit load path will be appended to the contents of the variable
|
||||
@@ -704,6 +731,16 @@ in
|
||||
DefaultIPAccounting = lib.mkDefault true;
|
||||
};
|
||||
|
||||
# These are needed for systemd-fstab-generator to schedule systemd-fsck@
|
||||
# units.
|
||||
systemd.generatorPath = config.system.fsPackages ++ [
|
||||
cfg.package.util-linux
|
||||
];
|
||||
|
||||
systemd.generatorEnvironment = {
|
||||
PATH = lib.makeBinPath cfg.generatorPath;
|
||||
};
|
||||
|
||||
system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled [
|
||||
"DEVTMPFS"
|
||||
"CGROUPS"
|
||||
|
||||
@@ -92,6 +92,7 @@ let
|
||||
# Declare root explicitly to avoid shellcheck warnings, it comes from the env
|
||||
declare root
|
||||
|
||||
mkdir -p "$root/usr/bin"
|
||||
mkdir -p "$root/etc" "$root/var/lib"
|
||||
chmod 0755 "$root/etc" "$root/var/lib"
|
||||
mkdir -p "$root/var/lib/private" "$root/root" /run/nixos-containers
|
||||
|
||||
@@ -19,8 +19,6 @@ in
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
imports = lib.optionals (!systemdStage1) [ ./common/auto-format-root-device.nix ];
|
||||
|
||||
virtualisation = {
|
||||
emptyDiskImages = [ 512 ];
|
||||
useBootLoader = true;
|
||||
@@ -30,7 +28,6 @@ in
|
||||
# the new root device is /dev/vdb
|
||||
# an empty 512MiB drive, containing no Nix store.
|
||||
mountHostNixStore = true;
|
||||
fileSystems."/".autoFormat = lib.mkIf systemdStage1 true;
|
||||
};
|
||||
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
@@ -90,6 +87,8 @@ in
|
||||
# Create encrypted volume
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.succeed("echo "" | cryptsetup luksFormat /dev/vdb --batch-mode")
|
||||
machine.succeed("echo "" | cryptsetup luksOpen /dev/vdb cryptroot")
|
||||
machine.succeed("mkfs.ext4 /dev/mapper/cryptroot")
|
||||
machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks-wrong-keyfile.conf")
|
||||
machine.succeed("sync")
|
||||
machine.crash()
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [ ./common/auto-format-root-device.nix ];
|
||||
|
||||
# Use systemd-boot
|
||||
virtualisation = {
|
||||
@@ -48,7 +47,12 @@
|
||||
# Create encrypted volume
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -")
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdb cryptroot")
|
||||
machine.succeed("mkfs.ext4 /dev/mapper/cryptroot")
|
||||
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -")
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdc cryptroot2")
|
||||
machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2")
|
||||
|
||||
# Boot from the encrypted disk
|
||||
machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf")
|
||||
|
||||
@@ -38,7 +38,6 @@ in
|
||||
};
|
||||
};
|
||||
virtualisation.rootDevice = "/dev/mapper/cryptroot";
|
||||
virtualisation.fileSystems."/".autoFormat = true;
|
||||
boot.initrd.secrets."/etc/cryptroot.key" = keyfile;
|
||||
};
|
||||
};
|
||||
@@ -47,6 +46,8 @@ in
|
||||
# Create encrypted volume
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.succeed("cryptsetup luksFormat -q --iter-time=1 -d ${keyfile} /dev/vdb")
|
||||
machine.succeed("cryptsetup luksOpen --key-file ${keyfile} /dev/vdb cryptroot")
|
||||
machine.succeed("mkfs.ext4 /dev/mapper/cryptroot")
|
||||
|
||||
# Boot from the encrypted disk
|
||||
machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf")
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
cryptroot2.device = "/dev/vdc";
|
||||
};
|
||||
virtualisation.rootDevice = "/dev/mapper/cryptroot";
|
||||
virtualisation.fileSystems."/".autoFormat = true;
|
||||
# test mounting device unlocked in initrd after switching root
|
||||
virtualisation.fileSystems."/cryptroot2".device = "/dev/mapper/cryptroot2";
|
||||
};
|
||||
@@ -40,7 +39,11 @@
|
||||
testScript = ''
|
||||
# Create encrypted volume
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -")
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdb cryptroot")
|
||||
machine.succeed("mkfs.ext4 /dev/mapper/cryptroot")
|
||||
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -")
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdc cryptroot2")
|
||||
machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2")
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
};
|
||||
};
|
||||
virtualisation.rootDevice = "/dev/mapper/cryptroot";
|
||||
virtualisation.fileSystems."/".autoFormat = true;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -40,6 +39,8 @@
|
||||
# Create encrypted volume
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -")
|
||||
machine.succeed("echo -n supersecret | cryptsetup luksOpen -q /dev/vdb cryptroot")
|
||||
machine.succeed("mkfs.ext4 /dev/mapper/cryptroot")
|
||||
machine.succeed("PASSWORD=supersecret SYSTEMD_LOG_LEVEL=debug systemd-cryptenroll --tpm2-pcrs= --tpm2-device=auto /dev/vdb |& systemd-cat")
|
||||
|
||||
# Boot from the encrypted disk
|
||||
|
||||
@@ -79,9 +79,12 @@ in
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
# Create encrypted volume
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
|
||||
machine.succeed("echo -n ${passphrase} | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -")
|
||||
machine.succeed("echo -n ${passphrase} | cryptsetup luksOpen -q /dev/vdb cryptroot")
|
||||
machine.succeed("mkfs.ext4 /dev/mapper/cryptroot")
|
||||
|
||||
machine.succeed("echo -n ${passphrase} | cryptsetup luksFormat -q --iter-time=1 /dev/vdc -")
|
||||
machine.succeed("echo -n ${passphrase} | cryptsetup luksOpen -q /dev/vdc cryptroot2")
|
||||
machine.succeed("mkfs.ext4 /dev/mapper/cryptroot2")
|
||||
|
||||
@@ -19,6 +19,7 @@ in
|
||||
|
||||
nodes = {
|
||||
virthost = {
|
||||
environment.systemPackages = [ pkgs.jq ];
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings.PermitRootLogin = "prohibit-password";
|
||||
@@ -48,6 +49,10 @@ in
|
||||
virthost.succeed("cp '${snakeOilEd25519PrivateKey}' ~/.ssh/id_ed25519")
|
||||
virthost.succeed("chmod 600 ~/.ssh/id_ed25519")
|
||||
|
||||
with subtest("Check the environment generator"):
|
||||
print(virthost.succeed("jq '.' /etc/systemd/generator-environment.json"))
|
||||
print(virthost.succeed("/etc/systemd/system-environment-generators/env-generator"))
|
||||
|
||||
with subtest("ssh into a container with AF_UNIX"):
|
||||
virthost.wait_for_unit("container@guest.service")
|
||||
virthost.wait_until_succeeds("ssh -i ~/.ssh/id_ed25519 unix/run/systemd/nspawn/unix-export/guest/ssh echo meow | grep meow")
|
||||
|
||||
@@ -48,6 +48,7 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
||||
"initrd-init"
|
||||
"find-etc"
|
||||
"resolve-in-root"
|
||||
"env-generator"
|
||||
];
|
||||
|
||||
postInstall = ''
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
io::{self, Write},
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use serde::Deserialize;
|
||||
|
||||
const CONFIG_PATH: &str = "/etc/systemd/generator-environment.json";
|
||||
const KMSG_PATH: &str = "/dev/kmsg";
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Config(HashMap<String, String>);
|
||||
|
||||
/// Implementation for the entrypoint of the `env-generator` binary.
|
||||
///
|
||||
/// Reads the JSON config for the systemd generator environment and prints it in KEY=VALUE format
|
||||
/// to stdout. This makes the configured environment variables available for all systemd
|
||||
/// generators.
|
||||
fn env_generator_impl() -> Result<()> {
|
||||
let content = fs::read(CONFIG_PATH).with_context(|| format!("Failed to read {CONFIG_PATH}"))?;
|
||||
let config: Config = serde_json::from_slice(&content).context("Failed to parse config")?;
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
for (key, value) in config.0 {
|
||||
writeln!(&mut buffer, "{key}=\"{value}\"").context("Failed to write to buffer")?;
|
||||
}
|
||||
|
||||
let stdout = io::stdout();
|
||||
let mut locked = stdout.lock();
|
||||
locked
|
||||
.write_all(&buffer)
|
||||
.context("Failed to write to stdout")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Entrypoint for the `env-generator` binary.
|
||||
///
|
||||
/// Generators cannot use normal logging but have to write to /dev/kmsg.
|
||||
///
|
||||
/// The return value is just here so that we can use the `main.rs` entrypoint for this binary.
|
||||
/// Errors returned from this function will not be logged and thus are meaningless.
|
||||
pub fn env_generator() -> Result<()> {
|
||||
if let Err(err) = env_generator_impl() {
|
||||
// Sometimes we do not have /dev/kmsg, e.g. inside a container
|
||||
if let Ok(mut kmsg) = fs::OpenOptions::new().write(true).open(KMSG_PATH) {
|
||||
let _ = write!(kmsg, "<3>env-generator: {err:#}");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
mod activate;
|
||||
mod config;
|
||||
mod env_generator;
|
||||
mod find_etc;
|
||||
mod fs;
|
||||
mod init;
|
||||
@@ -14,6 +15,7 @@ use anyhow::{Context, Result, bail};
|
||||
|
||||
pub use crate::{
|
||||
activate::activate,
|
||||
env_generator::env_generator,
|
||||
find_etc::find_etc,
|
||||
init::init,
|
||||
initrd_init::initrd_init,
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::{env, io::Write, process::ExitCode};
|
||||
|
||||
use log::Level;
|
||||
|
||||
use nixos_init::{find_etc, initrd_init, resolve_in_root};
|
||||
use nixos_init::{env_generator, find_etc, initrd_init, resolve_in_root};
|
||||
|
||||
fn main() -> ExitCode {
|
||||
let arg0 = env::args()
|
||||
@@ -15,6 +15,7 @@ fn main() -> ExitCode {
|
||||
"find-etc" => find_etc,
|
||||
"resolve-in-root" => resolve_in_root,
|
||||
"initrd-init" => initrd_init,
|
||||
"env-generator" => env_generator,
|
||||
_ => {
|
||||
log::error!("Command {arg0} unknown");
|
||||
return ExitCode::FAILURE;
|
||||
|
||||
Reference in New Issue
Block a user