From 8f833485da3a82b31bcaac4eeea8bfbd5ecd12bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20Schwarz=C3=A4ugl?=
-This file has 109215 words spanning 29343 lines and was last revised on 2025-11-25 19:55:28 +0100.
+This file has 113366 words spanning 30228 lines and was last revised on 2025-11-27 16:49:14 +0100.
@@ -978,7 +980,7 @@ This section defines my Emacs configuration. For a while, I considered to use ry
-My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2025-11-25 19:55:28 +0100)
+My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2025-11-27 16:49:14 +0100)
-
@@ -518,7 +519,7 @@
| Name | Hardware | Use | -|--------------------|-----------------------------------------------------|------------------------------------------------------| -|π» **pyramid** | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop | -|π» **bakery** | Lenovo Ideapad 720S-13IKB | Personal laptop | -|π» **machpizza** | MacBook Pro 2016 | MacOS reference and build sandbox | -|π **treehouse** | NVIDIA DGX Spark | Workstation, AI playground and home-manager reference| -|π₯οΈ **winters** | ASRock J4105-ITX, 32GB RAM | Secondary homeserver and data storgae | -|π₯οΈ **summers** | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM | Main homeserver running microvms, data storage | -|π₯οΈ **hintbooth** | HUNSN RM02, 8GB RAM | Router | -|βοΈ **milkywell** | Oracle Cloud: VM.Standard.E2.1.Micro | Authoritative DNS server | -|βοΈ **moonside** | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Proxy for local services, some lightweight services | -|βοΈ **belchsfactory**| Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Hydra builder and nix binary cache | -|βοΈ **monkeycave** | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Gaming server | -|βοΈ **eagleland** | Hetzner Cloud: CX23 | Mail server | -|π± **magicant** | Samsung Galaxy Z Flip 6 | Phone | -|πΏ **drugstore** | - | ISO installer configuration | -|πΏ **brickroad** | - | Kexec tarball | -|β **chaotheatre** | - | Demo config for checking out my configurtion | -|β **toto** | - | Helper configuration for bootstrapping a new system | +| Name | Hardware | Use | +|---------------------|-----------------------------------------------------|-----------------------------------------------------| +|π» **pyramid** | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop | +|π» **bakery** | Lenovo Ideapad 720S-13IKB | Personal laptop | +|π» **machpizza** | MacBook Pro 2016 | MacOS reference and build sandbox | +|π **treehouse** | NVIDIA DGX Spark | AI Workstation, remote builder, hm-only-reference | +|π₯οΈ **summers** | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM | Homeserver (microvms), remote builder, datastorage | +|π₯οΈ **winters** | ASRock J4105-ITX, 32GB RAM | Homeserver (IoT server in spe) | +|π₯οΈ **hintbooth** | HUNSN RM02, 8GB RAM | Router | +|βοΈ **stoicclub** | Cloud Server: 1 vCPUs, 8GB RAM | Authoritative dns server | +|βοΈ **liliputsteps** | Cloud Server: 1 vCPUs, 8GB RAM | SSH bastion | +|βοΈ **twothreetunnel**| Cloud Server: 2 vCPUs, 8GB RAM | Service proxy | +|βοΈ **eagleland** | Cloud Server: 2 vCPUs, 8GB RAM | Mailserver | +|βοΈ **moonside** | Cloud Server: 4 vCPUs, 24GB RAM | Gaming server, syncthing + lightweight services | +|βοΈ **belchsfactory** | Cloud Server: 4 vCPUs, 24GB RAM | Hydra builder and nix binarycache | +|π± **magicant** | Samsung Galaxy Z Flip 6 | Phone | +|πΏ **drugstore** | - | NixOS-installer ISO for bootstrapping new hosts | +|πΏ **brickroad** | - | Kexec tarball for bootstrapping low-memory machines | +|β **chaotheatre** | - | Demo config for checking out this configuration | +|β **toto** | - | Helper configuration for testing purposes |
These steps are required when setting up a normal NixOS host: @@ -1364,9 +1367,9 @@ If the new machine is home-manager only, perform these steps: 3) `home-manager --extra-experimental-features 'nix-command flakes' switch --flake .#$(hostname) --show-trace`
Currently, these adaptions are made to the configuration to account for bugs in upstream repos:
@@ -2724,7 +2727,7 @@ Otherwise, I define the function mkTemplates here which builds a na
Defines a formatter that can be called using nix flake format. While a nice utility, I have stronger tools to perform this job.
@@ -2750,6 +2753,21 @@ Defines a formatter that can be called using nix flake format. Whil
};
deadnix.enable = true;
statix.enable = true;
+ shfmt = {
+ enable = true;
+ indent_size = 4;
+ simplify = true;
+ # needed to replicate what my Emacs shfmt does
+ # there is no builtin option for space-redirects
+ package = pkgs.symlinkJoin {
+ name = "shfmt";
+ buildInputs = [ pkgs.makeWrapper ];
+ paths = [ pkgs.shfmt ];
+ postBuild = ''
+ wrapProgram $out/bin/shfmt --append-flags '-sr'
+ '';
+ };
+ };
shellcheck.enable = true;
};
settings.formatter.shellcheck.options = [
@@ -3858,14 +3876,26 @@ This is my main server that I run at home. It handles most tasks that require bi
proxyHost = "moonside";
server = {
inherit (config.repo.secrets.local.networking) localNetwork;
- garage = {
- data_dir = [
- {
- capacity = "200G";
- path = "/Vault/data/garage/main";
- }
+ restic = {
+ bucketName = "SwarselWinters";
+ paths = [
+ "/Vault/data/paperless"
+ "/Vault/data/koillection"
+ "/Vault/data/postgresql"
+ "/Vault/data/firefly-iii"
+ "/Vault/data/radicale"
+ "/Vault/data/matrix-synapse"
+ "/Vault/Eternor/Paperless"
+ "/Vault/Eternor/Bilder"
+ "/Vault/Eternor/Immich"
];
};
+ garage = {
+ data_dir = {
+ capacity = "200G";
+ path = "/Vault/data/garage/data";
+ };
+ };
};
};
@@ -3969,13 +3999,13 @@ This is my main server that I run at home. It handles most tasks that require bi
{ inputs, lib, config, minimal, nodes, globals, ... }:
{
@@ -4082,9 +4112,9 @@ This is my main server that I run at home. It handles most tasks that require bi
{ config, lib, modulesPath, ... }:
@@ -4118,9 +4148,9 @@ This is my main server that I run at home. It handles most tasks that require bi
{ lib, config, ... }:
let
@@ -4244,13 +4274,13 @@ in
{ lib, minimal, ... }:
{
@@ -4284,13 +4314,13 @@ in
{ lib, config, minimal, ... }:
{
@@ -4336,9 +4366,9 @@ in
{ config, lib, modulesPath, ... }:
@@ -4368,9 +4398,9 @@ in
{ lib, config, ... }:
let
@@ -4589,11 +4619,11 @@ My phone. I use only a minimal config for remote debugging here.
{ self, ... }:
+{ self, pkgs, ... }:
{
imports = [
@@ -4611,11 +4641,15 @@ My phone. I use only a minimal config for remote debugging here.
};
};
+ home.packages = with pkgs; [
+ attic-client
+ ];
# programs.zsh.initContent = "
# export GPG_TTY=\"$(tty)\"
# export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
# gpgconf --launch gpg-agent
# ";
+ swarselmodules.pii = true;
swarselsystems = {
isLaptop = false;
@@ -4803,6 +4837,12 @@ in
proxyHost = "moonside";
server = {
inherit (config.repo.secrets.local.networking) localNetwork;
+ restic = {
+ bucketName = "SwarselMoonside";
+ paths = [
+ "/persist/opt/minecraft"
+ ];
+ };
};
syncthing = {
serviceDomain = config.repo.secrets.common.services.domains.syncthing3;
@@ -4820,6 +4860,8 @@ in
shlink = true;
slink = true;
syncthing = true;
+ minecraft = true;
+ restic = true;
diskEncryption = lib.mkForce false;
};
}
@@ -4985,13 +5027,13 @@ in
{ lib, config, minimal, ... }:
{
@@ -5018,24 +5060,46 @@ in
isBtrfs = true;
isNixos = true;
isLinux = true;
+ isCloud = true;
proxyHost = "belchsfactory";
server = {
inherit (config.repo.secrets.local.networking) localNetwork;
+ garage = {
+ data_dir = {
+ capacity = "150G";
+ path = "/var/lib/garage/data";
+ };
+ keys = {
+ nixos = [
+ "attic"
+ ];
+ };
+ buckets = [
+ "attic"
+ ];
+ };
};
};
} // lib.optionalAttrs (!minimal) {
swarselprofiles = {
server = true;
};
+
+ swarselmodules.server = {
+ postgresql = lib.mkDefault true;
+ attic = lib.mkDefault true;
+ garage = lib.mkDefault true;
+ };
+
}
{ lib, modulesPath, ... }:
{
@@ -5056,9 +5120,9 @@ in
{ lib, pkgs, config, ... }:
let
@@ -5187,13 +5251,13 @@ in
{ lib, config, minimal, ... }:
{
@@ -5246,9 +5310,9 @@ in
{ lib, modulesPath, ... }:
@@ -5411,13 +5475,13 @@ in
{ lib, config, minimal, ... }:
{
@@ -5506,9 +5570,9 @@ in
{ lib, modulesPath, ... }:
@@ -5533,9 +5597,9 @@ in
{ lib, pkgs, config, ... }:
let
@@ -6051,9 +6115,9 @@ in
{ lib, pkgs, modulesPath, options, ... }:
{
@@ -6795,6 +6859,7 @@ in
github-nixpkgs-review-token = { owner = mainUser; };
}) // (lib.optionalAttrs modules.emacs {
emacs-radicale-pw = { owner = mainUser; };
+ github-forge-token = { owner = mainUser; };
}) // (lib.optionalAttrs modules.optional.work {
harica-root-ca = { sopsFile = certsSopsFile; path = "${homeDir}/.aws/certs/harica-root.pem"; owner = mainUser; };
}) // (lib.optionalAttrs modules.anki {
@@ -6881,9 +6946,10 @@ A breakdown of the flags being set:
-{ self, lib, pkgs, config, outputs, inputs, minimal, ... }:
+{ self, lib, pkgs, config, outputs, inputs, minimal, globals, ... }:
let
inherit (config.swarselsystems) mainUser;
+ inherit (config.repo.secrets.common) atticPublicKey;
settings = if minimal then { } else {
environment.etc."nixos/configuration.nix".source = pkgs.writeText "configuration.nix" ''
assert builtins.trace "This location is not used. The config is found in ${config.swarselsystems.flakePath}!" false;
@@ -6959,6 +7025,12 @@ in
"cgroups"
"pipe-operators"
];
+ substituters = [
+ "https://${globals.services.attic.domain}/${mainUser}"
+ ];
+ trusted-public-keys = [
+ atticPublicKey
+ ];
trusted-users = [ "@wheel" "${config.swarselsystems.mainUser}" ];
};
# extraOptions = ''
@@ -7792,7 +7864,7 @@ Here I only enable networkmanager and a few default networks. The r
-{ self, lib, pkgs, config, ... }:
+{ self, lib, pkgs, config, globals, ... }:
let
certsSopsFile = self + /secrets/certs/secrets.yaml;
clientSopsFile = self + /secrets/${config.node.name}/secrets.yaml;
@@ -7844,7 +7916,7 @@ in
networking = {
inherit (config.swarselsystems) hostName;
hosts = {
- "192.168.178.24" = [ "store.swarsel.win" ];
+ "${globals.networks.home-lan.hosts.winters.ipv4}" = [ globals.services.transmission.domain ];
};
wireless.iwd = {
enable = true;
@@ -9532,9 +9604,9 @@ Here I am forcing startWhenNeeded to false so that the value will n
Generate hostId using head -c4 /dev/urandom | od -A none -t x4
The hostkey can be generated with ssh-keygen -t ed25519 -N "" -f /etc/secrets/initrd/ssh_host_ed25519_key.
Use lspci -v | grep -iA8 'network\|ethernet' to supposedly find out which kernel module is needed for networking in initrd. However I prefer a different approach:
@@ -9596,75 +9668,11 @@ Use lspci -nn | grep -i network to find out manufacturer info:
| 04:00.0 | -Network | -controller | -[0280]: | -MEDIATEK | -Corp. | -MT7922 | -802.11ax | -PCI | -Express | -Wireless | -Network | -Adapter | -[14c3:0616] | -
| 6a:00.0 | -Ethernet | -controller | -[0200]: | -Intel | -Corporation | -I210 | -Gigabit | -Network | -Connection | -[8086:1533] | -(rev | -03) | -- |
From the last bracket you then find out the correct kernel module:
@@ -9858,9 +9866,9 @@ in{ lib, config, ... }:
let
@@ -10410,6 +10418,7 @@ in
let
inherit (confLib.gen { name = "postgresql"; port = 3254; }) serviceName;
postgresVersion = 14;
+ postgresDirPrefix = if config.swarselsystems.isCloud then "/var/lib" else "/Vault/data" ;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
@@ -10418,9 +10427,13 @@ in
${serviceName} = {
enable = true;
package = pkgs."postgresql_${builtins.toString postgresVersion}";
- dataDir = "/Vault/data/${serviceName}/${builtins.toString postgresVersion}";
+ dataDir = "${postgresDirPrefix}/${serviceName}/${builtins.toString postgresVersion}";
};
};
+ environment.persistence."/persist".directories = lib.mkIf (config.swarselsystems.isImpermanence && config.swarselsystems.isCloud) [
+ { directory = "/var/lib/postgresql"; user = "postgres"; group = "postgres"; mode = "0750"; }
+ ];
+
};
}
@@ -11446,6 +11459,7 @@ in
This manages backups for my pictures and obsidian files.
+Note: you still need to run restic-<name> init once on the host to get the bucket running.
{ lib, config, globals, confLib, ... }:
let
@@ -14024,38 +14036,114 @@ in
+Garage acts as my s3 endpoint. I use it on two of my servers: +
+
Generate the admin token using openssl rand -base64 32.
Generate the rpc token using openssl rand -hex 32.
+If a website is to be deployed using a s3 bucket, add the corresponding files in one of two ways: +
+ +
+either 1) use vhost addressing: aws s3 cp <local file> s3://<path to file; no bucket identifier needed> --endpoint-url https://<bucket>.<garage domain> --region swarsel
+
+or 2) use classic path addressing aws s3 cp <local file> s3://<bucket>/<path to file> --endpoint-url https://<garage domain> --region swarsel
+
{ self, lib, pkgs, config, configName, globals, dns, confLib, ... }:
+# inspired by https://github.com/atropos112/nixos/blob/7fef652006a1c939f4caf9c8a0cb0892d9cdfe21/modules/garage.nix
+{ lib, pkgs, config, globals, dns, confLib, ... }:
let
- inherit (confLib.gen { name = "garage"; port = 3900; }) servicePort serviceName serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
+ inherit (confLib.gen {
+ name = "garage";
+ port = 3900;
+ domain = config.repo.secrets.common.services.domains."garage-${config.node.name}";
+ }) servicePort serviceName specificServiceName serviceDomain subDomain baseDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
- sopsFile = self + /secrets/${configName}/secrets2.yaml;
+ cfg = lib.recursiveUpdate config.services.${serviceName} config.swarselsystems.server.${serviceName};
+ inherit (config.swarselsystems) sopsFile mainUser;
- cfg = config.services.${serviceName};
+ # needs SSD
metadata_dir = "/var/lib/garage/meta";
+ # metadata_dir = if config.swarselsystems.isCloud then "/var/lib/garage/meta" else "/Vault/data/garage/meta";
+
+ garageRpcPort = 3901;
+ garageWebPort = 3902;
+ garageAdminPort = 3903;
+ garageK2VPort = 3904;
+
+ adminDomain = "${subDomain}admin.${baseDomain}";
+ webDomain = "${subDomain}web.${baseDomain}";
in
{
options = {
swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
swarselsystems.server.${serviceName} = {
- data_dir = lib.mkOption {
- type = lib.types.either lib.types.path (lib.types.listOf lib.types.attrs);
- default = "/var/lib/garage/data";
+ data_dir = {
+ path = lib.mkOption {
+ type = lib.types.str;
+ description = "Directory where Garage stores its metadata";
+ };
+ capacity = lib.mkOption {
+ type = lib.types.str;
+ };
+ };
+ buckets = lib.mkOption {
+ type = lib.types.listOf lib.types.str;
+ description = "List of buckets to create";
+ };
+ keys = lib.mkOption {
+ type = lib.types.attrsOf (lib.types.listOf lib.types.str);
+ default = { };
+ description = "Keys and their associated buckets. Each key gets full access (read/write/owner) to its listed buckets.";
+ example = {
+ my_key_name = [ "bucket1" "bucket2" ];
+ my_other_key = [ "bucket2" "bucket3" ];
+ };
};
};
};
config = lib.mkIf config.swarselmodules.server.${serviceName} {
+ assertions = [
+ {
+ assertion = config.swarselsystems.server.${serviceName}.buckets != [ ];
+ message = "If Garage is enabled, at least one bucket must be specified in atro.garage.buckets";
+ }
+ {
+ assertion = builtins.length (lib.attrsToList config.swarselsystems.server.${serviceName}.keys) > 0;
+ message = "If Garage is enabled, at least one key must be specified in atro.garage.keys";
+ }
+ {
+ assertion =
+ let
+ allKeyBuckets = lib.flatten (lib.attrValues config.swarselsystems.server.${serviceName}.keys);
+ invalidBuckets = builtins.filter (bucket: !(lib.elem bucket config.swarselsystems.server.${serviceName}.buckets)) allKeyBuckets;
+ in
+ invalidBuckets == [ ];
+ message = "All buckets referenced in keys must exist in the buckets list";
+ }
+ ];
- swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
- "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
+ swarselsystems.server.dns.${baseDomain}.subdomainRecords = {
+ "${subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
+ "${subDomain}admin" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
+ "${subDomain}web" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
+ "*.${subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
+ "*.${subDomain}web" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
sops = {
@@ -14063,58 +14151,233 @@ in
secrets.garage-rpc-secret = { inherit sopsFile; };
};
+ # DynamicUser cannot read above secrets
+ systemd.services.${serviceName}.serviceConfig = {
+ DynamicUser = false;
+ ProtectHome = lib.mkForce false;
+ };
+
environment = {
persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [
- { directory = metadata_dir; }
+ { directory = "/var/lib/garage"; }
+ (lib.mkIf config.swarselsystems.isCloud { directory = config.swarselsystems.server.${serviceName}.data_dir.path; })
];
systemPackages = [
cfg.package
];
};
- globals.services.${serviceName} = {
+ globals.services.${specificServiceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
};
- systemd.services.${serviceName}.serviceConfig = {
- DynamicUser = false;
- ProtectHome = lib.mkForce false;
- };
services.${serviceName} = {
enable = true;
package = pkgs.garage_2;
settings = {
- inherit (config.swarselsystems.${serviceName}) data_dir;
+ data_dir = [ config.swarselsystems.server.${serviceName}.data_dir ];
inherit metadata_dir;
db_engine = "lmdb";
- block_size = "1MiB";
+ block_size = "128M";
use_local_tz = false;
+ disable_scrub = true;
+ replication_factor = 1;
+ compression_level = "none";
- replication_factor = 2; # Number of copies of data
+ rpc_bind_addr = "[::]:${builtins.toString garageRpcPort}";
+ # we are not joining our nodes, just use the private ipv4
+ rpc_public_addr = "${globals.networks."${if config.swarselsystems.isCloud then config.node.name else "home"}-${config.swarselsystems.server.localNetwork}".hosts.${config.node.name}.ipv4}:${builtins.toString garageRpcPort}";
- rpc_bind_addr = "[::]:3901";
- rpc_public_addr = "${config.repo.secrets.local.ipv4}:4317";
rpc_secret_file = config.sops.secrets.garage-rpc-secret.path;
s3_api = {
- s3_region = "swarsel";
- api_bind_addr = "0.0.0.0:${builtins.toString servicePort}";
- root_domain = ".s3.garage.localhost";
+ s3_region = mainUser;
+ api_bind_addr = "[::]:${builtins.toString servicePort}";
+ root_domain = ".${serviceDomain}";
+ };
+
+ s3_web = {
+ bind_addr = "[::]:${builtins.toString garageWebPort}";
+ root_domain = ".${config.repo.secrets.common.services.domains."garage-web-${config.node.name}"}";
+ add_host_to_metrics = true;
};
admin = {
- api_bind_addr = "0.0.0.0:3903";
+ api_bind_addr = "[::]:${builtins.toString garageAdminPort}";
admin_token_file = config.sops.secrets.garage-admin-token.path;
};
k2v_api = {
- api_bind_addr = "[::]:3904";
+ api_bind_addr = "[::]:${builtins.toString garageK2VPort}";
};
};
};
+
+ systemd.services = {
+ garage-buckets = {
+ description = "Create Garage buckets";
+ after = [ "garage.service" ];
+ wants = [ "garage.service" ];
+ wantedBy = [ "multi-user.target" ];
+
+ path = [ cfg.package pkgs.gawk pkgs.coreutils ];
+
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ User = "root";
+ Group = "root";
+ };
+
+ script = ''
+ garage status
+
+ # Checking repeatedly with garage status until getting 0 exit code
+ while ! garage status >/dev/null 2>&1; do
+ echo "Garage not yet operational, waiting..."
+ echo "Current garage status output:"
+ garage status 2>&1 || true
+ echo "---"
+ sleep 5
+ done
+
+ # Now we check if garage status shows any failed nodes by checking for ==== FAILED NODES ====
+ while garage status | grep -q "==== FAILED NODES ===="; do
+ echo "Garage has failed nodes, waiting..."
+ echo "Current garage status output:"
+ garage status 2>&1 || true
+ echo "---"
+ sleep 5
+ done
+
+ echo "Garage is operational, proceeding with bucket management."
+
+ # Get list of existing buckets
+ existing_buckets=$(garage bucket list | tail -n +2 | awk '{print $3}' | grep -v '^$' || true)
+
+ # Create buckets that should exist
+ ${lib.concatMapStringsSep "\n" (bucket: ''
+ if [[ "$(garage bucket info ${lib.escapeShellArg bucket} 2>&1 >/dev/null)" == *"Bucket not found"* ]]; then
+ echo "Creating bucket ${lib.escapeShellArg bucket}"
+ garage bucket create ${lib.escapeShellArg bucket}
+ else
+ echo "Bucket ${lib.escapeShellArg bucket} already exists"
+ fi
+ '')
+ cfg.buckets}
+
+ # Remove buckets that shouldn't exist
+ for bucket in $existing_buckets; do
+ should_exist=false
+ ${lib.concatMapStringsSep "\n" (bucket: ''
+ if [[ "$bucket" == ${lib.escapeShellArg bucket} ]]; then
+ should_exist=true
+ fi
+ '')
+ cfg.buckets}
+
+ if [[ "$should_exist" == "false" ]]; then
+ echo "Removing bucket $bucket"
+ garage bucket delete --yes "$bucket"
+ fi
+ done
+ '';
+ };
+
+ garage-keys = {
+ description = "Create Garage keys and set permissions";
+ after = [ "garage-buckets.service" ];
+ wants = [ "garage-buckets.service" ];
+ requires = [ "garage-buckets.service" ];
+ wantedBy = [ "multi-user.target" ];
+
+ path = [ cfg.package pkgs.gawk pkgs.coreutils ];
+
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ User = "root";
+ Group = "root";
+ };
+
+ script = ''
+ garage key list
+ echo "Managing keys..."
+
+ # Get list of existing keys
+ existing_keys=$(garage key list | tail -n +2 | awk '{print $3}' | grep -v '^$' || true)
+
+ # Create keys that should exist
+ ${lib.concatStringsSep "\n" (lib.mapAttrsToList (keyName: _: ''
+ if [[ "$(garage key info ${lib.escapeShellArg keyName} 2>&1)" == *"0 matching keys"* ]]; then
+ echo "Creating key ${lib.escapeShellArg keyName}"
+ garage key create ${lib.escapeShellArg keyName}
+ else
+ echo "Key ${lib.escapeShellArg keyName} already exists"
+ fi
+ '')
+ cfg.keys)}
+
+ # Set up key permissions for buckets
+ ${lib.concatStringsSep "\n" (lib.mapAttrsToList (
+ keyName: buckets:
+ lib.concatMapStringsSep "\n" (bucket: ''
+ echo "Granting full access to key ${lib.escapeShellArg keyName} for bucket ${lib.escapeShellArg bucket}"
+ garage bucket allow --read --write --owner --key ${lib.escapeShellArg keyName} ${lib.escapeShellArg bucket}
+ '')
+ buckets
+ )
+ cfg.keys)}
+
+ # Remove permissions from buckets that are no longer associated with keys
+ ${lib.concatStringsSep "\n" (lib.mapAttrsToList (keyName: buckets: ''
+ # Get current buckets this key has access to
+ current_buckets=$(garage key info ${lib.escapeShellArg keyName} | grep -A 1000 "==== BUCKETS FOR THIS KEY ====" | tail -n +3 | awk '{print $3}' | grep -v '^$' || true)
+
+ # Remove access from buckets not in the desired list
+ for current_bucket in $current_buckets; do
+ should_have_access=false
+ ${lib.concatMapStringsSep "\n" (bucket: ''
+ if [[ "$current_bucket" == ${lib.escapeShellArg bucket} ]]; then
+ should_have_access=true
+ fi
+ '')
+ buckets}
+
+ if [[ "$should_have_access" == "false" ]]; then
+ echo "Removing access for key ${lib.escapeShellArg keyName} from bucket $current_bucket"
+ garage bucket deny --key ${lib.escapeShellArg keyName} $current_bucket
+ fi
+ done
+ '')
+ cfg.keys)}
+
+ # Remove keys that shouldn't exist
+ for key in $existing_keys; do
+ should_exist=false
+ ${lib.concatStringsSep "\n" (lib.mapAttrsToList (keyName: _: ''
+ if [[ "$key" == ${lib.escapeShellArg keyName} ]]; then
+ should_exist=true
+ fi
+ '')
+ cfg.keys)}
+
+ if [[ "$should_exist" == "false" ]]; then
+ echo "Removing key $key"
+ garage key delete --yes "$key"
+ fi
+ done
+ '';
+ };
+ };
+
+ security.acme.certs."${webDomain}" = {
+ domain = "*.${webDomain}";
+ };
+
nodes.${serviceProxy}.services.nginx = {
upstreams = {
${serviceName} = {
@@ -14122,9 +14385,42 @@ in
"${serviceAddress}:${builtins.toString servicePort}" = { };
};
};
+ "${serviceName}Web" = {
+ servers = {
+ "${serviceAddress}:${builtins.toString garageWebPort}" = { };
+ };
+ };
+ "${serviceName}Admin" = {
+ servers = {
+ "${serviceAddress}:${builtins.toString garageAdminPort}" = { };
+ };
+ };
};
virtualHosts = {
+ "${adminDomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ acmeRoot = null;
+ oauth2.enable = false;
+ locations = {
+ "/" = {
+ proxyPass = "http://${serviceName}Admin";
+ };
+ };
+ };
+ "*.${webDomain}" = {
+ useACMEHost = webDomain;
+ forceSSL = true;
+ acmeRoot = null;
+ oauth2.enable = false;
+ locations = {
+ "/" = {
+ proxyPass = "http://${serviceName}Web";
+ };
+ };
+ };
"${serviceDomain}" = {
+ serverAliases = [ "*.${serviceDomain}" ];
enableACME = true;
forceSSL = true;
acmeRoot = null;
@@ -14132,6 +14428,9 @@ in
locations = {
"/" = {
proxyPass = "http://${serviceName}";
+ extraConfig = ''
+ client_max_body_size 0;
+ '';
};
};
};
@@ -14144,9 +14443,9 @@ in
{ inputs, lib, config, globals, dns, confLib, ... }:
let
@@ -14190,9 +14489,9 @@ in
{ config, globals, dns, ... }:
with dns.lib.combinators; {
@@ -14315,13 +14614,15 @@ with dns.lib.combinators; {
{ lib, config, globals, dns, confLib, ... }:
+{ lib, config, pkgs, globals, dns, confLib, ... }:
let
- inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/var/lib/minecraft"; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6;
+ inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/opt/minecraft"; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6;
+ inherit (config.swarselsystems) mainUser;
+ worldName = "${mainUser}craft";
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
@@ -14351,9 +14652,9 @@ in
serviceConfig = {
User = "root";
- WorkingDirectory = "/var/lib/minecraft/swarselcraft";
+ WorkingDirectory = "${serviceDir}/${worldName}";
- ExecStart = "/usr/bin/java @user_jvm_args.txt @libraries/net/minecraftforge/forge/1.20.1-47.2.20/unix_args.txt nogui";
+ ExecStart = "${lib.getExe pkgs.temurin-jre-bin-17} @user_jvm_args.txt @libraries/net/minecraftforge/forge/1.20.1-47.2.20/unix_args.txt nogui";
Restart = "always";
RestartSec = 30;
@@ -14371,9 +14672,9 @@ in
{ lib, config, globals, dns, confLib, ... }:
let
@@ -14494,6 +14795,157 @@ in
+Generate the attic server token using openssl genrsa -traditional 4096 | base64 -w0
+
+$ attic login local http://localhost:8080 eyJ… +βοΈ Configuring server "local" +
+ ++$ attic cache create hello +β¨ Created cache "hello" on "local" +
+ +{ lib, config, globals, dns, confLib, ... }:
+let
+ inherit (confLib.gen { name = "attic"; port = 8091; }) serviceName serviceDir servicePort serviceAddress serviceDomain serviceProxy proxyAddress4 proxyAddress6;
+ inherit (config.swarselsystems) mainUser isPublic sopsFile;
+ serviceDB = "atticd";
+in
+{
+ options = {
+ swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ };
+ config = lib.mkIf config.swarselmodules.server.${serviceName} {
+
+ swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
+ "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
+ };
+
+ globals.services.${serviceName} = {
+ domain = serviceDomain;
+ inherit proxyAddress4 proxyAddress6;
+ };
+
+ sops = lib.mkIf (!isPublic) {
+ secrets = {
+ attic-server-token = { inherit sopsFile; };
+ attic-garage-access-key = { inherit sopsFile; };
+ attic-garage-secret-key = { inherit sopsFile; };
+ };
+ templates = {
+ "attic.env" = {
+ content = ''
+ ATTIC_SERVER_TOKEN_RS256_SECRET_BASE64=${config.sops.placeholder.attic-server-token}
+ AWS_ACCESS_KEY_ID=${config.sops.placeholder.attic-garage-access-key}
+ AWS_SECRET_ACCESS_KEY=${config.sops.placeholder.attic-garage-secret-key}
+ '';
+ };
+ };
+ };
+
+ services.atticd = {
+ enable = true;
+ environmentFile = config.sops.templates."attic.env".path;
+ settings = {
+ listen = "[::]:${builtins.toString servicePort}";
+ api-endpoint = "https://${serviceDomain}/";
+ allowed-hosts = [
+ serviceDomain
+ ];
+ require-proof-of-possession = false;
+ compression = {
+ type = "zstd";
+ level = 3;
+ };
+ database.url = "postgresql:///atticd?host=/run/postgresql";
+
+ storage =
+ if config.swarselmodules.server.garage then {
+ type = "s3";
+ region = mainUser;
+ bucket = serviceName;
+ # attic must be patched to never serve pre-signed s3 urls directly
+ # otherwise it will redirect clients to this localhost endpoint
+ endpoint = "http://127.0.0.1:3900";
+ } else {
+ type = "local";
+ path = serviceDir;
+ # attic must be patched to never serve pre-signed s3 urls directly
+ # otherwise it will redirect clients to this localhost endpoint
+ };
+
+ garbage-collection = {
+ interval = "1 day";
+ default-retention-period = "3 months";
+ };
+
+ chunking = {
+ nar-size-threshold = if config.swarselmodules.server.garage then 0 else 64 * 1024; # 64 KiB
+
+ min-size = 16 * 1024; # 16 KiB
+ avg-size = 64 * 1024; # 64 KiB
+ max-size = 256 * 1024; # 256 KiBize = 262144;
+ };
+ };
+ };
+
+ services.postgresql = {
+ enable = true;
+ enableTCPIP = true;
+ ensureDatabases = [ serviceDB ];
+ ensureUsers = [
+ {
+ name = serviceDB;
+ ensureDBOwnership = true;
+ }
+ ];
+ };
+
+ systemd.services.atticd = lib.mkIf config.swarselmodules.server.garage {
+ requires = [ "garage.service" ];
+ after = [ "garage.service" ];
+ };
+
+ nodes.${serviceProxy}.services.nginx = {
+ upstreams = {
+ ${serviceName} = {
+ servers = {
+ "${serviceAddress}:${builtins.toString servicePort}" = { };
+ };
+ };
+ };
+ virtualHosts = {
+ "${serviceDomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ acmeRoot = null;
+ oauth2.enable = false;
+ locations = {
+ "/" = {
+ proxyPass = "http://${serviceName}";
+ extraConfig = ''
+ client_max_body_size 0;
+ '';
+ };
+ };
+ };
+ };
+ };
+
+ };
+}
+
+Some standard options that should be set for every microvm host.
@@ -15144,9 +15596,9 @@ Some standard options that should be set for every microvm host.Some standard options that should be set vor every microvm guest. We set the default
@@ -15190,9 +15642,9 @@ inSteps to get a home-manager only setup up and running:
@@ -15275,16 +15727,17 @@ in
Again, we adapt nix to our needs, enable the home-manager command for non-NixOS machines (NixOS machines are using it as a module) and setting user information that I always keep the same.
{ self, outputs, lib, pkgs, config, ... }:
+{ self, outputs, lib, pkgs, config, globals, confLib, ... }:
let
inherit (config.swarselsystems) mainUser flakePath isNixos isLinux;
+ inherit (confLib.getConfig.repo.secrets.common) atticPublicKey;
in
{
options.swarselmodules.general = lib.mkEnableOption "general nix settings";
@@ -15306,7 +15759,7 @@ in
};
in
''
- plugin-files = ${nix-plugins}/lib/nix/plugins
+ plugin-files = ${nix-plugins}/lib/nix/plugins
extra-builtins-file = ${self + /nix/extra-builtins.nix}
'';
settings = {
@@ -15317,6 +15770,12 @@ in
"cgroups"
"pipe-operators"
];
+ substituters = [
+ "https://${globals.services.attic.domain}/${mainUser}"
+ ];
+ trusted-public-keys = [
+ atticPublicKey
+ ];
trusted-users = [ "@wheel" "${mainUser}" ];
connect-timeout = 5;
bash-prompt-prefix = "[33m$SHLVL:\\w [0m";
@@ -15491,6 +15950,9 @@ This holds packages that I can use as provided, or with small modifications (as
# ssh login using idm
opkssh
+ # cache
+ attic-client
+
# dict
(aspellWithDicts (dicts: with dicts; [ de en en-computers en-science ]))
@@ -16050,6 +16512,7 @@ in
} // (lib.optionalAttrs (!isPublic) { });
systemd.user.sessionVariables = {
DOCUMENT_DIR_PRIV = lib.mkForce "${homeDir}/Documents/Private";
+ FLAKE = "${config.home.homeDirectory}/.dotfiles";
} // lib.optionalAttrs (!isPublic) {
SWARSEL_MAIL1 = address1;
SWARSEL_MAIL2 = address2;
@@ -16214,9 +16677,9 @@ nix-index provides a way to find out which packages are provided by which deriva
{ lib, config, ... }:
let
@@ -16324,6 +16787,7 @@ in
programs.atuin = {
enable = true;
enableZshIntegration = true;
+ enableBashIntegration = true;
settings = {
auto_sync = true;
sync_frequency = "5m";
@@ -16723,7 +17187,10 @@ in
};
history = {
expireDuplicatesFirst = true;
- path = "$HOME/.histfile";
+ append = true;
+ ignoreSpace = true;
+ ignoreDups = true;
+ path = "${config.home.homeDirectory}/.histfile";
save = 100000;
size = 100000;
};
@@ -16799,19 +17266,27 @@ in
{ config, pkgs, lib, ... }:
+{ config, lib, ... }:
{
options.swarselmodules.bash = lib.mkEnableOption "bash settings";
config = lib.mkIf config.swarselmodules.bash {
programs.bash = {
- bashrcExtra = ''
- export PATH="${pkgs.nix}/bin:$PATH"
+ enable = true;
+ # needed for remote builders
+ bashrcExtra = lib.mkIf (!config.swarselsystems.isNixos) ''
+ export PATH="/nix/var/nix/profiles/default/bin:$PATH"
'';
+ historyFile = "${config.home.homeDirectory}/.histfile";
+ historySize = 100000;
+ historyFileSize = 100000;
+ historyControl = [
+ "ignoreboth"
+ ];
};
};
}
@@ -16819,9 +17294,9 @@ in
{ lib, config, ... }:
{
@@ -18496,12 +18971,14 @@ in
secrets = {
fever-pw = { path = "${homeDir}/.emacs.d/.fever"; };
emacs-radicale-pw = { };
+ github-forge-token = { };
};
templates = {
authinfo = {
path = "${homeDir}/.emacs.d/.authinfo";
content = ''
machine ${globals.services.radicale.domain} login ${radicaleUser} password ${config.sops.placeholder.emacs-radicale-pw}
+ machine api.github.com login ${mainUser}^forge password ${config.sops.placeholder.github-forge-token}
'';
};
};
@@ -19212,9 +19689,9 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
{ lib, config, ... }:
{
@@ -19227,9 +19704,9 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
{ lib, config, ... }:
{
@@ -19243,9 +19720,9 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
{ lib, config, ... }:
{
@@ -19278,9 +19755,9 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
Sets up a systemd user service for anki that does not stall the shutdown process. Note that the outcommented ExecStart does not work because the home-manager anki package builds a separate anki package that - I think - cannot be referenced as no such expression exists in the module.
{ lib, config, pkgs, ... }:
{
@@ -19361,9 +19838,9 @@ Sets up a systemd user service for anki that does not stall the shutdown process
{ lib, config, pkgs, ... }:
{
@@ -19396,9 +19873,9 @@ Sets up a systemd user service for anki that does not stall the shutdown process
{ lib, config, pkgs, ... }:
{
@@ -20440,9 +20917,9 @@ in
{ lib, config, pkgs, nixosConfig ? config, ... }:
let
@@ -20601,9 +21078,9 @@ in
{ lib, config, pkgs, globals, inputs, nixosConfig ? config, ... }:
let
@@ -20675,9 +21152,9 @@ in
{ lib, config, ... }:
let
@@ -20712,9 +21189,9 @@ in
{ lib, config, nixosConfig ? config, ... }:
let
@@ -20737,9 +21214,9 @@ in
{ lib, config, ... }:
let
@@ -20758,9 +21235,9 @@ in
{ lib, config, ... }:
let
@@ -20779,9 +21256,9 @@ in
{ lib, pkgs, config, ... }:
let
@@ -20867,9 +21344,9 @@ in
{ lib, config, ... }:
let
@@ -20900,9 +21377,9 @@ in
{ lib, config, ... }:
let
@@ -20922,9 +21399,9 @@ in
{ lib, config, pkgs, ... }:
let
@@ -20964,9 +21441,9 @@ in
{ lib, config, pkgs, ... }:
let
@@ -20993,9 +21470,9 @@ in
{ lib, config, ... }:
let
@@ -22328,11 +22805,11 @@ In short, the options defined here are passed to the modules systems using
{ config, globals, ... }:
+{ config, lib, globals, ... }:
{
_module.args = {
confLib = rec {
@@ -22342,12 +22819,17 @@ In short, the options defined here are passed to the modules systems using 2cf03
{ self, lib, pkgs, ... }:
let
@@ -22467,9 +22949,9 @@ writeShellApplication {
shopt -s nullglob globstar
@@ -24402,9 +24884,9 @@ writeShellApplication {
Sometimes my DE crashes after putting it to suspend - to be precise, it happens when I put it into suspend when I have multiple screens plugged in. I have never taken the time to debug the issue, but instead just switch to a different TTY and then use this script to kill the hanging session.
@@ -24424,9 +24906,9 @@ writeShellApplication {This script allows for quick git replace of a string.
@@ -24503,9 +24985,9 @@ writeShellApplication {{ self, homeConfig, lib, pkgs, ... }:
let
@@ -24521,9 +25003,9 @@ mkPackages packageNames pkgs
{ name, homeConfig, writeShellApplication, fzf, ... }:
@@ -24685,9 +25167,9 @@ in
{ lib, config, ... }:
{
@@ -24891,9 +25373,9 @@ in
{ lib, config, ... }:
{
@@ -25008,9 +25490,9 @@ in
{ lib, config, ... }:
{
@@ -25465,6 +25947,11 @@ In this section I define extra functions that I need. Some of these functions I
Since I am rebinding the C-z hotkey for emacs-evil-state toggling, I want to have a function that still lets me perform this action quickly.
+
+We set a keybinding to this in Custom Keybindings.
+
+
+
;; -*- lexical-binding: t; -*-
@@ -25482,7 +25969,11 @@ Since I am rebinding the C-z hotkey for emacs-evil-state toggling,
4.2.1.2. Switching to last used buffer
-I often find myself bouncing between two buffers when I do not want to use a window split. This funnction simply jumps to the last used buffer.
+I often find myself bouncing between two buffers when I do not want to use a window split. This function simply jumps to the last used buffer.
+
+
+
+We set a keybinding to this in Custom Keybindings.
@@ -25591,6 +26082,10 @@ The below function avoids these problems. Originally I used the function d
However, this function does not work on regions. Later, I found a solution implemented by crux. I do not need the whole package, so I just extracted the three functions I needed from it.
+
+We set a keybinding to this in Custom Keybindings.
+
+
(defun crux-get-positions-of-line-or-region ()
@@ -25779,9 +26274,17 @@ This function was found here:
-4.2.1.9. Magit: List directories using vertico/consult
-
+
+4.2.1.9. Magit: List directories using vertico/consult
+
+
+At work and when working on private projects, I often have to jump between several git repositories. This function fires up a picker that gets me to the magit overview page of that repository.
+
+
+
+We set a keybinding to this in Custom Keybindings.
+
+
(defun swarsel/consult-magit-repos ()
@@ -25902,6 +26405,10 @@ Normally emacs cycles between three states:
However, I want to be able to fold a single heading consistently.
+
+We set a keybinding to this in Custom Keybindings.
+
+
(defun org-fold-outer ()
@@ -25964,6 +26471,69 @@ These functions are used here:
+
+
+
+
+4.2.1.16. Insert link to another header in org file
+
+
+When writing this file, I often want to refer to a different section of the file. One way to do this is to C-x O (consult-org-heading) to get to said heading, then C=c s (org-store-link), finally C-o (evil-jump-backward) to get back to the origin and insert the link using C-c C-l (org-insert-link).
+
+
+
+These two scripts just let me do all of this in one step. I have styled the picker in a way that is similar to consult-org-heading.
+
+
+
+We set a keybinding to this in Custom Keybindings.
+
+
+
+
+ (defun swarsel/org-colorize-outline (parents raw)
+ (let* ((palette ["#58B6ED" "#8BD49C" "#33CED8" "#4B9CCC"
+ "yellow" "orange" "salmon" "red"])
+ (n (length parents))
+ (colored-parents
+ (cl-mapcar
+ (lambda (p i)
+ (propertize p 'face `(:foreground ,(aref palette (mod i (length palette))) :weight bold)))
+ parents
+ (number-sequence 0 (1- n)))))
+ (concat
+ (when parents
+ (string-join colored-parents "/"))
+ (when parents "/")
+ (propertize raw 'face `(:foreground ,(aref palette (mod n (length palette)))
+ :weight bold)))))
+
+(defun swarsel/org-insert-link-to-heading ()
+ (interactive)
+ (let ((candidates '()))
+ (org-map-entries
+ (lambda ()
+ (let* ((raw (org-get-heading t t t t))
+ (parents (org-get-outline-path t))
+ (m (copy-marker (point)))
+ (colored (swarsel/org-colorize-outline parents raw)))
+ (push (cons colored m) candidates))))
+
+ (let* ((choice (completing-read "Heading: " (mapcar #'car candidates)))
+ (marker (cdr (assoc choice candidates)))
+ id raw-heading)
+ (unless marker
+ (user-error "No marker for heading??"))
+
+ (save-excursion
+ (goto-char marker)
+ (setq id (prot-org--id-get))
+ (setq raw-heading (org-get-heading t t t t)))
+
+ (insert (org-link-make-string (format "#%s" id)
+ raw-heading)))))
+
@@ -26080,6 +26650,7 @@ I also define some keybinds to some combinations directly. Those are used mostly
"<DUMMY-m>" 'swarsel/last-buffer
"M-\\" 'indent-region
"M-r" 'swarsel/consult-magit-repos
+ "M-i" 'swarsel/org-insert-link-to-heading
"<Paste>" 'yank
"<Cut>" 'kill-region
"<Copy>" 'kill-ring-save
@@ -26099,7 +26670,7 @@ I also define some keybinds to some combinations directly. Those are used mostly
4.2.3. Directory setup / File structure
-In this section I setup some aliases that I use for various directories on my system. Some of these are actually used for magit repository finding etc., but many of them serve no real use and I need to clean this up someday.
+In this section I setup some aliases that I use for various directories on my system. This is just to prevent setting the same stuff too often.
@@ -26107,12 +26678,12 @@ In this section I setup some aliases that I use for various directories on my sy
;; set Nextcloud directory for journals etc.
(setq
swarsel-emacs-directory "~/.emacs.d"
- swarsel-dotfiles-directory "~/.dotfiles"
+ swarsel-dotfiles-directory (getenv "FLAKE")
swarsel-swarsel-org-filepath (expand-file-name "SwarselSystems.org" swarsel-dotfiles-directory)
swarsel-tasks-org-file "Tasks.org"
swarsel-archive-org-file "Archive.org"
- swarsel-work-projects-directory "~/Documents/Work"
- swarsel-private-projects-directory "~/Documents/Private"
+ swarsel-work-projects-directory (getenv "DOCUMENT_DIR_WORK")
+ swarsel-private-projects-directory (getenv "DOCUMENT_DIR_PRIV")
)
@@ -26200,7 +26771,7 @@ Here I set up some things that are too minor to put under other categories.
;; use UTF-8 everywhere
(set-language-environment "UTF-8")
-(profiler-start 'cpu)
+;; (profiler-start 'cpu)
;; set default font size
(defvar swarsel/default-font-size 130)
(setq swarsel-standard-font "FiraCode Nerd Font Mono"
@@ -26529,6 +27100,10 @@ This minor-mode adds functionality for doing better surround-commands; for examp
4.3.7.6. evil-visual-mark-mode
+
+This makes it so that when setting a mark in evil mode (using m <key>), it creates a visual marker at that place that reminds me what the key for that marker position is (the marker is of course not part of the text of the document, and is hence not saved).
+
+
(use-package evil-visual-mark-mode
@@ -26565,8 +27140,12 @@ This adds support for tree-sitter objects. This allows for the following chords:
-4.3.7.8. evil-textobj-tree-sitter
+4.3.7.8. evil-numbers
+
+A very simple package that brings back the vim possibility of incrementing/decrementing numbers. I do not need it often, but it is nice to have.
+
+
(use-package evil-numbers)
@@ -26580,7 +27159,7 @@ This adds support for tree-sitter objects. This allows for the following chords:
4.3.8. ispell
-This should setup a wordlist that can be used as a dictionary. However, for some reason this does not work, and I will need to further investigate this issue.
+This sets up a wordlist that is, for example, used in completions. When coding, I do not really need this, but it is sometimes useful when writing prose.
@@ -26657,7 +27236,7 @@ Used in:
@@ -26692,11 +27271,11 @@ This minor mode allows mixing fixed and variable pitch fonts within the same buf
4.3.13. Modeline
-Here I set up the modeline with some information that I find useful. Specficially I am using the doom modeline. Most informations I disable for it, except for the cursor information (row + column) as well as a widget for mu4e and git information.
+Here I set up the modeline with some information that I find useful. I was using the doom modeline for a while. Most informations I disabled for it, except for the cursor information (row + column) as well as a widget for mu4e and git information.
-I have currently disabled this in favor of mini-modeline.
+I have currently disabled this in favor of mini-modeline, which saves more screen space and holds only the information I really need.
@@ -26718,7 +27297,20 @@ I have currently disabled this in favor of 4.3.14. mini-modeline
-I have found that the doom-modeline, while very useful, consumes too much screen space for my liking. This modeline takes a more minimalistic approach.
+I have found that the doom-modeline, while very useful, consumes too much screen space for my liking. This modeline takes a more minimalistic approach. The only information that is shown is:
+
+
+
+- the line number
+- state of the file (whether it is saved etc.)
+- the name of the file
+- the percentage of the cursor in the file
+- the major mode of the file
+- the current evil mode
+
+
+
+This is really the perfect solution for me, but it might not be for everyone.
@@ -26762,24 +27354,16 @@ I have found that the doom-modeline, while very useful, consumes too much screen
4.3.15.1. Vertico, Orderless, Marginalia, Consult, Embark
-This set of packages uses the default emacs completion framework and works together to provide a very nice user experience:
-
-
-
-- Vertico simply provides a vertically stacking completion
-- Marginalia adds more information to completion results
-- Orderless allows for fuzzy matching
-- Consult provides better implementations for several user functions, e.g.
consult-line or consult-outline
-- Embark allows acting on the results in the minibuffer while the completion is still ongoing - this is extremely useful since it allows to, for example, read the documentation for several functions without closing the help search. It can also collect the results of a grep operation into a seperate buffer that edits the result in their original location.
-
-
-
-Nerd icons is originally enabled here: Icons
+This set of packages uses the default emacs completion framework and works together to provide a very nice user experience.
4.3.15.1.1. vertico
+
+Vertico simply provides a vertically stacking completion framework.
+
+
(setq read-buffer-completion-ignore-case t
@@ -26824,6 +27408,10 @@ This package allows for Ido-like directory navigation.
4.3.15.1.3. orderless
+
+Orderless allows for fuzzy matching.
+
+
When first installing orderless, I often times faced the problem, that when editing long files and calling consult-line, Emacs would hang when changing a search term in the middle (e.g. from servicse.xserver to servic.xserver in order to fix the typo). The below orderless rules have a more strict matching that has a positive impact on performance.
@@ -26854,6 +27442,10 @@ When first installing orderless, I often times faced the problem, that when edit
4.3.15.1.4. consult
+
+Consult provides better implementations for several user functions, e.g. consult-line or consult-outline.
+
+
The big winner here are the convenient keybinds being setup here for general use. Also, I setup vim-navigation for minibuffer completions. consult-buffer is set twice because I am still used to that weird C-M-j command that I chose for ivy-switch-buffer when I first started using Emacs. I want to move to the other command but for now it is not feasible to delete the other one.
@@ -26884,6 +27476,10 @@ The big winner here are the convenient keybinds being setup here for general use
4.3.15.1.5. embark
+
+Embark allows acting on the results in the minibuffer while the completion is still ongoing - this is extremely useful since it allows to, for example, read the documentation for several functions without closing the help search. It can also collect the results of a grep operation into a seperate buffer that edits the result in their original location.
+
+
I have stripped down the embark keybinds heavily. It is very useful to me even in it's current state, but it quickly becomes overwhelming. embark-dwim acts on a candidate without closing the minibuffer, which is very useful. embark-act lets the user choose from all actions, but has an overwhelming interface.
@@ -26932,6 +27528,10 @@ Provides previews for embark.
4.3.15.1.7. marginalia
+
+Marginalia adds more information to completion results.
+
+
I set the annotation-mode of marginalia to heavy. This gives even more information on the stuff that you are looking at. One thing I am missing from ivy is the highlighting on mode-commands based on the current state of the mode. Also, I do not understand all the shorthands used by marginalia yet.
@@ -26955,6 +27555,7 @@ I set the annotation-mode of marginalia to heavy. This gives even m
As stated above, this simply provides nerd-icons to the completion framework.
+It is originally enabled here: Icons
@@ -27105,6 +27706,10 @@ This places little angled indicators on the fringe of a window which indicate bu
This defines the authentication sources used by org-calfw (Calendar) and Forge.
+
+This file is written using home-manager sops in Home-manager: Emacs
+
+
;; (setq auth-sources '( "~/.emacs.d/.caldav" "~/.emacs.d/.authinfo.gpg")
@@ -27426,7 +28031,11 @@ This just makes org-mode a little bit more beautiful, mostly by making the 4.4.1.10. Presentations
-Recently I have grown fond of holding presentations using Emacs :)
+Recently I have grown fond of holding presentations using Emacs.
+
+
+
+When holding presentations, I think it is important to not have too many distractions on your slides. org-present just shows a plain background, is very responsive, and it is still an org buffer (so you can e.g. run source block codes while in the presentation).
@@ -27537,9 +28146,13 @@ Recently I have grown fond of holding presentations using Emacs :)
-
-4.4.1.11. Render markdown blocks as body to expand noweb blocks
-
+
+4.4.1.11. Render markdown blocks as body to expand noweb blocks
+
+
+I have written this function to allow me to get a preview of the information that is gathered throughout the file and aggregated in Manual steps when setting up a new machine. Normally, running a markdown source block does nothing in Emacs. Hence, I just let it return the output, which inserts the noweb-ref blocks.
+
+
(defun org-babel-execute:markdown (body params)
"Just return BODY unchanged, allowing noweb expansion."
@@ -27553,7 +28166,11 @@ Recently I have grown fond of holding presentations using Emacs :)
4.4.2. Nix Mode
-This adds a rudimentary nix-mode to Emacs. I have not really tried this out, as I am mostly editing nix-files in org-mode anyways.
+This adds a nix mode to Emacs. This has become increasingly useful since I have added lsp-mode in org-src blocks, because since that time, I am now able to actually make use of major modes while I theoretically stay in org-mode.
+
+
+
+It supports all functions that I normally need. Note that getting completions for flake inputs is a bit finnicky and I am not quite fond of it yet.
@@ -27604,7 +28221,7 @@ This adds a rudimentary nix-mode to Emacs. I have not really tried this out, as
4.4.3. HCL Mode
-This adds support for Hashicorp Configuration Language. I need this at work.
+This adds support for Hashicorp Configuration Language. Used at work, it is mostly a Terraform Mode that does not support autoformatting upon save. It still is nice :)
@@ -27622,7 +28239,7 @@ This adds support for Hashicorp Configuration Language. I need this at work.
4.4.4. Jenkinsfile/Groovy
-This adds support for Groovy, which I specifically need to work with Jenkinsfiles. I need this at work.
+This adds support for Groovy, which I specifically need to work with Jenkinsfiles. Similar to [BROKEN LINK: 7aa9803f-b419-40fa-aafc-4bb934c8f687], it just provides some nice functions.
@@ -27639,6 +28256,11 @@ This adds support for Groovy, which I specifically need to work with Jenkinsfile
4.4.5. Ansible
+
+This is supposed to provide auto-completion when turned on. Of course I cannot globally turn this on since it would run in any .yaml file then, but even when manually started, it seems to do nothing. This would be nice at work.
+
+
+
(use-package ansible)
@@ -27651,7 +28273,7 @@ This adds support for Groovy, which I specifically need to work with Jenkinsfile
4.4.6. Dockerfile
-This adds support for Dockerfiles. I need this at work.
+This adds support for Dockerfiles in a similar way to [BROKEN LINK: ebd53be9-c38a-4a0f-a7b4-eee30a0074fc].
@@ -27667,7 +28289,7 @@ This adds support for Dockerfiles. I need this at work.
4.4.7. Terraform Mode
-This adds support for Terraform configuration files. I need this at work.
+This adds support for Terraform configuration files. This is basically the same as the [BROKEN LINK: 7aa9803f-b419-40fa-aafc-4bb934c8f687] mode as the languages are very similar.
@@ -27688,7 +28310,11 @@ This adds support for Terraform configuration files. I need this at work.
4.4.8. nix formatting
-Adds functions for formatting nix code.
+Adds functions for formatting nix code. I make huge use of this using the chords C-<Space> o b (org-babel-mark-block) and then C-<Space> o n (nixpkgs-fmt-region). This is what I use to keep my nix org-src-blocks formatted. However, using [BROKEN LINK: a67adf2f-20ce-49d6-ba6b-0341ca3d9972], the resulting tangled files will be formatted in any case.
+
+
+
+Note that for files that are not managed using this file (which there should normally not be many of), we can still use nix fmt for running treefmt for formatting and checks.
@@ -27703,7 +28329,7 @@ Adds functions for formatting nix code.
4.4.9. shfmt
-Adds functions for formatting shellscripts.
+Adds functions for formatting shellscripts. Similarly to [BROKEN LINK: 460a47fd-cddc-4080-9eba-6724fc63606e]m I use this using the chords C-<Space> o b (org-babel-mark-block) and then C-<Space> o s (shfmt-region). This is what I use to keep shell script blocks formatted in this file. This is also handled by treefmt, but still, I want this file to stay organized as well.
@@ -27724,6 +28350,10 @@ Adds functions for formatting shellscripts.
4.4.10.1. Mode
+
+Adds a mode for markdown, specifically MultiMarkdown, which allows me to render LaTeX and other nice things.
+
+
(setq markdown-command "pandoc")
@@ -27742,6 +28372,10 @@ Adds functions for formatting shellscripts.
4.4.10.2. LaTeX in Markdown
+
+Allows me to render LaTeX just where I write it. I do not need this as much anymore, but during my studies this was very valuable to me.
+
+
(add-hook 'markdown-mode-hook
@@ -27758,6 +28392,10 @@ Adds functions for formatting shellscripts.
4.4.11. elfeed
+
+This adds elfeed, a neat RSS reader for Emacs. I use this as a client for FreshRSS. While I read most of my feeds on my phone (using Capy Reader), it is still good to have an Emacs-native reader as well. Some time ago I was still running a separate Emacs instance on my server: [BROKEN LINK: 0e07e2fb-adc4-4fd8-9b54-0a59338a471e]. This instance would then sync the read feeds to other instances. This was very brittle however and is only left as a historical note.
+
+
(use-package elfeed)
@@ -27796,7 +28434,7 @@ Adds functions for formatting shellscripts.
4.4.12. Ripgrep
-This is the ripgrep command for Emacs.
+This is the ripgrep package for Emacs.
@@ -27815,7 +28453,7 @@ Tree-sitter is a parsing library integrated into Emacs to provide better syntax
-In order to update the language grammars, run the next command below.
+In order to update the language grammars, run the next command below. NOTE: since we now load epkgs.treesit-grammars.with-all-grammars in Home-manager: Emacs, we actually never run this anymore. I leave it here however for a potential future reader. For safety, I still instruct treesit to install missing grammars on the fly.
@@ -27977,7 +28615,7 @@ magit is the best git utility I have ever used - it has a beautiful interface an
-Also, Emacs needs a little extra love to accept my Yubikey for git commits etc. We also set that here.
+Also, Emacs needs a little extra love to accept my Yubikey for git commits etc. We set that here: [BROKEN LINK: 59df9a4c-2a1f-466b-abe2-fbb8524cd0ed].
@@ -27997,7 +28635,7 @@ Also, Emacs needs a little extra love to accept my Yubikey for git commits etc.
4.4.19. Yubikey support
-The following settings are needed to make sure emacs works for magit commits and pushes. It is not a beautiful solution since commiting uses pinentry-emacs and pushing uses pinentry-gtk2, but it works for now at least.
+The following settings are needed to make sure emacs works for magit commits and pushes. It is not a beautiful solution since commiting uses pinentry-emacs and pushing uses pinentry-gtk2, but it works for now at least. This works especially well since I have switched from pinentry-gtk3 to pinentry-waypromt.
@@ -28031,6 +28669,10 @@ NOTE: Make sure to configure a GitHub token before using this package!
(1) in practice: github -<> settings -<> developer option -<>
create classic token with repo; user; read:org permissions
(2)machine api.github.com login USERNAMEforge password 012345abcdef…
+
+
+
+The above is handled by [BROKEN LINK: ebb558ed-883a-486f-a6f5-8b283eb735a3] and only here as a historical note. Forge lets me interact with non-core git objects like issues and pull requests from within emacs.
@@ -28434,6 +29076,10 @@ company is now disabled since it seems that corfu runs just fine with lsp-mode a
4.4.32. lsp-mode in org-src blocks
+
+This incredible function allows to start a sub-pane in a org-file while in a source-block that spins up a lsp-server. In practise that allows me to use a nix lsp when editing complex blocks in my config. The only bother is that we have to add the modes where it should run manually to org-babel-lang-list, but that is a small price to pay for the usefulness that it brings.
+
+
;; thanks to https://tecosaur.github.io/emacs-config/config.html#lsp-support-src
(cl-defmacro lsp-org-babel-enable (lang)
@@ -28472,6 +29118,11 @@ company is now disabled since it seems that corfu runs just fine with lsp-mode a
4.4.33. lsp-bridge
+
+This is another lsp-implementation for Emacs using multi-threading, so this should be the least blocking one. Still, in general I prefer eglot.
+
+
+
(use-package lsp-bridge
@@ -28754,9 +29405,9 @@ This adds the simple utility of sending desktop notifications whenever a new mai
-
-4.4.39.3. Work: Signing Mails (S/MIME, smime)
-
+
+4.4.39.3. Work: Signing Mails (S/MIME, smime)
+
Used to automatically sign messages sent from my work email address using S/MIME certificate.
@@ -29039,9 +29690,9 @@ Also see `prot-window-delete-popup-frame'." command)
This sections is no longer used really. An introduction can be found in Structure of this file under the historical note. The little noweb-ref blocks that I still use are found in Hosts and Services.
-
-5.1. General steps when setting up a new machine
-
+
+5.1. General steps when setting up a new machine
+
These general steps are needed when setting up a new machine and do not fit into another block well:
@@ -29056,9 +29707,9 @@ These general steps are needed when setting up a new machine and do not fit into
- `systemd-cryptenroll --fido2-device=auto /dev/`
-
-5.2. Current patches and fixes
-
+
+5.2. Current patches and fixes
+
These are current deviations from the standard settings that I take while some things are broken upstream
@@ -31561,25 +32212,26 @@ Here lies defined the readme for GitHub and Forgejo:
### Hosts
- | Name | Hardware | Use |
- |--------------------|-----------------------------------------------------|------------------------------------------------------|
- |π» **pyramid** | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop |
- |π» **bakery** | Lenovo Ideapad 720S-13IKB | Personal laptop |
- |π» **machpizza** | MacBook Pro 2016 | MacOS reference and build sandbox |
- |π **treehouse** | NVIDIA DGX Spark | Workstation, AI playground and home-manager reference|
- |π₯οΈ **winters** | ASRock J4105-ITX, 32GB RAM | Secondary homeserver and data storgae |
- |π₯οΈ **summers** | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM | Main homeserver running microvms, data storage |
- |π₯οΈ **hintbooth** | HUNSN RM02, 8GB RAM | Router |
- |βοΈ **milkywell** | Oracle Cloud: VM.Standard.E2.1.Micro | Authoritative DNS server |
- |βοΈ **moonside** | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Proxy for local services, some lightweight services |
- |βοΈ **belchsfactory**| Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Hydra builder and nix binary cache |
- |βοΈ **monkeycave** | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Gaming server |
- |βοΈ **eagleland** | Hetzner Cloud: CX23 | Mail server |
- |π± **magicant** | Samsung Galaxy Z Flip 6 | Phone |
- |πΏ **drugstore** | - | ISO installer configuration |
- |πΏ **brickroad** | - | Kexec tarball |
- |β **chaotheatre** | - | Demo config for checking out my configurtion |
- |β **toto** | - | Helper configuration for bootstrapping a new system |
+ | Name | Hardware | Use |
+ |---------------------|-----------------------------------------------------|-----------------------------------------------------|
+ |π» **pyramid** | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop |
+ |π» **bakery** | Lenovo Ideapad 720S-13IKB | Personal laptop |
+ |π» **machpizza** | MacBook Pro 2016 | MacOS reference and build sandbox |
+ |π **treehouse** | NVIDIA DGX Spark | AI Workstation, remote builder, hm-only-reference |
+ |π₯οΈ **summers** | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM | Homeserver (microvms), remote builder, datastorage |
+ |π₯οΈ **winters** | ASRock J4105-ITX, 32GB RAM | Homeserver (IoT server in spe) |
+ |π₯οΈ **hintbooth** | HUNSN RM02, 8GB RAM | Router |
+ |βοΈ **stoicclub** | Cloud Server: 1 vCPUs, 8GB RAM | Authoritative dns server |
+ |βοΈ **liliputsteps** | Cloud Server: 1 vCPUs, 8GB RAM | SSH bastion |
+ |βοΈ **twothreetunnel**| Cloud Server: 2 vCPUs, 8GB RAM | Service proxy |
+ |βοΈ **eagleland** | Cloud Server: 2 vCPUs, 8GB RAM | Mailserver |
+ |βοΈ **moonside** | Cloud Server: 4 vCPUs, 24GB RAM | Gaming server, syncthing + lightweight services |
+ |βοΈ **belchsfactory** | Cloud Server: 4 vCPUs, 24GB RAM | Hydra builder and nix binarycache |
+ |π± **magicant** | Samsung Galaxy Z Flip 6 | Phone |
+ |πΏ **drugstore** | - | NixOS-installer ISO for bootstrapping new hosts |
+ |πΏ **brickroad** | - | Kexec tarball for bootstrapping low-memory machines |
+ |β **chaotheatre** | - | Demo config for checking out this configuration |
+ |β **toto** | - | Helper configuration for testing purposes |
</details>
## General Nix tips & useful links
@@ -32044,7 +32696,7 @@ similarly, there exists an version that starts from the right.
diff --git a/modules/home/common/atuin.nix b/modules/home/common/atuin.nix
index 82383f5..f2d79ea 100644
--- a/modules/home/common/atuin.nix
+++ b/modules/home/common/atuin.nix
@@ -8,6 +8,7 @@ in
programs.atuin = {
enable = true;
enableZshIntegration = true;
+ enableBashIntegration = true;
settings = {
auto_sync = true;
sync_frequency = "5m";
diff --git a/modules/home/common/bash.nix b/modules/home/common/bash.nix
index 08176f6..ccf99c4 100644
--- a/modules/home/common/bash.nix
+++ b/modules/home/common/bash.nix
@@ -1,12 +1,20 @@
-{ config, pkgs, lib, ... }:
+{ config, lib, ... }:
{
options.swarselmodules.bash = lib.mkEnableOption "bash settings";
config = lib.mkIf config.swarselmodules.bash {
programs.bash = {
- bashrcExtra = ''
- export PATH="${pkgs.nix}/bin:$PATH"
+ enable = true;
+ # needed for remote builders
+ bashrcExtra = lib.mkIf (!config.swarselsystems.isNixos) ''
+ export PATH="/nix/var/nix/profiles/default/bin:$PATH"
'';
+ historyFile = "${config.home.homeDirectory}/.histfile";
+ historySize = 100000;
+ historyFileSize = 100000;
+ historyControl = [
+ "ignoreboth"
+ ];
};
};
}
diff --git a/modules/home/common/settings.nix b/modules/home/common/settings.nix
index ff86d63..3e5e47a 100644
--- a/modules/home/common/settings.nix
+++ b/modules/home/common/settings.nix
@@ -1,7 +1,7 @@
-{ self, outputs, lib, pkgs, config, globals, nixosConfig ? config, ... }:
+{ self, outputs, lib, pkgs, config, globals, confLib, ... }:
let
inherit (config.swarselsystems) mainUser flakePath isNixos isLinux;
- inherit (nixosConfig.repo.secrets.common) atticPublicKey;
+ inherit (confLib.getConfig.repo.secrets.common) atticPublicKey;
in
{
options.swarselmodules.general = lib.mkEnableOption "general nix settings";
@@ -23,7 +23,7 @@ in
};
in
''
- plugin-files = ${nix-plugins}/lib/nix/plugins
+ plugin-files = ${nix-plugins}/lib/nix/plugins
extra-builtins-file = ${self + /nix/extra-builtins.nix}
'';
settings = {
diff --git a/modules/home/common/zsh.nix b/modules/home/common/zsh.nix
index 30aa13c..50ce19a 100644
--- a/modules/home/common/zsh.nix
+++ b/modules/home/common/zsh.nix
@@ -67,7 +67,10 @@ in
};
history = {
expireDuplicatesFirst = true;
- path = "$HOME/.histfile";
+ append = true;
+ ignoreSpace = true;
+ ignoreDups = true;
+ path = "${config.home.homeDirectory}/.histfile";
save = 100000;
size = 100000;
};
diff --git a/modules/nixos/server/minecraft/default.nix b/modules/nixos/server/minecraft/default.nix
index 40ed55a..bc90c47 100644
--- a/modules/nixos/server/minecraft/default.nix
+++ b/modules/nixos/server/minecraft/default.nix
@@ -1,6 +1,8 @@
-{ lib, config, globals, dns, confLib, ... }:
+{ lib, config, pkgs, globals, dns, confLib, ... }:
let
- inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/var/lib/minecraft"; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6;
+ inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/opt/minecraft"; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6;
+ inherit (config.swarselsystems) mainUser;
+ worldName = "${mainUser}craft";
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
@@ -30,9 +32,9 @@ in
serviceConfig = {
User = "root";
- WorkingDirectory = "/var/lib/minecraft/swarselcraft";
+ WorkingDirectory = "${serviceDir}/${worldName}";
- ExecStart = "/usr/bin/java @user_jvm_args.txt @libraries/net/minecraftforge/forge/1.20.1-47.2.20/unix_args.txt nogui";
+ ExecStart = "${lib.getExe pkgs.temurin-jre-bin-17} @user_jvm_args.txt @libraries/net/minecraftforge/forge/1.20.1-47.2.20/unix_args.txt nogui";
Restart = "always";
RestartSec = 30;
diff --git a/modules/nixos/server/restic.nix b/modules/nixos/server/restic.nix
index f668104..cb5c046 100644
--- a/modules/nixos/server/restic.nix
+++ b/modules/nixos/server/restic.nix
@@ -4,6 +4,14 @@ let
in
{
options.swarselmodules.server.restic = lib.mkEnableOption "enable restic backups on server";
+ options.swarselsystems.server.restic = {
+ bucketName = lib.mkOption {
+ type = lib.types.str;
+ };
+ paths = lib.mkOption {
+ type = lib.types.listOf lib.types.str;
+ };
+ };
config = lib.mkIf config.swarselmodules.server.restic {
sops = {
@@ -26,20 +34,10 @@ in
in
{
backups = {
- SwarselWinters = {
+ "${config.swarselsystems.server.restic.bucketName}" = {
environmentFile = config.sops.templates."restic-env".path;
passwordFile = config.sops.secrets.resticpw.path;
- paths = [
- "/Vault/data/paperless"
- "/Vault/data/koillection"
- "/Vault/data/postgresql"
- "/Vault/data/firefly-iii"
- "/Vault/data/radicale"
- "/Vault/data/matrix-synapse"
- "/Vault/Eternor/Paperless"
- "/Vault/Eternor/Bilder"
- "/Vault/Eternor/Immich"
- ];
+ inherit (config.swarselsystems.server.restic) paths;
pruneOpts = [
"--keep-daily 3"
"--keep-weekly 2"
diff --git a/modules/shared/config-lib.nix b/modules/shared/config-lib.nix
index efe307f..4ecc055 100644
--- a/modules/shared/config-lib.nix
+++ b/modules/shared/config-lib.nix
@@ -8,6 +8,8 @@
domainDefault = service: config.repo.secrets.common.services.domains.${service};
proxyDefault = config.swarselsystems.proxyHost;
+ getConfig = config;
+
gen = { name, user ? name, group ? name, dir ? null, port ? null, domain ? (domainDefault name), address ? addressDefault, proxy ? proxyDefault }: rec {
servicePort = port;
serviceName = name;
diff --git a/secrets/moonside/secrets.yaml b/secrets/moonside/secrets.yaml
index 493716d..d365eb7 100644
--- a/secrets/moonside/secrets.yaml
+++ b/secrets/moonside/secrets.yaml
@@ -14,6 +14,10 @@ microbin-admin-password: ENC[AES256_GCM,data:+UyWJAsQ4Jd5iJgdepJ/m9OvkEewLKQz+A=
microbin-uploader-password: ENC[AES256_GCM,data:20QOWTMLS7iTS/Q=,iv:EuUYcY1l4ykKjWvCA0bpXPU0033jlQ8qjYyqSuLAQl0=,tag:Ka5gWBajMdeZS25AajToiA==,type:str]
#ENC[AES256_GCM,data:ZnMVMv6M,iv:z53BHIVvMUfYseftc6DTU9Mlb9ywEvNHv24TvIZiMFI=,tag:QdeWjrw0pmJsXYobADzA1A==,type:comment]
shlink-api: ENC[AES256_GCM,data:XdfDJMjyhJyeqVB4RKgCdkWT2nYC/Pw21D8H/JzkGLuwGx8Q,iv:zucJGNLX8018gD34NL/BwTe0fPFucqpBtMCYXd3IGHs=,tag:/sN/ayEhUaCPmu6fS+mMHQ==,type:str]
+#ENC[AES256_GCM,data:R5mm4WAJww==,iv:6Uyb7Qtl6vt7nur/NLBlrVtKoPkF3ZjXdAhT24HW/ug=,tag:6X9b1zZbpHoEZmaYb9NQSw==,type:comment]
+resticpw: ENC[AES256_GCM,data:PcrDphqR5Pin2hM=,iv:lnMlqwyCvbH75qbL2eJYblmuFOaVMmbPHjZ5l0n2Glw=,tag:YUxadLufJ2VPghLded851A==,type:str]
+resticaccesskey: ENC[AES256_GCM,data:DOp2cFy1Y5HyXcsQ5O3nsrEOQBtlQQ3P8Q==,iv:0X6HF9kbPNDmhtENHgFeOSHln6xlCf5DNJfqavucDWI=,tag:+THGH00yBT9RhvJtENco2Q==,type:str]
+resticsecretaccesskey: ENC[AES256_GCM,data:qpPTWx16Z92cup6ACh2KQPeIk8KPasQB4e/SwxUxfA==,iv:EqWTKXXA7wyArlF+D33tKF37tz8/ORsjsWjRPYBWPqg=,tag:F21+4cL/cozDIene7UQcyA==,type:str]
sops:
age:
- recipient: age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh
@@ -25,8 +29,8 @@ sops:
bURRem1aY203VW0ya0tZWUY3WTJLQ3MKonflaevgNP91G1cVgzoE6/K800kyG6BK
Goe81HCYFfm86pzv5wV3/38j7fTZNeZnKwPFkMgEUueF1kA8J9V5CA==
-----END AGE ENCRYPTED FILE-----
- lastmodified: "2025-08-12T09:24:55Z"
- mac: ENC[AES256_GCM,data:qeBiuiK/On/NeMpjiCKeIvbQCRH0JcPFldJaTD+nHLtwNU+qpHX4y+dL/jTQrdSWxHV9+E3KmxnakEP91qZnycrSXhwSIIavNtXUP1veuv/JmHOxW6UxpJBJVDeMNe9k2AFQ3gwYEnXrisjvLDkYyqa+E+GsE7b82i3iyerpskY=,iv:jbw0OIJM3vr9SXkdAObc6JS6v4r11s6MPkg33x1sCvU=,tag:/BAMuCJgh78UgOXkTVkN7Q==,type:str]
+ lastmodified: "2025-11-27T14:38:31Z"
+ mac: ENC[AES256_GCM,data:PgNvIZeLRnGo6XYuzYsWhc/5pyKUpNQyXBwlgHk0F734lDlsX0ZPinekq35uDEn8NceWnh7Qi8ATZI/oFMsZn8EcB3SnMj8vzRH20Gm5bpESP2nu5Wxki/m0Eq+6afHFTc0k7dPnbvyQcL0MbUiA+nrembqHWRWo8lmrATWZrSc=,iv:Suf3RdzzeXTVebR4cSvhFCO2kWJV+ZECHy+REMa3KAs=,tag:2LSxZDge/aRMzzMcqWULOg==,type:str]
pgp:
- created_at: "2025-06-13T21:18:31Z"
enc: |-
@@ -60,4 +64,4 @@ sops:
-----END PGP MESSAGE-----
fp: 4BE7925262289B476DBBC17B76FD3810215AE097
unencrypted_suffix: _unencrypted
- version: 3.10.2
+ version: 3.11.0