5 Commits

Author SHA1 Message Date
Shelvacu
d03b383a30 stuff 2024-06-28 14:29:14 -07:00
Shelvacu
3d478c8d37 wip commands 2024-06-22 17:03:25 -07:00
Shelvacu
e052a165ec wip commands 2024-06-22 17:00:44 -07:00
Shelvacu
5a9e975723 Merge branch 'master' of git.uninsane.org:shelvacu/nix-stuff 2024-06-22 16:50:31 -07:00
Shelvacu
91d9098ae2 remove (unnecssary) common-packages 2024-06-22 16:49:44 -07:00
313 changed files with 2993 additions and 20944 deletions

6
.gitignore vendored
View File

@@ -1,6 +1,2 @@
result
result-*
/.generated
/result
.nixos-test-history
/packages/vacu-history/target/
/packages/altcaps/target/

26
.sops.yaml Normal file
View File

@@ -0,0 +1,26 @@
shel_keys: &shel_keys
- &pixel-termux age1y4zp4ddq6xyffd8fgmn2jkl78qfh4m94gcls2cu6vvjnwwznx5uqywjekm
- &t460s age1g9sh8u6s344569d3cg8h30g9h7thld5pexcwzc4549jc84jvceqqjt9cfh
- &pixel-nix age1t5s3txyj403rfecdhq5q2z3cnavy6m543gzyhkl2nu5t8fz0zctqtvm2tj
- &compute-deck-user age1dzdf4rgep3ctk3dnrmrqtdgrchaa8nszfc4dp29gqwsst3z6jyrq57vfsj
machine_host_keys:
- &trip age10lv32k2guszr5y69sez3z5xj92wzmdxvfejd6hm8xr0pmclw2cvq0hk6pe
- &compute-deck-host age1hcqem868xhjdj3lzsvgf0duylwrdp9nqs06a9d0043cpsuhms4as7cqnv4
- &liam age1hkve3khk7fthyrwxjqdf4r37lrqpmnkz6mke7psuphvu2ykynqaq9g6ja5
the_test_key: &test_key age1eqv5759uknu7d46rqyyzsmgt43qumsge33yp2xygapprnt8zu3sqx6kt8w
creation_rules:
- path_regex: secrets/[^/]+$
key_groups:
- age: *shel_keys
- path_regex: ^secrets/liam/
key_groups:
- age:
- *pixel-termux
- *t460s
- *pixel-nix
- *compute-deck-user
- *liam
- path_regex: ^tests/test_secrets/
key_groups:
- age:
- *test_key

View File

@@ -1,31 +1,13 @@
more just notes for now
---
deploy:
```sh
nixos-rebuild switch --flake .#triple-dezert --target-host trip.shelvacu.com --use-remote-sudo
```
---
build flake on remote machine, including eval:
```sh
git add . && ssh trip nix flake check $(nix flake archive --to ssh://trip --json | jq .path -r)
```
---
search for string in closure
```sh
rg search_str $(nix path-info --recursive ./result)
```
or
```sh
rg search_str $(nix path-info --recursive .#qb.trip)
```
more just notes for now
deploy:
```sh
nixos-rebuild switch --flake .#triple-dezert --target-host trip.shelvacu.com --use-remote-sudo
```
build flake on remote machine, including eval:
```sh
git add . && ssh trip nix flake check $(nix flake archive --to ssh://trip --json | jq .path -r)
```

View File

@@ -1,42 +0,0 @@
{
self,
lib,
pkgs,
...
}:
let
ignoreList = [
"iso"
"host-pxe-installer"
"host-pxe-installer-aarch64"
"pxe-initrd"
];
# We don't want iso/img derivations here because they de-dupe terribly. Any change anywhere requires generating a new iso/img file.
isoContentsStr = lib.concatStringsSep "\n" (
map (
c: "${c.source} => ${c.target}"
) self.nixosConfigurations.shel-installer-iso.config.isoImage.contents
);
isoContents = pkgs.writeText "iso-contents" isoContentsStr;
pxeConfig = self.nixosConfigurations.shel-installer-pxe.config;
pxeContents = pkgs.linkFarm "pxe-initrd-contents" {
inherit (pxeConfig.boot.initrd) compressor;
inherit (pxeConfig.system.build) initialRamdisk;
storeContents = pkgs.linkFarmFromDrvs "store-contents" pxeConfig.netboot.storeContents;
};
extraBuilds = { inherit isoContents pxeContents; };
buildListWithout = builtins.filter (v: !builtins.elem v ignoreList) (
builtins.attrNames self.buildList
);
allBuilds = self.buildList // extraBuilds;
in
rec {
archiveList = map (name: {
inherit name;
broken = builtins.elem name self.brokenBuilds;
impure = builtins.elem name self.impureBuilds;
}) (buildListWithout ++ builtins.attrNames extraBuilds);
drvs = allBuilds;
buildDepsDrvs = builtins.mapAttrs (_: v: pkgs.closureInfo { rootPaths = [ v.drvPath ]; }) drvs;
}

View File

@@ -1,30 +0,0 @@
#!/usr/bin/env bash
source shellvaculib.bash
svl_exact_args $# 0
svl_assert_probably_in_script_dir
declare -a nix_eval=(
nix eval
--show-trace
)
declare -a hosts=(
triple-dezert
compute-deck
liam
lp0
#skip shel-installer-*
fw
legtop
mmm
prophecy
)
set -x
"${nix_eval[@]}" --impure ".#.nixOnDroidConfigurations.default.activationPackage"
for host in "${hosts[@]}"; do
"${nix_eval[@]}" ".#.nixosConfigurations.${host}.config.system.build.toplevel"
done

View File

@@ -1,31 +0,0 @@
{
config,
lib,
utils,
vacuModuleType,
...
}:
let
for-systemd-services = lib.concatMapAttrs (cert: units: {
"acme-selfsigned-${cert}" = {
wantedBy = units;
before = units;
};
}) config.vacu.acmeCertDependencies;
for-security-acme-certs = lib.concatMapAttrs (cert: units: {
${cert}.reloadServices = units;
}) config.vacu.acmeCertDependencies;
in
lib.optionalAttrs (vacuModuleType == "nixos") {
options.vacu.acmeCertDependencies = lib.mkOption {
default = { };
example = ''
vacu.acmeCertDependencies."mail.example.com" = [ "postfix.service" ];
'';
type = lib.types.attrsOf (lib.types.listOf utils.systemdUtils.lib.unitNameType);
};
config = {
systemd.services = for-systemd-services;
security.acme.certs = for-security-acme-certs;
};
}

View File

@@ -1,51 +0,0 @@
{
lib,
vacuModuleType,
config,
...
}:
let
inherit (lib) mkOption types filter;
fatalAssertions = map (x: x.message) (filter (x: !x.assertion && x.fatal) config.vacu.assertions);
triggeredWarnings = map (x: x.message) (
filter (x: !x.assertion && !x.fatal) config.vacu.assertions
);
withAsserts =
x:
if fatalAssertions != [ ] then
throw ''
Failed assertions:
${lib.concatStringsSep "\n" (map (x: "- ${x}") fatalAssertions)}''
else
lib.showWarnings triggeredWarnings x;
adapter = {
config = {
assertions = map (x: { inherit (x) assertion message; }) (
filter (x: x.fatal) config.vacu.assertions
);
warnings = triggeredWarnings;
};
};
in
{
imports = lib.optional (vacuModuleType != "plain") adapter;
options.vacu.assertions = mkOption {
default = [ ];
type = types.listOf (
types.submodule {
options.assertion = mkOption { type = types.bool; };
options.message = mkOption { type = types.str; };
options.fatal = mkOption {
type = types.bool;
default = true;
};
}
);
};
options.vacu.withAsserts = mkOption {
readOnly = true;
default = withAsserts;
};
}

View File

@@ -1,29 +0,0 @@
{
lib,
pkgs,
config,
...
}:
let
inherit (lib) types;
in
{
options.vacu.checks = lib.mkOption {
type = types.attrsOf types.package;
default = { };
};
options.vacu.textChecks = lib.mkOption {
type = types.attrsOf types.lines;
default = { };
};
config.vacu.checks = lib.mapAttrs (
name: lines:
pkgs.runCommand "vacu-textChecks-${name}" { } ''
(
set -xev
${lines}
touch "$out"
)
''
) config.vacu.textChecks;
}

29
common/commands.nix Normal file
View File

@@ -0,0 +1,29 @@
{ config, lib, ... }: let
inherit (lib) mkOption types;
in {
options = {
vacu.commands = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, config, options, ... }: {
options = {
content = mkOption {
type = types.str;
default = "";
};
enable = mkOption {
type = types.bool;
default = config.content != "";
defaultText = ''${name}.content != ""'';
};
kind = mkOption {
type = types.enum [ "alias" "function" ];
default = "alias";
};
};
}));
};
};
config = {
#todo
};
}

View File

@@ -1,17 +0,0 @@
# todo: rename this module
# stuff that does actual configuring (so can't be in ./module.nix) but works in nixos module, home-manager modules, and nix-on-droid modules
{
inputs,
vacuModuleType,
config,
lib,
...
}:
lib.optionalAttrs (vacuModuleType != "plain") {
nix.registry = lib.mkIf (!config.vacu.isMinimal) {
vacu.to = {
type = "path";
path = inputs.self.outPath;
};
};
}

View File

@@ -1,125 +0,0 @@
{
config,
lib,
inputs,
vacuModuleType,
vacuModules,
...
}:
let
inherit (lib) mkOption types;
inherit (inputs) self;
expectedModuleTypes = [
"nixos"
"nix-on-droid"
"plain"
];
anyRev = attrs: toString (attrs.rev or attrs.dirtyRev or "unk");
anyShortRev = attrs: toString (attrs.shortRev or attrs.dirtyShortRev or "unk");
in
if !builtins.elem vacuModuleType expectedModuleTypes then
builtins.throw "error: unrecognized vacuModuleType ${builtins.toString vacuModuleType}"
else
{
imports = [
vacuModules.packageSet
vacuModules.systemKind
../dns
./acmeDependencies.nix
./assertions.nix
./checks.nix
./common-but-not.nix
./git.nix
./hosts.nix
./hpn.nix
./lix.nix
./minimal-nixos.nix
./nixos.nix
./nixos-rebuild.nix
./nixvim.nix
./nix.nix
./nix-on-droid.nix
./packages.nix
./remapCapsLock.nix
./shell
./sops.nix
./sourceTree.nix
./staticNames.nix
./units-config.nix
./units-impl.nix
./verify-system
./thunderbird.nix
];
options = {
vacu.rootCAs = mkOption { type = types.listOf types.str; };
vacu.versionId = mkOption {
type = types.str;
readOnly = true;
};
vacu.versionInfo = mkOption { readOnly = true; };
vacu.hostName = mkOption {
type = types.nullOr types.str;
default = null;
};
vacu.shortHostName = mkOption {
type = types.nullOr types.str;
default = config.vacu.hostName;
defaultText = "{option}`vacu.hostName`";
};
vacu.vnopnCA = mkOption {
readOnly = true;
type = types.str;
};
};
config = {
vacu.versionId = "${anyShortRev self}-${self.lastModifiedDate or "unk"}";
vacu.versionInfo =
{
rev = anyRev self;
inherit (self) lastModified lastModifiedDate;
inherit (config.vacu) versionId;
inherit vacuModuleType;
inputRevs = lib.mapAttrs (_: v: anyRev v) inputs;
}
// lib.optionalAttrs (!config.vacu.isMinimal) {
flakePath = self.outPath;
inherit inputs;
};
vacu.nix.caches.vacu = {
url = "https://nixcache.shelvacu.com/";
keys = [ "nixcache.shelvacu.com:73u5ZGBpPRoVZfgNJQKYYBt9K9Io/jPwgUfuOLsJbsM=" ];
};
vacu.nix.caches.nix-community = {
url = "https://nix-community.cachix.org/";
keys = [ "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ];
enable = false;
};
vacu.nix.caches.nix-on-droid = {
url = "https://nix-on-droid.cachix.org/";
keys = [ "nix-on-droid.cachix.org-1:56snoMJTXmDRC1Ei24CmKoUqvHJ9XCp+nidK7qkMQrU=" ];
enable = false;
};
vacu.nix.caches.nixos = {
url = "https://cache.nixos.org/";
keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
};
vacu.vnopnCA = ''
-----BEGIN CERTIFICATE-----
MIIBnjCCAUWgAwIBAgIBBTAKBggqhkjOPQQDAjAgMQswCQYDVQQGEwJVUzERMA8G
A1UEAxMIdm5vcG4gQ0EwHhcNMjQwODEyMjExNTQwWhcNMzQwODEwMjExNTQwWjAg
MQswCQYDVQQGEwJVUzERMA8GA1UEAxMIdm5vcG4gQ0EwWTATBgcqhkjOPQIBBggq
hkjOPQMBBwNCAARqRbSeq00FfYUGeCHVkzwrjrydI56T12xy+iut0c4PemSuhyxC
AgfdKYtDqMNZmSqMaLihzkBenD0bN5i0ndjho3AwbjAPBgNVHRMBAf8EBTADAQH/
MCwGA1UdHgEB/wQiMCCgGDAKhwgKTkwA///8ADAKgggudDJkLmxhbqEEMAKBADAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAjSkbJQCQc1WP6nIP5iLDIKGFrdMAoG
CCqGSM49BAMCA0cAMEQCIFtyawkZqFhvzgmqG/mYNNO6DdsQTPQ46x/08yrEiiF4
AiA+FwAPqX+CBkaSdIhuhv1kIecmvacnDL5kpyB+9nDodw==
-----END CERTIFICATE-----
'';
vacu.rootCAs = [ config.vacu.vnopnCA ];
vacu.ssh.authorizedKeys = import inputs.vacu-keys;
};
}

View File

@@ -1,5 +0,0 @@
{ lib, vacuModuleType, ... }:
lib.optionalAttrs (vacuModuleType == "nixos") {
options.vacu.desktopApps = lib.mkEnableOption "asdf";
#todo
}

186
common/generic.nix Normal file
View File

