Compare commits

...

337 commits
invi ... master

Author SHA1 Message Date
Natsu Kagami baa3d1cd0d
Update youmubot 2024-11-10 23:13:35 +01:00
Natsu Kagami cd4a9807cb
Update nixpkgs 2024-11-04 18:23:59 +01:00
Natsu Kagami f98b48a5e3
Update nixpkgs 2024-11-01 16:27:41 +01:00
Natsu Kagami fc57e77340
Update zotero and add zoom 2024-11-01 16:27:37 +01:00
Natsu Kagami dc49540f8d
Update youmubot 2024-10-31 14:10:47 +01:00
Natsu Kagami c36f5f66b1
Move stuff to various S3 stores instead of local minio (#5)
Move most things to Cloudflare R2, whilst gotosocial goes to local.

Reviewed-on: #5
Co-authored-by: Natsu Kagami <nki@nkagami.me>
Co-committed-by: Natsu Kagami <nki@nkagami.me>
2024-10-31 13:04:58 +00:00
Natsu Kagami 8702656b24
Update gotosocial to 0.17.0 2024-10-19 20:06:00 +02:00
Natsu Kagami 02ea7e95b7
Update osu 2024-10-17 11:36:39 +02:00
Natsu Kagami 22d1dbebe6
Update youmubot 2024-10-13 22:41:50 +02:00
Natsu Kagami c14aab4a8f
Update phanpy and gts 2024-10-12 17:08:29 +02:00
Natsu Kagami d99d57f53e
Update nixpkgs-unstable, add scala to common 2024-10-10 17:01:14 +02:00
Natsu Kagami 267f135972
Enhance nx and nsh to support unstable and git nixpkgs 2024-10-10 16:59:52 +02:00
Natsu Kagami 600ba660c9
Add compatibility workarounds for 24.05 2024-10-09 11:47:29 +02:00
Natsu Kagami 55397974b4
Update conduit to v0.9 2024-10-07 22:53:57 +02:00
Natsu Kagami 2f7179e7d5
Update youmubot 2024-10-07 22:36:03 +02:00
Natsu Kagami 2c54a0a9a1
sway: only import menu prefix if we have plasma 2024-09-28 15:23:25 +02:00
Natsu Kagami 21947fd510
kitty: use themeFile instead of just theme 2024-09-28 15:05:23 +02:00
Natsu Kagami 097a0efd90
Update nixpkgs-unstable and home-manager 2024-09-28 15:03:51 +02:00
Natsu Kagami 5cc543c9db
Suspend then hibernate on lid switch 2024-09-28 14:25:10 +02:00
Natsu Kagami 6a1deaae36
Export XDG_MENU_PREFIX as plasma- in sway 2024-09-27 11:51:27 +02:00
Natsu Kagami 5af862a4ad
Move pls to fish.functions definition 2024-09-27 11:51:03 +02:00
Natsu Kagami a1bd5600a9
Disable avahi 2024-09-27 10:43:48 +02:00
Natsu Kagami a59fa31628
Update authentik 2024-09-25 09:33:40 +02:00
Natsu Kagami 81b549a670
Update nixpkgs 2024-09-24 14:28:04 +02:00
Natsu Kagami 17e66e339c
Create notifications for pls 2024-09-22 15:46:35 +02:00
Natsu Kagami 63c2616c0f
Update nixpkgs-unstable 2024-09-22 15:07:48 +02:00
Natsu Kagami bc5de8bc77
Update youmubot 2024-09-14 18:16:54 +02:00
Natsu Kagami 177f0f686e
Set timezone to just default 2024-09-14 15:58:13 +03:00
Natsu Kagami 4fe33b7e80
Use new vpn format 2024-09-14 15:58:13 +03:00
Natsu Kagami 5ecad94dcb
Update nixpkgs 2024-09-11 11:57:52 +02:00
Natsu Kagami 84fa06937c
Update youmubot 2024-08-24 23:50:19 +02:00
Natsu Kagami 08d0c7aea3
Enable gamemode 2024-08-24 23:22:08 +02:00
Natsu Kagami 5b85a94be7
Update crane 2024-08-19 17:53:03 +02:00
Natsu Kagami 40d325218f
Update nix-gaming 2024-08-19 17:36:28 +02:00
Natsu Kagami db7e115863
Update home manager 2024-08-19 17:34:33 +02:00
Natsu Kagami 59f9ae8d5b
Remove NUR 2024-08-19 17:28:08 +02:00
Natsu Kagami fbe19bac34
Update nixpkgs 2024-08-19 17:25:24 +02:00
Natsu Kagami bc4cfe7c69
Set up build farm (#3)
Reviewed-on: #3
Co-authored-by: Natsu Kagami <nki@nkagami.me>
Co-committed-by: Natsu Kagami <nki@nkagami.me>
2024-08-19 14:04:52 +00:00
Natsu Kagami 70ab3aa5b3
Update osu 2024-08-17 17:03:07 +02:00
Natsu Kagami 41f717c5be
Properly configure firewall to allow tinc to pass through 2024-08-16 15:02:25 +02:00
Natsu Kagami 9fecd353f8
Add nix cache implementation 2024-08-16 14:36:11 +02:00
Natsu Kagami f0807443fd
Resolve tinc hosts with subdomains too 2024-08-16 14:13:30 +02:00
Natsu Kagami b1db7229cd
Remove conflicting secrets config 2024-08-16 14:13:05 +02:00
Natsu Kagami f4c514baa6
Set up tinc for framework 2024-08-15 18:37:13 +02:00
Natsu Kagami 58a49a71a8
Get things to work 2024-08-15 18:11:33 +02:00
Natsu Kagami e8424a0d21
Update lix 2024-08-15 17:18:29 +02:00
Natsu Kagami 81d3c1dcd1
Update nixpkgs 2024-08-15 17:16:06 +02:00
Natsu Kagami 08111c8f13
Use stable kernel until mesa is fixed 2024-08-13 18:31:43 +02:00
Natsu Kagami 5d2f127bcc
Remove obsolete parameters 2024-08-13 18:31:43 +02:00
Natsu Kagami a490d5a5ef
Use nixpkgs swayfx 2024-08-13 18:31:43 +02:00
Natsu Kagami a5df4c0b58
Update authentik and phanpy 2024-08-12 15:53:47 +02:00
Natsu Kagami 73d9b5fb4e
Update nixpkgs and move postgresql 2024-08-12 15:21:11 +02:00
Natsu Kagami e772814eed
Clean up deprecated config 2024-08-07 14:52:11 +02:00
Natsu Kagami 7b53f1d945
Update youmubot 2024-08-07 14:30:39 +02:00
Natsu Kagami 167d1dddb8
Update youmubot 2024-08-05 13:44:55 +02:00
Natsu Kagami 472daa8e59
Migrate gitea 2024-08-05 13:31:59 +02:00
Natsu Kagami d18a5ca503
Update youmubot 2024-08-04 23:14:01 +02:00
Natsu Kagami f164a27290
Update nixpkgs 2024-08-04 22:50:17 +02:00
Natsu Kagami 0887487c29
Update osu 2024-08-04 22:49:04 +02:00
Natsu Kagami 0b2e4feebb
Update thunderbird to 128 2024-08-04 22:49:04 +02:00
Natsu Kagami 8ec79eac11
Update to address home-manager config changes 2024-08-02 18:35:31 +02:00
Natsu Kagami 07478138d9
Update to address nixpkgs depreations 2024-08-02 18:27:48 +02:00
Natsu Kagami 45e90570b7
Add power_profiles prompt to framework 2024-08-02 18:12:11 +02:00
Natsu Kagami 28080d31c0
Set up special indentation for crab 2024-07-29 17:07:15 +02:00
Natsu Kagami e82627e317
Update nixpkgs 2024-07-29 13:56:11 +02:00
Natsu Kagami 228db93202
Update nixpkgs and youmubot 2024-07-24 03:02:03 +02:00
Natsu Kagami fec7f40440
Add yoga to tinc 2024-07-23 18:27:08 +02:00
Natsu Kagami 38c7afa96f
Update nixpkgs 2024-07-22 20:03:03 +02:00
Natsu Kagami 581093ff78
Add hylo to tree-sitter 2024-07-22 17:37:20 +02:00
Natsu Kagami 9a11fd1b38
Update kak-tree-sitter to 1.1.2 2024-07-17 16:53:19 +02:00
Natsu Kagami 530a746260
Update nixpkgs, rbw patch no longer needed 2024-07-17 14:23:38 +02:00
Natsu Kagami 8bd64fbe79
Add rust-analyzer and marksman to kak-lsp 2024-07-15 21:24:50 +02:00
Natsu Kagami 0f2686f9a7
Add plugins to OBS 2024-07-15 00:43:15 +02:00
Natsu Kagami af7e118298
Update youmubot 2024-07-15 00:35:26 +02:00
Natsu Kagami 7018b23522
Update nixpkgs 2024-07-13 15:42:53 +02:00
Natsu Kagami bd2af0670d
Assign osu scheme handler 2024-07-13 02:54:31 +02:00
Natsu Kagami a3d59d71ec
Add bitwarden prompt 2024-07-11 16:40:40 +02:00
Natsu Kagami 58b72cbb8c
Use Lix 2024-07-11 16:35:11 +02:00
Natsu Kagami c488e5e05d
Simplify flake configuration 2024-07-11 16:26:10 +02:00
Natsu Kagami 59c25c883a
Enable kwallet as a secrets dbus module 2024-07-11 16:02:26 +02:00
Natsu Kagami 567542d665
Embed language servers inside kak-lsp's PATH 2024-07-10 22:20:08 +02:00
Natsu Kagami 30ba277d46
Set a default dns for ipv6 2024-07-10 22:20:08 +02:00
Natsu Kagami 2657e7f3fc
Disable wifi power_save on framework 2024-07-10 22:20:08 +02:00
Natsu Kagami 527c6ba4e5
Temporarily patch rbw 2024-07-10 22:20:08 +02:00
Natsu Kagami 3b9f2d3dec
Delete some unused stuff 2024-07-09 17:58:06 +02:00
Natsu Kagami 7f1f963d5e
Move gitea to forgejo 2024-07-03 20:41:25 +02:00
Natsu Kagami 9c64c4dca9
Update nixpkgs 2024-07-03 19:54:13 +02:00
Natsu Kagami c397c143e1
Add ltex-ls to latex 2024-07-03 19:48:25 +02:00
Natsu Kagami 27e1fcf99b
Add back hack-font for plasma 2024-07-02 15:37:04 +02:00
Natsu Kagami edf38dc4e1
Start premid without sandbox 2024-07-01 21:48:24 +02:00
Natsu Kagami 3affdb3174
Update postgresql to 16 on authentik 2024-06-25 23:08:53 +02:00
Natsu Kagami 41106623e8
Move sway startups to desktop files 2024-06-25 20:24:48 +02:00
Natsu Kagami 47b96aee71
Update phanpy 2024-06-25 19:52:34 +02:00
Natsu Kagami 5426a7c526
Update youmubot 2024-06-25 14:02:28 +02:00
Natsu Kagami c16efcf256
Set trusted users 2024-06-25 13:27:01 +02:00
Natsu Kagami c59b47c1ce
Fix texlab forward search 2024-06-23 17:57:48 +02:00
Natsu Kagami ea7e32973a
Update preferred apps to align more to plasma 2024-06-23 17:38:30 +02:00
Natsu Kagami 99b653229e
Move framework to unstable 2024-06-22 16:53:58 +02:00
Natsu Kagami 5f61631957
Patch in text-input for swayfx 2024-06-22 15:43:34 +02:00
Natsu Kagami 54264260ed
Use framework nixos hardware module 2024-06-22 15:43:34 +02:00
Natsu Kagami 15a74c324f
Add nerd font symbols 2024-06-22 15:43:34 +02:00
Natsu Kagami e7be048163
Update youmubot 2024-06-22 15:43:19 +02:00
Natsu Kagami 3bae764ff5
Update nixpkgs 2024-06-20 02:40:17 +02:00
Natsu Kagami f323e92b48
Do the same for systemd.extraCommands... 2024-06-18 10:25:28 +02:00
Natsu Kagami 506bcfb5e3
Set theme name to breeze 2024-06-17 19:33:51 +02:00
Natsu Kagami 690f939c71
sway: Keep default variables imported to systemd 2024-06-17 19:21:49 +02:00
Natsu Kagami 1c87a689e6
Update youmubot 2024-06-16 23:51:34 +02:00
Natsu Kagami 69200a098f
Update gotosocial to 0.16.0 2024-06-16 23:04:45 +02:00
Natsu Kagami 89fa620591
Update conduit to v0.8 2024-06-16 22:32:25 +02:00
Natsu Kagami 40bc313429
Remove workaround for 316784 2024-06-12 20:37:19 +02:00
Natsu Kagami f2dfe30ff3
Put icons into sway dirs 2024-06-11 23:42:57 +02:00
Natsu Kagami 0d4bf856c3
Put FontAwesome before emojis in monospace fonts 2024-06-11 23:40:46 +02:00
Natsu Kagami 5acc4d91a0
Update nixpkgs 2024-06-11 23:40:24 +02:00
Natsu Kagami 6e88c391f9
Use near-native writefreely module
... we can use the official one when nixOS/nixpkgs#319138 lands
2024-06-11 23:17:31 +02:00
Natsu Kagami 2326c903c0
Add elixir config for kak-lsp 2024-06-11 22:13:52 +02:00
Natsu Kagami cc7d62745c
Use native toml format instead of handrolling 2024-06-11 19:43:48 +02:00
Natsu Kagami 23c2436ab6
Update gts to 0.16.0-rc2 2024-06-11 19:21:20 +02:00
Natsu Kagami cbb496cb47
Import PATH into systemd environment for xdg-desktop-portals 2024-06-11 19:21:20 +02:00
Natsu Kagami c02946aba3
Add a simple wifi-indicator script 2024-06-09 18:45:03 +02:00
Natsu Kagami d0943fd8b4
Add Blobmoji fallback to default fonts 2024-06-09 18:44:23 +02:00
Natsu Kagami 7a3f3e1b8c
Update gts to 0.16 2024-06-08 18:06:19 +02:00
Natsu Kagami a42ca31aed
Merge branch 'master' into 24.05 2024-06-08 17:39:20 +02:00
Natsu Kagami f4c8297a55
Deploy kagami-do 2024-06-08 17:38:50 +02:00
Natsu Kagami c7cdc4ff5e
Keep GTK im module on sway 2024-06-08 17:01:10 +02:00
Natsu Kagami 97a162786f
Make portal windows float in sway 2024-06-07 22:45:25 +02:00
Natsu Kagami a6b28f8c05
Keep nixpkgs in nix channel list 2024-06-07 13:50:38 +02:00
Natsu Kagami 37a712e117
Update youmubot 2024-06-05 12:22:45 +02:00
Natsu Kagami b46da01895
Move yoga to plasma6 2024-06-04 10:58:24 +02:00
Natsu Kagami 3be0332f7c
Set ANKI_WAYLAND 2024-06-04 01:37:31 +02:00
Natsu Kagami 989c7e64c6
Add kontact 2024-06-04 01:35:29 +02:00
Natsu Kagami 0efe7f556a
Use pinentry-gnome3 for now for the caching 2024-06-03 23:49:10 +02:00
Natsu Kagami 1f14b6b02a
Rid of gnome-keyring 2024-06-03 23:38:09 +02:00
Natsu Kagami aa3524840c
Properly use breeze themes 2024-06-03 22:57:34 +02:00
Natsu Kagami fc9898a5ec
Change script to properly start plasma 2024-06-03 22:39:06 +02:00
Natsu Kagami 9f9c76d0d2
Remove references to qt5 2024-06-03 21:42:44 +02:00
Natsu Kagami 5d5609e5a9
Move to full kde :3 2024-06-03 21:42:14 +02:00
Natsu Kagami 2bbbf47ce2
Enable some kde specifics 2024-06-03 14:09:45 +02:00
Natsu Kagami 3b78843f34
Enable plasma6 2024-06-03 03:33:00 +02:00
Natsu Kagami 7d8d80c6a3
Update login script 2024-06-03 03:32:53 +02:00
Natsu Kagami 3ebdd014b8
Update mpd-mpris 2024-06-03 03:29:53 +02:00
Natsu Kagami b1316346b9
Properly set waybar and swayidle to only toggle on sway 2024-06-02 23:02:39 +02:00
Natsu Kagami 37d8642ed9
Clean up some secret management stuff 2024-06-02 18:03:23 +02:00
Natsu Kagami 74ad74af1f
Remove previously needed unstable references 2024-06-02 16:56:54 +02:00
Natsu Kagami db64c71a2a
Change supportedFilesystems to new syntax 2024-06-01 17:35:32 +02:00
Natsu Kagami f6044a11ba
Temporarily override kitty with 0.35 2024-06-01 17:34:26 +02:00
Natsu Kagami 2fe1f71699
Let nixpkgs.flake.setNixPath/nixpkgs.flake.setFlakeRegistry set nixpkgs references 2024-06-01 17:32:29 +02:00
Natsu Kagami eed4c25127
Update nixpkgs to final release 2024-06-01 17:29:45 +02:00
Natsu Kagami 4ab9afd9c3
Enable kde plasma browser integration 2024-06-01 17:25:45 +02:00
Natsu Kagami 445c3fcc4c
Update how we propagate the adwaita theme 2024-05-28 22:02:54 +02:00
Natsu Kagami 8eca740ad3
Enable swaync only on sway 2024-05-28 22:02:40 +02:00
Natsu Kagami 666478ad36
Use fcitx wayland best practice 2024-05-28 22:02:11 +02:00
Natsu Kagami 381520a013
Set home-manager to backup and override by default 2024-05-28 22:01:36 +02:00
Natsu Kagami 07179e77e8
Make a nice menu for switching 2024-05-28 22:01:08 +02:00
Natsu Kagami 5681d080e5
Remove eza input 2024-05-27 11:07:31 +02:00
Natsu Kagami fff8f3042a
Update to new nix-gaming release 2024-05-27 11:06:04 +02:00
Natsu Kagami 1cba13a2e8
Minimal changes to make 24.05 compile on framework 2024-05-27 11:03:15 +02:00
Natsu Kagami 7d19c95472
Temporarily disable virtualbox
Not yet compatible with kernel 6.9, see NixOS/nixpkgs#312336
2024-05-24 16:33:42 +02:00
Natsu Kagami ef5af56cb6
Kakoune: make number-lines highlighter belong to window scope as peneira expects 2024-05-24 16:33:21 +02:00
Natsu Kagami 08a7b1edb7
Update nixpkgs and such 2024-05-23 18:24:02 +02:00
Natsu Kagami 1624eacdf0
Update authentik 2024-05-22 23:03:33 +02:00
Natsu Kagami 51f06ac76c
Update dtth-phanpy 2024-05-21 18:35:12 +02:00
Natsu Kagami 6ae7ccf045
Revert back to using latest kakoune-lsp
We don't need metal-support patches anymore
2024-05-17 16:27:10 +02:00
Natsu Kagami c9a33982de
Update youmubot 2024-05-07 21:27:19 +02:00
Natsu Kagami 9d0116cc7d
Add hibernation to yoga 2024-05-07 19:30:13 +02:00
Natsu Kagami 5c9cde7f87
Revert timezone change 2024-05-07 08:24:49 -04:00
Natsu Kagami 5e8f6081f0
Update nixpkgs 2024-05-07 08:23:17 -04:00
Natsu Kagami feb61f5f41
Override my location 2024-04-26 17:06:05 -04:00
Natsu Kagami e17341a42f
Update pbcopy/paste 2024-04-26 13:16:10 -04:00
Natsu Kagami c7cc8f9516
Add AnyConnect useragent into openconnect-epfl script 2024-04-26 13:15:56 -04:00
Natsu Kagami c0dca78a74
Update dtth-phanpy 2024-04-25 20:10:35 +02:00
Natsu Kagami dd3063e6f1
Update conduit 2024-04-25 20:05:03 +02:00
Natsu Kagami b2263d1fe5
Update youmubot 2024-04-25 19:26:07 +02:00
Natsu Kagami 98d935e2d5
Update authentik to 2024.4.0 2024-04-25 19:01:10 +02:00
Natsu Kagami ee6bf03506
Set timezone 2024-04-25 12:00:58 -04:00
Natsu Kagami 580601ddd5
Add qtwayland to buildInputs of owncloud-client 2024-04-22 12:32:14 +02:00
Natsu Kagami e9e5a00308
Move back to thunderbird 2024-04-22 11:57:42 +02:00
Natsu Kagami 9d924cc9a9
Update nixpkgs 2024-04-20 02:50:34 +02:00
Natsu Kagami 8e3f767dd9
Fix configuration bug in peertube 2024-04-18 23:06:40 +02:00
Natsu Kagami fbcc19fc97
Add peertube-runner service to nki-home 2024-04-18 15:58:16 +02:00
Natsu Kagami 3e3a433bca
Universally add polkit 2024-04-18 14:56:52 +02:00
Natsu Kagami 94ce7860bb
Add /mnt/osu mount 2024-04-18 14:56:30 +02:00
Natsu Kagami c834fd0ef7
Update nixpkgs-unstable 2024-04-18 00:40:27 +02:00
Natsu Kagami ea5aacd63d
Update nixpkgs 2024-04-14 00:14:35 +02:00
Natsu Kagami 244cecb3ba
Update gts 2024-04-12 02:03:21 +02:00
Natsu Kagami fb1652d82b
Add templ support for kak 2024-04-07 17:38:13 +02:00
Natsu Kagami 91603a500d
Revamp kak-lsp config to use language-server 2024-04-06 23:56:46 +02:00
Natsu Kagami 526ed059db
Update home-manager 2024-04-05 17:50:19 +02:00
Natsu Kagami 99e7ec3143
Update kakoune 2024-04-05 17:49:26 +02:00
Natsu Kagami c74fe98853
Update gts and phanpy 2024-04-02 23:23:09 +02:00
Natsu Kagami 6f2dc57089
Merge branch 'peertube' 2024-04-02 23:15:15 +02:00
Natsu Kagami d9db52e92a
Use later gcc for vesktop 2024-04-02 22:55:30 +02:00
Natsu Kagami 9ac5fedc75
Update kak to add indentation guides 2024-03-30 14:48:55 +01:00
Natsu Kagami 53dec713ec
Disable swayidle 2024-03-30 14:19:14 +01:00
Natsu Kagami 908f74f121
Update nixpkgs 2024-03-30 14:17:55 +01:00
Natsu Kagami 9c376e38bc
Add peertube 2024-03-29 22:21:05 +01:00
Natsu Kagami be5237eeeb
Set up peertube 2024-03-16 15:35:12 +01:00
Natsu Kagami 662be5e96d
Update conduit-rs to latest next branch 2024-03-13 12:53:25 +01:00
Natsu Kagami ef304742ce
Update gotosocial to 0.14.2 2024-03-13 12:53:10 +01:00
Natsu Kagami a688ce8cef
Update nixpkgs 2024-03-13 12:29:47 +01:00
Natsu Kagami 36eebe0174
Update osu!lazer 2024-03-13 12:29:47 +01:00
Natsu Kagami b6b12df069
Detect vesktop correctly from sway 2024-03-13 12:29:47 +01:00
Natsu Kagami 45a27e64bc
Add markdown lsp 2024-03-11 15:00:09 +01:00
Natsu Kagami 857b7fc98a
Use latest vesktop 2024-03-11 14:59:57 +01:00
Natsu Kagami 7285080198
Update youmubot 2024-03-10 05:07:25 +01:00
Natsu Kagami 483c34e501
Update authentik 2024-03-10 05:02:44 +01:00
Natsu Kagami b836868109
Add nom package 2024-03-08 04:30:05 +01:00
Natsu Kagami 641fc6a51c
Add rebuild command with nom 2024-03-08 04:29:58 +01:00
Natsu Kagami 9319833752
Move kagamiPC to xanmod 2024-03-08 04:29:42 +01:00
Natsu Kagami ed5245630f
Update nixpkgs 2024-03-08 04:29:26 +01:00
Natsu Kagami 9d01f43bb0
Revert "Add osu!lazer wrapper"
This reverts commit d1a37d19d7.
2024-03-08 03:30:23 +01:00
Natsu Kagami edeca6408b
Update youmubot 2024-03-08 01:11:43 +01:00
Natsu Kagami 0fc02235e1
Update gotosocial to 0.14.0 2024-03-06 15:14:15 +01:00
Natsu Kagami 3ccaa71de6
Update dtth-phanpy 2024-03-06 13:54:53 +01:00
Natsu Kagami d1a37d19d7
Add osu!lazer wrapper 2024-03-06 13:05:16 +01:00
Natsu Kagami eafa4af3cf
Update youmubot 2024-03-06 01:57:06 +01:00
Natsu Kagami 5f5b966c76
Update gotosocial 2024-03-06 00:19:12 +01:00
Natsu Kagami 70107fbe4d
Update youmubot 2024-03-06 00:05:48 +01:00
Natsu Kagami a722647f27
Update nix-gaming 2024-03-06 00:02:26 +01:00
Natsu Kagami 9a51746ac2
Update osu!lazer 2024-03-02 20:33:44 +01:00
Natsu Kagami 151f5838b2
Update gts instance info 2024-03-01 13:54:08 +01:00
Natsu Kagami 6a35224cd8
Update gotosocial to 0.14.0-rc2 2024-03-01 13:32:53 +01:00
Natsu Kagami 052f372f67
Add yaml support to kak-tree-sitter 2024-03-01 13:08:39 +01:00
Natsu Kagami 1247233c36
Update kak-tree-sitter 2024-03-01 12:03:01 +01:00
Natsu Kagami 16f735f25b
Fix kakoune failing to compile
... and move its definition into overlay
2024-03-01 11:31:23 +01:00
Natsu Kagami 20c30726bb
Update kak-lsp/kakoune 2024-02-29 15:03:21 +01:00
Natsu Kagami c64a76b6b3
Move jdk stuff to common 2024-02-29 15:02:49 +01:00
Natsu Kagami 65aca5a3f5
Remove java awt options 2024-02-29 15:02:49 +01:00
Natsu Kagami 91f4e896a5
Update youmubot 2024-02-29 14:27:21 +01:00
Natsu Kagami 2d3ebab8dd
Use latest input-remapper 2024-02-23 19:02:41 +01:00
Natsu Kagami 2bbe9db98b
Update nixpkgs and such 2024-02-23 11:53:11 +01:00
Natsu Kagami db3c1acb2c
Update osu 2024-02-23 11:24:22 +01:00
Natsu Kagami 224974dd77
Move to youmubot serenity 0.12 2024-02-18 01:42:34 +01:00
Natsu Kagami d90650116e
Update gotosocial 2024-02-18 01:42:34 +01:00
Natsu Kagami 0c8a5e1368
Reorder typst root detection file list 2024-02-17 19:46:25 +01:00
Natsu Kagami 77baad5311
Update nixpkgs and such 2024-02-15 16:24:21 +01:00
Natsu Kagami c1badc0580
Update youmubot 2024-02-14 13:16:09 +01:00
Natsu Kagami efdad6975d
Temporarily deploy youmu on rosu-v2 branch 2024-02-14 01:47:23 +01:00
Natsu Kagami 23d22a3171
Update gts 2024-02-06 14:41:09 +01:00
Natsu Kagami cf2d7b0271
Use unstable premid 2024-02-06 14:30:02 +01:00
Natsu Kagami f4e00a834b
Add cp+ 2024-02-06 14:30:02 +01:00
Natsu Kagami aa7f5ba285
Update youmubot 2024-02-05 01:51:53 +01:00
Natsu Kagami 2888c0a300
framework: Enable hibernation and lock before doing it 2024-02-02 13:18:38 +01:00
Natsu Kagami cec9dd4d85
Update authentik 2024-02-02 01:11:33 +01:00
Natsu Kagami ea8a3fd15a
Update osu 2024-02-02 01:10:40 +01:00
Natsu Kagami 955e63b1e8
Update dtth-phanpy 2024-01-30 18:36:37 +01:00
Natsu Kagami 6c302bf948
Add qpwgraph to applications 2024-01-30 18:36:36 +01:00
Natsu Kagami d6c218859c
Disable plymouth as it's not bringing much joy 2024-01-29 13:27:27 +01:00
Natsu Kagami 9879ab0048
Use unstable logseq altogether 2024-01-29 13:27:15 +01:00
Natsu Kagami 65686fdf16
Set some stuff up for the framework 2024-01-28 15:08:20 +01:00
Natsu Kagami dccc3802d7
Add sensors package to dependencies 2024-01-28 14:46:35 +01:00
Natsu Kagami 43e97d65c4
Update authentik 2024-01-26 13:52:05 +01:00
Natsu Kagami 3cd23cce00
Change stateDir of gitea so we don't need a symlink 2024-01-26 13:51:58 +01:00
Natsu Kagami 97c065231b
Set conduit to correctly point to new mountpoint 2024-01-26 13:44:46 +01:00
Natsu Kagami 9c2dfd483b
Update nixpkgs and such 2024-01-26 10:39:25 +01:00
Natsu Kagami 38390db87c
Move sway init to first thing to do in fish 2024-01-25 23:38:11 +01:00
Natsu Kagami 1f38c3c29f
Set kakoune :new to open kitty os-window 2024-01-21 09:59:03 +01:00
Natsu Kagami 5cf73ba503
Mount stuff with compression enabled 2024-01-20 13:27:27 +01:00
Natsu Kagami bc0cea6575
Let bitwarden be floating 2024-01-20 12:45:59 +01:00
Natsu Kagami 08792154ed
Bind ^ to mail 2024-01-19 14:55:20 +01:00
Natsu Kagami ec89cef3a2
Set default shell to fish 2024-01-19 14:46:36 +01:00
Natsu Kagami 62c14ffd0d
Set up secure boot for framework and new SSD 2024-01-19 13:13:47 +01:00
Natsu Kagami 25ab9e9b70
Add framework 2024-01-19 11:37:19 +01:00
Natsu Kagami 099b6ffa28
Update nixpkgs and such 2024-01-19 11:31:58 +01:00
Natsu Kagami df3b2e7b00
Update osu-lazer 2024-01-17 11:21:02 +01:00
Natsu Kagami 0c0b3fb83d
Update gotosocial to 0.13.1 2024-01-17 11:20:19 +01:00
Natsu Kagami 8f82978e8d
Update osu-lazer 2023-12-30 19:56:01 +01:00
Natsu Kagami b79855b9b9
Update youmubot 2023-12-27 18:07:11 +01:00
Natsu Kagami ae97651a64
Update dtth-phanpy 2023-12-27 16:12:08 +01:00
Natsu Kagami cfce2aaecb
Set new users to auto-join DTTH space 2023-12-27 15:31:41 +01:00
Natsu Kagami 6109922b19
Use kak-lsp fork that doesn't kill nil 2023-12-26 19:53:26 +01:00
Natsu Kagami d4b9c4edfc
Add osu to x1c1 2023-12-26 15:54:43 +01:00
Natsu Kagami 308e4412ad
Update nixpkgs 2023-12-26 15:07:06 +01:00
Natsu Kagami 49a4c49e08
Make fwupd common 2023-12-26 14:18:25 +01:00
Natsu Kagami d1ce95aa08
Update nixpkgs 2023-12-26 14:18:25 +01:00
Natsu Kagami 4c491f359c
Replace rnix-lsp with nil 2023-12-10 01:59:12 +01:00
Natsu Kagami 61c02e0a02
Update kak-tree-sitter 2023-12-10 01:59:11 +01:00
Natsu Kagami 91a5ee5df5
Low latency for sdac 2023-12-08 01:14:08 +01:00
Natsu Kagami adf3aeadfa
Get latest osu 2023-12-06 21:22:04 +01:00
Natsu Kagami ef1c71b462
Remove thunderbird override from overlay 2023-12-05 21:22:51 +01:00
Natsu Kagami c89832abab
Update dtth-phanpy 2023-12-03 16:11:51 +01:00
Natsu Kagami 3e40481ddd
Use latest gts 2023-12-02 21:48:09 +01:00
Natsu Kagami 44305d6805
Remove old cruff, server is 23.11 now 2023-12-01 23:19:34 +01:00
Natsu Kagami 2d726f8c04
Move vesktop to its correct place 2023-12-01 22:28:23 +01:00
Natsu Kagami 32c9474e7e
Update to 23.11!! 2023-12-01 22:05:54 +01:00
Natsu Kagami fb9d120c37
Update youmubot 2023-11-26 16:23:23 +01:00
Natsu Kagami 058e62f921
Undo NIXOS_OZONE_WL as it fucks up IMEs 2023-11-26 15:49:15 +01:00
Natsu Kagami ea0180e420
Use vesktop 2023-11-26 15:49:15 +01:00
Natsu Kagami f0a983c52d
Set git to use fancy conflict style with 3-way diffs 2023-11-26 15:49:15 +01:00
Natsu Kagami 58034eb5b0
Use latest mesa 2023-11-26 15:49:09 +01:00
Natsu Kagami 947be2b7c7
Update nixos-m1 2023-11-25 18:58:39 +01:00
Natsu Kagami 31c59ca13d
Make bar slightly fancier 2023-11-25 18:58:38 +01:00
Natsu Kagami dd88bf11c8
Remove deploy action 2023-11-21 14:57:35 +01:00
Natsu Kagami 01903f3547
Update youmubot 2023-11-21 14:57:05 +01:00
Natsu Kagami 1e822b9fe9
Update bitwarden to 1.30 2023-11-21 14:34:14 +01:00
Natsu Kagami 35d27c09c2
Enable avahi 2023-11-21 13:28:19 +01:00
Natsu Kagami f96e48e3b4
Revert the kak-lsp broken config 2023-11-21 13:20:35 +01:00
Natsu Kagami feca54585c
Use programs.fish.enable 2023-11-20 21:26:11 +01:00
Natsu Kagami cedbbeafb5
Update kakoune and kak-lsp 2023-11-20 11:46:13 +01:00
Natsu Kagami a7104c6197
Slight changes in taste for macnix 2023-11-18 16:07:43 +01:00
Natsu Kagami 066344ec2f
Update nixpkgs 2023-11-16 16:02:37 +01:00
Natsu Kagami 0ce6c530cd
Enable all ozone stuff on sway 2023-11-16 16:02:31 +01:00
Natsu Kagami 7f0d5b0da1
More youmu debugging 2023-11-16 01:33:06 +01:00
Natsu Kagami c6518aae2f
Use youmu debug 2023-11-16 01:03:46 +01:00
Natsu Kagami 37b780ba72
Increase emoji size limits in GtS 2023-11-13 22:38:56 +01:00
Natsu Kagami 4f32f04d6b
Fix crashing logseq for now 2023-11-09 13:29:12 +01:00
Natsu Kagami a268436f68
test -f is not enough 2023-11-08 20:56:42 +01:00
Natsu Kagami 536eec198a
Move tide variables to a specific file 2023-11-08 14:48:03 +01:00
Natsu Kagami 93d9e820db
Redo tide configuration 2023-11-08 12:47:29 +01:00
Natsu Kagami 237e6afa33
Add easyeffects 2023-11-08 11:50:57 +01:00
Natsu Kagami 33cf7ed435
Mount Projects on boot 2023-11-08 11:50:46 +01:00
Natsu Kagami caf6677f71
Update tide 2023-11-08 11:50:34 +01:00
Natsu Kagami 7a100e241b
Add x-scheme-handler/file handler 2023-11-07 23:23:31 +01:00
Natsu Kagami fde3ba411d
Add gajim 2023-11-07 16:08:43 +01:00
Natsu Kagami 2693126dca
Upgrade conduit from 0.6 to next 2023-11-07 13:48:55 +01:00
Natsu Kagami 7d71caa8db
Mount font folders to make flatpaks not cry 2023-11-06 13:09:12 +01:00
Natsu Kagami 1f10e0e943
Update nixpkgs and change GUI app set 2023-11-05 13:15:35 +01:00
Natsu Kagami 0233a84edc
Add explicit vaultwarden version 2023-11-05 13:14:27 +01:00
Natsu Kagami f155382789
Make nix config evaluate on m1 2023-11-05 13:09:34 +01:00
Natsu Kagami cfc752a3db
Make some packages unavailble on aarch64 2023-10-27 11:30:44 +02:00
Natsu Kagami b33f843d42
Update nixos-m1 2023-10-27 11:26:59 +02:00
Natsu Kagami 43bcb4721b
Update gts to 0.12.1 2023-10-27 11:26:21 +02:00
Natsu Kagami 92cc5096cb
Update nixpkgs 2023-10-25 21:37:01 +02:00
Natsu Kagami d89a084d56
Use newer jdk 2023-10-25 14:21:52 +02:00
Natsu Kagami a32c24a376
Update gts to 0.12.0 2023-10-23 16:38:32 +02:00
Natsu Kagami b173c6a874
Use wine 32-on-64 2023-10-23 16:21:07 +02:00
Natsu Kagami c92779eb96
Update youmubot again! 2023-10-22 17:49:53 +02:00
Natsu Kagami 3fe1a12813
Update youmubot 2023-10-22 17:25:18 +02:00
Natsu Kagami 54c30642bc
Update phanpy 2023-10-22 17:22:09 +02:00
Natsu Kagami 872528ed1f
Update jjdk 2023-10-21 23:28:07 +02:00
Natsu Kagami 5d2ea18b48
Add owncast 2023-10-19 23:28:04 +02:00
Natsu Kagami 8a430a1399
Update gts to 0.12.0-rc2 2023-10-19 22:41:13 +02:00
Natsu Kagami 6a67d1b8ae
Add wine and stuff 2023-10-19 19:59:19 +02:00
Natsu Kagami 9a84dde328
Update gts to 0.12.0-rc1 2023-10-17 23:31:09 +02:00
Natsu Kagami a9bba20428
Enable fingerprint auth 2023-10-17 08:12:17 +02:00
Natsu Kagami a7cf162fe3
Move timer target requirement 2023-10-17 08:05:16 +02:00
Natsu Kagami 6e11b80b40
Enable timer for real 2023-10-17 08:00:06 +02:00
Natsu Kagami 69af06d78a
Set up invidious 2023-10-17 07:58:25 +02:00
90 changed files with 3718 additions and 2936 deletions

View file

@ -32,76 +32,76 @@ jobs:
git status
false
fi
deploy:
if: "github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'Deploy')"
runs-on: ubuntu-latest
name: Deploy
steps:
- uses: actions/checkout@v2.3.4
- name: Notify deployment starting
run: |
git show --no-patch | curl \
--fail-with-body \
-u "${{ secrets.NTFY_CREDS }}" \
-H "X-Title: Deployment to nki-personal-do started" \
-H "X-Priority: 1" \
-H "X-Tags: cloud" \
-H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
-d "Commit info:
" \
-d @- \
https://ntfy.nkagami.me/nki-personal-do
- name: Add SSH key
env:
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
run: |
mkdir -p /home/runner/.ssh
echo "${{ secrets.NIX_SECRETS_SSH_KEY }}" > /home/runner/.ssh/nix_secrets_key
echo "${{ secrets.NIX_DEPLOY_SSH_KEY }}" > /home/runner/.ssh/nix_deploy_key
chmod 600 /home/runner/.ssh/*
ssh-agent -a $SSH_AUTH_SOCK > /dev/null
ssh-add /home/runner/.ssh/*
ssh-keyscan ${{ secrets.INSTANCE_IP }} >> /home/runner/.ssh/known_hosts
ssh-keyscan git.dtth.ch >> /home/runner/.ssh/known_hosts
- uses: cachix/install-nix-action@v20
with:
extra_nix_config: |
# Enable flakes
experimental-features = nix-command flakes
# Deploy tokens
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
# Import my substituters
extra-substituters = https://natsukagami.cachix.org
extra-trusted-public-keys = natsukagami.cachix.org-1:3U6GV8i8gWEaXRUuXd2S4ASfYgdl2QFPWg4BKPbmYiQ=
- name: Deploy with deploy-rs
env:
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
run: |
nix run .#deploy-rs -- . --hostname ${{ secrets.INSTANCE_IP }} -s -- -L
- name: Notify deployment succeeding
run: |
git show --no-patch | curl \
--fail-with-body \
-u "${{ secrets.NTFY_CREDS }}" \
-H "X-Title: Deployment to nki-personal-do succeeded" \
-H "X-Tags: tada,cloud" \
-H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
-d "Commit info:
" \
-d @- \
https://ntfy.nkagami.me/nki-personal-do
- name: Notify deployment failing
if: ${{ failure() }}
run: |
git show --no-patch | curl \
--fail-with-body \
-u "${{ secrets.NTFY_CREDS }}" \
-H "X-Title: Deployment to nki-personal-do failed" \
-H "X-Priority: 4" \
-H "X-Tags: warning,cloud" \
-H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
-d "Commit info:
" \
-d @- \
https://ntfy.nkagami.me/nki-personal-do
# deploy:
# if: "github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'Deploy')"
# runs-on: ubuntu-latest
# name: Deploy
# steps:
# - uses: actions/checkout@v2.3.4
# - name: Notify deployment starting
# run: |
# git show --no-patch | curl \
# --fail-with-body \
# -u "${{ secrets.NTFY_CREDS }}" \
# -H "X-Title: Deployment to nki-personal-do started" \
# -H "X-Priority: 1" \
# -H "X-Tags: cloud" \
# -H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
# -d "Commit info:
# " \
# -d @- \
# https://ntfy.nkagami.me/nki-personal-do
# - name: Add SSH key
# env:
# SSH_AUTH_SOCK: /tmp/ssh_agent.sock
# run: |
# mkdir -p /home/runner/.ssh
# echo "${{ secrets.NIX_SECRETS_SSH_KEY }}" > /home/runner/.ssh/nix_secrets_key
# echo "${{ secrets.NIX_DEPLOY_SSH_KEY }}" > /home/runner/.ssh/nix_deploy_key
# chmod 600 /home/runner/.ssh/*
# ssh-agent -a $SSH_AUTH_SOCK > /dev/null
# ssh-add /home/runner/.ssh/*
# ssh-keyscan ${{ secrets.INSTANCE_IP }} >> /home/runner/.ssh/known_hosts
# ssh-keyscan git.dtth.ch >> /home/runner/.ssh/known_hosts
# - uses: cachix/install-nix-action@v20
# with:
# extra_nix_config: |
# # Enable flakes
# experimental-features = nix-command flakes
# # Deploy tokens
# access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
# # Import my substituters
# extra-substituters = https://natsukagami.cachix.org
# extra-trusted-public-keys = natsukagami.cachix.org-1:3U6GV8i8gWEaXRUuXd2S4ASfYgdl2QFPWg4BKPbmYiQ=
# - name: Deploy with deploy-rs
# env:
# SSH_AUTH_SOCK: /tmp/ssh_agent.sock
# run: |
# nix run .#deploy-rs -- . --hostname ${{ secrets.INSTANCE_IP }} -s -- -L
# - name: Notify deployment succeeding
# run: |
# git show --no-patch | curl \
# --fail-with-body \
# -u "${{ secrets.NTFY_CREDS }}" \
# -H "X-Title: Deployment to nki-personal-do succeeded" \
# -H "X-Tags: tada,cloud" \
# -H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
# -d "Commit info:
# " \
# -d @- \
# https://ntfy.nkagami.me/nki-personal-do
# - name: Notify deployment failing
# if: ${{ failure() }}
# run: |
# git show --no-patch | curl \
# --fail-with-body \
# -u "${{ secrets.NTFY_CREDS }}" \
# -H "X-Title: Deployment to nki-personal-do failed" \
# -H "X-Priority: 4" \
# -H "X-Tags: warning,cloud" \
# -H "Actions: view, Open Job on GitHub, ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
# -d "Commit info:
# " \
# -d @- \
# https://ntfy.nkagami.me/nki-personal-do

View file

@ -4,6 +4,8 @@ keys:
- &nki_pc age1tt0peqg8zdfh74m5sdgwsczcqh036nhgmwvkqnvywll88uvmm9xs433rhm
- &nkagami_main age1n8tnmmgredzltzwkspag7aufhrn6034ny8ysjeulhkwdnf7vqqaqec4mg5
- &nkagami_do age1z2h24mjt80fryqupajkh3kg5r4sjgw65uqy489xeqxhqj8u2a9fsm3ff36
- &nki_yoga age1vhjhmxura35apu5zdwg5ur5r40xay45ld9szh07dy0ph9chgsu7shfm4h9
- &nki_framework age188tgu3psvywk6shq85mk2q0jdjwd0tcswzwlwu5pa5n3pndx75dq090z59
creation_rules:
- path_regex: kagami-air-m1/secrets\.yaml$
key_groups:
@ -16,9 +18,20 @@ creation_rules:
- *nki_pc
- *nkagami_main
- *nkagami_do
- path_regex: nki-home/secrets/secrets\.yaml$
- *nki_framework
- path_regex: nki-home/secrets\.yaml$
key_groups:
- age:
- *nki_pc
- *nkagami_main
- *nkagami_do
- path_regex: nki-yoga-g8/secrets\.yaml$
key_groups:
- age:
- *nki_yoga
- age1axvjllyv2gutngwmp3pvp4xtq2gqneldaq2c4nrzmaye0uwmk9lqsealdv # The machine itself
- path_regex: nki-framework/secrets\.yaml$
key_groups:
- age:
- *nki_framework
- age1vgh6kvee8lvxylm7z86fpl3xzjyjs4u3zdfkyf064rjvxk9fpumsew7n27 # The machine itself

View file

@ -12,7 +12,9 @@ in
{ lib, pkgs, config, ... }:
with lib; {
imports = [
defaultShell
# defaultShell
./modules/services/nix-cache
./modules/services/nix-build-farm
];
## Packages

File diff suppressed because it is too large Load diff

177
flake.nix
View file

@ -2,17 +2,19 @@
description = "nki's systems";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
nixos-hardware.url = "github:nixos/nixos-hardware";
darwin.url = "github:lnl7/nix-darwin/master";
darwin.inputs.nixpkgs.follows = "nixpkgs-unstable";
home-manager.url = "github:nix-community/home-manager/release-23.05";
home-manager.url = "github:nix-community/home-manager/release-24.05";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
home-manager-unstable.url = "github:nix-community/home-manager";
home-manager-unstable.inputs.nixpkgs.follows = "nixpkgs-unstable";
sops-nix.url = "github:Mic92/sops-nix";
sops-nix.inputs.nixpkgs.follows = "nixpkgs-unstable";
sops-nix.inputs.nixpkgs-stable.follows = "nixpkgs";
deploy-rs.url = "github:Serokell/deploy-rs";
nur.url = "github:nix-community/NUR";
# --- Secure boot
lanzaboote = {
@ -23,33 +25,35 @@
# --- Build tools
flake-utils.url = github:numtide/flake-utils;
crane.url = github:ipetkov/crane;
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
arion.url = github:hercules-ci/arion;
lix-module = {
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.91.1-1.tar.gz";
inputs.nixpkgs.follows = "nixpkgs";
};
# ---
# Imported apps
rnix-lsp.url = "github:nix-community/rnix-lsp";
youmubot.url = "github:natsukagami/youmubot";
swayfx = {
url = github:WillPower3309/swayfx;
inputs.nixpkgs.follows = "nixpkgs";
};
# swayfx = {
# url = github:WillPower3309/swayfx;
# inputs.nixpkgs.follows = "nixpkgs";
# };
mpd-mpris = {
url = github:natsukagami/mpd-mpris;
inputs.nixpkgs.follows = "nixpkgs";
};
dtth-phanpy.url = "git+ssh://gitea@git.dtth.ch/nki/phanpy";
conduit = {
url = gitlab:famedly/conduit/v0.6.0;
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
eza.url = github:eza-community/eza/v0.12.0;
eza.inputs.nixpkgs.follows = "nixpkgs";
dtth-phanpy.url = "git+ssh://gitea@git.dtth.ch/nki/phanpy?ref=dtth-fork";
conduit.url = "gitlab:famedly/conduit/v0.9.0";
nix-gaming.url = github:fufexan/nix-gaming;
# --- Sources
kakoune.url = github:mawww/kakoune;
kakoune.flake = false;
kak-lsp.url = github:natsukagami/kak-lsp/metals-support;
kak-lsp.url = github:kakoune-lsp/kakoune-lsp;
kak-lsp.flake = false;
nixos-m1.url = github:tpwrules/nixos-apple-silicon;
nixos-m1.inputs.nixpkgs.follows = "nixpkgs";
@ -59,7 +63,7 @@
secrets.url = "git+ssh://git@github.com/natsukagami/nix-deploy-secrets";
};
outputs = { self, darwin, nixpkgs, nixpkgs-unstable, home-manager, deploy-rs, sops-nix, nur, ... }@inputs:
outputs = { self, darwin, nixpkgs, nixpkgs-unstable, home-manager, deploy-rs, sops-nix, ... }@inputs:
let
overlays = import ./overlay.nix inputs;
lib = nixpkgs.lib;
@ -71,23 +75,12 @@
nixpkgsAsRegistry_ = stable: { lib, ... }: {
imports = [ applyOverlays ];
nix.registry.current-system.flake = self;
nix.registry.nixpkgs.flake = stable;
nix.registry.nixpkgs-unstable.flake = nixpkgs-unstable;
nixpkgs.config.allowUnfree = true;
nix.nixPath = [
"nixpkgs=${nixpkgs}"
nix.nixPath = lib.mkDefault [
"nixpkgs-unstable=${nixpkgs-unstable}"
"/nix/var/nix/profiles/per-user/root/channels"
];
# Binary Cache for Haskell.nix
nix.settings.trusted-public-keys = [
# "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
];
nix.settings.substituters = [
# "https://cache.iog.io"
];
};
nixpkgsAsRegistry = nixpkgsAsRegistry_ nixpkgs;
osuStable = { pkgs, ... }: {
nix.settings = {
@ -95,6 +88,20 @@
trusted-public-keys = [ "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" ];
};
environment.systemPackages = [ inputs.nix-gaming.packages.${pkgs.hostPlatform.system}.osu-stable ];
programs.gamemode = {
enable = true;
enableRenice = true;
settings = {
general = {
renice = 10;
};
custom = {
start = "${pkgs.libnotify}/bin/notify-send 'GameMode started'";
end = "${pkgs.libnotify}/bin/notify-send 'GameMode ended'";
};
};
};
};
# Common Nix modules
@ -103,6 +110,7 @@
(nixpkgsAsRegistry_ stable)
./common.nix
sops-nix.nixosModules.sops
inputs.lix-module.nixosModules.default
];
};
common-nixos = stable: { ... }: {
@ -111,9 +119,39 @@
./modules/common/linux
(common-nix stable)
inputs.secrets.nixosModules.common
inputs.nix-gaming.nixosModules.pipewireLowLatency
];
};
mkPersonalSystem = nixpkgs-module: system: { configuration
, homeManagerUsers ? { }
, extraModules ? [ ]
, includeCommonModules ? true
,
}:
let
home-manager-module =
if nixpkgs-module == inputs.nixpkgs then inputs.home-manager
else if nixpkgs-module == inputs.nixpkgs-unstable then inputs.home-manager-unstable
else builtins.abort "Unknown nixpkgs module, use `nixpkgs` or `nixpkgs-unstable`";
in
nixpkgs-module.lib.nixosSystem {
inherit system;
modules =
(if includeCommonModules then [
(common-nixos nixpkgs-module)
] else [ ]) ++ [
configuration
# Home Manager
home-manager-module.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users = homeManagerUsers;
}
] ++ extraModules;
};
in
{
overlays.default = lib.composeManyExtensions overlays;
@ -137,29 +175,16 @@
};
# Home configuration
nixosConfigurations."nki-home" = nixpkgs.lib.nixosSystem rec {
system = "x86_64-linux";
modules = [
(common-nixos nixpkgs)
./nki-home/configuration.nix
osuStable
inputs.home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.nki = { ... }: {
imports = [
./home/kagami-pc-home.nix
];
};
}
];
nixosConfigurations."kagamiPC" = mkPersonalSystem nixpkgs-unstable "x86_64-linux" {
configuration = ./nki-home/configuration.nix;
homeManagerUsers.nki = import ./home/kagami-pc-home.nix;
extraModules = [ osuStable ];
};
# yoga g8 configuration
nixosConfigurations."nki-yoga-g8" = nixpkgs.lib.nixosSystem rec {
system = "x86_64-linux";
modules = [
(common-nixos nixpkgs)
nixosConfigurations."nki-yoga-g8" = mkPersonalSystem nixpkgs "x86_64-linux" {
configuration = ./nki-yoga-g8/configuration.nix;
homeManagerUsers.nki = import ./home/nki-x1c1.nix;
extraModules = [
inputs.lanzaboote.nixosModules.lanzaboote
({ ... }: {
# Sets up secure boot
@ -169,40 +194,38 @@
pkiBundle = "/etc/secureboot";
};
})
./nki-yoga-g8/configuration.nix
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.nki = import ./home/nki-x1c1.nix;
}
];
};
# framework configuration
nixosConfigurations."nki-framework" = mkPersonalSystem nixpkgs-unstable "x86_64-linux" {
configuration = ./nki-framework/configuration.nix;
homeManagerUsers.nki = import ./home/nki-framework.nix;
extraModules = [
inputs.lanzaboote.nixosModules.lanzaboote
inputs.nixos-hardware.nixosModules.framework-13-7040-amd
({ ... }: {
# Sets up secure boot
boot.loader.systemd-boot.enable = lib.mkForce false;
boot.lanzaboote = {
enable = true;
pkiBundle = "/etc/secureboot";
};
})
];
};
# macbook nixos
nixosConfigurations."kagami-air-m1" = inputs.nixpkgs.lib.nixosSystem rec {
system = "aarch64-linux";
modules = [
(common-nixos inputs.nixpkgs)
inputs.nixos-m1.nixosModules.apple-silicon-support
./kagami-air-m1/configuration.nix
inputs.home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.nki = import ./home/macbook-nixos.nix;
}
];
nixosConfigurations."kagami-air-m1" = mkPersonalSystem nixpkgs "aarch64-linux" {
configuration = ./kagami-air-m1/configuration.nix;
homeManagerUsers.nki = import ./home/macbook-nixos.nix;
extraModules = [ inputs.nixos-m1.nixosModules.apple-silicon-support ];
};
# DigitalOcean node
nixosConfigurations."nki-personal-do" = nixpkgs.lib.nixosSystem rec {
system = "x86_64-linux";
modules = [
(common-nixos nixpkgs)
nixosConfigurations."nki-personal-do" = mkPersonalSystem nixpkgs "x86_64-linux" {
configuration = ./nki-personal-do/configuration.nix;
extraModules = [
inputs.arion.nixosModules.arion
./modules/my-tinc
inputs.youmubot.nixosModules.default
./nki-personal-do/configuration.nix
inputs.secrets.nixosModules.nki-personal-do
];
};
@ -217,8 +240,8 @@
# This is highly advised, and will prevent many possible mistakes
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
} // (inputs.flake-utils.lib.eachDefaultSystem (system: {
formatter = nixpkgs.legacyPackages.${system}.nixpkgs-fmt;
}));
}

View file

@ -1,51 +1,54 @@
{ pkgs, config, lib, ... }:
with lib; {
with lib;
let
kwallet = { pkgs, lib, ... }: {
home.packages = with pkgs; [ kdePackages.kwallet kdePackages.ksshaskpass ];
home.sessionVariables = {
# https://wiki.archlinux.org/title/KDE_Wallet#Using_the_KDE_Wallet_to_store_ssh_key_passphrases
SSH_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass;
SSH_ASKPASS_REQUIRE = "prefer";
};
# Enable this for sway
wayland.windowManager.sway.config.startup = [
{ command = "${pkgs.kdePackages.kwallet-pam}/libexec/pam_kwallet_init"; }
];
# Automatic dbus activation
xdg.dataFile."dbus-1/services/org.freedesktop.secrets.service".text = ''
[D-BUS Service]
Name=org.freedesktop.secrets
Exec=${pkgs.kdePackages.kwallet}/bin/kwalletd6
'';
};
in
{
imports = [
./modules/monitors.nix
./modules/linux/graphical
./modules/X11/xfce4-notifyd.nix
./modules/programs/discord.nix
kwallet
];
config = (mkIf pkgs.stdenv.isLinux {
home.packages = with pkgs; [
psmisc # killall and friends
file # Query file type
pinentry-gnome
] ++ (
if pkgs.stdenv.isx86_64
then [
vivaldi
mpv # for anki
pkgs.unstable.anki-bin
tdesktop
whatsapp-for-linux
]
else [ ]
);
## Gnome-keyring
services.gnome-keyring = {
enable = true;
components = [ "pkcs11" "secrets" "ssh" ];
};
# services.gpg-agent.enable = true;
# services.gpg-agent.pinentryFlavor = "curses";
# services.gpg-agent.enableSshSupport = true;
# Git "safe-directory"
programs.git.extraConfig.safe.directory = [
"${config.home.homeDirectory}/.config/nixpkgs"
pinentry-gnome3 # until pinentry-qt introduces caching
];
systemd.user.startServices = "sd-switch";
# Audio stuff!
services.easyeffects.enable = true;
# Bluetooth controls
services.mpris-proxy.enable = true;
# services.mpris-proxy.enable = true;
# Owncloud
services.owncloud-client.enable = true;
services.owncloud-client.package = pkgs.owncloud-client.overrideAttrs (attrs: {
buildInputs = attrs.buildInputs ++ [ pkgs.qt6.qtwayland ];
});
# UDisks automounter
services.udiskie.enable = true;

View file

@ -1,8 +1,5 @@
{ config, pkgs, lib, ... }:
{ config, pkgs, ... }:
let
texlab = pkgs.unstable.texlab;
in
{
imports = [
./kakoune/kak.nix
@ -12,13 +9,6 @@ in
./modules/programs/my-kitty
./modules/programs/openconnect-epfl.nix
./common-linux.nix
# PATH Overrides
({ config, lib, ... }: {
home.sessionPath = lib.mkBefore [
"${config.home.homeDirectory}/.bin/overrides"
];
})
];
# Let Home Manager install and manage itself.
@ -29,46 +19,16 @@ in
# Packages that are not in programs section
home.packages = with pkgs; [
# Build Tools
## C++
autoconf
automake
## SQL
flyway
## Go
go # to be configured later
## Rust
rust-analyzer
## JavaScript
yarn
## Nix
cachix
rnix-lsp
## Latex
tectonic
texlab
## Typst
typst
## Python
python3
## Scala
pkgs.unstable.scala-cli
# Fonts
fantasque-sans-mono
## Get the nerd font symbols
(nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; })
# CLI tools
fd
sd
ripgrep
fossil
openssh
tea # gitea CLI (gh-like)
fx # JSON viewer
glow # Markdown viewer
## File Manager
nnn
nix-output-monitor # Nice nix output formatting
unstable.scala-next
## PDF Processors
poppler_utils
## htop replacement
@ -80,13 +40,6 @@ in
unzip
zstd
atool
## To do tunneling with cloudflare
pkgs.cloudflared
# Databases
postgresql
mariadb
];
home.sessionVariables = {
@ -116,9 +69,9 @@ in
direnv.nix-direnv.enable = true;
direnv.config.global.load_dotenv = true;
exa = {
eza = {
enable = true;
enableAliases = true;
enableFishIntegration = true;
};
fzf = {
@ -150,6 +103,8 @@ in
.envrc
.kakrc
''}";
safe.directory = "*";
merge.conflictstyle = "diff3";
};
};

View file

@ -1,8 +1,3 @@
{
allowUnfree = true;
packageOverrides = pkgs: {
nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/master.tar.gz") {
inherit pkgs;
};
};
}

View file

@ -1,9 +1,37 @@
{ config, pkgs, lib, ... }:
{ config, options, pkgs, lib, ... }:
with lib;
let
bootDesktop = pkgs.writeScript "boot-desktop" ''
#!/usr/bin/env fish
set -a PATH ${pkgs.gum}/bin
set -x GUM_CHOOSE_HEADER "Select the Desktop to boot into:"
set CHOICES
if which sway &>/dev/null
set -a CHOICES "sway"
end
if which startplasma-wayland &>/dev/null
set -a CHOICES "KDE Plasma"
end
set -a CHOICES "None: continue to shell"
switch (gum choose $CHOICES)
case "sway"
systemctl --user unset-environment NIXOS_OZONE_WL
exec sway
case "KDE Plasma"
exec ${pkgs.kdePackages.plasma-workspace}/libexec/plasma-dbus-run-session-if-needed startplasma-wayland
case '*'
exec fish -i
end
'';
in
{
imports = [
./tide/nix-shell.nix
./tide
];
options.programs.fish.everywhereAbbrs = mkOption {
@ -23,22 +51,28 @@ with lib;
config.programs.fish = {
enable = true;
functions = {
rebuild = {
body = ''
pls nixos-rebuild --flake ~/.config/nixpkgs -L --log-format internal-json -v $argv \
&| ${pkgs.nix-output-monitor}/bin/nom --json
'';
wraps = "nixos-rebuild";
};
# Simplify nix usage!
nx = {
body = ''
set impure
if test $argv[1] = "--impure"
set impure "--impure"
set argv $argv[2..]
end
if test (count $argv) -gt 0
nix run $impure nixpkgs#$argv[1] -- $argv[2..]
else
echo "nx [--impure] {package} [args...]"
argparse -s 'h/help' 'impure' 'u/unstable' 'g/git' -- $argv
if set -q _flag_help || test (count $argv) -eq 0
echo "nx [--impure] [-u/--unstable/-g/--git] {package} [args...]"
return 1
else
set -q _flag_impure && set impure "--impure"
set nixpkgs "nixpkgs"
set -q _flag_unstable && set nixpkgs "nixpkgs-unstable"
set -q _flag_git && set nixpkgs "github:nixOS/nixpkgs/nixpkgs-unstable"
nix run $impure $nixpkgs"#"$argv[1] -- $argv[2..]
end
'';
wraps = "nix run";
description = "Runs an app from the nixpkgs store.";
};
@ -46,25 +80,35 @@ with lib;
description = "Spawns a shell from the given nixpkgs packages";
wraps = "nix shell";
body = ''
set impure
if test $argv[1] = "--impure"
set impure "--impure"
set argv $argv[2..]
function help
echo "nsh [--impure] [--impure] [-u/--unstable/-g/--git] {package}* [-c command args...]"
end
if test (count $argv) -gt 0
set minusc (contains -i -- "-c" $argv)
if test -z $minusc
nix shell $impure nixpkgs#$argv -c fish
else if test $minusc -eq (count $argv)
echo "nsh [--impure] {packages} [-c command args...]"
argparse -s 'h/help' 'impure' 'u/unstable' 'g/git' -- $argv
if set -q _flag_help || test (count $argv) -eq 0
help
return 0
end
set packages $argv
set minusc (contains -i -- "-c" $argv)
if test -n "$minusc"
if test $minusc -eq 1
help
return 1
else
nix shell $impure nixpkgs#$argv[..(math $minusc - 1)] $argv[$minusc..]
end
set packages $argv[..(math $minusc - 1)]
set argv $argv[(math $minusc + 1)..]
else
echo "nsh [--impure] {packages} [-c command args...]"
set argv "fish" "-i"
end
if test (count $packages) -eq 0
help
return 1
end
set -q _flag_impure && set impure "--impure"
set nixpkgs "nixpkgs"
set -q _flag_unstable && set nixpkgs "nixpkgs-unstable"
set -q _flag_git && set nixpkgs "github:nixOS/nixpkgs/nixpkgs-unstable"
nix shell $impure $nixpkgs"#"$packages --command $argv
'';
};
# Grep stuff
@ -82,17 +126,44 @@ with lib;
};
echo-today = "date +%F";
newfile = "mkdir -p (dirname $argv[-1]) && touch $argv";
# pls
pls = {
wraps = "sudo";
body = ''
set -l cmd "`"(string join " " -- $argv)"`"
echo "I-It's not like I'm gonna run "$cmd" for you or a-anything! Baka >:C" >&2
# Send a notification on password prompt
if command sudo -vn 2>/dev/null
# nothing to do, user already authenticated
else
# throw a notification
set notif_id (kitten notify -P \
-p ${./haruka.png} \
-a "pls" \
-u critical \
"A-a command requires your p-password" \
(printf "I-I need your p-password to r-run the following c-command:\n\n%s" $cmd))
command sudo -v -p "P-password please: "
kitten notify -i $notif_id ""
end
command sudo $argv
'';
};
};
tide = {
nix-shell.enable = true;
enable = true;
leftItems = options.programs.fish.tide.leftItems.default;
rightItems = options.programs.fish.tide.rightItems.default;
};
shellAliases = {
cat = "bat --theme=GitHub ";
catp = "bat --theme=GitHub -p ";
l = "exa -l --color=always ";
"cp+" = "rsync -avzP";
};
everywhereAbbrs = {
@ -107,9 +178,17 @@ with lib;
if test -e /opt/homebrew/bin/brew
/opt/homebrew/bin/brew shellenv | source
end
# Override PATH
set --export --prepend PATH ~/.bin/overrides ~/.local/bin
'';
interactiveShellInit = ''
# Sway!
if status --is-login; and test -z $DISPLAY; and test (tty) = "/dev/tty1"
exec ${bootDesktop}
end
function fish_greeting
${pkgs.timg}/bin/timg ${./arona.jpg}
printf (env LANG=ja_JP.UTF-8 date +"\n%A%Y%m%d%H%M \n\n")
@ -176,23 +255,8 @@ with lib;
set -q PERL_LOCAL_LIB_ROOT; or set -x PERL_LOCAL_LIB_ROOT ${config.home.homeDirectory}/perl5;
set -x PERL_MB_OPT --install_base\ \"${config.home.homeDirectory}/perl5\";
set -x PERL_MM_OPT INSTALL_BASE=${config.home.homeDirectory}/perl5;
# Sway!
if status --is-login; and which sway >/dev/null; and test -z $DISPLAY; and test (tty) = "/dev/tty1"
read -P "Press enter to start sway..."; and exec sway
end
'';
plugins = [
{
name = "tide";
src = pkgs.fetchFromGitHub {
owner = "IlanCosman";
repo = "tide";
rev = "447945d2cff8f70d5c791dd4eec8b322d37798dd";
# sha256 = lib.fakeSha256;
sha256 = "sha256-1c2E3UC3r9hPfijAQoZ/+4yXieFxC4+hkk7wUyr30NM=";
};
}
{
name = "fzf";
src = pkgs.fetchFromGitHub {
@ -221,8 +285,8 @@ with lib;
target = ".config/fish/conf.d/change_cmd.fish";
};
"fish/pls.fish" = {
source = ./. + "/pls.fish";
target = ".config/fish/conf.d/pls.fish";
source = ./pls_extra.fish;
target = ".config/fish/conf.d/pls_extra.fish";
};
};
}

BIN
home/fish/haruka.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -1,155 +0,0 @@
alias sue="pls -e"
function pls
set -l cmd "`"(string join " " -- $argv)"`"
echo "I-It's not like I'm gonna run "$cmd" for you or a-anything! Baka >:C" >&2
# Send a notification on password prompt
if command sudo -vn 2>/dev/null
# nothing to do, user already authenticated
else
# throw a notification
# notify-send -t 3000 -u critical -i ~/Downloads/harukablush.jpg -h "STRING:command:"$cmd "A-a command requires your p-password" (printf "I-I need your p-password to r-run the following c-command: %s" $cmd)
end
command sudo $argv
end
function sudo
echo "Not polite enough."
end
function __fish_prepend_pls -d "Prepend 'pls ' to the beginning of the current commandline"
# If there is no commandline, insert the last item from history
# and *then* toggle
if not commandline | string length -q
commandline -r "$history[1]"
end
set -l cmd (commandline -po)
set -l cursor (commandline -C)
if test "$cmd[1]" = e
commandline -C 0
commandline -i "su"
commandline -C (math $cursor + 2)
else if test "$cmd[1]" = sue
commandline -r (string sub --start=3 (commandline -p))
commandline -C -- (math $cursor - 2)
else if test "$cmd[1]" != pls
commandline -C 0
commandline -i "pls "
commandline -C (math $cursor + 4)
else
commandline -r (string sub --start=5 (commandline -p))
commandline -C -- (math $cursor - 4)
end
end
bind --preset -e -M insert \es
bind -M insert \es __fish_prepend_pls
function __fish_man_page
# Get all commandline tokens not starting with "-"
set -l args (commandline -po | string match -rv '^-')
# If commandline is empty, exit.
if not set -q args[1]
printf \a
return
end
#Skip `pls` and display then manpage of following command
while set -q args[2]
and string match -qr -- '^(pls|.*=.*)$' $args[1]
set -e args[1]
end
# If there are at least two tokens not starting with "-", the second one might be a subcommand.
# Try "man first-second" and fall back to "man first" if that doesn't work out.
set -l maincmd (basename $args[1])
if set -q args[2]
# HACK: If stderr is not attached to a terminal `less` (the default pager)
# wouldn't use the alternate screen.
# But since we don't know what pager it is, and because `man` is totally underspecified,
# the best we can do is to *try* the man page, and assume that `man` will return false if it fails.
# See #7863.
if man "$maincmd-$args[2]" &>/dev/null
man "$maincmd-$args[2]"
else if man "$maincmd" &>/dev/null
man "$maincmd"
else
printf \a
end
else
if man "$maincmd" &>/dev/null
man "$maincmd"
else
printf \a
end
end
commandline -f repaint
end
#
# Completion for pls
#
function __fish_pls_print_remaining_args
set -l tokens (commandline -opc) (commandline -ct)
set -e tokens[1]
# These are all the options mentioned in the man page for Todd Miller's "pls.ws" pls (in that order).
# If any other implementation has different options, this should be harmless, since they shouldn't be used anyway.
set -l opts A/askpass b/background C/close-from= E/preserve-env='?'
# Note that "-h" is both "--host" (which takes an option) and "--help" (which doesn't).
# But `-h` as `--help` only counts when it's the only argument (`pls -h`),
# so any argument completion after that should take it as "--host".
set -a opts e/edit g/group= H/set-home h/host= 1-help
set -a opts i/login K/remove-timestamp k/reset-timestamp l/list n/non-interactive
set -a opts P/preserve-groups p/prompt= S/stdin s/shell U/other-user=
set -a opts u/user= T/command-timeout= V/version v/validate
argparse -s $opts -- $tokens 2>/dev/null
# The remaining argv is the subcommand with all its options, which is what
# we want.
if test -n "$argv"
and not string match -qr '^-' $argv[1]
string join0 -- $argv
return 0
else
return 1
end
end
function __fish_pls_no_subcommand
not __fish_pls_print_remaining_args >/dev/null
end
function __fish_complete_pls_subcommand
set -l args (__fish_pls_print_remaining_args | string split0)
set -lx -a PATH /usr/local/sbin /sbin /usr/sbin
__fish_complete_subcommand --commandline $args
end
# All these options should be valid for GNU and OSX pls
complete -c pls -n __fish_no_arguments -s h -d "Display help and exit"
complete -c pls -n __fish_no_arguments -s V -d "Display version information and exit"
complete -c pls -n __fish_pls_no_subcommand -s A -d "Ask for password via the askpass or \$SSH_ASKPASS program"
complete -c pls -n __fish_pls_no_subcommand -s C -d "Close all file descriptors greater or equal to the given number" -xa "0 1 2 255"
complete -c pls -n __fish_pls_no_subcommand -s E -d "Preserve environment"
complete -c pls -n __fish_pls_no_subcommand -s H -d "Set home"
complete -c pls -n __fish_pls_no_subcommand -s K -d "Remove the credential timestamp entirely"
complete -c pls -n __fish_pls_no_subcommand -s P -d "Preserve group vector"
complete -c pls -n __fish_pls_no_subcommand -s S -d "Read password from stdin"
complete -c pls -n __fish_pls_no_subcommand -s b -d "Run command in the background"
complete -c pls -n __fish_pls_no_subcommand -s e -rF -d Edit
complete -c pls -n __fish_pls_no_subcommand -s g -a "(__fish_complete_groups)" -x -d "Run command as group"
complete -c pls -n __fish_pls_no_subcommand -s i -d "Run a login shell"
complete -c pls -n __fish_pls_no_subcommand -s k -d "Reset or ignore the credential timestamp"
complete -c pls -n __fish_pls_no_subcommand -s l -d "List the allowed and forbidden commands for the given user"
complete -c pls -n __fish_pls_no_subcommand -s n -d "Do not prompt for a password - if one is needed, fail"
complete -c pls -n __fish_pls_no_subcommand -s p -d "Specify a custom password prompt"
complete -c pls -n __fish_pls_no_subcommand -s s -d "Run the given command in a shell"
complete -c pls -n __fish_pls_no_subcommand -s u -a "(__fish_complete_users)" -x -d "Run command as user"
complete -c pls -n __fish_pls_no_subcommand -s v -n __fish_no_arguments -d "Validate the credentials, extending timeout"
# Complete the command we are executed under pls
complete -c pls -x -n 'not __fish_seen_argument -s e' -a "(__fish_complete_pls_subcommand)"

47
home/fish/pls_extra.fish Normal file
View file

@ -0,0 +1,47 @@
alias sue="pls -e"
function sudo
echo "Not polite enough."
end
bind --preset -M visual \es 'fish_commandline_prepend pls'
bind -M insert \es 'fish_commandline_prepend pls'
function __fish_man_page
# Get all commandline tokens not starting with "-", up to and including the cursor's
set -l args (string match -rv '^-|^$' -- (commandline -cpx && commandline -t))
# If commandline is empty, exit.
if not set -q args[1]
printf \a
return
end
# Skip leading commands and display the manpage of following command
while set -q args[2]
and string match -qr -- '^(and|begin|builtin|caffeinate|command|doas|entr|env|exec|if|mosh|nice|not|or|pipenv|prime-run|setsid|sudo|pls|systemd-nspawn|time|watch|while|xargs|.*=.*)$' $args[1]
set -e args[1]
end
# If there are at least two tokens not starting with "-", the second one might be a subcommand.
# Try "man first-second" and fall back to "man first" if that doesn't work out.
set -l maincmd (path basename $args[1])
# HACK: If stderr is not attached to a terminal `less` (the default pager)
# wouldn't use the alternate screen.
# But since we don't know what pager it is, and because `man` is totally underspecified,
# the best we can do is to *try* the man page, and assume that `man` will return false if it fails.
# See #7863.
if set -q args[2]
and not string match -q -- '*/*' $args[2]
and man "$maincmd-$args[2]" &>/dev/null
man "$maincmd-$args[2]"
else
if man "$maincmd" &>/dev/null
man "$maincmd"
else
printf \a
end
end
commandline -f repaint
end

View file

@ -0,0 +1,87 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.programs.fish.tide;
in
{
options.programs.fish.tide = {
enable = mkEnableOption "Enable tide integrations for fish";
items = mkOption {
type = types.attrsOf types.str;
description = "Additional item definitions to create";
default = { };
};
rightItems = mkOption {
type = types.listOf types.str;
description = "The list of right-items, note that `time` is not included here and will always appear last";
default = [
"status"
"cmd_duration"
"jobs"
"direnv"
"node"
"python"
"rustc"
"java"
"php"
"pulumi"
"ruby"
"go"
"gcloud"
"kubectl"
"distrobox"
"toolbox"
"terraform"
"aws"
"crystal"
"elixir"
"nix_shell"
];
};
leftItems = mkOption {
type = types.listOf types.str;
description = "The list of left-items. Note that `newline` and `character` is not included here and will always appear last";
default = [ "os" "context" "pwd" "git" ];
};
};
config.programs.fish =
let
tideItems = attrsets.mapAttrs' (name: def: { name = "_tide_item_${name}"; value = def; });
in
mkIf cfg.enable {
functions = tideItems ({
nix_shell = ''
# In a Nix Shell
if set -qx DIRENV_FILE && test -f $DIRENV_FILE && rg -q "^use flake" $DIRENV_FILE
set -U tide_nix_shell_color "FFA500"
set -U tide_nix_shell_bg_color normal
_tide_print_item nix_shell ""
end
'';
} // cfg.items);
plugins = [
{
name = "tide";
src = pkgs.fetchFromGitHub {
owner = "IlanCosman";
repo = "tide";
rev = "v6.0.1";
# sha256 = lib.fakeSha256;
sha256 = "sha256-oLD7gYFCIeIzBeAW1j62z5FnzWAp3xSfxxe7kBtTLgA=";
};
}
];
};
config.xdg.configFile."fish/tide/init.fish" = {
text = ''
# Configure tide items
set -U tide_left_prompt_items ${concatMapStringsSep " " escapeShellArg cfg.leftItems} newline character
set -U tide_right_prompt_items ${concatMapStringsSep " " escapeShellArg cfg.rightItems} time
'';
onChange = "fish ~/.config/fish/tide/init.fish";
};
}

View file

@ -1,22 +0,0 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.programs.fish.tide.nix-shell;
in
{
options.programs.fish.tide.nix-shell = {
enable = mkEnableOption "An indicator of having a `nix shell` environment";
};
config.programs.fish = mkIf cfg.enable {
functions._tide_item_nix_shell = ''
# In a Nix Shell
if string match -q "/nix/store/*" $PATH
set -U tide_nix_shell_color (set -q DIRENV_DIR && echo "FFA500" || echo "blue")
set -U tide_nix_shell_bg_color normal
_tide_print_item nix_shell ""
end
'';
};
}

View file

@ -21,9 +21,12 @@
texlive.combined.scheme-full
inkscape # for TeX svg
# Java & sbt
openjdk11
sbt
# Gaming stuff
wineWowPackages.full
# wine-lol
winetricks
lutris
steam
# Manage tlmc
flacon
@ -34,6 +37,7 @@
# Enable X11 configuration
linux.graphical.type = "wayland";
linux.graphical.wallpaper = ./images/pixiv_18776904.png;
linux.graphical.defaults.webBrowser = "librewolf.desktop";
programs.my-sway.enable = true;
programs.my-sway.fontSize = 15.0;
programs.my-sway.enableLaptopBars = false;

View file

@ -0,0 +1,79 @@
# Catppuccin theme for Kakoune
declare-option str rosewater "rgb:dc8a78"
declare-option str flamingo "rgb:dd7878"
declare-option str pink "rgb:ea76cb"
declare-option str mauve "rgb:8839ef"
declare-option str red "rgb:d20f39"
declare-option str maroon "rgb:e64553"
declare-option str peach "rgb:fe640b"
declare-option str yellow "rgb:df8e1d"
declare-option str green "rgb:40a02b"
declare-option str teal "rgb:179299"
declare-option str sky "rgb:04a5e5"
declare-option str sapphire "rgb:209fb5"
declare-option str blue "rgb:1e66f5"
declare-option str lavender "rgb:7287fd"
declare-option str text "rgb:4c4f69"
declare-option str subtext1 "rgb:5c5f77"
declare-option str subtext0 "rgb:6c6f85"
declare-option str overlay2 "rgb:7c7f93"
declare-option str overlay1 "rgb:8c8fa1"
declare-option str overlay0 "rgb:9ca0b0"
declare-option str surface2 "rgb:acb0be"
declare-option str surface1 "rgb:bcc0cc"
declare-option str surface0 "rgb:ccd0da"
declare-option str base "rgb:eff1f5"
declare-option str mantle "rgb:e6e9ef"
declare-option str crust "rgb:dce0e8"
set-face global title "%opt{text}+b"
set-face global header "%opt{subtext0}+b"
set-face global bold "%opt{maroon}+b"
set-face global italic "%opt{maroon}+i"
set-face global mono "%opt{green}"
set-face global block "%opt{sapphire}"
set-face global link "%opt{blue}"
set-face global bullet "%opt{peach}"
set-face global list "%opt{peach}"
set-face global Default "%opt{text},%opt{base}"
set-face global PrimarySelection "%opt{text},%opt{surface2}"
set-face global SecondarySelection "%opt{text},%opt{surface2}"
set-face global PrimaryCursor "%opt{crust},%opt{rosewater}"
set-face global SecondaryCursor "%opt{text},%opt{overlay0}"
set-face global PrimaryCursorEol "%opt{surface2},%opt{lavender}"
set-face global SecondaryCursorEol "%opt{surface2},%opt{overlay1}"
set-face global LineNumbers "%opt{overlay1},%opt{base}"
set-face global LineNumberCursor "%opt{rosewater},%opt{surface2}+b"
set-face global LineNumbersWrapped "%opt{rosewater},%opt{surface2}+i"
set-face global MenuForeground "%opt{text},%opt{surface1}+b"
set-face global MenuBackground "%opt{text},%opt{surface0}"
set-face global MenuInfo "%opt{crust},%opt{teal}"
set-face global Information "%opt{crust},%opt{teal}"
set-face global Error "%opt{crust},%opt{red}"
set-face global StatusLine "%opt{text},%opt{mantle}"
set-face global StatusLineMode "%opt{crust},%opt{yellow}"
set-face global StatusLineInfo "%opt{crust},%opt{teal}"
set-face global StatusLineValue "%opt{crust},%opt{yellow}"
set-face global StatusCursor "%opt{crust},%opt{rosewater}"
set-face global Prompt "%opt{teal},%opt{base}+b"
set-face global MatchingChar "%opt{maroon},%opt{base}"
set-face global Whitespace "%opt{overlay1},%opt{base}+f"
set-face global WrapMarker "Whitespace"
set-face global BufferPadding "%opt{base},%opt{base}"
set-face global value "%opt{peach}"
set-face global type "%opt{blue}"
set-face global variable "%opt{text}"
set-face global module "%opt{maroon}"
set-face global function "%opt{blue}"
set-face global string "%opt{green}"
set-face global keyword "%opt{mauve}"
set-face global operator "%opt{sky}"
set-face global attribute "%opt{green}"
set-face global comment "%opt{overlay0}"
set-face global documentation "comment"
set-face global meta "%opt{yellow}"
set-face global builtin "%opt{red}"

View file

@ -1,59 +1,67 @@
{ config, pkgs, lib, ... }:
{ pkgs, lib, ... }:
let
kakounePkg =
pkgs.kakoune.override {
kakoune = with lib; pkgs.stdenv.mkDerivation rec {
pname = "kakoune-unwrapped";
version = "r${builtins.substring 0 6 pkgs.sources.kakoune.rev}";
src = pkgs.sources.kakoune;
makeFlags = [ "debug=no" "PREFIX=${placeholder "out"}" ];
preConfigure = ''
export version="v${version}";
'';
enableParallelBuilding = true;
doInstallCheck = true;
installCheckPhase = ''
$out/bin/kak -ui json -e "kill 0"
'';
postInstall = ''
# make share/kak/autoload a directory
cd "$out/share/kak"
autoload_target=$(readlink autoload)
rm autoload
mkdir autoload
ln -s --relative "$autoload_target" autoload
'';
};
};
kak-lsp = pkgs.libs.crane.buildPackage {
src = pkgs.sources.kak-lsp;
buildInputs = (with pkgs;
lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ Security SystemConfiguration CoreServices ])
) ++ (with pkgs; [ libiconv ]);
};
kak-lsp-frontend = { pkgs, lib, ... }:
let
langserver = name: {
args = [ "--stdio" ];
command = "${pkgs.nodePackages.vscode-langservers-extracted}/bin/vscode-${name}-language-server";
filetypes = [ name ];
roots = [ "package.json" ".git" ];
name = "vscode-${name}-language-server";
value = {
args = [ "--stdio" ];
command = "vscode-${name}-language-server";
filetypes = [ name ];
roots = [ "package.json" ".git" ];
};
package = pkgs.nodePackages.vscode-langservers-extracted;
};
tailwind = {
command = "tailwindcss-language-server";
args = [ "--stdio" ];
filetypes = [ "html" "css" "javascript" "typescript" "templ" ];
roots = [ "tailwind.config.{js,cjs,mjs,ts}" "package.json" ".git" ];
settings_section = "tailwindCSS";
settings.tailwindCSS = {
validate = "warning";
userLanguages.templ = "html";
};
package = pkgs.tailwindcss-language-server;
};
templModule = { pkgs, lib, ... }: {
programs.kak-lsp.languageServers."vscode-html-language-server".filetypes = [ "templ" ];
programs.kak-lsp.languageServers."tailwindcss-language-server".filetypes = [ "templ" ];
programs.kak-lsp.languageServers.templ = {
command = "templ";
args = [ "lsp" ];
filetypes = [ "templ" ];
roots = [ "go.mod" ".git" ];
package = pkgs.unstable.templ;
};
};
in
{
programs.kak-lsp.languages = lib.attrsets.genAttrs [ "html" "css" "json" ] langserver;
imports = [ templModule ];
programs.kak-lsp.languageServers = (builtins.listToAttrs (map langserver [ "html" "css" "json" ])) // {
tailwindcss-language-server = tailwind;
};
};
ltexLsp = { pkgs, lib, ... }: {
programs.kak-lsp.languageServers.ltex-ls = {
command = "ltex-ls";
args = [ "--log-file=/tmp" ];
filetypes = [ "latex" "typst" ];
roots = [ "main.tex" "main.typ" ".git" ];
package = pkgs.ltex-ls;
};
};
in
{
imports = [ ../modules/programs/my-kakoune ./kaktex.nix kak-lsp-frontend ];
imports = [ ../modules/programs/my-kakoune ./kaktex.nix kak-lsp-frontend ltexLsp ];
home.packages = with pkgs; [
# ctags for peneira
@ -68,7 +76,6 @@ in
programs.my-kakoune.enable = true;
programs.my-kakoune.enable-fish-session = true;
programs.kak-lsp.enable = true;
programs.kak-lsp.package = kak-lsp;
programs.kak-lsp.semanticTokens.additionalFaces = [
# Typst
{ face = "header"; token = "heading"; }
@ -84,13 +91,20 @@ in
{ face = "ts_markup_italic"; token = "text"; modifiers = [ "emph" ]; }
];
programs.kak-lsp.languages.typescript = {
programs.kak-lsp.languageServers.elixir-ls = {
args = [ ];
command = "elixir-ls";
filetypes = [ "elixir" ];
roots = [ "mix.exs" ];
};
programs.kak-lsp.languageServers.typescript-language-server = {
args = [ "--stdio" ];
command = "typescript-language-server";
filetypes = [ "typescript" ];
filetypes = [ "typescript" "javascript" ];
roots = [ "package.json" ];
package = pkgs.nodePackages.typescript-language-server;
};
programs.kak-lsp.languages.fsharp = {
programs.kak-lsp.languageServers.fsautocomplete = {
args = [ "--adaptive-lsp-server-enabled" "--project-graph-enabled" "--source-text-factory" "RoslynSourceText" ];
command = "fsautocomplete";
filetypes = [ "fsharp" ];
@ -100,7 +114,7 @@ in
AutomaticWorkspaceInit = true;
};
};
programs.kak-lsp.languages.scala = {
programs.kak-lsp.languageServers.metals = {
command = "metals";
filetypes = [ "scala" ];
roots = [ "build.sbt" "build.sc" ];
@ -110,12 +124,18 @@ in
showInferredType = true;
decorationProvider = true;
inlineDecorationProvider = true;
# From kakoune-lsp's own options
icons = "unicode";
isHttpEnabled = true;
statusBarProvider = "log-message";
compilerOptions = { overrideDefFormat = "unicode"; };
};
package = pkgs.metals;
};
programs.kak-lsp.languages.latex = {
programs.kak-lsp.languageServers.texlab = {
command = "texlab";
filetypes = [ "latex" ];
roots = [ ".git" "main.tex" "all.tex" ];
roots = [ "main.tex" "all.tex" ".git" ];
settings_section = "texlab";
settings.texlab = {
build.executable = "latexmk";
@ -131,16 +151,32 @@ in
} else
{
executable = "${pkgs.zathura}/bin/zathura";
args = [ "--synctex-forward" "%l:1:%f" "%p" "-x" "/home/nki/.bin/kaktex jump %{input} %{line}" ];
args = [ "--synctex-forward" "%l:1:%f" "%p" "-x" "${./kaktex} jump %%{input} %%{line} %%{column}" ];
});
};
package = pkgs.texlab;
};
programs.kak-lsp.languages.typst = {
command = "${pkgs.typst-lsp}/bin/typst-lsp";
programs.kak-lsp.languageServers.typst-lsp = {
command = "typst-lsp";
filetypes = [ "typst" ];
roots = [ ".git" "main.typ" ];
roots = [ "main.typ" ".git" ];
settings_section = "typst-lsp";
settings.typst-lsp = { };
settings.typst-lsp = {
experimentalFormatterMode = "on";
};
};
programs.kak-lsp.languageServers.marksman = {
command = "marksman";
filetypes = [ "markdown" ];
roots = [ ".marksman.toml" ".git" ];
package = pkgs.marksman;
};
programs.kak-lsp.languageServers.rust-analyzer = {
args = [ ];
command = "rust-analyzer";
filetypes = [ "rust" ];
roots = [ "Cargo.toml" ];
package = pkgs.rust-analyzer;
};
programs.my-kakoune.tree-sitter.extraAliases = {
@ -159,47 +195,113 @@ in
conditional = "keyword_conditional";
include = "keyword_control_import";
};
programs.my-kakoune.tree-sitter.languages = {
scala =
let
src = pkgs.fetchFromGitHub {
owner = "tree-sitter";
repo = "tree-sitter-scala";
rev = "70afdd5632d57dd63a960972ab25945e353a52f6";
hash =
if pkgs.stdenv.isDarwin
then lib.fakeHash
else "sha256-xr43ejHGCH4mcjOqxTJpO11LWKcHKAEETt6ZWUG9vo4=";
leaveDotGit = true;
};
in
{
grammar.src = src;
queries.src = src;
queries.path = "queries/scala";
programs.my-kakoune.tree-sitter.languages =
let
tree-sitter-go = pkgs.fetchFromGitHub {
owner = "tree-sitter";
repo = "tree-sitter-go";
rev = "v0.20.0";
hash = "sha256-G7d8CHCyKDAb9j6ijRfHk/HlgPqSI+uvkuRIRRvjkHI=";
};
haskell =
let
src = pkgs.fetchFromGitHub {
owner = "tree-sitter";
repo = "tree-sitter-haskell";
rev = "ba0bfb0e5d8e9e31c160d287878c6f26add3ec08";
sha256 =
if pkgs.stdenv.isDarwin
then "sha256-lW3E4gSZV/m2RfofUqeiCu8KDz06YEvXbYKs8smXFi4="
else "sha256-nocX9L8vD655nzky4PQulygWAjKGC1rh3SYDr7t4wBQ=";
leaveDotGit = true;
in
{
scala =
let
src = pkgs.fetchFromGitHub {
owner = "tree-sitter";
repo = "tree-sitter-scala";
rev = "70afdd5632d57dd63a960972ab25945e353a52f6";
hash = "sha256-bi0Lqo/Zs2Uaz1efuKAARpEDg5Hm59oUe7eSXgL1Wow=";
};
in
{
grammar.src = src;
queries.src = src;
queries.path = "queries/scala";
};
in
{
grammar.src = src;
grammar.compile.args = [ "-c" "-fpic" "../parser.c" "../scanner.c" "../unicode.h" "-I" ".." ];
queries.src = src;
haskell =
let
src = pkgs.fetchFromGitHub {
owner = "tree-sitter";
repo = "tree-sitter-haskell";
rev = "ba0bfb0e5d8e9e31c160d287878c6f26add3ec08";
hash = "sha256-ZSOF0CLOn82GwU3xgvFefmh/AD2j5zz8I0t5YPwfan0=";
};
in
{
grammar.src = src;
grammar.compile.args = [ "-c" "-fpic" "../parser.c" "../scanner.c" "../unicode.h" "-I" ".." ];
queries.src = src;
queries.path = "queries";
};
yaml = {
grammar.src = pkgs.fetchFromGitHub {
owner = "ikatyang";
repo = "tree-sitter-yaml";
rev = "0e36bed171768908f331ff7dff9d956bae016efb";
hash = "sha256-bpiT3FraOZhJaoiFWAoVJX1O+plnIi8aXOW2LwyU23M=";
};
grammar.compile.args = [ "-c" "-fpic" "../scanner.cc" "../parser.c" "-I" ".." ];
grammar.link.args = [ "-shared" "-fpic" "scanner.o" "parser.o" ];
grammar.link.flags = [ "-O3" "-lstdc++" ];
queries.src = pkgs.fetchFromGitHub {
owner = "helix-editor";
repo = "helix";
rev = "dbd248fdfa680373d94fbc10094a160aafa0f7a7";
hash = "sha256-wk8qVUDFXhAOi1Ibc6iBMzDCXb6t+YiWZcTd0IJybqc=";
};
queries.path = "runtime/queries/yaml";
};
templ =
let
src = pkgs.fetchFromGitHub {
owner = "vrischmann";
repo = "tree-sitter-templ";
rev = "044ad200092170727650fa6d368df66a8da98f9d";
hash = "sha256-hJuB3h5pp+LLfP0/7bAYH0uLVo+OQk5jpzJb3J9BNkY=";
};
in
{
grammar.src = src;
queries.src = pkgs.runCommandLocal "templ-tree-sitter-queries" { } ''
mkdir -p $out/queries
# copy most stuff from tree-sitter-templ
install -m644 ${src}/queries/templ/* $out/queries
# override inherited files
cat ${tree-sitter-go}/queries/highlights.scm ${src}/queries/templ/highlights.scm > $out/queries/highlights.scm
'';
queries.path = "queries";
};
go = {
grammar.src = tree-sitter-go;
grammar.compile.args = [ "-c" "-fpic" "../parser.c" "-I" ".." ];
grammar.link.args = [ "-shared" "-fpic" "parser.o" ];
queries.src = tree-sitter-go;
queries.path = "queries";
};
};
programs.my-kakoune.package = kakounePkg;
hylo =
let
src = pkgs.fetchFromGitHub {
owner = "natsukagami";
repo = "tree-sitter-hylo";
rev = "494cbdff0d13cbc67348316af2efa0286dbddf6f";
hash = "sha256-R5UeoglCTl0do3VDJ/liCTeqbxU9slvmVKNRA/el2VY=";
};
in
{
grammar.src = src;
grammar.compile.args = [ "-c" "-fpic" "../parser.c" "-I" ".." ];
grammar.link.args = [ "-shared" "-fpic" "parser.o" ];
queries.src = src;
queries.path = "queries";
};
};
programs.my-kakoune.package = pkgs.kakoune;
programs.my-kakoune.rc =
builtins.readFile ./kakrc + ''
@ -211,11 +313,11 @@ in
'';
programs.my-kakoune.extraFaces = {
Default = "%opt{white},%opt{background}";
BufferPadding = "%opt{background},%opt{background}";
MenuForeground = "blue,white+bF";
MenuBackground = "bright-blue,white+F";
Information = "bright-blue,white";
Default = "%opt{text},%opt{base}";
BufferPadding = "%opt{base},%opt{base}";
MenuForeground = "%opt{blue},white+bF";
MenuBackground = "%opt{sky},white+F";
Information = "%opt{sky},white";
# Markdown help color scheme
InfoDefault = "Information";
InfoBlock = "@block";
@ -407,10 +509,7 @@ in
}
];
programs.my-kakoune.themes = {
catppuccin-latte = builtins.fetchurl {
url = "https://raw.githubusercontent.com/catppuccin/kakoune/f6d43770609433c45046632f1bb68d1395305dbb/colors/catppuccin_latte.kak";
sha256 = "sha256:0ycvxs8hmsvd0zrpxiby16wzmapvmz6p34b6j343pc1girw6fi4i";
};
catppuccin-latte = ./catppuccin-latte.kak;
};
}

View file

@ -1,36 +1,34 @@
# Enable kak-tree-sitter
eval %sh{ kak-tree-sitter --kakoune -d --server }
## Set some color overrides
set global kts_yellow "rgb:e2b75e"
set global kts_teal "rgb:008080"
set global kts_mauve "rgb:c264ff"
set global kts_sky "rgb:6aa622"
eval %sh{test -z "$WE_STARTED_KAK" && kak-tree-sitter --kakoune -d --server --init $kak_session}
map global normal <c-t> ": enter-user-mode tree-sitter<ret>"
# ## Set some color overrides
# set global kts_yellow "rgb:e2b75e"
# set global kts_teal "rgb:008080"
# set global kts_mauve "rgb:c264ff"
# set global kts_sky "rgb:6aa622"
# Color scheme
colorscheme catppuccin-latte
set global background default
set global base "default"
# Set indentation guides
add-highlighter global/indent-guides show-whitespaces -tab " " -spc " " -lf " " -nbsp " "
set-face global Whitespace default,default
set-face global WhitespaceIndent +d@comment
# Assistant
set global ui_options terminal_assistant=cat
# Enable line numbers
addhl global/ number-lines
hook global WinCreate .* %{
addhl window/number-lines number-lines
}
set global grepcmd "rg --line-number --no-column --no-heading --color=never "
# Floating terminal
# define-command floating-terminal -params 1 -docstring "Open a floating terminal running the given command" %{
# evaluate-commands -save-regs 'a' %{
# set-register a %arg{@}
# evaluate-commands %sh{
# alacritty \
# --class=alacritty,floating \
# -o window.dimensions.lines=24 \
# -o window.dimensions.columns=120 \
# -e sh -c "$kak_quoted_reg_a" < /dev/null > /dev/null 2>&1 &
# }
# }
# }
# map global user t -docstring "Open a side terminal on the current directory" ' :iterm-terminal-horizontal fish<ret>'
# Kitty-specific options
hook -group windowing global KakBegin .* %{
set global kitty_window_type os-window
}
# Comment line and block
map global normal <#> ': comment-line<ret>'
@ -43,9 +41,9 @@ map global goto f -docstring "current grep-jump match" '<esc>: grep-jump<ret>'
hook global RegisterModified '"' %{ nop %sh{
printf "%s" "$kak_main_reg_dquote" | pbcopy >/dev/null 2>/dev/null &
}}
map global user P -docstring "Paste before cursor from clipboard" '! pbpaste<ret>'
map global user p -docstring "Paste after cursor from clipboard" '<a-!> pbpaste<ret>'
map global user R -docstring "Replace selection with text from clipboard" '<a-d>! pbpaste<ret>'
map global user P -docstring "Paste before cursor from clipboard" '! pbpaste -n | cat<ret>'
map global user p -docstring "Paste after cursor from clipboard" '<a-!> pbpaste -n | cat<ret>'
map global user R -docstring "Replace selection with text from clipboard" '<a-d>! pbpaste -n | cat<ret>'
define-command -params 0 -docstring "Copy line down" copyline %{
execute-keys -draft 'xy'%val{count}'P'
}
@ -63,11 +61,13 @@ map global normal D ": delete-current-brackets<ret>"
# Tab sizes
hook global InsertChar \t %{ exec -draft -itersel h@ }
set global tabstop 4
set global indentwidth 4
hook global WinSetOption filetype=(c|cpp|haskell|nix|yaml) %{
set global tabstop 2
set global indentwidth 2
set global tabstop 2
set global indentwidth 2
# Language-specific tabstop with override
hook global WinSetOption filetype=(rust) %{
set window tabstop 4
set window indentwidth 4
}
# Ctrl + a in insert mode = esc
@ -93,8 +93,9 @@ hook global InsertCompletionHide .* %{
# Enable LSP
try %{
eval %sh{test -z "$WE_STARTED_KAK" && kak-lsp --kakoune -s $kak_session}
set-option global lsp_cmd "kak-lsp -s %val{session}"
}
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|fsharp|ocaml|haskell|nix|scala|typst|html|css|json) %{
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|fsharp|ocaml|haskell|nix|scala|typst|html|css|json|markdown|templ|elixir) %{
lsp-enable-window
map window lsp N -docstring "Display the next message request" ": lsp-show-message-request-next<ret>"
map window normal <c-l> ": enter-user-mode lsp<ret>"
@ -102,9 +103,16 @@ hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c
map window normal <c-s-h> ": lsp-hover-buffer<ret>"
# lsp-auto-hover-insert-mode-enable
set window lsp_hover_anchor true
map global insert <tab> '<a-;>:try lsp-snippets-select-next-placeholders catch %{ execute-keys -with-hooks <lt>tab> }<ret>' -docstring 'Select next snippet placeholder'
map global object a '<a-semicolon>lsp-object<ret>' -docstring 'LSP any symbol'
map global object <a-a> '<a-semicolon>lsp-object<ret>' -docstring 'LSP any symbol'
map global object f '<a-semicolon>lsp-object Function Method<ret>' -docstring 'LSP function or method'
map global object t '<a-semicolon>lsp-object Class Interface Struct<ret>' -docstring 'LSP class interface or struct'
map global object d '<a-semicolon>lsp-diagnostic-object --include-warnings<ret>' -docstring 'LSP errors and warnings'
map global object D '<a-semicolon>lsp-diagnostic-object<ret>' -docstring 'LSP errors'
}
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|haskell|nix|fsharp) %{
hook global WinSetOption filetype=(racket|rust|python|go|javascript|typescript|c|cpp|tex|latex|haskell|nix|fsharp|templ) %{
# Format the document if possible
hook window BufWritePre .* %{ lsp-formatting-sync }
}
@ -150,9 +158,6 @@ hook global WinSetOption filetype=(rust) %{
hook global WinSetOption filetype=(scala) %{
# Format the document if possible
hook -group scala-fmt window BufWritePre .* %{ lsp-formatting-sync }
set window tabstop 2
set window indentwidth 2
}
hook global WinSetOption filetype=(typst) %{
@ -210,6 +215,16 @@ hook global BufCreate .*[.]typ %{
add-highlighter buffer/ wrap
}
hook global BufCreate .*[.]templ %{
set-option buffer filetype templ
set-option buffer comment_line "//"
}
hook global BufCreate .*[.]hylo %{
set-option buffer filetype hylo
set-option buffer comment_line "//"
}
hook global BufOpenFile .* %{
modeline-parse
}

View file

@ -3,11 +3,11 @@
function usage
echo "Usage: "
echo " kaktex set [client] [session]"
echo " kaktex jump [file] [line]"
echo " kaktex jump [file] [line] [column]"
exit 1
end
if test (count $argv) -ne 3
if test (count $argv) -lt 3
usage
end
@ -19,7 +19,7 @@ switch $argv[1]
echo "
evaluate-commands -client $_kaktex_client %{
evaluate-commands -try-client $_kaktex_client %{
edit -- $argv[2] $argv[3]
edit -existing -- $argv[2] $(math $argv[3] + 1) $(math $argv[4] + 1)
}
}
" | kak -p $_kaktex_session

View file

@ -1,22 +1,12 @@
{ config, pkgs, lib, ... }:
let
kaktexScript = ./kaktex;
in
{
# Create kak-tex executable
home.file.kaktex = {
source = kaktexScript;
executable = true;
target = ".bin/kaktex";
};
# Source kaktex whenever we have a tex file
programs.my-kakoune.rc = ''
hook global WinSetOption filetype=(tex|latex) %{
hook window WinDisplay '.*' %{
eval %sh{
${kaktexScript} set $kak_client $kak_session
${./kaktex} set $kak_client $kak_session
}
}
}

View file

@ -1,18 +1,7 @@
{ pkgs, config, lib, ... }:
let
discord =
(pkgs.armcord.override { nss = pkgs.nss_latest; }).overrideAttrs (attrs: {
postInstall = ''
# Wrap the startup command
makeWrapper $out/opt/ArmCord/armcord $out/bin/armcord \
"''${gappsWrapperArgs[@]}" \
--prefix XDG_DATA_DIRS : "${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}/" \
--add-flags "--ozone-platform=x11 --enable-features=UseOzonePlatform --enable-features=WebRTCPipeWireCapturer" \
--prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath attrs.buildInputs}" \
--suffix PATH : ${lib.makeBinPath [ pkgs.xdg-utils ]}
'';
});
discord = pkgs.armcord.override { nss = pkgs.nss_latest; };
in
{
imports = [
@ -30,7 +19,7 @@ in
home.homeDirectory = "/home/nki";
nki.programs.kitty.enable = true;
nki.programs.kitty.fontSize = 18;
nki.programs.kitty.fontSize = 16;
programs.fish.shellInit = lib.mkAfter ''
set -eg MESA_GL_VERSION_OVERRIDE
set -eg MESA_GLSL_VERSION_OVERRIDE
@ -53,10 +42,6 @@ in
discord
typora
# Java & sbt
openjdk11
sbt
]);
# Graphical set up
@ -64,7 +49,7 @@ in
linux.graphical.wallpaper = ./images/wallpaper-macbook.jpg;
# Enable sway
programs.my-sway.enable = true;
programs.my-sway.fontSize = 12.0;
programs.my-sway.fontSize = 14.0;
programs.my-sway.enableLaptopBars = true;
programs.my-sway.enableMpd = false;
programs.my-sway.discord = "${discord}/bin/armcord";
@ -72,7 +57,7 @@ in
wayland.windowManager.sway.config.input."type:keyboard".xkb_layout = "jp";
wayland.windowManager.sway.config.output."eDP-1" = {
mode = "2560x1600@60Hz";
scale = "1.5";
scale = "1.25";
subpixel = "vrgb";
};
wayland.windowManager.sway.config.input."1452:641:Apple_Internal_Keyboard_/_Trackpad" = {
@ -112,7 +97,7 @@ in
home.file.".gnupg/gpg-agent.conf" = {
text = ''
pinentry-program ${pkgs.pinentry-gnome}/bin/pinentry-gnome3
pinentry-program ${pkgs.pinentry-gnome3}/bin/pinentry-gnome3
'';
onChange = ''
echo "Reloading gpg-agent"
@ -121,10 +106,6 @@ in
};
# Autostart
xdg.configFile."autostart/polkit.desktop".text = ''
${builtins.readFile "${pkgs.pantheon.pantheon-agent-polkit}/etc/xdg/autostart/io.elementary.desktop.agent-polkit.desktop"}
OnlyShowIn=sway;
'';
xdg.configFile."autostart/input-remapper-autoload.desktop".source =
"${pkgs.input-remapper}/share/applications/input-remapper-autoload.desktop";

View file

@ -3,9 +3,20 @@ with lib;
let
cfg = config.linux.graphical;
thunderbird = pkgs.thunderbird-128;
vscode = with pkgs; if stdenv.isAarch64 then unstable.vscode else unstable.vscode-fhs;
alwaysStartup = with pkgs; [ ];
wifi-indicator = pkgs.writeScriptBin "wifi-indicator" ''
#!/usr/bin/env fish
set wifi_output (${lib.getExe pkgs.iw} wlan0 link | rg "SSID: (.+)" --replace '🛜 $1' | string trim)
if test -z $wifi_output
echo " not connected"
else
echo $wifi_output
end
'';
in
{
imports = [ ./x11.nix ./wayland.nix ./alacritty.nix ];
@ -23,11 +34,16 @@ in
startup = mkOption {
type = types.listOf types.package;
description = "List of packages to include in ~/.config/autostart";
default = [ ];
default = with pkgs; [
librewolf
thunderbird
vesktop
premid
];
};
defaults.webBrowser = mkOption {
type = types.str;
default = "firefox.desktop";
default = "librewolf.desktop";
description = "Desktop file of the default web browser";
};
};
@ -42,29 +58,47 @@ in
feh # For images?
deluge # Torrent client
pavucontrol # PulseAudio control panel
firefox
librewolf
cinnamon.nemo # File manager
thunderbird # Email
sublime-music # For navidrome
# Note taking
obsidian
(logseq.override { electron = pkgs.electron_24; })
# cinny-desktop
gajim
vivaldi
# Audio
qpwgraph # Pipewire graph
zotero
unstable.zotero
libreoffice
mpv # for anki
anki-bin
# Chat stuff
tdesktop
whatsapp-for-linux
slack
zoom-us
librewolf
## CLI stuff
dex # .desktop file management, startup
# sct # Display color temperature
xdg-utils # Open stuff
] ++ (if pkgs.stdenv.isAarch64 then [ ] else [
gnome.cheese # Webcam check, expensive
# Chat stuff
unstable.slack
]));
wifi-indicator
]);
nki.programs.discord.enable = pkgs.stdenv.isx86_64;
nki.programs.discord.package = pkgs.vesktop;
# OBS
programs.obs-studio = {
enable = true;
plugins = with pkgs.obs-studio-plugins; [
wlrobs
input-overlay
obs-pipewire-audio-capture
];
};
# Yellow light!
services.wlsunset = {
@ -88,13 +122,33 @@ in
xdg.mimeApps.enable = true;
xdg.mimeApps.associations.added = {
"x-scheme-handler/mailto" = [ "org.gnome.Evolution.desktop" ];
"x-scheme-handler/mailto" = [ "thunderbird.desktop" "org.gnome.Evolution.desktop" ];
"application/pdf" = [ "org.gnome.Evince.desktop" ];
"text/plain" = [ "kakoune.desktop" ];
# Other Thunderbird stuff
"x-scheme-handler/mid" = [ "thunderbird.desktop" ];
"x-scheme-handler/news" = [ "thunderbird.desktop" ];
"x-scheme-handler/snews" = [ "thunderbird.desktop" ];
"x-scheme-handler/nntp" = [ "thunderbird.desktop" ];
"x-scheme-handler/feed" = [ "thunderbird.desktop" ];
"application/rss+xml" = [ "thunderbird.desktop" ];
"application/x-extension-rss" = [ "thunderbird.desktop" ];
};
xdg.mimeApps.defaultApplications = {
# Email
"x-scheme-handler/mailto" = [ "org.gnome.Evolution.desktop" ];
"x-scheme-handler/mailto" = [ "thunderbird.desktop" "org.gnome.Evolution.desktop" ];
"x-scheme-handler/webcal" = [ "thunderbird.desktop" ];
"x-scheme-handler/webcals" = [ "thunderbird.desktop" ];
# Other Thunderbird stuff
"x-scheme-handler/mid" = [ "thunderbird.desktop" ];
"x-scheme-handler/news" = [ "thunderbird.desktop" ];
"x-scheme-handler/snews" = [ "thunderbird.desktop" ];
"x-scheme-handler/nntp" = [ "thunderbird.desktop" ];
"x-scheme-handler/feed" = [ "thunderbird.desktop" ];
"application/rss+xml" = [ "thunderbird.desktop" ];
"application/x-extension-rss" = [ "thunderbird.desktop" ];
# Default web browser stuff
"text/html" = [ cfg.defaults.webBrowser ];
@ -104,6 +158,7 @@ in
"x-scheme-handler/https" = [ cfg.defaults.webBrowser ];
"x-scheme-handler/ftp" = [ cfg.defaults.webBrowser ];
"x-scheme-handler/ftps" = [ cfg.defaults.webBrowser ];
"x-scheme-handler/file" = [ cfg.defaults.webBrowser ];
# Torrent
"application/x-bittorrent" = [ "deluge.desktop" ];
@ -111,10 +166,10 @@ in
# Text
"text/plain" = [ "kakoune.desktop" ];
"application/pdf" = [ "org.gnome.Evince.desktop" ];
"application/pdf" = [ "okularApplication_pdf.desktop" ];
# Files
"inode/directory" = [ "nemo.desktop" ];
"inode/directory" = [ "dolphin.desktop" ];
};
# Add one for kakoune
@ -133,26 +188,37 @@ in
## GTK
gtk.enable = true;
gtk.cursorTheme = { inherit (config.home.pointerCursor) package name size; };
gtk.font.name = "system-ui";
gtk.font.name = "IBM Plex Sans JP";
gtk.font.size = 10;
gtk.iconTheme = {
package = pkgs.numix-icon-theme;
name = "Numix";
package = pkgs.kdePackages.breeze-icons;
name = "breeze";
};
gtk.theme = {
package = pkgs.numix-gtk-theme;
name = "Numix";
package = pkgs.kdePackages.breeze-gtk;
name = "Breeze";
};
gtk.gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc";
gtk.gtk2.extraConfig = ''
gtk-enable-animations=1
gtk-im-module="fcitx"
gtk-theme-name="Numix"
gtk-primary-button-warps-slider=1
gtk-toolbar-style=3
gtk-menu-images=1
gtk-button-images=1
gtk-sound-theme-name="ocean"
gtk-icon-theme-name="breeze"
'';
gtk.gtk3.extraConfig.gtk-im-module = "fcitx";
gtk.gtk4.extraConfig.gtk-im-module = "fcitx";
## Qt
qt.enable = true;
qt.platformTheme = "gnome";
qt.style.package = pkgs.adwaita-qt;
qt.style.name = "adwaita";
qt.platformTheme.name = "kde";
qt.platformTheme.package = with pkgs.kdePackages; [ plasma-integration systemsettings ];
qt.style.package = [ pkgs.kdePackages.breeze ];
qt.style.name = "Breeze";
home.sessionVariables = {
# Set up Java font style
_JAVA_OPTIONS = "-Dawt.useSystemAAFontSettings=lcd";
};
xdg.configFile =
let
@ -162,17 +228,22 @@ in
source =
let
srcFile = pkgs.runCommand "${pkg.name}-startup" { } ''
mkdir - p $out
cp $
(ls - d ${
pkg}/share/applications/*.desktop | head -n 1) $out/${pkg.name}.desktop
mkdir -p $out
cp $(ls -d ${pkg}/share/applications/*.desktop | head -n 1) $out/${pkg.name}.desktop
'';
in
"${srcFile}/${pkg.name}.desktop";
};
};
autoStartup = listToAttrs (map f cfg.startup);
in
listToAttrs (map f (cfg.startup ++ alwaysStartup));
autoStartup // {
## Polkit UI
"autostart/polkit.desktop".text = ''
${builtins.readFile "${pkgs.pantheon.pantheon-agent-polkit}/etc/xdg/autostart/io.elementary.desktop.agent-polkit.desktop"}
OnlyShowIn=sway;
'';
};
# IBus configuration
# dconf.settings."desktop/ibus/general" = {
# engines-order = hm.gvariant.mkArray hm.gvariant.type.string [ "xkb:jp::jpn" "mozc-jp" "Bamboo" ];

View file

@ -2,31 +2,19 @@
let
notificationModule = { config, pkgs, lib, ... }:
let
swaync = pkgs.unstable.swaynotificationcenter;
swaync = pkgs.swaynotificationcenter;
in
with lib; mkIf (config.linux.graphical.type == "wayland") {
home.packages = [ swaync ];
wayland.windowManager.sway.config = {
startup = [
{ command = "swaync"; }
];
};
xdg.configFile = {
"swaync/config.json" = {
text = builtins.toJSON {
widgets = [ "inhibitors" "title" "dnd" "mpris" "notifications" ];
scripts = { };
};
onChange = "swaync-client -R";
};
"swaync/style.css" = {
source = ./swaync.css;
onChange = "swaync-client -rs";
};
services.swaync = {
enable = true;
settings.widgets = [ "inhibitors" "title" "dnd" "mpris" "notifications" ];
style = ./swaync.css;
};
systemd.user.services.swaync.Install.WantedBy = lib.mkForce [ "sway-session.target" ];
systemd.user.services.swaync.Unit.PartOf = lib.mkForce [ "sway-session.target" ];
programs.my-sway.waybar = {
extraSettings = {
extraSettings = [{
modules-right = mkAfter [ "custom/swaync" ];
modules."custom/swaync" = {
tooltip = false;
@ -48,21 +36,35 @@ let
on-click-right = "${swaync}/bin/swaync-client -d -sw";
escape = true;
};
};
}];
extraStyle = mkAfter ''
#custom-swaync {
padding: 0 10px;
margin: 0 5px;
background: #F0FFFF;
color: #000000;
}
'';
};
};
plasmaModule = { pkgs, ... }: {
home.packages = with pkgs.kdePackages; [
discover
kmail
kontact
akonadi
kdepim-runtime
kmail-account-wizard
akonadi-import-wizard
];
xdg.configFile."plasma-workspace/env/wayland.sh".source = pkgs.writeScript "plasma-wayland-env.sh" ''
export NIXOS_OZONE_WL=1
'';
xdg.dataFile."dbus-1/services/org.freedesktop.Notifications.service".source = "${pkgs.kdePackages.plasma-workspace}/share/dbus-1/services/org.kde.plasma.Notifications.service";
};
in
with lib;
{
imports = [ notificationModule ];
imports = [ notificationModule plasmaModule ];
config = mkIf (config.linux.graphical.type == "wayland") {
# Additional packages
home.packages = with pkgs; [
@ -70,13 +72,17 @@ with lib;
# Mimic the clipboard stuff in MacOS
(pkgs.writeShellScriptBin "pbcopy" ''
exec ${pkgs.wl-clipboard}/bin/wl-copy
exec ${pkgs.wl-clipboard}/bin/wl-copy "$@"
'')
(pkgs.writeShellScriptBin "pbpaste" ''
exec ${pkgs.wl-clipboard}/bin/wl-paste -n
exec ${pkgs.wl-clipboard}/bin/wl-paste "$@"
'')
];
home.sessionVariables = {
ANKI_WAYLAND = "1";
};
# Notification system
# services.dunst = {
# enable = true;

View file

@ -3,6 +3,11 @@
let
monitors = {
# Internal
"framework" = {
name = "BOE 0x0BCA Unknown";
mode = "2256x1504@60Hz";
scale = 1.25;
};
# External
## Work @ EPFL
"work" = {

View file

@ -44,14 +44,16 @@ in
set -gx EDITOR "kak"
alias e="kak"
'';
_tide_item_kakoune = ''
};
programs.fish.tide = {
items.kakoune = ''
if set -q kak_session
set -U tide_kakoune_color FFA500
set -U tide_kakoune_bg_color normal
_tide_print_item kakoune " " "e[$kak_session]"
end
'';
rightItems = mkAfter [ "kakoune" ];
};
};
}

View file

@ -4,52 +4,23 @@ with lib;
let
lspConfig =
{
language = {
bash = {
args = [ "start" ];
command = "bash-language-server";
filetypes = [ "sh" ];
roots = [ ".git" ".hg" ];
};
c_cpp = {
language_ids = {
c = "c_cpp";
cpp = "c_cpp";
javascript = "javascriptreact";
typescript = "typescriptreact";
protobuf = "proto";
sh = "shellscript";
};
language_servers = {
ccls = {
args = [ "-v=2" "-log-file=/tmp/ccls.log" ];
command = "ccls";
filetypes = [ "c" "cpp" ];
roots = [ "compile_commands.json" ".cquery" ".git" ];
};
crystal = {
command = "scry";
filetypes = [ "crystal" ];
roots = [ "shard.yml" ];
};
css = {
args = [ "--stdio" ];
command = "css-languageserver";
filetypes = [ "css" ];
roots = [ "package.json" ];
};
d = {
command = "dls";
filetypes = [ "d" "di" ];
roots = [ ".git" "dub.sdl" "dub.json" ];
};
dart = {
command = "dart_language_server";
filetypes = [ "dart" ];
roots = [ "pubspec.yaml" ".git" ];
};
elm = {
args = [ "--stdio" ];
command = "elm-language-server";
filetypes = [ "elm" ];
roots = [ "elm.json" ];
};
fsharp = {
command = "FSharpLanguageServer";
filetypes = [ "fsharp" ];
roots = [ ".git" "*.fsx" ];
};
go = {
gopls = {
command = "gopls";
filetypes = [ "go" ];
offset_encoding = "utf-8";
@ -57,101 +28,27 @@ let
settings = { gopls = { hoverKind = "SynopsisDocumentation"; semanticTokens = true; }; };
settings_section = "gopls";
};
haskell = {
haskell-language-server = {
args = [ "--lsp" ];
command = "haskell-language-server-wrapper";
filetypes = [ "haskell" ];
roots = [ "Setup.hs" "stack.yaml" "*.cabal" "package.yaml" ];
settings_section = "haskell";
};
html = {
args = [ "--stdio" ];
command = "html-languageserver";
filetypes = [ "html" ];
roots = [ "package.json" ];
};
javascript = {
args = [ "lsp" ];
command = "flow";
filetypes = [ "javascript" ];
roots = [ ".flowconfig" ];
};
json = {
args = [ "--stdio" ];
command = "json-languageserver";
filetypes = [ "json" ];
roots = [ "package.json" ];
};
latex = {
command = "texlab";
filetypes = [ "latex" ];
roots = [ ".git" "main.tex" "all.tex" ];
settings_section = "texlab";
settings.texlab = {
build.executable = "latexmk";
build.args = [ "-pdf" "-shell-escape" "-interaction=nonstopmode" "-synctex=1" "%f" ];
build.forwardSearchAfter = true;
build.onSave = true;
forwardSearch = {
executable = "/Applications/Skim.app/Contents/SharedSupport/displayline";
args = [ "-r" "-g" "%l" "%p" "%f" ];
};
};
};
nim = {
command = "nimlsp";
filetypes = [ "nim" ];
roots = [ "*.nimble" ".git" ];
};
nix = {
command = "rnix-lsp";
nil = {
command = "${pkgs.nil}/bin/nil";
filetypes = [ "nix" ];
roots = [ "flake.nix" "shell.nix" ".git" ];
settings.nil = {
formatting.command = [ "${getExe pkgs.nixpkgs-fmt}" ];
};
};
ocaml = {
args = [ ];
command = "ocamllsp";
filetypes = [ "ocaml" ];
roots = [ "Makefile" "opam" "*.opam" "dune" ".merlin" ".ocamlformat" ];
};
php = {
args = [ "--stdio" ];
command = "intelephense";
filetypes = [ "php" ];
roots = [ ".htaccess" "composer.json" ];
};
python = {
pyls = {
command = "pyls";
filetypes = [ "python" ];
offset_encoding = "utf-8";
roots = [ "requirements.txt" "setup.py" ".git" ".hg" ];
};
racket = {
args = [ "-l" "racket-langserver" ];
command = "racket";
filetypes = [ "racket" ];
roots = [ ".git" ];
};
reason = {
args = [ "--stdio" ];
command = "ocaml-language-server";
filetypes = [ "reason" ];
roots = [ "package.json" "Makefile" ".git" ".hg" ];
};
ruby = {
args = [ "stdio" ];
command = "solargraph";
filetypes = [ "ruby" ];
roots = [ "Gemfile" ];
};
rust = {
args = [ ];
command = "rust-analyzer";
filetypes = [ "rust" ];
roots = [ "Cargo.toml" ];
};
};
semantic_tokens.faces = [
## Items
@ -188,7 +85,7 @@ let
verbosity = 255;
};
languageOption = types.submodule {
languageServerOption = types.submodule {
options = {
filetypes = mkOption {
type = types.listOf types.str;
@ -222,10 +119,28 @@ let
default = null;
description = "Additional settings to be passed to the LSP server.";
};
package = mkOption {
type = types.nullOr types.package;
default = null;
description = "The default package of the language server. Will be appended as the ending segments of the PATH to kak-lsp";
};
};
};
cfg = config.programs.kak-lsp;
serverPackages =
filter (v: v != null)
(lib.mapAttrsToList (_: serv: serv.package) cfg.languageServers);
wrappedPackage = pkgs.symlinkJoin {
name = "kak-lsp-wrapped";
nativeBuildInputs = [ pkgs.makeWrapper ];
paths = [ cfg.package ];
postBuild = ''
wrapProgram $out/bin/kak-lsp --suffix PATH ":" ${lib.makeBinPath serverPackages}
'';
};
in
{
options.programs.kak-lsp = {
@ -259,35 +174,40 @@ in
description = "Server timeout";
};
languages = mkOption {
type = types.attrsOf languageOption;
languageServers = mkOption {
type = types.attrsOf languageServerOption;
default = { };
description = "The language options";
};
languageIds = mkOption {
type = types.attrsOf types.str;
default = { };
description = "Language IDs to be sent to the LSP";
};
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
config = mkIf cfg.enable
{
home.packages = [ wrappedPackage ];
# Configurations
xdg.configFile."kak-lsp/kak-lsp.toml" = {
source = pkgs.runCommand "config.toml"
# Configurations
xdg.configFile."kak-lsp/kak-lsp.toml" =
let
toml = pkgs.formats.toml { };
toLspConfig = lib.filterAttrsRecursive (n: v: n != "package" && v != null);
in
{
buildInputs = [ pkgs.yj ];
preferLocalBuild = true;
} ''
yj -jt -i \
< ${
pkgs.writeText "config.json" (builtins.toJSON {
source = toml.generate "config.toml"
{
semantic_tokens.faces = cfg.semanticTokens.faces ++ cfg.semanticTokens.additionalFaces;
server.timeout = cfg.serverTimeout;
snippet_support = cfg.enableSnippets;
verbosity = 255;
language = lspConfig.language // cfg.languages;
})
} \
> $out
'';
language_server = toLspConfig (lspConfig.language_servers // cfg.languageServers);
language_ids = lspConfig.language_ids // cfg.languageIds;
};
};
};
};
}

View file

@ -43,83 +43,96 @@ in
};
package = mkPackageOption pkgs "kak-tree-sitter" { };
features = {
highlighting = mkOption {
type = types.bool;
description = "Enable highlighting";
default = true;
};
text_objects = mkOption {
type = types.bool;
description = "Enable text objects";
default = true;
};
};
highlighterGroups = mkOption {
type = types.attrsOf types.str;
default = {
attribute = "@attribute";
comment = "@comment";
conceal = "%opt{kts_mauve}+i";
constant = "%opt{kts_peach}";
constant_builtin_boolean = "%opt{kts_sky}";
constant_character = "%opt{kts_yellow}";
constant_macro = "%opt{kts_mauve}";
constant_numeric = "%opt{kts_peach}";
constructor = "%opt{kts_sapphire}";
diff_plus = "%opt{kts_green}";
diff_minus = "%opt{kts_red}";
diff_delta = "%opt{kts_blue}";
diff_delta_moved = "%opt{kts_mauve}";
error = "%opt{kts_red}+b";
conceal = "%opt{mauve}+i";
constant = "%opt{peach}";
constant_builtin_boolean = "%opt{sky}";
constant_character = "%opt{yellow}";
constant_macro = "%opt{mauve}";
constant_numeric = "%opt{peach}";
constructor = "%opt{sapphire}";
diff_plus = "%opt{green}";
diff_minus = "%opt{red}";
diff_delta = "%opt{blue}";
diff_delta_moved = "%opt{mauve}";
error = "%opt{red}+b";
function = "@function";
function_builtin = "@builtin";
function_macro = "+i@ts_function";
hint = "%opt{kts_blue}+b";
info = "%opt{kts_green}+b";
hint = "%opt{blue}+b";
info = "%opt{green}+b";
keyword = "keyword";
keyword_conditional = "+i@ts_keyword";
keyword_control_conditional = "+i@ts_keyword";
keyword_control_directive = "+i@ts_keyword";
keyword_control_import = "+i@ts_keyword";
keyword_directive = "+i@ts_keyword";
label = "%opt{kts_sapphire}+i";
markup_bold = "%opt{kts_peach}+b";
markup_heading = "%opt{kts_red}";
markup_heading_1 = "%opt{kts_red}";
markup_heading_2 = "%opt{kts_mauve}";
markup_heading_3 = "%opt{kts_green}";
markup_heading_4 = "%opt{kts_yellow}";
markup_heading_5 = "%opt{kts_pink}";
markup_heading_6 = "%opt{kts_teal}";
markup_heading_marker = "%opt{kts_peach}+b";
markup_italic = "%opt{kts_pink}+i";
markup_list_checked = "%opt{kts_green}";
markup_list_numbered = "%opt{kts_blue}+i";
markup_list_unchecked = "%opt{kts_teal}";
markup_list_unnumbered = "%opt{kts_mauve}";
markup_link_label = "%opt{kts_blue}";
markup_link_url = "%opt{kts_teal}+u";
markup_link_uri = "%opt{kts_teal}+u";
markup_link_text = "%opt{kts_blue}";
markup_quote = "%opt{kts_gray1}";
markup_raw = "%opt{kts_sky}";
markup_raw_block = "%opt{kts_sky}";
markup_raw_inline = "%opt{kts_green}";
markup_strikethrough = "%opt{kts_gray1}+s";
label = "%opt{sapphire}+i";
markup_bold = "%opt{peach}+b";
markup_heading = "%opt{red}";
markup_heading_1 = "%opt{red}";
markup_heading_2 = "%opt{mauve}";
markup_heading_3 = "%opt{green}";
markup_heading_4 = "%opt{yellow}";
markup_heading_5 = "%opt{pink}";
markup_heading_6 = "%opt{teal}";
markup_heading_marker = "%opt{peach}+b";
markup_italic = "%opt{pink}+i";
markup_list_checked = "%opt{green}";
markup_list_numbered = "%opt{blue}+i";
markup_list_unchecked = "%opt{teal}";
markup_list_unnumbered = "%opt{mauve}";
markup_link_label = "%opt{blue}";
markup_link_url = "%opt{teal}+u";
markup_link_uri = "%opt{teal}+u";
markup_link_text = "%opt{blue}";
markup_quote = "%opt{crust}";
markup_raw = "%opt{sky}";
markup_raw_block = "%opt{sky}";
markup_raw_inline = "%opt{green}";
markup_strikethrough = "%opt{crust}+s";
namespace = "@module";
operator = "@operator";
property = "%opt{kts_sky}";
punctuation = "%opt{kts_overlay2}";
punctuation_special = "%opt{kts_sky}";
special = "%opt{kts_blue}";
spell = "%opt{kts_mauve}";
string = "%opt{kts_green}";
string_regex = "%opt{kts_peach}";
string_regexp = "%opt{kts_peach}";
string_escape = "%opt{kts_mauve}";
string_special = "%opt{kts_blue}";
string_special_path = "%opt{kts_green}";
string_special_symbol = "%opt{kts_mauve}";
string_symbol = "%opt{kts_red}";
tag = "%opt{kts_teal}";
tag_error = "%opt{kts_red}";
text_title = "%opt{kts_mauve}";
type = "%opt{kts_yellow}";
type_enum_variant = "%opt{kts_flamingo}";
property = "%opt{sky}";
punctuation = "%opt{overlay2}";
punctuation_special = "%opt{sky}";
special = "%opt{blue}";
spell = "%opt{mauve}";
string = "%opt{green}";
string_regex = "%opt{peach}";
string_regexp = "%opt{peach}";
string_escape = "%opt{mauve}";
string_special = "%opt{blue}";
string_special_path = "%opt{green}";
string_special_symbol = "%opt{mauve}";
string_symbol = "%opt{red}";
tag = "%opt{teal}";
tag_error = "%opt{red}";
text_title = "%opt{mauve}";
type = "@type";
type_enum_variant = "+i@ts_type";
variable = "@variable";
variable_builtin = "@builtin";
variable_other_member = "%opt{kts_teal}";
variable_parameter = "%opt{kts_maroon}+i";
warning = "%opt{kts_peach}+b";
variable_other_member = "%opt{teal}";
variable_parameter = "+i@variable";
warning = "%opt{peach}+b";
};
};
@ -174,8 +187,6 @@ in
config =
let
aliasedOnce = name: values: if asserts.assertMsg (builtins.length values 1) "face ${name} was aliased more than once: ${toString values}" then (builtins.head values) else [ ];
allGroups = attrsets.recursiveUpdate cfg.highlighterGroups cfg.extraHighlighterGroups;
aliases = attrsets.recursiveUpdate cfg.aliases cfg.extraAliases;
@ -189,10 +200,24 @@ in
toml = pkgs.formats.toml { };
srcName = src: lib.removePrefix "/nix/store/" src.outPath;
mkGitRepo = src: pkgs.runCommandLocal "${src.name}-git" { } ''
cp -r --no-preserve=all ${src} $out
cd $out
if ! test -d $out/.git; then
${lib.getExe pkgs.git} init -b ${srcName src}
${lib.getExe pkgs.git} config user.email "a@b.com"
${lib.getExe pkgs.git} config user.name "a"
${lib.getExe pkgs.git} add .
${lib.getExe pkgs.git} commit -m "Just making a git commit"
fi
'';
toLanguageConf = name: lang: with lang; {
grammar = {
inherit (grammar) path;
url = "${grammar.src}";
source.git.url = "${mkGitRepo grammar.src}";
source.git.pin = "${srcName grammar.src}";
compile = grammar.compile.command;
compile_args = grammar.compile.args;
compile_flags = grammar.compile.flags;
@ -201,7 +226,8 @@ in
link_flags = grammar.link.flags;
};
queries = {
url = "${queries.src}";
source.git.url = "${mkGitRepo queries.src}";
source.git.pin = "${srcName queries.src}";
path = if queries.path == null then "runtime/queries/${name}" else queries.path;
};
};
@ -220,19 +246,14 @@ in
xdg.configFile."kak-tree-sitter/config.toml" = {
source = toml.generate "config.toml" {
highlight.groups = builtins.map toScm (builtins.attrNames allGroups ++ builtins.attrNames aliases);
features = cfg.features;
language = builtins.mapAttrs toLanguageConf cfg.languages;
};
onChange =
let
buildCmd = lang: "ktsctl -fci ${lang}";
buildAll = strings.concatMapStringsSep "\n" buildCmd (builtins.attrNames cfg.languages);
in
''
# Rebuild languages
${buildAll}
'';
onChange = ''
export PATH=$PATH:${lib.getBin pkgs.gcc}
${cfg.package}/bin/ktsctl sync -a
'';
};
programs.my-kakoune.extraFaces = faces;

View file

@ -2,11 +2,20 @@
let
cfg = config.nki.programs.kitty;
cmd = if pkgs.stdenv.isDarwin then "cmd" else "ctrl";
theme = { lib, options, config, ... }: {
programs.kitty = lib.mkIf config.nki.programs.kitty.enable (
if builtins.hasAttr "themeFile" options.programs.kitty then {
themeFile = "ayu_light";
} else {
theme = "Ayu Light";
}
);
};
in
with lib;
{
imports = [ ./darwin.nix ./linux.nix ./tabs.nix ];
imports = [ theme ./darwin.nix ./linux.nix ./tabs.nix ];
options.nki.programs.kitty = {
enable = mkEnableOption "Enable kitty";
@ -51,8 +60,6 @@ with lib;
font.name = "Fantasque Sans Mono";
font.size = cfg.fontSize;
theme = "Ayu Light";
settings =
let
# Background color and transparency
@ -93,6 +100,18 @@ with lib;
## Hints
"${cfg.cmd}+shift+p>n" = "kitten hints --type=linenum --linenum-action=tab kak {path} +{line}";
};
extraConfig =
let
# Nerd Fonts glyph map
glyphMap = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/Sharparam/dotfiles/main/kitty/.config/kitty/font-nerd-symbols.conf";
hash = "sha256-1OaDWLC3y8ASD2ttRWWgPEpRnfKXu6H6vS3cFVpzT0o=";
};
in
''
include ${glyphMap}
'';
};
}

View file

@ -1,4 +1,4 @@
{ pkgs, lib, config, ... }:
{ pkgs, lib, options, config, osConfig, ... }:
with lib;
let
cfg = config.programs.my-sway;
@ -18,6 +18,9 @@ let
"9:🔨 9"
"10:🎲 misc"
];
extraWorkspaces = {
mail = "📧 Email";
};
wsAttrs = builtins.listToAttrs (
map
(i: { name = toString (remainder i 10); value = builtins.elemAt workspaces (i - 1); })
@ -42,6 +45,12 @@ let
${pkgs.grim}/bin/grim -g (${pkgs.slurp}/bin/slurp) - | ${pkgs.swappy}/bin/swappy -f -
'';
rofi-rbw-script = pkgs.writeShellApplication {
name = "rofi-rbw-script";
runtimeInputs = with pkgs; [ rofi wtype rofi-rbw ];
text = "rofi-rbw";
};
ignored-devices = [ "Surface_Headphones" ];
playerctl = "${pkgs.playerctl}/bin/playerctl --ignore-player=${strings.concatStringsSep "," ignored-devices}";
@ -75,11 +84,6 @@ in
description = "The command for the browser";
default = "${pkgs.firefox-wayland}/bin/firefox";
};
discord = mkOption {
type = types.nullOr types.str;
description = "The command for discord";
default = "${config.nki.programs.discord.package}/bin/discord";
};
lockCmd = mkOption {
type = types.str;
@ -106,12 +110,12 @@ in
default = barWith: [ (barWith { }) ];
};
extraSettings = mkOption {
type = types.raw;
type = types.listOf types.raw;
description = "Extra settings to be included with every default bar";
default = { };
default = [ ];
};
extraStyle = mkOption {
type = types.str;
type = types.lines;
description = "Additional style for the default waybar";
default = "";
};
@ -120,8 +124,20 @@ in
config.wayland.windowManager.sway = mkIf cfg.enable {
enable = true;
systemdIntegration = true;
systemd.enable = true;
systemd.variables = options.wayland.windowManager.sway.systemd.variables.default ++ [
"PATH" # for portals
"XDG_DATA_DIRS" # For extra icons
"XDG_DATA_HOME" # For extra icons
] ++ lib.optionals osConfig.services.desktopManager.plasma6.enable [
"XDG_MENU_PREFIX"
];
systemd.extraCommands = options.wayland.windowManager.sway.systemd.extraCommands.default
++ [
"systemctl --user restart xdg-desktop-portal.service"
];
checkConfig = false; # Not working atm
config = {
### Inputs
#
@ -152,16 +168,9 @@ in
{ command = "${pkgs.dex}/bin/dex -ae sway"; }
# Waybar
{ command = "systemctl --user restart waybar"; always = true; }
# Startup programs
{ command = "${cfg.browser}"; }
{ command = "thunderbird"; } # Rely on system package with plugins
] ++ (if cfg.discord != null then [
{ command = "${cfg.discord}"; }
] ++ lib.lists.optional
(!pkgs.stdenv.isAarch64)
(
{ command = "${pkgs.premid}/bin/premid"; }
) else [ ]);
# IME
{ command = "fcitx5"; }
];
### Keybindings
#
@ -214,6 +223,7 @@ in
# Launcher
"${mod}+space" = "exec rofi -show drun";
"${mod}+tab" = "exec ${./rofi-window.py}";
"${mod}+shift+p" = "exec ${lib.getExe rofi-rbw-script}";
} // {
## Splits
"${mod}+v" = "split v";
@ -255,6 +265,11 @@ in
])
(builtins.attrNames wsAttrs))
)) //
{
# Extra workspaces
"${mod}+asciicircum" = "workspace ${extraWorkspaces.mail}";
"${mod}+shift+asciicircum" = "move to workspace ${extraWorkspaces.mail}";
} //
# Move workspaces between outputs
{
"${mod}+ctrl+h" = "move workspace to output left";
@ -286,17 +301,32 @@ in
];
"${builtins.elemAt workspaces 1}" = [
{ class = "^((d|D)iscord|((A|a)rm(c|C)ord))$"; }
{ class = "VencordDesktop"; }
{ app_id = "VencordDesktop"; }
{ class = "vesktop"; }
{ app_id = "vesktop"; }
];
"📧 Email" = [
${extraWorkspaces.mail} = [
{ app_id = "thunderbird"; }
{ app_id = "evolution"; }
];
};
# Commands
window.commands = [
{ criteria = { title = ".*"; }; command = "inhibit_idle fullscreen"; }
{ criteria = { app_id = ".*float.*"; }; command = "floating enable"; }
{ criteria = { class = ".*float.*"; }; command = "floating enable"; }
];
] ++ (
# Floating assignments
let
criterias = [
{ app_id = ".*float.*"; }
{ app_id = "org\\.freedesktop\\.impl\\.portal\\.desktop\\..*"; }
{ class = ".*float.*"; }
{ title = "Extension: .*Bitwarden.*"; }
];
toCommand = criteria: { inherit criteria; command = "floating enable"; };
in
map toCommand criterias
);
# Focus
focus.followMouse = true;
focus.mouseWarping = true;
@ -319,16 +349,21 @@ in
swaynag.enable = true;
# Environment Variables
extraSessionCommands = ''
export MOZ_ENABLE_WAYLAND=1
export SDL_VIDEODRIVER=wayland
export QT_QPA_PLATFORM=wayland
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
export QT_IM_MODULE=fcitx
export GTK_IM_MODULE=fcitx # Til text-input is merged
# export NIXOS_OZONE_WL=1 # Until text-input is merged
'' + (if config.services.gnome-keyring.enable then ''
# gnome-keyring
eval `gnome-keyring-daemon`
export SSH_AUTH_SOCK
'' else "");
if type gnome-keyring-daemon >/dev/null; then
eval `gnome-keyring-daemon`
export SSH_AUTH_SOCK
fi
'' else "") + lib.optionalString osConfig.services.desktopManager.plasma6.enable ''
export XDG_MENU_PREFIX=plasma-
'';
# Extra
wrapperFeatures.base = true;
wrapperFeatures.gtk = true;
@ -360,27 +395,26 @@ in
'' + ''
# Enable portal stuff
exec ${pkgs.writeShellScript "start-portals.sh" ''
# Import the WAYLAND_DISPLAY env var from sway into the systemd user session.
dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
# Stop any services that are running, so that they receive the new env var when they restart.
systemctl --user stop pipewire pipewire-media-session xdg-desktop-portal xdg-desktop-portal-wlr
systemctl --user start pipewire-media-session
''}
'';
};
config.services.swayidle = mkIf cfg.enable {
enable = true;
systemdTarget = "sway-session.target";
timeouts = [
# Lock after 15 minutes of idle
{ timeout = 15 * 60; command = cfg.lockCmd; }
# { timeout = 15 * 60; command = cfg.lockCmd; }
];
events = [
{ event = "lock"; command = cfg.lockCmd; }
{ event = "before-sleep"; command = cfg.lockCmd; }
];
};
config.programs.waybar =
let
barWith = { showMedia ? true, showConnectivity ? true, extraSettings ? { }, ... }: (mkMerge [{
barWith = { showMedia ? true, showConnectivity ? true, extraSettings ? { }, ... }: mkMerge ([{
position = "top";
modules-left = [
"sway/workspaces"
@ -391,7 +425,7 @@ in
];
modules-right =
lib.optional showMedia (if cfg.enableMpd then "mpd" else "custom/media")
++ [
++ [
"tray"
"pulseaudio"
] ++ lib.optionals showConnectivity [
@ -402,7 +436,7 @@ in
"memory"
"temperature"
] ++ lib.optionals cfg.enableLaptopBars [ "battery" "battery#bat2" ]
++ [
++ [
"clock"
];
@ -432,8 +466,35 @@ in
spacing = 10;
};
"clock" = {
tooltip-format = "{:%Y-%m-%d | %H:%M}";
format-alt = "{:%Y-%m-%d}";
# format = "{:📅 %Y-%m-%d | 🕰️ %H:%M [%Z]}";
format = "📅 {0:%Y-%m-%d} | 🕰 {0:%H:%M [%Z]}";
tooltip-format = "\n<span size='9pt' font_family='Noto Sans Mono CJK JP'>{calendar}</span>";
timezones = [
"Europe/Zurich"
"America/Toronto"
"Asia/Tokyo"
"Asia/Ho_Chi_Minh"
];
calendar = {
mode = "year";
mode-mon-col = 3;
weeks-pos = "right";
on-scroll = 1;
on-click-right = "mode";
format = {
months = "<span color='#ffead3'><b>{}</b></span>";
days = "<span color='#ecc6d9'><b>{}</b></span>";
weeks = "<span color='#99ffdd'><b>W{}</b></span>";
weekdays = "<span color='#ffcc66'><b> </b></span>"; # See https://github.com/Alexays/Waybar/issues/3132
today = "<span color='#ff6699'><b><u>{}</u></b></span>";
};
};
actions = {
on-click-middle = "mode";
on-click-right = "tz_up";
on-scroll-up = "shift_up";
on-scroll-down = "shift_down";
};
};
"cpu" = {
format = "{usage}% ";
@ -542,13 +603,14 @@ in
"on-click" = "${playerctl} play-pause";
};
};
}
cfg.waybar.extraSettings
extraSettings]);
}] ++
cfg.waybar.extraSettings
++ [ extraSettings ]);
in
mkIf cfg.enable {
enable = true;
systemd.enable = true;
systemd.target = "sway-session.target";
settings = cfg.waybar.makeBars barWith;
style = ''
* {
@ -586,7 +648,8 @@ in
}
#window, #sway, #sway-window {
padding: 0 10px;
padding-left: 1em;
margin-bottom: 0.4em;
}
#mode {
@ -594,9 +657,16 @@ in
border-bottom: 3px solid #ffffff;
}
#clock, #battery, #cpu, #memory, #temperature, #backlight, #network, #pulseaudio, #bluetooth, #custom-media, #tray, #mode, #idle_inhibitor, #mpd {
padding: 0 10px;
margin: 0 5px;
/* #clock, #battery, #cpu, #memory, #temperature, #backlight, #network, #pulseaudio, #bluetooth, #custom-media, #tray, #mode, #idle_inhibitor, #mpd { */
.modules-right > * > * {
margin: 0.2em 0 0.4em 0;
padding: 0.2em 0.5em;
border: 1px solid rgba(0, 0, 0, 0.25);
border-radius: 0.3em;
}
.modules-right > *:not(:last-child) > * {
margin-right: 0.4em;
}
#clock {
@ -707,7 +777,7 @@ in
};
config.home.packages = mkIf cfg.enable (with pkgs; [
# Needed for QT_QPA_PLATFORM
qt5.qtwayland
kdePackages.qtwayland
# For waybar
font-awesome
]);

View file

@ -4,12 +4,15 @@ let
name = "openconnect-epfl";
runtimeInputs = with pkgs; [ openconnect rbw ];
text = ''
GASPAR_PASSWORD=$(rbw get gaspar)
GASPAR_TOKEN=$(rbw code gaspar)
METHOD="Microsoft Entra ID"
RBW_ENTRY="EPFL Microsoft Auth"
GASPAR_PASSWORD=$(rbw get "$RBW_ENTRY")
GASPAR_TOKEN=$(rbw code "$RBW_ENTRY")
printf "%s\n%s" "$GASPAR_PASSWORD" "$GASPAR_TOKEN" | sudo openconnect \
printf "\n%s\n%s\n%s\n" "$METHOD" "$GASPAR_PASSWORD" "$GASPAR_TOKEN" | command sudo openconnect \
--passwd-on-stdin \
-u pham \
-u "pham" \
--useragent='AnyConnect' \
"https://vpn.epfl.ch"
'';
};

118
home/nki-framework.nix Normal file
View file

@ -0,0 +1,118 @@
{ pkgs, config, lib, ... }:
{
imports = [
# Common configuration
./common.nix
# We use our own firefox
# ./firefox.nix
# osu!
./osu.nix
];
# Home Manager needs a bit of information about you and the
# paths it should manage.
home.username = "nki";
home.homeDirectory = "/home/nki";
# More packages
home.packages = (with pkgs; [
# CLI stuff
python3
zip
# TeX
texlive.combined.scheme-full
# Note-taking
rnote
]);
# Graphical set up
linux.graphical.type = "wayland";
linux.graphical.wallpaper = ./images/wallpaper_0.png;
linux.graphical.defaults.webBrowser = "librewolf.desktop";
# Enable sway
programs.my-sway.enable = true;
programs.my-sway.fontSize = 14.0;
programs.my-sway.terminal = "${config.programs.kitty.package}/bin/kitty";
programs.my-sway.browser = "librewolf";
wayland.windowManager.sway.config = {
# Keyboard support
input."*".xkb_layout = "jp";
input."1278:34:HHKB-Hybrid_3_Keyboard".xkb_layout = "jp";
input."1:1:AT_Translated_Set_2_keyboard" = {
xkb_options = "ctrl:swapcaps";
};
input."2362:628:PIXA3854:00_093A:0274_Touchpad" = {
drag = "enabled";
natural_scroll = "enabled";
tap = "enabled";
};
};
programs.my-sway.waybar.extraSettings =
let
change-mode = pkgs.writeScript "change-mode" ''
#!/usr/bin/env ${lib.getExe pkgs.fish}
set -ax PATH ${lib.getBin pkgs.power-profiles-daemon} ${lib.getBin pkgs.rofi} ${lib.getBin pkgs.ripgrep}
set profiles (powerprofilesctl list | rg "^[ *] (\S+):" -r '$1')
set selected_index (math (contains -i (powerprofilesctl get) $profiles) - 1)
set new_profile (printf "%s\n" $profiles | rofi -dmenu -p "Switch to power profile" -a $selected_index)
powerprofilesctl set $new_profile
'';
in
[{
modules."battery"."on-click" = change-mode;
}];
# input-remapping
xdg.configFile."autostart/input-remapper-autoload.desktop".source =
"${pkgs.input-remapper}/share/applications/input-remapper-autoload.desktop";
# Kitty
nki.programs.kitty = {
enable = true;
fontSize = 16;
};
# Multiple screen setup
services.kanshi = with config.common.monitors; {
enable = true;
settings = [
{
profile.name = "undocked";
profile.outputs = [{ criteria = "eDP-1"; }];
}
{
profile.name = "work-both";
profile.outputs = [
{
criteria = "eDP-1";
position = "0,${toString (builtins.floor ((2160 / work.scale - 1200) + 1200 / 3))}";
status = "enable";
}
{ criteria = work.name; position = "1920,0"; }
];
}
{
profile.name = "work-one";
profile.outputs = [
{
criteria = "eDP-1";
status = "disable";
}
];
}
{ output.criteria = config.common.monitors.work.name; }
];
};
# This value determines the Home Manager release that your
# configuration is compatible with. This helps avoid breakage
# when a new Home Manager release introduces backwards
# incompatible changes.
#
# You can update Home Manager without changing this value. See
# the Home Manager release notes for a list of state version
# changes in each release.
home.stateVersion = "21.05";
}

View file

@ -7,7 +7,7 @@
# We use our own firefox
# ./firefox.nix
# osu!
# ./osu.nix
./osu.nix
];
# Home Manager needs a bit of information about you and the
@ -24,10 +24,6 @@
texlive.combined.scheme-full
# Note-taking
rnote
# Java & sbt
openjdk11
sbt
]);
# Graphical set up

View file

@ -1,33 +1,32 @@
{ pkgs, config, lib, ... }:
{ pkgs, lib, ... }:
let
osu-pkg = pkgs.unstable.osu-lazer-bin;
# with pkgs; with lib;
# appimageTools.wrapType2 rec {
# pname = "osu-lazer-bin";
# version = "2023.914.0";
# osu-pkg = pkgs.unstable.osu-lazer-bin;
osu-pkg = with pkgs; with lib;
appimageTools.wrapType2 rec {
pname = "osu-lazer-bin";
version = "2024.1009.1";
src = fetchurl {
url = "https://github.com/ppy/osu/releases/download/${version}/osu.AppImage";
sha256 = "sha256-2H2SPcUm/H/0D9BqBiTFvaCwd0c14/r+oWhyeZdNpoU=";
};
extraPkgs = pkgs: with pkgs; [ icu ];
# src = fetchurl {
# url = "https://github.com/ppy/osu/releases/download/${version}/osu.AppImage";
# # sha256 = "sha256-edu93pvTEM5/s0kW55U1xfYGDl0eUpGXypvuYIwsM3w=";
# hash = lib.fakeHash;
# };
# extraPkgs = pkgs: with pkgs; [ icu ];
# extraInstallCommands =
# let contents = appimageTools.extract { inherit pname version src; };
# in
# ''
# mv -v $out/bin/${pname}-${version} $out/bin/osu\!
# install -m 444 -D ${contents}/osu\!.desktop -t $out/share/applications
# for i in 16 32 48 64 96 128 256 512 1024; do
# install -D ${contents}/osu\!.png $out/share/icons/hicolor/''${i}x$i/apps/osu\!.png
# done
# '';
# };
extraInstallCommands =
let contents = appimageTools.extract { inherit pname version src; };
in
''
mv -v $out/bin/${pname} $out/bin/osu\!
install -m 444 -D ${contents}/osu\!.desktop -t $out/share/applications
for i in 16 32 48 64 96 128 256 512 1024; do
install -D ${contents}/osu\!.png $out/share/icons/hicolor/''${i}x$i/apps/osu\!.png
done
'';
};
in
{
home.packages = [ osu-pkg ];
xdg.mimeApps.defaultApplications."x-scheme-handler/osu" = "osu!.desktop";
# home.packages = [ pkgs.osu-lazer ];
}

View file

@ -13,6 +13,8 @@
../modules/personal/fonts
# Encrypted DNS
../modules/services/edns
# Override base mesa
({ ... }: { nixpkgs.overlays = lib.mkBefore [ (final: prev: { mesa = prev.mesa.override { enableOpenCL = true; meson = final.unstable.meson; }; }) ]; })
];
# time.timeZone = lib.mkForce "Asia/Ho_Chi_Minh";
@ -28,6 +30,30 @@
useExperimentalGPUDriver = true;
experimentalGPUInstallMode = "overlay";
};
# Override mesa
nixpkgs.overlays = lib.mkAfter [
(final: prev: {
mesa-asahi-edge = prev.mesa-asahi-edge.overrideAttrs (attrs: {
version = "24.0.0";
# buildInputs = attrs.buildInputs ++ (with pkgslw; [ libclc cmake (spirv-llvm-translator.override { inherit (llvmPackages_15) llvm; }) ]);
# nativeBuildInputs = attrs.nativeBuildInputs ++ (with pkgs; [ pkgs.unstable.spirv-llvm-translator ]);
src = final.fetchFromGitLab {
# latest release
domain = "gitlab.freedesktop.org";
owner = "asahi";
repo = "mesa";
rev = "asahi-20231121";
hash = "sha256-IcKKe1RA8sCaUfWK71ELzF15YaBS3DjoYhNMIWiQ5Jw=";
};
patches = lib.forEach attrs.patches (p:
if lib.hasSuffix "opencl.patch" p
then ./mesa-asahi-edge/opencl.patch else p);
});
})
];
## Additional mesa-related packages
environment.systemPackages = with pkgs; [ SDL2 ];
# Power Management
services.upower = {
@ -44,7 +70,7 @@
services.printing.drivers = with pkgs; [ epfl-cups-drivers ];
# Enable touchpad support (enabled default in most desktopManager).
services.xserver.libinput.enable = true;
services.libinput.enable = true;
# Keyboard
services.input-remapper.enable = true;
services.input-remapper.serviceWantedBy = [ "multi-user.target" ];

View file

@ -0,0 +1,66 @@
diff --git a/meson.build b/meson.build
index 04d89987311..babfe440973 100644
--- a/meson.build
+++ b/meson.build
@@ -1812,7 +1812,7 @@ endif
dep_clang = null_dep
if with_clc
- llvm_libdir = dep_llvm.get_variable(cmake : 'LLVM_LIBRARY_DIR', configtool: 'libdir')
+ llvm_libdir = get_option('clang-libdir')
dep_clang = cpp.find_library('clang-cpp', dirs : llvm_libdir, required : false)
diff --git a/meson_options.txt b/meson_options.txt
index e885ba61a8a..29ce0270479 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,6 +1,12 @@
# Copyright © 2017-2019 Intel Corporation
# SPDX-License-Identifier: MIT
+option(
+ 'clang-libdir',
+ type : 'string',
+ value : '',
+ description : 'Locations to search for clang libraries.'
+)
option(
'platforms',
type : 'array',
diff --git a/src/gallium/targets/opencl/meson.build b/src/gallium/targets/opencl/meson.build
index 7c14135898e..74dc6850603 100644
--- a/src/gallium/targets/opencl/meson.build
+++ b/src/gallium/targets/opencl/meson.build
@@ -39,7 +39,8 @@ if dep_llvm.version().version_compare('>=10.0.0')
polly_isl_dep = cpp.find_library('PollyISL', dirs : llvm_libdir, required : false)
endif
-dep_clang = cpp.find_library('clang-cpp', dirs : llvm_libdir, required : false)
+clang_libdir = get_option('clang-libdir')
+dep_clang = cpp.find_library('clang-cpp', dirs : clang_libdir, required : false)
# meson will return clang-cpp from system dirs if it's not found in llvm_libdir
linker_rpath_arg = '-Wl,--rpath=@0@'.format(llvm_libdir)
@@ -123,7 +124,7 @@ if with_opencl_icd
configuration : _config,
input : 'mesa.icd.in',
output : 'mesa.icd',
- install : true,
+ install : false,
install_tag : 'runtime',
install_dir : join_paths(get_option('sysconfdir'), 'OpenCL', 'vendors'),
)
diff --git a/src/gallium/targets/rusticl/meson.build b/src/gallium/targets/rusticl/meson.build
index b2963fe6dfa..99d6d801b94 100644
--- a/src/gallium/targets/rusticl/meson.build
+++ b/src/gallium/targets/rusticl/meson.build
@@ -76,7 +76,7 @@ configure_file(
configuration : _config,
input : 'rusticl.icd.in',
output : 'rusticl.icd',
- install : true,
+ install : false,
install_tag : 'runtime',
install_dir : join_paths(get_option('sysconfdir'), 'OpenCL', 'vendors'),
)

View file

@ -12,8 +12,8 @@ let
images = {
postgresql = mkImage {
imageName = "postgres";
finalImageTag = "12-alpine";
imageDigest = "sha256:f52ffee699232c84d820c35c28656363f4fda6a3e3e934b83f4e5e1898e2bdfa";
finalImageTag = "16-alpine";
imageDigest = "sha256:b40547ea0c7bcb401d8f11c6a233ebe65e2067e5966e54ccf9b03c5f01c2957c";
};
redis = mkImage {
imageName = "redis";
@ -22,8 +22,8 @@ let
};
authentik = mkImage {
imageName = "ghcr.io/goauthentik/server";
finalImageTag = "2023.8.3";
imageDigest = "sha256:82a07af063e8f93d0f174b6b058fcb6d54cd31ca2a271d23173cb149e19e8116";
finalImageTag = "2024.8.2";
imageDigest = "sha256:71984fdbb7a9414f5172bb446104d3fe4ab1ab412c8b3343bb97b04449dd53eb";
};
};
authentikEnv = pkgs.writeText "authentik.env" ''
@ -48,7 +48,14 @@ in
};
config = mkIf cfg.enable {
systemd.services.arion-authentik.serviceConfig.EnvironmentFile = cfg.envFile;
systemd.services.arion-authentik = {
serviceConfig.EnvironmentFile = cfg.envFile;
serviceConfig.Type = "notify";
serviceConfig.NotifyAccess = "all";
script = lib.mkBefore ''
${lib.getExe pkgs.wait4x} http http://127.0.0.1:${toString cfg.port} --expect-status-code 200 -t 0 -q -- systemd-notify --ready &
'';
};
virtualisation.arion.projects.authentik.settings = {
services.postgresql.service = {
image = images.postgresql;

View file

@ -10,9 +10,10 @@ let
user = "bitwarden";
port = 8001;
notificationsPort = 8002;
host = "bw.nkagami.me";
package = pkgs.vaultwarden-postgresql;
in
{
options.cloud.bitwarden = {
@ -37,12 +38,6 @@ in
inherit port host;
noCloudflare = true;
};
cloud.traefik.hosts.bitwarden-notifications = {
inherit host;
port = notificationsPort;
path = "/notifications/hub";
noCloudflare = true;
};
# systemd unit
systemd.services.bitwarden-server = {
after = [ "network.target" ];
@ -52,12 +47,11 @@ in
DATABASE_URL = databaseUrl;
DATA_FOLDER = "/var/lib/bitwarden-server";
WEB_VAULT_FOLDER = "${pkgs.unstable.vaultwarden-vault}/share/vaultwarden/vault";
WEB_VAULT_FOLDER = "${pkgs.vaultwarden-vault}/share/vaultwarden/vault";
ROCKET_PORT = toString port;
WEBSOCKET_ENABLED = "true";
WEBSOCKET_PORT = toString notificationsPort;
PUSH_ENABLED = "true";
DOMAIN = "https://${host}";
};
@ -65,7 +59,7 @@ in
serviceConfig = {
User = user;
Group = user;
ExecStart = "${pkgs.unstable.vaultwarden-postgresql}/bin/vaultwarden";
ExecStart = "${package}/bin/vaultwarden";
EnvironmentFile = lists.optional (cfg.envFile != null) cfg.envFile;
LimitNOFILE = "1048576";
PrivateTmp = "true";

View file

@ -73,7 +73,9 @@ with lib;
global.server_name = server_name;
global.port = instance.port;
global.allow_registration = instance.allow_registration;
global.database_path = "/var/lib/${srvName}/";
global.database_path = "/mnt/data/${srvName}/";
global.well_known_client = "https://${instance.host}";
global.well_known_server = "${instance.host}:443";
});
in
{
@ -103,7 +105,8 @@ with lib;
"@system-service"
"~@privileged"
];
StateDirectory = "${srvName}";
# StateDirectory = "/mnt/data/${srvName}";
BindPaths = [ "/mnt/data/${srvName}" ];
ExecStart = "${cfg.package}/bin/conduit";
Restart = "on-failure";
RestartSec = 10;
@ -113,56 +116,12 @@ with lib;
))
cfg.instances);
# Serving .well-known files
# This is a single .well-known/matrix/server file that points to the server,
# which is NOT on port 8448 since Cloudflare doesn't allow us to route HTTPS
# through that port.
config.services.nginx = mkIf cfg.enable
{
enable = true;
virtualHosts = lib.attrsets.mapAttrs'
(name: instance: lib.attrsets.nameValuePair "conduit-${name}-well-known" {
listen = [{ addr = "127.0.0.1"; port = instance.well-known_port; }];
# Check https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-well-known.md
# for the file structure.
root = pkgs.symlinkJoin
{
name = "well-known-files-for-conduit-${name}";
paths = [
(pkgs.writeTextDir ".well-known/matrix/client" (builtins.toJSON {
"m.homeserver".base_url = "https://${instance.host}";
"org.matrix.msc3575.proxy".url = "https://${instance.host}";
}))
(pkgs.writeTextDir ".well-known/matrix/server" (builtins.toJSON {
"m.server" = "${instance.host}:443";
}))
];
};
# Enable CORS from anywhere since we want all clients to find us out
extraConfig = ''
add_header 'Access-Control-Allow-Origin' "*";
'';
})
cfg.instances;
};
config.cloud.traefik.hosts = mkIf cfg.enable (
(lib.attrsets.mapAttrs'
(name: instance: lib.attrsets.nameValuePair "conduit-${name}" ({
inherit (instance) host port noCloudflare;
}))
cfg.instances)
// (lib.attrsets.mapAttrs'
(name: instance: lib.attrsets.nameValuePair "conduit-${name}-well-known" (
let
server_name = if instance.server_name == "" then instance.host else instance.server_name;
in
{
port = instance.well-known_port;
filter = "Host(`${server_name}`) && PathPrefix(`/.well-known`)";
}
))
cfg.instances)
);
}

