1
1
Fork 0

Compare commits

..

161 Commits

Author SHA1 Message Date
Tim Van Baak 725ba42c78 tmp 2024-04-13 04:50:53 +00:00
Tim Van Baak c2a45ec1bb imperium: Comic Momo and Gnome Terminal 2024-04-09 20:29:34 -07:00
Tim Van Baak e550e73d5d beatific: add exiftool to default programs 2024-03-13 09:49:03 -07:00
Tim Van Baak d6da7b5306 beatific: add VPN hosts for home services 2024-02-22 15:04:34 -08:00
Tim Van Baak e8239a9960 centroid: open mopidy to beatific 2024-02-22 23:03:23 +00:00
Tim Van Baak 5680da15c0 centroid: enable Nebula 2024-02-22 22:55:24 +00:00
Jaculabilis 17a863831e empyrean: add vhosts for home service stubs 2024-02-22 22:37:50 +00:00
Tim Van Baak 8841ab5c5a unfolder: add comic-mono and gnome-terminal 2024-02-22 13:44:48 -08:00
Tim Van Baak 7e983774cd imperium: follow unfolder's printing config 2024-02-19 07:29:38 -08:00
Jaculabilis 0543198e6b empyrean: enable automatic gitea archive cleanup
The backup dumps are reaching GB size, pretty sure there's not a GB of git data
2024-02-12 15:53:53 +00:00
Tim Van Baak cd76ffcd5a unfolder: enable printing and avahi 2024-02-06 08:22:36 -08:00
Tim Van Baak 982ec72e6b syncthings: init from nixpkgs 2024-02-06 08:22:36 -08:00
Jaculabilis fbf96fd83a beatific: highlight hostname of SSH sessions 2024-02-05 18:12:12 +00:00
Jaculabilis c74cb1d16d empyrean: add ecumene static site 2024-02-05 03:49:01 +00:00
Tim Van Baak 981ba9f6a5 beatific: histcontrol ignore both 2024-01-31 17:38:36 -08:00
Tim Van Baak b416859153 beatific: add sqlite to programs 2024-01-31 17:38:36 -08:00
Tim Van Baak 726e0fd9b6 backyard: add jellyfin group to tvb 2024-01-31 00:07:49 +00:00
Tim Van Baak bf4b31f4fc beatific: fix PS1 with spaces 2024-01-31 00:06:09 +00:00
Tim Van Baak 265ed5b9e7 centroid: add mopidy-jellyfin connection 2024-01-30 20:47:30 +00:00
Tim Van Baak 6a9cd5b5d2 Add cd .. aliases 2024-01-27 11:11:12 -08:00
Tim Van Baak d162e2262b beatific: system bashrc 2024-01-27 11:10:46 -08:00
Tim Van Baak 7d927ede86 beatific: alias smv 2024-01-26 13:43:18 -08:00
Tim Van Baak 8043cd2a93 beatific: alias xo=xdg-open 2024-01-26 10:00:51 -08:00
Tim Van Baak 1956c75a61 centroid: add lan revproxy 2024-01-20 04:51:10 +00:00
Tim Van Baak 89e1752d0e centroid: Add mopidy-youtube with yt-dlp stitched in 2024-01-20 04:04:59 +00:00
Tim Van Baak 612fcb7dce centroid: Set up mopidy 2024-01-20 03:46:41 +00:00
Tim Van Baak 75a6b01fc6 beatific: nixos-rebuild --fast 2024-01-19 04:36:58 +00:00
Tim Van Baak 46c862085f centroid: get pipewire sound working 2024-01-19 04:36:37 +00:00
Tim Van Baak af0918603d centroid: pin nixpkgs 2024-01-19 01:34:08 +00:00
Tim Van Baak d8628b33cc centroid: enable networkmanager 2024-01-19 01:21:34 +00:00
Tim Van Baak d4a34ffe19 Regenerate hardware-configuration.nix from nixos-generate-config 2024-01-19 00:51:37 +00:00
Tim Van Baak a13d098d4e centroid: remove root ssh key 2024-01-19 00:26:45 +00:00
Tim Van Baak 5afdd69a2f centroid: enable time, i18n, programs, ssh, hosts 2024-01-19 00:08:24 +00:00
Tim Van Baak 6f3c75e53c beatific: add centroid key 2024-01-18 23:53:57 +00:00
Tim Van Baak 22ec014c38 centroid: remove some unneeded options 2024-01-18 23:20:49 +00:00
Tim Van Baak 87da6efaed centroid: enable beatific module 2024-01-18 23:10:24 +00:00
Tim Van Baak 1c8603fd8e centroid: clean up after nixos-infect a bit 2024-01-18 23:03:00 +00:00
Tim Van Baak 969cc2ecec centroid: init via nixos-infect 2024-01-18 22:55:55 +00:00
Tim Van Baak 51f72d2d55 beatific: add an xclip copy script 2024-01-17 15:05:12 -08:00
Tim Van Baak c86cf48127 unfolder: extra programs 2024-01-17 14:57:41 -08:00
Tim Van Baak 9befa8bb16 beatific: add puddletag to extra programs 2024-01-17 14:57:27 -08:00
Jaculabilis 8335a93596 empyrean: revproxy mirror to catacomb
Keeping a full local copy of the mirror is unsustainable without expanding empyrean's relatively small storage
2024-01-17 12:32:45 +00:00
Tim Van Baak 471930cb64 catacomb: add port for mirror vhost 2024-01-17 12:13:15 +00:00
Jaculabilis a5b364fbc1 empyrean: remove newtab vhost
This doesn't appear to be used. I think the intake configuration overwrote it.
2024-01-12 18:51:42 +00:00
Tim Van Baak 12117f37bb unfolder: add obsidian 2024-01-12 10:45:58 -08:00
Jaculabilis 46c6157fab empyrean: fix HTTPS for nonexistent subdomains
nginx always chooses a server block for a connection and the listen parameters are checked before server name. This meant that HTTPS connections missed the default 444 server block because it only matched HTTP. With this, those requests now get an SSL error.
2024-01-12 18:21:52 +00:00
Jaculabilis c9242c0bea empyrean: fix cron job 2024-01-08 23:11:30 +00:00
Tim Van Baak 84fa63493f catacomb: serve mirror directly 2024-01-08 20:11:19 +00:00
Jaculabilis 44583f670f empyrean: cron job to move files from phone to NAS 2024-01-05 01:22:43 +00:00
Jaculabilis ba3c46b8f4 beatific: alias cp to -rp 2024-01-04 20:55:43 +00:00
Jaculabilis fa46c83f46 empyrean: Enable syncthing 2024-01-04 20:55:12 +00:00
Tim Van Baak 48f36f5d9e catacomb: enable syncthing 2024-01-04 19:57:13 +00:00
Tim Van Baak 17b87e606c catacomb: comment on networking.hostId 2024-01-04 19:57:13 +00:00
Tim Van Baak b4a32f04b5 catacomb: reorganize and pare down packages 2024-01-04 19:57:13 +00:00
Tim Van Baak e71acea928 beatific: Force syncthing config and database to .config 2024-01-04 19:57:08 +00:00
Tim Van Baak d47d87d91f beatific: Pin registry nixpkgs to flake input 2024-01-04 19:57:01 +00:00
Tim Van Baak 0fce9564f5 beatific: Add beatific.extraPrograms
This is partly a way to keep notes on useful software that I might otherwise forget about
2024-01-04 19:56:53 +00:00
Tim Van Baak 96d6e73346 beatific: add jq and htmlq 2023-12-29 16:28:49 -08:00
Tim Van Baak f8e09d26d1 beatific: enable default programs 2023-12-27 05:17:57 +00:00
Tim Van Baak 3a954c35c1 beatific: add more default programs 2023-12-27 05:17:45 +00:00
Tim Van Baak a8730b3a13 catacomb: workaround for a rare ZFS bug
This can be removed if a recent 23.11 is taken or 24.05
2023-12-27 05:01:34 +00:00
Tim Van Baak 5b752f7cfa beatific: add vagrant pubkey 2023-12-24 16:03:54 +00:00
Tim Van Baak 40087d26be beatific: set git default branch 2023-12-23 13:15:42 -08:00
Tim Van Baak c9f65b73d7 unfolder: enable tvb-syncthing 2023-12-23 13:02:08 -08:00
Tim Van Baak 6b5dcb6e1d beatific: refactor tvb-syncthing to module 2023-12-23 13:01:26 -08:00
Tim Van Baak e381001f0a beatific: add imperium host entry 2023-12-22 22:07:21 -08:00
Tim Van Baak 741a0bc340 imperium: add obsidian 2023-12-22 22:06:57 -08:00
Tim Van Baak 49d864839a imperium: syncthing system service 2023-12-19 20:06:54 -08:00
Tim Van Baak 532e7a5c6b beatific: allow `sudo nixos-rebuild` without password for tvb 2023-12-19 19:33:47 -08:00
Tim Van Baak 7afcfbac2b beatific: alias nixos-rebuild to nr 2023-12-18 12:39:12 -08:00
Tim Van Baak c0cbd43411 imperium: enable printing 2023-12-18 12:38:47 -08:00
Tim Van Baak 4676c9e91d imperium: Get TF2 working
Requires launch option: LD_PRELOAD=$LD_PRELOAD:/run/current-system/sw/lib/libtcmalloc_minimal.so %command%