@@ -0,0 +1,186 @@
{ config, pkgs, lib, inputs, ... }: let
inherit (lib) mkOption types flip concatMapStringsSep optionalString concatStringsSep readFile mapAttrsToList literalExpression;
inherit (builtins) attrValues;
cfg = config.vacu;
packageNames = lib.splitString "\n" ''
ruby_3_3
nixos-rebuild
nano
vim
wget
screen
tmux
lsof
htop
mosh
dnsutils
iperf3
nmap
rsync
ethtool
sshfs
ddrescue
pciutils
ncdu
nix-index
git
pv
unzip
file
ripgrep
jq
units
tree
rclone
iputils
ssh-to-age
sops
inetutils
neovim
diffutils
findutils
utillinux
tzdata
hostname
man
gnugrep
gnused
gnutar
bzip2
gzip
xz
zip
unzip
openssh
dig
bash
git'';
plainPackageOpts = map (name: { name = name; value = { enable = lib.mkDefault true; }; }) packageNames;
packageOpts = lib.recursiveUpdate (builtins.listToAttrs plainPackageOpts) {
nix-search-cli.package = inputs.nix-search-cli.packages.${pkgs.system}.default;
nix-search-cli.enable = lib.mkDefault true;
nix-inspect.package = inputs.nix-inspect.packages.${pkgs.system}.default;
nix-inspect.enable = lib.mkDefault true;
};
in {
imports = [ ./package-set.nix ./ssh.nix ./commands.nix ];
options = {
vacu.nix.extraSubstituters = mkOption { type = types.listOf types.str; };
vacu.nix.extraTrustedKeys = mkOption { type = types.listOf types.str; };
};
config = {
vacu.packages = packageOpts;
vacu.nix.extraSubstituters = [
"https://nixcache.shelvacu.com/"
"https://nix-community.cachix.org/"
];
vacu.nix.extraTrustedKeys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
"nixcache.shelvacu.com:73u5ZGBpPRoVZfgNJQKYYBt9K9Io/jPwgUfuOLsJbsM="
];
vacu.ssh.authorizedKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC4LYvUe9dsQb9OaTDFI4QKPtMmOHOGLwWsXsEmcJW86" # Termux on pixel6pro
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHcYwYy9/0Gu/GsqS72Nkz6OkId+zevqXA/aTIcvqflp" # t460s windows
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFsErA6M9LSHj2hPlLuHD8Lpei7WjMup1JxI1vxA6B8W" # pixel6pro nix-on-droid
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKoy1TrmfhBGWtVedgOM1FB1oD2UdodN3LkBnnLx6Tug" # compute-deck
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICVeSzDkGTueZijB0xUa08e06ovAEwwZK/D+Cc7bo91g" # triple-dezert
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOtwtao/TXbiuQOYJbousRPVesVcb/2nP0PCFUec0Nv8" # triple-dezert (root)
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAxAFFxQMXAgi+0cmGaNE/eAkVfEl91wafUqFIuAkI5I" # compute-deck (root)
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDcRDekd8ZOYfQS5X95/yNof3wFYIbHqWeq4jY0+ywQX" # pro1x nix-on-droid
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExSObd1lZprdqAFLqFhtxDEckV0q/vZZIYqrYFKfkoC" # devver
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGHLPOxRd68+DJ/bYmqn0wsgwwIcMSMyuU1Ya16hCb/m" # fw (root)
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINQ2c0GzlVMjV06CS7bWbCaAbzG2+7g5FCg/vClJPe0C" # fw
];
vacu.ssh.config = ''
Host deckvacu
User deck
Host rsb
User user
HostName finaltask.xyz
Port 2222
Host awoo
HostName 45.142.157.71
Host trip
HostName trip.shelvacu.com
Port 6922
Host liam
HostName 178.128.79.152
Host pluto
HostName pluto.somevideogam.es
Host *
User shelvacu
GlobalKnownHostsFile ${pkgs.writeText "known_hosts" knownHostsText}
'';
vacu.ssh.knownHosts = {
#public hosts
"github.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
"gitlab.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf";
#colin's stuff
"uninsane.org" = {
extraHostNames = [ "git.uninsane.org" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8";
};
"desko" = {
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk";
};
#daymocker's stuff
"pluto" = {
extraHostNames = [ "74.208.184.137" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICpHY4fLZ1hNuB2oRQM7R3b4eQyIHbFB45ZYp3XCELLg";
};
#personal hosts
"zigbee-hub" = {
extraHostNames = [ "10.78.79.114" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBJxwUYddOxgViJDOiokfaQ6CsCx/Sw+b3IisdJv8zFN root@zigbee-hub";
};
trip = {
extraHostNames = [ "triple-dezert" "trip.shelvacu.com" "[trip.shelvacu.com]:6922" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGUQux9V0mSF5IauoO1z311NXR7ymEbwRMzT+OaaNQr+";
};
servacu = {
extraHostNames = [ "mail.dis8.net" "servacu.shelvacu.com" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE+E6na7np0HnBV2X7owno+Fg+bNNRSHLxO6n1JzdUTV";
};
finaltask = {
extraHostNames = [ "rsb" "finaltask.xyz" "[finaltask.xyz]:2222" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTx8WBNNKBVRV98HgDChpd59SHbreJ87SXU+zOKan6y";
};
compute-deck = {
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGt43GmXCxkl5QjgPQ/QimW11lKfXmV4GFWvlxQSf4TQ";
};
"2esrever" = {
extraHostNames = [ "10.4.5.218" "10.244.46.71" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH0LnPrJxAdffZ//uRe3NBiIfFCBNMLqKVylkyU0llvT";
};
awoo = {
extraHostNames = [ "45.142.157.71" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQaDjjfSK8jnk9aFIiYH9LZO4nLY/oeAc7BKIPUXMh1";
};
deckvacu = {
publicKey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEa8qpFkIlLLJkH8rmEAn6/MZ9ilCGmEQWC3CeFae7r1kOqfwRk0nq0oyOGJ50uIh+PpwEh3rbgq6mLfpRfsFmM=";
};
liam = {
extraHostNames = [ "liam.dis8.net" "178.128.79.152" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHOqJYVHOIFmEA5uRbbirIupWvyBLAFwic/8EZQRdN/c";
};
devver = {
extraHostNames = [ "devver.t2d.lan" "10.78.79.10" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFeFaH2tzWIiCPdKNmxl3NqCnPTdmVIOBinauUAEl+UU";
};
fw = {
extraHostNames = [ "fw.t2d.lan" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA6lX25mCy35tf1NpcHMAdeRgvT7l0Dw0FWBH3eX4TE2";
};
};
};
}

View File

@@ -1,58 +0,0 @@
{ lib, config, vacuModules, ... }:
{
imports = [ vacuModules.git ];
vacu.git.enable = lib.mkDefault config.vacu.isDev;
vacu.git.config = {
init.defaultBranch = "master";
pull.rebase = false;
user.name = "Shelvacu";
user.email = "git@shelvacu.com";
author.name = "Shelvacu";
author.email = "git@shelvacu.com";
committer.name = "Shelvacu on ${config.vacu.hostName}";
committer.email = "git@shelvacu.com";
user.useConfigOnly = true;
checkout.workers = 0;
# "We *could* use atomic writes, but those are slowwwwww! Are you sure?????" - git, still living in the 90s
# Yes git, I'm sure
core.fsync = "all";
diff.mnemonicPrefix = true;
gc.reflogExpire = "never";
gc.reflogExpireUnreachable = "never";
url."https://github.com/".insteadOf = [
"hgh:"
"github-http:"
"github-https:"
];
url."git@github.com:".insteadOf = [
"sgh:"
"gh:"
"github-ssh:"
];
url."git@github.com:shelvacu/".insteadOf = [ "vgh:" ];
url."https://gitlab.com/".insteadOf = [
"hgl:"
"gitlab-http:"
"gitlab-https:"
];
url."git@gitlab.com:".insteadOf = [
"sgl:"
"gl:"
"gitlab-ssh:"
];
url."git@gitlab.com:shelvacu/".insteadOf = [ "vgl:" ];
url."https://git.uninsane.org/".insteadOf = [
"hu:"
"uninsane-http:"
"uninsane-https:"
];
url."git@git.uninsane.org:".insteadOf = [
"u:"
"su:"
"uninsane-ssh"
];
url."git@git.uninsane.org:shelvacu/".insteadOf = [ "vu:" ];
};
}

View File

@@ -1,4 +0,0 @@
{ ... }:
{
imports = [ ./common-but-not.nix ];
}

View File

@@ -1,155 +0,0 @@
{ lib, vacuModules, ... }:
{
imports = [
vacuModules.knownHosts
vacuModules.ssh
];
vacu.hosts = {
#public hosts
"github.com".sshKeys =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
"gitlab.com".sshKeys =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf";
"git.sr.ht".sshKeys =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZvRd4EtM7R+IHVMWmDkVU3VLQTSwQDSAvW0t2Tkj60";
"sdf.org" = {
sshHostname = "tty.sdf.org";
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJJk3a190w/1TZkzVKORvz/kwyKmFY144lVeDFm80p17";
};
"rsn" = {
altNames = [
"rsyncnet"
"rsync.net"
];
sshUsername = "fm2382";
sshHostname = "fm2382.rsync.net";
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINdUkGe6kKn5ssz4WRZKjcws0InbQqZayenzk9obmP1z";
};
#colin's stuff
"servo" = {
altNames = [
"git.uninsane.org"
"uninsane.org"
];
isLan = true;
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8";
};
"desko" = {
isLan = true;
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk";
};
#daymocker's stuff
"pluto" = {
sshHostname = "pluto.somevideogam.es";
primaryIp = "74.208.184.137";
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICpHY4fLZ1hNuB2oRQM7R3b4eQyIHbFB45ZYp3XCELLg";
};
#powerhouse hosts
"ostiary" = {
isLan = true;
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBSYyd1DGPXGaV4mD34tUbXvbtIi/Uv2otoMUsCkxRse";
};
"habitat" = {
# previously known as zigbee-hub
primaryIp = "10.78.79.114";
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBJxwUYddOxgViJDOiokfaQ6CsCx/Sw+b3IisdJv8zFN";
};
"vnopn" = {
primaryIp = "10.78.79.1";
isLan = true;
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEMgJE8shlTYF3nxKR/aILd1SzwDwhtCrjz9yHL7lgSZ";
};
#personal hosts
triple-dezert = {
altNames = [
"trip"
"trip.shelvacu.com"
"triple-dezert.shelvacu.com"
];
sshAliases = [ "trip" ];
primaryIp = "172.83.159.53";
altIps = [ "10.78.79.237" ];
isLan = true;
sshPort = 6922;
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGUQux9V0mSF5IauoO1z311NXR7ymEbwRMzT+OaaNQr+";
};
prophecy = {
altNames = [
"prop"
"prop.shelvacu.com"
"prophecy.shelvacu.com"
];
sshAliases = [ "prop" ];
primaryIp = "205.201.63.13";
altIps = [ "10.78.79.22" ];
isLan = true;
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFPmy1+1CL6mLbp0IfRTLwsVdjKmw5u0kbQqHin8oXMq";
};
servacu = {
altNames = [
"mail.dis8.net"
"servacu.shelvacu.com"
];
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE+E6na7np0HnBV2X7owno+Fg+bNNRSHLxO6n1JzdUTV";
};
finaltask = {
altNames = [
"rsb"
"finaltask.xyz"
];
sshAliases = [ "rsb" ];
primaryIp = "45.87.250.193";
sshPort = 2222;
sshUsername = "user";
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPTx8WBNNKBVRV98HgDChpd59SHbreJ87SXU+zOKan6y";
};
compute-deck = {
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGt43GmXCxkl5QjgPQ/QimW11lKfXmV4GFWvlxQSf4TQ";
};
"2esrever" = {
altIps = [
"10.4.5.218"
"10.244.46.71"
];
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH0LnPrJxAdffZ//uRe3NBiIfFCBNMLqKVylkyU0llvT";
};
awoo = {
primaryIp = "45.142.157.71";
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQaDjjfSK8jnk9aFIiYH9LZO4nLY/oeAc7BKIPUXMh1";
};
deckvacu = {
sshUsername = "deck";
sshKeys = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEa8qpFkIlLLJkH8rmEAn6/MZ9ilCGmEQWC3CeFae7r1kOqfwRk0nq0oyOGJ50uIh+PpwEh3rbgq6mLfpRfsFmM=";
};
liam = {
altNames = [ "liam.dis8.net" ];
primaryIp = "178.128.79.152";
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHOqJYVHOIFmEA5uRbbirIupWvyBLAFwic/8EZQRdN/c";
};
fw = {
isLan = true;
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA6lX25mCy35tf1NpcHMAdeRgvT7l0Dw0FWBH3eX4TE2";
};
legtop = {
altNames = [ "lt" ];
isLan = true;
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKvunOGsmHg8igMGo0FpoXaegYI20wZylG8nsMFY4+JL";
};
mmm = {
primaryIp = "10.78.79.11";
isLan = true;
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFsorkZ3rIZ2lLigwQWfA64xZRlt5lk6QPzypg55eLlD";
};
solis = {
altNames = [ "solis.dis8.net" ];
primaryIp = "89.213.174.171";
# altIps = [ "2a0f:9400:7e11:cd44:0000:0000:0000:0001" ];
sshKeys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPhFKmRMfk+4Xx96Jwt6S9/ikC0cm4ukeO8hjpZDj+9n";
};
};
}

View File

@@ -1,15 +0,0 @@
{
config,
lib,
vacuModuleType,
...
}:
{
# options.vacu.ssh-hpn.enable = lib.mkEnableOption "openssh hpn";
}
// lib.optionalAttrs (vacuModuleType == "nixos") {
# config.nixpkgs.overlays = [ (old: new: {
# openssh-without-hpn = old.openssh;
# openssh = if config.vacu.ssh-hpn.enable then new.openssh_hpn else new.openssh-without-hpn;
# }) ];
}

View File

@@ -1,7 +0,0 @@
{ vacuModuleType, ... }:
if vacuModuleType == "nixos" then
{
# imports = [ inputs.lix-module.nixosModules.default ];
}
else
{ }

View File

@@ -1,53 +0,0 @@
{
config,
pkgs,
lib,
vacuModuleType,
inputs,
...
}:
let
inherit (lib) mkIf mkDefault;
in
lib.optionalAttrs (vacuModuleType == "nixos") {
config = mkIf config.vacu.isMinimal {
programs.git.lfs.enable = false;
programs.git.package = pkgs.gitMinimal;
nix.registry.nixpkgs.to = lib.mkForce {
type = "github";
owner = "NixOS";
repo = "nixpkgs";
rev = inputs.nixpkgs.rev;
};
# mostly copied from nixos's /profiles/minimal.nix
documentation.enable = mkDefault false;
documentation.doc.enable = mkDefault false;
documentation.info.enable = mkDefault false;
documentation.man.enable = mkDefault false;
documentation.nixos.enable = mkDefault false;
# Perl is a default package.
environment.defaultPackages = mkDefault [ ];
environment.stub-ld.enable = false;
# The lessopen package pulls in Perl.
programs.less.lessopen = mkDefault null;
programs.command-not-found.enable = mkDefault false;
services.logrotate.enable = mkDefault false;
services.udisks2.enable = mkDefault false;
xdg.autostart.enable = mkDefault false;
xdg.icons.enable = mkDefault false;
xdg.mime.enable = mkDefault false;
xdg.sounds.enable = mkDefault false;
};
}

View File

@@ -1,4 +0,0 @@
{ ... }:
{
}

View File

@@ -1,71 +0,0 @@
#!/bin/bash
# replaceme START
declare -A cache_to_url
cache_to_url["foo"]="https://example.com/some-nix-cache"
declare -a caches_to_use=("foo")
declare nixCmd="foo"
# replaceme END
declare -a preArgs
declare -a passThruArgs
cache_name=""
function valid_cache_name() {
cache_name="$1"
if [[ $cache_name == -* ]]; then
echo "invalid cache name" >&2
exit 1
fi
}
while [[ -n $1 ]]; do
arg="$1"
shift
case "$arg" in
"--without-cache")
cache_name="$1"
shift
valid_cache_name "$cache_name"
caches_to_use=("${caches_to_use[@]/$cache_name/}")
;;
"--with-cache")
cache_name="$1"
shift
valid_cache_name "$cache_name"
caches_to_use+=("$cache_name")
;;
"--only-cache")
cache_name="$1"
shift
valid_cache_name "$cache_name"
caches_to_use=("$cache_name")
;;
"--on-trip")
if [[ $HOSTNAME == "triple-dezert" ]]; then
echo "Warn: skipping --on-trip: already on trip" >&2
else
passThruArgs+=("--builders" "ssh://trip x86_64-linux,aarch64-linux" "--max-jobs" "0" "--option" "builders-use-substitutes" "true")
fi
;;
"--")
passThruArgs+=("$arg" "$@")
break
;;
*)
passThruArgs+=("$arg")
;;
esac
done
declare -a substituters
for c in "${caches_to_use[@]}"; do
url="${cache_to_url["$c"]}"
substituters+=("$url")
done
substituters_together="${substituters[*]}"
preArgs+=("--option" "substituters" "$substituters_together")
exec "$nixCmd" "${preArgs[@]}" "${passThruArgs[@]}"

View File

@@ -1,20 +0,0 @@
{
config,
lib,
vacuModuleType,
...
}:
let
inherit (lib) mkDefault;
in
lib.optionalAttrs (vacuModuleType == "nix-on-droid") {
nix.substituters = lib.mkForce config.vacu.nix.substituterUrls;
nix.trustedPublicKeys = lib.mkForce config.vacu.nix.trustedKeys;
vacu.shell.functionsDir = "${config.user.home}/.nix-profile/share/vacufuncs";
environment.etc.bashrc.text = config.vacu.shell.interactiveLines;
environment.etc.profile.text = config.vacu.shell.interactiveLines;
environment.etc."vacu/info.json".text = builtins.toJSON config.vacu.versionInfo;
vacu.hostName = mkDefault "nix-on-droid";
vacu.shortHostName = mkDefault "nod";
}

View File

@@ -1,34 +0,0 @@
{ lib, config, ... }:
let
inherit (lib) mkOption types;
caches = builtins.attrValues config.vacu.nix.caches;
enabledCaches = builtins.filter (c: c.enable) caches;
in
{
options = {
vacu.nix.caches = mkOption {
type = types.attrsOf (
types.submodule (
{ ... }:
{
options = {
url = mkOption { type = types.str; };
keys = mkOption {
type = types.listOf types.str;
default = [ ];
};
enable = mkOption {
default = true;
type = types.bool;
};
};
}
)
);
};
vacu.nix.substituterUrls = mkOption { readOnly = true; };
vacu.nix.trustedKeys = mkOption { readOnly = true; };
};
config.vacu.nix.substituterUrls = map (c: c.url) enabledCaches;
config.vacu.nix.trustedKeys = builtins.concatMap (c: c.keys) enabledCaches;
}

View File

@@ -1,23 +0,0 @@
{
pkgs,
config,
lib,
vacuModuleType,
...
}:
let
nixos-rebuild = pkgs.nixos-rebuild.override { nix = config.nix.package; };
in
lib.optionalAttrs (vacuModuleType == "nixos") {
system.build.nixos-rebuild = lib.mkForce (
pkgs.runCommandLocal "nixos-rebuild-wrapped"
{
nativeBuildInputs = [ pkgs.makeShellWrapper ];
meta.mainProgram = "nixos-rebuild";
}
''
mkdir -p "$out"/bin
makeShellWrapper ${lib.getExe nixos-rebuild} "$out"/bin/nixos-rebuild --add-flags "--use-remote-sudo --use-substitutes"
''
);
}

View File

@@ -1,45 +1,51 @@
{ lib, pkgs, config, inputs, utils, ... }:
{
lib,
pkgs,
config,
vacuModuleType,
...
}:
lib.optionalAttrs (vacuModuleType == "nixos") {
imports = [ ../nixos-modules ];
options.vacu.underTest = lib.mkOption {
default = false;
type = lib.types.bool;
imports = [ ./generic.nix ];
options.vacu.acmeCertDependencies = lib.mkOption {
default = {};
example = ''
vacu.acmeCertDependencies."mail.example.com" = [ "postfix.service" ];
'';
type = lib.types.attrsOf (lib.types.listOf utils.systemdUtils.lib.unitNameType);
};
config = {
programs.mosh.enable = true;
config = let
for-systemd-services = lib.concatMapAttrs
(cert: units:
{
"acme-selfsigned-${cert}" = {
wantedBy = units;
before = units;
};
}
)
config.vacu.acmeCertDependencies;
for-security-acme-certs = lib.concatMapAttrs
(cert: units:
{
${cert}.reloadServices = units;
}
)
config.vacu.acmeCertDependencies;
in {
console = {
keyMap = lib.mkDefault "us";
};
networking = lib.mkIf (config.vacu.hostName != null) { inherit (config.vacu) hostName; };
vacu.packages."xorg-xev" = {
enable = config.services.xserver.enable;
package = pkgs.xorg.xev;
};
programs.nix-ld.enable = true;
system.nixos.tags = [
"vacu${config.vacu.versionId}"
config.vacu.hostName
];
environment.etc."vacu/info.json".text = builtins.toJSON config.vacu.versionInfo;
environment.etc."chromium" = lib.mkIf config.vacu.isGui {
source = "/run/current-system/sw/etc/chromium";
};
environment.systemPackages = config.vacu.packageList;
i18n.defaultLocale = lib.mkDefault "en_US.UTF-8";
time.timeZone = "America/Los_Angeles";
users.users.shelvacu = lib.mkIf (!config.vacu.isContainer) {
openssh.authorizedKeys.keys = lib.attrValues config.vacu.ssh.authorizedKeys;
users.users.shelvacu = {
openssh.authorizedKeys.keys = config.vacu.ssh.authorizedKeys;
isNormalUser = true;
extraGroups = [ "wheel" ];
};
systemd.services = for-systemd-services;
security.acme.certs = for-security-acme-certs;
services.openssh = {
# require public key authentication for better security
settings.PasswordAuthentication = false;
@@ -47,45 +53,29 @@ lib.optionalAttrs (vacuModuleType == "nixos") {
settings.PermitRootLogin = "prohibit-password";
};
nix.settings.trusted-users = lib.mkIf (!config.vacu.isContainer) [ "shelvacu" ];
nix.settings.trusted-users = [ "shelvacu" ];
security.sudo.wheelNeedsPassword = lib.mkDefault false;
programs.screen = {
enable = true;
screenrc = ''
defscrollback 10000
termcapinfo xterm* ti@:te@
maptimeout 5
'';
};
} // (if config.system.nixos.release == "23.11" then {} else { enable = true; });
programs.tmux = lib.mkIf (!config.vacu.isContainer) {
enable = true;
extraConfig = "setw mouse";
clock24 = true;
};
programs.tmux.enable = true;
programs.tmux.extraConfig = "setw mouse";
programs.tmux.clock24 = true;
nix.settings = {
experimental-features = [
"nix-command"
"flakes"
];
substituters = lib.mkForce config.vacu.nix.substituterUrls;
extra-substituters = lib.mkForce [ ];
trusted-public-keys = lib.mkForce config.vacu.nix.trustedKeys;
extra-trusted-public-keys = lib.mkForce [ ];
experimental-features = [ "nix-command" "flakes" ];
substituters = config.vacu.nix.extraSubstituters;
trusted-public-keys = config.vacu.nix.extraTrustedKeys;
};
nixpkgs.config.allowUnfree = lib.mkDefault true;
security.pki.certificates = config.vacu.rootCAs;
programs.mosh.enable = lib.mkDefault true;
# commands.nix
environment.pathsToLink = [
"/share/vacufuncs"
"/etc/chromium"
];
programs.bash.interactiveShellInit = config.vacu.shell.interactiveLines;
programs.bash.promptInit = lib.mkForce "";
systemd.services.nix-daemon.serviceConfig.Nice = "10";
programs.ssh.extraConfig = config.vacu.ssh.config;
};
}

View File

@@ -1,31 +0,0 @@
{
pkgs,
config,
inputs,
lib,
...
}:
let
inherit (lib) mkOption types;
nixvim-name = if config.vacu.nixvim.minimal then "nixvim-minimal" else "nixvim";
in
{
options = {
vacu.nixvim.minimal = mkOption {
type = types.bool;
default = config.vacu.isMinimal;
};
vacu.nixvimPkg = mkOption {
type = types.package;
readOnly = true;
};
};
config = {
vacu.nixvimPkg = inputs.self.packages.${pkgs.system}.${nixvim-name};
vacu.shell.functions = lib.mkIf (!config.vacu.isMinimal) {
nvim-plain = ''${pkgs.neovim}/bin/nvim "$@"'';
nvim-nixvim = ''${config.vacu.nixvimPkg}/bin/nvim "$@"'';
nvim = ''nvim-nixvim "$@"'';
};
};
}

32
common/package-set.nix Normal file
View File

@@ -0,0 +1,32 @@
{ config, pkgs, lib, ... }: let
inherit (lib) mkOption types;
pkgOptions = builtins.attrValues config.vacu.packages;
enabledOptions = builtins.filter (o: o.enable) pkgOptions;
enabledPkgs = builtins.map (o: o.package) enabledOptions;
in {
options = {
vacu.packages = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, config, options, ... }: {
options = {
enable = mkOption {
type = types.bool;
default = true;
description = "Will this package be installed (included in environment.systemPackages)";
};
package = mkOption {
type = types.package;
default = pkgs.${name};
defaultText = "pkgs.${name}";
};
};
}));
};
vacu.packageList = mkOption {
type = types.listOf types.package;
readOnly = true;
};
};
config.vacu.packageList = enabledPkgs;
}

View File

@@ -1,263 +0,0 @@
{
pkgs,
config,
lib,
vacuModuleType,
...
}:
let
enableFfmpeg = !config.vacu.isMinimal;
enableFfmpegFull = enableFfmpeg && config.vacu.isGui;
enableFfmpegHeadless = enableFfmpeg && !config.vacu.isGui;
winePkgs = pkgs.wineWow64Packages;
in
{
vacu.packages = lib.mkMerge [
{
borgbackup.enable = config.vacu.isDev && (pkgs.system != "aarch64-linux"); # borgbackup build is borken on aarch64
ffmpeg-vacu-full = {
enable = enableFfmpegFull;
package = pkgs.ffmpeg-full;
overrides.libbluray = config.vacu.packages.libbluray-all.finalPackage;
};
ffmpeg-vacu-headless = {
enable = enableFfmpegHeadless;
package = pkgs.ffmpeg-headless;
overrides.libbluray = config.vacu.packages.libbluray-all.finalPackage;
};
libbluray-all = {
package = pkgs.libbluray;
overrides = {
withJava = true;
withAACS = true;
withBDplus = true;
};
};
inkscape-all = {
package = pkgs.inkscape-with-extensions;
# null actually means everything https://github.com/NixOS/nixpkgs/commit/5efd65b2d94b0ac0cf155e013b6747fa22bc04c3
overrides.inkscapeExtensions = null;
};
p7zip-unfree = {
package = pkgs.p7zip;
overrides.enableUnfree = true;
};
wine.package = winePkgs.waylandFull;
wine-fonts.package = winePkgs.fonts;
vacu-units.package = config.vacu.units.finalPackage;
}
(lib.mkIf config.vacu.isGui
# just do all the matrix clients, surely one of them will work enough
''
cinny-desktop
element-call
element-desktop
fluffychat
fractal
gomuks
gomuks-web
# hydrogen has no -desktop version
iamb
kazv
matrix-commander
matrix-commander-rs
matrix-dl
mm
neosay
nheko
pinecone
# quaternion # build is borked
''
)
(lib.mkIf config.vacu.isGui
# pkgs for systems with a desktop GUI
''
acpi
anki
audacity
arduino-ide
bitwarden-desktop
brave
dino
filezilla
gamemode
gnome-maps
gparted
ghidra
gimp
haruna
iio-sensor-proxy
inkscape-all
jellyfin-media-player
josm
kdePackages.elisa
kdePackages.kdenlive
libreoffice-qt6-fresh
# librewolf
linphone
merkaartor
nextcloud-client
obsidian
openscad
openshot-qt
orca-slicer
OSCAR
prismlauncher
shotcut
signal-desktop
svp
# thunderbird #managed thru vacu.programs.thunderbird
tremotesf
ungoogled-chromium
vlc
wayland-utils
wev
wine
wine-fonts
wireshark
wl-clipboard
''
)
# pkgs for development-ish
(lib.mkIf config.vacu.isDev ''
cargo
clippy
gnumake
man-pages
patchelf
python3
ruby
rustc
rust-script
shellcheck
stdenv.cc
'')
(lib.mkIf (!config.vacu.isMinimal)
# big pkgs for non-minimal systems
''
aircrack-ng
android-tools
bitwarden-cli
dmidecode
fido2-manage
flac
hdparm
home-manager
imagemagickBig
kanidm_1_6
libsmi
man
mdadm
megatools
mercurial #aka hg
minicom
mkvtoolnix-cli
# neovim => see common/nixvim.nix
net-snmp
nix-index
nix-inspect
nix-search-cli
nix-tree
nmap
nvme-cli
proxmark3
rclone
ripgrep-all
smartmontools
tcpdump
termscp
tshark
yt-dlp
''
)
# pkgs included everywhere
''
_7zip
altcaps
ddrescue
dig
dnsutils
ethtool
file
# git is handled by common/git.nix
gnutls
gptfdisk
hostname
htop
inetutils
iperf3
iputils
jq
jujutsu
killall
libossp_uuid # provides `uuid` binary
linuxquota
lshw
lsof
mosh
nano
ncdu
netcat-openbsd
nixos-rebuild
openssl
# p7zip-unfree
pciutils
progress
psutils
pv
ripgrep
rsync
screen
# sed => gnused
shellvaculib
# sops => should use `nr vacu#sops` instead
sshfs
ssh-to-age
# tar => gnutar
tmux
tree
tzdata
# units => vacu-units
unzip
usbutils
vacu-units
vim
wget
zip
''
# packages that are in [`requiredPackages`][1] in nixos, but maybe not included in nix-on-droid
# [1]: https://github.com/NixOS/nixpkgs/blob/26d499fc9f1d567283d5d56fcf367edd815dba1d/nixos/modules/config/system-path.nix#L11
(lib.optionalAttrs (vacuModuleType == "nix-on-droid") ''
#stdenv.cc.libc shouldn't be needed right?
acl
attr
bashInteractive
bzip2
cpio
curl
diffutils
findutils
gawk
getent
getconf
gnugrep
gnupatch
gnused
gnutar
gzip
less
libcap
mkpasswd
ncurses
#netcat is replaced by netcat-openbsd
openssh
procps
su
time
util-linux
which
xz
zstd
'')
];
}

View File

@@ -1,36 +0,0 @@
{
pkgs,
lib,
config,
vacuModuleType,
...
}:
let
inherit (lib) mkOption types;
in
lib.optionalAttrs (vacuModuleType == "nixos") {
options.vacu.enableCapsLockRemap = mkOption {
type = types.bool;
default = config.vacu.isGui;
defaultText = "{option}`vacu.isGui`";
};
config = lib.mkIf config.vacu.enableCapsLockRemap {
# https://discourse.nixos.org/t/best-way-to-remap-caps-lock-to-esc-with-wayland/39707/6
services.interception-tools =
let
itools = pkgs.interception-tools;
itools-caps = pkgs.interception-tools-plugins.caps2esc;
in
{
enable = true;
plugins = [ itools-caps ];
# requires explicit paths: https://github.com/NixOS/nixpkgs/issues/126681
udevmonConfig = pkgs.lib.mkDefault ''
- JOB: "${itools}/bin/intercept -g $DEVNODE | ${itools-caps}/bin/caps2esc -m 1 | ${itools}/bin/uinput -d $DEVNODE"
DEVICE:
EVENTS:
EV_KEY: [KEY_CAPSLOCK, KEY_ESC]
'';
};
};
}

View File

@@ -1,29 +0,0 @@
{
pkgs,
lib,
config,
vaculib,
...
}:
let
inherit (vaculib) script;
in
{
options.vacu.shell.containerAliases = lib.mkEnableOption "container aliases";
config = lib.mkIf config.vacu.shell.containerAliases {
vacu.packages = [
(script "ncrun" ''
svl_min_args $# 2
svl_auto_sudo
container="$1"
shift
exec ${lib.getExe pkgs.nixos-container} run "$container" -- "$@"
'')
(script "ncrl" ''
svl_exact_args $# 1
svl_auto_sudo
exec ${lib.getExe pkgs.nixos-container} root-login "$1"
'')
];
};
}

View File

@@ -1,192 +0,0 @@
{
config,
lib,
pkgs,
vaculib,
...
}:
let
inherit (lib) mkOption types;
cfg = config.vacu.shell;
writeShellFunction =
name: text:
pkgs.writeTextFile {
inherit name;
executable = false;
destination = "/share/vacufuncs/${name}";
text = ''
${text}
'';
checkPhase = ''
${pkgs.stdenv.shellDryRun} "$target"
'';
};
functionPackages = lib.mapAttrsToList writeShellFunction cfg.functions;
vacuInitFile = pkgs.writeText "vacu.shell.interactiveLines.sh" cfg.interactiveLines;
wrappedBashPkg = vaculib.makeWrapper {
original = pkgs.bash;
new = "vacuinit-bash";
prepend_flags = [
"--init-file"
vacuInitFile
];
};
wrappedBash = lib.getExe wrappedBashPkg;
in
{
imports = [
./not-aliases.nix
./ps1.nix
./container-aliases.nix
./vacuhistory.nix
./qcd.nix
];
options = {
vacu.shell.functionsDir = mkOption {
type = types.path;
default = "/run/current-system/sw/share/vacufuncs";
};
vacu.shell.interactiveLines = mkOption {
type = types.lines;
readOnly = true;
};
vacu.shell.wrappedBash = mkOption { readOnly = true; };
vacu.shell.idempotentShellLines = mkOption {
type = types.lines;
default = "";
};
vacu.shell.color = mkOption {
type = types.enum (builtins.attrNames vaculib.shellColors);
default = "white";
};
vacu.shell.functions = mkOption { type = types.attrsOf types.str; };
};
config.vacu = {
shell.interactiveLines = ''
if [[ $- == *i* ]]; then
SHELLVACULIB_COMPAT=1 source ${lib.escapeShellArg pkgs.shellvaculib.file}
if [[ -f ${cfg.functionsDir}/vacureload ]]; then
function __vacushell_load() { eval "$(<${cfg.functionsDir}/vacureload)"; }
__vacushell_load
unset __vacushell_load
fi
fi
'';
shell.wrappedBash = wrappedBash;
shell.idempotentShellLines = lib.mkBefore ''
PROMPT_COMMAND=()
PS0=""
'';
shell.functions = {
"vacureload" = ''
declare -gA vacuShellFunctionsLoaded
if ! [[ -f ${cfg.functionsDir}/vacureload ]]; then
echo "vacureload: I think that's my cue to leave (${cfg.functionsDir}/vacureload not found, assuming vacureload-less config has been loaded and unloading myself)" 1>&2
for funcname in "''${!vacuShellFunctionsLoaded[@]}"; do
unset -f $funcname
done
return
fi
for funcname in "''${!vacuShellFunctionsLoaded[@]}"; do
if ! [[ -f ${cfg.functionsDir}/$funcname ]]; then
unset -f $funcname
fi
done
for fullPath in ${cfg.functionsDir}/*; do
local funcname="$(basename "$fullPath")"
local followedPath="$(readlink -f "$fullPath")"
if [[ "''${vacuShellFunctionsLoaded[$funcname]-}" != "$followedPath" ]]; then
unset -f $funcname
eval "function ''${funcname}() { if [[ -f '$fullPath' ]]; then eval "'"$'"(<'$fullPath')"'"'"; else echo '$funcname is no longer there, kindly removing myself.' 1>&2; unset $funcname; return 1; fi }"
vacuShellFunctionsLoaded[$funcname]=$followedPath
fi
unset followedPath
unset funcname
done
__run_idempotents
# your idempotent shell lines are idempotent, right?
__run_idempotents
'';
"__run_idempotents" = cfg.idempotentShellLines;
vhich = ''
if [[ $# != 1 ]]; then
echo "expected exactly one arg" 1>&2
return 1
fi
declare query="$1"
declare quote='`'"$query'"
declare kind="$(type -t -- "$query")"
if [[ "$kind" == "" ]]; then
echo "could not find any command $quote" 1>&2
return 1
fi
echo "$quote is a $kind"
case "$kind" in
"alias")
alias "$query"
return 0
;;
"keyword")
echo "See https://www.gnu.org/software/bash/manual/html_node/Reserved-Word-Index.html"
return 0
;;
"function")
if [[ -v vacuShellFunctionsLoaded["$query"] ]]; then
echo "$quote is a vacufunc"
path="''${vacuShellFunctionsLoaded[$query]}"
# continue to below
else
declare -f "$query"
return 0
fi
;;
"builtin")
echo "Docs: https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html#index-$query"
return 0
;;
"file")
path="$(type -p "$query")"
# continue to below
;;
*)
echo 'ERR: unexpected return from `type -t`: '"$kind" 1>&2
return 1
esac
echo "path:"
while [[ -L "$path" ]]; do
declare dest="$(readlink -- "$path")"
echo " $path is a symlink to $dest"
if [[ "$dest" != /* ]]; then
dest="$(dirname -- "$path")/$dest"
fi
path="$dest"
done
echo " $path"
if ! [[ -e "$path" ]]; then
echo "$path does not exist!"
return 1
fi
if ! [[ -x "$path" ]]; then
echo "$path is not executable!"
return 1
fi
canon="$(readlink -f -- "$path")"
if [[ "$path" != "$canon" ]]; then
echo " $path canonicalizes to $canon"
path="$canon"
fi
magic_parse="$(file --brief --mime -- "$path")"
echo "magic: $magic_parse"
case "$magic_parse" in
'text/x-shellscript;'* | 'text/plain;'*)
echo "initial contents:"
echo
head --lines=10 "$path" | head --bytes=2000
echo "..."
;;
esac
'';
};
packages = functionPackages;
};
}

View File

@@ -1,226 +0,0 @@
# These are the things that might in a simpler time go in ~/.bashrc as aliases. But they're not aliases, cuz aliases are bad
{
pkgs,
lib,
config,
vaculib,
...
}:
let
inherit (vaculib) script;
simple =
name: args:
let
binContents = ''
#!${lib.getExe pkgs.bash}
exec ${lib.escapeShellArgs args} "$@"'';
funcContents = ''
declare aliasName=${lib.escapeShellArg name}
declare -a replacementWords=(${lib.escapeShellArgs args})
declare replacementStr
declare oldIFS="$IFS"
IFS=' '
replacementStr="''${replacementWords[*]}"
IFS="$oldIFS"
COMP_LINE="''${COMP_LINE/#$aliasName/$replacementStr}"
COMP_POINT=$(( COMP_POINT + ''${#replacementStr} - ''${#aliasName} ))
COMP_CWORD=$(( COMP_CWORD + ''${#replacementWords[@]} - 1 ))
COMP_WORDS=("''${replacementWords[@]}" "''${COMP_WORDS[@]:1}")
_comp_command_offset 0
'';
in
pkgs.runCommandLocal "vacu-notalias-simple-${name}"
{
pname = name;
meta.mainProgram = name;
}
''
mkdir -p "$out"/bin
printf '%s' ${lib.escapeShellArg binContents} > "$out"/bin/${name}
chmod a+x "$out"/bin/${name}
out_base="$(basename -- "$out")"
LC_ALL=C
completion_function_name="_completion_''${out_base//[^a-zA-Z0-9_]/_}"
completion_file="$out"/share/bash-completion/completions/${name}
mkdir -p "$(dirname -- "$completion_file")"
printf '%s() {\n%s\n}\n' "$completion_function_name" ${lib.escapeShellArg funcContents} > "$completion_file"
printf 'complete -F %s %s\n' "$completion_function_name" ${lib.escapeShellArg name} >> "$completion_file"
'';
ms_text = with_sudo: ''
svl_minmax_args $# 1 2
host="$1"
session_name="''${2:-main}"
set -x
mosh -- "$host" ${lib.optionalString with_sudo "sudo"} screen -RdS "$session_name"
'';
systemctl = "${pkgs.systemd}/bin/systemctl";
journalctl = "${pkgs.systemd}/bin/journalctl";
in
{
imports = [ { vacu.packages.copy-altcaps.enable = config.vacu.isGui; } ];
vacu.packages = [
(script "ms" (ms_text false))
(script "mss" (ms_text true))
(script "msl" ''
svl_exact_args $# 1
host="$1"
echo 'echo "user:"; screen -ls; echo; echo "root:"; sudo screen -ls' | ssh -T "$host"
'')
(script "rmln" ''
svl_min_args $# 1
for arg in "$@"; do
if [[ "$arg" != -* ]] && [[ ! -L "$arg" ]]; then
svl_die "$arg is not a symlink"
fi
done
rm "$@"
'')
(script "copy-altcaps" ''
result="$(altcaps "$@")"
printf '%s' "$result" | wl-copy
echo "Copied to clipboard: $result"
'')
(script "nr" ''
# nix run nixpkgs#<thing> -- <args>
svl_min_args $# 1
installable="$1"
shift
if [[ "$installable" != *'#'* ]]; then
installable="nixpkgs#$installable"
fi
nix run "$installable" -- "$@"
'')
(script "nb" ''
# nix build nixpkgs#<thing> <args>
svl_min_args $# 1
installable="$1"
shift
if [[ "$installable" != *'#'* ]]; then
installable="nixpkgs#$installable"
fi
nix build "$installable" "$@"
'')
(script "ns" ''
# nix shell nixpkgs#<thing>
svl_min_args $# 1
new_args=( )
for arg in "$@"; do
if [[ "$arg" != *'#'* ]] && [[ "$arg" != -* ]]; then
arg="nixpkgs#$arg"
fi
new_args+=("$arg")
done
nix shell "''${new_args[@]}"
'')
(script "nixview" ''
svl_min_args $# 1
view_cmd="$1"
shift
d="$(mktemp -d --suffix=vacu-nixview)"
l="$d/out"
nix build --out-link "$l" "$@"
"$view_cmd" "$l"
rm -r "$d"
'')
(simple "nixcat" [
"nixview"
"cat"
])
(simple "nixless" [
"nixview"
"less"
])
(simple "sc" [ systemctl ])
(simple "scs" [
systemctl
"status"
"--lines=20"
"--full"
])
(simple "scc" [
systemctl
"cat"
])
(simple "scr" [
systemctl
"restart"
])
(simple "jc" [
journalctl
"--pager-end"
])
(simple "jcu" [
journalctl
"--pager-end"
"-u"
])
(simple "gs" [
"git"
"status"
])
(script "list-auto-roots" ''
auto_roots="/nix/var/nix/gcroots/auto"
svl_exact_args $# 0
echo "List of auto-added nix gcroots, excluding system profiles:"
echo
for fn in "$auto_roots/"*; do
if ! [[ -L "$fn" ]]; then
die "fn is not a symlink!?: $fn"
fi
pointed="$(readlink -v -- "$fn")"
if ! [[ -e "$pointed" ]]; then
continue
fi
if [[ "$pointed" == /nix/var/nix/profiles/system-* ]]; then
continue
fi
printf '%s\n' "$pointed"
done
'')
];
vacu.shell.functions = {
nd = ''
svl_min_args $# 1
declare -a args=("$@")
lastarg="''${args[-1]}"
if [[ "$lastarg" == "-"* ]]; then
echo "nd: last argument must be the directory" 1>&2
return 1
fi
for arg in "''${args[@]::''${#args[@]}-1}"; do
if [[ "$arg" != "-"* ]]; then
echo "nd: last argument must be the directory" 1>&2
return 1
fi
done
mkdir "''${args[@]}" && cd "''${args[-1]}"
'';
nt = ''pushd "$(mktemp -d "$@")"'';
};
vacu.textChecks."vacu-shell-functions-nd" = ''
source ${lib.escapeShellArg pkgs.shellvaculib.file}
function nd() {
${config.vacu.shell.functions.nd}
}
start=/tmp/test-place
mkdir -p $start
cd $start
nd a
[[ "$PWD" == "$start/a" ]]
cd $start
nd -p b/c
[[ "$PWD" == "$start/b/c" ]]
'';
vacu.textChecks."vacu-shell-functions-nt" = ''
source ${lib.escapeShellArg pkgs.shellvaculib.file}
function nt() {
${config.vacu.shell.functions.nt}
}
start=$PWD
nt
[[ "$PWD" != "$start" ]]
popd
[[ "$PWD" == "$start" ]]
'';
}

View File

@@ -1,57 +0,0 @@
{
config,
lib,
vaculib,
vacuModuleType,
...
}:
let
cfg = config.vacu.shell;
# https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
colors = vaculib.shellColors;
# TODO: reset_without_clear doesn't fully work
# thanks colin https://git.uninsane.org/colin/nix-files/src/commit/7f5b2628016c8ca1beec417766157c7676a9c5e5/hosts/common/programs/zsh/starship.nix#L24
# https://man.archlinux.org/man/bash.1#PROMPTING
# \[ and \] begins and ends "a sequence of non-printing characters"
set_color = colornum: ''\[\e[1;${toString colornum}m\]'';
set_inverted_color = colornum: ''\[\e[1;37;${toString (colornum + 10)}m\]'';
reset_color = ''\[\e[0m\]'';
colornum = colors.${cfg.color};
root_text = root: lib.optionalString root "ROOT@";
final = root: if root then (set_inverted_color colors.red) + "!!" else "$";
hostName = if vacuModuleType == "plain" then ''\h'' else config.vacu.shortHostName;
default_ps1 =
root:
""
+ ''\n''
# + ''\[${reset_without_clear}\]''
+ (set_color colornum)
+ "${root_text root}${hostName}:\\w"
+ " "
+ ''$(vacu_shell_show_return_code)''
+ ''\n''
+ (set_color colornum)
+ (final root)
+ reset_color
+ " ";
in
{
vacu.shell.idempotentShellLines = ''
function vacu_shell_show_return_code() {
local ret=$?
local color=${toString colors.green}
if [[ "$ret" != 0 ]]; then
color=${toString colors.red}
fi
printf '\e[1;%dm' $color
printf "%d" "$ret"
return "$ret"
}
if [[ $EUID == 0 ]]; then
PS1=${lib.escapeShellArg (default_ps1 true)}
else
PS1=${lib.escapeShellArg (default_ps1 false)}
fi
'';
}

View File

@@ -1,50 +0,0 @@
{
lib,
config,
vacuModuleType,
vaculib,
...
}:
let
inherit (lib) mkOption types;
home =
if vacuModuleType == "nix-on-droid" then
"/data/data/com.termux.nix/files/home"
else
"/home/shelvacu";
in
{
options.vacu.qcd = mkOption {
default = { };
type = types.attrsOf types.path;
};
config.vacu.shell.functions.qcd = ''
svl_exact_args $# 1
declare the_arg="$1"
declare base="''${the_arg%%/*}"
declare rest="''${the_arg:''${#base}}"
declare path
if false; then :
${lib.pipe config.vacu.qcd [
(lib.mapAttrsToList (
alias: path:
''elif [[ $base == ${lib.escapeShellArg alias} ]]; then path=${lib.escapeShellArg path}''
))
(lib.concatStringsSep "\n")
]}
fi
if ! [[ -v path ]]; then
svl_eprintln "unrecognized alias $base"
return 1
fi
cd -- "$path$rest"
'';
config.vacu.qcd = {
ns = "${home}/dev/nix-stuff";
np = "${home}/dev/nixpkgs";
dev = "${home}/dev";
};
}

View File

@@ -1,11 +0,0 @@
{ ... }:
{
config.vacu.shell.idempotentShellLines = ''
if [[ $- == *i* ]]; then
# don't overwrite files by default when using > redirection
set -o noclobber
# disable ! history expansion
set +o histexpand
fi
'';
}

View File

@@ -1,15 +0,0 @@
{ pkgs, ... }:
{
config.vacu = {
shell.idempotentShellLines = ''
if [[ -z "''${VACU_HISTORY_SESSION_ID-}" ]]; then
VACU_HISTORY_SESSION_ID="$(${pkgs.libossp_uuid}/bin/uuid)"
fi
VACU_HISTORY_DB_PATH="$HOME/vacu-shell-history.sqlite"
function vacu_history_record() {
LC_ALL=C HISTTIMEFORMAT='%S|%M|%H|%d|%m|%Y|%w|%j|%z|' history 1 | VACU_HISTORY_SESSION_ID="$VACU_HISTORY_SESSION_ID" VACU_HISTORY_DB_PATH="$VACU_HISTORY_DB_PATH" ${pkgs.vacu-history}/bin/vacu-history
}
PS0='$(vacu_history_record >/dev/null)'"$PS0"
'';
};
}

View File

@@ -1,82 +0,0 @@
{
lib,
pkgs,
config,
vaculib,
...
}:
let
ssh-to-age = lib.getExe pkgs.ssh-to-age;
sshToAge =
sshPubText:
vaculib.outputOf {
name = "age-from-ssh.txt";
cmd = ''printf '%s' ${lib.escapeShellArg sshPubText} | ${ssh-to-age} > "$out"'';
};
userKeys = lib.attrValues config.vacu.ssh.authorizedKeys;
userKeysAge = map sshToAge userKeys;
agesOf = hostname: map sshToAge config.vacu.hosts.${hostname}.sshKeys;
singleGroup = keys: [ { age = keys; } ];
testAgeSecret = "AGE-SECRET-KEY-1QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQPQQ94XCHF";
testAgePublic = vaculib.outputOf {
name = "test-age-public-key.txt";
cmd = ''printf '%s' ${lib.escapeShellArg testAgeSecret} | ${pkgs.age}/bin/age-keygen -y > "$out"'';
};
sopsConfig = {
creation_rules = [
{
path_regex = "/secrets/misc/[^/]+$";
key_groups = singleGroup userKeysAge;
}
{
path_regex = "/secrets/hosts/liam\\.yaml$";
key_groups = singleGroup (userKeysAge ++ agesOf "liam");
}
{
path_regex = "/secrets/hosts/triple-dezert\\.yaml$";
key_groups = singleGroup (userKeysAge ++ agesOf "triple-dezert");
}
{
path_regex = "/secrets/hosts/prophecy\\.yaml$";
key_groups = singleGroup (userKeysAge ++ agesOf "prophecy");
}
{
path_regex = "/secrets/hosts/solis\\.yaml$";
key_groups = singleGroup (userKeysAge ++ agesOf "solis");
}
{
path_regex = "/secrets/radicle-private\\.key$";
key_groups = singleGroup (userKeysAge ++ agesOf "fw");
}
{
path_regex = "/secrets/garage-rpc\\.key$";
key_groups = singleGroup (userKeysAge ++ agesOf "triple-dezert" ++ agesOf "prophecy" ++ agesOf "solis");
}
{
path_regex = "/tests/triple-dezert/test_secrets/";
key_groups = singleGroup [ testAgePublic ];
}
];
};
sopsConfigFile = pkgs.writers.writeYAML "sops.yaml" sopsConfig;
wrappedSops = vaculib.makeWrapper {
original = lib.getExe pkgs.sops;
new = "vacu-nix-stuff-sops";
add_flags = [
"--config"
sopsConfigFile
];
run = lib.singleton ''
set -e
age_keys=("${testAgeSecret}" "$(cat $HOME/.ssh/id_ed25519 | ${lib.getExe pkgs.ssh-to-age} -private-key)")
export SOPS_AGE_KEY
printf -v SOPS_AGE_KEY "%s\n" "''${age_keys[@]}"
# declare -p SOPS_AGE_KEY
'';
};
in
{
options.vacu.sopsConfigFile = vaculib.mkOutOption sopsConfigFile;
options.vacu.wrappedSops = vaculib.mkOutOption wrappedSops;
}

View File

@@ -1,26 +0,0 @@
{
inputs,
pkgs,
lib,
config,
vacuModuleType,
...
}:
let
inherit (lib) mkOption types;
in
{
options.vacu.sourceTree = mkOption {
readOnly = true;
type = types.package;
};
config =
{
vacu.sourceTree = pkgs.linkFarm "simple-inputs-tree" inputs;
}
// (lib.optionalAttrs (vacuModuleType == "nixos" || vacuModuleType == "nix-on-droid") {
environment.etc = lib.optionalAttrs (!config.vacu.isMinimal) {
"vacu/sources".source = "${config.vacu.sourceTree}";
};
});
}

113
common/ssh.nix Normal file
View File

@@ -0,0 +1,113 @@
{ config, pkgs, lib, inputs, ... }: let
inherit (lib) mkOption types flip concatMapStringsSep optionalString concatStringsSep readFile mapAttrsToList literalExpression;
inherit (builtins) attrValues;
cfg = config.vacu;
knownHosts = attrValues cfg.ssh.knownHosts;
knownHostsText = (flip (concatMapStringsSep "\n") knownHosts
(h: assert h.hostNames != [];
optionalString h.certAuthority "@cert-authority " + concatStringsSep "," h.hostNames + " "
+ (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile)
)) + "\n";
in {
options = {
vacu.ssh.authorizedKeys = mkOption {
type = types.listOf types.str;
};
vacu.ssh.config = mkOption {
type = types.lines;
};
# Straight copied from nixpkgs
# https://github.com/NixOS/nixpkgs/blob/46397778ef1f73414b03ed553a3368f0e7e33c2f/nixos/modules/programs/ssh.nix
vacu.ssh.knownHosts = mkOption {
default = {};
type = types.attrsOf (types.submodule ({ name, config, options, ... }: {
options = {
certAuthority = mkOption {
type = types.bool;
default = false;
description = ''
This public key is an SSH certificate authority, rather than an
individual host's key.
'';
};
hostNames = mkOption {
type = types.listOf types.str;
default = [ name ] ++ config.extraHostNames;
defaultText = literalExpression "[ ${name} ] ++ config.${options.extraHostNames}";
description = ''
A list of host names and/or IP numbers used for accessing
the host's ssh service. This list includes the name of the
containing `knownHosts` attribute by default
for convenience. If you wish to configure multiple host keys
for the same host use multiple `knownHosts`
entries with different attribute names and the same
`hostNames` list.
'';
};
extraHostNames = mkOption {
type = types.listOf types.str;
default = [];
description = ''
A list of additional host names and/or IP numbers used for
accessing the host's ssh service. This list is ignored if
`hostNames` is set explicitly.
'';
};
publicKey = mkOption {
default = null;
type = types.nullOr types.str;
example = "ecdsa-sha2-nistp521 AAAAE2VjZHN...UEPg==";
description = ''
The public key data for the host. You can fetch a public key
from a running SSH server with the {command}`ssh-keyscan`
command. The public key should not include any host names, only
the key type and the key itself.
'';
};
publicKeyFile = mkOption {
default = null;
type = types.nullOr types.path;
description = ''
The path to the public key file for the host. The public
key file is read at build time and saved in the Nix store.
You can fetch a public key file from a running SSH server
with the {command}`ssh-keyscan` command. The content
of the file should follow the same format as described for
the `publicKey` option. Only a single key
is supported. If a host has multiple keys, use
{option}`programs.ssh.knownHostsFiles` instead.
'';
};
};
}));
description = ''
The set of system-wide known SSH hosts. To make simple setups more
convenient the name of an attribute in this set is used as a host name
for the entry. This behaviour can be disabled by setting
`hostNames` explicitly. You can use
`extraHostNames` to add additional host names without
disabling this default.
'';
example = literalExpression ''
{
myhost = {
extraHostNames = [ "myhost.mydomain.com" "10.10.1.4" ];
publicKeyFile = ./pubkeys/myhost_ssh_host_dsa_key.pub;
};
"myhost2.net".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILIRuJ8p1Fi+m6WkHV0KWnRfpM1WxoW8XAS+XvsSKsTK";
"myhost2.net/dsa" = {
hostNames = [ "myhost2.net" ];
publicKeyFile = ./pubkeys/myhost2_ssh_host_dsa_key.pub;
};
}
'';
};
};
config = {
assertions = flip mapAttrsToList cfg.ssh.knownHosts (name: data: {
assertion = (data.publicKey == null && data.publicKeyFile != null) ||
(data.publicKey != null && data.publicKeyFile == null);
message = "knownHost ${name} must contain either a publicKey or publicKeyFile";
});
};
};

View File

@@ -1,89 +0,0 @@
{
lib,
vacuModuleType,
config,
...
}:
let
inherit (lib) mkOption types;
domainPartRegex = "[[:alnum:]]([[:alnum:]-]{0,61}[[:alnum:]])?";
domainRegex = ''^${domainPartRegex}(\.${domainPartRegex})*$'';
domainType = types.strMatching domainRegex;
hostsLines = lib.pipe config.vacu.staticNames [
(lib.mapAttrsToList (k: v: [ k ] ++ v))
(lib.filter (v: (builtins.length v) > 1))
(map (lib.concatStringsSep " "))
(lib.concatStringsSep "\n")
];
ip4Seg = ''[0-9]{1,3}'';
ip4Regex = lib.concatStringsSep ''\.'' [
ip4Seg
ip4Seg
ip4Seg
ip4Seg
];
ip6Regex = ''[0-9a-fA-F:]+'';
ipRegex = ''(${ip4Regex})|(${ip6Regex})'';
in
{
imports =
[
{
vacu.assertions = map (ip: {
assertion = (builtins.match ipRegex ip) != null;
message = ''config.vacu.staticNames: attr name "${ip}" is invalid'';
}) (builtins.attrNames config.vacu.staticNames);
}
]
++ lib.optional (vacuModuleType == "nixos") { networking.hosts = config.vacu.staticNames; }
++ lib.optional (vacuModuleType == "nix-on-droid") {
environment.etc.hosts.text = ''
127.0.0.1 localhost
::1 localhost
${hostsLines}
'';
};
options.vacu.staticNames = mkOption {
type = types.attrsOf (types.listOf domainType);
default = { };
};
config.vacu.staticNames = {
"205.201.63.13" = [
"prop"
"prophecy"
"prophecy.shelvacu-static"
];
"10.78.79.22" = [ "prophecy.t2d.lan.shelvacu-static" ];
"178.128.79.152" = [
"liam"
"liam.shelvacu-static"
];
"172.83.159.53" = [
"trip"
"triple-dezert"
"triple-dezert.shelvacu-static"
];
"10.78.79.237" = [ "triple-dezert.t2d.lan.shelvacu-static" ];
"205.201.63.12" = [
"servo"
"uninsane-servo.shelvacu-static"
];
"10.78.79.1" = [
"vnopn"
"vnopn.shelvacu-static"
"vnopn.t2d.lan.shelvacu-static"
];
"10.78.79.11" = [
"mmm"
"mmm.shelvacu-static"
"mmm.t2d.lan.shelvacu-static"
];
"10.78.79.69" = [
"oeto"
"oeto.shelvacu-static"
"oeto.t2d.lan.shelvacu-static"
];
};
}

View File

@@ -1,100 +0,0 @@
{
lib,
config,
vacuModuleType,
vaculib,
...
}:
let
inherit (lib) mkOption types;
vacustoreCalUUID = "dd9a924e-57d9-4ea1-b7ec-22d1f0ff3d51";
vacustoreCalConfig = {
"cache.enabled" = true;
calendar-main-in-composite = true;
color = "#33d17a";
disabled = false;
"imip.identity.key" = "id1"; #what is this
name = "Personal";
readOnly = false;
type = "caldav";
uri = "https://vacu.store/remote.php/dav/calendars/shelvacu/personal/";
username = "shelvacu";
};
in
{
options.vacu.programs.thunderbird = {
enable = mkOption {
default = false;
type = types.bool;
};
};
config = lib.optionalAttrs (vacuModuleType == "nixos") (lib.mkIf config.vacu.programs.thunderbird.enable {
programs.thunderbird = {
enable = true;
policies = {
DisableTelemetry = true;
DNSOverHTTPS.Enabled = false;
ExtensionSettings = {
#*cloud - FileLink for Nextcloud and ownCloud
"cloud@johannes-endres.de".installation_mode = "normal_installed";
#NTFNTF: Notify on This Folder Not That Folder
"ntfntf@dan-sullivan.co.uk".installation_mode = "normal_installed";
};
SSLVersionMin = "tls1.3";
SearchEngines.Remove = [
"Amazon.com"
"Bing"
"DuckDuckGo"
"Google"
"Wikipedia (en)"
];
};
preferences = {
"accessibility.typeaheadfind.flashBar" = 0; #what is this
"app.donation.eoy.version.viewed" = -1; #dunno if this actually works
"browser.search.region" = "US";
"calendar.alarms.playsound" = false;
"calendar.alarms.show" = false;
"calendar.ui.version" = 3;
"intl.date_time.pattern_override.date_full" = "MMMM d, yyyy G z";
"intl.date_time.pattern_override.date_short" = "yyyy-MM-dd";
"intl.date_time.pattern_override.time_medium" = "HH:mm:ss z";
"intl.date_time.pattern_override.time_short" = "HH:mm";
# "ldap_2.servers.Contacts.carddav.url" = "https://vacu.store/remote.php/dav/addressbooks/users/shelvacu/contacts/";
# "ldap_2.servers.Contacts.carddav.username" = "shelvacu";
# "ldap_2.servers.Contacts.description" = "vacu.store Contacts";
# "ldap_2.servers.Contacts.dirType" = 102; #no idea what this does
"mail.account.account1.identities" = "id1,id2,id3";
"mail.account.account1.server" = "server1";
"mail.compose.other.header" = "X-Shelvacu-Custom-Header";
"mail.compose.warned_about_customize_from" = true;
"mail.identity.id1.fullName" = "Shelvacu";
"mail.identity.id1.useremail" = "shelvacu@shelvacu.com";
"mail.identity.id1.catchAll" = true;
"mail.server.server1.hostname" = "imap.shelvacu.com";
"mail.server.server1.login_at_startup" = true;
"mail.server.server1.name" = "shelvacu@shelvacu.com";
"mail.server.server1.port" = 993;
"mail.server.server1.type" = "imap";
"mail.server.server1.socketType" = 3; #TLS (as opposed to plaintext or STARTTLS)
"mail.server.server1.userName" = "shelvacu";
"mail.shell.checkDefaultClient" = false;
"mail.showCondensedAddresses" = false;
"mail.smtp.defaultserver" = "smtp1";
"mail.smtpserver.smtp1.authMethod" = 3;
"mail.smtpserver.smtp1.hostname" = "smtp.shelvacu.com";
"mail.smtpserver.smtp1.port" = 465;
"mail.smtpserver.smtp1.try_ssl" = 3;
"mail.smtpserver.smtp1.type" = "smtp";
"mail.smtpserver.smtp1.username" = "shelvacu";
"mail.startup.enabledMailCheckOnce" = true;
"mail.threadpane.listview" = 1;
"mailnews.customHeaders" = "X-Vacu-Action";
"mailnews.default_sort_type" = 27;
"mailnews.mark_message_read.auto" = false;
"mailnews.start_page.enabled" = false;
# "searchintegration.enable" = false;
} // vaculib.mapAttrNames (n: "calendar.registry.${vacustoreCalUUID}.${n}") vacustoreCalConfig;
};
});
}

View File

@@ -1,35 +0,0 @@
{
vacu.units.extraUnits = {
b = "bit";
B = "byte";
kibi- = "1024";
Ki- = "kibi";
mebi- = "1024 kibi";
Mi- = "mebi";
gibi- = "1024 mebi";
Gi- = "gibi";
tebi- = "1024 gibi";
Ti- = "tebi";
pebi- = "1024 tebi";
Pi- = "pebi";
baud = "bit/s";
kbps = "kilobit/s";
kibps = "kibibit/s";
mbps = "megabit/s";
mibps = "mebibit/s";
gbps = "gigabit/s";
gibps = "gibibit/s";
tbps = "terabit/s";
tibps = "tebibit/s";
pbps = "petabit/s";
pibps = "pebibit/s";
month = "year/12";
mo = "month";
usd = "USD";
dollar = "USD";
cent = "0.01 USD";
"$" = "USD";
BTC = "bitcoin";
};
}

View File

@@ -1,127 +0,0 @@
{
config,
lib,
pkgs,
vaculib,
...
}:
let
inherit (lib) mkOption types;
unitNameRegex =
let
# Unit names cannot begin or end with an underscore (_), a comma (,) or a decimal point (.). Names must not contain any of the operator characters +, -, *, /, |, ^, ;, ~, the comment character #, or parentheses. To facilitate copying and pasting from documents, several typographical characters are converted to operators: the figure dash (U+2012), minus (-; U+2212), and en dash (; U+2013) are converted to the operator -; the multiplication sign (×; U+00D7), N-ary times operator (U+2A09), dot operator (‘⋅’; U+22C5), and middle dot (‘·’; U+00B7) are converted to the operator *; the division sign (‘÷’; U+00F7) is converted to the operator /; and the fraction slash (U+2044) is converted to the operator |; accordingly, none of these characters can appear in unit names.
disallowedAnywhere =
"+*/|^;~#()" + (builtins.fromJSON ''"\u2012\u2212\u2013\u00d7\u2a09\u22c5\u00b7\u00f7\u2044"'');
disallowedMiddle = "-" + disallowedAnywhere;
disallowedAtEnd = "23456789_,." + disallowedAnywhere;
disallowedAtBegin = "-01" + disallowedAtEnd;
anyExcept = chars: "[^${lib.escapeRegex chars}]";
singleChar = anyExcept disallowedAtBegin;
multiChar = "${anyExcept disallowedAtBegin}${anyExcept disallowedMiddle}*${anyExcept disallowedAtEnd}";
numberSuffix = regex: "${regex}_[0-9\\.,]+";
fullRegex = "${singleChar}|${multiChar}|${numberSuffix singleChar}|${numberSuffix multiChar}";
in
fullRegex;
unitsAttrsType = types.addCheck (types.attrsOf types.str) (
attrs: builtins.all (name: (builtins.match unitNameRegex name) != null) (builtins.attrNames attrs)
);
unitsDir = pkgs.stdenvNoCC.mkDerivation {
name = "vacu-units-files";
src = pkgs.units.src;
phases = [
"unpackPhase"
"installPhase"
];
installPhase = ''
mkdir -p "$out"
cp {definitions,elements}.units "$out"
ln -s ${../units/currency.units} "$out"/currency.units
ln -s ${../units/cpi.units} "$out"/cpi.units
printf '%s' ${lib.escapeShellArg config.vacu.units.lines} > "$out"/vacu.units
'';
};
in
{
options.vacu.units = {
originalPackage = mkOption {
type = types.package;
default = pkgs.units.override { enableCurrenciesUpdater = false; };
defaultText = "pkgs.units.override { ... }";
};
finalPackage = mkOption {
type = types.package;
readOnly = true;
};
check = mkOption {
type = types.package;
readOnly = true;
};
generatedConfigDir = mkOption {
readOnly = true;
type = types.package;
};
generatedConfigFile = mkOption {
readOnly = true;
type = types.pathInStore;
};
lines = mkOption {
default = "";
type = types.lines;
};
extraUnits = mkOption {
type = unitsAttrsType;
default = { };
};
};
config = lib.mkMerge [
{
vacu.units = {
finalPackage = vaculib.makeWrapper {
original = config.vacu.units.originalPackage;
new = "units";
prepend_flags = [
"--file"
config.vacu.units.generatedConfigFile
];
};
generatedConfigDir = unitsDir;
generatedConfigFile = "${unitsDir}/vacu.units";
lines = lib.mkOrder 750 ''
# default units file, includes elements.units, currency.units, cpi.units
!include definitions.units
'';
};
vacu.textChecks.units-config = ''
# `units --check` returns success (exit code 0) regardless of success >:(
# example output:
# $ result/bin/units --check
# Currency exchange rates from exchangerate-api.com (USD base) on 2024-11-14
# Consumer price index data from US BLS, 2024-02-18
# 7247 units, 125 prefixes, 134 nonlinear units
#
output="$(${lib.getExe config.vacu.units.finalPackage} --check)"
printf '%s' "$output"
filteredLines="$(printf '%s' "$output" \
| grep -v '^\s*$' \
| grep -v 'Currency exchange rates from' \
| grep -v 'Consumer price index data from' \
| grep -vE '[0-9]+ units, [0-9]+ prefixes, [0-9]+ nonlinear units' || true
)"
if [[ -n "$filteredLines" ]]; then
exit 1
fi
touch "$out"
'';
}
{
vacu.units.lines = lib.concatStringsSep "\n" (
lib.mapAttrsToList (name: value: "+${name} ${value}") config.vacu.units.extraUnits
);
}
];
}

View File

@@ -1,63 +0,0 @@
{
pkgs,
lib,
config,
...
}:
let
inherit (lib) mkOption mkEnableOption types;
cfg = config.vacu.verifySystem;
in
{
imports = [ ./nixos.nix ];
options.vacu.verifySystem = {
enable = (mkEnableOption "verify system is what is expected") // {
default = false;
};
verifiers = mkOption {
default = { };
type = types.attrsOf (
types.submodule (
{ name, config, ... }:
{
options = {
enable = mkEnableOption "Enable system ident check ${name}";
name = mkOption {
type = types.str;
default = name;
};
script = mkOption {
type = types.lines;
default = "## system ident check ${config.name}";
defaultText = lib.literalText ''## system ident check ${name}'';
};
};
}
)
);
};
verifyAllScript =
let
verifiers = (builtins.attrValues cfg.verifiers);
enabled = builtins.filter (s: s.enable) verifiers;
files = map (s: pkgs.writeText "vacu-verify-system-${s.name}.sh" s.script) enabled;
script = ''
## vacu verify-system
for f in ${lib.concatStringsSep " " files}; do
echo "verifying system with $f"
if ! source $f; then
echo "ERR: $f failed" >&2
return 1
fi
done
'';
scriptFile = pkgs.writeText "vacu-verify-system-all.sh" script;
in
mkOption {
readOnly = true;
default = scriptFile;
defaultText = "vacu-verify-system-all.sh package";
};
};
}

View File

@@ -1,69 +0,0 @@
{
lib,
config,
pkgs,
vacuModuleType,
...
}:
let
inherit (lib) mkOption types;
in
lib.optionalAttrs (vacuModuleType == "nixos") {
options.vacu.verifySystem.expectedMac = mkOption {
# lowercase only
type = types.nullOr (types.strMatching "[a-f0-9]{2}(:[a-f0-9]{2}){5}");
default = null;
};
config = lib.mkIf config.vacu.verifySystem.enable {
# system.activationScripts."00-verify-system" = {
# text = "if ! source ${config.vacu.verifySystem.verifyAllScript}; then exit $?; fi";
# supportsDryActivation = true;
# };
system.extraSystemBuilderCmds = ''
mv "$out"/bin/switch-to-configuration "$out"/bin/.switch-to-configuration-unverified
echo '#!${pkgs.bash}/bin/bash
(
PATH="${pkgs.coreutils}/bin"
if ! source ${config.vacu.verifySystem.verifyAllScript}; then
exit $?
fi
)
' > "$out"/bin/switch-to-configuration
echo "exec $out/bin/.switch-to-configuration-unverified" '"$@"' >> "$out"/bin/switch-to-configuration
${pkgs.coreutils}/bin/chmod a+x "$out"/bin/switch-to-configuration
'';
vacu.verifySystem.verifiers = {
hostname = {
enable = lib.mkDefault config.vacu.verifySystem.expectedMac == null;
script = ''
expected=${lib.escapeShellArg config.networking.hostName}
actual="$(</proc/sys/kernel/hostname)"
if [[ "$expected" != "$actual" ]]; then
echo "ERR: unexpected hostname; Trying to deploy to $expected but this is $actual" >&2
return 1
fi
'';
};
expectedMac = {
enable = config.vacu.verifySystem.expectedMac != null;
script = ''
declare expected=${lib.escapeShellArg (lib.toUpper config.vacu.verifySystem.expectedMac)}
declare -a actualMacs
mapfile -d"" -t actualMacs < <(${pkgs.iproute2}/bin/ip -j link | ${pkgs.jq}/bin/jq 'map([.permaddr, .address] | map(strings | ascii_upcase)) | flatten[]' --raw-output0)
for ifMac in "''${actualMacs[@]}"; do
if [[ "$ifMac" == "$expected" ]]; then
# all is well
return 0
fi
done
echo "ERR: Interface MAC address $expected not present, this may not be the system you intend to deploy to." >&2
echo " Found MAC addresses: ''${actualMacs[*]}" >&2
return 1
'';
};
};
};
}

View File

@@ -0,0 +1,6 @@
{ ... }: {
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
services.blueman.enable = true;
}

76
compute-deck/default.nix Normal file
View File

@@ -0,0 +1,76 @@
{ config, pkgs, lib, jovian, inputs, ... }:
{
imports = [
inputs.jovian.nixosModules.jovian
inputs.disko.nixosModules.default
inputs.homeManager.nixosModules.default
./hardware.nix
./partitioning.nix
./home.nix
./bluetooth.nix
./padtype.nix
../common-nixos-config.nix
];
system.nixos.tags = [ "host-${config.networking.hostName}" ];
boot.loader.systemd-boot.enable = false;
boot.loader.efi.efiSysMountPoint = "/boot/EFI";
boot.loader.grub.efiSupport = true;
boot.loader.grub.device = "nodev";
boot.loader.efi.canTouchEfiVariables = false;
boot.loader.grub.efiInstallAsRemovable = true;
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
networking.hostName = "compute-deck";
networking.hostId = "e595d9b0";
boot.supportedFilesystems = [ "zfs" ];
boot.zfs.forceImportRoot = false;
system.stateVersion = "23.11";
jovian.devices.steamdeck.enable = true;
networking.networkmanager.enable = true;
services.xserver.enable = true;
services.displayManager.sddm.enable = true;
services.xserver.desktopManager.plasma5.enable = true;
services.openssh.enable = true;
environment.systemPackages = with pkgs; [
audacity
librewolf
jupiter-hw-support
steamdeck-firmware
steamdeck-bios-fwupd
cargo
clippy
rust-analyzer
rustc
rustfmt
rustup
];
boot.kernelPatches = [
{
name = "gadget";
patch = null;
extraStructuredConfig = with lib.kernel; {
USB_ETH=module;
USB_GADGET=yes;
USB_LIBCOMPOSITE=yes;
USB_CONFIGFS=yes;
USB_DWC3=module;
USB_DWC3_PCI=module;
USB_DWC3_DUAL_ROLE=yes;
USB_DWC3_HOST=no;
USB_DWC3_GADGET=no;
USB_ROLE_SWITCH=yes;
};
}
];
}

62
compute-deck/hardware.nix Normal file
View File

@@ -0,0 +1,62 @@
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "nvme" "usbhid" "sdhci_pci" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
/*
fileSystems."/" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=root" ];
};
fileSystems."/home" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=home" ];
};
fileSystems."/nix" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=nix" ];
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=boot" ];
};
*/
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/2aad8cab-7b97-47de-8608-fe9f12e211a4";
fsType = "ext4";
};
fileSystems."/boot/EFI" =
{ device = "/dev/disk/by-uuid/C268-79C8";
fsType = "vfat";
};
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.wlo1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@@ -1,7 +1,18 @@
{ ... }:
{ inputs, ... }:
{
home-manager.users.shelvacu = {
# these make vscode-remote work
imports = [
inputs.vscode-server.homeModules.default
];
services.vscode-server.enable = true;
home.stateVersion = "23.11";
programs.git = {
enable = true;
userName = "Shelvacu";
userEmail = "git@shelvacu.com";
};
programs.librewolf = {
enable = true;

View File

@@ -1,22 +1,12 @@
{ inputs, ... }:
let
{ inputs, ... }: let
padtype-pkg = inputs.padtype.packages."x86_64-linux".default;
in
{
in {
environment.systemPackages = [ padtype-pkg ];
systemd.services."padtype" = {
wantedBy = [ "multi-user.target" ];
script = "${padtype-pkg}/bin/padtype";
};
boot.initrd.preLVMCommands = "${padtype-pkg}/bin/padtype &";
boot.initrd.kernelModules = [
"uhid"
"i2c_hid_acpi"
"usbhid"
"mac_hid"
"evdev"
"uinput"
];
}

View File

@@ -1,6 +1,5 @@
{ inputs, ... }:
{ ... }:
{
imports = [ inputs.disko.nixosModules.default ];
disko.devices.disk.blarg = {
device = "/dev/disk/by-id/nvme-Micron_2400_MTFDKBK2T0QFM_230341951668_1-part11";
content = {
@@ -14,29 +13,20 @@
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
mountOptions = [ "compress=zstd" "noatime" ];
};
"/home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
mountOptions = [ "compress=zstd" "noatime" ];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
mountOptions = [ "compress=zstd" "noatime" ];
};
# "/swap" = {
# mountpoint = "/.swapvol";
# swap.swapfile.size = "20M";
# };
# "/swap" = {
# mountpoint = "/.swapvol";
# swap.swapfile.size = "20M";
# };
};
};
};

2
dcd
View File

@@ -1,3 +1,3 @@
#!/bin/sh
git add . && nixos-rebuild --flake .#compute-deck --build-host trip --target-host shelvacu@compute-deck --use-remote-sudo "$@"
git add . && nixos-rebuild --flake .#compute-deck --build-host trip --target-host shelvacu@compute-deck --use-remote-sudo $@

View File

@@ -1,29 +0,0 @@
{
system ? builtins.currentSystem,
}:
let
flakeCompat = (import
(
let
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
nodeName = lock.nodes.root.inputs.flake-compat;
in
fetchTarball {
url = lock.nodes.${nodeName}.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.${nodeName}.locked.rev}.tar.gz";
sha256 = lock.nodes.${nodeName}.locked.narHash;
}
)
{
inherit system;
src = ./.;
}
);
flake = flakeCompat.outputs;
overlays = import ./overlays;
pkgs = import flake.inputs.nixpkgs {
inherit system overlays;
};
in
pkgs // {
nixpkgs-update = { ... }@args: import "${flake.inputs.nixpkgs}/maintainers/scripts/update.nix" ({ include-overlays = overlays; } // args);
}

57
devver/default.nix Normal file
View File

@@ -0,0 +1,57 @@
{ config, pkgs, lib, inputs, modulesPath, ... }:
{
imports = [
inputs.homeManager.nixosModules.default
../common-nixos-config.nix
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "virtio_pci" "usbhid" "virtio_blk" "9pnet_virtio" "9p" "autofs4" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" "9pnet_virtio" "9p" "autofs4" ];
boot.extraModulePackages = [ ];
system.nixos.tags = [ "host-${config.networking.hostName}" ];
networking.hostName = "devver";
boot.loader.external.enable = true;
boot.loader.external.installHook = pkgs.writeShellScript "vacuDirectBootInstaller" ''
PATH="$PATH:${pkgs.coreutils}/bin:${pkgs.gnused}/bin"
set -xev
mkdir -p /boot
cp $1/kernel /boot/kernel
cp $1/initrd /boot/initrd
cp $1/kernel-params /boot/kernel-params
sed -i "1 s|$| init=$1/sw/bin/init|" /boot/kernel-params
'';
users.users.root.shell = pkgs.bashInteractive;
fileSystems."/boot" = {
fsType = "9p";
device = "boot";
options = [
"trans=virtio"
"access=any"
"version=9p2000.L"
"posixacl"
"cache=mmap"
"nofail"
"noauto"
];
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/a373835d-b942-4232-85fe-922cb1880af3";
fsType = "ext4";
};
#boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
services.openssh.enable = true;
vacu.packages.nix-inspect.enable = false; #its broken for some reason I don't understand
system.stateVersion = "23.11";
}

2
dliam
View File

@@ -1,3 +1,3 @@
#!/bin/sh
git add . && nixos-rebuild --flake .#liam --build-host trip --target-host shelvacu@liam --use-remote-sudo "$@"
git add . && nixos-rebuild --flake .#liam --build-host trip --target-host shelvacu@liam --use-remote-sudo $@

3
dmmm
View File

@@ -1,3 +0,0 @@
#!/bin/sh
git add . && nixos-rebuild --flake .#mmm --build-host trip --target-host mmm --use-remote-sudo "$@"

View File

@@ -1,137 +0,0 @@
{
dns,
lib,
vaculib,
config,
...
}:
let
inherit (lib) mkOption types singleton;
inherit (dns.lib.combinators)
ns
ttl
spf
mx
;
inherit (config.vacu) hosts;
cloudnsNameServers = [
"pns51.cloudns.net."
"pns52.cloudns.net."
"pns53.cloudns.net."
"pns54.cloudns.net."
];
cloudnsSoa = (
ttl (60 * 60) {
nameServer = lib.head cloudnsNameServers;
adminEmail = "support@cloudns.net";
serial = 1970010101; # cloudns takes care of updating the serial
refresh = 7200;
retry = 1800;
expire = 1209600;
minimum = 3600;
}
);
dkimKeyLiam = {
name = "2024-03-liam";
content = "v=DKIM1; k=rsa; s=email; p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqoFR9cwOb+IpvaqrI55zlouWMUk5hjKHQARajqeOev2I6Gc3QIvU8btyhKCJu7pwxr+DxK/9HeqTmweCSXZmLlVZ6LjW80aAg+8l2DyMKZPaTowSQcExfNMwHqI1ByUPx49LQQEzvwv8Lx3To2+JghZNXHUx7gcraoCUQnRNzCMoMsGF25Yyt4piW6SXKWsbWHVXaL2i953PtT6agJYqssnBqPx6wqibrkeB9MbtSw97L5oQDaDLmJzEK54vRjFFV4X6/Q1d3D6M5PH0XGm6WEhrNEPgMAAZ6rBqi+AoXUz9E9B+kE/Zc6krCTiV0Y1uL83RCILaEJIjRsHqgrGRYEIBUb4Z5d4CgB3szixzaFTmG+XAgDLGnAHRNGeOn0bUmj35miLUopzGJgHCUQYjaaXMH4FSQMYBFPVqZ1aSiZO0EC/mbLlFbBy51RYPJQK0IusN4IqaBYw6jZYMEVlLWkNb34bfNtPKwoG4T3UjxmSRpfiNCFjYd4DaOz/FBAvUL9bx+qU7O6EZRtslROaWN18uSt20hBH0SpvEovj7vBgWWqXG/chNS7YSSaf3Tlb3I5NbqbmvwFF0t8uuEtN0Wh26qMuOKx70K90B9FpJBpfIk/w8FQ80kP6spbMN1v1T5fA7oZMV1fOn1IezH4wE5Yk/3dS+OXJ4YiLH/hWfjecCAwEAAQ==";
};
dmarc = lib.pipe [
# see https://www.rfc-editor.org/rfc/rfc7489.html#section-6.3
"v=DMARC1"
"p=reject" # policy = reject all mail that fails DKIM or SPF
# no need for sp=, policy applies to subdomains by default
"adkim=s" # match dkim domains strictly (foo.shelvacu.com != shelvacu.com)
"aspf=s" # match spf domains strictly
"fo=1" # failure reporting: report a failure if any of dkim or spf fails
"rua=mailto:dmarc-rua@shelvacu.com!25m"
"ruf=mailto:dmarc-ruf@shelvacu.com!25m"
] [
(map (s: s + ";"))
(lib.concatStringsSep " ")
];
vacuZoneExtModule = { config, ... }: {
imports = [ vacuDomainExtModule ];
options.vacu.cloudns = mkOption {
default = true;
type = types.bool;
};
config = lib.mkIf config.vacu.cloudns {
SOA = cloudnsSoa;
NS = map (server: ttl (60 * 60) (ns server)) cloudnsNameServers;
TTL = lib.mkDefault 300;
};
};
vacuDomainExtModule = { config, ... }: {
options.vacu = {
liamMail = mkOption {
default = false;
type = types.bool;
};
_ancestorHasDMARC = mkOption {
type = types.bool;
default = false;
internal = true;
};
};
options.subdomains = mkOption {
type = types.attrsOf (types.submodule [
{
config.vacu._ancestorHasDMARC = config.vacu.liamMail || config.vacu._ancestorHasDMARC;
}
vacuDomainExtModule
]);
};
config = lib.mkMerge [
(lib.mkIf config.vacu.liamMail {
MX = singleton (mx.mx 0 "liam.dis8.net.");
TXT = singleton (
spf.strict [
"mx"
"include:outbound.mailhop.org"
"include:_spf.mailersend.net"
"a:relay.dynu.com"
]
);
subdomains."${dkimKeyLiam.name}._domainkey".TXT = singleton dkimKeyLiam.content;
})
(lib.mkIf (config.vacu.liamMail && !config.vacu._ancestorHasDMARC) {
subdomains._dmarc.TXT = singleton dmarc;
})
];
};
# vacuZone = lib.mkMerge [
# dns.lib.types.zone
# (types.submodule vacuZoneExtModule)
# ];
in
{
imports = [
./jean-luc.org.nix
./pwrhs.win.nix
./shelvacu.miras.pet.nix
./for.miras.pet.nix
./shelvacu.com.nix
./dis8.net.nix
./sv.mt.nix
({ dns, ... }: {
options.vacu.dns = mkOption {
default = { };
type = types.attrsOf dns.lib.types.zone;
};
})
];
options.vacu.dns = mkOption {
type = types.attrsOf (types.submodule vacuZoneExtModule);
};
options.vacu.dnsData = vaculib.mkOutOptions rec {
tripPublicV4 = hosts.triple-dezert.primaryIp;
propPublicV4 = hosts.prophecy.primaryIp;
digitalOcean = {
reservedV4 = "138.197.233.105";
liamPublicV4 = "178.128.79.152";
mailPublicV4 = "167.99.161.174";
};
doV4 = digitalOcean.reservedV4;
awooV4 = hosts.awoo.primaryIp;
};
}

View File

@@ -1,28 +0,0 @@
{
lib,
config,
...
}:
let
inherit (lib) singleton;
inherit (config.vacu) dnsData;
inherit (config.vacu.dnsData.digitalOcean) liamPublicV4 mailPublicV4 reservedV4;
in
{
vacu.dns."dis8.net" = { ... }: {
vacu.liamMail = true;
A = singleton mailPublicV4;
subdomains = {
do-a.A = singleton reservedV4;
liam.A = singleton reservedV4;
mail.A = singleton liamPublicV4;
auwwth = {
subdomains.ns.A = singleton dnsData.awooV4;
NS = singleton "ns.auwwth.dis8.net.";
};
solis.A = singleton config.vacu.hosts.solis.primaryIp;
"_acme-challenge".CNAME = singleton "a55a31f9-74ac-44fc-bf97-c8c9f2498d3a.auth.dis8.net.";
};
};
}

View File

@@ -1,26 +0,0 @@
{ lib, config, ... }:
let
inherit (lib) singleton;
inherit (config.vacu) dnsData;
in
{
vacu.dns."for.miras.pet" =
{ ... }:
{
subdomains = {
"git".A = singleton dnsData.tripPublicV4;
"auth".A = singleton dnsData.tripPublicV4;
"wisdom".A = singleton dnsData.tripPublicV4;
"chat" =
{ ... }:
{
config.vacu.liamMail = true;
config.A = singleton dnsData.tripPublicV4;
config.subdomains."duo-1745490301302-14f65157._domainkey".TXT =
singleton "v=DKIM1; k=rsa; s=email; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA/94Rh5eMPsKwGGolkleY1Rhh2Q6H22bfdGVu0lXpoHP1K7JxloWu/Ice2vVN/udztmPY+BK1x+5qubcGZKpPt1bC9amsXnyTXfKIMGD2CNd0tnaO54hmMOfv+lTA9YjF0X93tcQP3yUxJgJ9yPZcalFl/bBAqv4/lUVLYFeIVQIDAQAB";
};
"gabriel-dropout".A = singleton dnsData.tripPublicV4;
"_acme-challenge".CNAME = singleton "199b8aa4-bc9f-4f43-88bf-3f613f62b663.auwwth.dis8.net.";
};
};
}

View File

@@ -1,24 +0,0 @@
{ lib, config, ... }:
let
inherit (lib) singleton;
inherit (config.vacu) dnsData;
main_ips = singleton dnsData.tripPublicV4;
in
{
vacu.dns."jean-luc.org" =
{ ... }:
{
vacu.liamMail = true;
A = main_ips;
NS = lib.mkAfter [ "ns2.afraid.org." ]; # note: appends to NS records from modules.cloudns
subdomains = {
"in".vacu.liamMail = true;
"*".A = main_ips;
"_acme-challenge".CNAME = singleton "8cc7a174-c4a6-40f5-9fff-dfb271c5ce0b.auwwth.dis8.net.";
"stats".A = main_ips;
"tdi-readings".CNAME = singleton "d20l6bh1gp7s8.cloudfront.net.";
"_a908498ee692a9729bf12e161ae1887d.tdi-readings".CNAME =
singleton "_1f055e4fc0f439e67304a33945d09002.hkvuiqjoua.acm-validations.aws.";
};
};
}

View File

@@ -1,14 +0,0 @@
{ lib, config, ... }:
let
inherit (lib) singleton;
inherit (config.vacu) dnsData;
in
{
vacu.dns."pwrhs.win" =
{ ... }:
{
A = singleton dnsData.tripPublicV4;
subdomains.habitat.A = singleton dnsData.tripPublicV4;
subdomains._acme-challenge.CNAME = singleton "73697955-1c51-48ba-ba1e-b3398850f59f.auwwth.dis8.net.";
};
}

View File

@@ -1,99 +0,0 @@
{
config,
lib,
vaculib,
...
}:
let
s = v: [ v ];
inherit (config.vacu) dnsData;
trip_ips = s dnsData.tripPublicV4;
prop_ips = s dnsData.propPublicV4;
solis_ips = s config.vacu.hosts.solis.primaryIp;
mail_thing = s "178.128.79.152";
# which domains to allow dmarc reports.
# ex: _dmarc.dis8.net TXT has "rua=rua-reports@shelvacu.com", reports will only be sent if shelvacu.com allows them
# allow all domains configured in this repo, and one level of subdomain (ideally all but thats hard, this should be good enough)
allow_report_domains = lib.pipe config.vacu.dns [
lib.attrNames
(list: list ++ [ "theviolincase.com" "violingifts.com" ])
(lib.concatMap (domain: [domain "*.${domain}"]))
];
in
{
vacu.dns."shelvacu.com" =
{ ... }:
{
vacu.liamMail = true;
A = trip_ips;
CAA = [
{
issuerCritical = true;
tag = "issue";
value = "letsencrypt.org";
}
{
issuerCritical = true;
tag = "issue";
value = "sectigo.com";
}
{
issuerCritical = true;
tag = "issuewild";
value = "letsencrypt.org";
}
{
issuerCritical = false;
tag = "iodef";
value = "mailto:caa-violation@shelvacu.com";
}
];
subdomains = {
_acme-challenge.CNAME = s "5cb20bf7-5203-417f-b729-fa3a3ad3b775.auwwth.dis8.net.";
_atproto.TXT = s "did=did:plc:oqenurzqeji6ulii3myxls64";
"_report._dmarc".subdomains = vaculib.mapNamesToAttrsConst { TXT = s "v=DMARC1"; } allow_report_domains;
admin-garage-trip.A = trip_ips;
auth.A = trip_ips;
autoconfig.A = mail_thing;
awoo.A = s "45.142.157.71";
dav.A = trip_ips;
dav-experiment.A = prop_ips;
ft.subdomains = {
"*".A = s "45.87.250.193";
_acme-challenge.CNAME = s "17aa43aa-9295-4522-8cf2-b94ba537753d.auth.acme-dns.io.";
};
# hzo3bcydh5khtpeio6zrzb7kwcwiccnh.subdomains._domainkey.CNAME = s "hzo3bcydh5khtpeio6zrzb7kwcwiccnh.dkim.amazonses.com.";
id.A = trip_ips;
imap.A = mail_thing;
jobs.A = trip_ips;
llm.A = trip_ips;
mail.A = mail_thing;
# mlsend2.subdomains._domainkey.CNAME = s "mlsend2._domainkey.mailersend.net.";
mumble.A = prop_ips;
nixcache.A = trip_ips;
ns1.CNAME = s "pns51.cloudns.net.";
ns2.CNAME = s "pns52.cloudns.net.";
ns3.CNAME = s "pns53.cloudns.net.";
ns4.CNAME = s "pns54.cloudns.net.";
prop.CNAME = s "prophecy";
prophecy.A = prop_ips;
prophecy.subdomains.garage.subdomains = {
s3.A = prop_ips;
admin.A = prop_ips;
};
rad.A = trip_ips;
s3-garage-trip.A = trip_ips;
servacu.A = s "167.99.161.174";
smtp.A = mail_thing;
sol.CNAME = s "solis";
solis.A = solis_ips;
solis.subdomains.garage.subdomains = {
s3.A = solis_ips;
admin.A = solis_ips;
};
trip.A = trip_ips;
vaultwarden.A = trip_ips;
www.A = trip_ips;
};
};
}

View File

@@ -1,15 +0,0 @@
{ lib, config, ... }:
let
inherit (lib) singleton;
inherit (config.vacu) dnsData;
in
{
vacu.dns."shelvacu.miras.pet" =
{ ... }:
{
vacu.liamMail = true;
A = singleton dnsData.tripPublicV4;
subdomains."_acme-challenge".CNAME =
singleton "65e44f64-3c65-46f6-b15f-4ad6363b21eb.auwwth.dis8.net.";
};
}

View File

@@ -1,24 +0,0 @@
{ lib, config, ... }:
let
inherit (lib) singleton;
inherit (config.vacu) dnsData;
in
{
vacu.dns."sv.mt" =
{ ... }:
{
vacu.liamMail = true;
A = singleton dnsData.propPublicV4;
subdomains.www.A = singleton dnsData.propPublicV4;
subdomains.thisthirdlevelisownedbyshelandwasnotmadeavailabletoemily = {
NS = [
"thisns1isonlyusedbyshelandisnotusedforthirdlevelregistrationfor.emilygeil.com."
"thisns2isonlyusedbyshelandisnotusedforthirdlevelregistrationfor.emilygeil.com."
"thisns3isonlyusedbyshelandisnotusedforthirdlevelregistrationfor.emilygeil.com."
"thisns4isonlyusedbyshelandisnotusedforthirdlevelregistrationfor.emilygeil.com."
"thisns5isonlyusedbyshelandisnotusedforthirdlevelregistrationfor.emilygeil.com."
];
# TXT = singleton "ha5d5dc3ca7b34574bc60929e3910ba8a";
};
};
}

3
dprop
View File

@@ -1,3 +0,0 @@
#!/bin/sh
git add . && nixos-rebuild --flake .#prophecy --build-host prop --target-host prop --use-remote-sudo "$@"

2
dtrip
View File

@@ -1,3 +1,3 @@
#!/bin/sh
git add . && nixos-rebuild --flake .#triple-dezert --build-host trip --target-host trip --use-remote-sudo "$@"
git add . && nixos-rebuild --flake .#triple-dezert --build-host trip --target-host trip --use-remote-sudo $@

1086
flake.lock generated

File diff suppressed because it is too large Load Diff

558
flake.nix
View File

@@ -1,497 +1,141 @@
{
description = "Configs for shelvacu's nix things";
description = "Config for triple-dezert server";
inputs = {
nixpkgs.url = "nixpkgs/nixos-25.05-small";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable-small";
disko = {
url = "git+https://git.uninsane.org/shelvacu/disko.git";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable"; #todo: put this back to -small once jovian-nixos is fixed
nixpkgs.url = "nixpkgs/nixos-23.11-small";
nixpkgs2405.url = "nixpkgs/nixos-24.05-small";
nix-inspect = {
url = "github:bluskript/nix-inspect";
#inputs.nixpkgs.follows = "nixpkgs";
};
vscode-server = {
url = "github:nix-community/nixos-vscode-server";
inputs.nixpkgs.follows = "nixpkgs";
};
disko-unstable = {
url = "git+https://git.uninsane.org/shelvacu/disko.git";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
dns = {
url = "github:nix-community/dns.nix";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
};
flake-compat.url = "github:edolstra/flake-compat";
flake-utils.url = "github:numtide/flake-utils";
home-manager = {
url = "github:nix-community/home-manager/release-25.05";
nix-on-droid = {
url = "github:nix-community/nix-on-droid/release-23.05";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager-unstable = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
impermanence.url = "github:nix-community/impermanence";
jovian-unstable = {
# there is no stable jovian :cry:
jovian = {
url = "github:Jovian-Experiments/Jovian-NixOS";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
most-winningest = {
url = "github:captain-jean-luc/most-winningest";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
};
nixos-hardware.url = "github:nixos/nixos-hardware";
nixos-apple-silicon-unstable = {
url = "github:tpwrules/nixos-apple-silicon";
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
nixvim = {
url = "github:nix-community/nixvim/nixos-25.05";
inputs.nixpkgs.follows = "nixpkgs";
};
nixvim-unstable = {
url = "github:nix-community/nixvim";
homeManager = {
url = "github:nix-community/home-manager/master";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
nix-colors = {
url = "github:Misterio77/nix-colors";
};
nix-on-droid = {
url = "github:nix-community/nix-on-droid";
nix-search-cli = {
url = "github:peterldowns/nix-search-cli";
inputs.nixpkgs.follows = "nixpkgs";
inputs.home-manager.follows = "home-manager";
};
padtype-unstable = {
url = "git+https://git.uninsane.org/shelvacu/padtype.git";
inputs.nixpkgs.follows = "nixpkgs-unstable";
padtype = {
url = "gitlab:shelvacu/padtype";
inputs.nixpkgs.follows = "nixpkgs";
};
sm64baserom.url = "git+https://git.uninsane.org/shelvacu/sm64baserom.git";
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
tf2-nix = {
url = "gitlab:shelvacu-forks/tf2-nix/with-my-patches";
microvm = {
url = "github:astro/microvm.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
vacu-keys = {
url = "git+https://git.uninsane.org/shelvacu/keys.nix.git";
flake = false;
};
};
outputs =
{
self,
nixpkgs,
nix-on-droid,
...
}@allInputs:
let
x86 = "x86_64-linux";
arm = "aarch64-linux";
lib = import "${nixpkgs}/lib";
overlays = import ./overlays;
vacuModules = import ./modules;
mkVaculib = { pkgs }: import ./vaculib { inherit pkgs; nix-colors-lib = allInputs.nix-colors.lib; };
vaculib = mkVaculib { inherit pkgs; };
defaultSuffixedInputNames = [
"nixvim"
"nixpkgs"
];
defaultInputs = { inherit (allInputs) self vacu-keys; };
mkInputs =
{
unstable ? false,
inp ? [ ],
}:
let
suffix = if unstable then "-unstable" else "";
inputNames = inp ++ defaultSuffixedInputNames;
thisInputsA = vaculib.mapNamesToAttrs (name: allInputs.${name + suffix}) inputNames;
in
if inp == "all" then allInputs else thisInputsA // defaultInputs;
mkPkgs =
arg:
let
argAttrAll = if builtins.isString arg then { system = arg; } else arg;
unstable = argAttrAll.unstable or false;
whichpkgs = if unstable then allInputs.nixpkgs-unstable else allInputs.nixpkgs;
argAttr = lib.removeAttrs argAttrAll [ "unstable" ];
config = {
allowUnfree = true;
# the security warning might as well have said "its insecure maybe but there's nothing you can do about it"
# presumably needed by nheko
permittedInsecurePackages = [
"olm-3.2.16"
"fluffychat-linux-1.27.0"
];
} // (argAttr.config or { });
in
import whichpkgs (
argAttr // { inherit config; } // { overlays = (argAttr.overlays or [ ]) ++ overlays; }
);
mkCommon =
{
unstable ? false,
inp ? [ ],
system ? x86,
vacuModuleType,
}:
let
pkgsStable = mkPkgs { unstable = false; inherit system; };
pkgsUnstable = mkPkgs { unstable = true; inherit system; };
pkgs = if unstable then pkgsUnstable else pkgsStable;
inputs = mkInputs { inherit unstable inp; };
vaculib = mkVaculib { inherit pkgs; };
in
{
inherit pkgs pkgsStable pkgsUnstable inputs vaculib;
specialArgs = {
inherit inputs vacuModules vacuModuleType vaculib pkgsStable pkgsUnstable;
inherit (allInputs) dns;
};
};
mkPlain =
{
unstable ? false,
system ? x86,
}@args:
let
common = mkCommon (args // {
vacuModuleType = "plain";
inp = "all";
});
inner = lib.evalModules {
modules = [
./common
{ vacu.systemKind = "server"; }
];
specialArgs = common.specialArgs // {
inherit (common) pkgs;
inherit (common.pkgs) lib;
};
};
in
inner.config.vacu.withAsserts inner;
pkgs = mkPkgs x86;
mkNixosConfig =
{
unstable ? false,
module,
system ? "x86_64-linux",
inp ? [ ],
}:
let
common = mkCommon { inherit unstable inp system; vacuModuleType = "nixos"; };
in
allInputs.nixpkgs.lib.nixosSystem {
inherit (common) specialArgs;
inherit system;
modules = [
{ nixpkgs.pkgs = common.pkgs; }
./common
module
];
};
in
{
debug.isoDeriv = (
import "${allInputs.nixpkgs}/nixos/release-small.nix" {
nixpkgs = ({ revCount = 0; } // allInputs.nixpkgs);
}
);
outputs = { self, nixpkgs, nix-on-droid, ... }@inputs: {
debug.isoDeriv = (import "${inputs.nixpkgs}/nixos/release-small.nix" { nixpkgs = ({ revCount = 0; } // inputs.nixpkgs); });
nixosConfigurations.triple-dezert = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./triple-dezert ];
specialArgs = { inherit inputs; };
};
lib = {
inherit
mkPlain
mkPkgs
mkInputs
mkNixosConfig
vaculib
;
};
nixosConfigurations.compute-deck = inputs.nixpkgs-unstable.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./compute-deck ];
specialArgs = { inherit inputs; };
};
nixosConfigurations = {
triple-dezert = mkNixosConfig {
module = ./hosts/triple-dezert;
inp = [
"most-winningest"
"sops-nix"
];
};
compute-deck = mkNixosConfig {
module = ./hosts/compute-deck;
inp = [
"jovian"
"home-manager"
"disko"
"padtype"
];
unstable = true;
};
liam = mkNixosConfig {
module = ./hosts/liam;
inp = [ "sops-nix" ];
};
lp0 = mkNixosConfig { module = ./hosts/lp0; };
shel-installer-iso = mkNixosConfig { module = ./hosts/installer/iso.nix; };
shel-installer-pxe = mkNixosConfig { module = ./hosts/installer/pxe.nix; };
fw = mkNixosConfig {
module = ./hosts/fw;
inp = [
"nixos-hardware"
"sops-nix"
"tf2-nix"
];
};
legtop = mkNixosConfig {
module = ./hosts/legtop;
inp = [ "nixos-hardware" ];
};
mmm = mkNixosConfig {
module = ./hosts/mmm;
inp = [ "nixos-apple-silicon" ];
system = "aarch64-linux";
unstable = true;
};
prophecy = mkNixosConfig {
module = ./hosts/prophecy;
system = "x86_64-linux";
inp = [
"impermanence"
"sops-nix"
"disko"
];
};
solis = mkNixosConfig {
module = ./hosts/solis;
system = "x86_64-linux";
inp = [
"disko"
"impermanence"
"sops-nix"
];
};
};
nixosConfigurations.liam = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./liam ];
specialArgs = { inherit inputs; };
};
nixOnDroidConfigurations.default =
let
common = mkCommon { system = arm; vacuModuleType = "nix-on-droid"; };
in
nix-on-droid.lib.nixOnDroidConfiguration {
modules = [
./common
./hosts/nix-on-droid
];
extraSpecialArgs = common.specialArgs;
inherit (common) pkgs;
};
nixosConfigurations.lp0 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./lp0 ];
specialArgs = { inherit inputs; };
};
nixosConfigurations.shel-installer = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./installer.nix ];
specialArgs = { inherit inputs; };
};
checks = nixpkgs.lib.genAttrs [ x86 ] (
system:
let
common = mkCommon { inherit system; vacuModuleType = "nixos"; };
inherit (common) pkgs;
plain = mkPlain { inherit system; };
commonTestModule = {
hostPkgs = pkgs;
_module.args.inputs = { inherit (allInputs) self; };
node.pkgs = pkgs;
node.pkgsReadOnly = true;
node.specialArgs = (lib.removeAttrs common.specialArgs [ "inputs" ]) // { selfPackages = self.packages.${system}; };
};
mkTest =
name:
nixpkgs.lib.nixos.runTest {
imports = [
commonTestModule
./tests/${name}
{ node.specialArgs.inputs = self.nixosConfigurations.${name}._module.specialArgs.inputs; }
];
};
checksFromConfig = plain.config.vacu.checks;
in
assert !(checksFromConfig ? liam) && !(checksFromConfig ? trip);
checksFromConfig
// {
liam = mkTest "liam";
triple-dezert = mkTest "triple-dezert";
}
);
nixosConfigurations.devver = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./devver ];
specialArgs = { inherit inputs; };
};
buildList =
let
toplevelOf = name: self.nixosConfigurations.${name}.config.system.build.toplevel;
deterministicCerts = import ./deterministic-certs.nix { nixpkgs = mkPkgs x86; };
renamedAarchPackages = lib.mapAttrs' (
name: value: lib.nameValuePair (name + "-aarch64") value
) self.packages.aarch64-linux;
packages = self.packages.x86_64-linux // renamedAarchPackages;
pxe-build = self.nixosConfigurations.shel-installer-pxe.config.system.build;
in
{
fw = toplevelOf "fw";
triple-dezert = toplevelOf "triple-dezert";
compute-deck = toplevelOf "compute-deck";
liam = toplevelOf "liam";
lp0 = toplevelOf "lp0";
legtop = toplevelOf "legtop";
mmm = toplevelOf "mmm";
shel-installer-iso = toplevelOf "shel-installer-iso";
shel-installer-pxe = toplevelOf "shel-installer-pxe";
prophecy = toplevelOf "prophecy";
iso = self.nixosConfigurations.shel-installer-iso.config.system.build.isoImage;
pxe-toplevel = toplevelOf "shel-installer-pxe";
pxe-kernel = pxe-build.kernel;
pxe-initrd = pxe-build.netbootRamdisk;
check-triple-dezert = self.checks.x86_64-linux.triple-dezert.driver;
check-liam = self.checks.x86_64-linux.liam.driver;
liam-sieve = self.nixosConfigurations.liam.config.vacu.liam-sieve-script;
nixosConfigurations.fw = inputs.nixpkgs2405.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./fw ];
specialArgs = { inherit inputs; };
};
nix-on-droid = self.nixOnDroidConfigurations.default.activationPackage;
nixOnDroidConfigurations.default = nix-on-droid.lib.nixOnDroidConfiguration {
modules = [ ./nix-on-droid.nix ];
extraSpecialArgs = { inherit inputs; };
};
nod-bootstrap-x86_64 = allInputs.nix-on-droid.packages.x86_64-linux.bootstrapZip-x86_64;
nod-bootstrap-aarch64 = allInputs.nix-on-droid.packages.x86_64-linux.bootstrapZip-aarch64;
diskoConfigurations.compute-deck = import ./compute-deck/partitioning.nix;
dc-priv = deterministicCerts.privKeyFile "test";
dc-cert = deterministicCerts.selfSigned "test" { };
inherit (allInputs.nixos-apple-silicon-unstable.packages.aarch64-linux)
m1n1
uboot-asahi
installer-bootstrap
;
installer-bootstrap-cross =
allInputs.nixos-apple-silicon-unstable.packages.x86_64-linux.installer-bootstrap;
}
// packages;
qb = self.buildList // {
trip = self.buildList.triple-dezert;
cd = self.buildList.compute-deck;
lt = self.buildList.legtop;
prop = self.buildList.prophecy;
check-trip = self.buildList.check-triple-dezert;
nod = self.buildList.nix-on-droid;
ak = self.buildList.authorizedKeys;
my-sops = self.buildList.wrappedSops;
};
brokenBuilds = [
"sm64coopdx-aarch64"
"installer-bootstrap"
];
impureBuilds = [
"nix-on-droid"
"nod"
"nod-bootstrap-x86_64"
"nod-bootstrap-aarch64"
];
archival = import ./archive.nix { inherit self pkgs lib; };
}
// (allInputs.flake-utils.lib.eachDefaultSystem (
system:
checks = nixpkgs.lib.genAttrs [ "x86_64-linux" ] (system:
let
mkNixvim =
{ unstable, minimal }:
let
common = mkCommon { inherit unstable; vacuModuleType = "nixvim"; };
nixvim-input = if unstable then allInputs.nixvim-unstable else allInputs.nixvim;
in
nixvim-input.legacyPackages.${system}.makeNixvimWithModule {
module = {
imports = [ ./nixvim ];
};
extraSpecialArgs = common.specialArgs // { inherit minimal; };
};
common = mkCommon { unstable = true; vacuModuleType = "plain"; };
inherit (common) pkgs pkgsStable pkgsUnstable;
plain = mkPlain { unstable = true; };
treefmtEval = allInputs.treefmt-nix.lib.evalModule pkgsUnstable ./treefmt.nix;
formatter = treefmtEval.config.build.wrapper;
vacuPackagePaths = import ./packages;
vacuPackages = builtins.intersectAttrs vacuPackagePaths pkgsStable;
pkgs = nixpkgs.legacyPackages.${system};
config = {
node.pkgs = pkgs;
node.pkgsReadOnly = false;
node.specialArgs.selfPackages = self.packages.${system};
node.specialArgs.inputs = inputs;
};
in
{
inherit formatter;
inherit (common) vaculib;
apps.sops = {
type = "app";
program = lib.getExe self.packages.${system}.wrappedSops;
liam = nixpkgs.lib.nixos.runTest {
hostPkgs = pkgs;
imports = [ config ./tests/liam.nix ];
};
vacuConfig = plain.config;
inherit vacuPackages;
legacyPackages = {
unstable = pkgsUnstable;
stable = pkgsStable;
nixpkgs-update = { ... }@args: import "${allInputs.nixpkgs}/maintainers/scripts/update.nix" ({ include-overlays = [ (import ./overlays/newPackages.nix) ]; } // args);
trip = nixpkgs.lib.nixos.runTest {
hostPkgs = pkgs;
imports = [ config ./tests/triple-dezert.nix ];
};
packages = rec {
archive = pkgsStable.callPackage ./scripts/archive { };
authorizedKeys = pkgsStable.writeText "authorizedKeys" (
lib.concatStringsSep "\n" (
lib.mapAttrsToList (k: v: "${v} ${k}") plain.config.vacu.ssh.authorizedKeys
)
);
dns = import ./scripts/dns {
inherit pkgs lib;
inputs = allInputs;
inherit (plain) config;
};
inherit formatter;
generated = pkgsStable.linkFarm "generated" {
nixpkgs = "${allInputs.nixpkgs}";
"liam-test/hints.py" = pkgs.writeText "hints.py" (
import ./typesForTest.nix {
name = "liam";
inherit (pkgsStable) lib;
inherit self;
inherit (allInputs) nixpkgs;
}
);
"dns/python-env" = builtins.dirOf (builtins.dirOf dns.interpreter);
"mailtest/python-env" = builtins.dirOf (
builtins.dirOf self.checks.x86_64-linux.liam.nodes.checker.vacu.mailtest.smtp.interpreter
);
};
host-pxe-installer = pkgs.callPackage ./host-pxe-installer.nix {
nixosInstaller = self.nixosConfigurations.shel-installer-pxe;
};
liam-sieve-script = self.nixosConfigurations.liam.config.vacu.liam-sieve-script;
nixvim = mkNixvim {
unstable = false;
minimal = false;
};
nixvim-unstable = mkNixvim {
unstable = true;
minimal = false;
};
nixvim-minimal = mkNixvim {
unstable = false;
minimal = true;
};
nixvim-unstable-minimal = mkNixvim {
unstable = true;
minimal = true;
};
# optionsDocNixOnDroid = (pkgs.nixosOptionsDoc {
# inherit (self.nixOnDroidConfigurations.default) options;
# }).optionsCommonMark;
openterface-qt-eudev = vacuPackages.openterface-qt.override { useSystemd = false; };
openterface-qt-systemd = vacuPackages.openterface-qt.override { useSystemd = true; };
sopsConfig = plain.config.vacu.sopsConfigFile;
sourceTree = plain.config.vacu.sourceTree;
units = plain.config.vacu.units.finalPackage;
update-git-keys = pkgsStable.callPackage ./scripts/update-git-keys.nix { inherit (plain) config; inputs = allInputs; };
vnopnCA = pkgsStable.writeText "vnopnCA.cert" plain.config.vacu.vnopnCA;
wrappedSops = plain.config.vacu.wrappedSops;
} // vacuPackages;
# trip_haproxy_config = let
# hacfg = self.nixosConfigurations.triple-dezert.config.containers.frontproxy.config.services.haproxy;
# in pkgs.stdenvNoCC.mkDerivation {
# name = "trip-haproxy-config-check";
# script = ''
# mkdir -p certs/shelvacu.com/
# touch certs/shelvacu.com/full.pem
# ${hacfg.package}/bin/haproxy \
# -f ${pkgs.writeText "haproxy-config" hacfg.config} \
# -c \
# -dW \
# -dD \
# -C $PWD
# '';
# };
}
));
);
nixosModules.common = import ./common-config.nix;
packages.x86_64-linux.digitalOceanImage = import ./generic-digitalocean-nixos.nix { inherit inputs; };
};
}

94
fw/default.nix Normal file
View File

@@ -0,0 +1,94 @@
{ config, inputs, pkgs, lib, ... }: {
imports = [
../common-nixos-config.nix
];
system.nixos.tags = [ "host-${config.networking.hostName}" ];
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
networking.networkmanager.enable = true;
vacu.packages.bitwarden-desktop.enable = true;
vacu.packages.nheko.enable = true;
vacu.packages.librewolf.enable = true;
vacu.packages.brave.enable = true;
vacu.packages.thunderbird.enable = true;
vacu.packages.wl-clipboard.enable = true;
vacu.packages.nextcloud-client.enable = true;
vacu.packages.signal-desktop.enable = true;
vacu.packages.fw-ectool.enable = true;
vacu.packages.framework-tool.enable = true;
vacu.packages.iio-sensor-proxy.enable = true;
vacu.packages.power-profiles-daemon.enable = true;
vacu.packages.acpi.enable = true;
services.xserver.enable = true;
services.displayManager.sddm.enable = true;
services.desktopManager.plasma6.enable = true;
boot.loader.grub.enable = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.efiInstallAsRemovable = true;
boot.loader.grub.memtest86.enable = true;
boot.loader.grub.mirroredBoots = [
{
devices = [ "nodev" ];
path = "/boot0";
}
{
devices = [ "nodev" ];
path = "/boot1";
}
];
networking.hostName = "fw"; # Define your hostname.
networking.hostId = "c6e309d5";
boot.zfs.extraPools = [ "fw" ];
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
systemd.services.zfs-mount.enable = false;
services.openssh.enable = true;
system.stateVersion = "23.11"; # Did you read the comment?
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "usbhid" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "fw/root";
fsType = "zfs";
};
fileSystems."/boot0" =
{ device = "/dev/disk/by-label/BOOT0";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
fileSystems."/boot1" =
{ device = "/dev/disk/by-label/BOOT1";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
hardware.cpu.amd.updateMicrocode = true;
hardware.enableAllFirmware = true;
hardware.opengl = {
driSupport = true;
driSupport32Bit = true;
};
programs.nix-ld.enable = true;
programs.steam = {
enable = true;
remotePlay.openFirewall = true;
};
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
services.blueman.enable = true;
}

View File

@@ -0,0 +1,10 @@
{ inputs, system ? "x86_64-linux" }:
let
pkgs = inputs.nixpkgs.legacyPackages.${system};
config = { config, ... }: {
imports = [ "${inputs.nixpkgs}/nixos/modules/virtualisation/digital-ocean-image.nix" ];
system.stateVersion = config.system.nixos.release;
};
in
(pkgs.nixos config).digitalOceanImage

View File

@@ -1,7 +0,0 @@
{ ... }:
{
imports = [ ../common/home.nix ];
home.stateVersion = "24.05";
home.homeDirectory = "/data/data/com.termux.nix/files/home";
home.username = "nix-on-droid";
}

View File

@@ -1,7 +0,0 @@
{ ... }:
{
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
services.blueman.enable = true;
}

View File

@@ -1,74 +0,0 @@
{ pkgs, inputs, ... }:
{
imports = [
inputs.jovian.nixosModules.jovian
# inputs.disko.nixosModules.default
inputs.home-manager.nixosModules.default
./hardware.nix
./home.nix
./bluetooth.nix
./partitioning.nix
./padtype.nix
];
boot.loader = {
systemd-boot.enable = false;
efi = {
efiSysMountPoint = "/boot/EFI";
canTouchEfiVariables = false;
};
grub = {
efiSupport = true;
device = "nodev";
efiInstallAsRemovable = true;
};
};
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
vacu.hostName = "compute-deck";
vacu.shortHostName = "cd";
vacu.shell.color = "blue";
vacu.systemKind = "desktop";
networking.hostId = "e595d9b0";
boot.supportedFilesystems = [ "zfs" ];
boot.zfs.forceImportRoot = false;
system.stateVersion = "23.11";
jovian.devices.steamdeck.enable = true;
networking.networkmanager.enable = true;
services.xserver.enable = true;
services.displayManager.sddm.enable = true;
services.desktopManager.plasma6.enable = true;
services.openssh.enable = true;
vacu.packages = ''
jupiter-hw-support
steamdeck-firmware
steamdeck-bios-fwupd
'';
# boot.kernelPatches = [
# {
# name = "gadget";
# patch = null;
# extraStructuredConfig = with lib.kernel; {
# USB_ETH=module;
# USB_GADGET=yes;
# USB_LIBCOMPOSITE=yes;
# USB_CONFIGFS=yes;
# USB_DWC3=module;
# USB_DWC3_PCI=module;
# USB_DWC3_DUAL_ROLE=yes;
# USB_DWC3_HOST=no;
# USB_DWC3_GADGET=no;
# USB_ROLE_SWITCH=yes;
# };
# }
# ];
}

View File

@@ -1,72 +0,0 @@
{
config,
lib,
modulesPath,
...
}:
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot.initrd.availableKernelModules = [
"nvme"
"xhci_pci"
"usbhid"
"sdhci_pci"
"dwc3_pci"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
/*
fileSystems."/" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=root" ];
};
fileSystems."/home" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=home" ];
};
fileSystems."/nix" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=nix" ];
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/63f25199-ee0b-4991-8861-c3ba3b464ef2";
fsType = "btrfs";
options = [ "subvol=boot" ];
};
*/
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/2aad8cab-7b97-47de-8608-fe9f12e211a4";
fsType = "ext4";
options = [ "nofail" ];
};
fileSystems."/boot/EFI" = {
device = "/dev/disk/by-uuid/C268-79C8";
fsType = "vfat";
options = [ "nofail" ];
};
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.wlo1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@@ -1,5 +0,0 @@
{ pkgs, ... }:
{
vacu.packages = pkgs.androidStudioPackages.stable.all;
users.users.shelvacu.extraGroups = [ "kvm" ];
}

View File

@@ -1,76 +0,0 @@
# everything to interact with my apex flex, pcsc stuff, fido2 stuff, etc
{
pkgs,
lib,
config,
...
}:
let
# to match package used in config.services.pcscd, unfortunately not exposed like usual
pcsclite-pkg = if config.security.polkit.enable then pkgs.pcscliteWithPolkit else pkgs.pcsclite;
in
{
# apparently this is already enabled??
# nixpkgs.overlays = [ ( final: prev: {
# libfido2 = prev.libfido2.override { withPcsclite = true; };
# } ) ];
vacu.packages = lib.mkMerge [
''
libfido2
pcsc-tools
scmccid
opensc
pcsclite
''
{ pcsclite.package = pcsclite-pkg; }
];
services.pcscd.enable = true;
# conflicts with pcscd, see https://stackoverflow.com/questions/55144458/unable-to-claim-usb-interface-device-or-resource-busy-stuck
boot.blacklistedKernelModules = [
"pn533_usb"
"pn533"
"nfc"
];
# bunch of stuff from https://wiki.nixos.org/wiki/Web_eID
# Tell p11-kit to load/proxy opensc-pkcs11.so, providing all available slots
# (PIN1 for authentication/decryption, PIN2 for signing).
# environment.etc."pkcs11/modules/opensc-pkcs11".text = ''
# module: ${pkgs.opensc}/lib/opensc-pkcs11.so
# '';
# environment.etc."opensc.conf".text = ''
# app default {
# reader_driver pcsc {
# enable_pinpad = false;
# }
# }
# '';
environment.systemPackages = [
# Wrapper script to tell to Chrome/Chromium to use p11-kit-proxy to load
# security devices, so they can be used for TLS client auth.
# Each user needs to run this themselves, it does not work on a system level
# due to a bug in Chromium:
#
# https://bugs.chromium.org/p/chromium/issues/detail?id=16387
(pkgs.writeShellScriptBin "setup-browser-eid" ''
NSSDB="''${HOME}/.pki/nssdb"
mkdir -p ''${NSSDB}
${pkgs.nssTools}/bin/modutil -force -dbdir sql:$NSSDB -add p11-kit-proxy \
-libfile ${pkgs.p11-kit}/lib/p11-kit-proxy.so
'')
];
# programs.firefox.enable = true;
# programs.firefox.policies.SecurityDevices.p11-kit-proxy = "${pkgs.p11-kit}/lib/p11-kit-proxy.so";
# trying CTAP-bridge
services.udev.extraRules = ''
KERNEL=="hidg[0-9]", SUBSYSTEM=="hidg", SYMLINK+="ctaphid", MODE="0666", TAG+="uaccess"
KERNEL=="ccidg[0-9]", SUBSYSTEM=="ccidg", SYMLINK+="ccidsc", MODE="0666", TAG+="uaccess"
'';
}

View File

@@ -1,158 +0,0 @@
{ inputs, pkgs, lib, vacuModules, ... }:
{
imports = [
inputs.nixos-hardware.nixosModules.framework-16-7040-amd
"${inputs.self}/tf2"
vacuModules.sops
./apex.nix
./android.nix
./thunderbolt.nix
./fwupd.nix
./zfs.nix
./virtualbox.nix
./radicle.nix
./tpm-fido.nix
./podman.nix
./waydroid.nix
];
boot.supportedFilesystems = [ "bcachefs" ];
vacu.hostName = "fw";
vacu.shell.color = "magenta";
vacu.verifySystem.expectedMac = "e8:65:38:52:5c:59";
vacu.systemKind = "laptop";
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
# standard kernel: waydroid works
# lqx kernel: games run with less stutters
boot.kernelPackages = pkgs.linuxKernel.packages.linux_lqx;
# boot.kernelPackages = pkgs.linuxKernel.packages.linux_6_15;
networking.networkmanager.enable = true;
services.irqbalance.enable = true;
# boot.kernelParams = [ "nvme.noacpi=1" ]; # DONT DO IT: breaks shit even more
services.fprintd.enable = false; # kinda broken
users.users.shelvacu.extraGroups = [ "dialout" ];
programs.steam.extraCompatPackages = [ pkgs.proton-ge-bin ];
vacu.packages = ''
android-studio
framework-tool
fw-ectool
headsetcontrol
openterface-qt
intiface-central
osu-lazer
mumble
obs-studio
'';
services.power-profiles-daemon.enable = true;
networking.firewall.enable = false;
services.xserver.enable = true;
services.displayManager.sddm.enable = true;
services.desktopManager.plasma6.enable = true;
services.printing.enable = true;
programs.system-config-printer.enable = true;
boot.loader.grub.enable = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.efiInstallAsRemovable = true;
boot.loader.grub.memtest86.enable = true;
boot.loader.grub.mirroredBoots = [
{
devices = [ "nodev" ];
path = "/boot0";
}
{
devices = [ "nodev" ];
path = "/boot1";
}
];
networking.hostId = "c6e309d5";
services.openssh.enable = true;
system.stateVersion = "23.11"; # Did you read the comment?
boot.initrd.availableKernelModules = [
"nvme"
"xhci_pci"
"thunderbolt"
"usb_storage"
"usbhid"
"sd_mod"
];
#boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
#boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "fw/root";
fsType = "zfs";
};
fileSystems."/cache" = {
device = "fw/cache";
fsType = "zfs";
};
fileSystems."/home/shelvacu/cache" = {
device = "/cache/shelvacu";
options = [ "bind" ];
};
fileSystems."/boot0" = {
device = "/dev/disk/by-label/BOOT0";
fsType = "vfat";
options = [
"fmask=0022"
"dmask=0022"
"nofail"
];
};
fileSystems."/boot1" = {
device = "/dev/disk/by-label/BOOT1";
fsType = "vfat";
options = [
"fmask=0022"
"dmask=0022"
"nofail"
];
};
hardware.cpu.amd.updateMicrocode = true;
hardware.enableAllFirmware = true;
hardware.graphics = {
extraPackages = [
pkgs.rocmPackages.clr.icd
pkgs.amdvlk
];
};
programs.nix-ld.enable = true;
programs.steam = {
enable = true;
remotePlay.openFirewall = true;
};
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
services.blueman.enable = true;
services.postgresql.enable = true; # for development
vacu.programs.thunderbird.enable = true;
}

View File

@@ -1,8 +0,0 @@
{ config, lib, ... }:
{
vacu.packages = [ config.services.fwupd.package ];
services.fwupd.enable = true;
#fwupd gets confused by the multiple EFI partitions, I think I just have to pick one
#update: it didn't work, I dunno why. Leaving this here anyways
services.fwupd.daemonSettings.EspLocation = lib.mkForce "/boot0";
}

View File

@@ -1,13 +0,0 @@
{ ... }:
{
virtualisation.containers.enable = true;
virtualisation.podman = {
enable = true;
# Create a `docker` alias for podman, to use it as a drop-in replacement
dockerCompat = true;
# Required for containers under podman-compose to be able to talk to each other.
defaultNetwork.settings.dns_enabled = true;
};
users.users.shelvacu.extraGroups = [ "podman" ];
}

View File

@@ -1,20 +0,0 @@
{ config, ... }:
{
sops.secrets.radicle-key = {
sopsFile = "${config.vacu.sops.secretsPath}/radicle-private.key";
format = "binary"; # its actually an openssh private key which is kinda plaintext, but there is no plaintext option and treating it as opaque binary works fine
};
services.radicle = {
enable = true;
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC2HqXfjT4vPEqqM5Pty7EuswzeO80IgG6MtCvDAqOkD";
privateKeyFile = config.sops.secrets.radicle-key.path;
settings = {
node.alias = "shelvacu-fw";
seedingPolicy.default = "block";
};
};
vacu.packages.radicle-node = {
enable = true;
package = config.services.radicle.package;
};
}

View File

@@ -1,13 +0,0 @@
{ lib, config, ... }:
{
services.hardware.bolt.enable = true;
vacu.packages = lib.mkMerge [
''
thunderbolt
bolt
kdePackages.plasma-thunderbolt
''
{ bolt.package = config.services.hardware.bolt.package; }
];
}

View File

@@ -1,14 +0,0 @@
{ config, ... }:
{
vacu.packages = [ "tpm-fido" ];
users.groups.uhid = { };
users.users.shelvacu.extraGroups = [
config.security.tpm2.tssGroup
config.users.groups.uhid.name
];
security.tpm2.enable = true;
security.tpm2.applyUdevRules = true;
services.udev.extraRules = ''
KERNEL=="uhid", SUBSYSTEM=="misc", GROUP="${config.users.groups.uhid.name}", MODE="0660"
'';
}

View File

@@ -1,8 +0,0 @@
{ ... }:
{
virtualisation.virtualbox.host = {
enable = true;
enableExtensionPack = true;
};
users.extraGroups.vboxusers.members = [ "shelvacu" ];
}

View File

@@ -1,5 +0,0 @@
{ ... }:
{
boot.kernelParams = [ "psi=1" ];
virtualisation.waydroid.enable = true;
}

View File

@@ -1,7 +0,0 @@
{ pkgs, ... }:
{
boot.zfs.extraPools = [ "fw" ];
systemd.services.zfs-mount.enable = false;
# see also fileSystems."/"
}

View File

@@ -1,30 +0,0 @@
{ config, lib, ... }:
{
# this is an installer image, created anew every time. There's no state we need to worry about messing up
system.stateVersion = config.system.nixos.release;
services.openssh.settings.PermitRootLogin = lib.mkForce "yes";
vacu.hostName = "vacuInstaller";
vacu.shell.color = "red";
vacu.systemKind = "minimal";
vacu.packages = ''
acpi
iio-sensor-proxy
aircrack-ng
# bitwarden-cli # 800MB closure size!
borgbackup
dmidecode
home-manager
man
mercurial
nix-index
nix-inspect
nix-search-cli
nmap
nvme-cli
rclone
smartmontools
tcpdump
termscp
'';
}

View File

@@ -1,8 +0,0 @@
{ modulesPath, ... }:
{
imports = [
./common
"${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
];
isoImage.isoBaseName = "nixos-shel-installer";
}

View File

@@ -1,7 +0,0 @@
{ modulesPath, ... }:
{
imports = [
./common
"${modulesPath}/installer/netboot/netboot-minimal.nix"
];
}

View File

@@ -1,7 +0,0 @@
{ ... }:
{
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
# services.blueman.enable = true;
}

View File

@@ -1,48 +0,0 @@
{ pkgs, inputs, ... }:
{
imports = [
../common/nixos.nix
inputs.nixos-hardware.nixosModules.gpd-micropc
./hardware.nix
./bluetooth.nix
];
vacu.hostName = "legtop";
vacu.shortHostName = "lt";
vacu.shell.color = "blue";
vacu.verifySystem.expectedMac = "30:9e:90:33:01:07";
vacu.systemKind = "laptop";
system.stateVersion = "24.05";
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
services.power-profiles-daemon.enable = true;
networking.networkmanager.enable = true;
services.openssh.enable = true;
services.xserver.enable = true;
services.displayManager.sddm.enable = true;
services.displayManager.sddm.wayland.enable = true;
services.desktopManager.plasma6.enable = true;
boot.loader.grub.enable = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.device = "nodev";
boot.loader.efi.canTouchEfiVariables = true;
hardware.cpu.intel.updateMicrocode = true;
hardware.enableAllFirmware = true;
services.fwupd.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
programs.steam.enable = true;
boot.kernelPackages = pkgs.linuxPackages_lqx;
}

View File

@@ -1,33 +0,0 @@
{ ... }:
{
boot.initrd.availableKernelModules = [
"ahci"
"xhci_pci"
"usbhid"
"usb_storage"
"sd_mod"
"sdhci_pci"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-uuid/e3aebf24-be76-4064-a9f5-3930c8cd1382";
fsType = "ext4";
};
boot.initrd.luks.devices."root".device = "/dev/disk/by-uuid/7fd2ca2d-7faf-4d40-8cde-ce531fa679b5";
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/4C47-D9A3";
fsType = "vfat";
options = [
"fmask=0022"
"dmask=0022"
"nofail"
];
};
nixpkgs.hostPlatform = "x86_64-linux";
hardware.cpu.intel.updateMicrocode = true;
}

View File

@@ -1,156 +0,0 @@
{
config,
vaculib,
pkgs,
lib,
...
}:
let
inherit (lib) mkOption;
cfg = config.vacu.liam.backup;
commonServiceConfig = {
Type = "oneshot";
StateDirectory = "auto-borg";
CacheDirectory = "auto-borg";
ReadOnlyPaths = cfg.paths ++ [ cfg.keyPath ];
User = cfg.user;
Group = cfg.user;
LockPersonality = true;
MemoryDenyWriteExecute = true;
PrivateDevices = true;
# PrivateUsers = true;
ProcSubset = "pid";
PrivateTmp = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
];
UMask = "0077";
AmbientCapabilities = [ "CAP_DAC_READ_SEARCH" ];
CapabilityBoundingSet = [ "CAP_DAC_READ_SEARCH" ];
};
in
{
options.vacu.liam.backup = {
user = mkOption { default = "autoborger"; };
rsyncUser = mkOption { default = "fm2382"; };
rsyncHost = mkOption {
default = "${cfg.rsyncUser}.rsync.net";
defaultText = "(output)";
};
repo = mkOption {
default = "${cfg.rsyncUser}@${cfg.rsyncHost}:borg-repos/liam-backup";
defaultText = "(output)";
};
package = mkOption {
default = pkgs.borgbackup;
defaultText = "pkgs.borgbackup";
};
cmd = mkOption {
default = lib.getExe cfg.package;
defaultText = "lib.getExe cfg.package";
};
paths = mkOption {
default = [
"/var/lib/mail"
"/var/lib/dovecot"
"/var/log"
];
};
keyPath = mkOption {
default = config.sops.secrets.liam-borg-key.path;
defaultText = "TODO";
};
};
config = {
vacu.assertions = lib.singleton {
assertion =
(lib.versionAtLeast cfg.package.version "1.4.0")
&& !(lib.versionAtLeast cfg.package.version "1.5.0");
message = "Only for version 1.4.x";
fatal = true;
};
sops.secrets.liam-borg-key = {
owner = cfg.user;
};
# systemd.tmpfiles.settings."10-auto-borg" = lib.genAttrs cfg.paths (_:
# {
# # A+ = append to ACLs recursively
# "A+" = {
# argument = "u:${cfg.user}:r-x";
# };
# }
# );
users.users.${cfg.user} = {
isSystemUser = true;
group = cfg.user;
home = "/var/lib/auto-borg";
};
users.groups.${cfg.user} = { };
systemd.services.auto-borg-gen-key = {
script = ''
set -euo pipefail
${lib.optionalString config.vacu.underTest "${pkgs.openssh}/bin/ssh -oBatchMode=yes -oStrictHostKeyChecking=accept-new ${cfg.rsyncHost} || true"}
${pkgs.openssh}/bin/ssh-keygen -t ed25519 -f "$STATE_DIRECTORY"/id_ed25519 -N ""
'';
serviceConfig = commonServiceConfig;
};
systemd.services.auto-borg = {
script = ''
set -euo pipefail
# makes a date like 2025-04-15_21-24-29_UTC
dashed_date="$(date -u '+%F_%H-%M-%S_%Z')"
archive_name="liam-auto-backup--$dashed_date"
export BORG_PASSPHRASE="$(cat ${lib.escapeShellArg cfg.keyPath})"
export BORG_REMOTE_PATH="borg14"
export BORG_RSH="ssh -i $STATE_DIRECTORY/id_ed25519"
export BORG_REPO=${lib.escapeShellArg cfg.repo}
export BORG_CACHE_DIR="$CACHE_DIRECTORY/borg"
export BORG_CONFIG_DIR="$STATE_DIRECTORY/borg"
cmd=(
${lib.escapeShellArg cfg.cmd}
create
--show-rc
--verbose
--show-version
--stats
--atime
"::$archive_name"
${lib.escapeShellArgs cfg.paths}
)
"''${cmd[@]}"
'';
serviceConfig = commonServiceConfig;
};
systemd.timers.auto-borg = {
enable = !config.vacu.underTest;
wantedBy = [ "timers.target" ];
# run every day at a random time between 3am and 4am, los angeles time
timerConfig = {
OnCalendar = "*-*-* 03:00:00 America/Los_Angeles";
RandomizedDelaySec = 3600;
};
};
};
}