View file

@ -33,7 +33,7 @@ with lib; {
{
systemd.services.heisenbridge = {
description = "Matrix<->IRC bridge";
requires = [ "matrix-synapse.service" ]; # So the registration file can be used by Synapse
requires = [ "matrix-conduit-nkagami.service" "matrix-synapse.service" ]; # So the registration file can be used by Synapse
wantedBy = [ "multi-user.target" ];
serviceConfig = rec {

View file

@ -4,35 +4,12 @@ let
cfg = config.cloud.gotosocial;
dbUser = "gotosocial";
configFile = pkgs.writeText "config.yml" (generators.toYAML { } {
# General
host = cfg.host;
account-domain = cfg.accountDomain;
bind-address = "localhost";
port = cfg.port;
# Database
db-port = 0; # Use socket
db-user = dbUser;
db-database = dbUser;
# Web
web-template-base-dir = "${cfg.package}/share/web/template";
web-asset-base-dir = "${cfg.package}/share/web/assets";
# OIDC
oidc-enabled = true;
oidc-idp-name = "DTTH";
oidc-scopes = [ "openid" "email" "profile" ];
# HTTP Client
http-client.block-ips = [ "11.0.0.0/24" ];
# Advanced
advanced-rate-limit-requests = 0;
# instance-inject-mastodon-version = true;
});
storageLocation = "/mnt/data/gotosocial";
in
{
options.cloud.gotosocial = {
enable = mkEnableOption "Enable our local GtS server";
package = mkPackageOption pkgs "gotosocial-bin" { };
package = mkPackageOption pkgs "gotosocial" { };
host = mkOption {
type = types.str;
description = "The GtS host";
@ -72,49 +49,59 @@ in
};
} else { });
# The service itself
systemd.services.gotosocial = {
after = [ "network.target" ];
serviceConfig = {
User = dbUser;
Group = dbUser;
ExecStart = "${cfg.package}/bin/gotosocial --config-path ${configFile} server start";
EnvironmentFile = cfg.envFile;
# Sandboxing options to harden security
# Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html
NoNewPrivileges = "yes";
PrivateTmp = "yes";
PrivateDevices = "yes";
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
RestrictNamespaces = "yes";
RestrictRealtime = "yes";
DevicePolicy = "closed";
ProtectSystem = "full";
ProtectControlGroups = "yes";
ProtectKernelModules = "yes";
ProtectKernelTunables = "yes";
LockPersonality = "yes";
SystemCallFilter = "~@clock @debug @module @mount @obsolete @reboot @setuid @swap";
# Denying access to capabilities that should not be relevant
# Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html
CapabilityBoundingSet = strings.concatStringsSep " " [
"CAP_RAWIO CAP_MKNOD"
"CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE"
"CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT"
"CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK"
"CAP_BLOCK_SUSPEND CAP_WAKE_ALARM"
"CAP_SYS_TTY_CONFIG"
"CAP_MAC_ADMIN CAP_MAC_OVERRIDE"
"CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW"
"CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG "
];
# You might need this if you are running as non-root on a privileged port (below 1024)
#AmbientCapabilities=CAP_NET_BIND_SERVICE
StateDirectory = "gotosocial";
WorkingDirectory = "/var/lib/gotosocial";
services.gotosocial = {
enable = true;
package = cfg.package;
environmentFile = cfg.envFile;
settings = {
# General
host = cfg.host;
account-domain = cfg.accountDomain;
bind-address = "localhost";
port = cfg.port;
# Instance
instance-languages = [ "en-ca" "vi" ];
# Accounts
accounts-registration-open = false;
accounts-allow-custom-css = true;
# Database
db-type = "postgres";
db-address = "/run/postgresql"; # Use socket
db-user = dbUser;
db-database = dbUser;
# Web
web-template-base-dir = "${cfg.package}/share/gotosocial/web/template";
web-asset-base-dir = "${cfg.package}/share/gotosocial/web/assets";
# Media
media-emoji-remote-max-size = 256 * 1024 /* bytes */;
media-emoji-local-max-size = 256 * 1024 /* bytes */;
media-remote-cache-days = 7;
media-cleanup-from = "00:00";
media-cleanup-every = "24h";
# OIDC
oidc-enabled = true;
oidc-idp-name = "DTTH";
oidc-scopes = [ "openid" "email" "profile" ];
# HTTP Client
http-client.block-ips = [ "11.0.0.0/24" ];
# Advanced
advanced-rate-limit-requests = 0;
# Storage
storage-backend = "local";
storage-local-base-path = "${storageLocation}/storage";
# instance-inject-mastodon-version = true;
};
wantedBy = [ "multi-user.target" ];
requires = [ "minio.service" "postgresql.service" ];
};
systemd.services.gotosocial.requires = mkAfter [ "postgresql.service" "arion-authentik.service" ];
systemd.services.gotosocial.after = mkAfter [ "postgresql.service" "arion-authentik.service" ];
systemd.services.gotosocial.unitConfig = {
RequiresMountsFor = [ storageLocation ];
ReadWritePaths = [ storageLocation ];
};
systemd.tmpfiles.settings."10-gotosocial".${storageLocation}.d = {
user = dbUser;
group = dbUser;
mode = "0700";
};
};
}

View file

@ -1,788 +0,0 @@
# Stub until 0.69.2 lands in stable
{ config, lib, pkgs, ... }:
let
defaultUser = "outline";
cfg = config.cloud.services.outline;
in
{
# See here for a reference of all the options:
# https://github.com/outline/outline/blob/v0.67.0/.env.sample
# https://github.com/outline/outline/blob/v0.67.0/app.json
# https://github.com/outline/outline/blob/v0.67.0/server/env.ts
# https://github.com/outline/outline/blob/v0.67.0/shared/types.ts
# The order is kept the same here to make updating easier.
options.cloud.services.outline = {
enable = lib.mkEnableOption (lib.mdDoc "outline");
package = lib.mkOption {
default = pkgs.unstable.outline;
defaultText = lib.literalExpression "pkgs.unstable.outline";
type = lib.types.package;
example = lib.literalExpression ''
pkgs.outline.overrideAttrs (super: {
# Ignore the domain part in emails that come from OIDC. This is might
# be helpful if you want multiple users with different email providers
# to still land in the same team. Note that this effectively makes
# Outline a single-team instance.
patchPhase = ${"''"}
sed -i 's/const domain = parts\.length && parts\[1\];/const domain = "example.com";/g' server/routes/auth/providers/oidc.ts
${"''"};
})
'';
description = lib.mdDoc "Outline package to use.";
};
user = lib.mkOption {
type = lib.types.str;
default = defaultUser;
description = lib.mdDoc ''
User under which the service should run. If this is the default value,
the user will be created, with the specified group as the primary
group.
'';
};
group = lib.mkOption {
type = lib.types.str;
default = defaultUser;
description = lib.mdDoc ''
Group under which the service should run. If this is the default value,
the group will be created.
'';
};
sequelizeArguments = lib.mkOption {
type = lib.types.str;
default = "";
example = "--env=production-ssl-disabled";
description = lib.mdDoc ''
Optional arguments to pass to `sequelize` calls.
'';
};
#
# Required options
#
secretKeyFile = lib.mkOption {
type = lib.types.str;
default = "/var/lib/outline/secret_key";
description = lib.mdDoc ''
File path that contains the application secret key. It must be 32
bytes long and hex-encoded. If the file does not exist, a new key will
be generated and saved here.
'';
};
utilsSecretFile = lib.mkOption {
type = lib.types.str;
default = "/var/lib/outline/utils_secret";
description = lib.mdDoc ''
File path that contains the utility secret key. If the file does not
exist, a new key will be generated and saved here.
'';
};
databaseUrl = lib.mkOption {
type = lib.types.str;
default = "local";
description = lib.mdDoc ''
URI to use for the main PostgreSQL database. If this needs to include
credentials that shouldn't be world-readable in the Nix store, set an
environment file on the systemd service and override the
`DATABASE_URL` entry. Pass the string
`local` to setup a database on the local server.
'';
};
redisUrl = lib.mkOption {
type = lib.types.str;
default = "local";
description = lib.mdDoc ''
Connection to a redis server. If this needs to include credentials
that shouldn't be world-readable in the Nix store, set an environment
file on the systemd service and override the
`REDIS_URL` entry. Pass the string
`local` to setup a local Redis database.
'';
};
publicUrl = lib.mkOption {
type = lib.types.str;
default = "http://localhost:3000";
description = lib.mdDoc "The fully qualified, publicly accessible URL";
};
port = lib.mkOption {
type = lib.types.port;
default = 3000;
description = lib.mdDoc "Listening port.";
};
storage = lib.mkOption {
description = lib.mdDoc ''
To support uploading of images for avatars and document attachments an
s3-compatible storage must be provided. AWS S3 is recommended for
redundancy however if you want to keep all file storage local an
alternative such as [minio](https://github.com/minio/minio)
can be used.
A more detailed guide on setting up S3 is available
[here](https://wiki.generaloutline.com/share/125de1cc-9ff6-424b-8415-0d58c809a40f).
'';
example = lib.literalExpression ''
{
accessKey = "...";
secretKeyFile = "/somewhere";
uploadBucketUrl = "https://minio.example.com";
uploadBucketName = "outline";
region = "us-east-1";
}
'';
type = lib.types.submodule {
options = {
accessKey = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "S3 access key.";
};
secretKeyFile = lib.mkOption {
type = lib.types.path;
description = lib.mdDoc "File path that contains the S3 secret key.";
};
region = lib.mkOption {
type = lib.types.str;
default = "xx-xxxx-x";
description = lib.mdDoc "AWS S3 region name.";
};
uploadBucketUrl = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc ''
URL endpoint of an S3-compatible API where uploads should be
stored.
'';
};
uploadBucketName = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "Name of the bucket where uploads should be stored.";
};
uploadMaxSize = lib.mkOption {
type = lib.types.int;
default = 26214400;
description = lib.mdDoc "Maxmium file size for uploads.";
};
forcePathStyle = lib.mkOption {
type = lib.types.bool;
default = true;
description = lib.mdDoc "Force S3 path style.";
};
acl = lib.mkOption {
type = lib.types.str;
default = "private";
description = lib.mdDoc "ACL setting.";
};
};
};
};
#
# Authentication
#
slackAuthentication = lib.mkOption {
description = lib.mdDoc ''
To configure Slack auth, you'll need to create an Application at
https://api.slack.com/apps
When configuring the Client ID, add a redirect URL under "OAuth & Permissions"
to `https://[publicUrl]/auth/slack.callback`.
'';
default = null;
type = lib.types.nullOr (lib.types.submodule {
options = {
clientId = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "Authentication key.";
};
secretFile = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "File path containing the authentication secret.";
};
};
});
};
googleAuthentication = lib.mkOption {
description = lib.mdDoc ''
To configure Google auth, you'll need to create an OAuth Client ID at
https://console.cloud.google.com/apis/credentials
When configuring the Client ID, add an Authorized redirect URI to
`https://[publicUrl]/auth/google.callback`.
'';
default = null;
type = lib.types.nullOr (lib.types.submodule {
options = {
clientId = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "Authentication client identifier.";
};
clientSecretFile = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "File path containing the authentication secret.";
};
};
});
};
azureAuthentication = lib.mkOption {
description = lib.mdDoc ''
To configure Microsoft/Azure auth, you'll need to create an OAuth
Client. See
[the guide](https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4)
for details on setting up your Azure App.
'';
default = null;
type = lib.types.nullOr (lib.types.submodule {
options = {
clientId = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "Authentication client identifier.";
};
clientSecretFile = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "File path containing the authentication secret.";
};
resourceAppId = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "Authentication application resource ID.";
};
};
});
};
oidcAuthentication = lib.mkOption {
description = lib.mdDoc ''
To configure generic OIDC auth, you'll need some kind of identity
provider. See the documentation for whichever IdP you use to fill out
all the fields. The redirect URL is
`https://[publicUrl]/auth/oidc.callback`.
'';
default = null;
type = lib.types.nullOr (lib.types.submodule {
options = {
clientId = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "Authentication client identifier.";
};
clientSecretFile = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "File path containing the authentication secret.";
};
authUrl = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "OIDC authentication URL endpoint.";
};
tokenUrl = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "OIDC token URL endpoint.";
};
userinfoUrl = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "OIDC userinfo URL endpoint.";
};
usernameClaim = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc ''
Specify which claims to derive user information from. Supports any
valid JSON path with the JWT payload
'';
default = "preferred_username";
};
displayName = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "Display name for OIDC authentication.";
default = "OpenID";
};
scopes = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = lib.mdDoc "OpenID authentication scopes.";
default = [ "openid" "profile" "email" ];
};
};
});
};
#
# Optional configuration
#
sslKeyFile = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = lib.mdDoc ''
File path that contains the Base64-encoded private key for HTTPS
termination. This is only required if you do not use an external reverse
proxy. See
[the documentation](https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4).
'';
};
sslCertFile = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = lib.mdDoc ''
File path that contains the Base64-encoded certificate for HTTPS
termination. This is only required if you do not use an external reverse
proxy. See
[the documentation](https://wiki.generaloutline.com/share/dfa77e56-d4d2-4b51-8ff8-84ea6608faa4).
'';
};
cdnUrl = lib.mkOption {
type = lib.types.str;
default = "";
description = lib.mdDoc ''
If using a Cloudfront/Cloudflare distribution or similar it can be set
using this option. This will cause paths to JavaScript files,
stylesheets and images to be updated to the hostname defined here. In
your CDN configuration the origin server should be set to public URL.
'';
};
forceHttps = lib.mkOption {
type = lib.types.bool;
default = true;
description = lib.mdDoc ''
Auto-redirect to HTTPS in production. The default is
`true` but you may set this to `false`
if you can be sure that SSL is terminated at an external loadbalancer.
'';
};
enableUpdateCheck = lib.mkOption {
type = lib.types.bool;
default = false;
description = lib.mdDoc ''
Have the installation check for updates by sending anonymized statistics
to the maintainers.
'';
};
concurrency = lib.mkOption {
type = lib.types.int;
default = 1;
description = lib.mdDoc ''
How many processes should be spawned. For a rough estimate, divide your
server's available memory by 512.
'';
};
maximumImportSize = lib.mkOption {
type = lib.types.int;
default = 5120000;
description = lib.mdDoc ''
The maximum size of document imports. Overriding this could be required
if you have especially large Word documents with embedded imagery.
'';
};
debugOutput = lib.mkOption {
type = lib.types.nullOr (lib.types.enum [ "http" ]);
default = null;
description = lib.mdDoc "Set this to `http` log HTTP requests.";
};
slackIntegration = lib.mkOption {
description = lib.mdDoc ''
For a complete Slack integration with search and posting to channels
this configuration is also needed. See here for details:
https://wiki.generaloutline.com/share/be25efd1-b3ef-4450-b8e5-c4a4fc11e02a
'';
default = null;
type = lib.types.nullOr (lib.types.submodule {
options = {
verificationTokenFile = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "File path containing the verification token.";
};
appId = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "Application ID.";
};
messageActions = lib.mkOption {
type = lib.types.bool;
default = true;
description = lib.mdDoc "Whether to enable message actions.";
};
};
});
};
googleAnalyticsId = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = lib.mdDoc ''
Optionally enable Google Analytics to track page views in the knowledge
base.
'';
};
sentryDsn = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = lib.mdDoc ''
Optionally enable [Sentry](https://sentry.io/) to
track errors and performance.
'';
};
sentryTunnel = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = lib.mdDoc ''
Optionally add a
[Sentry proxy tunnel](https://docs.sentry.io/platforms/javascript/troubleshooting/#using-the-tunnel-option)
for bypassing ad blockers in the UI.
'';
};
logo = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = lib.mdDoc ''
Custom logo displayed on the authentication screen. This will be scaled
to a height of 60px.
'';
};
smtp = lib.mkOption {
description = lib.mdDoc ''
To support sending outgoing transactional emails such as
"document updated" or "you've been invited" you'll need to provide
authentication for an SMTP server.
'';
default = null;
type = lib.types.nullOr (lib.types.submodule {
options = {
host = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "Host name or IP address of the SMTP server.";
};
port = lib.mkOption {
type = lib.types.port;
description = lib.mdDoc "TCP port of the SMTP server.";
};
username = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "Username to authenticate with.";
};
passwordFile = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc ''
File path containing the password to authenticate with.
'';
};
fromEmail = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "Sender email in outgoing mail.";
};
replyEmail = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc "Reply address in outgoing mail.";
};
tlsCiphers = lib.mkOption {
type = lib.types.str;
default = "";
description = lib.mdDoc "Override SMTP cipher configuration.";
};
secure = lib.mkOption {
type = lib.types.bool;
default = true;
description = lib.mdDoc "Use a secure SMTP connection.";
};
};
});
};
defaultLanguage = lib.mkOption {
type = lib.types.enum [
"da_DK"
"de_DE"
"en_US"
"es_ES"
"fa_IR"
"fr_FR"
"it_IT"
"ja_JP"
"ko_KR"
"nl_NL"
"pl_PL"
"pt_BR"
"pt_PT"
"ru_RU"
"sv_SE"
"th_TH"
"vi_VN"
"zh_CN"
"zh_TW"
];
default = "en_US";
description = lib.mdDoc ''
The default interface language. See
[translate.getoutline.com](https://translate.getoutline.com/)
for a list of available language codes and their rough percentage
translated.
'';
};
rateLimiter.enable = lib.mkEnableOption (lib.mdDoc "rate limiter for the application web server");
rateLimiter.requests = lib.mkOption {
type = lib.types.int;
default = 5000;
description = lib.mdDoc "Maximum number of requests in a throttling window.";
};
rateLimiter.durationWindow = lib.mkOption {
type = lib.types.int;
default = 60;
description = lib.mdDoc "Length of a throttling window.";
};
};
config = lib.mkIf cfg.enable {
assertions = [
{ assertion = pkgs.outline.version == "0.68.1"; message = "Please use the nixpkgs module for outline > 0.68.1"; }
];
users.users = lib.optionalAttrs (cfg.user == defaultUser) {
${defaultUser} = {
isSystemUser = true;
group = cfg.group;
};
};
users.groups = lib.optionalAttrs (cfg.group == defaultUser) {
${defaultUser} = { };
};
systemd.tmpfiles.rules = [
"f ${cfg.secretKeyFile} 0600 ${cfg.user} ${cfg.group} -"
"f ${cfg.utilsSecretFile} 0600 ${cfg.user} ${cfg.group} -"
"f ${cfg.storage.secretKeyFile} 0600 ${cfg.user} ${cfg.group} -"
];
services.postgresql = lib.mkIf (cfg.databaseUrl == "local") {
enable = true;
ensureUsers = [{
name = "outline";
ensurePermissions."DATABASE outline" = "ALL PRIVILEGES";
}];
ensureDatabases = [ "outline" ];
};
services.redis.servers.outline = lib.mkIf (cfg.redisUrl == "local") {
enable = true;
user = config.services.outline.user;
port = 0; # Disable the TCP listener
};
systemd.services.outline =
let
localRedisUrl = "redis+unix:///run/redis-outline/redis.sock";
localPostgresqlUrl = "postgres://localhost/outline?host=/run/postgresql";
# Create an outline-sequalize wrapper (a wrapper around the wrapper) that
# has the config file's path baked in. This is necessary because there is
# at least two occurrences of outline calling this from its own code.
sequelize = pkgs.writeShellScriptBin "outline-sequelize" ''
exec ${cfg.package}/bin/outline-sequelize \
--config $RUNTIME_DIRECTORY/database.json \
${cfg.sequelizeArguments} \
"$@"
'';
in
{
description = "Outline wiki and knowledge base";
wantedBy = [ "multi-user.target" ];
after = [ "networking.target" ]
++ lib.optional (cfg.databaseUrl == "local") "postgresql.service"
++ lib.optional (cfg.redisUrl == "local") "redis-outline.service";
requires = lib.optional (cfg.databaseUrl == "local") "postgresql.service"
++ lib.optional (cfg.redisUrl == "local") "redis-outline.service";
path = [
pkgs.openssl # Required by the preStart script
sequelize
];
environment = lib.mkMerge [
{
NODE_ENV = "production";
REDIS_URL = if cfg.redisUrl == "local" then localRedisUrl else cfg.redisUrl;
URL = cfg.publicUrl;
PORT = builtins.toString cfg.port;
AWS_ACCESS_KEY_ID = cfg.storage.accessKey;
AWS_REGION = cfg.storage.region;
AWS_S3_UPLOAD_BUCKET_URL = cfg.storage.uploadBucketUrl;
AWS_S3_UPLOAD_BUCKET_NAME = cfg.storage.uploadBucketName;
AWS_S3_UPLOAD_MAX_SIZE = builtins.toString cfg.storage.uploadMaxSize;
AWS_S3_FORCE_PATH_STYLE = builtins.toString cfg.storage.forcePathStyle;
AWS_S3_ACL = cfg.storage.acl;
CDN_URL = cfg.cdnUrl;
FORCE_HTTPS = builtins.toString cfg.forceHttps;
ENABLE_UPDATES = builtins.toString cfg.enableUpdateCheck;
WEB_CONCURRENCY = builtins.toString cfg.concurrency;
MAXIMUM_IMPORT_SIZE = builtins.toString cfg.maximumImportSize;
DEBUG = cfg.debugOutput;
GOOGLE_ANALYTICS_ID = lib.optionalString (cfg.googleAnalyticsId != null) cfg.googleAnalyticsId;
SENTRY_DSN = lib.optionalString (cfg.sentryDsn != null) cfg.sentryDsn;
SENTRY_TUNNEL = lib.optionalString (cfg.sentryTunnel != null) cfg.sentryTunnel;
TEAM_LOGO = lib.optionalString (cfg.logo != null) cfg.logo;
DEFAULT_LANGUAGE = cfg.defaultLanguage;
RATE_LIMITER_ENABLED = builtins.toString cfg.rateLimiter.enable;
RATE_LIMITER_REQUESTS = builtins.toString cfg.rateLimiter.requests;
RATE_LIMITER_DURATION_WINDOW = builtins.toString cfg.rateLimiter.durationWindow;
}
(lib.mkIf (cfg.slackAuthentication != null) {
SLACK_CLIENT_ID = cfg.slackAuthentication.clientId;
})
(lib.mkIf (cfg.googleAuthentication != null) {
GOOGLE_CLIENT_ID = cfg.googleAuthentication.clientId;
})
(lib.mkIf (cfg.azureAuthentication != null) {
AZURE_CLIENT_ID = cfg.azureAuthentication.clientId;
AZURE_RESOURCE_APP_ID = cfg.azureAuthentication.resourceAppId;
})
(lib.mkIf (cfg.oidcAuthentication != null) {
OIDC_CLIENT_ID = cfg.oidcAuthentication.clientId;
OIDC_AUTH_URI = cfg.oidcAuthentication.authUrl;
OIDC_TOKEN_URI = cfg.oidcAuthentication.tokenUrl;
OIDC_USERINFO_URI = cfg.oidcAuthentication.userinfoUrl;
OIDC_USERNAME_CLAIM = cfg.oidcAuthentication.usernameClaim;
OIDC_DISPLAY_NAME = cfg.oidcAuthentication.displayName;
OIDC_SCOPES = lib.concatStringsSep " " cfg.oidcAuthentication.scopes;
})
(lib.mkIf (cfg.slackIntegration != null) {
SLACK_APP_ID = cfg.slackIntegration.appId;
SLACK_MESSAGE_ACTIONS = builtins.toString cfg.slackIntegration.messageActions;
})
(lib.mkIf (cfg.smtp != null) {
SMTP_HOST = cfg.smtp.host;
SMTP_PORT = builtins.toString cfg.smtp.port;
SMTP_USERNAME = cfg.smtp.username;
SMTP_FROM_EMAIL = cfg.smtp.fromEmail;
SMTP_REPLY_EMAIL = cfg.smtp.replyEmail;
SMTP_TLS_CIPHERS = cfg.smtp.tlsCiphers;
SMTP_SECURE = builtins.toString cfg.smtp.secure;
})
];
preStart = ''
if [ ! -s ${lib.escapeShellArg cfg.secretKeyFile} ]; then
openssl rand -hex 32 > ${lib.escapeShellArg cfg.secretKeyFile}
fi
if [ ! -s ${lib.escapeShellArg cfg.utilsSecretFile} ]; then
openssl rand -hex 32 > ${lib.escapeShellArg cfg.utilsSecretFile}
fi
# The config file is required for the sequelize CLI.
${if (cfg.databaseUrl == "local") then ''
cat <<EOF > $RUNTIME_DIRECTORY/database.json
{
"production-ssl-disabled": {
"host": "/run/postgresql",
"username": null,
"password": null,
"dialect": "postgres"
}
}
EOF
'' else ''
cat <<EOF > $RUNTIME_DIRECTORY/database.json
{
"production": {
"use_env_variable": "DATABASE_URL",
"dialect": "postgres",
"dialectOptions": {
"ssl": {
"rejectUnauthorized": false
}
}
},
"production-ssl-disabled": {
"use_env_variable": "DATABASE_URL",
"dialect": "postgres"
}
}
EOF
''}
'';
script = ''
export SECRET_KEY="$(head -n1 ${lib.escapeShellArg cfg.secretKeyFile})"
export UTILS_SECRET="$(head -n1 ${lib.escapeShellArg cfg.utilsSecretFile})"
export AWS_SECRET_ACCESS_KEY="$(head -n1 ${lib.escapeShellArg cfg.storage.secretKeyFile})"
${lib.optionalString (cfg.slackAuthentication != null) ''
export SLACK_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.slackAuthentication.secretFile})"
''}
${lib.optionalString (cfg.googleAuthentication != null) ''
export GOOGLE_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.googleAuthentication.clientSecretFile})"
''}
${lib.optionalString (cfg.azureAuthentication != null) ''
export AZURE_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.azureAuthentication.clientSecretFile})"
''}
${lib.optionalString (cfg.oidcAuthentication != null) ''
export OIDC_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.oidcAuthentication.clientSecretFile})"
''}
${lib.optionalString (cfg.sslKeyFile != null) ''
export SSL_KEY="$(head -n1 ${lib.escapeShellArg cfg.sslKeyFile})"
''}
${lib.optionalString (cfg.sslCertFile != null) ''
export SSL_CERT="$(head -n1 ${lib.escapeShellArg cfg.sslCertFile})"
''}
${lib.optionalString (cfg.slackIntegration != null) ''
export SLACK_VERIFICATION_TOKEN="$(head -n1 ${lib.escapeShellArg cfg.slackIntegration.verificationTokenFile})"
''}
${lib.optionalString (cfg.smtp != null) ''
export SMTP_PASSWORD="$(head -n1 ${lib.escapeShellArg cfg.smtp.passwordFile})"
''}
${if (cfg.databaseUrl == "local") then ''
export DATABASE_URL=${lib.escapeShellArg localPostgresqlUrl}
export PGSSLMODE=disable
'' else ''
export DATABASE_URL=${lib.escapeShellArg cfg.databaseUrl}
''}
${cfg.package}/bin/outline-server
'';
serviceConfig = {
User = cfg.user;
Group = cfg.group;
Restart = "always";
ProtectSystem = "strict";
PrivateHome = true;
PrivateTmp = true;
UMask = "0007";
StateDirectory = "outline";
StateDirectoryMode = "0750";
RuntimeDirectory = "outline";
RuntimeDirectoryMode = "0750";
# This working directory is required to find stuff like the set of
# onboarding files:
WorkingDirectory = "${cfg.package}/share/outline";
};
};
};
}

