Merge pull request #267983 from nikstur/replace-simple-activation-2

nixos: replace activationScripts 2/x
This commit is contained in:
nikstur 2023-12-29 16:29:11 +01:00 committed by GitHub
commit 5a9c0b7600
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 177 additions and 132 deletions

View file

@ -226,18 +226,6 @@ in
"ldap.conf" = ldapConfig; "ldap.conf" = ldapConfig;
}; };
system.activationScripts = mkIf (!cfg.daemon.enable) {
ldap = stringAfter [ "etc" "groups" "users" ] ''
if test -f "${cfg.bind.passwordFile}" ; then
umask 0077
conf="$(mktemp)"
printf 'bindpw %s\n' "$(cat ${cfg.bind.passwordFile})" |
cat ${ldapConfig.source} - >"$conf"
mv -fT "$conf" /etc/ldap.conf
fi
'';
};
system.nssModules = mkIf cfg.nsswitch (singleton ( system.nssModules = mkIf cfg.nsswitch (singleton (
if cfg.daemon.enable then nss_pam_ldapd else nss_ldap if cfg.daemon.enable then nss_pam_ldapd else nss_ldap
)); ));
@ -258,42 +246,63 @@ in
}; };
}; };
systemd.services = mkIf cfg.daemon.enable { systemd.services = mkMerge [
nslcd = { (mkIf (!cfg.daemon.enable) {
wantedBy = [ "multi-user.target" ]; ldap-password = {
wantedBy = [ "sysinit.target" ];
preStart = '' before = [ "sysinit.target" "shutdown.target" ];
umask 0077 conflicts = [ "shutdown.target" ];
conf="$(mktemp)" unitConfig.DefaultDependencies = false;
{ serviceConfig.Type = "oneshot";
cat ${nslcdConfig} serviceConfig.RemainAfterExit = true;
test -z '${cfg.bind.distinguishedName}' -o ! -f '${cfg.bind.passwordFile}' || script = ''
printf 'bindpw %s\n' "$(cat '${cfg.bind.passwordFile}')" if test -f "${cfg.bind.passwordFile}" ; then
test -z '${cfg.daemon.rootpwmoddn}' -o ! -f '${cfg.daemon.rootpwmodpwFile}' || umask 0077
printf 'rootpwmodpw %s\n' "$(cat '${cfg.daemon.rootpwmodpwFile}')" conf="$(mktemp)"
} >"$conf" printf 'bindpw %s\n' "$(cat ${cfg.bind.passwordFile})" |
mv -fT "$conf" /run/nslcd/nslcd.conf cat ${ldapConfig.source} - >"$conf"
''; mv -fT "$conf" /etc/ldap.conf
fi
restartTriggers = [ '';
nslcdConfig
cfg.bind.passwordFile
cfg.daemon.rootpwmodpwFile
];
serviceConfig = {
ExecStart = "${nslcdWrapped}/bin/nslcd";
Type = "forking";
Restart = "always";
User = "nslcd";
Group = "nslcd";
RuntimeDirectory = [ "nslcd" ];
PIDFile = "/run/nslcd/nslcd.pid";
AmbientCapabilities = "CAP_SYS_RESOURCE";
}; };
}; })
}; (mkIf cfg.daemon.enable {
nslcd = {
wantedBy = [ "multi-user.target" ];
preStart = ''
umask 0077
conf="$(mktemp)"
{
cat ${nslcdConfig}
test -z '${cfg.bind.distinguishedName}' -o ! -f '${cfg.bind.passwordFile}' ||
printf 'bindpw %s\n' "$(cat '${cfg.bind.passwordFile}')"
test -z '${cfg.daemon.rootpwmoddn}' -o ! -f '${cfg.daemon.rootpwmodpwFile}' ||
printf 'rootpwmodpw %s\n' "$(cat '${cfg.daemon.rootpwmodpwFile}')"
} >"$conf"
mv -fT "$conf" /run/nslcd/nslcd.conf
'';
restartTriggers = [
nslcdConfig
cfg.bind.passwordFile
cfg.daemon.rootpwmodpwFile
];
serviceConfig = {
ExecStart = "${nslcdWrapped}/bin/nslcd";
Type = "forking";
Restart = "always";
User = "nslcd";
Group = "nslcd";
RuntimeDirectory = [ "nslcd" ];
PIDFile = "/run/nslcd/nslcd.pid";
AmbientCapabilities = "CAP_SYS_RESOURCE";
};
};
})
];
}; };

