Convert to tabs

This commit is contained in:
Greg Hellings
2023-12-12 16:32:24 -06:00
parent 35de7160ca
commit 98f1740f97
3 changed files with 335 additions and 335 deletions
+126 -126
View File
@@ -1,131 +1,131 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
{ {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
]; ];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
git git
(python3.withPackages (p: with p; [ pip virtualenv ])) (python3.withPackages (p: with p; [ pip virtualenv ]))
tmux tmux
tree tree
vim vim
xonsh xonsh
]; ];
services = { services = {
openssh.enable = true; openssh.enable = true;
}; };
systemd.services = let systemd.services = let
def = id: { def = id: {
enable = true; enable = true;
ephemeral = false; ephemeral = false;
extraEnvironment = { extraEnvironment = {
HTTP_PORT_MIN = builtins.toString (8000 + id); HTTP_PORT_MIN = builtins.toString (8000 + id);
HTTP_PORT_MAX = builtins.toString (8000 + id); HTTP_PORT_MAX = builtins.toString (8000 + id);
}; };
extraLabels = [ "nixos" "isaiah" ]; extraLabels = [ "nixos" "isaiah" ];
extraPackages = with pkgs; [ extraPackages = with pkgs; [
config.virtualisation.virtualbox.host.package config.virtualisation.virtualbox.host.package
curl curl
gawk gawk
packer packer
pup pup
(python3.withPackages (p: with p; [ pip virtualenv ])) (python3.withPackages (p: with p; [ pip virtualenv ]))
qemu_full qemu_full
qemu_kvm qemu_kvm
xonsh xonsh
xorriso xorriso
]; ];
name = "isaiah-nix-${builtins.toString id}"; name = "isaiah-nix-${builtins.toString id}";
nodeRuntimes = [ "node20" ]; nodeRuntimes = [ "node20" ];
package = pkgs.github-runner; package = pkgs.github-runner;
replace = true; replace = true;
runnerGroup = null; runnerGroup = null;
serviceOverrides = { serviceOverrides = {
Group = "vboxusers"; Group = "vboxusers";
}; };
tokenFile = "/etc/github_token"; tokenFile = "/etc/github_token";
user = "runner"; user = "runner";
url = "https://github.com/greg-hellings/vms"; url = "https://github.com/greg-hellings/vms";
workDir = "/home/runner/${builtins.toString id}"; workDir = "/home/runner/${builtins.toString id}";
}; };
runner = (import ./runner.nix); runner = (import ./runner.nix);
in { in {
gh-one = (runner { inherit config lib pkgs; svcName = "gh-one"; cfg = def 1; }); gh-one = (runner { inherit config lib pkgs; svcName = "gh-one"; cfg = def 1; });
gh-two = (runner { inherit config lib pkgs; svcName = "gh-two"; cfg = def 2; }); gh-two = (runner { inherit config lib pkgs; svcName = "gh-two"; cfg = def 2; });
gh-three = (runner { inherit config lib pkgs; svcName = "gh-three"; cfg = def 3; }); gh-three = (runner { inherit config lib pkgs; svcName = "gh-three"; cfg = def 3; });
gh-four = (runner { inherit config lib pkgs; svcName = "gh-four"; cfg = def 4; }); gh-four = (runner { inherit config lib pkgs; svcName = "gh-four"; cfg = def 4; });
gh-five = (runner { inherit config lib pkgs; svcName = "gh-five"; cfg = def 5; }); gh-five = (runner { inherit config lib pkgs; svcName = "gh-five"; cfg = def 5; });
}; };
networking = { networking = {
hostName = "myself"; hostName = "myself";
useDHCP = false; useDHCP = false;
defaultGateway = { defaultGateway = {
address = " 10.42.1.1"; address = " 10.42.1.1";
interface = "enp38s0"; interface = "enp38s0";
}; };
interfaces.enp38s0 = { interfaces.enp38s0 = {
ipv4.addresses = [ { ipv4.addresses = [ {
address = "10.42.1.6"; address = "10.42.1.6";
prefixLength = 16; prefixLength = 16;
} ]; } ];
}; };
nameservers = [ nameservers = [
"10.42.1.5" "10.42.1.5"
]; ];
}; };
virtualisation = { virtualisation = {
libvirtd = { libvirtd = {
enable = false; enable = false;
onBoot = "ignore"; onBoot = "ignore";
}; };
virtualbox.host = { virtualbox.host = {
enable = true; enable = true;
enableExtensionPack = true; enableExtensionPack = true;
}; };
}; };
users = { users = {
users = { users = {
runner = { runner = {
extraGroups = [ extraGroups = [
"kvm" "kvm"
"vboxusers" "vboxusers"
]; ];
group = "runner"; group = "runner";
isNormalUser = true; isNormalUser = true;
}; };
greg = { greg = {
extraGroups = [ extraGroups = [
"kvm" "kvm"
"sudo" "sudo"
"vboxusers" "vboxusers"
"wheel" "wheel"
]; ];
isNormalUser = true; isNormalUser = true;
}; };
}; };
groups.runner = {}; groups.runner = {};
}; };
system.stateVersion = lib.mkForce "24.05"; system.stateVersion = lib.mkForce "24.05";
boot = { boot = {
extraModprobeConfig = "options kvm_amd nested=1 vboxdrv"; extraModprobeConfig = "options kvm_amd nested=1 vboxdrv";
supportedFilesystems = [ "ntfs" ]; supportedFilesystems = [ "ntfs" ];
loader = { loader = {
efi = { efi = {
canTouchEfiVariables = true; canTouchEfiVariables = true;
efiSysMountPoint = "/boot"; efiSysMountPoint = "/boot";
}; };
systemd-boot = { systemd-boot = {
enable = true; enable = true;
configurationLimit = 10; configurationLimit = 10;
}; };
}; };
}; };
nixpkgs.config = { nixpkgs.config = {
allowUnfree = true; allowUnfree = true;
permittedInsecurePackages = [ permittedInsecurePackages = [
"nodejs-16.20.2" "nodejs-16.20.2"
]; ];
}; };
} }
+38 -38
View File
@@ -1,51 +1,51 @@
# Do not modify this file! It was generated by nixos-generate-config # Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes # and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead. # to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }: { config, lib, pkgs, modulesPath, ... }:
{ {
imports = imports =
[ (modulesPath + "/installer/scan/not-detected.nix") [ (modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "sr_mod" ]; boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ]; boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ]; boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ]; boot.extraModulePackages = [ ];
fileSystems."/" = fileSystems."/" =
{ device = "/dev/disk/by-uuid/714744ca-dd9d-4713-b571-c6ccfbf56d79"; { device = "/dev/disk/by-uuid/714744ca-dd9d-4713-b571-c6ccfbf56d79";
fsType = "btrfs"; fsType = "btrfs";
options = [ "subvol=nixos" ]; options = [ "subvol=nixos" ];
}; };
fileSystems."/home" = fileSystems."/home" =
{ device = "/dev/disk/by-uuid/714744ca-dd9d-4713-b571-c6ccfbf56d79"; { device = "/dev/disk/by-uuid/714744ca-dd9d-4713-b571-c6ccfbf56d79";
fsType = "btrfs"; fsType = "btrfs";
options = [ "subvol=home" ]; options = [ "subvol=home" ];
}; };
fileSystems."/boot" = fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/29E7-E20C"; { device = "/dev/disk/by-uuid/29E7-E20C";
fsType = "vfat"; fsType = "vfat";
}; };
fileSystems."/myvol" = fileSystems."/myvol" =
{ device = "/dev/nvme0n1p1"; { device = "/dev/nvme0n1p1";
fsType = "btrfs"; fsType = "btrfs";
}; };
swapDevices = [ ]; swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's # (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction # still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`. # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true; networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp38s0.useDHCP = lib.mkDefault true; # networking.interfaces.enp38s0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp39s0.useDHCP = lib.mkDefault true; # networking.interfaces.enp39s0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp42s0f3u5u3c2.useDHCP = lib.mkDefault true; # networking.interfaces.enp42s0f3u5u3c2.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
} }
+171 -171
View File
@@ -6,13 +6,13 @@
, svcName , svcName
, systemdDir ? "${svcName}/${cfg.name}" , systemdDir ? "${svcName}/${cfg.name}"
# %t: Runtime directory root (usually /run); see systemd.unit(5) # %t: Runtime directory root (usually /run); see systemd.unit(5)
, runtimeDir ? "%t/${systemdDir}" , runtimeDir ? "%t/${systemdDir}"
# %S: State directory root (usually /var/lib); see systemd.unit(5) # %S: State directory root (usually /var/lib); see systemd.unit(5)
, stateDir ? "%S/${systemdDir}" , stateDir ? "%S/${systemdDir}"
# %L: Log directory root (usually /var/log); see systemd.unit(5) # %L: Log directory root (usually /var/log); see systemd.unit(5)
, logsDir ? "%L/${systemdDir}" , logsDir ? "%L/${systemdDir}"
# Name of file stored in service state directory # Name of file stored in service state directory
, currentConfigTokenFilename ? ".current-token" , currentConfigTokenFilename ? ".current-token"
, ... , ...
@@ -21,187 +21,187 @@
with lib; with lib;
let let
workDir = if cfg.workDir == null then runtimeDir else cfg.workDir; workDir = if cfg.workDir == null then runtimeDir else cfg.workDir;
package = cfg.package.override { inherit (cfg) nodeRuntimes; }; package = cfg.package.override { inherit (cfg) nodeRuntimes; };
in in
{ {
description = "GitHub Actions runner"; description = "GitHub Actions runner";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ]; wants = [ "network-online.target" ];
after = [ "network.target" "network-online.target" ]; after = [ "network.target" "network-online.target" ];
environment = { environment = {
HOME = workDir; HOME = workDir;
RUNNER_ROOT = stateDir; RUNNER_ROOT = stateDir;
} // cfg.extraEnvironment; } // cfg.extraEnvironment;
path = (with pkgs; [ path = (with pkgs; [
bash bash
coreutils coreutils
git git
gnutar gnutar
gzip gzip
]) ++ [ ]) ++ [
config.nix.package config.nix.package
] ++ cfg.extraPackages; ] ++ cfg.extraPackages;
serviceConfig = mkMerge [ serviceConfig = mkMerge [
{ {
ExecStart = "${package}/bin/Runner.Listener run --startuptype service"; ExecStart = "${package}/bin/Runner.Listener run --startuptype service";
# Does the following, sequentially: # Does the following, sequentially:
# - If the module configuration or the token has changed, purge the state directory, # - If the module configuration or the token has changed, purge the state directory,
# and create the current and the new token file with the contents of the configured # and create the current and the new token file with the contents of the configured
# token. While both files have the same content, only the later is accessible by # token. While both files have the same content, only the later is accessible by
# the service user. # the service user.
# - Configure the runner using the new token file. When finished, delete it. # - Configure the runner using the new token file. When finished, delete it.
# - Set up the directory structure by creating the necessary symlinks. # - Set up the directory structure by creating the necessary symlinks.
ExecStartPre = ExecStartPre =
let let
# Wrapper script which expects the full path of the state, working and logs # Wrapper script which expects the full path of the state, working and logs
# directory as arguments. Overrides the respective systemd variables to provide # directory as arguments. Overrides the respective systemd variables to provide
# unambiguous directory names. This becomes relevant, for example, if the # unambiguous directory names. This becomes relevant, for example, if the
# caller overrides any of the StateDirectory=, RuntimeDirectory= or LogDirectory= # caller overrides any of the StateDirectory=, RuntimeDirectory= or LogDirectory=
# to contain more than one directory. This causes systemd to set the respective # to contain more than one directory. This causes systemd to set the respective
# environment variables with the path of all of the given directories, separated # environment variables with the path of all of the given directories, separated
# by a colon. # by a colon.
writeScript = name: lines: pkgs.writeShellScript "${svcName}-${name}.sh" '' writeScript = name: lines: pkgs.writeShellScript "${svcName}-${name}.sh" ''
set -euo pipefail set -euo pipefail
STATE_DIRECTORY="$1" STATE_DIRECTORY="$1"
WORK_DIRECTORY="$2" WORK_DIRECTORY="$2"
LOGS_DIRECTORY="$3" LOGS_DIRECTORY="$3"
${lines} ${lines}
''; '';
runnerRegistrationConfig = getAttrs [ "name" "tokenFile" "url" "runnerGroup" "extraLabels" "ephemeral" "workDir" ] cfg; runnerRegistrationConfig = getAttrs [ "name" "tokenFile" "url" "runnerGroup" "extraLabels" "ephemeral" "workDir" ] cfg;
newConfigPath = builtins.toFile "${svcName}-config.json" (builtins.toJSON runnerRegistrationConfig); newConfigPath = builtins.toFile "${svcName}-config.json" (builtins.toJSON runnerRegistrationConfig);
currentConfigPath = "$STATE_DIRECTORY/.nixos-current-config.json"; currentConfigPath = "$STATE_DIRECTORY/.nixos-current-config.json";
newConfigTokenPath = "$STATE_DIRECTORY/.new-token"; newConfigTokenPath = "$STATE_DIRECTORY/.new-token";
currentConfigTokenPath = "$STATE_DIRECTORY/${currentConfigTokenFilename}"; currentConfigTokenPath = "$STATE_DIRECTORY/${currentConfigTokenFilename}";
runnerCredFiles = [ runnerCredFiles = [
".credentials" ".credentials"
".credentials_rsaparams" ".credentials_rsaparams"
".runner" ".runner"
]; ];
unconfigureRunner = writeScript "unconfigure" '' unconfigureRunner = writeScript "unconfigure" ''
copy_tokens() { copy_tokens() {
# Copy the configured token file to the state dir and allow the service user to read the file # Copy the configured token file to the state dir and allow the service user to read the file
install --mode=666 ${escapeShellArg cfg.tokenFile} "${newConfigTokenPath}" install --mode=666 ${escapeShellArg cfg.tokenFile} "${newConfigTokenPath}"
# Also copy current file to allow for a diff on the next start # Also copy current file to allow for a diff on the next start
install --mode=600 ${escapeShellArg cfg.tokenFile} "${currentConfigTokenPath}" install --mode=600 ${escapeShellArg cfg.tokenFile} "${currentConfigTokenPath}"
} }
clean_state() { clean_state() {
find "$STATE_DIRECTORY/" -mindepth 1 -delete find "$STATE_DIRECTORY/" -mindepth 1 -delete
copy_tokens copy_tokens
} }
diff_config() { diff_config() {
changed=0 changed=0
# Check for module config changes # Check for module config changes
[[ -f "${currentConfigPath}" ]] \ [[ -f "${currentConfigPath}" ]] \
&& ${pkgs.diffutils}/bin/diff -q '${newConfigPath}' "${currentConfigPath}" >/dev/null 2>&1 \ && ${pkgs.diffutils}/bin/diff -q '${newConfigPath}' "${currentConfigPath}" >/dev/null 2>&1 \
|| changed=1 || changed=1
# Also check the content of the token file # Also check the content of the token file
[[ -f "${currentConfigTokenPath}" ]] \ [[ -f "${currentConfigTokenPath}" ]] \
&& ${pkgs.diffutils}/bin/diff -q "${currentConfigTokenPath}" ${escapeShellArg cfg.tokenFile} >/dev/null 2>&1 \ && ${pkgs.diffutils}/bin/diff -q "${currentConfigTokenPath}" ${escapeShellArg cfg.tokenFile} >/dev/null 2>&1 \
|| changed=1 || changed=1
# If the config has changed, remove old state and copy tokens # If the config has changed, remove old state and copy tokens
if [[ "$changed" -eq 1 ]]; then if [[ "$changed" -eq 1 ]]; then
echo "Config has changed, removing old runner state." echo "Config has changed, removing old runner state."
echo "The old runner will still appear in the GitHub Actions UI." \ echo "The old runner will still appear in the GitHub Actions UI." \
"You have to remove it manually." "You have to remove it manually."
clean_state clean_state
fi fi
} }
if [[ "${optionalString cfg.ephemeral "1"}" ]]; then if [[ "${optionalString cfg.ephemeral "1"}" ]]; then
# In ephemeral mode, we always want to start with a clean state # In ephemeral mode, we always want to start with a clean state
clean_state clean_state
elif [[ "$(ls -A "$STATE_DIRECTORY")" ]]; then elif [[ "$(ls -A "$STATE_DIRECTORY")" ]]; then
# There are state files from a previous run; diff them to decide if we need a new registration # There are state files from a previous run; diff them to decide if we need a new registration
diff_config diff_config
else else
# The state directory is entirely empty which indicates a first start # The state directory is entirely empty which indicates a first start
copy_tokens copy_tokens
fi fi
# Always clean workDir # Always clean workDir
find -H "$WORK_DIRECTORY" -mindepth 1 -delete find -H "$WORK_DIRECTORY" -mindepth 1 -delete
''; '';
configureRunner = writeScript "configure" '' configureRunner = writeScript "configure" ''
if [[ -e "${newConfigTokenPath}" ]]; then if [[ -e "${newConfigTokenPath}" ]]; then
echo "Configuring GitHub Actions Runner" echo "Configuring GitHub Actions Runner"
args=( args=(
--unattended --unattended
--disableupdate --disableupdate
--work "$WORK_DIRECTORY" --work "$WORK_DIRECTORY"
--url ${escapeShellArg cfg.url} --url ${escapeShellArg cfg.url}
--labels ${escapeShellArg (concatStringsSep "," cfg.extraLabels)} --labels ${escapeShellArg (concatStringsSep "," cfg.extraLabels)}
--name ${escapeShellArg cfg.name} --name ${escapeShellArg cfg.name}
${optionalString cfg.replace "--replace"} ${optionalString cfg.replace "--replace"}
${optionalString (cfg.runnerGroup != null) "--runnergroup ${escapeShellArg cfg.runnerGroup}"} ${optionalString (cfg.runnerGroup != null) "--runnergroup ${escapeShellArg cfg.runnerGroup}"}
${optionalString cfg.ephemeral "--ephemeral"} ${optionalString cfg.ephemeral "--ephemeral"}
) )
# If the token file contains a PAT (i.e., it starts with "ghp_" or "github_pat_"), we have to use the --pat option, # If the token file contains a PAT (i.e., it starts with "ghp_" or "github_pat_"), we have to use the --pat option,
# if it is not a PAT, we assume it contains a registration token and use the --token option # if it is not a PAT, we assume it contains a registration token and use the --token option
token=$(<"${newConfigTokenPath}") token=$(<"${newConfigTokenPath}")
if [[ "$token" =~ ^ghp_* ]] || [[ "$token" =~ ^github_pat_* ]]; then if [[ "$token" =~ ^ghp_* ]] || [[ "$token" =~ ^github_pat_* ]]; then
args+=(--pat "$token") args+=(--pat "$token")
else else
args+=(--token "$token") args+=(--token "$token")
fi fi
${package}/bin/Runner.Listener configure "''${args[@]}" ${package}/bin/Runner.Listener configure "''${args[@]}"
# Move the automatically created _diag dir to the logs dir # Move the automatically created _diag dir to the logs dir
mkdir -p "$STATE_DIRECTORY/_diag" mkdir -p "$STATE_DIRECTORY/_diag"
cp -r "$STATE_DIRECTORY/_diag/." "$LOGS_DIRECTORY/" cp -r "$STATE_DIRECTORY/_diag/." "$LOGS_DIRECTORY/"
rm -rf "$STATE_DIRECTORY/_diag/" rm -rf "$STATE_DIRECTORY/_diag/"
# Cleanup token from config # Cleanup token from config
rm "${newConfigTokenPath}" rm "${newConfigTokenPath}"
# Symlink to new config # Symlink to new config
ln -s '${newConfigPath}' "${currentConfigPath}" ln -s '${newConfigPath}' "${currentConfigPath}"
fi fi
''; '';
setupWorkDir = writeScript "setup-work-dirs" '' setupWorkDir = writeScript "setup-work-dirs" ''
# Link _diag dir # Link _diag dir
ln -s "$LOGS_DIRECTORY" "$WORK_DIRECTORY/_diag" ln -s "$LOGS_DIRECTORY" "$WORK_DIRECTORY/_diag"
# Link the runner credentials to the work dir # Link the runner credentials to the work dir
ln -s "$STATE_DIRECTORY"/{${lib.concatStringsSep "," runnerCredFiles}} "$WORK_DIRECTORY/" ln -s "$STATE_DIRECTORY"/{${lib.concatStringsSep "," runnerCredFiles}} "$WORK_DIRECTORY/"
''; '';
in in
map (x: "${x} ${escapeShellArgs [ stateDir workDir logsDir ]}") [ map (x: "${x} ${escapeShellArgs [ stateDir workDir logsDir ]}") [
"+${unconfigureRunner}" # runs as root "+${unconfigureRunner}" # runs as root
configureRunner configureRunner
setupWorkDir setupWorkDir
]; ];
# If running in ephemeral mode, restart the service on-exit (i.e., successful de-registration of the runner) # If running in ephemeral mode, restart the service on-exit (i.e., successful de-registration of the runner)
# to trigger a fresh registration. # to trigger a fresh registration.
Restart = if cfg.ephemeral then "on-success" else "no"; Restart = if cfg.ephemeral then "on-success" else "no";
# If the runner exits with `ReturnCode.RetryableError = 2`, always restart the service: # If the runner exits with `ReturnCode.RetryableError = 2`, always restart the service:
# https://github.com/actions/runner/blob/40ed7f8/src/Runner.Common/Constants.cs#L146 # https://github.com/actions/runner/blob/40ed7f8/src/Runner.Common/Constants.cs#L146
RestartForceExitStatus = [ 2 ]; RestartForceExitStatus = [ 2 ];
# Contains _diag # Contains _diag
LogsDirectory = [ systemdDir ]; LogsDirectory = [ systemdDir ];
# Default RUNNER_ROOT which contains ephemeral Runner data # Default RUNNER_ROOT which contains ephemeral Runner data
RuntimeDirectory = [ systemdDir ]; RuntimeDirectory = [ systemdDir ];
# Home of persistent runner data, e.g., credentials # Home of persistent runner data, e.g., credentials
StateDirectory = [ systemdDir ]; StateDirectory = [ systemdDir ];
StateDirectoryMode = "0700"; StateDirectoryMode = "0700";
WorkingDirectory = workDir; WorkingDirectory = workDir;
InaccessiblePaths = [ InaccessiblePaths = [
# Token file path given in the configuration, if visible to the service # Token file path given in the configuration, if visible to the service
"-${cfg.tokenFile}" "-${cfg.tokenFile}"
# Token file in the state directory # Token file in the state directory
"${stateDir}/${currentConfigTokenFilename}" "${stateDir}/${currentConfigTokenFilename}"
]; ];
KillSignal = "SIGINT"; KillSignal = "SIGINT";
} }
(mkIf (cfg.user != null) { User = cfg.user; }) (mkIf (cfg.user != null) { User = cfg.user; })
cfg.serviceOverrides cfg.serviceOverrides
]; ];
} }