DRG also runs through Proton but at a prohibitive framerate whenever things are onscreen
2023-12-16 11:41:49 -08:00
Jaculabilis 05357d5423 beatific: allow imperium access 2023-12-15 21:41:39 +00:00
Tim Van Baak 6804636ce5 imperium: initialize config 2023-12-15 13:18:40 -08:00
Tim Van Baak 267b3d3898 imperium: add SSH key 2023-12-15 12:53:07 -08:00
Tim Van Baak 9d2ac1f8ec backyard: Upgrade to 23.11 2023-12-15 20:52:12 +00:00
Tim Van Baak ed5fee36ed beatific: Add 23.11 input 2023-12-15 20:52:12 +00:00
Tim Van Baak bdffba6351 stagirite: Move to 23.05
stagirite's hard drive died so if it comes back it might as well be current
2023-12-15 20:52:12 +00:00
Jaculabilis 9d964dd7f7 empyrean: remove defunct redstring 2023-12-14 16:08:16 +00:00
Jaculabilis 43a14b2bec empyrean: update intake-sources 2023-12-14 16:07:04 +00:00
Tim Van Baak 311aba7975 beatific: Add bc 2023-12-08 20:44:35 -08:00
Tim Van Baak 4d5227f51b beatific: add killall 2023-12-08 20:43:34 -08:00
Tim Van Baak 14842e99a1 catacomb: add tree and exiftool 2023-11-28 16:02:51 +00:00
Tim Van Baak eeb694b08c Fix yt-dlp argument quoting 2023-11-22 19:05:15 +00:00
Tim Van Baak d553d80270 unfolder: remove chrome from system packages 2023-10-28 06:13:50 -07:00
Tim Van Baak 23e9af7564 backyard: Enable Jellyfin server 2023-10-22 20:56:06 +00:00
Tim Van Baak 721e5a3ca1 beatific: Add DNS host entries 2023-10-22 20:52:10 +00:00
Tim Van Baak 33b50d12d9 catacomb: Update catacomb-server for .m4a 2023-10-20 04:20:36 +00:00
Tim Van Baak a0979abb57 catacomb: Add an updatable yt-dlp 2023-10-20 04:20:36 +00:00
Tim Van Baak 298b91f83f catacomb: Fix ssh setting path 2023-10-20 04:20:36 +00:00
Tim Van Baak 0b5ac640b8 backyard: resurrect backyard 2023-10-19 20:31:12 -07:00
Jaculabilis 1e740188e6 empyrean: update intake 2023-10-10 02:32:12 +00:00
Jaculabilis f2feb22a86 beatific: Link /etc/nixos to the current config 2023-09-28 14:37:15 +00:00
Jaculabilis ba9bfa01f3 beatific: Use programs.<prog> where available
Based on the option source, this doesn't actually change anything, but it seems like good practice in case it becomes necessary for another program or a future version of these.
2023-09-28 14:30:33 +00:00
Jaculabilis 092250889a empyrean: Move www static files for new static site 2023-09-28 14:25:11 +00:00
Tim Van Baak 0fc5aaa8c0 unfolder: promote duf, file, and tree to defaults 2023-09-13 13:32:28 -07:00
Jaculabilis 8a3e01091c empyrean: Update intake-sources 2023-09-04 20:56:14 +00:00
Tim Van Baak a6b52340af unfolder: add syncthing 2023-08-13 16:20:29 -07:00
Tim Van Baak 57dcaf1f07 catacomb: update to 23.05 2023-08-12 04:53:07 +00:00
Tim Van Baak 06b632ec68 catacomb: regenerate hardware config 2023-08-12 02:55:59 +00:00
Jaculabilis 820417819f Replace inquisitor with intake 2023-08-08 15:47:09 +00:00
Tim Van Baak f5faefb5e5 Add empyrean ascii banner 2023-08-03 22:54:44 -07:00
Jaculabilis 72c5619671 Add unfolder ascii banner 2023-08-03 22:43:03 -07:00
Tim Van Baak ce4a568809 Add some host-specific ascii banners 2023-08-04 05:32:29 +00:00
Jaculabilis de253930e3 Remove previous beatific config 2023-08-03 21:54:49 -07:00
Jaculabilis 6215ce2961 Add unfolder machine configs 2023-08-03 21:52:49 -07:00
Jaculabilis 637fea3bbd Add gitea group to tvb 2023-08-03 22:18:06 +00:00
Jaculabilis c13fabbdbc Enable beatific.isLighthouse and defaults.nebula 2023-08-02 18:11:53 +00:00
Jaculabilis 43c19146a9 Enable defaults.tvb 2023-08-02 17:59:22 +00:00
Jaculabilis 071cb4774d Enable defaults.ssh 2023-08-02 17:55:21 +00:00
Jaculabilis 8ef887a4f0 Enable defaults.{time,i18n} 2023-08-02 17:46:48 +00:00
Jaculabilis c431fb3ca5 Add beatific module to empyrean 2023-08-02 17:45:22 +00:00
Jaculabilis a718222744 Update intake-sources 2023-08-02 17:35:29 +00:00
Tim Van Baak 0b8ef01e5e Add backyard pubkey 2023-08-02 17:30:48 +00:00
Tim Van Baak 5470f2672d Enable defaults.nebula 2023-08-02 17:27:42 +00:00
Tim Van Baak 504d1a4283 Enable defaults.tvb 2023-08-02 17:19:54 +00:00
Tim Van Baak a4089b030f Enable defaults.ssh, leave defaults.programs 2023-08-02 17:12:05 +00:00
Tim Van Baak 83cbd95c95 Enable defaults.i18n 2023-08-02 17:09:23 +00:00
Tim Van Baak 72720464ec Enable defaults.time 2023-08-02 17:07:00 +00:00
Tim Van Baak 13090dd594 Add beatific module to catacomb 2023-08-02 17:03:35 +00:00
Tim Van Baak bda35d7da4 Remove monitor@isidore key 2023-08-02 16:52:27 +00:00
Tim Van Baak db33f88300 Refactor nebula config out 2023-08-02 16:49:50 +00:00
Tim Van Baak 1d515f416a Connect backyard to nebula@beatific 2023-08-02 16:29:18 +00:00
Tim Van Baak dd265429be Enable firewall 2023-08-02 15:39:25 +00:00
Tim Van Baak 35247f7b4a Add fancy ssh banner 2023-08-02 15:23:52 +00:00
Tim Van Baak b9c6e20ef6 Use mkFlag for other options 2023-08-02 15:19:57 +00:00
Tim Van Baak d87f127954 Add default ssh config 2023-08-02 15:18:26 +00:00
Tim Van Baak ec88265631 Add default installed programs 2023-08-02 02:40:19 +00:00
Tim Van Baak 2a618ce67f Factor out i18n settings 2023-08-02 02:28:32 +00:00
Tim Van Baak 656fdeef49 Add flake enable to module 2023-08-02 02:19:18 +00:00
Tim Van Baak 7feec36673 Factor out time zone and NTP 2023-08-02 02:17:10 +00:00
Tim Van Baak 4e8a2bb7e4 Create a beatific module with options 2023-08-02 01:59:06 +00:00
Tim Van Baak 9948b73eff Move previous module out of the way 2023-08-02 01:51:00 +00:00
Tim Van Baak d63efc38b9 Remove some unused options 2023-08-01 17:31:34 -07:00
Tim Van Baak b216c2acd9 Change time zone to UTC 2023-08-01 17:31:34 -07:00
Tim Van Baak a78c36b871 Regenerate hardware config to pick up swapfile 2023-08-01 17:31:31 -07:00
Tim Van Baak 733679c944 Update backyard hostname 2023-08-01 17:17:02 -07:00
Tim Van Baak 3ba86c1115 Initialize backyard config 2023-08-01 17:13:35 -07:00
Jaculabilis 852304140a Allow unfolder access to empyrean 2023-07-05 12:44:24 +00:00
Jaculabilis c3494644cc Add openssh to intake packages so it can scp 2023-07-05 12:44:09 +00:00
Jaculabilis 041c17bfb3 Update intake to 1.0.4 2023-07-05 12:43:42 +00:00
Jaculabilis 9c990c13a7 Add unfolder pubkey 2023-07-04 22:24:02 -07:00
Jaculabilis 35d9393733 Update empyrean key
I don't know what key that used to be
2023-07-05 04:57:24 +00:00
Jaculabilis d982e1c4cd Allow catacomb access to empyrean 2023-07-05 04:55:15 +00:00
Jaculabilis 79d941b343 Add catacomb pubkey 2023-07-05 04:54:12 +00:00
Jaculabilis c0887179ce Allow access from tvb@empyrean 2023-07-03 14:15:29 +00:00
Jaculabilis ca79e62268 Remove tinc from packages 2023-07-03 14:15:09 +00:00
Jaculabilis 7e43cd2efa Update intake-sources for intake-echo 2023-06-25 04:46:10 +00:00
Jaculabilis ff1ed94c3f Update intake-sources for reddit link fix 2023-06-24 13:54:52 +00:00
Jaculabilis ba5486e372 Update intake for channel markers 2023-06-24 04:02:49 +00:00
Jaculabilis 63c50d5c67 Update intake for crontab support 2023-06-22 01:52:08 +00:00
Jaculabilis 986c2d4674 Update intake for edit fixes 2023-06-21 21:37:53 +00:00
Jaculabilis 6587d70066 Update intake to fix a PATH issue 2023-06-21 04:01:41 +00:00
Jaculabilis f134165737 Add intake-sources 2023-06-20 21:34:14 +00:00
Jaculabilis cd4cf9107c Enable intake for tvb on port 5234 2023-06-20 04:35:45 +00:00
Jaculabilis 4f9b51a94b Add intake to empyrean 2023-06-20 04:35:11 +00:00
Jaculabilis b3a1f104ff Remove gitolite 2023-06-19 23:07:11 +00:00
Jaculabilis f252a38b1b Update empyrean configs to 23.05 2023-06-09 21:27:52 +00:00
Jaculabilis e8a7aae12e Add nixpkgs-next url 2023-06-09 20:42:52 +00:00
Jaculabilis bbe12a24d3 Use a simpler ref for 22.11 2023-06-09 20:29:51 +00:00
Jaculabilis 741d6a7d95 Up Gitea session lifetime to a week 2023-06-09 20:27:03 +00:00
35 changed files with 2011 additions and 513 deletions

View File