View File

@@ -1,74 +0,0 @@
{
modulesPath,
config,
vaculib,
...
}:
let
inherit (vaculib) mkOutOption;
in
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
(modulesPath + "/virtualisation/digital-ocean-config.nix")
./nginx.nix
./sops.nix
./dovecot.nix
./mail.nix
./dkim.nix
./sieve.nix
./network.nix
./backup.nix
];
options = {
vacu.liam = {
shel_domains = mkOutOption [
"shelvacu.com"
"dis8.net"
"mail.dis8.net"
"jean-luc.org"
"in.jean-luc.org"
"vacu.store"
"shelvacu.miras.pet"
"chat.for.miras.pet"
"sv.mt"
];
julie_domains = mkOutOption [
"violingifts.com"
"theviolincase.com"
"shop.theviolincase.com"
];
domains = mkOutOption (config.vacu.liam.shel_domains ++ config.vacu.liam.julie_domains);
relayhosts = {
allDomains = (mkOutOption "[outbound.mailhop.org]:587") // {
readOnly = false;
};
shelvacuAlt = (mkOutOption "[relay.dynu.com]:587") // {
readOnly = false;
};
};
reservedIpLocal = mkOutOption "10.46.0.7";
};
};
config = {
vacu.hostName = "liam";
vacu.shell.color = "cyan";
networking.domain = "dis8.net";
vacu.systemKind = "minimal";
hardware.enableAllFirmware = false;
hardware.enableRedistributableFirmware = false;
# networking.interfaces."ens3".useDHCP = false;
services.openssh.enable = true;
virtualisation.digitalOcean.setSshKeys = false;
users.users.root.openssh.authorizedKeys.keys =
config.users.users.shelvacu.openssh.authorizedKeys.keys;
system.stateVersion = "23.11";
};
}