View file

@ -17,6 +17,7 @@ index d218dbc1f..24c0505e3 100644
/**
* The product name
*/
@Public
- public APP_NAME = "Outline";
+ public APP_NAME = "DTTH Wiki";

View file

@ -0,0 +1,183 @@
commit 8c7f8c28fabc174a71499a4737579b24b5c4b244
Author: Natsu Kagami <nki@nkagami.me>
Date: Mon Oct 21 02:17:36 2024 +0200
Support R2
diff --git a/.env.sample b/.env.sample
index eb57ad85c..94ffcee07 100644
--- a/.env.sample
+++ b/.env.sample
@@ -66,6 +66,8 @@ AWS_S3_UPLOAD_BUCKET_URL=http://s3:4569
AWS_S3_UPLOAD_BUCKET_NAME=bucket_name_here
AWS_S3_FORCE_PATH_STYLE=true
AWS_S3_ACL=private
+AWS_S3_R2=true
+AWS_S3_R2_PUBLIC_URL=http://s3:4569
# AUTHENTICATION
diff --git a/app/utils/files.ts b/app/utils/files.ts
index 6607a6b12..5138f68ad 100644
--- a/app/utils/files.ts
+++ b/app/utils/files.ts
@@ -63,8 +63,13 @@ export const uploadFile = async (
xhr.addEventListener("loadend", () => {
resolve(xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 400);
});
- xhr.open("POST", data.uploadUrl, true);
- xhr.send(formData);
+ xhr.open(data.method, data.uploadUrl, true);
+ xhr.setRequestHeader("Content-Type", file.type);
+ if (data.method === "POST") {
+ xhr.send(formData);
+ } else {
+ xhr.send(file);
+ }
});
if (!success) {
diff --git a/server/env.ts b/server/env.ts
index 5b420f2e1..4ea1e8d3c 100644
--- a/server/env.ts
+++ b/server/env.ts
@@ -519,6 +519,14 @@ export class Environment {
environment.AWS_S3_UPLOAD_BUCKET_NAME
);
+ @IsOptional()
+ public AWS_S3_R2 = this.toBoolean(environment.AWS_S3_R2 ?? "false");
+
+ @IsOptional()
+ public AWS_S3_R2_PUBLIC_URL = this.toOptionalString(
+ environment.AWS_S3_R2_PUBLIC_URL
+ );
+
/**
* Whether to force path style URLs for S3 objects, this is required for some
* S3-compatible storage providers.
diff --git a/server/routes/api/attachments/attachments.ts b/server/routes/api/attachments/attachments.ts
index 5e6c27594..b7620f440 100644
--- a/server/routes/api/attachments/attachments.ts
+++ b/server/routes/api/attachments/attachments.ts
@@ -3,6 +3,7 @@ import { v4 as uuidv4 } from "uuid";
import { AttachmentPreset } from "@shared/types";
import { bytesToHumanReadable } from "@shared/utils/files";
import { AttachmentValidation } from "@shared/validations";
+import env from "@server/env";
import { AuthorizationError, ValidationError } from "@server/errors";
import auth from "@server/middlewares/authentication";
import { rateLimiter } from "@server/middlewares/rateLimiter";
@@ -90,16 +91,30 @@ router.post(
{ transaction }
);
- const presignedPost = await FileStorage.getPresignedPost(
- key,
- acl,
- maxUploadSize,
- contentType
- );
+ let uploadUrl;
+ let method;
+ let presignedPost = {
+ fields: {},
+ };
+ if (env.AWS_S3_R2) {
+ uploadUrl = await FileStorage.getPresignedPut(key);
+ method = "PUT";
+ } else {
+ uploadUrl = FileStorage.getUploadUrl();
+ method = "POST";
+
+ presignedPost = await FileStorage.getPresignedPost(
+ key,
+ acl,
+ maxUploadSize,
+ contentType
+ );
+ }
ctx.body = {
data: {
- uploadUrl: FileStorage.getUploadUrl(),
+ uploadUrl,
+ method,
form: {
"Cache-Control": "max-age=31557600",
"Content-Type": contentType,
diff --git a/server/storage/files/BaseStorage.ts b/server/storage/files/BaseStorage.ts
index ce0287ebc..a1931c83d 100644
--- a/server/storage/files/BaseStorage.ts
+++ b/server/storage/files/BaseStorage.ts
@@ -26,6 +26,8 @@ export default abstract class BaseStorage {
contentType: string
): Promise<Partial<PresignedPost>>;
+ public abstract getPresignedPut(key: string): Promise<string>;
+
/**
* Returns a promise that resolves with a stream for reading a file from the storage provider.
*
diff --git a/server/storage/files/LocalStorage.ts b/server/storage/files/LocalStorage.ts
index 83cf98c50..324e60dd9 100644
--- a/server/storage/files/LocalStorage.ts
+++ b/server/storage/files/LocalStorage.ts
@@ -30,6 +30,10 @@ export default class LocalStorage extends BaseStorage {
});
}
+ public async getPresignedPut(key: string) {
+ return this.getUrlForKey(key);
+ }
+
public getUploadUrl() {
return "/api/files.create";
}
diff --git a/server/storage/files/S3Storage.ts b/server/storage/files/S3Storage.ts
index a42442e0c..d55ef5472 100644
--- a/server/storage/files/S3Storage.ts
+++ b/server/storage/files/S3Storage.ts
@@ -4,6 +4,7 @@ import {
S3Client,
DeleteObjectCommand,
GetObjectCommand,
+ PutObjectCommand,
ObjectCannedACL,
} from "@aws-sdk/client-s3";
import { Upload } from "@aws-sdk/lib-storage";
@@ -58,6 +59,16 @@ export default class S3Storage extends BaseStorage {
return createPresignedPost(this.client, params);
}
+ public async getPresignedPut(key: string) {
+ const params = {
+ Bucket: env.AWS_S3_UPLOAD_BUCKET_NAME,
+ Key: key,
+ };
+
+ const command = new PutObjectCommand(params);
+ return await getSignedUrl(this.client, command, { expiresIn: 3600 });
+ }
+
private getPublicEndpoint(isServerUpload?: boolean) {
if (env.AWS_S3_ACCELERATE_URL) {
return env.AWS_S3_ACCELERATE_URL;
@@ -137,10 +148,17 @@ export default class S3Storage extends BaseStorage {
);
}
+ public getR2ObjectUrl = async (key: string) =>
+ env.AWS_S3_R2_PUBLIC_URL + "/" + key;
+
public getSignedUrl = async (
key: string,
expiresIn = S3Storage.defaultSignedUrlExpires
) => {
+ if (env.AWS_S3_R2) {
+ return this.getR2ObjectUrl(key);
+ }
+
const isDocker = env.AWS_S3_UPLOAD_BUCKET_URL.match(/http:\/\/s3:/);
const params = {
Bucket: this.getBucket(),

View file

@ -9,9 +9,7 @@ let
# to that database.
userFromDatabase = databaseName: {
name = databaseName;
ensurePermissions = {
"DATABASE \"${databaseName}\"" = "ALL PRIVILEGES";
};
ensureDBOwnership = true;
};
in
{
@ -32,10 +30,14 @@ in
ensureDatabases = cfg.databases;
ensureUsers = (map userFromDatabase cfg.databases) ++ [{
name = "root";
ensurePermissions = { "ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES"; };
}];
ensureUsers = (map userFromDatabase cfg.databases);
dataDir = "/mnt/data/postgresql/${config.services.postgresql.package.psqlSchema}";
};
config.systemd.services.postgresql.serviceConfig = {
StateDirectory = "postgresql postgresql ${config.services.postgresql.dataDir}";
StateDirectoryMode = "0750";
};
# Backup settings

View file

@ -20,6 +20,24 @@ let
in
valueType;
# https://www.cloudflare.com/ips/
trustedIPs =
let
files = [
(pkgs.fetchurl {
url = "https://www.cloudflare.com/ips-v4";
hash = "sha256-8Cxtg7wBqwroV3Fg4DbXAMdFU1m84FTfiE5dfZ5Onns=";
})
(pkgs.fetchurl {
url = "https://www.cloudflare.com/ips-v6";
hash = "sha256-np054+g7rQDE3sr9U8Y/piAp89ldto3pN9K+KCNMoKk=";
})
];
readLines = path: lib.splitString "\n" (builtins.readFile path);
in
lib.concatMap readLines files;
cfg = config.cloud.traefik;
in
{
@ -57,6 +75,7 @@ in
};
## HTTPS entrypoint: ok!
entrypoints.https.address = ":443";
entrypoints.https.forwardedHeaders.trustedIPs = trustedIPs;
## IMAP and SMTP
entrypoints.imap.address = ":993";
entrypoints.smtp-submission.address = ":587";

View file

@ -26,14 +26,25 @@ let
};
};
accounts = { pkgs, ... }: mkIf config.common.linux.enable {
environment.systemPackages = with pkgs.gnome; [ pkgs.glib gnome-control-center ];
graphics = { config, ... }: {
hardware =
if config.system.nixos.release == "24.05" then {
opengl.enable = true;
opengl.driSupport32Bit = true;
} else {
graphics.enable = true;
graphics.enable32Bit = true;
};
};
accounts = { pkgs, ... }: mkIf (config.common.linux.enable && !pkgs.stdenv.isAarch64) {
environment.systemPackages = [ pkgs.glib (pkgs.gnome-control-center or pkgs.gnome.gnome-control-center) ];
services.accounts-daemon.enable = true;
services.gnome.gnome-online-accounts.enable = true;
programs.evolution.enable = true;
programs.evolution.plugins = with pkgs; [ evolution-ews ];
services.gnome.evolution-data-server.enable = true;
services.gnome.evolution-data-server.plugins = with pkgs; [ evolution-ews ];
# programs.evolution.enable = true;
# programs.evolution.plugins = with pkgs; [ evolution-ews ];
# services.gnome.evolution-data-server.enable = true;
# services.gnome.evolution-data-server.plugins = with pkgs; [ evolution-ews ];
};
wlr = { ... }: mkIf config.common.linux.enable {
@ -49,6 +60,14 @@ let
environment.systemPackages = with pkgs; [ piper ];
};
kwallet = { pkgs, lib, ... }: mkIf cfg.enable {
environment.systemPackages = [ pkgs.kdePackages.kwallet ];
services.dbus.packages = [ pkgs.kdePackages.kwallet ];
xdg.portal = {
extraPortals = [ pkgs.kdePackages.kwallet ];
};
};
virtualisation = { pkgs, ... }: mkIf cfg.enable {
virtualisation.podman = {
enable = true;
@ -58,13 +77,56 @@ let
virtualisation.oci-containers.backend = "podman";
virtualisation.virtualbox.host.enable = true;
virtualisation.virtualbox.host.enable = false;
users.extraGroups.vboxusers.members = [ cfg.username ];
};
};
rt-audio = { pkgs, ... }: mkIf cfg.enable {
services.pipewire.lowLatency = {
# enable this module
enable = true;
# defaults (no need to be set unless modified)
quantum = 32;
rate = 48000;
};
security.rtkit.enable = true;
# Real time configurations
boot.kernel.sysctl = {
"vm.swappiness" = 10;
"fs.inotify.max_user_watches" = 524288;
};
security.pam.loginLimits = [
{
domain = "@audio";
item = "rtprio";
type = "-";
value = "90";
}
{
domain = "@audio";
item = "memlock";
type = "-";
value = "unlimited";
}
];
};
in
{
imports = with modules; [ adb ios wlr logitech virtualisation accounts ];
imports = with modules; [
./sops.nix
adb
ios
graphics
wlr
logitech
kwallet
virtualisation
accounts
rt-audio
];
options.common.linux = {
enable = mkOption {
@ -87,7 +149,7 @@ in
dnsServers = mkOption {
type = types.listOf types.str;
description = "DNS server list";
default = [ "8.8.8.8" "8.8.4.4" ];
default = [ "1.1.1.1" "2606:4700:4700:1111" ];
};
networks = mkOption {
type = types.attrsOf (types.submodule {
@ -121,11 +183,10 @@ in
boot.kernelPackages = mkDefault pkgs.linuxPackages_latest;
# Use the systemd-boot EFI boot loader.
boot = {
plymouth.enable = true;
loader.timeout = 60;
loader.systemd-boot.enable = true;
loader.efi.canTouchEfiVariables = true;
supportedFilesystems = [ "ntfs" ];
supportedFilesystems.ntfs = true;
};
boot.initrd.systemd.enable = builtins.length (builtins.attrNames (cfg.luksDevices)) > 0;
# LUKS devices
@ -143,8 +204,11 @@ in
cfg.luksDevices;
## Hardware-related
# Firmware stuff
services.fwupd.enable = true;
# Enable sound.
sound.enable = true;
services.pipewire = {
enable = true;
# alsa is optional
@ -153,6 +217,7 @@ in
pulse.enable = true;
};
# udev configurations
services.udev.packages = with pkgs; [
qmk-udev-rules # For keyboards
@ -174,12 +239,17 @@ in
extraGroups = [
"wheel" # Enable sudo for the user.
"plugdev" # Enable openrazer-daemon privileges
"audio"
];
shell = pkgs.fish;
};
nix.settings.trusted-users = [ "root" cfg.username ];
## Network configuration
systemd.network.enable = true;
networking.dhcpcd.enable = lib.mkForce false;
networking.useDHCP = false;
networking.useNetworkd = true;
systemd.network.wait-online.enable = false;
networking.hostName = cfg.networking.hostname;
networking.wireless.iwd.enable = true;
@ -202,38 +272,44 @@ in
services.tailscale.enable = true;
## Time and Region
time.timeZone = "Europe/Zurich";
time.timeZone = lib.mkDefault "Europe/Zurich";
# Select internationalisation properties.
console.keyMap = "jp106"; # Console key layout
i18n.defaultLocale = "ja_JP.UTF-8";
# Input methods (only fcitx5 works reliably on Wayland)
i18n.inputMethod = {
enabled = "fcitx5";
fcitx5.waylandFrontend = true;
fcitx5.addons = with pkgs; [
fcitx5-mozc
fcitx5-unikey
fcitx5-gtk
];
};
} // (if config.system.nixos.release == "24.05" then {
enabled = "fcitx5";
} else {
enable = true;
type = "fcitx5";
});
# Default packages
environment.systemPackages = with pkgs; [
kakoune # An editor
wget # A simple fetcher
fish # Good shell
## System monitoring tools
usbutils # lsusb and friends
pciutils # lspci and friends
psmisc # killall, pstree, ...
lm_sensors # sensors
## Security stuff
libsForQt5.qtkeychain
## Wayland
qt5.qtwayland
kdePackages.qtwayland
];
# Add a reliable terminal
programs.fish.enable = true;
# programs.gnome-terminal.enable = true;
# KDEConnect is just based
programs.kdeconnect.enable = true;
@ -243,20 +319,13 @@ in
programs.dconf.enable = true;
# Gaming! (not for ARM64)
programs.steam.enable = !pkgs.stdenv.isAarch64;
hardware.opengl.enable = true;
hardware.opengl.driSupport = true;
hardware.opengl.driSupport32Bit = !pkgs.stdenv.isAarch64; # For 32 bit applications
## Services
# gnome-keyring for storing keys
services.gnome.gnome-keyring.enable = true;
# OpenSSH so you can SSH to me
services.openssh.enable = true;
# PAM
security.pam.services.login.enableKwallet = true;
security.pam.services.login.enableGnomeKeyring = true;
security.pam.services.lightdm.enableKwallet = true;
security.pam.services.lightdm.enableGnomeKeyring = true;
security.pam.services.swaylock = { };
# Printers
services.printing.enable = true;
@ -264,8 +333,11 @@ in
xdg.portal = {
enable = true;
wlr.enable = true;
xdgOpenUsePortal = true;
# gtk portal needed to make gtk apps happy
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
extraPortals = [ pkgs.kdePackages.xdg-desktop-portal-kde pkgs.xdg-desktop-portal-gtk ];
config.sway.default = [ "wlr" "kde" "kwallet" ];
};
# D-Bus
services.dbus.packages = with pkgs; [ gcr ];

View file

@ -0,0 +1,18 @@
{ config, lib, ... }:
with { inherit (lib) types mkOption mkEnableOption; };
let
cfg = config.common.linux.sops;
in
{
options.common.linux.sops = {
enable = mkEnableOption "Enable sops configuration";
file = mkOption {
type = types.path;
description = "Path to the default sops file";
};
};
config = lib.mkIf cfg.enable {
sops.defaultSopsFile = cfg.file;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
};
}

View file

@ -34,11 +34,6 @@ in
default = 655;
description = "The port to listen on";
};
meshIp = mkOption {
type = types.str;
description = "The mesh ip to be assigned by hostname";
};
};
config = mkIf cfg.enable (builtins.seq
@ -51,7 +46,6 @@ in
myMeshIp = myHost.subnetAddr;
in
{
services.my-tinc.meshIp = myMeshIp;
# Scripts that set up the tinc services
environment.etc = {
"tinc/${networkName}/tinc-up".source = pkgs.writeScript "tinc-up-${networkName}" ''
@ -84,6 +78,11 @@ in
# firewall
networking.firewall.allowedUDPPorts = [ 655 ];
networking.firewall.allowedTCPPorts = [ 655 ];
networking.firewall.interfaces."tinc.${networkName}" = {
allowedUDPPortRanges = [{ from = 0; to = 65535; }];
allowedTCPPortRanges = [{ from = 0; to = 65535; }];
};
# configure tinc service
# ----------------------

View file

@ -23,10 +23,13 @@ in
hosts;
# Add all of them to host
networking.extraHosts = lib.strings.concatStringsSep
"\n"
(lib.attrsets.mapAttrsToList
(name: host: "${host.subnetAddr} ${name}.tinc")
hosts);
nki.services.edns = {
enable = true;
cloaking-rules =
(lib.attrsets.mapAttrs'
(name: host: { name = "${name}.tinc"; value = host.subnetAddr; })
hosts)
;
};
};
}

View file

@ -22,4 +22,14 @@
subnetAddr = "11.0.0.4";
ed25519PublicKey = "6MN5LVE4juavv8qJW2dTN4t/haKCADWquAQj/ADF7iN";
};
yoga = {
subnetAddr = "11.0.0.5";
ed25519PublicKey = "n+gIZjuuTPxi0OBqw2oOcmXd3loOHG+GQHBMXNlgyqI";
};
framework = {
subnetAddr = "11.0.0.6";
ed25519PublicKey = "YL7NA6Ydv/3FBfSzOPvyHlGweAViPvsG3b0Zh8L0NzF";
};
}

View file

@ -1,43 +1,29 @@
{ pkgs, lib, config, ... }:
{ pkgs, lib, ... }:
with lib;
let
noto-fonts-emoji-blob-bin =
let
pname = "noto-fonts-emoji-blob-bin";
version = "15.0";
in
pkgs.fetchurl {
name = "${pname}-${version}";
url = "https://github.com/C1710/blobmoji/releases/download/v${version}/Blobmoji.ttf";
sha256 = "sha256-n5yVk2w9x7UVrMe0Ho6nwu1Z9E/ktjo1UHdHKStoJWc=";
downloadToTemp = true;
recursiveHash = true;
postFetch = ''
install -Dm 444 $downloadedFile $out/share/fonts/blobmoji/Blobmoji.ttf
'';
};
in
{
imports = [ ./mounting.nix ];
# Fonts
config.fonts = {
fonts = with pkgs; [
packages = with pkgs; mkForce [
noto-fonts-emoji-blob-bin
ibm-plex
(nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; })
noto-fonts
noto-fonts-cjk
(pkgs.noto-fonts-cjk-sans or pkgs.noto-fonts-cjk)
merriweather
corefonts
font-awesome
hack-font # for Plasma
];
} // (if pkgs.stdenv.isLinux then {
enableDefaultFonts = false;
enableDefaultPackages = false;
fontconfig = {
defaultFonts = {
emoji = lib.mkBefore [ "Blobmoji" ];
serif = lib.mkBefore [ "IBM Plex Serif" "IBM Plex Sans JP" "IBM Plex Sans KR" ];
sansSerif = lib.mkBefore [ "IBM Plex Sans" "IBM Plex Sans JP" "IBM Plex Sans KR" ];
monospace = lib.mkBefore [ "IBM Plex Mono" ];
serif = lib.mkBefore [ "IBM Plex Serif" "IBM Plex Sans JP" "IBM Plex Sans KR" "Blobmoji" ];
sansSerif = lib.mkBefore [ "IBM Plex Sans" "IBM Plex Sans JP" "IBM Plex Sans KR" "Blobmoji" ];
monospace = lib.mkBefore [ "IBM Plex Mono" "Font Awesome 6 Free" "Symbols Nerd Font" "Blobmoji" "IBM Plex Sans JP" ];
};
localConf = ''
<?xml version="1.0"?>
@ -49,6 +35,7 @@ in
<family>IBM Plex Sans</family>
<family>IBM Plex Sans JP</family>
<family>IBM Plex Sans KR</family>
<family>Blobmoji</family>
</prefer>
</alias>
</fontconfig>

View file

@ -0,0 +1,29 @@
{ pkgs, config, lib, ... }:
lib.mkIf pkgs.stdenv.isLinux {
system.fsPackages = [ pkgs.bindfs ];
fileSystems =
let
mkRoSymBind = path: {
device = path;
fsType = "fuse.bindfs";
options = [ "ro" "resolve-symlinks" "x-gvfs-hide" ];
};
aggregatedIcons = pkgs.buildEnv {
name = "system-icons";
paths = with pkgs; [
#libsForQt5.breeze-qt5 # for plasma
(pkgs.gnome-themes-extra or gnome.gnome-themes-extra) # Until 24.11
];
pathsToLink = [ "/share/icons" ];
};
aggregatedFonts = pkgs.buildEnv {
name = "system-fonts";
paths = config.fonts.packages;
pathsToLink = [ "/share/fonts" ];
};
in
{
"/usr/share/icons" = mkRoSymBind "${aggregatedIcons}/share/icons";
"/usr/local/share/fonts" = mkRoSymBind "${aggregatedFonts}/share/fonts";
};
}

View file

@ -16,7 +16,7 @@ in
security.pam = mkIf pkgs.stdenv.isLinux {
u2f = {
enable = true;
cue = true;
settings.cue = true;
};
# Services

View file

@ -8,6 +8,11 @@ in
options.nki.services.edns = {
enable = mkEnableOption "Enable encrypted DNS";
ipv6 = mkEnableOption "Enable ipv6";
cloaking-rules = mkOption {
type = types.attrsOf types.str;
default = { };
description = "A set of domain -> ip mapping for cloaking_rules";
};
};
config = mkIf cfg.enable {
@ -42,6 +47,11 @@ in
{ server_name = "*"; via = [ "anon-plan9-dns" "anon-v.dnscrypt.up-ipv4" ]; }
];
anonymized_dns.skip_incompatible = true;
# Cloaking rules
cloaking_rules = pkgs.writeText "cloaking_rules.txt" (lib.strings.concatStringsSep
"\n"
(lib.attrsets.mapAttrsToList (name: ip: "${name} ${ip}") cfg.cloaking-rules));
};
};
};

View file

@ -0,0 +1,66 @@
{ config, lib, ... }:
with { inherit (lib) mkOption types mkIf; };
let
cfg = config.services.nix-build-farm;
hosts = import ./hosts.nix;
build-user = "nix-builder";
isBuilder = host: host ? "builder";
allBuilders = lib.filterAttrs (_: isBuilder) hosts;
in
{
options.services.nix-build-farm = {
enable = mkOption {
type = types.bool;
default = true;
description = "Whether to enable nix-build-farm as a client";
};
hostname = mkOption {
type = types.enum (builtins.attrNames hosts);
description = "The hostname as listed in ./hosts.nix file";
};
privateKeyFile = mkOption {
type = types.path;
description = "The path to the private SSH key file";
};
ipAddrs = mkOption {
type = types.str;
description = "The ip addresses to limit access to";
default = "11.0.0.*";
};
};
config = mkIf cfg.enable (
let
host = hosts.${cfg.hostname};
otherHosts = lib.filterAttrs (name: _: name != cfg.hostname) hosts;
otherBuilders = lib.filterAttrs (name: _: name != cfg.hostname) allBuilders;
in
{
nix.distributedBuilds = true;
nix.buildMachines = lib.mapAttrsToList
(name: host: {
hostName = host.host;
sshUser = build-user;
sshKey = cfg.privateKeyFile;
} // host.builder)
otherBuilders;
users = mkIf (isBuilder host) {
users.${build-user} = {
description = "Nix build farm user";
group = build-user;
isNormalUser = true;
openssh.authorizedKeys.keys = lib.mapAttrsToList (_: host: ''from="${cfg.ipAddrs}" ${host.pubKey}'') otherHosts;
};
groups.${build-user} = { };
};
nix.settings.trusted-users = mkIf (isBuilder host) [ build-user ];
}
);
}

View file

@ -0,0 +1,37 @@
{
cloud = {
host = "cloud.tinc";
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE87ddj0fTH0NuvJz0dT5ln7v7zbafXqDVdM2A4ddOb0 root@nki-personal-do";
};
home = {
host = "home.tinc";
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK6N1uTxnbo73tyzD9X7d7OgPeoOpY7JmQaHASjSWFPI nki@kagamiPC";
builder = {
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUhiVTh2NlNBa0kyOTBCc1QzVG1IRVVJQWdXcVFyNm9jRmpjakRRczRoT2ggcm9vdEBrYWdhbWlQQwo=";
systems = [ "x86_64-linux" "aarch64-linux" ];
maxJobs = 16;
speedFactor = 2;
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
};
};
yoga = {
host = "yoga.tinc";
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE6ZrO/xIdmwBCUx80cscBSpJBBTp55OHGrXYBGRXKAw nki@nki-yoga-g8";
};
framework = {
host = "framework.tinc";
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH/g472MaT7YySUhBjxClfmMjpn98qYnKXDKlzWHYwuO nki@nki-framework";
builder = {
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUdOUlBCVFRkNTVVMXY1U1Jac0FjYVdhS3JGZTY0ZjIxOVViODVTQ2NWd28gcm9vdEBua2ktZnJhbWV3b3JrCg==";
systems = [ "x86_64-linux" "aarch64-linux" ];
maxJobs = 16;
speedFactor = 3;
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
};
};
}

View file

@ -0,0 +1 @@
nix.home.tinc:zG2uDy0MbLY0wLuoVH/qKzTD6hTfKZufA2cWDSTCZMA=

View file

@ -0,0 +1,60 @@
{ config, pkgs, lib, ... }:
with { inherit (lib) mkEnableOption mkOption types mkIf; };
let
cfg = config.nki.services.nix-cache;
bindAddr = "127.0.0.1:5000";
in
{
options.nki.services.nix-cache = {
enableClient = mkOption {
type = types.bool;
default = !cfg.enableServer;
description = "Enable nix-cache client";
};
enableServer = mkEnableOption "Enable nix-cache server";
host = mkOption {
type = types.str;
default = "nix.home.tinc";
};
publicKey = mkOption {
type = types.str;
default = builtins.readFile ./cache-pub-key.pem;
};
privateKeyFile = mkOption {
type = types.path;
description = "Path to the private key .pem file";
};
};
config = {
nix.settings = mkIf cfg.enableClient {
substituters = lib.mkAfter [ "http://${cfg.host}" ];
trusted-public-keys = [ cfg.publicKey ];
};
services.harmonia = mkIf cfg.enableServer {
enable = true;
signKeyPath = cfg.privateKeyFile;
settings = {
bind = bindAddr;
priority = 45;
};
};
services.nginx = mkIf cfg.enableServer {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
# ... existing hosts config etc. ...
"${cfg.host}" = {
locations."/".proxyPass = "http://${bindAddr}";
};
};
};
};
}

View file

@ -1,12 +0,0 @@
{ pkgs, config, lib, ... }:
with lib;
let
cfg = config.nki.services.pam;
in
{
options.nki.services.pam.enableGnomeKeyring = mkEnableOption "Enable gnome-keyring on login";
config = mkIf cfg.enableGnomeKeyring {
security.pam.services.login.enableGnomeKeyring = true;
# security.pam.services.login.gnupg.enable = true;
};
}

View file

@ -0,0 +1,132 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, pkgs, lib, ... }:
{
imports =
[
# Include the results of the hardware scan.
./hardware-configuration.nix
# Fonts
../modules/personal/fonts
# Encrypted DNS
../modules/services/edns
# Wireless card
./wireless.nix
];
# Sops
common.linux.sops.enable = true;
common.linux.sops.file = ./secrets.yaml;
sops.secrets."nix-build-farm/private-key" = { mode = "0400"; };
services.nix-build-farm.hostname = "framework";
services.nix-build-farm.privateKeyFile = config.sops.secrets."nix-build-farm/private-key".path;
# services.xserver.enable = true;
# services.xserver.displayManager.sddm.enable = true;
# services.xserver.displayManager.sddm.wayland.enable = true;
services.desktopManager.plasma6.enable = true;
# Power Management
services.upower = {
enable = true;
criticalPowerAction = "Hibernate";
usePercentageForPolicy = true;
percentageCritical = 3;
percentageLow = 10;
};
services.power-profiles-daemon.enable = true;
# powerManagement.enable = true;
# powerManagement.powertop.enable = true;
services.logind.lidSwitch = "suspend-then-hibernate";
# Printing
services.printing.drivers = with pkgs; [ epfl-cups-drivers ];
# Enable touchpad support (enabled default in most desktopManager).
services.libinput.enable = true;
# Keyboard
services.input-remapper.enable = true;
services.input-remapper.serviceWantedBy = [ "multi-user.target" ];
hardware.uinput.enable = true;
# Define a user account. Don't forget to set a password with passwd.
common.linux.username = "nki";
# Networking
common.linux.networking = {
hostname = "nki-framework";
networks."10-wired".match = "enp*";
networks."20-wireless".match = "wlan*";
dnsServers = [ "127.0.0.1" ];
};
nki.services.edns.enable = true;
nki.services.edns.ipv6 = true;
# Backup home
services.btrbk.extraPackages = with pkgs; [ sudo ];
services.btrbk.instances.home = {
onCalendar = "hourly";
settings = {
snapshot_preserve = "24h 30d 6m 1y";
snapshot_preserve_min = "7d";
volume."/" = {
subvolume.home.snapshot_name = ".backups-home";
};
};
};
# Enable fingerprint auth for some stuff
security.pam.services.sudo.fprintAuth = true;
security.pam.services.swaylock.fprintAuth = true;
security.pam.services.login.fprintAuth = true;
# tinc network
sops.secrets."tinc-private-key" = { };
services.my-tinc = {
enable = true;
hostName = "framework";
ed25519PrivateKey = config.sops.secrets."tinc-private-key".path;
bindPort = 6565;
};
# Secrets
# sops.defaultSopsFile = ./secrets.yaml;
# sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
## tinc
# sops.secrets."tinc/ed25519-private-key" = { };
# services.my-tinc = {
# enable = true;
# hostName = "macbooknix";
# ed25519PrivateKey = config.sops.secrets."tinc/ed25519-private-key".path;
# bindPort = 6565;
# };
services.dbus.packages = with pkgs; [ gcr ];
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# Copy the NixOS configuration file and link it from the resulting system
# (/run/current-system/configuration.nix). This is useful in case you
# accidentally delete configuration.nix.
# system.copySystemConfiguration = true;
# 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 = "22.05"; # Did you read the comment?
}

View file

@ -0,0 +1,74 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.kernelPackages = pkgs.linuxPackages; # until mesa fixed
boot.kernelParams = [
# Hibernation
"resume=UUID=fa8aaf51-b99f-4fb4-9230-8c0957d8af3f"
"resume_offset=5776640" # btrfs inspect-internal map-swapfile -r /var/swapfile
];
fileSystems."/" =
{
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
fsType = "btrfs";
options = [ "subvol=root" "compress=zstd" ];
};
services.btrfs.autoScrub = {
enable = true;
interval = "monthly";
};
common.linux.luksDevices."cryptroot" = "/dev/disk/by-uuid/94226aae-6d1c-401a-bfad-3aa5f371a365";
fileSystems."/home" =
{
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
fsType = "btrfs";
options = [ "subvol=home" "compress=zstd" ];
};
fileSystems."/nix" =
{
device = "/dev/disk/by-uuid/fa8aaf51-b99f-4fb4-9230-8c0957d8af3f";
fsType = "btrfs";
options = [ "subvol=nix" "compress=zstd" ];
};
fileSystems."/boot" =
{
device = "/dev/disk/by-uuid/6A0E-4D23";
fsType = "vfat";
};
swapDevices = [
{ device = "/var/swapfile"; size = 32 * 1024; priority = 10; }
];
# 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.wlp1s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
environment.systemPackages = with pkgs; [ vulkan-validation-layers ];
# Fingerprint
services.fprintd.enable = true;
hardware.sensor.iio.enable = true; # Orientaion and ambient light sensors
}

View file

@ -0,0 +1,32 @@
tinc-private-key: ENC[AES256_GCM,data:cKtOFrF5FRSHWxe/QxH5O9GAba1WcWeCwW1IOzmbgdtFufRoWbCtYeaLP+WQhQ70z6xobiY9DN8Jrh7mDptKSsfKrrx2SH5JrdpsoINhLMbetXq7E29+q6CkS8NlLgE/KyV8eFjQySNsYiA/+Efq9xj9e1wOmHBDsND/jgiJDkA1qsEIFZg/vuv8LdoRY3TV/oKJ4pao9+70G4H+8Ef1sMZHGNe9qJ94Wa71nNX2fTSjKH5YBbRijMAePWr/IeCpZ9Phs7RqjBs=,iv:l0iB136X7nLVblQjFi7K4f42JKSxdsiLIRy5GPzK1nc=,tag:HAgkvWkl0Rx62ejGZckdKA==,type:str]
nix-build-farm:
private-key: ENC[AES256_GCM,data:w56sobHrhvVcKbuK15Yj20EqgFrR/5pNy/rcQjlZCiFEfgPC6ZrbsxziIdMTOX+Q4DyllKCKo+g/MIKm5S+s+nIff509ODlILhTtXlZvZlnT9+wvm5oN3WQCdkkqOr1gNnErPupfMxA6V35tNvNBCeomYuM8Xb7TuH4I1fXa5GFeT0Tnp5A2WqWoS1MzXz34CxlKXvoL6i4w7nUngt5zaGr9oMZbSa0pHxEzIhXk6h/lE864QlJid7q/mDok9gh2R80WvArGtNNj9PrT6cNKYIFuXo7vITkSkT3vo9BLflg5sgRxy4+7rBaRla0ziihQvZLtworwo6aNDvEqPqYfiX0TMYPpEWvJpp/HGDJy+Po7b0ZZkwSza+tB0J79vFH2h11Px1XSwXdq757Bn9G4OTb5oKWS5ycBU4xTnnHQBjYTSooFxYyTAvfKNEsB8AHKSuQRZgtVhWoOSPpJ6YL94ClUIT+DTaNmQjwouqNatf/nif+N/FCar8JWZDE+FX1TBu0yLmJie/f0LCdCQx+6IVdyXg7oVCoNiGg0,iv:TeSxlVc0WlOMMUtv/uq3f7JvW/kNCM7LjguhZxL51a4=,tag:m1iuk4pAX/yugM0ObzkJHQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age188tgu3psvywk6shq85mk2q0jdjwd0tcswzwlwu5pa5n3pndx75dq090z59
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmL2Z1RzBWaTI1TDl6WDNa
NTNVdEhTSFU5enNlTGVNWTI5anBZb1BtaVhjCm1BRnJDSXl1cWdBRUs1VnREVjBU
QWZxdkgzdm9JL0k5WmhDL1RCNTltdm8KLS0tIFhvQTlKMDZiVklTRWd4TzVmc2ll
bmpjcWdBV1doZml2NjlzQzdQczJ3alEKBMRP3POxtPIqBWnrvxY/++5jtVE70Uxa
EVfhsUO76A/hzyxfzpLEy1QGFE+DB/zlU0CK7HkNGPD2TrBHbzkPJA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1vgh6kvee8lvxylm7z86fpl3xzjyjs4u3zdfkyf064rjvxk9fpumsew7n27
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2MUxQU0dZOGRaekF4MWdo
T0krcERtRTJndFR1RHZmL0t6MjBxMW5PSENNCkR6SUhxQ0FoaEhuaWpiUzJ0MnJE
RXRERzVhL0lRVW1iRUlac0c5OHZsckEKLS0tIC9VM1dNZTNzdkFnMWk2YUwvcDNB
TDZnVjBaVzZBem5lZDB1MW4xQ0RmZ28K6d7mF+f3ZyilXlSIQGT2pBrTWuYLccE1
rYIJjHjFft/2wPX2gAW9VTiwfMT3lKJhJRqNdoie5phV5BZhkb3D9w==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-08-17T14:58:10Z"
mac: ENC[AES256_GCM,data:ZCrzXDttLxYUvdLiqM5I17Ys6O3zoOVKq8xP78VaLb3AAoV4RGGQxixKVQ6K9h84e8bFymh512BR7xKa9fqebxTyL1XCqPkRaSZy0aWjbc6QCaK+JD4yqivgO/x5x2xgMpX/ZhPFzKNLpMga61bnm6plvF8ocG+wOqYvj3vL0Ss=,iv:QZ8YJD7h2QD2jqVKo4bg0rwpZSTyyNw6zZDcBfClKPo=,tag:PH2XnTqxV2irymg2+Z+Egg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.0

View file

@ -0,0 +1,13 @@
{ pkgs, lib, ... }: {
environment.systemPackages = with pkgs; [ iw ];
# Disable power_save on boot
services.udev.packages = [
(pkgs.writeTextFile {
name = "udev_disable_wifi_power_save";
destination = "/etc/udev/rules.d/10-wifi-power_save.rules";
text = ''
ACTION=="add", SUBSYSTEM=="net", KERNEL=="wl*", RUN+="${lib.getExe pkgs.iw} dev $name set power_save off"
'';
})
];
}

View file

@ -0,0 +1,5 @@
{ config, pkgs, lib, ... }: {
environment.etc = {
"wireplumber/main.lua.d/51-sdac.lua".source = ./sdac.lua;
};
}

16
nki-home/audio/sdac.lua Normal file
View file

@ -0,0 +1,16 @@
rule = {
matches = {
{
{ "node.name", "matches", "alsa_output.usb-Grace_Design_SDAC-00.*" },
},
},
apply_properties = {
["audio.format"] = "S24_3LE",
["audio.rate"] = 96000,
["api.alsa.period-size"] = 2,
["api.alsa.headroom"] = 0,
["api.alsa.disable-batch"] = true
},
}
table.insert(alsa_monitor.rules, rule)

View file

@ -10,19 +10,37 @@ with lib;
[
# Include the results of the hardware scan.
./hardware-configuration.nix
# secret management
./secrets
# Fonts
../modules/personal/fonts
# Encrypted DNS
../modules/services/edns
# Other services
../modules/personal/u2f.nix
./peertube-runner.nix
];
# Kernel
boot.kernelPackages = pkgs.linuxKernel.packages.linux_xanmod_stable;
# Plasma!
services.desktopManager.plasma6.enable = true;
## Encryption
# Kernel modules needed for mounting USB VFAT devices in initrd stage
common.linux.luksDevices.root = "/dev/disk/by-uuid/7c6e40a8-900b-4f85-9712-2b872caf1892";
common.linux.sops.enable = true;
common.linux.sops.file = ./secrets.yaml;
# Nix cache server
sops.secrets."nix-cache/private-key" = { owner = "harmonia"; group = "harmonia"; mode = "0600"; };
nki.services.nix-cache = {
enableServer = true;
privateKeyFile = config.sops.secrets."nix-cache/private-key".path;
};
sops.secrets."nix-build-farm/private-key" = { mode = "0400"; };
services.nix-build-farm.hostname = "home";
services.nix-build-farm.privateKeyFile = config.sops.secrets."nix-build-farm/private-key".path;
# Networking
common.linux.networking =
@ -53,13 +71,11 @@ with lib;
PrivateKeyFile = config.sops.secrets."dtth-wg/private-key".path;
};
wireguardPeers = [{
wireguardPeerConfig = {
PublicKey = "+7iI4jwmM1Qr+/DKB1Hv8JgFkGu7lSV0PAoo+O5d3yQ=";
PresharedKeyFile = config.sops.secrets."dtth-wg/preshared-key".path;
AllowedIPs = [ "100.64.0.0/10" "fd00::/106" ];
Endpoint = "vpn.dtth.ch:51820";
PersistentKeepalive = 25;
};
PublicKey = "+7iI4jwmM1Qr+/DKB1Hv8JgFkGu7lSV0PAoo+O5d3yQ=";
PresharedKeyFile = config.sops.secrets."dtth-wg/preshared-key".path;
AllowedIPs = [ "100.64.0.0/10" "fd00::/106" ];
Endpoint = "vpn.dtth.ch:51820";
PersistentKeepalive = 25;
}];
};
systemd.network.networks."dtth-wg" = {
@ -67,8 +83,8 @@ with lib;
address = [ "100.73.146.80/32" "fd00::33:105b/128" ];
DHCP = "no";
routes = [
{ routeConfig = { Destination = "100.64.0.0/10"; Scope = "link"; }; }
{ routeConfig.Destination = "fd00::/106"; }
{ Destination = "100.64.0.0/10"; Scope = "link"; }
{ Destination = "fd00::/106"; }
];
};
@ -97,6 +113,7 @@ with lib;
"/mnt/Data" = ntfsMount "/dev/disk/by-uuid/A90680F8BBE62FE3";
"/mnt/Stuff" = ntfsMount "/dev/disk/by-uuid/717BF2EE20BB8A62";
"/mnt/Shared" = ntfsMount "/dev/disk/by-uuid/76AC086BAC0827E7";
"/mnt/osu" = ntfsMount "/dev/disk/by-uuid/530D3E1648CD1C26";
};
# PAM
@ -129,7 +146,7 @@ with lib;
MusicFolder = "/mnt/Stuff/Music";
};
systemd.services.navidrome.serviceConfig.BindReadOnlyPaths = lib.mkAfter [ "/etc" ];
networking.firewall.allowedTCPPorts = [ 4533 ];
networking.firewall.allowedTCPPorts = [ 4533 8000 ];
# Printers
services.printing.enable = true;

View file

@ -7,6 +7,7 @@
imports =
[
(modulesPath + "/installer/scan/not-detected.nix")
./audio
];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
@ -19,6 +20,12 @@
device = "/dev/disk/by-uuid/32a74827-4624-43ef-b066-b52e1f11793d";
fsType = "ext4";
};
fileSystems."/home/nki/Projects" =
{
device = "/dev/disk/by-uuid/025cb533-e21b-47f2-b7d5-322b7b95b831";
fsType = "btrfs";
options = [ "compress=zstd" ];
};
fileSystems."/boot" =
{
@ -29,10 +36,6 @@
swapDevices =
[{ device = "/dev/disk/by-uuid/561f6441-1915-4059-a5e1-76a449b0c9bf"; }];
# GPU options
services.xserver.videoDrivers = [ "amdgpu" ];
hardware.opengl.enable = true;
# bluetooth usb
hardware.firmware = [ pkgs.rtl8761b-firmware ];
}

View file

@ -0,0 +1,67 @@
{ config, pkgs, lib, ... }:
let
user = "peertube-runner-nodejs";
instance = "systemd-instance";
in
{
sops.secrets."peertube/dtth-key" = {
restartUnits = [ "peertube-runner.service" ];
};
users.groups.${user} = { };
users.users.${user} = {
isSystemUser = true;
group = user;
};
sops.templates."peertube-config.toml".owner = user;
sops.templates."peertube-config.toml".content = ''
[jobs]
concurrency = 2
[ffmpeg]
threads = 12
nice = 20
[[registeredInstances]]
url = "https://peertube.dtth.ch"
runnerToken = "${config.sops.placeholder."peertube/dtth-key"}"
runnerName = "kagamipc"
'';
environment.etc."${user}/${instance}/config.toml".source = config.sops.templates."peertube-config.toml".path;
systemd.services.peertube-runner = {
description = "PeerTube runner daemon";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
requires = [ ];
serviceConfig =
{
ExecStart = "${lib.getExe' pkgs.peertube.runner "peertube-runner"} server --id ${instance}";
User = user;
RuntimeDirectory = user;
StateDirectory = user;
CacheDirectory = user;
# Hardening
ProtectSystem = "full";
PrivateDevices = false;
NoNewPrivileges = true;
ProtectHome = true;
CapabilityBoundingSet = "~CAP_SYS_ADMIN";
};
environment = {
NODE_ENV = "production";
# Override XDG values to fit env-path
# https://github.com/sindresorhus/env-paths/blob/main/index.js
XDG_DATA_HOME = "/run";
XDG_CONFIG_HOME = "/etc";
XDG_CACHE_HOME = "/var/cache";
XDG_STATE_HOME = "/var/lib";
};
path = with pkgs; [ nodejs ffmpeg ];
};
}

View file

@ -11,6 +11,12 @@ scrobble:
dtth-wg:
private-key: ENC[AES256_GCM,data:ySxPGzOplKwNLxRnPNw7If7xzxMwRkwTasT7FaQE9n5YB04R+gaQVjDqPqg=,iv:f5t94bUoo9sCGGwWytiuhg5jcKjzRjbR3Q0OIM28VDU=,tag:fJos9Hb9XytQbfGaPMa1/A==,type:str]
preshared-key: ENC[AES256_GCM,data:96q0ZfvPz4pb53XvTGameVkcETamYH8Xbv69672RBdacH6QjRCCVvPnBTfA=,iv:Q2Yonb07/Uu6KidhMgRX4zJuNU1ZySNC7g/5TwpMU80=,tag:1qQQdk20yIQlGZmX+/25RA==,type:str]
peertube:
dtth-key: ENC[AES256_GCM,data:Gu7qOisVBZrFXKBr51165FJ7Ej4hV+lIf3AMC02R3UFNXOnTHF2xC8E=,iv:F83FuD1VjZEJFMcx3gkQuKCpJmYdHtO15fRHkYdMxJM=,tag:ScH42Tr5ZsIo9JMnXhylSw==,type:str]
nix-cache:
private-key: ENC[AES256_GCM,data:4sbfIQb10Y50CrZbgjN+1iXEbXTpDqMbIB/yA3WlaAqhLtb8HKib5aZX3DLoxFbVihJcztQsvBBgEAhT9iMijoksaT9qzBQ5yIn4NGCfFem1DK8DQdjhTLMCVTyMFCT7hQHu/2Sd7w==,iv:zTSxuKOtOLekOBKBvl9MScD/Bo1Hviqq/n8Saa+1Cgo=,tag:fx73fCDPY9d07V3KKMw3DA==,type:str]
nix-build-farm:
private-key: ENC[AES256_GCM,data:m5neeWCEdaZ1MRhNwTptfDIgv3ABNlYyNil3oTD81Jbe/6WxWaS5Q++CRlHCjc2hOoHsWsZixw8iGZVTA+QXgH6B9C6A4oOAhgR9m92EGTEfFw0qxQbdzs7U98Yonx/N8SApUycZZB/EU81+MrDNY4GGzCiO6s00/vZLkDTYnqRFgbo+8KTG0BQTl4q+VYP2q3l0wy+Ivz5CWPmbz42Xdin/sBnjeFHKDuof4iZZnN3i8gUJ/mMw3lbdiHd6A8DL0G5Ut46ljzMC2aMsZOATCID3mPOPgI0xIetDofPJLDqVsNqptRHo8WB+KwDidvl222f5F7JqdSqgAMOJYPscrX0odufApiJfg5bbXBygvrDfAlPSruW7GsWGoKAhw0qC4NC/j+qYCwhS0qdorCLnIy3zzMtA6HkHtE675hy7/7oLj7k9Y8MhE4PxztjXTmDazaVCtKhnA/DpaxP2mH84gfCkJFD1YF9jtPm+P3e+46FwkW+WnHaA2L+H7Evava30DLEBhh5y9Gd1A3JN4isn,iv:7KUWg7+GWgmGJkbIvsy9gtccZBb+1Y5uDWhXQFk0obk=,tag:qJdM684XPHxecLVxVb5pgw==,type:str]
sops:
kms: []
gcp_kms: []
@ -44,8 +50,8 @@ sops:
bUhIT0Z2b1dVWGNyS1hRVFRyZTA4d00KchP7EhSOMwBl5vFuuskzosRoi8jUu1sw
hVjJNF2a40ewgkQgVAoWEzirHbknbQORzmepDDRth7Bve3UQU64+GA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-04-29T13:03:22Z"
mac: ENC[AES256_GCM,data:ZNDRS6LLy89TZoW27c57RMnjs6M/GBH0XfKKlrhys8gL7+I0V/++ry59VDbLxvqS4nPR4C5hk777+B5dqnseyYW2xRT3NKYxocCQu5kO6A8L/wB00j3bm3SSIGwLcKJPibEqi7ymU53K0bmZdjRMChkBwv3CnDNkM3Dc6rvZ2DM=,iv:Z1ZjnYW1Yk+oEzNknQDytTengjKxcud95LZTFfKMnpw=,tag:pnZ+UGQWuRCKoTll00oUKA==,type:str]
lastmodified: "2024-08-16T13:59:20Z"
mac: ENC[AES256_GCM,data:ncT8fbtEb9ZcLcftXwgAKJRPPSG4TRHFMArtVgWNmIjDRcCNNT7ICa+9Dl8DAYKRJ+8pgelV9StIg2f7rvypHYlckontEP5nwSFzEApLItG3AZXewTC8VPoDYb4T8/OWKDoa5kBMvGrDr1bFP/CZz7H8No+k5TV7fVExsw0PHpg=,iv:vxbkeJtHkOAq7NcaZEIOMV3qGEqBUg/vpJYumBBfY70=,tag:T0yw2x1O5Tp0UllLpcFryg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3
version: 3.9.0

View file

@ -1,6 +0,0 @@
{ config, pkgs, ... }:
{
sops.defaultSopsFile = ./secrets.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
}

View file

@ -10,9 +10,10 @@
../modules/cloud/bitwarden
../modules/cloud/mail
../modules/cloud/conduit
../modules/cloud/writefreely
../modules/cloud/gotosocial
../modules/cloud/outline.nix
# Encrypted DNS
../modules/services/edns
./headscale.nix
./gitea.nix
@ -20,8 +21,14 @@
./writefreely.nix
./synapse.nix
./phanpy.nix
./invidious.nix
./owncast.nix
./peertube.nix
./outline.nix
];
system.stateVersion = "21.11";
common.linux.enable = false; # Don't enable the "common linux" module, this is a special machine.
# Personal user
@ -47,6 +54,7 @@
environment.systemPackages = with pkgs; [
git
htop-vim
kakoune
docker-compose
];
@ -55,19 +63,15 @@
services.do-agent.enable = true;
system.autoUpgrade = {
enable = true;
allowReboot = true;
flake = "github:natsukagami/nix-home#nki-personal-do";
};
nix = {
package = pkgs.nixUnstable;
extraOptions = ''
experimental-features = nix-command flakes
'';
};
nki.services.edns.enable = true;
nki.services.edns.ipv6 = true;
# Secret management
sops.defaultSopsFile = ./secrets/secrets.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
@ -80,6 +84,10 @@
services.my-tinc.rsaPrivateKey = config.sops.secrets."tinc/rsa-private-key".path;
services.my-tinc.ed25519PrivateKey = config.sops.secrets."tinc/ed25519-private-key".path;
sops.secrets."nix-build-farm/private-key" = { mode = "0400"; };
services.nix-build-farm.hostname = "home";
services.nix-build-farm.privateKeyFile = config.sops.secrets."nix-build-farm/private-key".path;
# Set up traefik
sops.secrets.cloudflare-dns-api-token = { owner = "traefik"; };
sops.secrets.traefik-dashboard-users = { owner = "traefik"; };
@ -184,75 +192,13 @@
protocol = "udp";
};
# Outline
sops.secrets.minio-secret-key = { owner = "root"; mode = "0444"; };
sops.secrets.authentik-oidc-client-secret = { owner = "outline"; };
sops.secrets."outline/smtp-password" = { owner = "outline"; };
cloud.services.outline = {
enable = true;
package = pkgs.unstable.outline.overrideAttrs (attrs: {
patches = if builtins.hasAttr "patches" attrs then attrs.patches else [ ] ++ [ ../modules/cloud/outline/dtth-wiki.patch ];
});
databaseUrl = "postgres://outline:outline@localhost/outline?sslmode=disable";
sequelizeArguments = "--env=production-ssl-disabled";
redisUrl = "local";
publicUrl = "https://wiki.dtth.ch";
port = 18729;
storage = {
accessKey = "minio";
secretKeyFile = config.sops.secrets.minio-secret-key.path;
region = config.services.minio.region;
uploadBucketUrl = "https://s3.dtth.ch";
uploadBucketName = "dtth-outline";
uploadMaxSize = 50 * 1024 * 1000;
};
maximumImportSize = 50 * 1024 * 1000;
oidcAuthentication = {
clientId = "3a0c10e00cdcb4a1194315577fa208a747c1a5f7";
clientSecretFile = config.sops.secrets.authentik-oidc-client-secret.path;
authUrl = "https://auth.dtth.ch/application/o/authorize/";
tokenUrl = "https://auth.dtth.ch/application/o/token/";
userinfoUrl = "https://auth.dtth.ch/application/o/userinfo/";
displayName = "DTTH Account";
};
smtp = {
fromEmail = "DTTH Wiki <dtth.wiki@nkagami.me>";
replyEmail = "";
host = "mx1.nkagami.me";
username = "dtth.wiki@nkagami.me";
passwordFile = config.sops.secrets."outline/smtp-password".path;
port = 465;
secure = true;
};
forceHttps = false;
};
cloud.postgresql.databases = [ "outline" ];
systemd.services.outline.requires = [ "postgresql.service" ];
cloud.traefik.hosts.outline = { host = "wiki.dtth.ch"; port = 18729; };
# GoToSocial
sops.secrets.gts-env = { };
sops.secrets.gts-env = { restartUnits = [ "gotosocial.service" ]; };
cloud.gotosocial = {
enable = true;
envFile = config.sops.secrets.gts-env.path;
};
# Minio
sops.secrets.minio-credentials = { };
services.minio = {
enable = true;
listenAddress = ":61929";
consoleAddress = ":62929";
rootCredentialsFile = config.sops.secrets.minio-credentials.path;
dataDir = lib.mkForce [ "/mnt/data/minio" ];
};
cloud.traefik.hosts.minio = { host = "s3.dtth.ch"; port = 61929; };
system.stateVersion = "21.11";
# ntfy
cloud.traefik.hosts.ntfy-sh = { host = "ntfy.nkagami.me"; port = 11161; noCloudflare = true; };
services.ntfy-sh = {

View file

@ -9,11 +9,28 @@ let
signingKey = "0x3681E15E5C14A241";
catppuccinThemes = builtins.fetchurl {
url = "https://github.com/catppuccin/gitea/releases/download/v0.2.1/catppuccin-gitea.tar.gz";
sha256 = "sha256:18l67whffayrgylsf5j6g7sj95anjcjl0cy7fzqn1wrm0gg2xns0";
catppuccinThemes = pkgs.fetchurl {
url = "https://github.com/catppuccin/gitea/releases/download/v0.4.1/catppuccin-gitea.tar.gz";
hash = "sha256-/P4fLvswitlfeaKaUykrEKvjbNpw5Q/nzGQ/GZaLyUI=";
};
themes = strings.concatStringsSep "," [
staticDir = pkgs.runCommandLocal "forgejo-static" { } ''
mkdir -p $out
tmp=$(mktemp -d)
cp -r ${config.services.forgejo.package.data}/* $tmp
chmod -R +w $tmp
# Copy icons
install -m 0644 ${./gitea/img}/* $tmp/public/assets/img
# Copy the themes
env PATH=${pkgs.gzip}/bin:${pkgs.gnutar}/bin:$PATH \
tar -xvf ${catppuccinThemes} -C $tmp/public/assets/css
cp -r $tmp/* $out
'';
default-themes = "forgejo-auto, forgejo-light, forgejo-dark, gitea-auto, gitea-light, gitea-dark, forgejo-auto-deuteranopia-protanopia, forgejo-light-deuteranopia-protanopia, forgejo-dark-deuteranopia-protanopia, forgejo-auto-tritanopia, forgejo-light-tritanopia, forgejo-dark-tritanopia";
themes = strings.concatStringsSep ", " [
"catppuccin-macchiato-green"
"catppuccin-mocha-teal"
"catppuccin-macchiato-sky"
@ -73,7 +90,15 @@ let
];
in
{
users.users.${user} = {
home = config.services.forgejo.stateDir;
useDefaultShell = true;
isSystemUser = true;
group = user;
};
users.groups.${user} = { };
sops.secrets."gitea/signing-key".owner = user;
sops.secrets."gitea/minio-secret-key".owner = user;
sops.secrets."gitea/mailer-password".owner = user;
# database
cloud.postgresql.databases = [ user ];
@ -83,21 +108,20 @@ in
noCloudflare = true;
};
systemd.services.gitea.requires = [ "postgresql.service" ];
systemd.services.forgejo.requires = [ "postgresql.service" ];
services.gitea = {
services.forgejo = {
enable = true;
inherit user;
appName = "DTTHgit";
settings = {
server = {
DOMAIN = host;
ROOT_URL = "https://${host}/";
HTTP_ADDRESS = "127.0.0.1";
HTTP_PORT = port;
STATIC_ROOT_PATH = staticDir;
};
repository = {
DEFAULT_PRIVATE = "private";
@ -111,10 +135,10 @@ in
};
"repository.signing" = {
SIGNING_KEY = signingKey;
SIGNING_NAME = "DTTHGit";
SIGNING_NAME = "DTTHgit";
SIGNING_EMAIL = "dtth-gitea@nkagami.me";
};
ui.THEMES = "auto,gitea,arc-green," + themes;
ui.THEMES = default-themes + "," + themes;
"ui.meta" = {
AUTHOR = "DTTHgit - Gitea instance for GTTH";
DESCRIPTION = "DTTHGit is a custom Gitea instance hosted for DTTH members only.";
@ -151,9 +175,23 @@ in
PATH = "${pkgs.git}/bin/git";
};
storage = {
STORAGE_TYPE = "minio";
MINIO_USE_SSL = "true";
MINIO_ENDPOINT = "60c0807121eb35ef52cdcd4a33735fa6.r2.cloudflarestorage.com";
MINIO_ACCESS_KEY_ID = "704c29ade7a8b438b77ab520da2799ca";
MINIO_SECRET_ACCESS_KEY = "#miniosecretkey#";
MINIO_BUCKET = "dtth-gitea";
MINIO_LOCATION = "auto";
MINIO_CHECKSUM_ALGORITHM = "md5"; # R2 moment
};
federation.ENABLED = true;
DEFAULT.APP_NAME = "DTTHGit";
};
stateDir = "/mnt/data/gitea";
mailerPasswordFile = secrets."gitea/mailer-password".path;
database = {
@ -172,31 +210,30 @@ in
};
# Set up gpg signing key
systemd.services.gitea = {
systemd.services.forgejo = {
path = with pkgs; [ gnupg ];
environment.GNUPGHOME = "${config.services.gitea.stateDir}/.gnupg";
# https://github.com/NixOS/nixpkgs/commit/93c1d370db28ad4573fb9890c90164ba55391ce7
serviceConfig.SystemCallFilter = mkForce "~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap";
preStart = ''
# Import the signing subkey
if cat ${config.services.gitea.stateDir}/.gnupg/gpg.conf | grep -q ${signingKey}; then
echo "Keys already imported"
# imported
else
echo "Import your keys!"
${pkgs.gnupg}/bin/gpg --quiet --import ${secrets."gitea/signing-key".path}
echo "trusted-key ${signingKey}" >> ${config.services.gitea.stateDir}/.gnupg/gpg.conf
exit 1
fi
# Copy icons
mkdir -p ${config.services.gitea.stateDir}/custom/public/img
install -m 0644 ${./gitea/img}/* ${config.services.gitea.stateDir}/custom/public/img
# Copy the themes
mkdir -p ${config.services.gitea.stateDir}/custom/public/css
env PATH=${pkgs.gzip}/bin:${pkgs.gnutar}/bin:$PATH \
tar -xvf ${catppuccinThemes} -C ${config.services.gitea.stateDir}/custom/public/css/
'';
preStart =
let
configFile = "${config.services.forgejo.customDir}/conf/app.ini";
in
''
# Update minio secret key
chmod u+w ${configFile} && \
${lib.getExe pkgs.replace-secret} '#miniosecretkey#' '${config.sops.secrets."gitea/minio-secret-key".path}' '${configFile}' && \
chmod u-w ${configFile}
# Import the signing subkey
if cat ${config.services.forgejo.stateDir}/.gnupg/gpg.conf | grep -q ${signingKey}; then
echo "Keys already imported"
# imported
else
echo "Import your keys!"
${pkgs.gnupg}/bin/gpg --quiet --import ${secrets."gitea/signing-key".path}
echo "trusted-key ${signingKey}" >> ${config.services.forgejo.stateDir}/.gnupg/gpg.conf
exit 1
fi
'';
};
}

View file

@ -9,9 +9,11 @@
swapDevices = [{ device = "/var/swapfile"; size = 4 * 1024; priority = 1024; }];
zramSwap.enable = true;
# volumes
services.btrfs.autoScrub.enable = true;
fileSystems.data = {
device = "/dev/disk/by-id/scsi-0HC_Volume_31812942";
fsType = "ext4";
device = "/dev/disk/by-id/scsi-0HC_Volume_101470796";
fsType = "btrfs";
mountPoint = "/mnt/data";
options = [ "compress=zstd" ];
};
}

View file

@ -0,0 +1,71 @@
{ config, pkgs, lib, ... }:
let
ipv6-rotator =
let
src = pkgs.fetchFromGitHub {
owner = "iv-org";
repo = "smart-ipv6-rotator";
rev = "61c019c2b14304c2a111a6db4c492d10ab2308cf";
hash = "sha256-a4BQH2D7La51vdPqMQSlZB73twX9Zcjq8mxbT5SdCpo=";
};
in
pkgs.writeShellApplication {
name = "smart-ipv6-rotator";
runtimeInputs = [ (pkgs.python3.withPackages (p: with p; [ pyroute2 requests ])) ];
text = ''
if [ -z "$IPV6_ROTATOR_RANGE" ]; then
echo "Range required"
exit 1
fi
python3 ${src}/smart-ipv6-rotator.py "$@" --ipv6range="$IPV6_ROTATOR_RANGE"
'';
};
in
{
sops.secrets."invidious" = { mode = "0444"; };
sops.secrets."invidious-rotator-env" = { mode = "0444"; };
cloud.postgresql.databases = [ "invidious" ];
cloud.traefik.hosts.invidious = { host = "invi.dtth.ch"; port = 61191; };
services.invidious = {
enable = true;
domain = "invi.dtth.ch";
port = 61191;
extraSettingsFile = config.sops.secrets.invidious.path;
settings = {
db.user = "invidious";
db.dbname = "invidious";
external_port = 443;
https_only = true;
hsts = false;
registration_enabled = true;
login_enabled = true;
admins = [ "nki" ];
# video_loop = false;
# autoplay = true;
# continue = true;
# continue_autoplay = true;
# listen = false;
# quality = "hd720";
# comments = [ "youtube" ];
# captions = [ "en" "vi" "de" "fr" ];
};
};
systemd.timers.smart-ipv6-rotator = {
description = "Rotate ipv6 routes to Google";
timerConfig = { OnCalendar = "*-*-* 00,06,12,18:00:00"; };
wantedBy = [ "invidious.service" "timers.target" ];
unitConfig = { };
};
systemd.services.smart-ipv6-rotator = {
serviceConfig = {
Type = "oneshot";
ExecStart = "${ipv6-rotator}/bin/smart-ipv6-rotator run";
EnvironmentFile = [
config.sops.secrets.invidious-rotator-env.path
];
};
};
}

View file

@ -1,67 +0,0 @@
{ lib, pkgs, config, ... }:
with lib;
let
user = "nextcloud";
host = "cloud.dtth.ch";
port = 61155;
secrets = config.sops.secrets;
in
{
sops.secrets."nextcloud/admin-password" = { owner = user; };
sops.secrets."nextcloud/minio-secret-key" = { owner = user; key = "minio-secret-key"; };
# database
cloud.postgresql.databases = [ user ];
# traefik
cloud.traefik.hosts.nextcloud = {
inherit port host;
};
systemd.services.nextcloud.requires = [ "postgresql.service" ];
services.nextcloud = {
enable = true;
hostName = host;
package = pkgs.nextcloud26;
enableBrokenCiphersForSSE = false;
home = "/mnt/data/nextcloud";
https = true;
database.createLocally = false;
extraApps = with pkgs.nextcloud26Packages.apps; {
inherit calendar contacts deck forms groupfolders news tasks;
sociallogin = pkgs.fetchNextcloudApp rec {
url = "https://github.com/zorn-v/nextcloud-social-login/releases/download/v5.4.3/release.tar.gz";
sha256 = "sha256-ZKwtF9j9WFIk3MZgng9DmN00A73S2Rb4qbehL9adaZo=";
};
};
config = {
# Database
dbtype = "pgsql";
dbname = user;
dbuser = user;
dbhost = "/run/postgresql";
# User
adminuser = "nki";
adminpassFile = secrets."nextcloud/admin-password".path;
# General
overwriteProtocol = "https";
defaultPhoneRegion = "VN";
objectstore.s3 = {
enable = true;
bucket = "nextcloud-dtth";
autocreate = true;
key = "minio";
secretFile = config.sops.secrets."nextcloud/minio-secret-key".path;
hostname = "s3.dtth.ch";
port = 443;
useSsl = true;
usePathStyle = true;
region = "us-east-1";
};
};
};
services.nginx.virtualHosts.${host}.listen = [{ inherit port; addr = "127.0.0.1"; }];
}

View file

@ -0,0 +1,56 @@
{ config, pkgs, ... }: {
sops.secrets.authentik-oidc-client-secret = { owner = "outline"; };
sops.secrets."outline/smtp-password" = { owner = "outline"; };
sops.secrets."outline/s3-secret-key" = { owner = "outline"; };
services.outline = {
enable = true;
package = pkgs.outline.overrideAttrs (attrs: {
patches = attrs.patches or [ ] ++ [
../modules/cloud/outline/dtth-wiki.patch
../modules/cloud/outline/r2.patch
];
});
databaseUrl = "postgres://outline:outline@localhost/outline?sslmode=disable";
redisUrl = "local";
publicUrl = "https://wiki.dtth.ch";
port = 18729;
storage = {
accessKey = "6ef730e13f172d2ed6ed77f0b5b9bad9";
secretKeyFile = config.sops.secrets."outline/s3-secret-key".path;
region = "auto";
uploadBucketUrl = "https://60c0807121eb35ef52cdcd4a33735fa6.r2.cloudflarestorage.com";
uploadBucketName = "dtth-outline";
uploadMaxSize = 50 * 1024 * 1000;
};
maximumImportSize = 50 * 1024 * 1000;
oidcAuthentication = {
clientId = "3a0c10e00cdcb4a1194315577fa208a747c1a5f7";
clientSecretFile = config.sops.secrets.authentik-oidc-client-secret.path;
authUrl = "https://auth.dtth.ch/application/o/authorize/";
tokenUrl = "https://auth.dtth.ch/application/o/token/";
userinfoUrl = "https://auth.dtth.ch/application/o/userinfo/";
displayName = "DTTH Account";
};
smtp = {
fromEmail = "DTTH Wiki <dtth.wiki@nkagami.me>";
replyEmail = "";
host = "mx1.nkagami.me";
username = "dtth.wiki@nkagami.me";
passwordFile = config.sops.secrets."outline/smtp-password".path;
port = 465;
secure = true;
};
forceHttps = false;
};
cloud.postgresql.databases = [ "outline" ];
systemd.services.outline.requires = [ "postgresql.service" ];
systemd.services.outline.environment = {
AWS_S3_R2 = "true";
AWS_S3_R2_PUBLIC_URL = "https://s3.wiki.dtth.ch";
};
cloud.traefik.hosts.outline = { host = "wiki.dtth.ch"; port = 18729; };
}

View file

@ -0,0 +1,19 @@
{ pkgs, config, lib, ... }:
let
host = "owncast.nkagami.me";
port = 61347;
user = "owncast";
in
{
# traefik
cloud.traefik.hosts.owncast = {
inherit port host;
};
services.owncast = {
inherit user port;
listen = "0.0.0.0"; # Listen to direct IP requests too
enable = true;
openFirewall = true;
dataDir = "${config.fileSystems.data.mountPoint}/owncast";
};
}

View file

@ -0,0 +1,80 @@
{ config, lib, pkgs, ... }:
let
secrets = config.sops.secrets;
cfg = config.services.peertube;
host = "peertube.dtth.ch";
port = 19878;
in
{
sops.secrets."peertube" = { owner = cfg.user; restartUnits = [ "peertube.service" ]; };
sops.secrets."peertube-env" = { owner = cfg.user; restartUnits = [ "peertube.service" ]; };
# database
cloud.postgresql.databases = [ "peertube" ];
# traefik
cloud.traefik.hosts.peertube = {
inherit port host;
noCloudflare = true;
};
services.peertube = {
enable = true;
enableWebHttps = true;
listenWeb = 443;
listenHttp = port;
localDomain = host;
secrets.secretsFile = secrets."peertube".path;
serviceEnvironmentFile = secrets."peertube-env".path;
# Databases
redis.createLocally = true;
database = {
host = "/run/postgresql";
};
# S3
settings.object_storage = {
enabled = true;
region = "auto";
proxy.proxify_private_files = false;
web_videos = {
bucket_name = "dtthtube";
prefix = "web-videos/";
base_url = "https://content.peertube.dtth.ch";
};
streaming_playlists = {
bucket_name = "dtthtube";
prefix = "hls-playlists/";
base_url = "https://content.peertube.dtth.ch";
};
};
# Storage
settings.client.videos = {
resumable_upload.max_chunk_size = "90MB";
};
settings.storage = {
storyboards = "/var/lib/peertube/storage/storyboards/";
tmp = "/mnt/data/peertube/tmp/";
tmp_persistent = "/mnt/data/peertube/tmp_persistent/";
web_videos = "/mnt/data/peertube/web-videos/";
};
# Trust proxy
settings.trust_proxy = [ "loopback" ] ++ config.services.traefik.staticConfigOptions.entrypoints.https.forwardedHeaders.trustedIPs;
# Federation
settings.federation = {
sign_federated_fetches = true;
videos.federate_unlisted = true;
videos.cleanup_remote_interactions = true;
};
dataDirs = [ "/var/lib/peertube" "/mnt/data/peertube" ];
};
}

File diff suppressed because one or more lines are too long

View file

@ -29,6 +29,7 @@ in
enable = true;
withJemalloc = true;
dataDir = "${config.fileSystems.data.mountPoint}/matrix-synapse-dtth";
extras = [ "systemd" "url-preview" "oidc" "postgres" ];
settings = {
server_name = "dtth.ch";
enable_registration = false;
@ -75,6 +76,10 @@ in
"fec0::/10"
];
app_service_config_files = app_services;
auto_join_rooms = [
"#join-dtth-matrix:dtth.ch"
];
};
extraConfigFiles = [
(config.sops.secrets."matrix-synapse-dtth/oidc-config".path)

View file

@ -11,7 +11,7 @@ in
# traefik
cloud.traefik.hosts.writefreely-dtth = { inherit host port; };
sops.secrets."writefreely-dtth" = { owner = user; };
sops.secrets."writefreely-oauth-secret" = { owner = user; };
users.users.${user} = {
isSystemUser = true;
@ -53,22 +53,24 @@ in
monetization = false;
};
"oauth.generic" = {
client_id = "rpoTTr2Wz0h4EgOSCHe0G85O8DCQDMup7JW9U9fV";
host = "https://auth.dtth.ch";
display_name = "DTTH";
token_endpoint = "/application/o/token/";
inspect_endpoint = "/application/o/userinfo/";
auth_endpoint = "/application/o/authorize/";
scope = "email openid profile";
map_user_id = "nickname";
map_username = "preferred_username";
map_display_name = "name";
allow_registration = true;
};
"oauth.generic" = { };
};
oauth = {
enable = true;
clientId = "rpoTTr2Wz0h4EgOSCHe0G85O8DCQDMup7JW9U9fV";
clientSecretFile = config.sops.secrets."writefreely-oauth-secret".path;
host = "https://auth.dtth.ch";
displayName = "DTTH";
tokenEndpoint = "/application/o/token/";
inspectEndpoint = "/application/o/userinfo/";
authEndpoint = "/application/o/authorize/";
scopes = [ "email" "openid" "profile" ];
mapUserId = "nickname";
mapUsername = "preferred_username";
mapDisplayName = "name";
};
extraSettingsFile = config.sops.secrets."writefreely-dtth".path;
database.type = "sqlite3";

View file

@ -15,8 +15,7 @@ let
if value == true then "true" else "false"
else
toString value);
in
"${key} = ${value'}";
in "${key} = ${value'}";
};
cfg = config.nki.services.writefreely;
@ -32,20 +31,19 @@ let
host = cfg.settings.app.host or "${hostProtocol}://${cfg.host}";
};
database =
if cfg.database.type == "sqlite3" then {
type = "sqlite3";
filename = cfg.settings.database.filename or "writefreely.db";
database = cfg.database.name;
} else {
type = "mysql";
username = cfg.database.user;
password = "#dbpass#";
database = cfg.database.name;
host = cfg.database.host;
port = cfg.database.port;
tls = cfg.database.tls;
};
database = if cfg.database.type == "sqlite3" then {
type = "sqlite3";
filename = cfg.settings.database.filename or "writefreely.db";
database = cfg.database.name;
} else {
type = "mysql";
username = cfg.database.user;
password = "#dbpass#";
database = cfg.database.name;
host = cfg.database.host;
port = cfg.database.port;
tls = cfg.database.tls;
};
server = cfg.settings.server or { } // {
bind = cfg.settings.server.bind or "localhost";
@ -58,6 +56,24 @@ let
cfg.settings.server.pages_parent_dir or cfg.package.src;
keys_parent_dir = cfg.settings.server.keys_parent_dir or cfg.stateDir;
};
"oauth.generic" = cfg.settings."oauth.generic" or { } // (if cfg.oauth.enable then {
client_id = cfg.oauth.clientId;
client_secret = "#oauth_client_secret#";
host = cfg.oauth.host;
display_name = cfg.oauth.displayName;
callback_proxy = cfg.oauth.callbackProxy;
callback_proxy_api = cfg.oauth.callbackProxyApi;
token_endpoint = cfg.oauth.tokenEndpoint;
inspect_endpoint = cfg.oauth.inspectEndpoint;
auth_endpoint = cfg.oauth.authEndpoint;
scope = lib.concatStringsSep " " cfg.oauth.scopes;
allow_disconnect = cfg.oauth.allowDisconnect;
map_user_id = cfg.oauth.mapUserId;
map_username = cfg.oauth.mapUsername;
map_display_name = cfg.oauth.mapDisplayName;
map_email = cfg.oauth.mapEmail;
} else { });
};
configFile = format.generate "config.ini" settings;
@ -91,10 +107,14 @@ let
optionalString (cfg.database.passwordFile != null)
"$(head -n1 ${cfg.database.passwordFile})"
}
oauth_client_secret=${
optionalString cfg.oauth.enable
"$(head -n1 ${cfg.oauth.clientSecretFile})"
}
install -m 0660 ${configFile} '${cfg.stateDir}/config.ini'
cp -f ${configFile} '${cfg.stateDir}/config.ini'
sed -e "s,#dbpass#,$db_pass,g" -i '${cfg.stateDir}/config.ini'
${if cfg.extraSettingsFile != null then "cat ${cfg.extraSettingsFile} >> ${cfg.stateDir}/config.ini" else ""}
sed -e "s,#oauth_client_secret#,$oauth_client_secret,g" -i '${cfg.stateDir}/config.ini'
chmod 440 '${cfg.stateDir}/config.ini'
${text}
@ -123,7 +143,7 @@ let
withConfigFile ''
query () {
local result=$(${sqlite}/bin/sqlite3 \
'${cfg.stateDir}/${settings.database.filename}'
'${cfg.stateDir}/${settings.database.filename}' \
"$1" \
)
@ -132,53 +152,46 @@ let
${text}
'';
in
{
in {
options.nki.services.writefreely = {
enable =
lib.mkEnableOption (lib.mdDoc "Writefreely, build a digital writing community");
lib.mkEnableOption "Writefreely, build a digital writing community";
package = lib.mkOption {
type = lib.types.package;
default = pkgs.writefreely;
defaultText = lib.literalExpression "pkgs.writefreely";
description = lib.mdDoc "Writefreely package to use.";
description = "Writefreely package to use.";
};
stateDir = mkOption {
type = types.path;
default = "/var/lib/writefreely";
description = lib.mdDoc "The state directory where keys and data are stored.";
description = "The state directory where keys and data are stored.";
};
user = mkOption {
type = types.str;
default = "writefreely";
description = lib.mdDoc "User under which Writefreely is ran.";
description = "User under which Writefreely is ran.";
};
group = mkOption {
type = types.str;
default = "writefreely";
description = lib.mdDoc "Group under which Writefreely is ran.";
description = "Group under which Writefreely is ran.";
};
host = mkOption {
type = types.str;
default = "";
description = lib.mdDoc "The public host name to serve.";
description = "The public host name to serve.";
example = "example.com";
};
extraSettingsFile = mkOption {
type = types.nullOr types.path;
default = null;
description = lib.mdDoc "Additional configs to be appended to the config file";
};
settings = mkOption {
default = { };
description = lib.mdDoc ''
description = ''
Writefreely configuration ({file}`config.ini`). Refer to
<https://writefreely.org/docs/latest/admin/config>
for details.
@ -192,7 +205,7 @@ in
theme = mkOption {
type = types.str;
default = "write";
description = lib.mdDoc "The theme to apply.";
description = "The theme to apply.";
};
};
@ -201,7 +214,7 @@ in
type = types.port;
default = if cfg.nginx.enable then 18080 else 80;
defaultText = "80";
description = lib.mdDoc "The port WriteFreely should listen on.";
description = "The port WriteFreely should listen on.";
};
};
};
@ -212,74 +225,158 @@ in
type = mkOption {
type = types.enum [ "sqlite3" "mysql" ];
default = "sqlite3";
description = lib.mdDoc "The database provider to use.";
description = "The database provider to use.";
};
name = mkOption {
type = types.str;
default = "writefreely";
description = lib.mdDoc "The name of the database to store data in.";
description = "The name of the database to store data in.";
};
user = mkOption {
type = types.nullOr types.str;
default = if cfg.database.type == "mysql" then "writefreely" else null;
defaultText = "writefreely";
description = lib.mdDoc "The database user to connect as.";
description = "The database user to connect as.";
};
passwordFile = mkOption {
type = types.nullOr types.path;
default = null;
description = lib.mdDoc "The file to load the database password from.";
description = "The file to load the database password from.";
};
host = mkOption {
type = types.str;
default = "localhost";
description = lib.mdDoc "The database host to connect to.";
description = "The database host to connect to.";
};
port = mkOption {
type = types.port;
default = 3306;
description = lib.mdDoc "The port used when connecting to the database host.";
description = "The port used when connecting to the database host.";
};
tls = mkOption {
type = types.bool;
default = false;
description =
lib.mdDoc "Whether or not TLS should be used for the database connection.";
description = "Whether or not TLS should be used for the database connection.";
};
migrate = mkOption {
type = types.bool;
default = true;
description =
lib.mdDoc "Whether or not to automatically run migrations on startup.";
description = "Whether or not to automatically run migrations on startup.";
};
createLocally = mkOption {
type = types.bool;
default = false;
description = lib.mdDoc ''
description = ''
When {option}`services.writefreely.database.type` is set to
`"mysql"`, this option will enable the MySQL service locally.
'';
};
};
oauth = {
enable = lib.mkEnableOption "Enable generic OAuth authentication";
clientId = mkOption {
type = types.str;
description = "The client ID associated with WriteFreely in the OAuth provider application.";
};
clientSecretFile = mkOption {
type = types.str;
description = "The file to load the OAuth client secret from.";
};
host = mkOption {
type = types.str;
description = "The base url of the OAuth provider application, including the protocol.";
example = "https://example.com";
};
displayName = mkOption {
type = types.str;
description = "The human-readable name of the OAuth service that appears on the login button, will appear as `Log in with [display_name]`.";
};
callbackProxy = mkOption {
type = types.str;
default = "";
description = "The url of an inbound proxy that sits in front of the default `/oauth/callback/generic` endpoint. Use if you want the OAuth callback to be somewhere other than that generic location. Default is blank.";
example = "https://example.com/whatever/path";
};
callbackProxyApi = mkOption {
type = types.str;
default = "";
description = "The url of an outbound proxy to send your OAuth requests through. Default is blank.";
example = "https://my-proxy.example.com";
};
tokenEndpoint = mkOption {
type = types.str;
description = "The API endpoint of the OAuth provider implementation to obtain an access token by presenting an authorization grant or refresh token. This is a fragment of a url, appended to host as described above.";
example = "/oauth/token";
};
inspectEndpoint = mkOption {
type = types.str;
description = "The API endpoint of the OAuth provider that returns basic user info given their authentication information. This is a fragment of a url, appended to host as described above.";
example = "/oauth/userinfo";
};
authEndpoint = mkOption {
type = types.str;
description = "The API endpoint of the OAuth provider that returns an authorization grant. This is a fragment of a url, appended to host as described above.";
example = "public";
};
scopes = mkOption {
type = types.listOf types.str;
default = [ "read_user" ];
description = "A scope or set of scopes required by some OAuth providers. This will usually be blank in this config file, and is set to `read_user` by default.";
};
allowDisconnect = mkOption {
type = types.bool;
default = false;
description = "Whether or not an individual user is allowed to disconnect this OAuth provider from their account.";
};
mapUserId = mkOption {
type = types.str;
default = "";
defaultText = "<none>";
description = "Use this User ID key in the provider's user info, instead of the default key (user_id).";
};
mapUsername = mkOption {
type = types.str;
default = "";
defaultText = "<none>";
description = "Use this Username key in the provider's user info, instead of the default key (username)";
};
mapDisplayName = mkOption {
type = types.str;
default = "";
defaultText = "<none>";
description = "Use this Display Name key in the provider's user info, instead of the default key (*none*)";
};
mapEmail = mkOption {
type = types.str;
default = "";
defaultText = "<none>";
description = "Use this Email key in the provider's user info, instead of the default key (email)";
};
};
admin = {
name = mkOption {
type = types.nullOr types.str;
description = lib.mdDoc "The name of the first admin user.";
description = "The name of the first admin user.";
default = null;
};
initialPasswordFile = mkOption {
type = types.path;
description = lib.mdDoc ''
description = ''
Path to a file containing the initial password for the admin user.
If not provided, the default password will be set to `nixos`.
'';
@ -292,14 +389,13 @@ in
enable = mkOption {
type = types.bool;
default = false;
description =
lib.mdDoc "Whether or not to enable and configure nginx as a proxy for WriteFreely.";
description = "Whether or not to enable and configure nginx as a proxy for WriteFreely.";
};
forceSSL = mkOption {
type = types.bool;
default = false;
description = lib.mdDoc "Whether or not to force the use of SSL.";
description = "Whether or not to force the use of SSL.";
};
};
@ -307,8 +403,7 @@ in
enable = mkOption {
type = types.bool;
default = false;
description =
lib.mdDoc "Whether or not to automatically fetch and configure SSL certs.";
description = "Whether or not to automatically fetch and configure SSL certs.";
};
};
};
@ -344,11 +439,12 @@ in
optionalAttrs (cfg.group == "writefreely") { writefreely = { }; };
};
systemd.tmpfiles.rules =
[ "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -" ];
systemd.tmpfiles.settings."10-writefreely".${cfg.stateDir}.d = {
inherit (cfg) user group;
mode = "0750";
};
systemd.services.writefreely = {
path = with pkgs; [ openssl ];
after = [ "network.target" ]
++ optional isSqlite "writefreely-sqlite-init.service"
++ optional isMysql "writefreely-mysql-init.service"
@ -393,29 +489,27 @@ in
cfg.admin.initialPasswordFile;
};
script =
let
migrateDatabase = optionalString cfg.database.migrate ''
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db migrate
'';
createAdmin = optionalString (cfg.admin.name != null) ''
if [[ $(query "SELECT COUNT(*) FROM users") == 0 ]]; then
admin_pass=$(head -n1 ${cfg.admin.initialPasswordFile})
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' --create-admin ${cfg.admin.name}:$admin_pass
fi
'';
in
withSqlite ''
if ! test -f '${settings.database.filename}'; then
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db init
fi
${migrateDatabase}
${createAdmin}
script = let
migrateDatabase = optionalString cfg.database.migrate ''
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db migrate
'';
createAdmin = optionalString (cfg.admin.name != null) ''
if [[ $(query "SELECT COUNT(*) FROM users") == 0 ]]; then
admin_pass=$(head -n1 ${cfg.admin.initialPasswordFile})
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' --create-admin ${cfg.admin.name}:$admin_pass
fi
'';
in withSqlite ''
if ! test -f '${settings.database.filename}'; then
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db init
fi
${migrateDatabase}
${createAdmin}
'';
};
systemd.services.writefreely-mysql-init = mkIf isMysql {
@ -432,38 +526,36 @@ in
cfg.admin.initialPasswordFile;
};
script =
let
updateUser = optionalString isMysqlLocal ''
# WriteFreely currently *requires* a password for authentication, so we
# need to update the user in MySQL accordingly. By default MySQL users
# authenticate with auth_socket or unix_socket.
# See: https://github.com/writefreely/writefreely/issues/568
${config.services.mysql.package}/bin/mysql --skip-column-names --execute "ALTER USER '${cfg.database.user}'@'localhost' IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD('$db_pass'); FLUSH PRIVILEGES;"
'';
migrateDatabase = optionalString cfg.database.migrate ''
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db migrate
'';
createAdmin = optionalString (cfg.admin.name != null) ''
if [[ $(query 'SELECT COUNT(*) FROM users') == 0 ]]; then
admin_pass=$(head -n1 ${cfg.admin.initialPasswordFile})
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' --create-admin ${cfg.admin.name}:$admin_pass
fi
'';
in
withMysql ''
${updateUser}
if [[ $(query "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '${cfg.database.name}'") == 0 ]]; then
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db init
fi
${migrateDatabase}
${createAdmin}
script = let
updateUser = optionalString isMysqlLocal ''
# WriteFreely currently *requires* a password for authentication, so we
# need to update the user in MySQL accordingly. By default MySQL users
# authenticate with auth_socket or unix_socket.
# See: https://github.com/writefreely/writefreely/issues/568
${config.services.mysql.package}/bin/mysql --skip-column-names --execute "ALTER USER '${cfg.database.user}'@'localhost' IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD('$db_pass'); FLUSH PRIVILEGES;"
'';
migrateDatabase = optionalString cfg.database.migrate ''
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db migrate
'';
createAdmin = optionalString (cfg.admin.name != null) ''
if [[ $(query 'SELECT COUNT(*) FROM users') == 0 ]]; then
admin_pass=$(head -n1 ${cfg.admin.initialPasswordFile})
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' --create-admin ${cfg.admin.name}:$admin_pass
fi
'';
in withMysql ''
${updateUser}
if [[ $(query "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '${cfg.database.name}'") == 0 ]]; then
${cfg.package}/bin/writefreely -c '${cfg.stateDir}/config.ini' db init
fi
${migrateDatabase}
${createAdmin}
'';
};
services.mysql = mkIf isMysqlLocal {
@ -497,4 +589,3 @@ in
};
};
}

View file

@ -12,7 +12,6 @@
# Fonts
../modules/personal/fonts
# Some PAM stuff
../modules/services/pam/gnome-keyring.nix
../modules/services/swaylock.nix
];
# Use the latest kernel
@ -116,9 +115,6 @@
pciutils
];
# Gnome-keyring is useful
services.gnome.gnome-keyring.enable = true;
## Environment variables
environment.variables = {
# Input method overrides
@ -145,7 +141,6 @@
# };
# List services that you want to enable:
nki.services.pam.enableGnomeKeyring = true;
services.input-remapper.enable = true;
services.swaylock.enable = true;

View file

@ -36,6 +36,4 @@
[{ device = "/dev/disk/by-uuid/2694d189-2ff6-4719-a449-367c52ed3ad6"; }];
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
hardware.opengl.enable = true;
}

View file

@ -15,7 +15,24 @@
../modules/services/edns
];
services.xserver.desktopManager.plasma5.enable = true;
# Secrets
common.linux.sops.enable = true;
common.linux.sops.file = ./secrets.yaml;
# Build farm
sops.secrets."nix-build-farm/private-key" = { mode = "0400"; };
services.nix-build-farm.hostname = "yoga";
services.nix-build-farm.privateKeyFile = config.sops.secrets."nix-build-farm/private-key".path;
## tinc
sops.secrets."tinc-private-key" = { };
services.my-tinc = {
enable = true;
hostName = "yoga";
ed25519PrivateKey = config.sops.secrets."tinc-private-key".path;
};
services.desktopManager.plasma6.enable = true;
# Power Management
services.upower = {
@ -85,6 +102,11 @@
};
};
# Enable fingerprint auth for some stuff
security.pam.services.sudo.fprintAuth = true;
security.pam.services.swaylock.fprintAuth = true;
security.pam.services.login.fprintAuth = true;
# Secrets
# sops.defaultSopsFile = ./secrets.yaml;
# sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];

View file

@ -13,6 +13,11 @@
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
boot.kernelParams = [
# Hibernation
"resume=UUID=b32d27bf-9df6-43c1-8b93-c0693811bf5b"
"resume_offset=9731998" # btrfs inspect-internal map-swapfile -r /var/swapfile
];
fileSystems."/" =
{
@ -41,6 +46,9 @@
"mtk_t7xx"
];
# Fingerprint
services.fprintd.enable = true;
hardware.sensor.iio.enable = true; # Orientaion and ambient light sensors
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking

32
nki-yoga-g8/secrets.yaml Normal file
View file

@ -0,0 +1,32 @@
tinc-private-key: ENC[AES256_GCM,data:lzmisexQPfRlIMGqbmb+uqGtOPceQ3CJGlVOeOC6nbP/IDwkufSWtxugYmUwi9IJKwO0mldijiKWuG3p9005H++8567hhPy/bU7fA4vyVC+3UVGW6l0mE+yKQXTyI7kzxkXMCK5a4Q4rUJj544vU6pt75/mytfg+Cox2woGZAHZvJ/pRuHDe2t3R6w3EYYTu6x1w5azGnFvCOVdR6XPsGJA2p3oRnEpz64L7KD2QOdtm0YsfMnorH9FbvkZgNr927VbRnBRJ1QM=,iv:4K4w6ruQxtRGjmFnWszlXZKp36TuTTnrB0sDEE/tmrM=,tag:NBP897Sw84bvZTvo/+fVfA==,type:str]
nix-build-farm:
private-key: ENC[AES256_GCM,data:etqFl2T2atN2djxqktFRtrTGqsC61A+ZUd2yS0PLm5KPO2s2/k6XqQGac9rUWP86C1YGpTJhUMzYuOPGW4yNc0YmoeHVslxBR7nX8pubXabZNdB2YMm/yAgsdeeflo4slbxJ6+00eH0iCrtWcHtWbZafHnxojborZABOvCsODdx/ahJ4J9aHqf22cAqe9iJY3L0TgE+iazKS8OO+C/PTaQiV02NZjP8GajRMXzPVoYT7wz3u0t0q0m/t8FkhMIDl9QKL+kFUDeLEGoCBzR57JXLZiW1gJsRxbkP8hVIB3s4TQnhasxqQQlCJuqBSNFl/cGdBm/ADm/yi78VHQG7rUxUrFVDL4Aoidjp6GyoojLIEpdQjtlvC7RCLNpTibV6B71EB3obpjMmmIwfoDLT4jEWhXNx3b8DnMoa0Qh4ba+HBJf+XKA93B0qOJWwJzj4qH9uqBK3xPOGTkqQMmd9M1HYrStTcI/JUX0WvEMwk8xI8MZN/TsLij4w5i6NCwSqa8Dn2lyLK0BGp5C8RT8R4k6U2ieyY6lmxsGIe,iv:703rM/FQz65upd1JWTHNsjAXh2BeoknkALShKuHUsis=,tag:yAB6KJqpm1mOFT5GzKRPBw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1vhjhmxura35apu5zdwg5ur5r40xay45ld9szh07dy0ph9chgsu7shfm4h9
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBseVN3ODV1YkZnNms0Y09l
dUFBK1EyOTEydWg5KzAwcjZVSG8yYlRDWlhRCklLS2ZJNlBvSlEyOGF2ZFg2UGVW
UC9LN0hxdmtGN3JlOWJaTU5hbGwvc2MKLS0tIGM1NGZxd1NoTXNacEJqMVlsbTdi
MytuNUNydmJYWFYyQk9DaHVuVk85cjAKScucMPO8pyMlSxFw09NqzqVmDYVEh5xT
4fSTAsMwIiuOyV7jvHYORxKWNMLr5t6fnj8+OFq5qUc//jNWf9pVuA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1axvjllyv2gutngwmp3pvp4xtq2gqneldaq2c4nrzmaye0uwmk9lqsealdv
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYNXp6MWZGb2dGdW1ML2xq
ZWMvSVdWalQ5Z2NzTWd3Z1AweXlXZnRwUWtRCkY1VFhPS0NtbFZKU0VCMlAvSmhG
N2NmdWxTUEpMb05Ld3p6MzhhRkdBc3cKLS0tIGQ0TmFxdk1GV205azRzZ0hUWitj
eitNc1E2SzY5bkUxNWtNczRsWWJaU2MKUIu9GT7zu0MvvnXxiQfLW9pQcxFKOwPm
VRU2k3XQkYjSDZX29DxrOzaPS/L3OYNyBYMyOW8GyMa2V12lMH6lPQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-08-16T14:17:07Z"
mac: ENC[AES256_GCM,data:qrMyVDLhtK4URqrHFBx+08PMrFyfib4iH0y7iAeVB/oFGazjm3O5MeS9fNYJeONghuelux69nh2FRfSJHG/moEBcWlL68R4xbCb4he528P+n7mQnR54BNFJdT2oOra4bqO9n/4m2UA8jmA0veoqSrZUVjnmjftqOedjnRESY1L8=,iv:jql79ItwPcJg/nnbsUywOzWz/UJy0ZpY04pvEF290c4=,tag:XKrToym2dXdippnivoK1/Q==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,101 +1,141 @@
{ nixpkgs, nixpkgs-unstable, nur, ... }@inputs:
{ nixpkgs, nixpkgs-unstable, ... }@inputs:
let
overlay-unstable = final: prev: {
stable = import nixpkgs { config.allowUnfree = true; system = prev.system; };
unstable = import nixpkgs-unstable { config.allowUnfree = true; system = prev.system; };
x86 = import nixpkgs-unstable { system = prev.system; config.allowUnsupportedSystem = true; };
};
overlay-needs-unstable = final: prev: {
# override some packages that needs unstable that cannot be changed in the setup.
nix-direnv = prev.unstable.nix-direnv;
# Typst updates really quickly.
typst = final.unstable.typst;
typst-lsp = final.unstable.typst-lsp;
# Sublime-music has a bug with playlists in 0.11.x
sublime-music =
if builtins.compareVersions prev.sublime-music.version "0.12" < 0
then final.unstable.sublime-music
else prev.sublime-music;
# New stuff in Kanshi 1.4.0
kanshi =
if builtins.compareVersions prev.kanshi.version "1.4.0" < 0
then final.callPackage final.unstable.kanshi.override { }
else prev.kanshi;
# Until 0.35 is in
kitty = final.unstable.kitty;
};
overlay-imported = final: prev: {
rnix-lsp = inputs.rnix-lsp.defaultPackage."${final.system}";
sway = prev.sway.override { sway-unwrapped = final.swayfx-unwrapped; };
deploy-rs = inputs.deploy-rs.packages.default;
dtth-phanpy = inputs.dtth-phanpy.packages.${final.system}.default;
matrix-conduit = inputs.conduit.packages.${final.system}.default;
exa = inputs.eza.packages.${final.system}.default.overrideAttrs (attrs: {
postInstall = attrs.postInstall + ''
ln -sv $out/bin/eza $out/bin/exa
'';
});
# A list of source-style inputs.
sources = final.lib.attrsets.filterAttrs (name: f: !(builtins.hasAttr "outputs" f)) inputs;
};
overlay-versioning = final: prev: {
input-remapper =
prev.input-remapper.overrideAttrs (oldAttrs: rec {
version = "2.0.0";
name = "input-remapper-${version}";
src = final.fetchFromGitHub {
owner = "sezanzeb";
repo = "input-remapper";
rev = "${version}";
sha256 = "sha256-yQRUhezzI/rz7A+s5O7NGP8DjPzzXA80gIAhhV7mc3w=";
};
gotosocial = prev.gotosocial.overrideAttrs (attrs: rec {
version = "0.17.1";
ldflags = [
"-s"
"-w"
"-X main.Version=${version}"
];
doCheck = false;
web-assets = final.fetchurl {
url = "https://github.com/superseriousbusiness/gotosocial/releases/download/v${version}/gotosocial_${version}_web-assets.tar.gz";
hash = "sha256-rGntLlIbgfCtdqpD7tnvAY8qwF+BpYbQWfAGMhdOTgY=";
};
src = final.fetchFromGitHub {
owner = "superseriousbusiness";
repo = "gotosocial";
rev = "v${version}";
hash = "sha256-oWWsCs9jgd244yzWhgLkuHp7kY0BQ8+Ay6KpuBVG+U8=";
};
postInstall = ''
tar xf ${web-assets}
mkdir -p $out/share/gotosocial
mv web $out/share/gotosocial/
'';
});
input-remapper = final.unstable.input-remapper;
kakoune-unwrapped =
prev.kakoune-unwrapped.overrideAttrs (attrs: {
version = "r${builtins.substring 0 6 inputs.kakoune.rev}";
src = inputs.kakoune;
patches = [
# patches in the original package was already applied
];
});
thunderbird = final.wrapThunderbird final.thunderbirdPackages.thunderbird-115 { };
swayfx-unwrapped = prev.swayfx-unwrapped.overrideAttrs (attrs: {
patches = (attrs.patches or [ ]) ++ [
(final.fetchurl {
url = "https://patch-diff.githubusercontent.com/raw/WillPower3309/swayfx/pull/315.patch";
hash = "sha256-zamOLHUjlzRs8PytPTAzEsdzgVtK+HVziHgrhwPcB+E=";
})
];
});
librewolf = (prev.librewolf.override {
nativeMessagingHosts = with final; [ kdePackages.plasma-browser-integration ];
});
# Add desktop file to premid
premid = final.symlinkJoin {
name = prev.premid.name;
paths = [
prev.premid
(final.makeDesktopItem {
name = prev.premid.name;
desktopName = "PreMID";
exec = "${final.lib.getExe prev.premid} --no-sandbox %U";
icon = "premid";
})
];
};
# https://github.com/NixOS/nixpkgs/issues/334822
vulkan-validation-layers = prev.vulkan-validation-layers.overrideAttrs (attrs: {
buildInputs = attrs.buildInputs ++ [
final.spirv-tools
];
});
};
overlay-libs = final: prev: {
libs.crane = inputs.crane.lib.${prev.system};
libs.crane = inputs.crane.mkLib final;
};
overlay-packages = final: prev: {
gotosocial-bin = final.callPackage ./packages/x86_64-linux/gotosocial-bin.nix { };
kak-tree-sitter = final.callPackage ./packages/common/kak-tree-sitter.nix { rustPlatform = final.unstable.rustPlatform; };
kak-lsp =
let
src = inputs.kak-lsp;
cargoArtifacts = final.libs.crane.buildDepsOnly { inherit src; };
in
final.libs.crane.buildPackage {
inherit src cargoArtifacts;
buildInputs = (with final;
lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ Security SystemConfiguration CoreServices ])
) ++ (with final; [ libiconv ]);
};
};
overlay-aarch64-linux = final: prev:
let
optionalOverride = pkg: alt:
if prev.stdenv.isLinux && prev.stdenv.isAarch64 then alt else pkg;
in
{
# See https://github.com/sharkdp/fd/issues/1085
fd = optionalOverride prev.fd (prev.fd.overrideAttrs (attrs: {
preBuild = ''
export JEMALLOC_SYS_WITH_LG_PAGE=16
'';
}));
# See https://www.reddit.com/r/AsahiLinux/comments/zqejue/kitty_not_working_with_mesaasahiedge/
kitty = optionalOverride prev.kitty (final.writeShellApplication {
name = "kitty";
runtimeInputs = [ ];
text = ''
MESA_GL_VERSION_OVERRIDE=3.3 MESA_GLSL_VERSION_OVERRIDE=330 ${prev.kitty}/bin/kitty "$@"
'';
});
# Zotero does not have their own aarch64-linux build
zotero = optionalOverride prev.zotero (final.callPackage ./packages/aarch64-linux/zotero.nix { });
# Typora for aarch64-linux only
typora = optionalOverride
(builtins.abort "no support for non-aarch64-linux")
(final.callPackage ./packages/aarch64-linux/typora.nix { });
};
overlay-asahi = inputs.nixos-m1.overlays.default;
overlay-rust-is-dumb = final: prev: {
# Use stable delta compiled with old Rust version
delta = final.stable.delta;
deepfilternet = final.stable.deepfilternet;
harmonia = final.callPackage
(import
(builtins.fetchurl {
url = "https://raw.githubusercontent.com/Mic92/nixpkgs/63f91202f5cd071187ede5e5ffc56003cb442876/pkgs/by-name/ha/harmonia/package.nix";
sha256 = "1mz211c0bxn116ix0j5xx4wlglpbkfg7d3npw1z8hg9gc0vbj2xb";
}))
{ };
};
in
[
# inputs.swayfx.inputs.scenefx.overlays.override
# inputs.swayfx.overlays.override
inputs.mpd-mpris.overlays.default
inputs.rust-overlay.overlays.default
inputs.youmubot.overlays.default
(import ./overlays/openrazer)
overlay-unstable
overlay-needs-unstable
@ -103,16 +143,10 @@ in
overlay-imported
overlay-versioning
overlay-libs
overlay-asahi
overlay-aarch64-linux
nur.overlay
overlay-rust-is-dumb
(import ./packages/common)
inputs.mpd-mpris.overlays.default
inputs.swayfx.overlays.default
inputs.youmubot.overlays.default
# Bug fixes
] # we assign the overlay created before to the overlays of nixpkgs.

View file

@ -1,20 +1,41 @@
{ lib, rustPlatform, fetchFromGitHub, symlinkJoin, clang, git, ... }:
{ lib, rustPlatform, fetchFromSourcehut, symlinkJoin, clang, git, writeText, ... }:
let
src = fetchFromGitHub {
owner = "phaazon";
src = fetchFromSourcehut {
owner = "~hadronized";
repo = "kak-tree-sitter";
rev = "3567f648bbf6a5d556c43bde5433dff45eabd693";
hash = "sha256-xr7CtOfMO4nRu2MOIQX3jR0wsKGsjYiF/TGXSAsidM4=";
rev = "kak-tree-sitter-v1.1.2";
hash = "sha256-wBWfSyR8LGtug/mCD0bJ4lbdN3trIA/03AnCxZoEOSA=";
};
kak-tree-sitter = rustPlatform.buildRustPackage rec {
kak-tree-sitter = rustPlatform.buildRustPackage {
inherit src;
pname = "kak-tree-sitter";
version = "0.4.6";
cargoHash = "sha256-6HJxJTr4P1/6Yy3/dtfiaCFoHA4iKvmuwg51jTYU2eo=";
version = "1.1.2";
cargoHash = "sha256-OQPUWqJAts8DbFNSsC/CmMCbuZ9TVxRTR05O7oiodKI=";
cargoBuildOptions = [ "--package" "kak-tree-sitter" "--package" "ktsctl" ];
nativeBuildInputs = [ clang git ];
patches = [
# Allow absolute-path style repos
(writeText "resources.patch" ''
diff --git a/ktsctl/src/resources.rs b/ktsctl/src/resources.rs
index f1da3ff..ac89345 100644
--- a/ktsctl/src/resources.rs
+++ b/ktsctl/src/resources.rs
@@ -48,7 +48,8 @@ impl Resources {
url
.trim_start_matches("http")
.trim_start_matches('s')
- .trim_start_matches("://"),
+ .trim_start_matches(":/")
+ .trim_start_matches("/"),
);
self.runtime_dir.join("sources").join(url_dir)
'')
];
};
in
kak-tree-sitter

View file

@ -1,31 +0,0 @@
{ stdenv, lib, autoPatchelfHook }:
with lib;
let
in
stdenv.mkDerivation rec {
pname = "gotosocial-bin";
version = "0.11.1";
src = builtins.fetchurl {
url = "https://github.com/superseriousbusiness/gotosocial/releases/download/v${version}/gotosocial_${version}_linux_amd64.tar.gz";
sha256 = "sha256:01ylmsvlq86nf2hsj8mcgnhpgc7g0vyqs5sx3g2j79a4835sai2f";
# sha256 = fakeSha256;
};
nativeBuildInputs = [ autoPatchelfHook ];
sourceRoot = ".";
installPhase = ''
install -m755 -D gotosocial $out/bin/gotosocial
mkdir $out/share
cp -r web $out/share/web
cp -r example $out/share/example
'';
meta = with lib; {
homepage = "https://docs.gotosocial.org";
description = "GoToSocial network";
platforms = platforms.linux;
};
}