@ -3,11 +3,11 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1668681692,
"narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "009399224d5e398d03b22badca40a37ac85412a1",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
@ -31,12 +31,79 @@
"type": "github"
}
},
"intake": {
"inputs": {
"flake-compat": [
"flake-compat"
],
"nixos-shell": "nixos-shell",
"nixpkgs": [
"nixpkgs-2305"
]
},
"locked": {
"lastModified": 1696904526,
"narHash": "sha256-VbPMkzZBNhRB5fj2cEBnTRP1LRJHOWX1d8KGuAqtezQ=",
"ref": "refs/heads/master",
"rev": "8fd6f3b751fd46c0d4571d1cf4f330dc38b8270e",
"revCount": 79,
"type": "git",
"url": "ssh://gitea@git.alogoulogoi.com/Jaculabilis/intake.git"
},
"original": {
"type": "git",
"url": "ssh://gitea@git.alogoulogoi.com/Jaculabilis/intake.git"
}
},
"intake-sources": {
"inputs": {
"nixpkgs": [
"nixpkgs-2305"
]
},
"locked": {
"lastModified": 1700115142,
"narHash": "sha256-EuLKiCD8AVQUEADh+TJoePc6GR+TKVvmbOb4Duld2gI=",
"ref": "refs/heads/master",
"rev": "327a79479d80dc7c1760f32887b7f07723529d66",
"revCount": 26,
"type": "git",
"url": "ssh://gitea@git.alogoulogoi.com/Jaculabilis/intake-sources.git"
},
"original": {
"type": "git",
"url": "ssh://gitea@git.alogoulogoi.com/Jaculabilis/intake-sources.git"
}
},
"nixos-shell": {
"inputs": {
"nixpkgs": [
"intake",
"nixpkgs"
]
},
"locked": {
"lastModified": 1686216465,
"narHash": "sha256-0A4K6xVIyxUi2YZu4+156WwzAO1GDWGcKiMvsXpBQDQ=",
"owner": "Mic92",
"repo": "nixos-shell",
"rev": "65489e7eeef8eeea43e1e4218ad1b99d58852c7c",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "nixos-shell",
"type": "github"
}
},
"nixos-wsl": {
"inputs": {
"flake-compat": "flake-compat",
"flake-compat": [
"flake-compat"
],
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
"nixpkgs-2305"
]
},
"locked": {
@ -53,26 +120,46 @@
"type": "github"
}
},
"nixpkgs": {
"nixpkgs-2305": {
"locked": {
"lastModified": 1669833724,
"narHash": "sha256-/HEZNyGbnQecrgJnfE8d0WC5c1xuPSD2LUpB6YXlg4c=",
"lastModified": 1685566663,
"narHash": "sha256-btHN1czJ6rzteeCuE/PNrdssqYD2nIA4w48miQAFloM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "4d2b37a84fad1091b9de401eb450aae66f1a741e",
"rev": "4ecab3273592f27479a583fb6d975d4aba3486fe",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "refs/tags/22.11",
"ref": "23.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-2311": {
"locked": {
"lastModified": 1701282334,
"narHash": "sha256-MxCVrXY6v4QmfTwIysjjaX0XUhqBbxTWWB4HXtDYsdk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "057f9aecfb71c4437d2b27d3323df7f93c010b7e",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-compat": "flake-compat",
"intake": "intake",
"intake-sources": "intake-sources",
"nixos-wsl": "nixos-wsl",
"nixpkgs": "nixpkgs"
"nixpkgs-2305": "nixpkgs-2305",
"nixpkgs-2311": "nixpkgs-2311"
}
}
},

View File

@ -1,27 +1,103 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs?ref=refs/tags/22.11";
nixos-wsl.url = "github:nix-community/NixOS-WSL";
nixos-wsl.inputs.nixpkgs.follows = "nixpkgs";
nixpkgs-2305.url = "github:NixOS/nixpkgs/23.05";
nixpkgs-2311.url = "github:NixOS/nixpkgs/23.11";
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
nixos-wsl = {
url = "github:nix-community/NixOS-WSL";
inputs.nixpkgs.follows = "nixpkgs-2305";
inputs.flake-compat.follows = "flake-compat";
};
intake = {
url = "git+ssh://gitea@git.alogoulogoi.com/Jaculabilis/intake.git";
inputs.nixpkgs.follows = "nixpkgs-2305";
inputs.flake-compat.follows = "flake-compat";
};
intake-sources = {
url = "git+ssh://gitea@git.alogoulogoi.com/Jaculabilis/intake-sources.git";
inputs.nixpkgs.follows = "nixpkgs-2305";
};
};
outputs = { self, nixpkgs, nixos-wsl }: {
nixosConfigurations = {
catacomb = nixpkgs.lib.nixosSystem {
system = "aarch64-linux";
modules = [ ./machine/catacomb ];
outputs = {
self,
nixpkgs-2305,
nixpkgs-2311,
flake-compat,
nixos-wsl,
intake,
intake-sources,
}@inputs: {
nixosModules.beatific = import ./modules/beatific.nix;
nixosConfigurations = let
pinNixpkgs = nixpkgs: { ... }: {
nix.registry.nixpkgs.to = { type = "path"; path = nixpkgs; };
};
empyrean = nixpkgs.lib.nixosSystem {
in {
backyard = nixpkgs-2311.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./machine/empyrean ];
modules = [
self.nixosModules.beatific
(pinNixpkgs nixpkgs-2311)
./machine/backyard
];
};
stagirite = nixpkgs.lib.nixosSystem {
catacomb = nixpkgs-2305.lib.nixosSystem {
system = "aarch64-linux";
modules = [
self.nixosModules.beatific
(pinNixpkgs nixpkgs-2305)
./machine/catacomb
];
};
centroid = nixpkgs-2311.lib.nixosSystem {
system = "x86_64-linux";
modules = [
self.nixosModules.beatific
(pinNixpkgs nixpkgs-2311)
./machine/centroid
];
};
empyrean = nixpkgs-2305.lib.nixosSystem {
system = "x86_64-linux";
modules = [
self.nixosModules.beatific
intake.nixosModules.default
intake-sources.nixosModules.default
(pinNixpkgs nixpkgs-2305)
./machine/empyrean
];
};
imperium = nixpkgs-2311.lib.nixosSystem {
system = "x86_64-linux";
modules = [
self.nixosModules.beatific
(pinNixpkgs nixpkgs-2311)
({ ... }: {
environment.systemPackages = [ nixpkgs-2311.legacyPackages."i686-linux".gperftools ];
})
./machine/imperium
];
};
stagirite = nixpkgs-2305.lib.nixosSystem {
system = "x86_64-linux";
modules = [
nixos-wsl.nixosModules.wsl
./machine/stagirite
];
};
unfolder = nixpkgs-2305.lib.nixosSystem {
system = "x86_64-linux";
modules = [
self.nixosModules.beatific
(pinNixpkgs nixpkgs-2305)
./machine/unfolder
];
};
};
};
}

14
keys/default.nix Normal file
View File

@ -0,0 +1,14 @@
{
tvb = [
./nix-on-droid.vagrant.pub
./tvb.backyard.pub
./tvb.catacomb.pub
./tvb.centroid.pub
./tvb.empyrean.pub
./tvb.imperium.pub
./tvb.palamas.pub
./tvb.stagirite.pub
./tvb.unfolder.pub
./tvb.vagrant.pub
];
}

View File

@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCzx37PqIaJVWdQs5meVgI4Cg1GRGk6srrix0AUvQeaBS9MOVtJLi+HfnNkcW4GPk9qVlz1E7ciQ7YUw+ny7QbHxcbib2Tawwfk3cx9xiNcN6UI9EzF/rTbNB2Cex8A4sEr5UvoE0BjT5yPaXyrjn8vLksGWq4dlZBM3xeJqe3KP+OxPL0vik3SVGOr/6ZQ7H9cwX5+/p6rCWQuVtwZMcaE6QyXYg5J5FQUaIrFvKbOVklJIkQSbXGzIYQO/QlQC0xWGBapJtGQw/lsQ3YqnFSMkkw8qrKbde07rg8p1FSuqTu+a1ePK+/F4klNel174+39YSobY2/6biPP3Uj/Yhorf4Tw141tIT75e3ebtK5faatQmNOyXcA7LULXK7XemJkZy8PmbNNTeBIKyoI6XQdzk95gpb2C4LEJmV040YMgXhOIiKsHQVgss9FuC+oP5jXWU/JuNXBRHa1IpJjcJhIhg7jnh6ZNZHyK0EpeUs3Zp7usv7mz6CGwb04yvTsWOhZRc+6EoHaHyrNvFPfkPeGsZzxhIbprCyDMtKWsI9GCtztcRhQWBgornUVEs5CurLJBbClQTrZLVv2fn9UnXWPYZTLYL7aFwRIGyKr8ZOOMFxbLOGdeFlqc5TGCP416e8PZvhE+BuDmxiKtQJ/dsQFqVzvOZb2WQRsYRPYvvXbvUw== monitor@isidore

View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEpvV9dKUVBlv5VU3LU0XIGTQK/McPf3H31HHD/vINGG nix-on-droid@vagrant

1
keys/tvb.backyard.pub Normal file
View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGYv5vs78+UAeRagopi4BuvmmK1l3zZwQPY3R4rnp7oV tvb@backyard

1
keys/tvb.catacomb.pub Normal file
View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDitOuQeddhGh3Zg/fnawTrIdomMhgR6rJchbfAAEUz7JDWyrwZoU0/kMBcn9qZZBFE0MDeUSbQbF+voA7/dwZKB+3GBOurg75KSxtwDLHw4urC5U9VCZnbOrFnl5K51oopduxE7vqZdtTzJztcDVKwJILSFPS2hDC3Zt7+pnB1z0aMOJIMyqfogSk29dxREHO130tbrRWI6bCrAJKXWMFSEx6N1pGoOvOKZu4YVdiDSqTPdSYW4D4ivC5Wtt74rGz8/su5xvZKHgNf/d/hILlg/zhnGzH5gn8HvN5pqRksh2fiteGxDQoXgaRGEb93RLe6KV7XPy60vmI+uE06lsow0C7hLrSWorhLQOuLG1J5JzzF0SmFRUOYQoc6BbOLLVXVBa1VcmpupHMJiw6ldJv9yD410bXd+IwIDS9IkW1MIfvN5j35AvnaJCEHVUSrkEjgqCpkNxNPl7V3h7YRw6F/AljTvgEER91mPUvwfJrC0sMo/+DWNwIbnK+jjioD2szHXz2EpXlVhkMSwey/rNZffQpzFHWsm3Za/+4KxWBUO/2MRz2x1haDvvD37hN2kC5w0DSC6MsJucDVlyEjgDQkVEBKujkBv4fpYLpN4VoqVDYytpgnRTm0QIb+ISStG19Fq1uj3UtHFyWI5d8P3jiev4DTtqCpQo9NWa4zu/mbCw== tvb@catacomb

1
keys/tvb.centroid.pub Normal file
View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC364peKQVWeqFNzhJJkvHumKerKPkczeX2I/e9FFZyL tvb@centroid

View File

@ -1 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC1h/6CedtyFIjFTT7M5e0dEKJkhPbCQ1RLhtj/83H//AK6bzRbWfnKzSH0VXpsHjaU/Ipc1Jl2fQ23r8i/QyKHUKK7xPeGcY5J7oIHVggkEKW2n9R27Ml9BriKxx6ltButnwSOVYk7dyNhz93GYTTEF3ydh4X7HP2Cv7rh5fbca3s69GXRjOVGmIuuVbaJiaMmiWhBI4LYtqwpo1zGXMjfNlXcMFw7VA4EG2UpkJkcWeyN/AI3ZS/YybcTQNCAg+Xnk94CVys/b5wTuGWRplDrRlNR00MUWpr94+u/xk+sC4/6vT7je2W4GjA1jTq4XmewTEV4cxOu+l1jtHZBgvHho5X0fOogdN52MkjuaXzByZB/Br5xTkBRv0tDf5haX4HzuBC29yU9rt62SEQRzvZxObCCGDcIYR/1HTgjDZkRuwgO/1RoRh5SvwbptvPwpBMvx25S//ZJESLO++lqxjgRZSr/05YpZ5diffEIGd1J0Jz0NGv4XBPcMBnSMKFmdwOy+5jnBbW2OjPQaPslXHEKYTfOByzCA8LgppkxvmL08GIjxYfEljioHR5by+Z6SjG1VvifMFA6FN/+DN6ZH0LmeOMa5YM1Zl3bx5RaANpnSNvi6rmxkQa1oMaK0l482FvpVkg6o1h9si/AeNTEbiX9ozHdjekfuzBSk6Jfo6xw+Q== tvb@empyrean
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCuAlVTZ4g7x8Fv3YoHn4KRr5GHfylgJjkC6lujti7Fd3JhZ34OB5L/FuCKLo0rv/1qpIcGHk01FMNT/hDcbyBRPN5QG1s7x39Bt8yBVePoJK0+malGkI90z4zV1b5LEjvRhr7+KuOskt3eVbhKcEXiJpDdqOOgqvppmQZOb6jb03+q01rPLzz0S20jUDLRSdnmlcNDv16lMXTX9zgWDeVIVErTvoLAI8RloqKUgienheLJSS6sdEk4AjL2PKldKE6mIOxZWiYSTS9+2ClqV8u3l1UTZ7+DOw8FWASmMYaaBvJRDEUzDKA/iOAjpfPO7WOn+yjRyiT7IFVFoz2XtXwZD0OEQhbgLZtPlhOHh5wn++YNnvzLYd5cYSWVya0FYzVis24hbaGjrwB5tzD0riL2lRzo3ZjktpL7RlCSLfO/2Cb14hLOxZTZZcgdM6Ef/1YatJiEpRQ7FLP45Di3hKc9QEsqQP1BrhhYQOCWwEHAgVXM8W1ncEBXiCnrelegVy0= tvb@empyrean

1
keys/tvb.imperium.pub Normal file
View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHGUvJ7Gd1mN2mF/hy12dizwEw64zn+jT0vFpkhGF07s tvb@imperium

1
keys/tvb.unfolder.pub Normal file
View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCom6c/UrhM6KrzDcm8kJGZJ5ugR4wRfsFUhTJ5F4oLNQcNspvqlUfxT4Hjv4xHA5hCjvPYi7JxVWxBsOEmmIs/LAjFXRNw9Kz8m7TCf/lct+JUpf6eCn6a/orhA0OdUv4c9aiH2Dzp4ob3lR6xYvYUOH3LuffqypSXP0k5zCSetROUgTZibEpa0oE2GevcyjQAExpCjx02ZRIGkGOM20CXtm3EJsTzIs6uk4+2F9hB+HMqePFKCzsgOlFfVCNWiKNywLavXo7Gn0O9pWidufXZ9s8nCBiOEzU1n6T8pNQBat4z7G1uKFKKWNDPL6/HNEmCq0JxUuXSSjg8LIk+uqPH49Ubpf8EORON8z8nVFAAqbuI6rdYc7J9DllQ7hb7EBT9w9w+mcz3XH0BsGzJUOMD9r0P96pWOn+I6A9jPmOqoOZDzGpfYS18+zYWET/ohH4U4pABcW4nwGx0Jz7Fj6iQW3tyjOefuXcz+sJoYKo/9FOh44KYf4pgu3hfoMlGC0M= tvb@unfolder

View File

@ -0,0 +1,58 @@
{ config, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./jellyfin.nix
];
boot.loader.grub = {
enable = true;
device = "/dev/sda";
};
beatific.hostName = "backyard";
beatific.defaults.tvbSync = false;
# Enable networking
networking.networkmanager.enable = true;
users.users.tvb.extraGroups = [ "networkmanager" ];
networking.firewall = {
enable = false;
};
#
users.users.guest = {
group = "guest";
description = "gueSSHtbook sshd user";
};
users.groups.guest = {};
systemd.services.guesshd = let
nssModulesPath = config.system.nssModules.path;
in {
enable = false;
description = "gueSSHtbook SSH daemon";
wantedBy = "multi-user.target";
after = [ "network.target" ];
stopIfChanged = false;
path = [ config.programs.ssh.package pkgs.gawk ];
environment.LD_LIBRARY_PATH = nssModulesPath;
#restartTriggers = [ config path goes here ];
# need keys to exist, see prestart in sshd.nix
serviceConfig = {
ExecStart = "${config.programs.ssh.package}/bin/sshd -D -f /path/to/config";
KillMode = "process";
Restart = "always";
Type = "simple";
};
networking.firewall.allowedTCPPorts = [ 2345 ];
#
# This value governs how some stateful data, like databases, are handled
# across different versions of NixOS. This should not be changed to a new
# release unless the sysadmin has determined that no services would be
# adversely affected by changing this.
system.stateVersion = "23.05";
}

View File

@ -0,0 +1,35 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/798089ca-f249-431d-aa08-65909b85a184";
fsType = "ext4";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/5d55f9b7-cde3-403d-9c91-61c4b68c71f9"; }
];
# 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.eno1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -0,0 +1,39 @@
{ pkgs, ... }:
{
# Enable jellyfin
services.jellyfin.enable = true;
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
# Create a default vhost to deny traffic, so traffic has to actually match a vhost
default = {
default = true;
locations."/".return = "444";
};
"jellyfin" = {
listen = [
# Available on the local network (host managed by router)
{ addr = "jellyfin.backyard.lan"; port = 80; }
# Available by name on beatific (host managed by beatific module)
{ addr = "jellyfin.backyard.home"; port = 80; }
# Available by port on beatific until I solve DNS for non-NixOS hosts
{ addr = "10.22.20.8"; port = 8096; }
];
locations."/".extraConfig = ''
proxy_buffering off;
proxy_pass http://localhost:8096/;
'';
};
};
};
networking.firewall.allowedTCPPorts = [
80 # http
8096 # jellyfin
];
users.users.tvb.extraGroups = [ "jellyfin" ];
}

View File