View File

@@ -1,208 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (config.vacu.liam)
shel_domains
julie_domains
domains
relayhosts
;
mapLines = f: lis: lib.concatStringsSep "\n" (map f lis);
debug = false;
fqdn = config.networking.fqdn;
relayable_domains = [
"shelvacu.com"
"vacu.store"
"chat.for.miras.pet"
];
dovecot_transport = "lmtp:unix:private/dovecot-lmtp";
reject_spam_sources = [
"reject-spam-test@example.com"
"buyerservice@made-in-china.com"
"upgrade-plans@asuswebstorage.com"
"info@rfidlabel.com"
"made-in-china.com"
"*.made-in-china.com"
"hotels.com"
"*.hotels.com"
];
banned_ips = [
"45.192.103.243/32"
"165.154.207.0/24"
"165.154.226.0/24"
"210.242.134.0/26"
"137.220.198.0/24"
"122.96.0.0/15"
];
# must be bigger than gmail's 25MB "attachment limit" which after base64 encoding (x 1.33) is ~33MB
mailSizeLimit = 35 * 1024 * 1024;
in
{
networking.firewall.allowedTCPPorts = [
25
465
];
vacu.acmeCertDependencies."liam.dis8.net" = [ "postfix.service" ];
services.postfix = {
enable = true;
hostname = fqdn;
# this goes into virtual_alias_maps
# "Note: for historical reasons, virtual_alias_maps apply to recipients in all domain classes, not only the virtual alias domain class."
virtual =
''
julie@shelvacu.com julie
mom@shelvacu.com julie
psv@shelvacu.com psv
''
+ (mapLines (d: "@${d} shelvacu") shel_domains)
+ "\n"
+ (mapLines (d: "@${d} julie") julie_domains);
transport = ''
shelvacu@${fqdn} ${dovecot_transport}
julie@${fqdn} ${dovecot_transport}
psv@${fqdn} ${dovecot_transport}
backup@${fqdn} ${dovecot_transport}
'';
sslKey = config.security.acme.certs."liam.dis8.net".directory + "/key.pem";
sslCert = config.security.acme.certs."liam.dis8.net".directory + "/full.pem";
postmasterAlias = "shelvacu";
rootAlias = "shelvacu";
enableSubmission = false;
enableSubmissions = true;
mapFiles.header_checks = pkgs.writeText "header-checks" (
''
/./ INFO checker headers
''
+ (mapLines (
d: "/^(from|x-original-from|return-path|mail-?from):.*@${lib.escape [ "." ] d}\\s*>?\\s*$/ REJECT"
) domains)
);
mapFiles.sender_access = pkgs.writeText "sender-access" (
mapLines (pattern: "${pattern} REJECT spam") (domains ++ reject_spam_sources)
);
mapFiles.banned_ips = pkgs.writeText "banned-ips" (mapLines (ip: "${ip} REJECT spam") banned_ips);
# hack to get postfix to add a X-Original-To header
mapFiles.add_envelope_to = pkgs.writeText "addenvelopeto" "/(.+)/ PREPEND X-Envelope-To: $1";
# mapFiles.sender_transport = pkgs.writeText "sender-transport" "@shelvacu.com relayservice";
mapFiles.sender_transport = pkgs.writeText "sender-transport" (
mapLines (d: "@${d} relayservice") relayable_domains
);
mapFiles.sender_relay = pkgs.writeText "sender-relay" (
''
@shelvacu.com ${relayhosts.allDomains} ${relayhosts.shelvacuAlt}
''
+ (mapLines (d: "@${d} ${relayhosts.allDomains}") relayable_domains)
);
mapFiles.extra_login_maps = pkgs.writeText "extra-login-maps" (
''
robot@vacu.store vacustore
zulip-notify@chat.for.miras.pet miracult-zulip
idrac-62pn9z1@shelvacu.com idrac-62pn9z1
''
+ config.services.postfix.virtual
);
# verbatim appended to main.cf
extraConfig = ''
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
inet_protocols = ipv4
virtual_alias_domains =
${lib.concatStringsSep ",\n " domains}
message_size_limit = ${toString mailSizeLimit}
sender_dependent_default_transport_maps = hash:/etc/postfix/sender_transport
sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay
header_checks = pcre:/etc/postfix/header_checks
smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/sender_access permit
smtpd_client_restrictions = check_client_access cidr:/etc/postfix/banned_ips permit
smtpd_recipient_restrictions = check_recipient_access pcre:/etc/postfix/add_envelope_to permit
recipient_delimiter = +
#we should never use these transport methods unless thru transport map
# RFC3463:
# 5.X.X = permanent error
# X.3.X = mail system failure
# X.3.5 = System incorrectly configured
# I would've never thought there'd be a standard way to specifically say "you found an error in my config"
local_transport = error:5.3.5 how did this even happen?? (e-local)
virtual_transport = error:5.3.5 how did this even happen?? (e-virtual)
# X.7.1 = Delivery not authorized, message refused
relay_transport = error:5.7.1 relay is so very disabled
lmtp_destination_recipient_limit = 1
always_bcc = backup@${fqdn}
# not actually 1024 bits, this applies to all DHE >= 1024 bits
smtpd_tls_dh1024_param_file = ${lib.optionalString config.services.dovecot2.enableDHE config.security.dhparams.params.dovecot2.path}
# smtp_bind_address = 10.46.0.7
# inet_interfaces = all
# inet_protocols = ipv4
${lib.optionalString config.services.opendkim.enable (
assert (config.services.opendkim.socket == "local:/run/opendkim/opendkim.sock");
''
smtpd_milters = unix:/run/opendkim/opendkim.sock
non_smtpd_milters = unix:/run/opendkim/opendkim.sock
''
)}
'';
masterConfig."relayservice" = {
command = "smtp";
type = "unix";
args = [
"-o"
"smtp_sasl_auth_enable=yes"
"-o"
"smtp_sasl_security_options=noanonymous"
"-o"
"smtp_tls_security_level=secure"
"-o"
"smtp_sasl_password_maps=texthash:${config.sops.secrets.relay_creds.path}"
"-o"
"smtp_tls_wrappermode=no"
] ++ (if debug then [ "-v" ] else [ ]);
};
masterConfig.qmgr = lib.mkIf debug { args = [ "-v" ]; };
masterConfig.cleanup = lib.mkIf debug { args = [ "-v" ]; };
masterConfig.smtpd = lib.mkIf debug { args = [ "-v" ]; };
submissionsOptions = {
smtpd_tls_key_file = config.security.acme.certs."liam.dis8.net".directory + "/key.pem";
smtpd_tls_cert_file = config.security.acme.certs."liam.dis8.net".directory + "/full.pem";
smtpd_tls_security_level = "encrypt";
smtpd_sasl_auth_enable = "yes";
smtpd_tls_auth_only = "yes";
smtpd_reject_unlisted_recipient = "no";
smtpd_client_restrictions = "permit_sasl_authenticated,reject";
milter_macro_daemon_name = "ORIGINATING";
smtpd_sasl_security_options = "noanonymous";
smtpd_sasl_type = "dovecot";
smtpd_sasl_path = "private/dovecot-auth";
message_size_limit = "100000000";
smtpd_sender_login_maps = "hash:/etc/postfix/extra_login_maps";
smtpd_sender_restrictions = "reject_authenticated_sender_login_mismatch";
header_checks = "";
# mozilla intermediate config
smtpd_tls_mandatory_protocols = "!SSLv2,!SSLv3,!TLSv1,!TLSv1.1";
smtpd_tls_protocols = "!SSLv2,!SSLv3,!TLSv1,!TLSv1.1";
smtpd_tls_mandatory_ciphers = "medium";
tls_medium_cipherlist = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305";
tls_preempt_cipherlist = "no";
};
};
}

