Merge branch 'main' of gh:greg-hellings/nixos-config

This commit is contained in:
Greg Hellings
2023-12-12 20:45:52 -06:00
11 changed files with 396 additions and 157 deletions
+4
View File
@@ -0,0 +1,4 @@
{ ... }:
{
}
+1
View File
@@ -2,3 +2,4 @@ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINAX6pNx5mbwIa8X+GzktyNijfYmJUpgROFpRxSW9js0
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFWPSFQT0AH77wrwRhiskcBS0w4ZakBRdJywYYBsnm3S greg@genesis
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMYzms+KIe5/bYF3uCyFjA5e1AgMPLIA3c4k417coqBe gregory.hellings@ls23003
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINnRc/kBhxcjpUtiRQY+BXnSObdp0jFL1395wAQxJip7 greg@jude
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAl6DJVrPSujvJSAEA5Q8tRrzfJs/c6DMwqwQEUFffIR greg@myself
+1
View File
@@ -51,6 +51,7 @@ in {
linode = machine { name = "linode"; };
lappy = machine { name = "lappy"; };
mm = unstable { name = "mm"; };
myself = unstable { name = "myself"; };
iso = machine { name = "iso"; };
iso-beta = unstable { name = "iso"; };
# nix build '.#nixosConfigurations.wsl.config.system.build.installer'
-1
View File
@@ -8,7 +8,6 @@
./nextcloud.nix
./nginx.nix
./postgres.nix
./rei.nix
./synapse.nix
];
greg.home = false;
+1 -89
View File
@@ -23,6 +23,7 @@ in {
services = {
forgejo = rec {
enable = true;
package = pkgs.unstable.forgejo;
database = {
type = "postgres";
user = "forgejo";
@@ -132,99 +133,10 @@ in {
# CI SERVICES
##########
##########################################################################################
# Service user
users.users.drone = {
isSystemUser = true;
group = "drone";
home = droneDir;
};
users.groups.drone = {};
# Environment secrets
age.secrets.drone = {
file = ../../secrets/drone.age;
owner = "root";
};
virtualisation.oci-containers = {
backend = "podman";
containers = {
"drone" = {
environment = {
DRONE_GITEA_SERVER = "https://${srcDomain}";
DRONE_LOGS_DEBUG = "true";
DRONE_SERVER_HOST = ciDomain;
DRONE_SERVER_PROTO = "https";
DRONE_SERVER_PROXY_HOST = ciDomain;
DRONE_SERVER_PROXY_PROTO = "https";
DRONE_TLS_AUTOCERT = "false"; # Suppress it generating SSL certificates, as our proxy handles that
};
environmentFiles = [
"/run/agenix/drone"
];
extraOptions = [ "--pull=newer" ];
image = "drone/drone:2.17";
ports = [ "${ciPort}:80" ];
volumes = [ "${droneDir}:/data" ];
};
"drone-docker" = {
environment = droneWorkerEnvironment;
environmentFiles = [
"/run/agenix/drone"
];
extraOptions = [ "--pull=newer" ];
image = "drone/drone-runner-docker:1.8";
volumes = [ "/run/podman/podman.sock:/var/run/docker.sock" ];
};
};
};
systemd.services = {
"podman-drone".serviceConfig = {
StateDirectory = "drone";
StateDirectoryMode = pkgs.lib.mkForce "0777";
WorkingDirectory = droneDir;
};
"drone-exec-runner" = {
environment = droneWorkerEnvironment;
description = "Drone pipeline runner that executes locally";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
path = with pkgs; [
bash
drone-runner-exec
git
podman
];
preStart = ''
mkdir -p ${execWorkDir}
cat /run/agenix/drone > ${execWorkDir}/conf.env
echo "" >> ${execWorkDir}/conf.env
'';
script = "exec ${pkgs.drone-runner-exec}/bin/drone-runner-exec daemon ${execWorkDir}/conf.env";
serviceConfig = {
StateDirectory = "drone-exec";
StateDirectoryMode = pkgs.lib.mkForce "0777";
};
};
};
greg.proxies."${ciDomain}" = {
target = "http://localhost:${ciPort}";
ssl = true;
genAliases = false;
};
##########################################################################################
###########
# CI WORKERS
##########
##########################################################################################
virtualisation.podman = {
enable = true;
dockerCompat = true;
-27
View File
@@ -1,27 +0,0 @@
{ config, ... }:
{
services.monica = {
enable = true;
appKeyFile = config.age.secrets.monica.path;
appURL = "https://people.thehellings.com";
database = {
port = 5432;
};
nginx = {
addSSL = true;
enableACME = true;
serverAliases = [ "people.thehellings.com" ];
};
};
age.secrets.monica = {
file = ../../secrets/monica.age;
owner = "monica";
};
greg.backup.jobs.monica = {
src = "/var/lib/monica";
dest = "monica";
user = "monica";
};
}
+131
View File
@@ -0,0 +1,131 @@
{ config, pkgs, lib, ... }:
{
imports = [
./hardware-configuration.nix
];
environment.systemPackages = with pkgs; [
git
(python3.withPackages (p: with p; [ pip virtualenv ]))
tmux
tree
vim
xonsh
];
services = {
openssh.enable = true;
};
systemd.services = let
def = id: {
enable = true;
ephemeral = false;
extraEnvironment = {
HTTP_PORT_MIN = builtins.toString (8000 + id);
HTTP_PORT_MAX = builtins.toString (8000 + id);
};
extraLabels = [ "nixos" "isaiah" ];
extraPackages = with pkgs; [
config.virtualisation.virtualbox.host.package
curl
gawk
packer
pup
(python3.withPackages (p: with p; [ pip virtualenv ]))
qemu_full
qemu_kvm
xonsh
xorriso
];
name = "isaiah-nix-${builtins.toString id}";
nodeRuntimes = [ "node20" ];
package = pkgs.github-runner;
replace = true;
runnerGroup = null;
serviceOverrides = {
Group = "vboxusers";
};
tokenFile = "/etc/github_token";
user = "runner";
url = "https://github.com/greg-hellings/vms";
workDir = "/home/runner/${builtins.toString id}";
};
runner = (import ./runner.nix);
in {
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-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-five = (runner { inherit config lib pkgs; svcName = "gh-five"; cfg = def 5; });
};
networking = {
hostName = "myself";
useDHCP = false;
defaultGateway = {
address = " 10.42.1.1";
interface = "enp38s0";
};
interfaces.enp38s0 = {
ipv4.addresses = [ {
address = "10.42.1.6";
prefixLength = 16;
} ];
};
nameservers = [
"10.42.1.5"
];
};
virtualisation = {
libvirtd = {
enable = false;
onBoot = "ignore";
};
virtualbox.host = {
enable = true;
enableExtensionPack = true;
};
};
users = {
users = {
runner = {
extraGroups = [
"kvm"
"vboxusers"
];
group = "runner";
isNormalUser = true;
};
greg = {
extraGroups = [
"kvm"
"sudo"
"vboxusers"
"wheel"
];
isNormalUser = true;
};
};
groups.runner = {};
};
system.stateVersion = lib.mkForce "24.05";
boot = {
extraModprobeConfig = "options kvm_amd nested=1 vboxdrv";
supportedFilesystems = [ "ntfs" ];
loader = {
efi = {
canTouchEfiVariables = true;
efiSysMountPoint = "/boot";
};
systemd-boot = {
enable = true;
configurationLimit = 10;
};
};
};
nixpkgs.config = {
allowUnfree = true;
permittedInsecurePackages = [
"nodejs-16.20.2"
];
};
}
+51
View File
@@ -0,0 +1,51 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/714744ca-dd9d-4713-b571-c6ccfbf56d79";
fsType = "btrfs";
options = [ "subvol=nixos" ];
};
fileSystems."/home" =
{ device = "/dev/disk/by-uuid/714744ca-dd9d-4713-b571-c6ccfbf56d79";
fsType = "btrfs";
options = [ "subvol=home" ];
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/29E7-E20C";
fsType = "vfat";
};
fileSystems."/myvol" =
{ device = "/dev/nvme0n1p1";
fsType = "btrfs";
};
swapDevices = [ ];
# 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
# 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`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp38s0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp39s0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp42s0f3u5u3c2.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
+207
View File
@@ -0,0 +1,207 @@
{ config
, lib
, pkgs
, cfg ? config.services.github-runner
, svcName
, systemdDir ? "${svcName}/${cfg.name}"
# %t: Runtime directory root (usually /run); see systemd.unit(5)
, runtimeDir ? "%t/${systemdDir}"
# %S: State directory root (usually /var/lib); see systemd.unit(5)
, stateDir ? "%S/${systemdDir}"
# %L: Log directory root (usually /var/log); see systemd.unit(5)
, logsDir ? "%L/${systemdDir}"
# Name of file stored in service state directory
, currentConfigTokenFilename ? ".current-token"
, ...
}:
with lib;
let
workDir = if cfg.workDir == null then runtimeDir else cfg.workDir;
package = cfg.package.override { inherit (cfg) nodeRuntimes; };
in
{
description = "GitHub Actions runner";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network.target" "network-online.target" ];
environment = {
HOME = workDir;
RUNNER_ROOT = stateDir;
} // cfg.extraEnvironment;
path = (with pkgs; [
bash
coreutils
git
gnutar
gzip
]) ++ [
config.nix.package
] ++ cfg.extraPackages;
serviceConfig = mkMerge [
{
ExecStart = "${package}/bin/Runner.Listener run --startuptype service";
# Does the following, sequentially:
# - 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
# token. While both files have the same content, only the later is accessible by
# the service user.
# - Configure the runner using the new token file. When finished, delete it.
# - Set up the directory structure by creating the necessary symlinks.
ExecStartPre =
let
# Wrapper script which expects the full path of the state, working and logs
# directory as arguments. Overrides the respective systemd variables to provide
# unambiguous directory names. This becomes relevant, for example, if the
# caller overrides any of the StateDirectory=, RuntimeDirectory= or LogDirectory=
# 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
# by a colon.
writeScript = name: lines: pkgs.writeShellScript "${svcName}-${name}.sh" ''
set -euo pipefail
STATE_DIRECTORY="$1"
WORK_DIRECTORY="$2"
LOGS_DIRECTORY="$3"
${lines}
'';
runnerRegistrationConfig = getAttrs [ "name" "tokenFile" "url" "runnerGroup" "extraLabels" "ephemeral" "workDir" ] cfg;
newConfigPath = builtins.toFile "${svcName}-config.json" (builtins.toJSON runnerRegistrationConfig);
currentConfigPath = "$STATE_DIRECTORY/.nixos-current-config.json";
newConfigTokenPath = "$STATE_DIRECTORY/.new-token";
currentConfigTokenPath = "$STATE_DIRECTORY/${currentConfigTokenFilename}";
runnerCredFiles = [
".credentials"
".credentials_rsaparams"
".runner"
];
unconfigureRunner = writeScript "unconfigure" ''
copy_tokens() {
# 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}"
# Also copy current file to allow for a diff on the next start
install --mode=600 ${escapeShellArg cfg.tokenFile} "${currentConfigTokenPath}"
}
clean_state() {
find "$STATE_DIRECTORY/" -mindepth 1 -delete
copy_tokens
}
diff_config() {
changed=0
# Check for module config changes
[[ -f "${currentConfigPath}" ]] \
&& ${pkgs.diffutils}/bin/diff -q '${newConfigPath}' "${currentConfigPath}" >/dev/null 2>&1 \
|| changed=1
# Also check the content of the token file
[[ -f "${currentConfigTokenPath}" ]] \
&& ${pkgs.diffutils}/bin/diff -q "${currentConfigTokenPath}" ${escapeShellArg cfg.tokenFile} >/dev/null 2>&1 \
|| changed=1
# If the config has changed, remove old state and copy tokens
if [[ "$changed" -eq 1 ]]; then
echo "Config has changed, removing old runner state."
echo "The old runner will still appear in the GitHub Actions UI." \
"You have to remove it manually."
clean_state
fi
}
if [[ "${optionalString cfg.ephemeral "1"}" ]]; then
# In ephemeral mode, we always want to start with a clean state
clean_state
elif [[ "$(ls -A "$STATE_DIRECTORY")" ]]; then
# There are state files from a previous run; diff them to decide if we need a new registration
diff_config
else
# The state directory is entirely empty which indicates a first start
copy_tokens
fi
# Always clean workDir
find -H "$WORK_DIRECTORY" -mindepth 1 -delete
'';
configureRunner = writeScript "configure" ''
if [[ -e "${newConfigTokenPath}" ]]; then
echo "Configuring GitHub Actions Runner"
args=(
--unattended
--disableupdate
--work "$WORK_DIRECTORY"
--url ${escapeShellArg cfg.url}
--labels ${escapeShellArg (concatStringsSep "," cfg.extraLabels)}
--name ${escapeShellArg cfg.name}
${optionalString cfg.replace "--replace"}
${optionalString (cfg.runnerGroup != null) "--runnergroup ${escapeShellArg cfg.runnerGroup}"}
${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 it is not a PAT, we assume it contains a registration token and use the --token option
token=$(<"${newConfigTokenPath}")
if [[ "$token" =~ ^ghp_* ]] || [[ "$token" =~ ^github_pat_* ]]; then
args+=(--pat "$token")
else
args+=(--token "$token")
fi
${package}/bin/Runner.Listener configure "''${args[@]}"
# Move the automatically created _diag dir to the logs dir
mkdir -p "$STATE_DIRECTORY/_diag"
cp -r "$STATE_DIRECTORY/_diag/." "$LOGS_DIRECTORY/"
rm -rf "$STATE_DIRECTORY/_diag/"
# Cleanup token from config
rm "${newConfigTokenPath}"
# Symlink to new config
ln -s '${newConfigPath}' "${currentConfigPath}"
fi
'';
setupWorkDir = writeScript "setup-work-dirs" ''
# Link _diag dir
ln -s "$LOGS_DIRECTORY" "$WORK_DIRECTORY/_diag"
# Link the runner credentials to the work dir
ln -s "$STATE_DIRECTORY"/{${lib.concatStringsSep "," runnerCredFiles}} "$WORK_DIRECTORY/"
'';
in
map (x: "${x} ${escapeShellArgs [ stateDir workDir logsDir ]}") [
"+${unconfigureRunner}" # runs as root
configureRunner
setupWorkDir
];
# If running in ephemeral mode, restart the service on-exit (i.e., successful de-registration of the runner)
# to trigger a fresh registration.
Restart = if cfg.ephemeral then "on-success" else "no";
# 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
RestartForceExitStatus = [ 2 ];
# Contains _diag
LogsDirectory = [ systemdDir ];
# Default RUNNER_ROOT which contains ephemeral Runner data
RuntimeDirectory = [ systemdDir ];
# Home of persistent runner data, e.g., credentials
StateDirectory = [ systemdDir ];
StateDirectoryMode = "0700";
WorkingDirectory = workDir;
InaccessiblePaths = [
# Token file path given in the configuration, if visible to the service
"-${cfg.tokenFile}"
# Token file in the state directory
"${stateDir}/${currentConfigTokenFilename}"
];
KillSignal = "SIGINT";
}
(mkIf (cfg.user != null) { User = cfg.user; })
cfg.serviceOverrides
];
}
-38
View File
@@ -1,38 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 mOmPfg X+7CjshhqaThstA+gFDN23HSrhaJPG/GSkeZSXRXqTg
btgSgDtB5tPaJMMfvZqv/CKqdAcFXBeHEm2ZuC8Fzvs
-> ssh-ed25519 YJiRbw EW9X5R7XGczSOoC5fc0gsHgHcK3nTT/KQzjYurw9tws
MB2AyaJFx44mdbsK2sBAYjILuKZxXpd25Ci57q+WyiE
-> ssh-ed25519 Nl/5yA lsY4ttlGcJ3FyPDh/Eg2P/xNsynBLLLqKIbzyVUVoQ0
iEAOfYQyMaglmF+QeMatBLIgG5N2MUNDhM5LP/jNvuk
-> ssh-rsa FS7DnA
QkRi9WLtEknHPvJktTXdMOMkEwufHU0JStgCc11rFACJ4ZAa7qb3448jWwq5slFi
G27RoJnMFmEhYkh5Yd6ck5fg/MELTLq/RHaXKJKUwcoXdej8EGN7B3/t+boVdMDK
ab37gwrQl4ek/8wlx/zNowkESPtNuA87MIOjOj2H7ZgvpchTPFqeTmNdR0AcoNBb
Yi7K8Y5yM3UPeUrot+Ad5wvqUzrlK77NNwsybvFSjeTCulUHlTj1FtIJL6xobT0v
IM4Iy/KcwjKK3QoIyMfAt95KuIRMT5GIkfdbQU/wUWSAunX8RiRV4USlkAgg5c0k
b7kKrGkCweAxfwD4AblVXmK9kN8SAwIMhh41PRRvTbtUJNtjUkFA3gNArpsmmVPI
5tNM8JUoe9E2F9WgJHkX4ctcN+Qu3gDKJbg7zvpTNLgw0wgfjh9h54L3p8L46x9L
Ut60f5oAYb6IqZu65WwTv5souNtq1soT3n3H2Tp7NPzAmdBy6G/p++xZ1RNfSeij
dnMMxOGmBiJ14upRaC7s5JZFbu/cwnX/2qLaY0sBXlpJpOFAsKmwd9TEm0+WCaSk
m5moOT7Ivjl8alPXQuOaAZfDFZvpcgOxNviy8iB1D22xkdkXerzbsL07uzKayU0r
SCi6XJmzCtS7TKbfmDjbLnDcVPylkWaKxXw9ekKoZBJ7LPMSfBVVPD+Zap20tV+u
pnfTkLTW3o8pRjvcip1Hl9XuWvyMnIgoKL4CYc0JzLQAcieRn8tVbDXes0O1pAMh
1LWwBHYQyVFTM8qIqpbt/ndKTB9euqEMzeMJ3oMYhDIchozSSwmbsRMrKqh6gWdI
ldeYn3F9sEi5pQwDA0KikDCuT2W2oek+KlQKKquGln/nWf+5m6HTgwvA7QxgIfZi
wYuG9aYxOWwylyUDeHCUJLQ7RPJk6Cik32pVEMaviNwTOnQPBlyzFAwDlq+0crdj
dV+6vo/rRY3UyU7FCuWE8SVZFTwP4E8SfEiqYgOOhE/6jDkAo8q32eEgLMG/9hi4
Ro6Zy6DEv5la3cHZEUz550K8PHhajScoOiNK5RcG0YgBpLO93awz/iyrUDM2KuwS
xNFcpD165x9VpD2F9yNzvIqnTc3F5rDWa7PhffOV1ECdZaUgxhX8vuNN78sW+A4L
ppuJsVgx1rQFxtavUijFbS5Oona0aOlRLQop2BaW9an+PIRghsYJb/e3vjIGshVH
T5GxobOT7C7nxxs+ovdUUNmr0bWEINicQ9eTAHFx6pGSzgodMS1qrtROoY1L3+My
KVAeLhS7S4ls3W7TDm/AnqNoZG/HUOEyBkXOOzOGgZvD7/LiohNVzW/e1rLO2ziQ
QZByHxpv5gHZCUSq+3jqrA
-> ssh-ed25519 FpzvfQ ztmplW5LE5mbFG2oxsnUQ5botTjz1427pPi47zwKTVs
l2leKVw0HKME7pfbP2P/S6YgwR+UDnLfLdyOszZ+2Tw
-> ssh-ed25519 GdLgCQ otYdayZhkpESECiKhTSuaoJufMNzdGNboK06fMDWWnM
EmdT4yHbso/SqzJsHpYIHZpTUTUM+5V57yJkftIusSY
-> >p|7o:_-grease O:zn
55ZZNnY7ZEWxwJDA
--- 6P7VSDuTwwkEO0Kc9r1COPei6CpAdumIdh9nwWtKQd8
§˘Ëä[5¶{»Msݧ×G Í‹’Ęř O˛Ň¬¶j–9çdÉ;äú;¤/|ť"HaA† $i#DvňČćUÝ1[(Y5j<
-2
View File
@@ -34,8 +34,6 @@ in
"3proxy.age".publicKeys = everyone;
"monica.age".publicKeys = everyone;
"linode-forgejo-runner.age".publicKeys = everyone;
"jude-forgejo-runner.age".publicKeys = everyone;
}