@ -1,13 +1,15 @@
{ pkgs, lib, ... }:
let
beatific = import ../../modules/beatific.nix;
in {
{
imports = [
./hardware-configuration.nix
./fileserver.nix
./mirror.nix
];
beatific.hostName = "catacomb";
beatific.defaults.tvbSync = true;
boot = {
loader = {
# Use the extlinux boot loader. (NixOS wants to enable GRUB by default)
@ -17,42 +19,26 @@ in {
};
supportedFilesystems = ["zfs"];
zfs.enableUnstable = true;
kernelParams = [ "zfs.zfs_dmu_offset_next_sync=0" ];
};
system.stateVersion = "22.11"; # Read the usual warning
swapDevices = [ { device = "/swap"; size = 1024; } ];
console.keyMap = "us";
i18n.defaultLocale = "en_US.UTF-8";
environment.systemPackages = with pkgs;
let
py3-packages = python-packages: with python-packages; [
flask
];
py3-with-packages = python3.withPackages py3-packages;
in [
wget vim curl git htop bash tmux psmisc man-pages pv lsof
zip unzip
py3-with-packages
usbutils
hdparm sdparm smartmontools gptfdisk gnufdisk
dosfstools
mkpasswd samba
tinc_pre
#file-rename
rsync
rclone gnupg
environment.systemPackages = with pkgs; [
lsof # list open files
mkpasswd # used for setting SMB passwords, I think?
samba # provides smbpasswd, mostly
smartmontools # provides smartctl
usbutils # provides lsusb
];
networking = {
hostName = "catacomb";
hostId = "beeeeee5";
hostId = "beeeeee5"; # this must be consistent for ZFS
firewall = {
enable = true;
allowPing = true;
allowedTCPPorts = [ 22 139 445 ];
allowedTCPPorts = [ 139 445 ];
allowedUDPPorts = [ 137 138 ];
};
};
@ -72,15 +58,7 @@ in {
];
};
services.openssh = {
enable = true;
passwordAuthentication = true;
};
services.ntp = {
enable = true;
servers = ["time.nist.gov"];
};
services.openssh.settings.PasswordAuthentication = true;
services.rsyncd.enable = true;
@ -162,22 +140,6 @@ in {
};
};
services.nebula.networks.beatific = lib.recursiveUpdate beatific.nebula-defaults {
enable = true;
# Network certificate and host credentials
ca = "/etc/nebula/beatific/beatific.crt";
cert = "/etc/nebula/beatific/catacomb.crt";
key = "/etc/nebula/beatific/catacomb.key";
# Connect to the lighthouse at empyrean
# Note that this is a VPN address, not a public address
lighthouses = [ beatific.empyrean-vpn-ip ];
# Map the lighthouse address to its public address
staticHostMap = beatific.empyrean-host-map;
};
services.zfs = {
autoScrub = {
enable = true;
@ -191,19 +153,14 @@ in {
};
users.users.tvb = {
isNormalUser = true;
uid = 1001;
password = "badpassword";
extraGroups = ["wheel" "nas"];
openssh.authorizedKeys.keyFiles = [
../../keys/tvb.palamas.pub
../../keys/tvb.stagirite.pub
../../keys/tvb.vagrant.pub
../../keys/monitor.isidore.pub
../../keys/inquisitor.conduit.pub
extraGroups = [ "nas" ];
packages = [
(pkgs.writeShellScriptBin "yt-dlp" ''
exec $HOME/.env/bin/yt-dlp "$@"
'')
];
};
#./keys/tvb.empyrean.pub
users.users.katydid = {
isNormalUser = true;
@ -211,5 +168,4 @@ in {
};
nix.settings.cores = 4;
nix.extraOptions = "experimental-features = nix-command flakes";
}

View File

@ -6,7 +6,7 @@ let
catacombServerSource = builtins.fetchGit {
url = "https://git.alogoulogoi.com/Jaculabilis/catacomb-server.git";
ref = "develop-nix";
rev = "63574bb39cc777deb56a76548f08789d238fcfec";
rev = "3d6fb16948c377f94d030648849f120c8ada3884";
};
catacombServer = pkgs.callPackage catacombServerSource {};

View File

@ -18,6 +18,11 @@
fsType = "ext4";
};
fileSystems."/backup" =
{ device = "catapool/backup";
fsType = "zfs";
};
fileSystems."/home/katydid" =
{ device = "catapool/user/katydid";
fsType = "zfs";
@ -28,41 +33,6 @@
fsType = "zfs";
};
fileSystems."/backup" =
{ device = "catapool/backup";
fsType = "zfs";
};
fileSystems."/home/katydid/audio" =
{ device = "catapool/user/katydid/audio";
fsType = "zfs";
};
fileSystems."/home/katydid/doc" =
{ device = "catapool/user/katydid/doc";
fsType = "zfs";
};
fileSystems."/home/katydid/image" =
{ device = "catapool/user/katydid/image";
fsType = "zfs";
};
fileSystems."/home/katydid/video" =
{ device = "catapool/user/katydid/video";
fsType = "zfs";
};
fileSystems."/nas/video" =
{ device = "catapool/nas/video";
fsType = "zfs";
};
fileSystems."/nas/doc" =
{ device = "catapool/nas/doc";
fsType = "zfs";
};
fileSystems."/nas/image" =
{ device = "catapool/nas/image";
fsType = "zfs";
@ -73,11 +43,21 @@
fsType = "zfs";
};
fileSystems."/nas/doc" =
{ device = "catapool/nas/doc";
fsType = "zfs";
};
fileSystems."/nas/game" =
{ device = "catapool/nas/game";
fsType = "zfs";
};
fileSystems."/nas/video" =
{ device = "catapool/nas/video";
fsType = "zfs";
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking

View File

@ -0,0 +1,22 @@
{ ... }:
{
# Configure nginx to serve /nas/doc/website/mirror/
services.nginx = {
enable = true;
virtualHosts."mirror.catacomb.home" = {
listen = [
{ addr = "10.22.20.2"; }
# Binding to 10.22.20.2:80 here confuses the empyrean revproxy, even when the revproxy
# is configured with the same hostname, and it serves from fileserver.nix instead.
# This nonstandard port supports the revproxy use case.
{ addr = "10.22.20.2"; port = 7474; }
];
root = "/nas/doc/website/mirror";
};
};
networking.firewall.allowedTCPPorts = [ 7474 ];
users.users.nginx.extraGroups = ["nas"];
}

View File

@ -0,0 +1,95 @@
{ pkgs, ... }:
{
imports = [
./hardware-configuration.nix
];
boot.loader.grub = {
efiSupport = true;
efiInstallAsRemovable = true;
device = "nodev";
};
beatific.hostName = "centroid";
beatific.defaults = {
tvbSync = false;
};
networking.networkmanager.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
# To avoid needing an active user session, run a single system instance
systemWide = true;
};
environment.systemPackages = with pkgs; [
mpv # cli media player
];
users.users.tvb.extraGroups = [
"mopidy"
"networkmanager"
"pipewire"
];
users.groups.mopidy = {}; # rw group for media directory
users.users.mopidy.extraGroups = [
"mopidy"
"pipewire" # necessary to allow the system service to play sound
];
services.mopidy = let
mopidy-ytdlp = pkgs.callPackage ./mopidy-youtube.nix { };
in {
enable = true;
extensionPackages = with pkgs; [
mopidy-jellyfin
mopidy-musicbox-webclient
# Replace the default mopidy-youtube, which doesn't have yt-dlp or a way to inject it
mopidy-ytdlp
];
configuration = ''
[file]
media_dirs =
/media/music|Music
[jellyfin]
hostname = jellyfin.backyard.lan
username = mopidy
password = mopidy
libraries = Music,Weird Song Halftime
album_format = {Name} ({ProductionYear})
[youtube]
youtube_dl_package = yt_dlp
'';
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
default = {
default = true;
locations."/".return = "444";
};
"mopidy.home.ktvb.site" = {
listen = [
{ addr = "10.22.20.7"; }
{ addr = "centroid.lan"; }
];
locations."/" = {
proxyWebsockets = true;
proxyPass = "http://localhost:6680";
};
};
};
};
networking.firewall.allowedTCPPorts = [ 80 ];
system.stateVersion = "23.11";
}

View File

@ -0,0 +1,40 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/a08e9b3c-8ac7-433e-bf2c-6da234a2fb4a";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/5D60-DD0E";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/6dce2950-f8dd-49eb-b4d3-fdcf06cf920b"; }
];
# 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.eno1.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp0s20f0u1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -0,0 +1,58 @@
{ lib
, fetchFromGitHub
, python3
, mopidy
}:
python3.pkgs.buildPythonApplication rec {
pname = "mopidy-youtube";
version = "3.6";
format = "setuptools";
src = fetchFromGitHub {
owner = "natumbri";
repo = pname;
rev = "refs/tags/v${version}";
hash = "sha256-Mp8eCVNGokJRwmYiZYCYRwV1QVDV02Uqfh6fGcPgJss=";
};
propagatedBuildInputs = with python3.pkgs; [
beautifulsoup4
cachetools
pykka
requests
youtube-dl # this no longer works
yt-dlp # <- added
ytmusicapi
] ++ [
mopidy
];
nativeCheckInputs = with python3.pkgs; [
vcrpy
pytestCheckHook
];
disabledTests = [
# Test requires a YouTube API key
"test_get_default_config"
];
disabledTestPaths = [
# Disable tests which interact with Youtube
"tests/test_api.py"
"tests/test_backend.py"
"tests/test_youtube.py"
];
pythonImportsCheck = [
"mopidy_youtube"
];
meta = with lib; {
description = "Mopidy extension for playing music from YouTube";
homepage = "https://github.com/natumbri/mopidy-youtube";
license = licenses.asl20;
maintainers = with maintainers; [ ];
};
}

View File

@ -9,16 +9,18 @@
[ # Include the results of the hardware scan.
./hardware-configuration.nix
#./amanuensis.nix
#./redstring.nix
./catacomb.nix
./gitea.nix
./inquisitor.nix
./sync-pipeline.nix
];
beatific.hostName = "empyrean";
beatific.isLighthouse = true;
beatific.defaults.tvbSync = true;
# Use the GRUB 2 boot loader.
boot.loader.grub = {
enable = true;
version = 2;
device = "/dev/xvda";
extraConfig = "serial --unit=0 --speed=115200 ; terminal_input serial console ; terminal_output serial console";
};
@ -27,42 +29,20 @@
nix = {
package = pkgs.nixFlakes;
settings.max-jobs = 2;
extraOptions = ''
experimental-features = nix-command flakes
'';
};
swapDevices = [ { device = "/swap"; size = 1024; } ];
networking.hostName = "empyrean";
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
# Per-interface useDHCP will be mandatory in the future, so this generated config
# replicates the default behaviour.
networking.useDHCP = false;
networking.interfaces.eth0.useDHCP = true;
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
console = {
font = "Lat2-Terminus16";
keyMap = "us";
};
# Set your time zone.
time.timeZone = "UTC";
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
vim htop git tinc_pre python3
tinc_pre
gitea
];
environment.variables.EDITOR = "vim";
services.nginx = let
static-site = srv-dir: {
@ -74,26 +54,36 @@
index index.html;
'';
};
service-stub = {
rejectSSL = true;
locations."/".return = "403";
};
in {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
# Static pages
"home.ktvb.site" = static-site "home.ktvb.site";
"wedding.ktvb.site" = static-site "wedding.ktvb.site";
"www.ktvb.site" = static-site "www.ktvb.site";
"mirror.alogoulogoi.com" = static-site "mirror.alogoulogoi.com";
"www.alogoulogoi.com" = static-site "www";
newtab = {
listen = [ { addr = "10.22.20.1"; port = 80; } ];
root = "/srv/newtab/";
"www.alogoulogoi.com" = static-site "www.alogoulogoi.com";
"ecumene.alogoulogoi.com" = static-site "ecumene.alogoulogoi.com";
# Home service stub domains
"mopidy.home.ktvb.site" = service-stub;
"jellyfin.home.ktvb.site" = service-stub;
# mirror revproxy
"mirror.alogoulogoi.com" = {
enableACME = true;
forceSSL = true;
extraConfig = ''
access_log /var/log/nginx/access_newtab.log;
index index.html;
access_log /var/log/nginx/access_mirror.alogoulogoi.com.log;
'';
locations."/".proxyPass = "http://mirror.catacomb.home:7474/";
};
# Deny all other subdomains
"alogoulogoi.com" = {
default = true;
rejectSSL = true;
locations."/".return = "444";
};
};
@ -103,20 +93,9 @@
acceptTerms = true;
};
services.gitolite = {
enable = true;
adminPubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDkSvOcY0eFuYqewc73MNHGP/Owzfnt+BZDSOCwr4h+gJenOBmXol695sRKdIw8phgshb6LsNyWeEAr3YISwzjdOvWNKpSsdyH/79VFIffC+/RBhPFhIPHn1zpHIwgthXji8FMmnO6B1bhJvbJxD5bUqhdBLnUeMhNgUkDj4Qi42S8yK1VZkgWRuPOTGqlzkODEdzG6OST7ndL58jEQaK8R2KRC2cZfrjingmPL+ORyf1/lGwyF6MEAmbQuE6UdspMs8FWt2e8jQJS+ZQ8dl+NDFrC1QfPRFpBJWnQceBcfAVZTtDaJpRhc4ClZstBy/bVRjiKeQiNv5NasjKRvvIvot4+LXmBKrXJs81enExtMSHMPuqPRlyVZLMMCVmdLDP/HUYOASDzlUhV/v5Wp0jjY4Wy0IWC7nm7P8EKsp1ZofwU6rJ9XPLpQJt7UUURX71h1FMaqi+lylW6xkD3LqD8oT5Bdp+Vs0bUbPQVRw1Fenjc6G1URU94GOAggyNgsWms= root@empyrean";
};
services.ntp = {
enable = true;
servers = ["time.nist.gov"];
};
services.openssh = {
enable = true;
passwordAuthentication = false;
permitRootLogin = "prohibit-password";
settings.PasswordAuthentication = false;
settings.PermitRootLogin = "prohibit-password";
};
services.tinc.networks.beatific = {
@ -124,36 +103,15 @@
chroot = false;
};
services.nebula.networks.beatific = {
enable = true;
# Network certificate and host credentials
ca = "/etc/nebula/beatific/beatific.crt";
cert = "/etc/nebula/beatific/empyrean.crt";
key = "/etc/nebula/beatific/empyrean.key";
# This host has a well-known IP at its VPS host, so it can function as a lighthouse/entry node
isLighthouse = true;
# Listen to connection requests from the public Internet
listen.port = 4242;
listen.host = "vpn.alogoulogoi.com";
# Don't filter anything at the VPN level
firewall.outbound = [ { port = "any"; proto = "any"; host = "any"; } ];
firewall.inbound = [ { port = "any"; proto = "any"; host = "any"; } ];
settings = {
# Enable UDP holepunching both ways, which allows nodes to establish more direct connections with each other
punchy = { punch = true; response = true; };
};
services.intake = {
listen = { addr = "10.22.20.1"; };
users.tvb.enable = true;
users.tvb.extraPackages = [ pkgs.intakeSources pkgs.openssh ];
};
networking.firewall = {
enable = true;
allowPing = true;
allowedTCPPorts = [
22 # ssh
80 # http
443 # https
655 # tinc
@ -163,50 +121,13 @@
];
};
users.users.tvb = {
isNormalUser = true;
group = "tvb";
extraGroups = [ "wheel" ]; # Enable sudo for the user.
openssh.authorizedKeys.keyFiles = [
../../keys/tvb.palamas.pub
../../keys/tvb.stagirite.pub
];
};
users.groups.tvb = {};
/*
users.users.guestbook = let
sign-guestbook = pkgs.writeShellScriptBin "sign-guestbook" ''
echo "Hello world!"
''
# Hack the shell path in since writeShellScriptBin doesn't take passthru
// { shellPath = "/bin/sign-guestbook"; };
in {
group = "guestbook";
password = "";
description = "Guestbook login";
shell = sign-guestbook;
isNormalUser = true;
createHome = false;
home = "/var/empty";
useDefaultShell = false;
};
users.groups.guestbook = {};
services.openssh.extraConfig = ''
Match user guestbook
PasswordAuthentication yes
PermitEmptyPasswords yes
Match all
PasswordAuthentication no
'';*/
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "20.03"; # Did you read the comment?
system.stateVersion = "23.05"; # Did you read the comment?
}

View File

@ -5,12 +5,7 @@
{
# Gitea configuration
services.gitea = {
# Enable Gitea and configure for reverse proxy
enable = true;
httpAddress = "127.0.0.1";
httpPort = 3300;
domain = "git.alogoulogoi.com";
rootUrl = "https://git.alogoulogoi.com/";
#useWizard = true; # Needed for first-time building
@ -22,6 +17,13 @@
interval = "weekly";
};
settings = {
"server" = {
# Configuration for reverse proxy
ROOT_URL = "https://git.alogoulogoi.com/";
HTTP_ADDR = "127.0.0.1";
HTTP_PORT = 3300;
DOMAIN = "git.alogoulogoi.com";
};
"repository" = {
DEFAULT_PRIVATE = true;
};
@ -37,10 +39,13 @@
"security" = {
INSTALL_LOCK = true;
};
"session" = {
SESSION_LIFE_TIME = 86400 * 7; # 1 week
};
"picture" = {
DISABLE_GRAVATAR = true;
};
"cron.archive_cleanup".ENABLED = false;
#"cron.archive_cleanup".ENABLED = false; # TODO: figure out why this was enabled
"cron.sync_external_users".ENABLED = false;
log.LEVEL = "Info";
# Private server
@ -66,5 +71,8 @@
proxy_pass http://localhost:3300/;
'';
};
# Give tvb group access to gitea config
users.users.tvb.extraGroups = [ "gitea" ];
}

View File

@ -1,138 +0,0 @@
{pkgs, ...}:
let
# Import the inquisitor package and build it
inquisitorSource = pkgs.fetchFromGitHub {
owner = "Jaculabilis";
repo = "Inquisitor";
rev = "addcb4f1a56c878b58f2e1c38dfd485761b31306";
sha256 = "0jjl92nf1y40acdly1kls0mppcadvmgbfr6qwczxni1f1zphw3as";
};
inquisitor = pkgs.callPackage inquisitorSource { inherit pkgs; };
# Define the inquisitor data directory
inquisiDir = "/var/lib/inquisitor";
# Define an scp helper for executing in cron jobs
scp-helper = pkgs.writeShellScriptBin "scp-helper" ''
${pkgs.openssh}/bin/scp -i ${inquisiDir}/inquisitor.key -oStrictHostKeyChecking=no "$@"
'';
# Define the inquisitor service user
inquisitorUser = {
name = "inquisitor";
group = "inquisitor";
description = "Inquisitor service user";
isSystemUser = true;
shell = pkgs.bashInteractive;
packages = [ inquisitor pkgs.cron ];
};
# Create the inquisitor config file in the nix store, pointing to /var/lib/
inquisitorConfig = pkgs.writeTextFile {
name = "inquisitor.conf";
text = ''
DataPath = ${inquisiDir}/data/
SourcePath = ${inquisiDir}/sources/
CachePath = ${inquisiDir}/cache/
Verbose = false
LogFile = ${inquisiDir}/inquisitor.log
'';
};
# Create a setup script to ensure the service directory state
inquisitorSetup = pkgs.writeShellScriptBin "inquisitor-setup.sh" ''
# Ensure the service directory and the default source directory
${pkgs.coreutils}/bin/mkdir -p ${inquisiDir}/data/inquisitor/
${pkgs.coreutils}/bin/mkdir -p ${inquisiDir}/sources/
${pkgs.coreutils}/bin/mkdir -p ${inquisiDir}/cache/
if [ ! -f ${inquisiDir}/data/inquisitor/state ]; then
${pkgs.coreutils}/bin/echo "{}" > ${inquisiDir}/data/inquisitor/state
fi
# Ensure the service owns the folders
chown -R ${inquisitorUser.name} ${inquisiDir}
# Ensure the scp helper is present
if [ -f ${inquisiDir}/scp-helper ]; then
rm ${inquisiDir}/scp-helper
fi
ln -s -t ${inquisiDir} ${scp-helper}/bin/scp-helper
'';
# Create a run script for the server
inquisitorRun = pkgs.writeShellScriptBin "inquisitor-run.sh" ''
cd ${inquisiDir}
${inquisitor}/bin/gunicorn \
--bind=localhost:24133 \
--workers=4 \
--timeout 120 \
--log-level debug \
"inquisitor.app:wsgi()"
'';
# Create a wrapper to execute the cli as the service user
inquisitorWrapper = pkgs.writeShellScriptBin "inq" ''
sudo --user=inquisitor ${inquisitor}/bin/inquisitor "$@"
'';
in
{
users.users.inquisitor = inquisitorUser;
users.groups.inquisitor = {};
# Link the config in /etc to avoid envvar shenanigans
environment.etc."inquisitor.conf".source = "${inquisitorConfig}";
# Give all users the inq wrapper
environment.systemPackages = [ inquisitorWrapper ];
# Allow the sudo in the cli wrapper without password
security.sudo.extraRules = [{
commands = [{
command = "${inquisitor}/bin/inquisitor";
options = [ "NOPASSWD" ];
}];
runAs = "${inquisitorUser.name}";
groups = [ "users" ];
}];
# Run the setup script on activation
system.activationScripts.inquisitorSetup = "${inquisitorSetup}/bin/inquisitor-setup.sh";
# Set up the inquisitor service
systemd.services.inquisitor =
{
description = "Inquisitor server";
script = "${inquisitorRun}/bin/inquisitor-run.sh";
serviceConfig = {
User = "${inquisitorUser.name}";
Type = "simple";
};
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
enable = true;
};
# Set up nginx to reverse proxy from the beatific url to the inq server
services.nginx.enable = true;
services.nginx.virtualHosts.inquisitorHost = {
listen = [ { addr = "10.22.20.1"; port = 80; } ];
locations."/".extraConfig = ''
access_log /var/log/nginx/access.inquisitor.log;
proxy_buffering off;
proxy_pass http://localhost:24133/;
'';
};
# Allow nginx through the firewall
networking.firewall = {
allowedTCPPorts = [
80 # http
443 # https
];
};
# Enable cron, but don't set up any system cron jobs
# Inquisitor updates will be managed manually
services.cron.enable = true;
}

View File

@ -1,120 +0,0 @@
# redstring server module
{ pkgs, ... }:
let
# Import package
redstringSource = builtins.fetchGit {
url = "https://git.alogoulogoi.com/Jaculabilis/redstring.git";
ref = "master";
rev = "91dd353ad1d48118452a949b15e100b3035bf297";
};
redstring = pkgs.callPackage redstringSource {};
# Define the data directory
redstringDir = "/var/lib/redstring/";
redstringData = "${redstringDir}docs/";
# Define the service user
redstringUser = {
name = "redstring";
description = "redstring service user";
group = "redstring";
isSystemUser = true;
};
# Create the public server config file in the nix store
publicConfigAttrs = {
root = redstringData;
edit = false;
};
publicConfig = pkgs.writeTextFile { name = "redstring-config-external.json"; text = (builtins.toJSON publicConfigAttrs); };
# Create the private server config file in the nix store
privateConfig = pkgs.writeTextFile {
name = "redstring-config-internal.json";
text = (builtins.toJSON {
root = redstringData;
edit = true;
});
};
# Create a setup script to ensure the data directory exists
redstringSetup = pkgs.writeShellScriptBin "redstring-setup.sh" ''
# Ensure the service directory
${pkgs.coreutils}/bin/mkdir -p ${redstringData}
# Ensure ownership
chown -R ${redstringUser.name} ${redstringDir}
chmod 700 ${redstringDir}
'';
# Create a run script for the public server
publicRun = pkgs.writeShellScriptBin "redstring-run-external.sh" ''
cd ${redstringDir}
${redstring}/bin/gunicorn \
--bind=localhost:24144 \
--workers=3 \
--log-level debug \
--env REDSTRING_CONFIG=${publicConfig} \
"redstring.server:wsgi()"
'';
# Create a run script for the private server
privateRun = pkgs.writeShellScriptBin "redstring-run-internal.sh" ''
cd ${redstringDir};
${redstring}/bin/gunicorn \
--bind=10.7.3.1:24145 \
--workers=3 \
--log-level debug \
--env REDSTRING_CONFIG=${privateConfig} \
"redstring.server:wsgi()"
'';
in
{
users.users.redstring = redstringUser;
users.groups.redstring = {};
# Run the setup script on activation
system.activationScripts.redstringSetup = "${redstringSetup}/bin/redstring-setup.sh";
# Set up the public redstring service
systemd.services."redstring-public" =
{
description = "redstring public read-only server";
script = "${publicRun}/bin/redstring-run-external.sh";
serviceConfig = {
User = "${redstringUser.name}";
Type = "simple";
};
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
enable = true;
};
# Set up the private redstring service
systemd.services."redstring-private" =
{
description = "redstring private editable server";
script = "${privateRun}/bin/redstring-run-internal.sh";
serviceConfig = {
User = redstringUser.name;
Type = "simple";
};
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
enable = true;
};
# Configure nginx to forward to the public server at the docs subdomain
services.nginx.virtualHosts."docs.alogoulogoi.com" = {
enableACME = true;
forceSSL = true;
extraConfig = ''
access_log /var/log/nginx/access.docs.log;
'';
locations."/".proxyPass = "http://localhost:24144";
};
# Open the firewall to the private server's port
networking.firewall.allowedTCPPorts = [ 24145 ];
}

View File

@ -0,0 +1,75 @@
{ pkgs, ... }:
# exiftool config and script based on that of @numinit
let
# An exiftool config that adds the OriginTimestamp property containing the best guess for file creation time
exiftool-config = pkgs.writeText "exiftool.config" ''
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
OriginTimestamp => {
Desire => {
0 => 'CreateDate',
1 => 'DateTimeOriginal',
2 => 'FileModifyDate'
},
ValueConv => '$val[0] || $val[1] || $val[2] || undef',
PrintConv => '$self->ConvertDateTime($val)',
PrintConvInv => '$self->InverseDateTime($val)'
}
}
)
'';
# A tool to use `find` and `exiftool` to sort images into YMD folders
sibd = pkgs.writeShellScriptBin "sort-images-by-date" ''
set -euo pipefail
if [ $# -lt 3 ]; then
echo "Usage: $0 [prefix] [src] [dest] [exiftool args...]" >&2
exit 1
fi
prefix="$1"
src="$2"
dest="$3"
# Remove $1, $2, $3 from $@ so the remainder can be passed to exiftool
shift; shift; shift
# This find expression matches .jpg/.png modified 14+ days ago.
# The -not (-name -prune) expressions exclude directories from the results by name.
# The exiftool command will move matched files to $dest/$prefix/year/month/day/filename.ext.
# -config loads the config defined above, which adds the OriginTimestamp composite property
# -filename tells exiftool to move each file to a new filename, $OriginTimestamp
# -d defines how the timestamp will be converted to a string, which ends up handling the pathing
${pkgs.findutils}/bin/find $src \
-not \( -name FalseKnees -prune \) \
-not \( -name Background -prune \) \
-type f \
-mtime +14 \
\( -name "*.jpg" -or -name "*.png" \) \
-exec ${pkgs.exiftool}/bin/exiftool \
-config ${exiftool-config} \
-api largefilesupport=1 \
-progress \
-filename'<OriginTimestamp' \
-d "''${dest}/''${prefix}/%Y-%m-%d/%%f%%-c.%%le" \
"$@" \
{} +
'';
# Script for cron jobs that sends output to journalctl -t sync-pipeline
sibd-cron = prefix: src: dest: pkgs.writeShellScript "sibd-cron" ''
${pkgs.systemd}/bin/systemd-cat -t sync-pipeline ${sibd}/bin/sort-images-by-date ${prefix} ${src} ${dest}
'';
in {
environment.systemPackages = [ sibd ];
services.cron = {
enable = true;
systemCronJobs = [
"0 0 * * 1 tvb ${sibd-cron "nokia" "/home/tvb/phone-sync/DCIM" "/home/tvb/phone-sync/staging"}"
"0 0 * * 1 tvb ${sibd-cron "nokia" "/home/tvb/phone-sync/Pictures" "/home/tvb/phone-sync/staging"}"
];
};
}

View File

@ -0,0 +1,80 @@
{ config, pkgs, ... }:
{
imports =
[
./hardware-configuration.nix
];
beatific.hostName = "imperium";
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.networkmanager.enable = true;
time.timeZone = "America/Los_Angeles";
services.xserver = {
enable = true;
displayManager.gdm.enable = true;
desktopManager.gnome.enable = true;
# keyboard
layout = "us";
xkbVariant = "";
};
# Enable sound with pipewire.
sound.enable = true;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
# This seems to be sufficient to autodetect the printing functionality of HP OfficeJet 6950
services.printing.enable = true;
services.printing.drivers = [ pkgs.hplip ];
services.avahi = {
enable = true;
nssmdns = true;
openFirewall = true;
};
users.users.tvb = {
extraGroups = [ "networkmanager" ];
};
# Configs needed to run TF2 on integrated graphics
programs.steam.enable = true;
nixpkgs.config.allowUnfree = true;
services.xserver.videoDrivers = [ "i915" ];
hardware.opengl.enable = true;
hardware.opengl.driSupport32Bit = true;
beatific.extraPrograms = true;
environment.systemPackages = with pkgs; [
comic-mono
firefox
gnome.gnome-terminal
libreoffice
mpv
obsidian
unzip
];
networking.firewall = {
enable = false;
};
# This value governs how some stateful data, like databases, are handled
# across different versions of NixOS. This should not be changed to a new
# release unless the sysadmin has determined that no services would be
# adversely affected by changing this.
system.stateVersion = "23.11";
}

View File

@ -0,0 +1,40 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/75addc56-2a0d-431e-a0c5-f6ee0e370e61";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/610F-1EB7";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/cc464bb4-e1c8-46c0-adbb-ea1a3cfa5b03"; }
];
# 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.eno1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -16,9 +16,10 @@ in
startMenuLaunchers = false;
};
system.stateVersion = "21.11";
#system.stateVersion = "21.11";
networking.hostName = "stagirite";
beatific.defaults.tvbSync = false;
fileSystems.winssh = {
device = "C:/Users/tvb/.ssh";

View File

@ -0,0 +1,103 @@
{ config, pkgs, lib, ... }:
{
imports =
[
./hardware-configuration.nix
];
beatific.hostName = "unfolder";
beatific.extraPrograms = true;
# Bootloader.
boot.loader.grub = {
enable = true;
device = "/dev/sda";
};
networking.networkmanager.enable = true;
# Override time zone to PST
time.timeZone = "America/Los_Angeles";
# Enable Gnome because it has a virtual keyboard for tablet mode
services.xserver = {
enable = true;
displayManager.gdm.enable = true;
desktopManager.gnome.enable = true;
# keymap configuration
layout = "us";
xkbVariant = "";
};
# Enable sound with pipewire.
sound.enable = true;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
systemd.user.services.yoga-rotate = {
enable = false; # TODO
description = "ThinkPad Yoga display rotation";
#wantedBy = ["multi-user.target"];
wantedBy = [ "graphical-session.target" ];
#requires = ["display-manager.service"];
partOf = [ "graphical-session.target" ];
#after = ["display-manager.service"];
path = [ pkgs.gnome-randr ];
serviceConfig = {
#Type = "simple";
ExecStart = "${pkgs.python3}/bin/python /home/tvb/rotate.py";
#KillMode = "process";
#User = "tvb";
Restart = "on-failure";
RestartSec = 5;
};
#environment = {
# DISPLAY = ":0";
# XAUTHORITY = "/home/tvb/.Xauthority";
#};
};
users.users.tvb = {
extraGroups = [ "networkmanager" ];
packages = with pkgs; [
gnome-randr python3
];
};
nixpkgs.config.allowUnfree = true;
environment.systemPackages = with pkgs; [
comic-mono
firefox
gnome.gnome-terminal
libreoffice
obsidian
mpv
];
networking.firewall = {
enable = true;
};
# This seems to be sufficient to autodetect the printing functionality of HP OfficeJet 6950
services.printing.enable = true;
services.printing.drivers = [ pkgs.hplip ];
services.avahi = {
enable = true;
nssmdns = true;
openFirewall = true;
};
# This value governs how some stateful data, like databases, are handled
# across different versions of NixOS. This should not be changed to a new
# release unless the sysadmin has determined that no services would be
# adversely affected by changing this.
system.stateVersion = "22.11";
}

View File

@ -0,0 +1,34 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/3a4363d6-c437-45ab-9f35-6831eb4a2cd8";
fsType = "ext4";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/4a083b38-322e-4d35-9877-a8dc1cda21d5"; }
];
# 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.wlp4s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