View File

@@ -1,32 +0,0 @@
{ lib, config, ... }:
let
# from `curl -fsSL http://169.254.169.254/metadata/v1.json | jq '.interfaces.public[0].anchor_ipv4'`
# {
# "ip_address": "10.46.0.7",
# "netmask": "255.255.0.0",
# "gateway": "10.46.0.1"
# }
interface_conf = {
useDHCP = true;
ipv4.addresses = [
{
address = "10.46.0.7";
prefixLength = 24;
}
];
ipv4.routes = [
{
address = "0.0.0.0";
prefixLength = 0;
via = "10.46.0.1";
options.scope = "global";
options.src = "10.46.0.7";
options.metric = "1200";
}
];
};
in
{
networking.interfaces."ens3" = lib.mkIf (!config.vacu.underTest) interface_conf;
networking.interfaces."eth0" = lib.mkIf (config.vacu.underTest) interface_conf;
}

View File

@@ -1,21 +0,0 @@
I think I can sort my email into these categories:
- A Top priority: should be a notification
- personal emails
- here is a code to login (except ms, ugh)
- B Normal priority: should be reviewed regularly, at least once every couple days
- (some) purchase receipts
- your credit card was used for <amount>
- money stuff
- patreons
- C Low priority: should be skimmed occaisionally to make sure nothing got caught that shouldn't have
- C1 good emails:
- your statement is available to view
-
- C2 spam
- D Shit-tier: never reviewed, except if I'm missing an email I was otherwise expecting
- unsolicited job offers
- anything definitely spam
- M Mailing lists
searches should generally search A,B,C but not D or M