View file

@ -12,7 +12,6 @@ let
mkDefault mkDefault
mkIf mkIf
mkOption mkOption
stringAfter
types types
; ;

View file

@ -39,9 +39,10 @@ in
hardware.firmware = [ package.fw ]; hardware.firmware = [ package.fw ];
system.activationScripts.setup-amdgpu-pro = '' systemd.tmpfiles.settings.amdgpu-pro = {
ln -sfn ${package}/opt/amdgpu{,-pro} /run "/run/amdgpu"."L+".argument = "${package}/opt/amdgpu";
''; "/run/amdgpu-pro"."L+".argument = "${package}/opt/amdgpu-pro";
};
system.requiredKernelConfig = with config.lib.kernelConfig; [ system.requiredKernelConfig = with config.lib.kernelConfig; [
(isYes "DEVICE_PRIVATE") (isYes "DEVICE_PRIVATE")

View file

@ -181,25 +181,33 @@ in {
''; '';
}; };
system.activationScripts.ipa = stringAfter ["etc"] '' systemd.services."ipa-activation" = {
# libcurl requires a hard copy of the certificate wantedBy = [ "sysinit.target" ];
if ! ${pkgs.diffutils}/bin/diff ${cfg.certificate} /etc/ipa/ca.crt > /dev/null 2>&1; then before = [ "sysinit.target" "shutdown.target" ];
rm -f /etc/ipa/ca.crt conflicts = [ "shutdown.target" ];
cp ${cfg.certificate} /etc/ipa/ca.crt unitConfig.DefaultDependencies = false;
fi serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
script = ''
# libcurl requires a hard copy of the certificate
if ! ${pkgs.diffutils}/bin/diff ${cfg.certificate} /etc/ipa/ca.crt > /dev/null 2>&1; then
rm -f /etc/ipa/ca.crt
cp ${cfg.certificate} /etc/ipa/ca.crt
fi
if [ ! -f /etc/krb5.keytab ]; then if [ ! -f /etc/krb5.keytab ]; then
cat <<EOF cat <<EOF
In order to complete FreeIPA integration, please join the domain by completing the following steps: In order to complete FreeIPA integration, please join the domain by completing the following steps:
1. Authenticate as an IPA user authorized to join new hosts, e.g. kinit admin@${cfg.realm} 1. Authenticate as an IPA user authorized to join new hosts, e.g. kinit admin@${cfg.realm}
2. Join the domain and obtain the keytab file: ipa-join 2. Join the domain and obtain the keytab file: ipa-join
3. Install the keytab file: sudo install -m 600 krb5.keytab /etc/ 3. Install the keytab file: sudo install -m 600 krb5.keytab /etc/
4. Restart sssd systemd service: sudo systemctl restart sssd 4. Restart sssd systemd service: sudo systemctl restart sssd
EOF EOF
fi fi
''; '';
};
services.sssd.config = '' services.sssd.config = ''
[domain/${cfg.domain}] [domain/${cfg.domain}]

View file

@ -280,6 +280,7 @@ in
wantedBy = [ "sysinit.target" ]; wantedBy = [ "sysinit.target" ];
before = [ "sysinit.target" "shutdown.target" ]; before = [ "sysinit.target" "shutdown.target" ];
conflicts = [ "shutdown.target" ]; conflicts = [ "shutdown.target" ];
after = [ "systemd-sysusers.service" ];
unitConfig.DefaultDependencies = false; unitConfig.DefaultDependencies = false;
unitConfig.RequiresMountsFor = [ "/nix/store" "/run/wrappers" ]; unitConfig.RequiresMountsFor = [ "/nix/store" "/run/wrappers" ];
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";

View file

@ -143,20 +143,15 @@ let
}; };
# Paths listed in ReadWritePaths must exist before service is started # Paths listed in ReadWritePaths must exist before service is started
mkActivationScript = name: cfg: mkTmpfiles = name: cfg:
let let
install = "install -o ${cfg.user} -g ${cfg.group}"; settings = { inherit (cfg) user group; };
in in lib.nameValuePair "borgbackup-job-${name}" ({
nameValuePair "borgbackup-job-${name}" (stringAfter [ "users" ] ('' "${config.users.users."${cfg.user}".home}/.config/borg".d = settings;
# Ensure that the home directory already exists "${config.users.users."${cfg.user}".home}/.cache/borg".d = settings;
# We can't assert createHome == true because that's not the case for root } // optionalAttrs (isLocalPath cfg.repo && !cfg.removableDevice) {
cd "${config.users.users.${cfg.user}.home}" "${cfg.repo}".d = settings;
# Create each directory separately to prevent root owned parent dirs });
${install} -d .config .config/borg
${install} -d .cache .cache/borg
'' + optionalString (isLocalPath cfg.repo && !cfg.removableDevice) ''
${install} -d ${escapeShellArg cfg.repo}
''));
mkPassAssertion = name: cfg: { mkPassAssertion = name: cfg: {
assertion = with cfg.encryption; assertion = with cfg.encryption;
@ -760,7 +755,7 @@ in {
++ mapAttrsToList mkSourceAssertions jobs ++ mapAttrsToList mkSourceAssertions jobs
++ mapAttrsToList mkRemovableDeviceAssertions jobs; ++ mapAttrsToList mkRemovableDeviceAssertions jobs;
system.activationScripts = mapAttrs' mkActivationScript jobs; systemd.tmpfiles.settings = mapAttrs' mkTmpfiles jobs;
systemd.services = systemd.services =
# A job named "foo" is mapped to systemd.services.borgbackup-job-foo # A job named "foo" is mapped to systemd.services.borgbackup-job-foo

View file

@ -220,10 +220,16 @@ in
logcheck = {}; logcheck = {};
}; };
system.activationScripts.logcheck = '' systemd.tmpfiles.settings.logcheck = {
mkdir -m 700 -p /var/{lib,lock}/logcheck "/var/lib/logcheck".d = {
chown ${cfg.user} /var/{lib,lock}/logcheck mode = "700";
''; inherit (cfg) user;
};
"/var/lock/logcheck".d = {
mode = "700";
inherit (cfg) user;
};
};
services.cron.systemCronJobs = services.cron.systemCronJobs =
let withTime = name: {timeArgs, ...}: timeArgs != null; let withTime = name: {timeArgs, ...}: timeArgs != null;

View file

@ -137,16 +137,24 @@ in
message = "networking.enableIPv6 must be true for yggdrasil to work"; message = "networking.enableIPv6 must be true for yggdrasil to work";
}]; }];
system.activationScripts.yggdrasil = mkIf cfg.persistentKeys '' # This needs to be a separate service. The yggdrasil service fails if
if [ ! -e ${keysPath} ] # this is put into its preStart.
then systemd.services.yggdrasil-persistent-keys = lib.mkIf cfg.persistentKeys {
mkdir --mode=700 -p ${builtins.dirOf keysPath} wantedBy = [ "multi-user.target" ];
${binYggdrasil} -genconf -json \ before = [ "yggdrasil.service" ];
| ${pkgs.jq}/bin/jq \ serviceConfig.Type = "oneshot";
'to_entries|map(select(.key|endswith("Key")))|from_entries' \ serviceConfig.RemainAfterExit = true;
> ${keysPath} script = ''
fi if [ ! -e ${keysPath} ]
''; then
mkdir --mode=700 -p ${builtins.dirOf keysPath}
${binYggdrasil} -genconf -json \
| ${pkgs.jq}/bin/jq \
'to_entries|map(select(.key|endswith("Key")))|from_entries' \
> ${keysPath}
fi
'';
};
systemd.services.yggdrasil = { systemd.services.yggdrasil = {
description = "Yggdrasil Network Service"; description = "Yggdrasil Network Service";

View file

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
inherit (lib) mkOption mkDefault types optionalString stringAfter; inherit (lib) mkOption mkDefault types optionalString;
cfg = config.boot.binfmt; cfg = config.boot.binfmt;

View file

@ -80,10 +80,17 @@ with lib;
ACTION=="add|change", SUBSYSTEM=="input", ATTR{name}=="${cfg.device}", ATTR{device/speed}="${toString cfg.speed}", ATTR{device/sensitivity}="${toString cfg.sensitivity}" ACTION=="add|change", SUBSYSTEM=="input", ATTR{name}=="${cfg.device}", ATTR{device/speed}="${toString cfg.speed}", ATTR{device/sensitivity}="${toString cfg.sensitivity}"
''; '';
system.activationScripts.trackpoint = systemd.services.trackpoint = {
'' wantedBy = [ "sysinit.target" ] ;
${config.systemd.package}/bin/udevadm trigger --attr-match=name="${cfg.device}" before = [ "sysinit.target" "shutdown.target" ];
conflicts = [ "shutdown.target" ];
unitConfig.DefaultDependencies = false;
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
serviceConfig.ExecStart = ''
${config.systemd.package}/bin/udevadm trigger --attr-match=name="${cfg.device}
''; '';
};
}) })
(mkIf (cfg.emulateWheel) { (mkIf (cfg.emulateWheel) {

View file

@ -85,35 +85,44 @@ in
}; };
}; };
###### wrappers activation script
system.activationScripts.vmwareWrappers =
lib.stringAfter [ "specialfs" "users" ]
''
mkdir -p "${parentWrapperDir}"
chmod 755 "${parentWrapperDir}"
# We want to place the tmpdirs for the wrappers to the parent dir.
wrapperDir=$(mktemp --directory --tmpdir="${parentWrapperDir}" wrappers.XXXXXXXXXX)
chmod a+rx "$wrapperDir"
${lib.concatStringsSep "\n" (vmwareWrappers)}
if [ -L ${wrapperDir} ]; then
# Atomically replace the symlink
# See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/
old=$(readlink -f ${wrapperDir})
if [ -e "${wrapperDir}-tmp" ]; then
rm --force --recursive "${wrapperDir}-tmp"
fi
ln --symbolic --force --no-dereference "$wrapperDir" "${wrapperDir}-tmp"
mv --no-target-directory "${wrapperDir}-tmp" "${wrapperDir}"
rm --force --recursive "$old"
else
# For initial setup
ln --symbolic "$wrapperDir" "${wrapperDir}"
fi
'';
# Services # Services
systemd.services."vmware-wrappers" = {
description = "Create VMVare Wrappers";
wantedBy = [ "multi-user.target" ];
before = [
"vmware-authdlauncher.service"
"vmware-networks-configuration.service"
"vmware-networks.service"
"vmware-usbarbitrator.service"
];
after = [ "systemd-sysusers.service" ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
script = ''
mkdir -p "${parentWrapperDir}"
chmod 755 "${parentWrapperDir}"
# We want to place the tmpdirs for the wrappers to the parent dir.
wrapperDir=$(mktemp --directory --tmpdir="${parentWrapperDir}" wrappers.XXXXXXXXXX)
chmod a+rx "$wrapperDir"
${lib.concatStringsSep "\n" (vmwareWrappers)}
if [ -L ${wrapperDir} ]; then
# Atomically replace the symlink
# See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/
old=$(readlink -f ${wrapperDir})
if [ -e "${wrapperDir}-tmp" ]; then
rm --force --recursive "${wrapperDir}-tmp"
fi
ln --symbolic --force --no-dereference "$wrapperDir" "${wrapperDir}-tmp"
mv --no-target-directory "${wrapperDir}-tmp" "${wrapperDir}"
rm --force --recursive "$old"
else
# For initial setup
ln --symbolic "$wrapperDir" "${wrapperDir}"
fi
'';
};
systemd.services."vmware-authdlauncher" = { systemd.services."vmware-authdlauncher" = {
description = "VMware Authentication Daemon"; description = "VMware Authentication Daemon";
serviceConfig = { serviceConfig = {

View file

@ -13,9 +13,9 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
''; '';
# ensure the directory to be monitored exists before incron is started # ensure the directory to be monitored exists before incron is started
system.activationScripts.incronTest = '' systemd.tmpfiles.settings.incron-test = {
mkdir /test "/test".d = { };
''; };
}; };
testScript = '' testScript = ''

View file

@ -13,10 +13,12 @@ in {
# The only thing the client needs to do is download a file. # The only thing the client needs to do is download a file.
client = { ... }: { client = { ... }: {
services.davfs2.enable = true; services.davfs2.enable = true;
system.activationScripts.davfs2-secrets = '' systemd.tmpfiles.settings.nextcloud = {
echo "http://nextcloud/remote.php/dav/files/${adminuser} ${adminuser} ${adminpass}" > /tmp/davfs2-secrets "/tmp/davfs2-secrets"."f+" = {
chmod 600 /tmp/davfs2-secrets mode = "0600";
''; argument = "http://nextcloud/remote.php/dav/files/${adminuser} ${adminuser} ${adminpass}";
};
};
virtualisation.fileSystems = { virtualisation.fileSystems = {
"/mnt/dav" = { "/mnt/dav" = {
device = "http://nextcloud/remote.php/dav/files/${adminuser}"; device = "http://nextcloud/remote.php/dav/files/${adminuser}";