46
modules/ascii.nix Normal file
View File

@ -0,0 +1,46 @@
{
beatific = ''
____ ______ _______ _____ ______ _____ ______ ./|,,/|
| _ \| ____| /\ |__ __|_ _| ____|_ _|/ ____/ < o o|
| |_) | |__ / \ | | | | | |__ | | | | <\ ( |
| _ <| __| / /\ \ | | | | | __| | | | | <\\ |\ |
| |_) | |____/ ____ \ | | _| |_| | _| |_| |___<\\\ |(__)
|____/|_____/_/ \_\|_| |_____|_| |_____|\_____|\\ |
'';
backyard = ''
____ ______ _ ____ __ _____ _____ ./|,,/|
| _ \ /\ / ____/| | / /\ \ / / /\ | __ \| __ \ < o o|
| |_) | / \ | | | |/ / \ \ / / / \ | |__) | | | |</ ( |
| _ < / /\ \| | | < \ V / / /\ \ | _ /| | | |// |\ |
| |_) / ____ | |____ | |\ \ | | / ____ \| | \ \| |__| |// |(__)
|____/_/ \_\_____\|_| \_\ |_|/_/ \_|_| \_|_____//// |
'';
catacomb = ''
______ _______ ______ ____ __ __ ____ ./|,,/|
/ ____/ /\ |__ __| /\ / ____// __ \| \ / | _ \ < o o|
| | / \ | | / \ | | | | | | . \/ . | |_) | ( |
| | / /\ \ | | / /\ \| | | | | | |\ /| | _ <\\ |\ |
| |____ / ____ \ | | / ____ | |__ _| |__| | | \/ | | |_) |\ |(__)
\_____/_/ \_\|_|/_/ \_\_____\\____/|_| |_|____/\\ |
'';
empyrean = ''
______ __ __ _______ _______ ______ _ _ ./|,,/|
| ____| \ / | __ \ \ / | __ \| ____| /\ | \ | | < o o|
| |__ | . \/ . | |__) \ \ / /| |__) | |__ / \ | \| |</ ( |
| __| | |\ /| | ___/ \ V / | _ /| __| / /\ \ | . ' |// |\ |
| |____| | \/ | | | | | | | \ \| |____ / ____ \| |\ |// |(__)
|______|_| |_|_| |_| |_| \_|______/_/ \_|_| \_|// |
'';
unfolder = ''
_ _ _ _ ______ ____ _ _____ ______ _____ ./|,,/|
| | | | \ | | ____|/ __ \| | | __ \| ____| __ \ < o o|
| | | | \| | |__ | | | | | | | | | |__ | |__) |\ ( |
| | | | . ' | __| | | | | | | | | | __| | _ /\\ |\ |
| |__| | |\ | | | |__| | |___| |__| | |____| | \ \\\ |(__)
\____/|_| \_|_| \____/|_____|_____/|______|_| <\_\\ |
'';
}