View File

@@ -1,960 +0,0 @@
{
pkgs,
lib,
config,
vaculib,
...
}:
let
inherit (builtins)
isString
isList
length
head
all
isInt
isAttrs
isFloat
isBool
;
inherit (lib)
concatStrings
concatStringsSep
splitString
match
replaceStrings
reverseList
elemAt
mapAttrsToList
;
mapConcat = f: xs: concatStrings (map f xs);
mapConcatSep =
sep: f: xs:
concatStringsSep sep (map f xs);
mapConcatLines = f: xs: mapConcatSep "\n" f xs;
isListWhere = xs: f: (isList xs) && (all f xs);
stringOrList = val: (isString val) || ((isListWhere val isString) && (length val) > 0);
listify = val: if isList val then val else [ val ];
is_match = regex: s: (match regex s) != null;
is_not_match = regex: s: !(is_match regex s);
only_printable_ascii = s: is_match "[ -~\r\n]*" s;
has_vars = s: lib.hasInfix ("$" + "{") s;
sieve_raw_escape_string =
s:
if !only_printable_ascii s then
builtins.trace s throw "s failed only_printable_ascii check"
else
replaceStrings [ ''"'' ''\'' "\n" "\r" ] [ ''\"'' ''\\'' ''\n'' ''\r'' ] s;
sieve_encode_string =
{
allow_vars,
for_debug_comment,
with_quotes,
}:
s:
assert isString s;
assert allow_vars || for_debug_comment || (!has_vars s);
let
a = sieve_raw_escape_string s;
b = if for_debug_comment then replaceStrings [ ''*/'' ] [ ''*\/'' ] a else a;
res = if with_quotes then ''"${b}"'' else b;
in
res;
sieve_quote_string = sieve_encode_string {
allow_vars = false;
for_debug_comment = false;
with_quotes = true;
};
sieve_quote_string_with_interp = sieve_encode_string {
allow_vars = true;
for_debug_comment = false;
with_quotes = true;
};
is_valid_long_ident = is_match "[a-z_][a-z0-9_]*";
is_number_ident = is_match "[0-9]*";
is_valid_ident = s: (is_valid_long_ident s) || (is_number_ident s);
interp =
ident:
assert isString ident;
assert is_valid_ident ident;
"$" + "{${ident}}";
dest = "envelope_to";
dest_domain = "envelope_to_domain";
set_envelope = ''
#set_envelope START
if header :index 1 :matches "X-Envelope-To" "*" {
set ${sieve_quote_string dest} "''${1}";
}
if header :index 1 :matches "X-Envelope-To" "*@*" {
set ${sieve_quote_string dest_domain} "''${2}";
}
#set_envelope END
'';
envelope_is =
key:
assert stringOrList key;
''string :is "${interp dest}" ${sieve_encode key}'';
envelope_matches =
key:
assert stringOrList key;
''string :matches "${interp dest}" ${sieve_encode key}'';
envelope_domain_is = key: ''string :is "${interp dest_domain}" ${sieve_quote_string key}'';
sieve_encode_list =
xs:
assert isListWhere xs isString;
"[ ${mapConcatSep ", " sieve_encode xs} ]";
sieve_encode =
val:
if isString val then
sieve_quote_string val
else if isList val then
sieve_encode_list val
else
assert "dunno what to do with this";
null;
sieve_debug_list = xs: "[ ${mapConcat (s: (sieve_debug s) + " ") xs}]";
sieve_debug_attrs =
attrs:
let
toPairStr = name: val: "${sieve_debug name} = ${sieve_debug val}; ";
pairStrs = mapAttrsToList toPairStr attrs;
pairsStr = concatStrings pairStrs;
in
"{ ${pairsStr}}";
sieve_debug =
val:
if isString val then
sieve_encode_string {
allow_vars = true;
for_debug_comment = true;
with_quotes = true;
} val
else if (isInt val) || (isFloat val) then
toString val
else if (isBool val) then
(if val then "true" else "false")
else if isNull val then
"null"
else if isList val then
sieve_debug_list val
else if isAttrs val then
sieve_debug_attrs val
else
assert "dunno what to do with this";
null;
is_flagish =
flag_name:
let
# escape_all = map lib.escapeRegex;
# all from https://datatracker.ietf.org/doc/html/rfc9051#name-formal-syntax
# resp-specials = escape_all [ "]" ];
# DQUOTE = ''"'';
# quoted-specials = escape_all [ DQUOTE "\\" ];
# list-wildcards = escape_all [ "%" "*" ];
# CTL = something; # 0x00 thru 0x1F, and 0x7F
# SP = escape_all [ " " ];
# atom-specials = (escape_all [ "(" ")" "{" ]) ++ [ SP CTL list-wildcards quoted-specials resp-specials ];
# " " 0x20 !allowed
# "!" 0x21 ok
# "\"" 0x22 !allowed
# "#" 0x23 ok
# "$" 0x24 ok
# "%" 0x25 !allowed
# "&" 0x26 ok
# "'" 0x27 ok
# "(" 0x28 !allowed
# ")" 0x29 !allowed
# "*" 0x2a !allowed
# "+" 0x2b ok
# ...
# "Z" 0x5a ok
# "[" 0x5b !allowed
# "\\" 0x5c !allowed
# "]" 0x5d ok
# "^" 0x5e ok
# ...
# "z" 0x7a ok
# "{" 0x7b !allowed
# "|" 0x7c ok
# "}" 0x7d ok
# "~" 0x7e ok
# DEL 0x7f !allowed
# ATOM-CHAR = something; # "any CHAR except atom-specials"
ATOM-CHAR = ''[]!#$&'+-Z^-z|}~]'';
atom = "${ATOM-CHAR}+";
flag-keyword = ''\$MDNSent|\$Forwarded|\$Junk|\$NotJunk|\$Phishing|(${atom})'';
flag-extension = ''\\(${atom})'';
flag = ''\\Answered|\\Flagged|\\Deleted|\\Seen|\\Draft|(${flag-keyword})|(${flag-extension})'';
in
(isString flag_name) && ((builtins.match flag flag_name) != null);
known_flags = rec {
seen = ''\Seen'';
read = seen;
};
pure_flags_impl =
flags: conditions:
assert isListWhere flags isString;
assert isListWhere conditions isString;
assert (length flags) > 0;
assert (length conditions) > 0;
let
argAttrs = { inherit flags conditions; };
firstFlag = head flags;
combined_condition = if (length conditions) == 1 then head conditions else (allof conditions);
in
''
# pure_flags ${sieve_debug argAttrs};
removeflag ${sieve_quote_string firstFlag};
if ${combined_condition} {
${record_action "pure_flags ${concatStringsSep " " flags}"}
${concatStringsSep "\n" (map (flag: ''addflag ${sieve_quote_string flag};'') flags)}
}
# pure_flags end
'';
pure_flags =
flags: conditions:
assert stringOrList flags;
assert stringOrList conditions;
pure_flags_impl (listify flags) (listify conditions);
exists_impl =
headers:
assert isListWhere headers isString;
if headers == [ ] then
"/* exists START: called with empty array */ false /* exists END */"
else
"/* exists START */ exists ${sieve_encode_list headers} /* exists END */";
exists =
headers:
assert stringOrList headers;
exists_impl (listify headers);
header_generic =
match_kind: header_s: match_es:
assert stringOrList header_s;
assert stringOrList match_es;
''/* header_generic START */ header ${match_kind} ${sieve_encode header_s} ${sieve_encode match_es} /* header_generic END */'';
header_matches = header_generic ":matches";
header_is = header_generic ":is";
subject_generic = match_kind: match_es: header_generic match_kind "Subject" match_es;
subject_matches = subject_generic ":matches";
subject_is = subject_generic ":is";
environment_generic =
match_kind: environment_name_s: match_es:
assert stringOrList environment_name_s;
assert stringOrList match_es;
"environment ${match_kind} ${sieve_encode environment_name_s} ${sieve_encode match_es}";
environment_matches = environment_generic ":matches";
environment_is = environment_generic ":is";
from_is =
addr_list:
assert stringOrList addr_list;
''/* from_is START */ address :is :all "From" ${sieve_encode addr_list} /* from_is END */'';
from_matches =
addr_list:
assert stringOrList addr_list;
''/* from_is START */ address :matches :all "From" ${sieve_encode addr_list} /* from_is END */'';
var_is =
var_name: rhs:
assert isString var_name;
assert stringOrList rhs;
''string :is "''${${var_name}}" ${sieve_encode rhs}'';
var_is_true = var_name: var_is var_name "1";
var_is_false = var_name: not (var_is_true var_name);
has_flag =
flag_name:
assert isString flag_name;
assert is_flagish flag_name; # no spaces allowed in flag names
''hasflag :is ${sieve_encode flag_name}'';
set_with_interp =
var_name: new_val:
assert isString var_name;
assert is_valid_ident var_name;
assert isString new_val;
"set ${sieve_encode var_name} ${sieve_quote_string_with_interp new_val};";
set =
var_name: new_val:
assert isString var_name;
assert is_valid_ident var_name;
assert isString new_val;
"set ${sieve_encode var_name} ${sieve_encode new_val};";
set_bool_var =
var_name: bool_val:
assert isBool bool_val;
set var_name (if bool_val then "1" else "0");
over_test_list =
name: test_list:
assert isListWhere test_list isString;
''
${name}(
${concatStringsSep ",\n" test_list}
)
'';
anyof = over_test_list "anyof";
allof = over_test_list "allof";
not = test: "not ${test}";
record_action =
action_desc:
assert isString action_desc;
''addheader "X-Vacu-Action" ${sieve_encode action_desc};'';
fileinto =
folder:
assert isString folder;
''
${record_action "fileinto ${folder}"}
fileinto :create ${sieve_encode folder};
'';
ihave =
extension_name_s:
assert stringOrList extension_name_s;
"ihave ${sieve_encode extension_name_s}";
# email_filters = map (e: ''
# elsif ${envelope_is e} { # item of email_filters
# ${record_action "email_filters fileinto ${mk_email_folder_name e}"}
# fileinto :create ${sieve_quote_string (mk_email_folder_name e)};
# }
# '') email_folders;
# domain_filters = map (d: ''
# elsif ${envelope_domain_is d} { # item of domain_filters
# ${record_action "domain_filters fileinto ${mk_domain_folder_name d}"}
# fileinto :create ${sieve_quote_string (mk_domain_folder_name d)};
# }
# '') domain_folders;
set_from =
{
condition,
var,
default ? "-",
warn_if_unset ? false,
}@args:
''
# set_from ${sieve_debug args}
if ${condition} {
${set_with_interp var (interp "1")}
}
else {
${lib.optionalString warn_if_unset (
maybe_debug "info: Could not set ${var} from condition ${condition}, setting to default(${default})"
)}
${set var default}
}
# set_from END
'';
set_var_from_environment =
item: var:
''
# set_var_from_environment
''
+ set_from {
condition = ''environment :matches ${sieve_quote_string item} "*"'';
inherit var;
};
maybe_debug = msg: ''
if ${ihave "vnd.dovecot.debug"} {
debug_log ${sieve_quote_string_with_interp msg};
}
'';
# trimmed down from https://pages.ebay.com/securitycenter/security_researchers_eligible_domains.html
ebay_domains = vaculib.listOfLines { } ''
ebay.com
ebay.co.uk
ebay.com.au
ebay.de
ebay.ca
ebay.fr
ebay.it
ebay.es
ebay.at
ebay.ch
ebay.com.hk
ebay.com.sg
ebay.com.my
ebay.in
ebay.ph
ebay.ie
ebay.pl
ebay.be
ebay.nl
ebay.cn
ebay.com.tw
ebay.co.jp
ebaythailand.co.th
'';
sieve_text = ''
require [
"fileinto",
"mailbox",
"imap4flags",
"editheader",
"environment",
"variables",
"date",
"index",
"ihave"
];
if ${
allof [
(ihave "imapsieve")
(environment_matches "imap.user" "*")
(environment_matches "location" "MS")
(environment_matches "phase" "post")
]
} {
${set_bool_var "in_imap" true}
} else {
${set_bool_var "in_imap" false}
}
if ${var_is_true "in_imap"} {
if ${
not (allof [
(environment_is "imap.cause" [
"APPEND"
"COPY"
""
])
(environment_is "imap.mailbox" [
"MagicRefilter"
""
])
])
} {
${maybe_debug "NOT doing anything cuz imap.cause and/or imap.mailbox isn't right"}
stop;
}
}
${set_envelope}
${set_var_from_environment "location" "env_location"}
${set_var_from_environment "phase" "env_phase"}
${set_var_from_environment "imap.user" "env_imap_user"}
${set_var_from_environment "imap.email" "env_imap_email"}
${set_var_from_environment "imap.cause" "env_imap_cause"}
${set_var_from_environment "imap.mailbox" "env_imap_mailbox"}
${set_var_from_environment "imap.changedflags" "env_imap_changedflags"}
${set_from {
condition = ''currentdate :matches "iso8601" "*"'';
var = "datetime";
}}
${set_with_interp "sieved_message" ''at ''${datetime} by ${config.vacu.versionId} loc ''${env_location} phase ''${env_phase} user ''${env_imap_user} email ''${env_imap_email} cause ''${env_imap_cause} mailbox ''${env_imap_mailbox} changedflags ''${env_imap_changedflags} envelope ''${dest}''}
${maybe_debug ''X-Vacu-Sieved: ''${sieved_message}''}
if ${ihave "envelope"} {
if envelope :all :matches "to" "*@*" {
${set_with_interp "userfor" (interp "1")}
} else {
error "i dunno what to do, theres no envelope";
}
}
elsif ${var_is_true "in_imap"} {
${set_with_interp "userfor" (interp "env_imap_user")}
}
else {
error "dont have envelope or imapsieve, dunno what to do";
}
if ${var_is "userfor" "shelvacu"} {
addheader "X-Vacu-Sieved" "''${sieved_message}";
removeflag "not-spamish";
removeflag "orders";
removeflag "banking";
removeflag "banking-statements";
removeflag "banking-transactions";
removeflag "A";
removeflag "B";
removeflag "B.subscriptions";
removeflag "C";
removeflag "D";
${pure_flags [ "wells-fargo" "banking" ] (envelope_is "wf-primary@shelvacu.com")}
${pure_flags
[ "wells-fargo-transactions" "banking-transactions" "B" ]
[
(has_flag "wells-fargo")
(subject_matches [
"You just got paid!"
"Wells Fargo card purchase exceeded preset amount"
"You made a payment"
"You made a credit card purchase of *"
"Your card wasn't present for a purchase"
"Account update"
"You've earned cash back from My Wells Fargo Deals"
"Confirmation of your Wells Fargo Rewards redemption"
"You sent money with Zelle(R)"
])
]
}
${pure_flags
[ "wells-fargo-statements" "banking-statements" "C" ]
[
(has_flag "wells-fargo")
(subject_matches [
"Your statement for credit card account *"
"Your statement for account *"
])
]
}
${pure_flags
[ "wells-fargo-action-required" "A" ]
[
# wf is actually careful about saying action required
(has_flag "wells-fargo")
(subject_matches "Action Required: *")
]
}
${pure_flags
[ "wells-fargo-misc" "A" ]
[
(has_flag "wells-fargo")
(not (has_flag "wells-fargo-transactions"))
(not (has_flag "wells-fargo-statements"))
(not (has_flag "wells-fargo-action-required"))
]
}
${pure_flags [ "chase" "banking" ] (envelope_is "chase@shelvacu.com")}
${pure_flags
[ "chase-transactions" "banking-transactions" "B" ]
[
(has_flag "chase")
(subject_matches [
"Your * payment is scheduled"
"You made a * transaction with *"
"Your * transaction with *"
"Chase security alert: You signed in with a new device"
])
]
}
${pure_flags
[ "chase-statements" "banking-statements" "C" ]
[
(has_flag "chase")
(subject_matches [
"Your credit card statement is available"
])
]
}
${pure_flags
[ "chase-spam" "D" ]
[
(has_flag "chase")
(anyof [
(header_is "From" "Chase Credit Journey <no.reply.alerts@chase.com>")
(subject_is [
"Review your recent activity"
"Good news: You may qualify for a credit line increase!"
"Your Chase card is available to use with Paze - Activate now!"
])
])
]
}
${pure_flags [ "experian" ] (envelope_is "fbyjemby@shelvacu.com")}
${pure_flags
[ "experian-spam" "D" ]
[
(has_flag "experian")
(subject_matches [
"*, your FICO* Score has been updated"
"Your monthly account statement is here, *"
])
]
}
${pure_flags
[ "paypal" "banking" ]
[
# can't go purely on envelope, because paypal loves to give my email to every merchant I interact with
(envelope_is "paypal@shelvacu.com")
(from_matches [
"*@paypal.com"
"*@*.paypal.com"
])
]
}
${pure_flags
[ "paypal-transactions" "banking-transactions" "B" ]
[
(has_flag "paypal")
(subject_matches [
"Receipt for your payment to *"
"*: $* USD"
"*: $* CAD"
"*: kr * SEK"
"You authorized a payment to *"
"You sent an automatic payment to *"
"Review your new automatic payment setup for *"
"You have a refund from *"
])
]
}
${pure_flags
[ "paypal-statements" "banking-statements" "C" ]
[
(has_flag "paypal")
(subject_matches [
"*, your * account statement is available."
])
]
}
${pure_flags [ "usps-id" ] (envelope_is "usps-id@shelvacu.com")}
${pure_flags
[ "usps-expected-delivery" "C" ]
[
(has_flag "usps-id")
(subject_matches "USPS* Expected Delivery *")
]
}
${pure_flags
[ "amazon-ignore" "C" ]
[
(envelope_is "amznbsns@shelvacu.com")
(subject_matches [
"Your Amazon.com order has shipped*"
"Your Amazon.com order of * has shipped!"
])
]
}
${pure_flags
[ "bandcamp-ignore" "C" ]
[
(envelope_is "bandcamp@shelvacu.com")
(subject_matches [
"* just announced a listening party on Bandcamp"
"New items from *"
"Starting in *"
"New from *"
])
]
}
${pure_flags
[ "bandcamp-not-ignore" "B.subscriptions" ]
[
(envelope_is "bandcamp@shelvacu.com")
''not hasflag "bandcamp-ignore"''
]
}
${pure_flags [ "ika-ignore" "D" ] (envelope_is "ika@dis8.net")}
${pure_flags
[ "ally-statement" "C" ]
[
(envelope_is "ally@shelvacu.com")
(subject_is "Your latest statement is ready to view.")
]
}
${pure_flags "bloomberg" (envelope_is "bloomberg@shelvacu.com")}
${pure_flags
[ "money-stuff" "not-spamish" ]
[
(envelope_is "bloomberg@shelvacu.com")
''header :matches "From" "\"Matt Levine\" *"''
]
}
${pure_flags
[ "money-stuff-podcast" "D" known_flags.read ]
[
(has_flag "money-stuff")
(subject_matches "Money Stuff: The Podcast:*")
]
}
${pure_flags
[ "money-stuff-not-podcast" "B.subscriptions" ]
[
(has_flag "money-stuff")
(not (has_flag "money-stuff-podcast"))
]
}
${pure_flags [ "git" "not-spamish" "B" ] (exists [
"X-GitHub-Reason"
"X-GitLab-Project"
])}
${pure_flags [ "git-uninsane" "git" "not-spamish" "B" ] (envelope_is "git-uninsane@shelvacu.com")}
${pure_flags [ "github" "git" "not-spamish" "B" ] (header_matches "List-Id" "*<*.github.com>")}
${pure_flags [ "mailing-list-by-envelope" "not-spamish" "B" ] (
envelope_matches "*-ml@shelvacu.com"
)}
${pure_flags [ "discourse" "not-spamish" "B" ] (exists "X-Discourse-Post-Id")}
${pure_flags [ "agora" "not-spamish" ] (envelope_is "agora@shelvacu.com")}
${pure_flags [ "postgres-list" "not-spamish" ] (
header_matches "List-Id" "<*.lists.postgresql.org>"
)}
${pure_flags [ "secureaccesswa" "not-spamish" "A" ] (from_is "help@secureaccess.wa.gov")}
${pure_flags [ "letsencrypt-mailing-list" "not-spamish" "B" ] (
envelope_is "lets-encrypt-mailing-list@shelvacu.com"
)}
${pure_flags [ "jmp-news" "not-spamish" "B" ] (header_matches "List-Id" "*<jmp-news.soprani.ca>")}
${pure_flags
[ "tf2wiki" "not-spamish" "B" ]
[
(envelope_is "tf2wiki@shelvacu.com")
(from_is "noreply@wiki.teamfortress.com")
]
}
${pure_flags "gmail-fwd" (envelope_is "gmailfwd-fc2e10bec8b2@shelvacu.com")}
${pure_flags [ "ebay" "orders" ] (envelope_is "ebay@shelvacu.com")}
${pure_flags
[ "ebay-delivered" "B" ]
[
(has_flag "ebay")
(subject_matches [
"*ORDER DELIVERED: *"
])
]
}
${pure_flags
[ "ebay-message" "B" ]
[
(has_flag "ebay")
(from_matches (map (domain: "*@members.${domain}") ebay_domains))
]
}
${pure_flags
[ "ebay-offer" "B" ]
[
(has_flag "ebay")
(subject_matches [
"You have an offer from the seller, *"
"You saw it at *, but the seller is now offering *"
])
]
}
${pure_flags
[ "ebay-order-update" "C" ]
[
(has_flag "ebay")
(subject_matches [
"Out for delivery: *"
"*DELIVERY UPDATE: *"
"*Order update: *"
"EARLY DELIVERY UPDATE: *"
"Important information regarding your Global Shipping Program transaction *" # ebay: "important information! your order is being shipped." why did you say this was ""important""???
"Your package is now with *"
"*Order confirmed: *"
"Your order is confirmed"
"Your order is in!"
"*An update on your order"
])
]
}
${pure_flags
[ "ebay-bid-ongoing-notification" "C" ]
[
(has_flag "ebay")
(subject_matches [
"Michael, your bid for * is winning"
"* just got a new bid."
])
]
}
${pure_flags
[ "ebay-feedback" "D" ]
[
(has_flag "ebay")
(subject_matches "Please provide feedback for your eBay items")
]
}
${pure_flags [ "royal-mail" "orders" ] (from_is "no-reply@royalmail.com")}
${pure_flags
[ "royal-mail-delivered" "B" ]
[
(has_flag "royal-mail")
(subject_matches "Your Royal Mail parcel has been delivered")
]
}
${pure_flags
[ "royal-mail-on-the-way" "D" ]
[
(has_flag "royal-mail")
(subject_matches "Your Royal Mail parcel is on its way")
]
}
${pure_flags [ "aliexpress" "orders" ] (from_is [
"transaction@notice.aliexpress.com"
"aliexpress@notice.aliexpress.com"
])}
${pure_flags
[ "aliexpress-delivered" "B" ]
[
(has_flag "aliexpress")
(from_is "transaction@notice.aliexpress.com")
(subject_matches "Order * has been signed for")
]
}
${pure_flags
[ "aliexpress" "orders" "C" ]
[
(has_flag "aliexpress")
(not (has_flag "aliexpress-delivered"))
]
}
${pure_flags [ "brandcrowd" "D" ] (envelope_is "brandcrowd@shelvacu.com")}
${pure_flags [ "cpapsupplies" "D" ] (envelope_is "cpapsupplies@shelvacu.com")}
${pure_flags [ "genshin" "D" ] (envelope_is "genshin@shelvacu.com")}
${pure_flags [ "jork" "B" ] (envelope_is "jork@shelvacu.com")}
${pure_flags [ "patreon" "not-spamish" ] (envelope_is "patreon@shelvacu.com")}
${pure_flags
[ "patreon-post" "B.subscriptions" ]
[
(has_flag "patreon")
(header_is "X-Mailgun-Tag" "template_newsletterpostcontrol")
]
}
${pure_flags
[ "patreon-free-member-digest" "D" ]
[
(has_flag "patreon")
(header_is "X-Mailgun-Tag" "template_freememberdigest")
]
}
${pure_flags
[ "patreon-other" "B" ]
[
(has_flag "patreon")
(not (has_flag "patreon-post"))
(not (has_flag "patreon-free-member-digest"))
]
}
${pure_flags [ "rsb" "B" ] (from_is "support@rapidseedbox.com")}
${pure_flags [ "fresh-avocado-dis8" "D" ] (envelope_is "fresh.avocado@dis8.net")}
${pure_flags [ "discord" "A" ] (envelope_matches "discord@*")}
${pure_flags [ "za-sa" "D" ] (from_matches [
"*@*.sa.com"
"*@*.za.com"
])}
${pure_flags [ "localdomain" "D" ] (from_matches [
"*@*.local"
"*@*.localdomain"
])}
${pure_flags [ "helium" "D" ] (envelope_is "creepyface@dis8.net")}
${pure_flags [ "sharkmood" "C" ] (envelope_is "sharkmood@dis8.net")}
${pure_flags [ "im-not-district-158" "D" ] (envelope_is [
"khamar.anderson@dis8.net"
"pbooth@dis8.net"
"sgaylor@dis8.net"
])}
${pure_flags [ "next-level-burger" "D" ] (header_matches "From" "*Next Level Burger*")}
${pure_flags [ "lyft" "D" ] (envelope_is "lyft@shelvacu.com")}
${pure_flags [ "coursera" "D" ] (from_matches "*.*.coursera.org")}
${pure_flags [ "taskrabbit" "D" ] (envelope_is "taskrabbit@shelvacu.com")}
${pure_flags [ "subscribestar_code" "A" ] (allof [
(envelope_is "subscribestar@shelvacu.com")
(subject_is "Your authentication code")
])}
${pure_flags "itch-io" (from_is "postmaster@itch.io")}
${pure_flags
[ "itch-io-update" "B.subscriptions" ]
[
(has_flag "itch-io")
(subject_matches "[itch.io] * update *")
]
}
${pure_flags
[ "lowering-the-bar" "B.subscriptions" ]
[
(envelope_is "ltb@shelvacu.com")
]
}
${pure_flags [ "hotels-com" "D" ] (from_matches [
"hotels.com"
"*.hotels.com"
])}
${pure_flags
[ "spamish-by-headers" "C" ]
[
(anyof [
(header_is "Precedence" "bulk")
(exists "List-Unsubscribe")
(exists "List-Unsubscribe-Post")
])
(not (has_flag "not-spamish"))
]
}
if hasflag "agora" {
${fileinto "M.agora"}
} elsif hasflag "postgres-list" {
${fileinto "M.postgres"}
} elsif hasflag "D" {
${fileinto "D"}
} elsif hasflag "C" {
${fileinto "C"}
} elsif hasflag "A" {
${fileinto "A"}
} elsif hasflag "B.subscriptions" {
${fileinto "B.subscriptions"}
} else {
${fileinto "B"}
}
}
# disable any sieve scripts that might want to run after this one
stop;
'';
pigeonhole_pkg = pkgs.dovecot_pigeonhole;
in
{
imports = [
# Allow running a sieve filter when a message gets moved to another folder in imap
# see https://doc.dovecot.org/2.3/configuration_manual/sieve/plugins/imapsieve/
{
services.dovecot2 = {
sieve.plugins = [ "sieve_imapsieve" ];
mailPlugins.perProtocol.imap.enable = [ "imap_sieve" ];
};
}
];
options.vacu.checkSieve = lib.mkOption {
readOnly = true;
default = pkgs.writeScriptBin "check-liam-sieve" ''
set -xev
${lib.escapeShellArgs [
(lib.getExe' pigeonhole_pkg "sieve-test")
"-c"
config.services.dovecot2.configFile
"-C" # force compilation
"-D" # enable sieve debugging
"-f"
"some-rando@example.com"
"-a"
"shelvacu@liam.dis8.net"
config.services.dovecot2.sieve.scripts.before
"/dev/null"
]}
'';
defaultText = "check-liam-sieve package";
};
options.vacu.liam-sieve-script = lib.mkOption {
readOnly = true;
default = pkgs.writeText "mainsieve" sieve_text;
defaultText = "mainsieve text package";
};
config = {
vacu.packages = [ pigeonhole_pkg ];
services.dovecot2.sieve = {
extensions = [
"fileinto"
"mailbox"
"editheader"
"vnd.dovecot.debug"
];
scripts.before = config.vacu.liam-sieve-script;
};
services.dovecot2.imapsieve.mailbox = [
{
name = "*";
causes = [
"APPEND"
"COPY"
"FLAG"
];
before = config.vacu.liam-sieve-script;
}
];
# services.dovecot2.mailboxes."magic-refilter".auto = "create";
};
}

View File

@@ -1,23 +0,0 @@
{
config,
vacuModules,
...
}:
{
imports = [ vacuModules.sops ];
config.sops = {
secrets.dovecot-passwd = {
restartUnits = [ "dovecot2.service" ];
};
secrets.dkim_key = {
name = "dkimkeys/2024-03-liam.private";
restartUnits = [ "opendkim.service" ];
owner = config.services.opendkim.user;
};
secrets.relay_creds = {
restartUnits = [ "postfix.service" ];
owner = config.services.postfix.user;
};
};
}

View File

@@ -1,23 +0,0 @@
{ inputs, ... }:
{
imports = [
../common/nixos.nix
inputs.nixos-apple-silicon.nixosModules.default
./hardware.nix
];
vacu.hostName = "mmm";
vacu.shell.color = "red";
vacu.verifySystem.enable = false;
vacu.verifySystem.expectedMac = "14:98:77:3f:b8:2e";
vacu.systemKind = "server";
# asahi recommends systemd-boot
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = false;
hardware.asahi.peripheralFirmwareDirectory = ./firmware;
services.openssh.enable = true;
system.stateVersion = "24.05";
}

Some files were not shown because too many files have changed in this diff Show More