32
modules/bashrc Normal file
View File

@ -0,0 +1,32 @@
# Set the title bar to user@host: pwd
_TITLE_BAR="\u@\h: \w"
_SET_TITLE_BAR="\[\e]0;$_TITLE_BAR\a\]"
# Shorten $HOME to ~ in PWD
_pwd_home () {
if [[ "$PWD" =~ ^"$HOME"(/|$) ]]; then
echo "~${PWD#$HOME}"
else
echo $PWD
fi
}
# Shorten path dir names
_pwd () {
DIR=$(_pwd_home)
[ "$DIR" != "/" ] && [ "$DIR" != "~" ] && printf '%s/' $(dirname "$DIR" | tr / '\n' | cut -c-1)
printf "$(basename "$DIR")"
}
_DIR='$(_pwd)'
# Color codes
_GREEN="\[\033[32;1m\]"
_DIM="\[\e[32;2m\]"
_OLIVE="\[\e[33;2m\]"
_RESET="\[\e[0m\]"
_HOST=$(if [ -z "$SSH_CLIENT" ]; then echo $_DIM; else echo $_OLIVE; fi)
# Nested shell level
_SHLVL=$(printf '\$%.0s' $(seq 1 $SHLVL))
# SSH detection
_SSH='$([ ! -z "$SSH_CLIENT" ] && echo "=>")'
# Build prompt
export PS1="$_SET_TITLE_BAR$_DIM[\A \u@$_RESET$_HOST\h$_DIM:$_RESET$_GREEN$_DIR$_RESET$_DIM]$_SHLVL$_RESET "
export HISTCONTROL=ignoreboth

View File

@ -1,23 +1,252 @@
# Shared configuration values
{ config, lib, pkgs, ... }:
let
nebula-port = 4242;
empyrean-vpn-ip = "10.22.20.1";
empyrean-ext-dns = "vpn.alogoulogoi.com";
inherit (lib) mkDefault mkIf mkMerge mkOption mkOverride types;
cfg = config.beatific;
mkFlag = description: mkOption {
type = types.bool;
inherit description;
default = true;
};
in {
nebula-defaults = {
listen.port = nebula-port;
options = {
beatific = {
# The host name is reused for beatific-specific configuration.
# The bulk of common config is handled in beatific.defaults below, but
# having one option without a default ensures that the module cannot be
# imported accidentally.
hostName = mkOption {
type = types.str;
description = "Hostname";
};
# Don't filter at the VPN level
firewall.outbound = [ { port = "any"; proto = "any"; host = "any"; } ];
firewall.inbound = [ { port = "any"; proto = "any"; host = "any"; } ];
isLighthouse = mkOption {
type = types.bool;
description = "Whether this host is a Nebula lighthouse";
default = false;
};
settings = {
# Enable UDP holepunching both ways, which allows nodes to establish more direct connections with each other
punchy = { punch = true; response = true; };
extraPrograms = mkOption {
type = types.bool;
description = "Additional default programs";
default = false;
};
# Groups of related defaults can be disabled by flipping off the switches here:
# beatific.defaults.${category} = false;
# They default to true because the point is to do these things by default.
defaults = {
time = mkFlag "Default time zone and NTP";
i18n = mkFlag "Default locale settings";
programs = mkFlag "Default installed programs";
ssh = mkFlag "Default sshd settings";
nebula = mkFlag "Default beatific nebula settings";
tvb = mkFlag "Default tvb account";
tvbSync = mkFlag "Configure system syncthing for tvb";
hosts = mkFlag "Default 10.22.20.* DNS host entries";
};
};
};
inherit empyrean-vpn-ip;
empyrean-host-map = { ${empyrean-vpn-ip} = [ "${empyrean-ext-dns}:${toString nebula-port}" ]; };
}
config = mkMerge [
{
# Options to always set
networking.hostName = cfg.hostName;
nix.extraOptions = "experimental-features = nix-command flakes";
# Link /etc/nixos to the flake source
environment.etc.nixos.source = ./..;
environment.etc."bashrc.local".source = ./bashrc;
environment.shellAliases = {
# Shortcut for nixos-rebuild
nr = "sudo nixos-rebuild --fast --flake $HOME/nixos-configs";
# Always preserve mode, ownership, ts with copy
cp = "cp -rp";
xo = "xdg-open";
smv = "rsync -v --remove-source-files";
".." = "cd ..";
"..." = "cd ../..";
"...." = "cd ../../..";
"....." = "cd ../../../..";
};
security.sudo.extraRules = [{
users = [ "tvb" ];
commands = [ { command = "/run/current-system/sw/bin/nixos-rebuild"; options = [ "NOPASSWD" ]; } ];
}];
}
(mkIf cfg.defaults.time {
# mkDefault time zone to make it easy to configure it to non-UTC
time.timeZone = mkDefault "UTC";
services.ntp.enable = true;
services.ntp.servers = [ "time.nist.gov" ];
})
(mkIf cfg.defaults.i18n {
# en_US.UTF-8
i18n.defaultLocale = "en_US.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_US.UTF-8";
LC_IDENTIFICATION = "en_US.UTF-8";
LC_MEASUREMENT = "en_US.UTF-8";
LC_MONETARY = "en_US.UTF-8";
LC_NAME = "en_US.UTF-8";
LC_NUMERIC = "en_US.UTF-8";
LC_PAPER = "en_US.UTF-8";
LC_TELEPHONE = "en_US.UTF-8";
LC_TIME = "en_US.UTF-8";
};
})
(mkIf cfg.defaults.programs {
environment.systemPackages = with pkgs; [
bc # Terminal calculator
curl
duf
exiftool
file # File type inspector
htmlq # jq for html
jq # jq for json
nebula
psmisc # provides killall
python3
rsync
sqlite
tree # Directory tree view
unzip
vim
wget
zip
(writeShellScriptBin "clip" ''
${xclip}/bin/xclip -sel c < $1
'')
];
programs = {
git = {
enable = true;
config.init.defaultBranch = "master";
};
htop.enable = true;
};
# The nixpkgs default is "nano", so we go one priority higher
environment.variables.EDITOR = mkOverride 999 "vim";
})
(mkIf cfg.extraPrograms {
environment.systemPackages = with pkgs; [
calibre # provides ebook-convert
imagemagick # image convertion cli
puddletag # mp3 tag editor
tesseract # OCR engine
];
})
(mkIf cfg.defaults.ssh {
services.openssh.enable = true;
services.openssh.banner = let
ascii = import ./ascii.nix;
in ascii.${cfg.hostName} or ascii.beatific;
networking.firewall.allowPing = true;
networking.firewall.allowedTCPPorts = [ 22 ];
})
(mkIf cfg.defaults.nebula {
services.nebula.networks.beatific = let
empyreanExternalDns = "vpn.alogoulogoi.com";
empyreanInternalIp = "10.22.20.1";
nebulaPort = 4242;
in {
enable = true;
# The lighthouse only listens on the designated subdomain
listen.host = if cfg.isLighthouse then empyreanExternalDns else "0.0.0.0";
listen.port = nebulaPort;
# Standard certificate paths
ca = "/etc/nebula/beatific/beatific.crt";
cert = "/etc/nebula/beatific/${cfg.hostName}.crt";
key = "/etc/nebula/beatific/${cfg.hostName}.key";
isLighthouse = cfg.isLighthouse;
# Non-lighthouses connect to the lighthouse at empyrean
# This should be a VPN address in the static host map
lighthouses = mkIf (! cfg.isLighthouse) [ empyreanInternalIp ];
# Currently there is no VPN-level traffic filtering
firewall.outbound = [ { port = "any"; proto = "any"; host = "any"; } ];
firewall.inbound = [ { port = "any"; proto = "any"; host = "any"; } ];
# Map the lighthouse address to its public address
staticHostMap = { ${empyreanInternalIp} = [ "${empyreanExternalDns}:${toString nebulaPort}" ]; };
settings = {
# Enable UDP holepunching both ways, which allows nodes to establish more direct connections with each other
punchy = { punch = true; response = true; };
};
};
})
(mkIf cfg.defaults.tvb {
users.groups.tvb = {};
users.users.tvb = {
isNormalUser = true;
group = "tvb";
extraGroups = [ "wheel" ];
initialPassword = "password";
openssh.authorizedKeys.keyFiles = (import ../keys).tvb;
};
})
(mkIf cfg.defaults.tvbSync {
# I haven't gotten user services to work correctly yet,
# so for now, tvb monopolizes the system syncthing instance.
# Adding users in the future should probably involve multiple
# system services so as not to require login to sync.
services.syncthing = {
enable = true;
configDir = "/home/tvb/.config/syncthing";
# this doesn't prevent syncthing from putting sync points in other locations, it's just a default
# normally it would make sense to put it at ~ but see https://github.com/NixOS/nixpkgs/pull/273693
dataDir = "/home/tvb/.config/syncthing";
openDefaultPorts = true;
user = "tvb";
group = "tvb";
};
})
(mkIf cfg.defaults.hosts {
# Create *.home host entries for all the beatific members
networking.hosts = {
"10.22.20.1" = [
"empyrean.home"
];
"10.22.20.2" = [
"catacomb.home"
"mirror.catacomb.home"
];
"10.22.20.3" = [
"palamas.home"
];
"10.22.20.4" = [
"stagirite.home"
];
"10.22.20.5" = [
"vagrant.home"
];
"10.22.20.6" = [
"unfolder.home"
];
"10.22.20.7" = [
"centroid.home"
"mopidy.home.ktvb.site"
];
"10.22.20.8" = [
"backyard.home"
"jellyfin.home.ktvb.site"
];
"10.22.20.9" = [
"imperium.home"
];
};
})
];
}

722
modules/syncthings.nix Normal file
View File

@ -0,0 +1,722 @@
{ config, lib, options, pkgs, ... }:
with lib;
let
cfg = config.services.syncthing;
opt = options.services.syncthing;
defaultUser = "syncthing";
defaultGroup = defaultUser;
settingsFormat = pkgs.formats.json { };
cleanedConfig = converge (filterAttrsRecursive (_: v: v != null && v != {})) cfg.settings;
isUnixGui = (builtins.substring 0 1 cfg.guiAddress) == "/";
# Syncthing supports serving the GUI over Unix sockets. If that happens, the
# API is served over the Unix socket as well. This function returns the correct
# curl arguments for the address portion of the curl command for both network
# and Unix socket addresses.
curlAddressArgs = path: if isUnixGui
# if cfg.guiAddress is a unix socket, tell curl explicitly about it
# note that the dot in front of `${path}` is the hostname, which is
# required.
then "--unix-socket ${cfg.guiAddress} http://.${path}"
# no adjustements are needed if cfg.guiAddress is a network address
else "${cfg.guiAddress}${path}"
;
devices = mapAttrsToList (_: device: device // {
deviceID = device.id;
}) cfg.settings.devices;
folders = mapAttrsToList (_: folder: folder //
throwIf (folder?rescanInterval || folder?watch || folder?watchDelay) ''
The options services.syncthing.settings.folders.<name>.{rescanInterval,watch,watchDelay}
were removed. Please use, respectively, {rescanIntervalS,fsWatcherEnabled,fsWatcherDelayS} instead.
'' {
devices = map (device:
if builtins.isString device then
{ deviceId = cfg.settings.devices.${device}.id; }
else
device
) folder.devices;
}) (filterAttrs (_: folder:
folder.enable
) cfg.settings.folders);
jq = "${pkgs.jq}/bin/jq";
updateConfig = pkgs.writers.writeBash "merge-syncthing-config" (''
set -efu
# be careful not to leak secrets in the filesystem or in process listings
umask 0077
curl() {
# get the api key by parsing the config.xml
while
! ${pkgs.libxml2}/bin/xmllint \
--xpath 'string(configuration/gui/apikey)' \
${cfg.configDir}/config.xml \
>"$RUNTIME_DIRECTORY/api_key"
do sleep 1; done
(printf "X-API-Key: "; cat "$RUNTIME_DIRECTORY/api_key") >"$RUNTIME_DIRECTORY/headers"
${pkgs.curl}/bin/curl -sSLk -H "@$RUNTIME_DIRECTORY/headers" \
--retry 1000 --retry-delay 1 --retry-all-errors \
"$@"
}
'' +
/* Syncthing's rest API for the folders and devices is almost identical.
Hence we iterate them using lib.pipe and generate shell commands for both at
the sime time. */
(lib.pipe {
# The attributes below are the only ones that are different for devices /
# folders.
devs = {
new_conf_IDs = map (v: v.id) devices;
GET_IdAttrName = "deviceID";
override = cfg.overrideDevices;
conf = devices;
baseAddress = curlAddressArgs "/rest/config/devices";
};
dirs = {
new_conf_IDs = map (v: v.id) folders;
GET_IdAttrName = "id";
override = cfg.overrideFolders;
conf = folders;
baseAddress = curlAddressArgs "/rest/config/folders";
};
} [
# Now for each of these attributes, write the curl commands that are
# identical to both folders and devices.
(mapAttrs (conf_type: s:
# We iterate the `conf` list now, and run a curl -X POST command for each, that
# should update that device/folder only.
lib.pipe s.conf [
# Quoting https://docs.syncthing.net/rest/config.html:
#
# > PUT takes an array and POST a single object. In both cases if a
# given folder/device already exists, its replaced, otherwise a new
# one is added.
#
# What's not documented, is that using PUT will remove objects that
# don't exist in the array given. That's why we use here `POST`, and
# only if s.override == true then we DELETE the relevant folders
# afterwards.
(map (new_cfg: ''
curl -d ${lib.escapeShellArg (builtins.toJSON new_cfg)} -X POST ${s.baseAddress}
''))
(lib.concatStringsSep "\n")
]
/* If we need to override devices/folders, we iterate all currently configured
IDs, via another `curl -X GET`, and we delete all IDs that are not part of
the Nix configured list of IDs
*/
+ lib.optionalString s.override ''
stale_${conf_type}_ids="$(curl -X GET ${s.baseAddress} | ${jq} \
--argjson new_ids ${lib.escapeShellArg (builtins.toJSON s.new_conf_IDs)} \
--raw-output \
'[.[].${s.GET_IdAttrName}] - $new_ids | .[]'
)"
for id in ''${stale_${conf_type}_ids}; do
curl -X DELETE ${s.baseAddress}/$id
done
''
))
builtins.attrValues
(lib.concatStringsSep "\n")
]) +
/* Now we update the other settings defined in cleanedConfig which are not
"folders" or "devices". */
(lib.pipe cleanedConfig [
builtins.attrNames
(lib.subtractLists ["folders" "devices"])
(map (subOption: ''
curl -X PUT -d ${lib.escapeShellArg (builtins.toJSON cleanedConfig.${subOption})} ${curlAddressArgs "/rest/config/${subOption}"}
''))
(lib.concatStringsSep "\n")
]) + ''
# restart Syncthing if required
if curl ${curlAddressArgs "/rest/config/restart-required"} |
${jq} -e .requiresRestart > /dev/null; then
curl -X POST ${curlAddressArgs "/rest/system/restart"}
fi
'');
in {
###### interface
options = {
services.syncthing = {
enable = mkEnableOption
(lib.mdDoc "Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync");
cert = mkOption {
type = types.nullOr types.str;
default = null;
description = mdDoc ''
Path to the `cert.pem` file, which will be copied into Syncthing's
[configDir](#opt-services.syncthing.configDir).
'';
};
key = mkOption {
type = types.nullOr types.str;
default = null;
description = mdDoc ''
Path to the `key.pem` file, which will be copied into Syncthing's
[configDir](#opt-services.syncthing.configDir).
'';
};
overrideDevices = mkOption {
type = types.bool;
default = true;
description = mdDoc ''
Whether to delete the devices which are not configured via the
[devices](#opt-services.syncthing.settings.devices) option.
If set to `false`, devices added via the web
interface will persist and will have to be deleted manually.
'';
};
overrideFolders = mkOption {
type = types.bool;
default = true;
description = mdDoc ''
Whether to delete the folders which are not configured via the
[folders](#opt-services.syncthing.settings.folders) option.
If set to `false`, folders added via the web
interface will persist and will have to be deleted manually.
'';
};
settings = mkOption {
type = types.submodule {
freeformType = settingsFormat.type;
options = {
# global options
options = mkOption {
default = {};
description = mdDoc ''
The options element contains all other global configuration options
'';
type = types.submodule ({ name, ... }: {
freeformType = settingsFormat.type;
options = {
localAnnounceEnabled = mkOption {
type = types.nullOr types.bool;
default = null;
description = lib.mdDoc ''
Whether to send announcements to the local LAN, also use such announcements to find other devices.
'';
};
localAnnouncePort = mkOption {
type = types.nullOr types.int;
default = null;
description = lib.mdDoc ''
The port on which to listen and send IPv4 broadcast announcements to.
'';
};
relaysEnabled = mkOption {
type = types.nullOr types.bool;
default = null;
description = lib.mdDoc ''
When true, relays will be connected to and potentially used for device to device connections.
'';
};
urAccepted = mkOption {
type = types.nullOr types.int;
default = null;
description = lib.mdDoc ''
Whether the user has accepted to submit anonymous usage data.
The default, 0, mean the user has not made a choice, and Syncthing will ask at some point in the future.
"-1" means no, a number above zero means that that version of usage reporting has been accepted.
'';
};
limitBandwidthInLan = mkOption {
type = types.nullOr types.bool;
default = null;
description = lib.mdDoc ''
Whether to apply bandwidth limits to devices in the same broadcast domain as the local device.
'';
};
maxFolderConcurrency = mkOption {
type = types.nullOr types.int;
default = null;
description = lib.mdDoc ''
This option controls how many folders may concurrently be in I/O-intensive operations such as syncing or scanning.
The mechanism is described in detail in a [separate chapter](https://docs.syncthing.net/advanced/option-max-concurrency.html).
'';
};
};
});
};
# device settings
devices = mkOption {
default = {};
description = mdDoc ''
Peers/devices which Syncthing should communicate with.
Note that you can still add devices manually, but those changes
will be reverted on restart if [overrideDevices](#opt-services.syncthing.overrideDevices)
is enabled.
'';
example = {
bigbox = {
id = "7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU";
addresses = [ "tcp://192.168.0.10:51820" ];
};
};
type = types.attrsOf (types.submodule ({ name, ... }: {
freeformType = settingsFormat.type;
options = {
name = mkOption {
type = types.str;
default = name;
description = lib.mdDoc ''
The name of the device.
'';
};
id = mkOption {
type = types.str;
description = mdDoc ''
The device ID. See <https://docs.syncthing.net/dev/device-ids.html>.
'';
};
autoAcceptFolders = mkOption {
type = types.bool;
default = false;
description = mdDoc ''
Automatically create or share folders that this device advertises at the default path.
See <https://docs.syncthing.net/users/config.html?highlight=autoaccept#config-file-format>.
'';
};
};
}));
};
# folder settings
folders = mkOption {
default = {};
description = mdDoc ''
Folders which should be shared by Syncthing.
Note that you can still add folders manually, but those changes
will be reverted on restart if [overrideFolders](#opt-services.syncthing.overrideFolders)
is enabled.
'';
example = literalExpression ''
{
"/home/user/sync" = {
id = "syncme";
devices = [ "bigbox" ];
};
}
'';
type = types.attrsOf (types.submodule ({ name, ... }: {
freeformType = settingsFormat.type;
options = {
enable = mkOption {
type = types.bool;
default = true;
description = lib.mdDoc ''
Whether to share this folder.
This option is useful when you want to define all folders
in one place, but not every machine should share all folders.
'';
};
path = mkOption {
# TODO for release 23.05: allow relative paths again and set
# working directory to cfg.dataDir
type = types.str // {
check = x: types.str.check x && (substring 0 1 x == "/" || substring 0 2 x == "~/");
description = types.str.description + " starting with / or ~/";
};
default = name;
description = lib.mdDoc ''
The path to the folder which should be shared.
Only absolute paths (starting with `/`) and paths relative to
the [user](#opt-services.syncthing.user)'s home directory
(starting with `~/`) are allowed.
'';
};
id = mkOption {
type = types.str;
default = name;
description = lib.mdDoc ''
The ID of the folder. Must be the same on all devices.
'';
};
label = mkOption {
type = types.str;
default = name;
description = lib.mdDoc ''
The label of the folder.
'';
};
devices = mkOption {
type = types.listOf types.str;
default = [];
description = mdDoc ''
The devices this folder should be shared with. Each device must
be defined in the [devices](#opt-services.syncthing.settings.devices) option.
'';
};
versioning = mkOption {
default = null;
description = mdDoc ''
How to keep changed/deleted files with Syncthing.
There are 4 different types of versioning with different parameters.
See <https://docs.syncthing.net/users/versioning.html>.
'';
example = literalExpression ''
[
{
versioning = {
type = "simple";
params.keep = "10";
};
}
{
versioning = {
type = "trashcan";
params.cleanoutDays = "1000";
};
}
{
versioning = {
type = "staggered";
fsPath = "/syncthing/backup";
params = {
cleanInterval = "3600";
maxAge = "31536000";
};
};
}
{
versioning = {
type = "external";
params.versionsPath = pkgs.writers.writeBash "backup" '''
folderpath="$1"
filepath="$2"
rm -rf "$folderpath/$filepath"
''';
};
}
]
'';
type = with types; nullOr (submodule {
freeformType = settingsFormat.type;
options = {
type = mkOption {
type = enum [ "external" "simple" "staggered" "trashcan" ];
description = mdDoc ''
The type of versioning.
See <https://docs.syncthing.net/users/versioning.html>.
'';
};
};
});
};
copyOwnershipFromParent = mkOption {
type = types.bool;
default = false;
description = mdDoc ''
On Unix systems, tries to copy file/folder ownership from the parent directory (the directory its located in).
Requires running Syncthing as a privileged user, or granting it additional capabilities (e.g. CAP_CHOWN on Linux).
'';
};
};
}));
};
};
};
default = {};
description = mdDoc ''
Extra configuration options for Syncthing.
See <https://docs.syncthing.net/users/config.html>.
Note that this attribute set does not exactly match the documented
xml format. Instead, this is the format of the json rest api. There
are slight differences. For example, this xml:
```xml
<options>
<listenAddress>default</listenAddress>
<minHomeDiskFree unit="%">1</minHomeDiskFree>
</options>
```
corresponds to the json:
```json
{
options: {
listenAddresses = [
"default"
];
minHomeDiskFree = {
unit = "%";
value = 1;
};
};
}
```
'';
example = {
options.localAnnounceEnabled = false;
gui.theme = "black";
};
};
guiAddress = mkOption {
type = types.str;
default = "127.0.0.1:8384";
description = lib.mdDoc ''
The address to serve the web interface at.
'';
};
systemService = mkOption {
type = types.bool;
default = true;
description = lib.mdDoc ''
Whether to auto-launch Syncthing as a system service.
'';
};
user = mkOption {
type = types.str;
default = defaultUser;
example = "yourUser";
description = mdDoc ''
The user to run Syncthing as.
By default, a user named `${defaultUser}` will be created whose home
directory is [dataDir](#opt-services.syncthing.dataDir).
'';
};
group = mkOption {
type = types.str;
default = defaultGroup;
example = "yourGroup";
description = mdDoc ''
The group to run Syncthing under.
By default, a group named `${defaultGroup}` will be created.
'';
};
all_proxy = mkOption {
type = with types; nullOr str;
default = null;
example = "socks5://address.com:1234";
description = mdDoc ''
Overwrites the all_proxy environment variable for the Syncthing process to
the given value. This is normally used to let Syncthing connect
through a SOCKS5 proxy server.
See <https://docs.syncthing.net/users/proxying.html>.
'';
};
dataDir = mkOption {
type = types.path;
default = "/var/lib/syncthing";
example = "/home/yourUser";
description = lib.mdDoc ''
The path where synchronised directories will exist.
'';
};
configDir = let
cond = versionAtLeast config.system.stateVersion "19.03";
in mkOption {
type = types.path;
description = lib.mdDoc ''
The path where the settings and keys will exist.
'';
default = cfg.dataDir + optionalString cond "/.config/syncthing";
defaultText = literalMD ''
* if `stateVersion >= 19.03`:
config.${opt.dataDir} + "/.config/syncthing"
* otherwise:
config.${opt.dataDir}
'';
};
databaseDir = mkOption {
type = types.path;
description = lib.mdDoc ''
The directory containing the database and logs.
'';
default = cfg.configDir;
defaultText = literalExpression "config.${opt.configDir}";
};
extraFlags = mkOption {
type = types.listOf types.str;
default = [];
example = [ "--reset-deltas" ];
description = lib.mdDoc ''
Extra flags passed to the syncthing command in the service definition.
'';
};
openDefaultPorts = mkOption {
type = types.bool;
default = false;
example = true;
description = lib.mdDoc ''
Whether to open the default ports in the firewall: TCP/UDP 22000 for transfers
and UDP 21027 for discovery.
If multiple users are running Syncthing on this machine, you will need
to manually open a set of ports for each instance and leave this disabled.
Alternatively, if you are running only a single instance on this machine
using the default ports, enable this.
'';
};
package = mkOption {
type = types.package;
default = pkgs.syncthing;
defaultText = literalExpression "pkgs.syncthing";
description = lib.mdDoc ''
The Syncthing package to use.
'';
};
};
};
imports = [
(mkRemovedOptionModule [ "services" "syncthing" "useInotify" ] ''
This option was removed because Syncthing now has the inotify functionality included under the name "fswatcher".
It can be enabled on a per-folder basis through the web interface.
'')
(mkRenamedOptionModule [ "services" "syncthing" "extraOptions" ] [ "services" "syncthing" "settings" ])
(mkRenamedOptionModule [ "services" "syncthing" "folders" ] [ "services" "syncthing" "settings" "folders" ])
(mkRenamedOptionModule [ "services" "syncthing" "devices" ] [ "services" "syncthing" "settings" "devices" ])
(mkRenamedOptionModule [ "services" "syncthing" "options" ] [ "services" "syncthing" "settings" "options" ])
] ++ map (o:
mkRenamedOptionModule [ "services" "syncthing" "declarative" o ] [ "services" "syncthing" o ]
) [ "cert" "key" "devices" "folders" "overrideDevices" "overrideFolders" "extraOptions"];
###### implementation
config = mkIf cfg.enable {
networking.firewall = mkIf cfg.openDefaultPorts {
allowedTCPPorts = [ 22000 ];
allowedUDPPorts = [ 21027 22000 ];
};
systemd.packages = [ pkgs.syncthing ];
users.users = mkIf (cfg.systemService && cfg.user == defaultUser) {
${defaultUser} =
{ group = cfg.group;
home = cfg.dataDir;
createHome = true;
uid = config.ids.uids.syncthing;
description = "Syncthing daemon user";
};
};
users.groups = mkIf (cfg.systemService && cfg.group == defaultGroup) {
${defaultGroup}.gid =
config.ids.gids.syncthing;
};
systemd.services = {
# upstream reference:
# https://github.com/syncthing/syncthing/blob/main/etc/linux-systemd/system/syncthing%40.service
syncthing = mkIf cfg.systemService {
description = "Syncthing service";
after = [ "network.target" ];
environment = {
STNORESTART = "yes";
STNOUPGRADE = "yes";
inherit (cfg) all_proxy;
} // config.networking.proxy.envVars;
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Restart = "on-failure";
SuccessExitStatus = "3 4";
RestartForceExitStatus="3 4";
User = cfg.user;
Group = cfg.group;
ExecStartPre = mkIf (cfg.cert != null || cfg.key != null)
"+${pkgs.writers.writeBash "syncthing-copy-keys" ''
install -dm700 -o ${cfg.user} -g ${cfg.group} ${cfg.configDir}
${optionalString (cfg.cert != null) ''
install -Dm400 -o ${cfg.user} -g ${cfg.group} ${toString cfg.cert} ${cfg.configDir}/cert.pem
''}
${optionalString (cfg.key != null) ''
install -Dm400 -o ${cfg.user} -g ${cfg.group} ${toString cfg.key} ${cfg.configDir}/key.pem
''}
''}"
;
ExecStart = ''
${cfg.package}/bin/syncthing \
-no-browser \
-gui-address=${if isUnixGui then "unix://" else ""}${cfg.guiAddress} \
-config=${cfg.configDir} \
-data=${cfg.databaseDir} \
${escapeShellArgs cfg.extraFlags}
'';
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectControlGroups = true;
ProtectHostname = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
CapabilityBoundingSet = [
"~CAP_SYS_PTRACE" "~CAP_SYS_ADMIN"
"~CAP_SETGID" "~CAP_SETUID" "~CAP_SETPCAP"
"~CAP_SYS_TIME" "~CAP_KILL"
];
};
};
syncthing-init = mkIf (cleanedConfig != {}) {
description = "Syncthing configuration updater";
requisite = [ "syncthing.service" ];
after = [ "syncthing.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = cfg.user;
RemainAfterExit = true;
RuntimeDirectory = "syncthing-init";
Type = "oneshot";
ExecStart = updateConfig;
};
};
syncthing-resume = {
wantedBy = [ "suspend.target" ];
};
};
};
}