Compare commits

..

399 Commits

Author SHA1 Message Date
1da87ebdb8 chore(server): drop grafana 2026-02-24 16:27:28 +08:00
24d72349b2 chore(zen): xdg migration 2026-02-20 17:16:44 +08:00
5630df0be7 chore(hmcl): remove hack 2026-02-20 17:16:44 +08:00
abeca5f52e chore: update flake.lock; update noctalia-shell 2026-02-20 17:12:14 +08:00
211b4bef15 feat(cli): add dust & dysk 2026-02-20 16:18:44 +08:00
3417ee5618 feat: update niri config 2026-02-20 16:18:25 +08:00
a4ed789ae9 feat: update neovim config 2026-02-20 16:18:00 +08:00
2f6c5feda7 fix: rename patched electron packages 2026-02-20 16:17:15 +08:00
e4087c9da8 feat(nvim): add taplo lsp (TOML) 2026-02-15 19:50:29 +08:00
291563bba3 feat(cli/misc): add jq 2026-02-15 19:50:12 +08:00
993b77d5d0 chore: update secrets 2026-02-13 11:37:26 +08:00
8c635dc3ad chore: update flack.lock 2026-02-13 11:37:26 +08:00
cffae80d70 chore(efl): update tuwunel 2026-02-13 11:37:26 +08:00
491a1ebb40 feat(browser): default to zen 2026-02-12 09:05:54 +08:00
25533605d3 feat(niri): update config 2026-02-12 09:05:45 +08:00
502920af58 feat(nvim): add vscode-json-languageserver 2026-02-11 12:34:13 +08:00
149397f16a chore: update secrets 2026-02-11 12:34:01 +08:00
3435e99cb1 chore(nvim): remove unused files 2026-02-08 22:50:32 +08:00
9faf6cdfe4 feat(nvim/blink.cmp): always use lua implementation 2026-02-08 01:52:43 +08:00
3d116fe3a7 chore: fmt 2026-02-08 01:51:27 +08:00
97761a3af5 feat(nvim/indent-blankline): use rainbow-delimiters integration 2026-02-08 01:40:38 +08:00
92ee55e82a feat(niri): noctalia windows keybind 2026-02-08 01:40:17 +08:00
2d324de58a feat(starship): tmux & shpool indicator 2026-02-08 01:39:54 +08:00
42fbf5cee6 feat(nvim): use mini.nvim & neo-tree 2026-02-07 12:09:21 +08:00
a1d873cc30 feat(nvim): use blink.cmp 2026-02-07 11:03:28 +08:00
e327d6acaf chore: use easytier 2.4.5 2026-02-06 22:19:47 +08:00
a9149d86c7 chore(pkgs): drop jj-starship 2026-02-06 21:37:23 +08:00
bdddabcd52 feat: shpool 2026-02-06 21:37:14 +08:00
b2860d63c5 chore: update flake.lock; update noctalia-shell 2026-02-06 16:23:43 +08:00
dc15d79266 feat: use ouch 2026-02-06 16:23:43 +08:00
b6992f554a chore: update secrets 2026-01-30 21:43:28 +08:00
06c0a24d98 fix: update environment for noctalia-shell 2026-01-30 21:35:16 +08:00
9aa25642ee fmt: disable typos 2026-01-30 21:35:16 +08:00
b6a6f966dc chore: update flake.lock; update noctalia-shell 2026-01-30 21:35:16 +08:00
754caf00d4 feat: shotwell -> loupe 2026-01-30 21:35:16 +08:00
ce8d76886a chore: update secrets 2026-01-23 20:32:48 +08:00
b3c173f0fa chore: update flake.lock; update noctalia-shell 2026-01-23 18:45:46 +08:00
d6850b86dc chore: update lazy-lock.json 2026-01-23 17:36:29 +08:00
9e38cb0712 feat: drop sched-ext 2026-01-17 21:44:51 +08:00
75b4d87dfa feat: drop playerctl 2026-01-17 14:41:31 +08:00
35358cf01c feat: system76-scheduler 2026-01-17 13:33:15 +08:00
5a1880587f chore: update lazy-lock.json 2026-01-16 20:59:43 +08:00
9c22723970 chore: update flake.lock 2026-01-16 20:26:33 +08:00
cb3578bb0d feat(jj): add jj tug 2026-01-16 20:26:15 +08:00
3313dfc89b feat(nvim): biome 2026-01-10 21:35:19 +08:00
29734f85ba fix: remove noctalia-shell entry from spawn-at-startup 2026-01-10 10:17:07 +08:00
afe06213de chore(nvim): update lazy-lock.json 2026-01-09 23:54:34 +08:00
69d6588c30 feat: add splayer 2026-01-09 23:54:23 +08:00
aee0fb44d5 feat(server): use xanmod_stable and zfs_unstable 2026-01-09 15:49:33 +08:00
602f599823 chore: update flake.lock
* updated noctalia-shell to v3.8.2
* removed television fish integration workaround
* removed `~/.config/fish/fish_variables` entry in my.persist.homeFiles
  since [fish v4.3.0](https://github.com/fish-shell/fish-shell/releases/tag/4.3.0)
  no longer sets universal variables by default
2026-01-09 15:07:37 +08:00
df0a21913e feat: tidy shell config 2026-01-03 10:09:43 +08:00
a56e9bdaf2 chore(nvim): update lazy-lock.json 2026-01-01 17:41:40 +08:00
e574a70020 feat(nvim): enable inlay hints for rust-analyzer 2026-01-01 15:39:04 +08:00
c6a3fde1bd feat(nix): warn-dirty = false 2026-01-01 11:37:41 +08:00
b3cd3fe209 feat(nvim): tidy old config; track lazy-lock.json 2025-12-31 22:06:51 +08:00
ad2aca84f0 chore: tidy Justfile 2025-12-31 22:04:21 +08:00
a07bcd9bab chore: update flake.lock; update noctalia-shell 2025-12-31 22:03:53 +08:00
7eb32cfabc feat: impure symlink 2025-12-28 11:07:50 +08:00
f9308dda9e refactor: config/hosts => hosts 2025-12-28 09:22:15 +08:00
99aea69128 chore(server): remove unnecessary pkgs.stable usage 2025-12-27 16:46:59 +08:00
d0cffe4f1c refactor: keys & emails 2025-12-27 16:46:24 +08:00
b8597104b3 fmt: tidy 2025-12-27 16:28:39 +08:00
3bd682e800 fix: television fish integration 2025-12-27 16:28:23 +08:00
296f250eba feat(nixd): suppress sema-primop-overridden 2025-12-27 16:28:00 +08:00
4ab322f08d refactor: pkgs 2025-12-27 16:27:30 +08:00
e112f5f21d chore: update flake.lock; update noctalia-shell 2025-12-27 16:25:42 +08:00
5bfd7bf857 chore(flake.nix): treefmt.inputs.nixpkgs.follows = "nixpkgs" 2025-12-21 15:29:41 +08:00
7a8e7ca9d7 feat(pkgs): jj-starship 2025-12-21 15:29:32 +08:00
91c539ad99 feat(tmux): set terminal-features 2025-12-21 12:58:36 +08:00
4c63836d35 fix(fish): async starship 2025-12-21 12:27:14 +08:00
a2eaa6f72d chore: fmt 2025-12-21 11:03:54 +08:00
c9edeca311 feat(fish): persist fish_variables 2025-12-21 10:58:42 +08:00
6482506cc3 fix(nvim): nixd nixpkgs 2025-12-21 10:58:24 +08:00
7f250e19ef fix: build 2025-12-21 10:51:54 +08:00
5feb543129 fix: stylix warning 2025-12-20 23:21:46 +08:00
454ad5885d feat: massive refactor 2025-12-20 23:05:28 +08:00
f4c1b313ce fix(server): nixpkgs config; migrate to new frp module 2025-12-20 20:45:33 +08:00
4509f9edf5 feat(niri): update config 2025-12-20 20:10:46 +08:00
bc197eb3ca refactor: massive refactor using flake-parts; use typos-cli and
keep-sorted
2025-12-20 18:12:03 +08:00
d5f027f586 feat: upgrade noctalia-shell 2025-12-19 23:41:19 +08:00
3d6620a308 chore: update flake.lock 2025-12-19 19:27:34 +08:00
3196ebd920 feat(niri): update config 2025-12-19 19:27:34 +08:00
9c920b2cdf feat(server): sshwifty 2025-12-16 18:26:17 +08:00
7b705fad80 chore: remove redundant default.nix 2025-12-14 13:58:21 +08:00
f3f00c14ad chore: update secrets 2025-12-14 10:43:32 +08:00
9ae37ea439 feat(fish): some changes 2025-12-14 10:43:17 +08:00
99103ff9d2 feat(niri): change column width 2025-12-14 10:42:58 +08:00
4c74679f85 build: add offline 2025-12-14 10:40:44 +08:00
90b85963cd feat(sops-nix): use restartUnits 2025-12-14 10:40:11 +08:00
010789965a chore: fmt 2025-12-13 17:00:21 +08:00
5988a98a09 feat: upgrade noctalia-shell 2025-12-13 16:59:08 +08:00
814511c939 feat(server): coding.langs.js.enable = true 2025-12-12 22:32:33 +08:00
b96a93b1bf fix: sudoedit -> doasedit 2025-12-12 22:32:14 +08:00
b92ada78e5 feat(server): rsshub 2025-12-12 22:31:51 +08:00
eb5ca52004 feat: drop config/hosts/${host}/default.nix 2025-12-12 22:31:27 +08:00
7952d72048 feat: add my-templates 2025-12-12 22:30:48 +08:00
cb5c3eff2e feat: drop chaotic-nyx; drop proton-ge-custom; linux-cachyos -> linux-xanmod
R.I.P. chaotic-nyx 😢
2025-12-12 19:59:50 +08:00
17c5344666 build: Makefile 2025-12-07 16:34:31 +08:00
8d7a4aed01 feat(direnv): configure 2025-12-07 12:46:43 +08:00
475837cd66 feat: use angrr (gc roots cleaner) 2025-12-07 12:45:49 +08:00
4f043b6ad1 chore: update secrets 2025-12-07 12:07:39 +08:00
5d3fc65be5 feat: set fish as user shell 2025-12-07 12:06:57 +08:00
3a82f9b652 feat(noctalia): enable OSD for all available events 2025-12-07 10:55:12 +08:00
cbdf26d69f feat: update nixpkgs-stable to 25.11 2025-12-07 00:17:32 +08:00
80792c399c feat(ayugram): use latest 2025-12-07 00:16:26 +08:00
b1546b5ee8 feat: upgrade noctalia-shell 2025-12-06 13:19:23 +08:00
52261371c0 feat(fish): yank to system clipboard 2025-12-06 02:40:42 +08:00
ab6dadd113 feat(shell): migrate to fish 2025-12-05 23:52:56 +08:00
837f865b4f feat: systemd-boot.configurationLimit = 10 2025-12-05 19:06:58 +08:00
e3b5a1d6c3 chore: update flake.lock 2025-12-05 19:06:36 +08:00
d161fd3e87 feat(nix): set download-buffer-size to 512MiB 2025-11-30 10:41:50 +08:00
2118c69dd8 feat(server/coder): use services.coder 2025-11-29 15:18:03 +08:00
c7cf3336a0 chore(imxyy-nix): use DP-1 and DP-2 2025-11-29 15:16:28 +08:00
15ac780c9d feat(langs/c): use clang 2025-11-29 15:16:14 +08:00
3cb98cfeb0 chore: update flake.lock 2025-11-29 15:09:09 +08:00
4ae4f3bb2b feat(nvim): typst; tidy language specific configurations 2025-11-23 14:49:31 +08:00
9273df1ab8 fmt(.editorconfig): insert_final_newline = true 2025-11-22 22:56:50 +08:00
374a3ef071 feat(btreset): python -> bash 2025-11-22 22:48:48 +08:00
0983d5b058 chore: update secrets 2025-11-22 22:20:06 +08:00
e8f025b9c5 chore: drop open-webui 2025-11-22 17:50:24 +08:00
4144c14868 chore: fmt 2025-11-22 17:35:42 +08:00
1417822aa6 feat: add garnix cache 2025-11-22 17:35:24 +08:00
3ea322dd0f chore: update flake.lock 2025-11-22 17:35:10 +08:00
86c85676ea chore: update secrets 2025-11-16 14:23:58 +08:00
b302abb724 feat(distrobox): add nvim 2025-11-15 19:49:28 +08:00
4817576834 chore: fmt 2025-11-15 19:49:13 +08:00
0683ced027 feat: upgrade noctalia-shell 2025-11-15 19:48:55 +08:00
cec8f7897a chore: update secrets 2025-11-15 19:48:22 +08:00
78a062432f chore: update secrets 2025-11-15 19:47:47 +08:00
4f77ac9385 chore: drop mpd 2025-11-15 15:43:43 +08:00
73e490f523 feat: upgrade go-musicfox 2025-11-15 15:42:54 +08:00
12c381da5f fmt: trailing LF 2025-11-15 15:08:20 +08:00
23a24820c5 chore: update secrets 2025-11-15 14:55:38 +08:00
d6e0b0ef96 feat(server/nextcloud): upgrade to 32 2025-11-15 14:55:38 +08:00
ef913abe9e feat: secure frp server address 2025-11-15 14:55:38 +08:00
4d0cd7b1e7 chore: update flake.lock; use treefmt 2025-11-15 14:54:08 +08:00
9482ba860f feat(imxyy-nix): use distrobox 2025-11-08 23:53:50 +08:00
44aca8ce69 feat(noctalia): update settings 2025-11-02 15:42:10 +08:00
792aaa20d5 fmt: LF at end of file 2025-11-02 15:41:15 +08:00
959956409d chore: update flake.lock; prepare for 25.11 migration 2025-11-01 21:05:31 +08:00
41969ab2e0 feat(noctalia): mm月dd日 -> mm/dd 2025-10-26 13:52:24 +08:00
e228fdc222 feat(style/gtk): use Adwaita Sans 2025-10-26 13:51:45 +08:00
6bc50deb6a refactor: font config 2025-10-26 13:44:36 +08:00
090677e101 feat(server): disable media related cli 2025-10-19 16:20:55 +08:00
8ae8e6f9b1 feat(server/nextcloud): drop nginx.recommendedHeaders 2025-10-19 16:20:15 +08:00
3acd90bbdd feat: update README.md 2025-10-18 22:16:59 +08:00
e9204bb2f5 feat(desktop): migrate to noctalia-shell, drop unused softwares 2025-10-18 22:16:33 +08:00
362d610f1d refactor(browser): set default browser 2025-10-18 22:15:39 +08:00
5a671c3ece feat(nvim): nvim-colorizer 2025-10-18 12:57:59 +08:00
f2111f7771 feat(noctalia): customize color theme 2025-10-18 12:57:07 +08:00
c71710867f feat(niri): use noctalia shell 2025-10-18 10:17:49 +08:00
465eb3c608 refactor(flake.nix): use nested flake input 2025-10-18 01:08:43 +08:00
9696d4f343 chore: update flake.lock 2025-10-18 01:04:48 +08:00
4218dbeb80 feat(langs/js): use pnpm 2025-10-17 19:52:40 +08:00
c167e3ac64 feat(cli): use fastfetch 2025-10-07 11:49:15 +08:00
f07598688f chore(nvim): tidy 2025-10-04 14:55:23 +08:00
e696472c5b feat(nvim): glance.nvim 2025-10-04 14:54:36 +08:00
dcfd134a4e feat(nvim): close nvim-tree when its the only window left 2025-10-04 14:53:46 +08:00
77d0a1c449 feat: add .lazy.lua to setup lazydev.nvim 2025-10-04 13:03:34 +08:00
7b1044214f feat: add .editorconfig 2025-10-04 13:03:24 +08:00
faba8a05e6 refactor: my.home -> my.hm for disambiguilty (e.g. my.home.home) 2025-10-03 22:17:36 +08:00
1eaee50e82 feat(nvim): enable exrc; drop unused file 2025-10-02 16:45:19 +08:00
763c55b68e chore: update secrets 2025-10-02 16:42:41 +08:00
95fc23da50 feat(server/minio): drop caddy reverse proxy 2025-10-02 16:42:10 +08:00
a6006d362d chore(server): drop headscale 2025-10-02 16:40:51 +08:00
57cc21a1cd feat(server/tuwunel): suppress_when_active 2025-10-02 16:40:24 +08:00
e78a3af90c feat(server): HF-plant 2025-10-02 16:28:07 +08:00
3652579508 chore: update flake.lock 2025-10-01 14:54:49 +08:00
1036d4ce0b feat: evince -> papers 2025-09-21 13:08:03 +08:00
354525129e chore: update flake.lock 2025-09-21 13:07:50 +08:00
7e9875ac38 fix: remove non-existent xmcl 2025-09-20 14:19:15 +08:00
a9089d81b1 fix(efl): tuwunel delegation 2025-09-20 14:16:05 +08:00
d61cd261e0 chore: update secrets 2025-09-14 11:11:46 +08:00
3f206e08c2 feat: init efl 😋 2025-09-14 11:11:27 +08:00
2677ed4594 fix(server/dns): loop 2025-09-14 11:10:11 +08:00
905274fe73 chore: update flake.lock 2025-09-14 11:09:26 +08:00
23b30d3a84 chore: update flake.lock 2025-09-05 19:40:00 +08:00
5bead3c20f chore: update secrets 2025-08-29 19:55:53 +08:00
dd2f880a3b feat: mautirx-telegram 2025-08-29 19:55:31 +08:00
1869ae86f1 refactor: custom packages 2025-08-29 13:01:46 +08:00
b7d6cd3dbf fix(waybar): incorrect mode config (dropping it has not effect) 2025-08-29 13:01:46 +08:00
900b66796b feat(niri): customize insert hint 2025-08-29 13:01:46 +08:00
44a479d6b4 fix(hmcl): wrap hmcl to fix config file persistence 2025-08-29 13:01:46 +08:00
b5dca35878 feat(server): drop unused web services 2025-08-29 13:01:46 +08:00
a1fa09008b feat(imxyy-nix): persist waydroid 2025-08-29 12:56:20 +08:00
375c9b59b9 feat(imxyy-nix): persist claude code 2025-08-29 12:55:58 +08:00
90f0b4aa63 fix(nvim): rust-analyzer config
It has been broken for thousands of years.
2025-08-26 21:52:08 +08:00
fba506e06d feat(imxyy-nix/keyd): use side button to replace right button
my mouse 😭
2025-08-24 21:50:28 +08:00
8b303fb0f0 feat(niri): prevent waybar black corners
ref: 05337ce855
2025-08-24 21:50:28 +08:00
49bbfe094a feat(niri): use gnome polkit agent 2025-08-24 21:50:28 +08:00
3c5c96d623 chore: update flake.lock; drop NUR 2025-08-24 21:50:28 +08:00
5a5fb9a426 feat: use nautilus instead of nemo 2025-08-24 21:50:28 +08:00
82ba9038ed feat(gtk/theme): use Adwaita 2025-08-24 21:50:28 +08:00
d22d597cf1 feat(nix): disable auto store optimisation to speed up input fetching 2025-08-24 21:50:28 +08:00
c61b1e8961 feat(nvim): prevent accidental <S-up> and <S-down> 2025-08-24 21:50:28 +08:00
475acb7fd1 feat: waydroid 2025-08-24 21:50:28 +08:00
3ef2f7da09 feat: fractal 2025-08-24 21:50:28 +08:00
fbc5a9ee8e feat(tuwunel): turn server 2025-08-17 00:35:00 +08:00
f46ad8a2f3 feat: revive minecraft server 😋 2025-08-17 00:02:32 +08:00
c14a3682ff fix(tuwunel): delegation 2025-08-17 00:02:01 +08:00
f4a0e2a862 fix: nextcloud mount 2025-08-16 23:13:23 +08:00
df589d6797 feat: update go-musicfox 2025-08-16 23:13:01 +08:00
1da80c49db fix(fcitx5/overlay): qq 2025-08-15 20:12:42 +08:00
8080d174ae chore: update flake.lock 2025-08-15 16:52:24 +08:00
0d39e2869b feat(wine): disable by default 2025-08-15 16:51:48 +08:00
953952f345 feat: disable minecraft server 😭 2025-08-15 16:51:23 +08:00
1f60272f14 feat: matrix-tuwunel 😋 2025-08-15 16:50:49 +08:00
e5474ffd29 feat(niri): maximize by default 2025-08-14 22:18:04 +08:00
dec6db7e8e feat: element-desktop 2025-08-14 21:19:47 +08:00
a966a7e81f feat(x16): moonlight 2025-08-14 21:19:34 +08:00
67b27c4079 chore: update flake.lock 2025-08-13 09:19:53 +08:00
e958163479 feat(nvim): move language servers to each language's .nix file 2025-08-13 09:18:49 +08:00
90cd4bdd84 feat(sddm): use cattpuccin 2025-08-12 12:50:46 +08:00
e1e3e96626 feat(niri): brightnessctl 2025-08-12 09:03:19 +08:00
16f11262ff feat(imxyy-nix-x16): persist gemini and claude 2025-08-12 09:02:50 +08:00
a2b63259ed feat(imxyy-nix-x16): power management 2025-08-12 09:02:03 +08:00
ab539b82ca fix(fcitx5/overlay): drop unecessary phases 2025-08-09 20:18:27 +08:00
05c2bc3627 fix(waybar): icon 2025-08-07 11:14:57 +08:00
464a162703 feat: rework fcitx5 overlay, avoid rebuild 2025-08-04 20:46:41 +08:00
8385671c4f chore: drop unused packages 2025-08-04 20:45:39 +08:00
433e26edaa feat: unfollow nixpkgs for niri, use binary cache; update flake.lock 2025-08-04 20:44:10 +08:00
c28d386c29 feat: persist gemini 2025-08-04 10:24:02 +08:00
a149d2a3df feat(cli): comma 2025-08-02 21:02:00 +08:00
ea02f5b023 chore: drop unused custom packages 2025-08-02 20:29:46 +08:00
bf904ec38a feat(fcitx5): update overlay 2025-08-02 18:25:02 +08:00
c419ac3a30 fix(nix): github token 2025-08-02 18:06:22 +08:00
244844242f feat(langs): java 2025-08-02 18:05:56 +08:00
f730d8d118 fix(zsh): use xdg.configHome in zdotdir 2025-08-02 18:05:09 +08:00
590343e5eb feat: update flake.lock; update sops-nix to use ssh key 2025-08-02 18:04:22 +08:00
5da17890cb feat(langs/rust): add ~/.cargo/bin to PATH 2025-07-30 22:34:51 +08:00
52692a4a47 feat(fcitx5): update overlay 2025-07-30 22:28:40 +08:00
f2cb379100 feat: prefer sjtug mirror over sjtu mirror due to stability 2025-07-30 22:28:23 +08:00
e6a2690baa feat: tidy 2025-07-27 22:11:59 +08:00
f642f9c9cc fix(server): qemu & virtio 2025-07-27 21:46:55 +08:00
7d08e1f5ef feat(audio): move to pipewire 2025-07-27 21:45:50 +08:00
3cb73506f1 chore: drop cava 2025-07-27 21:36:15 +08:00
4be7cd0c0f feat(btreset): use usbutils/usbreset 2025-07-27 20:51:58 +08:00
2d038b2ae2 feat(niri): disable auto scroll 2025-07-27 20:47:51 +08:00
dd8afc8954 refactor: overlay 2025-07-26 12:34:11 +08:00
e69600cc77 chore: update flake.lock 2025-07-26 12:33:07 +08:00
17ef457181 chore: drop unused softwares 2025-07-26 12:22:06 +08:00
a39b966a91 refactor: fcitx5 overlay 2025-07-26 12:19:59 +08:00
a0b044dbc9 feat(starship): speedup jj prompt 2025-07-24 21:48:43 +08:00
94764e7a5a feat: television (fuzzy finder) 2025-07-22 21:28:47 +08:00
fef786d317 feat(nix): github token 2025-07-22 21:28:27 +08:00
8ca0a6cc0f refactor: sops-nix 2025-07-22 21:21:41 +08:00
3263d72b59 feat(server): memos 2025-07-22 17:07:47 +08:00
1c7e5b9f05 feat(jj): set conflict-marker-style 2025-07-22 16:43:25 +08:00
1da34bf704 fix(headscale): RestartSec conflict 2025-07-22 16:43:25 +08:00
88107f9fe7 feat(server): authorize imxyy-nix-x16 2025-07-22 16:43:25 +08:00
5d1f622782 fix: immich 2025-07-22 16:42:43 +08:00
0ed99176ad chore: update flake.lock 2025-07-22 15:51:48 +08:00
4dddb0e803 chore(nvim): drop outdated config 2025-07-22 15:17:31 +08:00
4353f9da34 feat: qtct 2025-07-22 12:36:00 +08:00
66e772ce62 fix: imxyy-nix-x16 2025-07-18 23:57:21 +08:00
422259838b fix(imxyy-nix-server): NAS 2025-07-13 13:35:01 +08:00
390e75ce8e feat(imxyy-nix-x16/niri): scale 2025-07-13 13:34:44 +08:00
a3b627359b fix: systemd service restart 2025-07-13 13:31:48 +08:00
be75d12e9c chore(niri): update flake.lock 2025-07-13 13:17:18 +08:00
a63be876f7 chore: fmt 2025-07-13 13:11:23 +08:00
2b5a96bc20 chore: update secrets 2025-07-12 21:54:26 +08:00
02216bfa0c fix: imxyy-nix-x16 2025-07-12 21:54:05 +08:00
793dbac197 feat(imxyy-nix-x16): update secrets 2025-07-12 20:32:29 +08:00
c584091e60 feat: init imxyy-nix-x16 2025-07-12 19:52:42 +08:00
68b1765582 fix(tealdeer): auto update 2025-07-12 16:00:35 +08:00
8a169dbfa1 fix(open-webui): use stable 2025-07-11 20:43:58 +08:00
2c035ac47a fix: immich 2025-07-11 20:43:58 +08:00
5648ae6b31 feat: tealdeer (tldr) 2025-07-11 20:34:30 +08:00
c504274eca chore: drop cht.sh 2025-07-11 20:34:21 +08:00
bd192f0443 feat(imxyy-nix-server): immich 2025-07-11 18:30:02 +08:00
99e5362345 feat(jj): signing 2025-07-11 16:58:50 +08:00
35693c9782 feat(starship): use "jj root" to determine whether to show jj module 2025-07-11 15:40:59 +08:00
aba70d46a9 feat(starship): only show git status if not in a jj repo 2025-07-11 15:27:24 +08:00
be4de25d84 feat(zsh): starship prompt 2025-07-11 14:52:46 +08:00
2177549100 chore: update flake.lock 2025-07-11 14:52:35 +08:00
abdc2f5c6c feat(coding/langs): QML 2025-07-06 14:29:49 +08:00
99121f72c9 feat(style): use papirus icon 2025-07-06 14:29:34 +08:00
b460cb58ef refactor(pkgs): use haumea for automatic callPackage 2025-07-06 14:29:10 +08:00
32232d08db fix: add self back to wheel group 2025-07-05 11:25:38 +08:00
2d9c505ad7 feat(sing-box): use qjebbs/sing-box 2025-07-04 21:57:03 +08:00
667af5a5a6 refactor: overlay 2025-07-04 21:33:46 +08:00
e79ed0f643 feat(doas): add sudo wrapper 2025-07-04 21:32:35 +08:00
d0fcde133d feat: move to doas 2025-07-04 20:06:59 +08:00
b953e5b7ce chore: update flake.lock 2025-07-04 20:06:39 +08:00
c8f098f1a2 feat(sing-box): use PuerNya/sing-box/building for outbound_provider 2025-06-29 16:40:08 +08:00
e454e12d2f feat(kitty): do not use "-1" option 2025-06-29 15:16:30 +08:00
44a72b39e4 feat: use both sjtu mirrors 2025-06-29 15:16:30 +08:00
4af7226777 chore: update imxyy-nix password 2025-06-29 15:16:30 +08:00
28c59be2a7 feat(nvim): add leap.nvim 2025-06-29 15:16:30 +08:00
51b882f2c5 feat: add ~/.npm-global/bin to PATH 2025-06-29 15:16:30 +08:00
13b69ccc95 refactor: persist 2025-06-29 15:16:30 +08:00
be5fd3b9ff fix(wine): add to all.nix 2025-06-29 15:16:30 +08:00
20ddfb5ddd chore: drop trash and dooit 2025-06-29 15:16:30 +08:00
4d2949ab93 chore: drop cinny 2025-06-29 15:16:30 +08:00
e0faac096b feat: wechat 2025-06-29 15:16:30 +08:00
1c6708bad5 feat(wine): use bottles 2025-06-29 15:16:30 +08:00
a07742a206 feat(qq): use unstable 2025-06-29 15:16:30 +08:00
7bacc8ae06 feat: remote build for EFLKumo 2025-06-28 23:27:26 +08:00
f400aaf570 feat(tmux): manage by home-manager 2025-06-28 18:38:51 +08:00
dbd3195430 feat(imxyy-nix-server/virt): ignore unhandled MSR 2025-06-27 23:40:57 +08:00
d041f61c46 feat: update README.md 2025-06-27 23:22:24 +08:00
705f702535 feat: use nh (yet another nix helper) 2025-06-27 23:22:16 +08:00
8fe373eeb5 chore: drop useless github-cli-comp 2025-06-27 23:21:52 +08:00
64dd1077b6 feat: add jujutsu VCS 2025-06-27 23:21:29 +08:00
8fe95f071a chore: update flake.lock 2025-06-27 22:03:38 +08:00
bd21506f0d fix: do not mkForce substituters 2025-06-27 22:03:30 +08:00
c8c6a09684 feat(desktop): use NIXOS_OZONE_WL 2025-06-22 09:51:17 +08:00
0c679290c5 feat: zed-editor 2025-06-21 22:55:37 +08:00
4685f31aa1 feat(xwayland-satellite): use builtin fractional scaling 2025-06-21 22:55:20 +08:00
77b8578379 fix(niri): avoid double spawning xsettingsd 2025-06-21 13:03:46 +08:00
5bf4a22e8f feat(siyuan): v3.1.24 -> v.3.1.30 2025-06-21 11:38:35 +08:00
91257fbcf8 chore(matrix-synapse): use stable deu to the build failure of unstable 2025-06-21 11:36:42 +08:00
13cc8234e1 feat: move to umport for automatic module import 2025-06-21 11:30:35 +08:00
89aa6186f2 chore: remove unused nerd-fonts.jetbrains-mono 2025-06-21 10:42:11 +08:00
794593222c fix(niri): buggy clipboard in kitty (maybe?) 2025-06-21 10:37:24 +08:00
8c64e8e7b9 fix: emoji display 2025-06-21 10:36:55 +08:00
8348cd9a54 chore: update flake.lock 2025-06-20 21:55:51 +08:00
83772d34dd feat(niri): place-within-backdrop 2025-06-20 21:55:31 +08:00
5e5f2ed1bb chore(mpd): use stable due to the build failure of unstable 2025-06-20 21:55:03 +08:00
d7a3fc7a07 chore: drop waydroid 2025-06-20 21:53:34 +08:00
3c4bc5043e feat(imxyy-nix): use linux-cachyos 2025-06-20 21:53:20 +08:00
a2261cacd1 feat(imxyy-nix-server): use linux-cachyos 2025-06-17 08:16:52 +08:00
558faa058d chore: update flake.lock 2025-06-15 15:45:42 +08:00
9c547b6207 fix: persist zoxide database 2025-06-15 15:45:17 +08:00
2a4694b633 feat(zsh): move to official omz 2025-06-15 13:54:03 +08:00
2f170b9e08 fix(nvim): ident-blankline should be loaded earlier 2025-06-15 09:12:57 +08:00
b762cb91fe feat(nvim): tweak lazy.nvim 2025-06-15 09:10:35 +08:00
53e15c2324 chore(nvim): a lot
format, fix nvim-tree startup, update telescope, drop unused plugins
2025-06-14 19:47:08 +08:00
6a1889722c fix(nvim): diagnostic sign 2025-06-14 19:27:05 +08:00
ae231ba132 feat(nvim): tidy old config, improve startup time 2025-06-14 19:26:45 +08:00
feda825add chore: update secrets 2025-06-14 16:51:47 +08:00
f231663fe9 Merge branch 'master' of ssh://git.imxyy.top:2222/imxyy1soope1/nixos-dotfiles 2025-06-14 16:51:03 +08:00
ca45d3da81 chore(Makefile): use-remote-sudo -> sudo 2025-06-14 16:50:48 +08:00
985cd8aa9d fix(niri): fractional scaling
This works in latest unstable niri
2025-06-14 16:50:25 +08:00
1b6cf3b07f chore: update flake.lock 2025-06-14 16:49:53 +08:00
16cddf0335 chore(stylix): tidy 2025-06-14 13:55:26 +08:00
91a0e56ef1 chore: update secrets 2025-06-14 13:54:02 +08:00
e5b07a6fbe feat(niri): gnome-keyring 2025-06-08 09:58:48 +08:00
506ca711b5 feat: ttf-wps-fonts 2025-06-08 09:58:20 +08:00
0267058530 Merge branch 'master' of ssh://git.imxyy.top:2222/imxyy1soope1/nixos-dotfiles 2025-06-07 15:51:37 +08:00
06317b6c70 chore(headscale): drop magic dns 2025-06-07 15:51:25 +08:00
ad5e7aa5e7 fix(neovim): remove unecessary override 2025-06-07 15:50:28 +08:00
2cf0562cb6 fix(xwayland-satellite): fractional scaling 2025-06-07 14:31:44 +08:00
8c7b85fa12 chore: update flake.lock 2025-06-07 14:31:27 +08:00
cdb232a484 feat(make): nom 2025-06-07 12:52:32 +08:00
0f55da26e1 fix(bluetooth): A2DP profile not available on auto connect
not sure if it works
2025-06-07 11:59:06 +08:00
2fdf5aa8fe feat(browser): move to zen 2025-06-02 16:35:53 +08:00
2d85716642 Revert "chore: update flake.lock"
This reverts commit 4d36ddff56
since updated xwayland-satellite breaks fractional scaling.
2025-06-01 13:22:52 +08:00
117ada55c2 feat(niri): update bindings 2025-06-01 11:36:01 +08:00
87018a1c06 Merge branch 'master' of ssh://git.imxyy.top:2222/imxyy1soope1/nixos-dotfiles 2025-06-01 09:38:01 +08:00
4d36ddff56 chore: update flake.lock 2025-06-01 09:37:35 +08:00
c477dbeae6 feat(nvim): better outline icon 2025-05-31 15:32:57 +08:00
07890c4d9f feat(git): disable rebase on pull 2025-05-31 15:32:24 +08:00
2e2f77fffe chore: update secrets 2025-05-31 15:28:39 +08:00
ab3fbe30a9 fix: headscale & easytier server ip 2025-05-28 19:01:52 +08:00
7522628517 chore: update secrets 2025-05-27 10:21:06 +08:00
ffc74c1e6f chore: drop legacy proxy configuration 2025-05-27 10:20:42 +08:00
c45dadafa3 feat(imxyy-nix/ssh): remove elf-nix from authorized keys 2025-05-23 19:15:40 +08:00
27b7718048 chore: update secrets 2025-05-23 19:15:40 +08:00
33d0b7a694 fix(imxyy-nix-server/dns): fix DNS lookup timeout 2025-05-23 19:15:40 +08:00
80f0feed39 feat(imxyy-nix-server/ddns-go): fix command execution 2025-05-23 19:15:40 +08:00
6daffb4d5e fix(imxyy-nix-server/frp): server address 2025-05-23 19:15:40 +08:00
68e83817a5 feat(imxyy-nix-server/ssh): add imxyy-cloudwin to authorized keys 2025-05-23 19:15:40 +08:00
454c12ce90 fix(imxyy-nix-server/dns): DNS lookup timeout 2025-05-23 19:15:40 +08:00
7e4c48c3f1 chore: update flake.lock 2025-05-23 19:11:41 +08:00
990224174f feat(chromium): use KISS translator 2025-05-23 19:11:26 +08:00
dbbafc5140 fix: sddm autologin 2025-05-18 15:22:47 +08:00
dea4d8ed4c feat: 0517 update 2025-05-17 23:15:16 +08:00
3a12722913 chore: replace { ... } with _ 2025-05-10 19:07:06 +08:00
06c670bf30 chore: fmt 2025-05-10 18:22:21 +08:00
713f430b6d chore: update secrets 2025-05-10 18:22:10 +08:00
3ec4bdaa9b feat: update imxyy-hisense-pad ssh public key 2025-05-10 18:21:57 +08:00
50be5cf024 feat: update server kernel 2025-05-10 18:21:36 +08:00
d69b965651 feat(kitty): copy paste keybind 2025-05-10 13:54:24 +08:00
e2e8e35b0e chore: update flake.lock 2025-05-10 13:54:16 +08:00
64d4085b98 feat: nixd 2025-05-10 12:40:10 +08:00
e380732f90 fix(nvim): diagnostic sign 2025-05-10 12:38:35 +08:00
48ebcb7104 feat(nixpkgs): disable set NIX_PATH (use customized instead) 2025-05-10 12:38:35 +08:00
90dc945353 fix(wsl): nixpkgs hostPlatform 2025-05-08 09:16:42 +08:00
c9dab71e9b feat(git): check signature 2025-05-04 11:40:04 +08:00
c40b78db93 chore: update secrets 2025-05-04 10:59:49 +08:00
8e2fe9ba0b chore: flake 2025-05-04 10:59:34 +08:00
7c627d2a42 fix: wsl 2025-05-04 10:59:22 +08:00
a477e7095b feat: lazygit 2025-05-04 10:59:05 +08:00
27041ff1fa feat(nvim): switch virtual_lines 2025-05-04 10:58:47 +08:00
bf1539e914 fix: vscode 2025-05-04 10:58:16 +08:00
0a52c5f1b2 fix: impermanence permission 2025-05-04 10:58:06 +08:00
1a7112c21d chore: remove useless comments 2025-05-04 10:57:03 +08:00
515cfe3866 feat: disable tailscale 2025-05-04 10:56:42 +08:00
8949fbea6b feat: move to sddm 2025-05-04 10:56:31 +08:00
ba30d87ef4 Revert "feat: move to ly"
This reverts commit ece19eadb8.
2025-05-04 10:14:54 +08:00
ece19eadb8 feat: move to ly
move to ly DM in order to fix the annoying xdg-desktop-portal
2025-05-04 09:24:32 +08:00
a0164ce7c0 feat: git signing 2025-05-03 14:24:24 +08:00
36d63a667c feat: infuse 2025-05-03 14:13:53 +08:00
095d9ecb67 feat: swich to kitty 2025-05-03 09:56:23 +08:00
1ff4475a8f feat: 0501 update 2025-05-01 10:49:14 +08:00
dd010c6271 feat: 0425 update 2025-04-25 20:50:45 +08:00
2242e26ede refactor: what can I say 2025-04-19 12:42:19 +08:00
d34da2b672 chore: update flake lock 2025-04-18 22:30:01 +08:00
329 changed files with 7087 additions and 8115 deletions

13
.editorconfig Normal file
View File

@@ -0,0 +1,13 @@
root = true
[*]
indent_style = space
end_of_line = lf
charset = utf-8
insert_final_newline = true
[*.{nix,lua,yaml,css}]
indent_size = 2
[Makefile]
indent_size = 4

1
.envrc Normal file
View File

@@ -0,0 +1 @@
export IMPURE_ROOT=$(pwd)

20
.lazy.lua Normal file
View File

@@ -0,0 +1,20 @@
vim.lsp.config("nixd", {
settings = {
nixd = {
options = {
nixos = {
expr = '(builtins.getFlake ("git+file://" + toString ./.)).nixosConfigurations.'
.. vim.uv.os_gethostname()
.. ".options",
},
},
diagnostic = {
suppress = {
"sema-primop-overridden",
},
},
},
},
})
return {}

View File

@@ -1,11 +1,11 @@
keys:
- &imxyy-nix age1jf5pg2x6ta8amj40xdy0stvcvrdlkwc2nrwtmkpymu0qclk0eg5qmm9kns
- &imxyy-nix-server age1hpgg6psejh4y6jcdd34wxuml75fnweqpe0kh8376yqsctsfn9qxs037kk6
- &imxyy-cloudwin age1tp7th3rrv3x0l6jl76n0hjqjp223w2y586pkgr0hcjwdm254jd5shkj6a8
- &imxyy-nix ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOEFLUkyeaK8ZPPZdVNEmtx8zvoxi7xqS2Z6oxRBuUPO
- &imxyy-nix-server ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB28jpN+h5euh3NtdN+A+EtqgIatC22e4i1TPTioKire
- &imxyy-nix-x16 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMb5G/ieEYBOng66YeyttBQLThyM6W//z2POsNyq4Rw/
creation_rules:
- path_regex: secrets/.*\.(yaml|toml|json|env|dae|txt)$
- path_regex: secrets/.*\..*
key_groups:
- age:
- *imxyy-nix
- *imxyy-nix-server
- *imxyy-cloudwin
- *imxyy-nix-x16

51
Justfile Normal file
View File

@@ -0,0 +1,51 @@
set export
IMPURE_ROOT := `pwd`
all: fmt switch
@switch:
echo "Rebuilding NixOS..."
nh os switch . --impure
@switch-offline:
echo "Rebuilding NixOS without net..."
nh os switch . --impure --no-net
alias offline := switch-offline
@boot:
echo "Rebuilding NixOS..."
nh os boot . --impure
@test:
echo "Rebuilding NixOS..."
nh os test . --impure
@vm:
echo "Building NixOS VM..."
nh os build-vm . --impure
@update:
echo "Updating flakes..."
nix flake update
@repl:
nixos-rebuild repl --flake .
@cleandry:
echo "Listing all generations older than 15 days..."
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --dry-run --older-than 15d
nix profile wipe-history --profile ~/.local/state/nix/profiles/profile --dry-run --older-than 15d
@clean:
echo "Removing all generations older than 15 days..."
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 15d
nix profile wipe-history --profile ~/.local/state/nix/profiles/profile --older-than 15d
@gc:
nix store gc --debug
@fmt:
echo "Formatting files..."
nix fmt

View File

@@ -1,45 +0,0 @@
all: fmt switch
switch:
@echo "Rebuilding NixOS..."
@nixos-rebuild switch --flake . --use-remote-sudo
boot:
@echo "Rebuilding NixOS..."
@nixos-rebuild boot --flake . --use-remote-sudo
vm:
@echo "Building NixOS VM..."
@nixos-rebuild build-vm --flake .
update:
@echo "Updating flakes..."
@nix flake update
history:
@nix profile history --profile /nix/var/nix/profiles/system
replpkgs:
@nix repl -f flake:nixpkgs
repl:
@nixos-rebuild repl --flake .
cleandry:
@echo "Listing all generations older than 15 days..."
@sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --dry-run --older-than 15d
@nix run home-manager#home-manager -- expire-generations -15days --dry-run
clean:
@echo "Removing all generations older than 15 days..."
@sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 15d
@nix run home-manager#home-manager -- expire-generations -15days
gc:
@nix store gc --debug
fmt:
@echo "Formatting nix files..."
@nix fmt
.PHONY: os home news update history repl clean gc fmt

49
README.md Normal file
View File

@@ -0,0 +1,49 @@
<h2 align="center">:snowflake: imxyy_soope_'s NixOS Config :snowflake:</h2>
> This configuration and READMEs in this repo borrows heavily from [ryan4yin/nix-config](https://github.com/ryan4yin/nix-config) and his
> [cookbook](https://github.com/ryan4yin/nixos-and-flakes-book). Many thanks to his spirit of sharing!
This repository is home to the nix code that builds my systems:
Currently, this repository contains the nix code that builds:
1. NixOS Desktop: NixOS with home-manager, niri, neovim, etc.
2. NixOS home server
3. NixOS WSL
See [./hosts](./hosts) for details of each host.
## Why NixOS & Flakes?
Nix allows for easy-to-manage, collaborative, reproducible deployments. This
means that once something is setup and configured once, it works (almost)
forever. If someone else shares their configuration, anyone else can just use it
(if you really understand what you're copying/refering now).
As for Flakes, refer to
[Introduction to Flakes - NixOS & Nix Flakes Book](https://nixos-and-flakes.thiscute.world/nixos-with-flakes/introduction-to-flakes)
This configuration uses [flake-parts](https://flake.parts/) for better flake organization and modularity,
enabling declarative host definitions and cleaner separation of concerns.
## Folder Structure
- `modules/` - custom NixOS modules
- `modules/core/` - core system modules (nix, persistence, time, user, xdg)
- `modules/cli/` - command-line tools and utilities
- `modules/coding/` - development environments and editors
- `modules/desktop/` - desktop applications and window managers
- `modules/virt/` - virtualization configurations
- `profiles/` - system configuration profiles
- `profiles/base.nix` - base configuration for all hosts
- `profiles/desktop.nix` - desktop environment configuration
- `profiles/server.nix` - server-specific configuration
- `profiles/wsl.nix` - WSL-specific configuration
- `hosts/<name>/` - host-specific configs
- `flake/` - flake-parts modules
- `flake/hosts.nix` - declarative host definitions
- `lib/` - custom nix library
- `pkgs/` - custom packages
- `overlays/` - nixpkgs overlays
- `vars.nix` - my variables
- `secrets/` - secrets managed by sops-nix. see [./secrets](./secrets) for details
- `flake.nix` - flake entry

BIN
assets/avatar.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -1,26 +0,0 @@
{ lib, hostname, ... }:
{
environment.etc.issue.text = "\\e{lightcyan}\\S\\e{reset} Login (\\l)\n\n";
networking.hostName = hostname;
system.stateVersion = "24.11";
systemd.services."systemd-machine-id-commit".enable = lib.mkForce false;
my = {
home = {
# Nicely reload system units when changing configs
systemd.user.startServices = "sd-switch";
home.stateVersion = "24.11";
};
xdg.enable = true;
persist = {
nixosDirs = [
"/root"
"/var"
];
nixosFiles = [
"/etc/machine-id"
];
};
};
}

View File

@@ -1,15 +0,0 @@
{ ... }:
{
services.open-webui = {
enable = true;
host = "127.0.0.1";
port = 8089;
};
services.caddy.virtualHosts."ai.imxyy.top" = {
extraConfig = ''
reverse_proxy :8089 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -1,38 +0,0 @@
{ config, ... }:
{
services.postgresql.ensureUsers = [
{
name = "coder";
ensureDBOwnership = true;
}
];
services.postgresql.ensureDatabases = [ "coder" ];
virtualisation.oci-containers = {
containers = {
coder = {
image = "ghcr.io/coder/coder:latest";
environment = {
CODER_ACCESS_URL = "https://coder.imxyy.top";
CODER_HTTP_ADDRESS = "0.0.0.0:8086";
CODER_PG_CONNECTION_URL = "postgresql://coder:coderdatabase@127.0.0.1/coder?sslmode=disable";
};
extraOptions = [
"--network=host"
"--group-add=${toString config.users.groups.podman.gid}"
];
volumes = [
"/var/lib/coder:/home/coder/.config"
"/var/run/docker.sock:/var/run/docker.sock"
];
ports = [ "8086:8086" ];
};
};
};
services.caddy.virtualHosts."coder.imxyy.top" = {
extraConfig = ''
reverse_proxy :8086 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -1,26 +0,0 @@
{ ... }:
{
imports = [
./nixos.nix
./hardware.nix
./home.nix
./virt.nix
./docker.nix
./minecraft.nix
./samba.nix
./net.nix
./caddy.nix
./nextcloud.nix
./mail.nix
./gitea.nix
./vault.nix
./homepage.nix
./code.nix
./yesplaymusic.nix
./ai.nix
./grafana.nix
./note.nix
./matrix.nix
./minio.nix
];
}

View File

@@ -1,45 +0,0 @@
{ pkgs, ... }:
{
services.grafana = {
enable = true;
settings = {
server = {
http_addr = "0.0.0.0";
http_port = 8090;
domain = "grafana.imxyy.top";
};
};
};
services.prometheus = {
enable = true;
package = pkgs.stable.prometheus;
port = 8091;
exporters = {
node = {
enable = true;
port = 8092;
enabledCollectors = [
"systemd"
"zfs"
];
};
};
scrapeConfigs = [
{
job_name = "node";
static_configs = [
{
targets = [ "127.0.0.1:8092" ];
}
];
}
];
};
services.caddy.virtualHosts."grafana.imxyy.top" = {
extraConfig = ''
reverse_proxy :8090 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -1,37 +0,0 @@
{ lib, ... }:
{
my.home = {
programs.zsh = {
shellAliases = {
proxy_on = lib.mkForce "export http_proxy=http://127.0.0.1:7890 https_proxy=http://127.0.0.1:7890 all_proxy=socks://127.0.0.1:7891";
};
sessionVariables = {
no_proxy = "192.168.3.0/24";
};
};
};
my = {
cmd.all.enable = true;
coding.editor.neovim.enable = true;
coding.misc.enable = true;
coding.langs.lua.enable = true;
persist = {
enable = true;
homeDirs = [
"workspace"
"Virt"
".ssh"
".local/state"
".local/share"
".local/share/nvim"
".cache"
".ollama"
];
nixosDirs = [
"/etc/ssh"
];
};
};
}

View File

@@ -1,19 +0,0 @@
{ ... }:
{
virtualisation.oci-containers = {
containers = {
sun-panel = {
image = "hslr/sun-panel:latest";
volumes = [
"/var/lib/sun-panel:/app/conf"
];
ports = [ "8085:3002" ];
};
};
};
services.caddy.virtualHosts."home.imxyy.top" = {
extraConfig = ''
reverse_proxy :8085
'';
};
}

View File

@@ -1,47 +0,0 @@
{ ... }:
{
services.matrix-synapse = {
enable = true;
settings = {
server_name = "matrix.imxyy.top";
public_baseurl = "https://matrix.imxyy.top";
listeners = [
{
port = 8094;
bind_addresses = [ "127.0.0.1" ];
type = "http";
tls = false;
x_forwarded = true;
resources = [
{
names = [
"client"
"federation"
];
compress = true;
}
];
}
];
turn_uris = [ "turns:vkvm.imxyy.top:5349" ];
turn_shared_secret = "ac779a48c03bb451839569d295a29aa6ab8c264277bec2df9c9c7f5e22936288";
turn_user_lifetime = "1h";
database_type = "psycopg2";
database_args.database = "matrix-synapse";
};
extraConfigFiles = [
"/var/lib/matrix-synapse/secret"
];
};
services.caddy.virtualHosts."matrix.imxyy.top" = {
extraConfig = ''
reverse_proxy :8094
handle_path /_matrix {
reverse_proxy :8094
}
handle_path /_synapse/client {
reverse_proxy :8094
}
'';
};
}

View File

@@ -1,645 +0,0 @@
{
config,
lib,
pkgs,
username,
sopsRoot,
...
}:
{
boot.kernelParams = [
"biosdevname=0"
"net.ifnames=0"
];
networking = {
useDHCP = lib.mkForce false;
dhcpcd = {
wait = "background";
IPv6rs = true;
extraConfig = ''
interface mac0
noipv4
'';
};
interfaces = {
eth0.wakeOnLan.enable = true;
eth1.wakeOnLan.enable = true;
mac0 = {
useDHCP = true;
ipv4.addresses = [
{
address = "192.168.3.2";
prefixLength = 24;
}
];
};
};
macvlans."mac0" = {
interface = "eth0";
mode = "bridge";
};
defaultGateway = {
address = "192.168.3.1";
interface = "mac0";
};
nameservers = [
"192.168.3.1"
];
firewall.enable = false;
nftables = {
enable = true;
flushRuleset = true;
ruleset = ''
table inet firewall {
set LANv4 {
type ipv4_addr
flags interval
elements = { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 }
}
set LANv6 {
type ipv6_addr
flags interval
elements = { fd00::/8, fe80::/10 }
}
set tcp_ports {
type inet_service
flags interval
elements = {
http,
https,
2222,
25565
}
}
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
ip daddr @LANv4 accept
ip6 daddr @LANv6 accept
}
chain output {
type filter hook output priority 100; policy accept;
ip daddr @LANv4 accept
ip6 daddr @LANv6 accept
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state invalid drop
ct state established,related accept
ip protocol { icmp, igmp } accept
ip saddr @LANv4 accept
ip6 saddr @LANv6 accept
tcp dport 2222 ct state new limit rate 15/minute counter accept
tcp dport @tcp_ports counter accept
}
chain forward {
type filter hook forward priority 0; policy accept;
}
chain nat {
type nat hook postrouting priority 0; policy accept;
ip saddr 192.168.3.0/24 masquerade
}
}
'';
};
};
services.openssh = {
enable = true;
settings = {
# PermitRootLogin = "yes";
PermitRootLogin = "prohibit-password";
PasswordAuthentication = true;
};
};
users.users.root.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOEFLUkyeaK8ZPPZdVNEmtx8zvoxi7xqS2Z6oxRBuUPO imxyy@imxyy-nix"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKqza/3b6a9JxsNxytHF5GPe4gQhbLrKxAPyZ0GpfVQt imxyy-hisense-pad"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8pivvE8PMtsOxmccfNhH/4KehDKhBfUfJbQZxo/SZT imxyy-ace5"
];
users.users.${username}.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOEFLUkyeaK8ZPPZdVNEmtx8zvoxi7xqS2Z6oxRBuUPO imxyy@imxyy-nix"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKqza/3b6a9JxsNxytHF5GPe4gQhbLrKxAPyZ0GpfVQt imxyy-hisense-pad"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8pivvE8PMtsOxmccfNhH/4KehDKhBfUfJbQZxo/SZT imxyy-ace5"
];
sops.secrets.dae-imxyy-nix-server = {
sopsFile = sopsRoot + /dae-imxyy-nix-server.dae;
format = "binary";
};
services.dae = {
enable = true;
configFile = config.sops.secrets.dae-imxyy-nix-server.path;
};
systemd.services.dae.after = [ "sops-nix.service" ];
sops.secrets.mihomo = {
sopsFile = sopsRoot + /mihomo.yaml;
format = "yaml";
key = "";
};
systemd.services.mihomo.after = [ "sops-nix.service" ];
services.mihomo = {
enable = true;
configFile = config.sops.secrets.mihomo.path;
webui = pkgs.metacubexd;
};
sops.secrets.frp-env = {
sopsFile = sopsRoot + /frp.env;
format = "dotenv";
};
systemd.services.frp.serviceConfig.EnvironmentFile = [
config.sops.secrets.frp-env.path
];
services.frp = {
enable = true;
role = "client";
settings = {
serverAddr = "vkvm.imxyy.top";
serverPort = 7000;
auth.token = "{{ .Envs.FRP_AUTH_TOKEN }}";
proxies = [
{
name = "nextcloud-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "nextcloud.imxyy.top" ];
}
{
name = "nextcloud-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "nextcloud.imxyy.top" ];
}
{
name = "oidc-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "oidc.imxyy.top" ];
}
{
name = "oidc-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "oidc.imxyy.top" ];
}
{
name = "headscale-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "headscale.imxyy.top" ];
}
{
name = "headscale-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "headscale.imxyy.top" ];
}
{
name = "mail-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "mail.imxyy.top" ];
}
{
name = "mail-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "mail.imxyy.top" ];
}
{
name = "gitea-ssh";
type = "tcp";
localIP = "127.0.0.1";
localPort = 2222;
remotePort = 2222;
}
{
name = "gitea-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "git.imxyy.top" ];
}
{
name = "gitea-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "git.imxyy.top" ];
}
{
name = "vault-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "vault.imxyy.top" ];
}
{
name = "vault-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "vault.imxyy.top" ];
}
{
name = "home-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "home.imxyy.top" ];
}
{
name = "home-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "home.imxyy.top" ];
}
{
name = "coder-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "coder.imxyy.top" ];
}
{
name = "coder-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "coder.imxyy.top" ];
}
{
name = "music-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "music.imxyy.top" ];
}
{
name = "music-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "music.imxyy.top" ];
}
{
name = "ai-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "ai.imxyy.top" ];
}
{
name = "ai-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "ai.imxyy.top" ];
}
{
name = "grafana-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "grafana.imxyy.top" ];
}
{
name = "grafana-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "grafana.imxyy.top" ];
}
{
name = "note-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "note.imxyy.top" ];
}
{
name = "note-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "note.imxyy.top" ];
}
{
name = "siyuan-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "sy.imxyy.top" ];
}
{
name = "siyuan-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "sy.imxyy.top" ];
}
{
name = "matrix-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "matrix.imxyy.top" ];
}
{
name = "matrix-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "matrix.imxyy.top" ];
}
{
name = "minecraft";
type = "tcp";
localIP = "127.0.0.1";
localPort = 25565;
remotePort = 25565;
}
];
};
};
services.tailscale = {
enable = true;
useRoutingFeatures = "both";
extraSetFlags = [ "--accept-dns=false" ];
};
services.headscale = {
enable = true;
address = "0.0.0.0";
port = 8080;
settings = {
logtail.enabled = false;
server_url = "https://headscale.imxyy.top";
dns = {
base_domain = "tailnet.imxyy.top";
extra_records = [
{
"name" = "home.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "nextcloud.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "mail.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "git.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "vault.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "mc.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "home.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "coder.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "music.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
];
};
ip_prefixes = "100.64.0.0/10";
derp.paths = [
(toString (
pkgs.writeText "derp.yaml" ''
regions:
900:
regionid: 900
regioncode: custom-tok
regionname: imxyy_soope_ Tokyo
nodes:
- name: 900a
regionid: 900
hostname: vkvm.imxyy.top
# 901:
# regionid: 901
# regioncode: custom-cn
# regionname: imxyy_soope_ Hu Bei
# nodes:
# - name: 901a
# regionid: 901
# hostname: ry.imxyy.top
# derpport: 1443
''
))
];
derp.urls = lib.mkForce [ ];
oidc = {
only_start_if_oidc_is_available = true;
issuer = "https://oidc.imxyy.top";
client_id = "https://headscale.imxyy.top";
allowed_domains = [
"imxyy.top"
"*.imxyy.top"
];
client_secret = "";
expiry = 0;
extra_params.domain_hint = "imxyy.top";
strip_email_domain = true;
};
};
};
systemd.services."headscale" = {
serviceConfig = {
Restart = lib.mkOverride 500 "always";
RestartMaxDelaySec = lib.mkOverride 500 "1m";
RestartSec = lib.mkOverride 500 "100ms";
RestartSteps = lib.mkOverride 500 9;
};
after = [
"podman-obligator.service"
];
requires = [
"podman-obligator.service"
];
};
sops.secrets.et-imxyy-nix-server = {
sopsFile = sopsRoot + /et-imxyy-nix-server.toml;
format = "binary";
};
environment.systemPackages = [ pkgs.easytier ];
systemd.services."easytier" = {
enable = true;
script = "easytier-core -c ${config.sops.secrets.et-imxyy-nix-server.path}";
serviceConfig = {
Restart = lib.mkOverride 500 "always";
RestartMaxDelaySec = lib.mkOverride 500 "1m";
RestartSec = lib.mkOverride 500 "100ms";
RestartSteps = lib.mkOverride 500 9;
User = "root";
};
wantedBy = [ "multi-user.target" ];
after = [
"network.target"
"sops-nix.service"
];
path = with pkgs; [
easytier
iproute2
bash
];
};
virtualisation.oci-containers = {
containers = {
obligator = {
image = "anderspitman/obligator:latest";
volumes = [
"/var/lib/obligator:/data"
"/var/lib/obligator:/api"
];
ports = [ "8081:1616" ];
cmd = [
"-storage-dir"
"/data"
"-api-socket-dir"
"/api"
"-root-uri"
"https://oidc.imxyy.top"
"-port"
"1616"
];
};
};
};
services.caddy.virtualHosts."headscale.imxyy.top" = {
extraConfig = ''
reverse_proxy :8080 {
header_up X-Real-IP {remote_host}
}
'';
};
services.caddy.virtualHosts."oidc.imxyy.top" = {
extraConfig = ''
reverse_proxy :8081 {
header_up X-Real-IP {remote_host}
}
'';
};
systemd.services.ddns-go =
let
ddns-go = pkgs.buildGoModule rec {
pname = "ddns-go";
version = "6.6.7";
src = pkgs.fetchFromGitHub {
owner = "jeessy2";
repo = "ddns-go";
rev = "v${version}";
hash = "sha256-Ejoe6e9GFhHxQ9oIBDgDRQW9Xx1XZK+qSAXiRXLdn+c=";
};
meta.mainProgram = "ddns-go";
vendorHash = "sha256-XZii7gV3DmTunYyGYzt5xXhv/VpTPIoYKbW4LnmlAgs=";
doCheck = false;
};
in
{
description = "Go Dynamic DNS";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${lib.getExe ddns-go} -l :9876 -f 10 -cacheTimes 180 -c /var/lib/ddns-go/config.yaml";
Restart = "always";
RestartSec = 120;
};
};
services.dnsmasq =
let
subDomains = [
"home"
"nextcloud"
"mail"
"git"
"vault"
"coder"
"headscale"
"oidc"
"mc"
"music"
"ai"
];
in
{
enable = true;
resolveLocalQueries = false;
settings = {
server = [
"120.53.53.53"
"223.5.5.5"
];
address = map (sub: "/${sub}.imxyy.top/192.168.3.2") subDomains ++ [
"/imxyy-nix-server/192.168.3.2"
"/imxyy-cloudwin/192.168.3.4"
"/printer.home/192.168.3.53"
];
};
};
}

View File

@@ -1,33 +0,0 @@
{
lib,
config,
username,
sopsRoot,
...
}:
{
boot.loader = {
efi.canTouchEfiVariables = true;
systemd-boot.enable = true;
grub.enable = false;
timeout = 0;
};
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
systemd.services.nix-daemon = {
environment.TMPDIR = "/var/cache/nix";
serviceConfig.CacheDirectory = "nix";
};
environment.variables.NIX_REMOTE = "daemon";
sops.secrets.imxyy-nix-server-hashed-password = {
sopsFile = sopsRoot + /imxyy-nix-server-hashed-password.txt;
format = "binary";
neededForUsers = true;
};
users.users.${username}.hashedPasswordFile =
lib.mkForce config.sops.secrets.imxyy-nix-server-hashed-password.path;
users.users.root.hashedPasswordFile = lib.mkForce config.sops.secrets.imxyy-nix-server-hashed-password.path;
}

View File

@@ -1,61 +0,0 @@
{
config,
sopsRoot,
...
}:
{
sops.secrets = {
flatnote-env = {
sopsFile = sopsRoot + /flatnote.env;
format = "dotenv";
};
siyuan-env = {
sopsFile = sopsRoot + /siyuan.env;
format = "dotenv";
};
};
virtualisation.oci-containers = {
containers = {
flatnotes = {
image = "dullage/flatnotes:latest";
volumes = [
"/mnt/nas/flatnotes/data:/data"
];
environmentFiles = [
"${config.sops.secrets.flatnote-env.path}"
];
ports = [ "8093:8080" ];
};
siyuan = {
image = "apkdv/siyuan-unlock:v3.1.24";
volumes = [
"/mnt/nas/siyuan/workspace:/workspace"
"/mnt/nas/siyuan:/home/siyuan"
];
cmd = [
"--workspace=/workspace"
];
environment = {
PUID = "0";
PGID = "0";
};
environmentFiles = [
"${config.sops.secrets.siyuan-env.path}"
];
ports = [ "8095:6806" ];
};
};
};
services.caddy.virtualHosts = {
"note.imxyy.top" = {
extraConfig = ''
reverse_proxy :8093
'';
};
"sy.imxyy.top" = {
extraConfig = ''
reverse_proxy :8095
'';
};
};
}

View File

@@ -1,24 +0,0 @@
{ ... }:
{
virtualisation.oci-containers.containers."YesPlayMusic" = {
image = "git.imxyy.top/imxyy1soope1/yesplaymusic:latest";
environment = {
"NODE_TLS_REJECT_UNAUTHORIZED" = "0";
};
volumes = [
"/etc/localtime:/etc/localtime:ro"
];
ports = [
"8088:80/tcp"
];
log-driver = "journald";
};
services.caddy.virtualHosts."music.imxyy.top" = {
extraConfig = ''
reverse_proxy :8088 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -1,7 +0,0 @@
{ ... }:
{
imports = [
./nixos.nix
./home.nix
];
}

View File

@@ -1,14 +0,0 @@
{ lib, username, ... }:
{
my.home.programs.zsh.shellAliases = {
localproxy_on = "export http_proxy=http://192.168.128.1:7890 https_proxy=http://192.168.128.1:7890 all_proxy=socks://192.168.128.1:7890";
};
my = {
sops.sshKeyPath = "/home/${username}/.ssh/id_ed25519";
coding.all.enable = true;
coding.editor.vscode.enable = lib.mkForce false;
cmd.misc.enable = true;
xdg.enable = true;
cmd.media.all.enable = true;
};
}

View File

@@ -1,10 +0,0 @@
{ ... }:
{
imports = [
./nixos.nix
./hardware.nix
./home.nix
./virt.nix
./net.nix
];
}

View File

@@ -1,215 +0,0 @@
{
config,
lib,
pkgs,
username,
...
}:
{
my.home = {
home.packages = with pkgs; [
localsend
rclone
wpsoffice-cn
wps-office-fonts
evince
# siyuan-unlock
anki
ayugram-desktop
telegram-desktop
signal-desktop
cinny-desktop
discord
qq
gnome-clocks
wineWowPackages.waylandFull
pavucontrol
pamixer
];
programs.zsh = {
shellAliases = {
cageterm = "cage -m DP-2 -s -- alacritty -o font.size=20";
cagefoot = "cage -m DP-2 -s -- foot --font=monospace:size=20";
cagekitty = "cage -m DP-2 -s -- kitty -o font_size=20";
};
sessionVariables = {
no_proxy = "192.168.3.0/24";
PATH = "/home/${username}/bin:$PATH";
};
profileExtra = ''
if [ `tty` = "/dev/tty1" -a $XDG_RUNTIME_DIR ]; then
echo 'Starting Niri...'
exec uwsm start niri-uwsm.desktop
elif [ `tty` = "/dev/tty6" ]; then
clear
fi
'';
};
programs.niri.settings.outputs = {
DP-2 = {
enable = true;
mode = {
width = 2560;
height = 1440;
refresh = 75.033;
};
scale = 1.25;
position = {
x = 0;
y = 0;
};
};
DP-3 = {
enable = true;
mode = {
width = 2560;
height = 1440;
refresh = 75.033;
};
scale = 1.25;
};
};
};
my = {
autologin = {
enable = true;
user = "${username}";
ttys = [
1
6
];
};
gpg.enable = true;
cmd.all.enable = true;
coding.all.enable = true;
desktop.all.enable = true;
desktop.wm.dwm.enable = lib.mkForce false;
desktop.browser.librewolf.enable = lib.mkForce false;
i18n.fcitx5.enable = true;
xdg = {
enable = true;
defaultApplications =
let
browser = [ "chromium-browser.desktop" ];
editor = [ "codium.desktop" ];
imageviewer = [ "org.gnome.Shotwell-Viewer.desktop" ];
in
{
"inode/directory" = [ "nemo.desktop" ];
"application/pdf" = [ "evince.desktop" ];
"text/*" = editor;
"application/json" = editor;
"text/html" = editor;
"text/xml" = editor;
"application/xml" = editor;
"application/xhtml+xml" = editor;
"application/xhtml_xml" = editor;
"application/rdf+xml" = editor;
"application/rss+xml" = editor;
"application/x-extension-htm" = editor;
"application/x-extension-html" = editor;
"application/x-extension-shtml" = editor;
"application/x-extension-xht" = editor;
"application/x-extension-xhtml" = editor;
"x-scheme-handler/about" = browser;
"x-scheme-handler/ftp" = browser;
"x-scheme-handler/http" = browser;
"x-scheme-handler/https" = browser;
"x-scheme-handler/unknown" = browser;
"audio/*" = imageviewer;
"video/*" = imageviewer;
"image/*" = imageviewer;
"image/gif" = imageviewer;
"image/jpeg" = imageviewer;
"image/png" = imageviewer;
"image/webp" = imageviewer;
};
extraBookmarks =
let
homedir = config.my.home.home.homeDirectory;
in
[
"file://${homedir}/Documents/%E7%8F%AD%E7%BA%A7%E4%BA%8B%E5%8A%A1 "
"file://${homedir}/NAS NAS"
"file://${homedir}/NAS/imxyy_soope_ NAS imxyy_soope_"
"file://${homedir}/NAS/imxyy_soope_/OS NAS OS"
];
};
persist = {
enable = true;
homeDirs = [
".android"
"Android"
".ssh"
"bin"
"workspace"
"WineApps"
"Virt"
".cache"
".local/state"
".local/share/Anki2"
".local/share/dooit"
".local/share/nvim"
".local/share/shotwell"
".local/share/Steam"
".local/share/SteamOS"
".local/share/Trash"
".local/share/cheat.sh"
".local/share/Kingsoft"
".local/share/oss.krtirtho.spotube"
".local/share/AyuGramDesktop"
".local/share/TelegramDesktop"
".local/share/cinny"
".config/Signal"
".config/discord"
".config/QQ"
".config/Kingsoft"
".config/dconf"
".config/gh"
".config/pulse"
".config/chromium"
".config/go-musicfox/db"
".config/tmux/plugins"
".config/pip"
".config/obs-studio"
".config/libreoffice"
".config/Moonlight Game Streaming Project"
".config/sunshine"
];
nixosDirs = [
"/etc/ssh"
];
homeFiles = [
".config/mpd/mpd.db" # requires bindfs
".config/go-musicfox/cookie"
".hmcl.json"
];
nixosFiles = [
"/etc/davfs2/secrets"
];
};
};
}

View File

@@ -1,319 +0,0 @@
{
lib,
pkgs,
username,
...
}:
let
btreset = pkgs.writeScriptBin "btreset" ''
#!${lib.getExe pkgs.python3}
import subprocess
import os
import sys
SYM = "BT"
def action(line: str) -> bool:
if line.find(SYM) == -1:
return False
temp = line.split(" ")
bus = temp[1]
device = temp[3][:-1]
subprocess.run(["${lib.getExe usbreset}", f"/dev/bus/usb/{bus}/{device}"])
return True
if __name__ == "__main__":
if os.path.exists("/tmp/.btreseted") and len(sys.argv) == 1 and "-f" not in sys.argv[1:]:
exit(0)
res_byte = subprocess.check_output("/run/current-system/sw/bin/lsusb")
res = res_byte.decode()
lst = res.split("\n")
if any(tuple(map(action, lst))):
with open("/tmp/.btreseted", "w"):
...
'';
usbreset = pkgs.writeCBin "usbreset" ''
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>
int main(int argc, char **argv)
{
const char *filename;
int fd;
int rc;
if (argc != 2) {
fprintf(stderr, "Usage: usbreset device-filename\n");
return 1;
}
filename = argv[1];
fd = open(filename, O_WRONLY);
if (fd < 0) {
perror("Error opening output file");
return 1;
}
printf("Resetting USB device %s\n", filename);
rc = ioctl(fd, USBDEVFS_RESET, 0);
if (rc < 0) {
perror("Error in ioctl");
return 1;
}
printf("Reset successful\n");
close(fd);
return 0;
}
'';
in
{
security.pam.loginLimits = [
{
domain = "*";
type = "soft";
item = "nofile";
value = "524288";
}
];
systemd.services.btreset = {
script = lib.getExe btreset;
wantedBy = [ "multi-user.target" ];
serviceConfig.Type = "oneshot";
};
boot.kernelParams = [
"usbcore.autosuspend=-1" # Avoid usb autosuspend (for usb bluetooth adapter)
"fsck.mode=skip"
];
boot.loader = {
efi.canTouchEfiVariables = true;
systemd-boot.enable = true;
grub.enable = false;
timeout = 0;
};
hardware.graphics.enable = true;
hardware.graphics.enable32Bit = true;
systemd.services.nix-daemon = {
environment.TMPDIR = "/var/cache/nix";
serviceConfig.CacheDirectory = "nix";
};
environment.variables.NIX_REMOTE = "daemon";
# services.pipewire.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
# alsa.enable = true;
# alsa.support32Bit = true;
# pulse.enable = true;
alsa.enable = false;
alsa.support32Bit = false;
pulse.enable = false;
audio.enable = false;
configPackages = [
/*
(pkgs.writeTextDir "share/pipewire/media-session.d/bluez-monitor.conf" ''
rules = [
{
actions = {
update-props = {
bluez5.autoswitch-profile = true;
}
}
}
]
'')
*/
];
};
services.pipewire.wireplumber.extraConfig = {
/*
"10-bluez" = {
"monitor.bluez.properties" = {
"bluez5.enable-sbc-xq" = true;
"bluez5.enable-msbc" = true;
"bluez5.enable-hw-volume" = true;
"bluez5.roles" = [
"hsp_hs"
"hsp_ag"
"hfp_hf"
"hfp_ag"
];
};
};
*/
/*
"11-bluetooth-policy" = {
"wireplumber.settings" = {
"bluetooth.autoswitch-to-headset-profile" = false;
};
};
*/
};
services.pulseaudio = {
enable = true;
support32Bit = true;
package = pkgs.pulseaudioFull;
extraConfig = ''
load-module module-switch-on-connect
unload-module module-suspend-on-idle
'';
};
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
settings = {
General.Enable = "Source,Sink,Media,Socket";
};
};
users.extraUsers.${username}.extraGroups = [ "audio" ];
fonts = {
enableDefaultPackages = false;
fontDir.enable = true;
packages = with pkgs; [
noto-fonts
noto-fonts-cjk-sans
noto-fonts-emoji
jetbrains-mono
nerd-fonts.symbols-only
];
fontconfig.defaultFonts = {
serif = [
"Noto Serif CJK SC"
"Noto Serif"
"Symbols Nerd Font"
"Noto Color Emoji"
];
sansSerif = [
"Noto Sans CJK SC"
"Noto Sans"
"Symbols Nerd Font"
"Noto Color Emoji"
];
monospace = [
"JetBrains Mono"
"Noto Sans Mono CJK SC"
"Symbols Nerd Font Mono"
"Noto Color Emoji"
];
emoji = [ "Noto Color Emoji" ];
};
};
services.printing.enable = true;
services.keyd = {
enable = true;
keyboards.default.settings = {
main = {
capslock = "overload(control, esc)";
home = "end";
};
shift = {
home = "home";
};
control = {
delete = "print";
};
};
};
services.gvfs.enable = true;
virtualisation.waydroid.enable = true;
programs.wireshark.enable = true;
programs.wireshark.package = pkgs.wireshark;
users.users.${username}.extraGroups = [ "wireshark" ];
services.sunshine = {
enable = true;
autoStart = true;
capSysAdmin = true;
applications.apps = [
{
name = "Desktop";
image-path = "desktop.png";
}
];
};
services.openssh = {
enable = true;
settings = {
# Forbid root login through SSH.
PermitRootLogin = null;
PasswordAuthentication = true;
};
};
environment.systemPackages = [
pkgs.rclone
btreset
];
fileSystems =
let
config = pkgs.writeText "rclone.conf" ''
[Nextcloud]
type = webdav
url = https://192.168.3.2/remote.php/dav/files/imxyy_soope_
vendor = nextcloud
user = imxyy_soope_
pass = C2UUiMyPoynWWKS9kf_Fr8rcoXxgUswPYi4s
[NAS]
type = smb
host = 192.168.3.2
user = nas
pass = O74S6-7jDFykwCvZ8vuIxohh00Ty7XJF
'';
in
{
"/home/${username}/Nextcloud" = {
device = "Nextcloud:";
fsType = "rclone";
options = [
"nodev"
"nofail"
"allow_other"
"args2env"
"config=${toString config}"
"uid=1000"
"gid=100"
"rw"
"no-check-certificate"
"vfs-cache-mode=full"
];
};
"/home/${username}/NAS" = {
device = "//192.168.3.2/share";
fsType = "cifs";
options = [
"username=nas"
"password=nasshare"
"x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s"
"nodev"
"nofail"
"uid=1000"
"gid=100"
"vers=3"
"rw"
];
};
};
}

View File

@@ -1,35 +0,0 @@
{
"version": 1,
"rules": [
{
"domain": [
"cm.steampowered.com",
"ol.epicgames.com",
"csgo.wmsj.cn",
"dota2.wmsj.cn",
"wmsjsteam.com",
"dl.steam.clngaa.com",
"dl.steam.ksyna.com",
"gstore.val.manlaxy.com",
"st.dl.bscstorage.net",
"st.dl.eccdnx.com",
"st.dl.pinyuncloud.com",
"steampipe.steamcontent.tnkjmec.com",
"steampowered.com.8686c.com",
"steamstatic.com.8686c.com",
"steambroadcast.akamaized.net",
"steamcdn-a.akamaihd.net",
"steamcommunity-a.akamaihd.net",
"steamstore-a.akamaihd.net",
"steamusercontent-a.akamaihd.net",
"steamuserimages-a.akamaihd.net"
],
"domain_suffix": [
".steamcontent.com",
".steamserver.net",
".steamchina.com"
],
"invert": false
}
]
}

View File

@@ -1,11 +0,0 @@
#!/bin/sh
sudo mkdir -p /run/systemd/system/docker.service.d
sudo su -c 'cat << EOF >/run/systemd/system/docker.service.d/override.conf
[Service]
Environment="http_proxy=http://127.0.0.1:7890"
Environment="https_proxy=http://127.0.0.1:7890"
Environment="all_proxy=socks5h://127.0.0.1:7891"
EOF'
sudo systemctl daemon-reload
sudo systemctl restart docker

907
flake.lock generated

File diff suppressed because it is too large Load Diff

286
flake.nix
View File

@@ -3,203 +3,145 @@
inputs = {
# Nixpkgs
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable-small";
nixpkgs-stable.url = "github:nixos/nixpkgs/release-24.11";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
nixpkgs-stable.url = "github:nixos/nixpkgs/release-25.11";
nixpkgs-master.url = "github:nixos/nixpkgs/master";
# nixpkgs.follows = "nixpkgs-stable";
nixpkgs.follows = "nixpkgs-unstable";
# SOPS
sops-nix.url = "github:Mic92/sops-nix";
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
# nixpkgs.follows = "nixpkgs-master";
# Home manager
home-manager.url = "github:nix-community/home-manager/master";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
# Impermanence
impermanence.url = "github:nix-community/impermanence";
# NUR
nur.url = "github:nix-community/NUR";
# NeoVim nightly
# neovim-nightly.url = "github:nix-community/neovim-nightly-overlay";
# neovim-nightly.inputs.nixpkgs.follows = "nixpkgs";
nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions";
# OMZ
omz.url = "github:imxyy1soope1/omz/master";
omz.inputs.nixpkgs.follows = "nixpkgs";
# dwm
dwm.url = "github:imxyy1soope1/dwm/master";
dwm.inputs.nixpkgs.follows = "nixpkgs";
# Niri
niri.url = "github:sodiboo/niri-flake";
niri.inputs.nixpkgs.follows = "nixpkgs";
niri.inputs.nixpkgs-stable.follows = "nixpkgs-stable";
quickshell.url = "git+https://git.outfoxxed.me/outfoxxed/quickshell";
quickshell.inputs.nixpkgs.follows = "nixpkgs";
darkly.url = "github:Bali10050/Darkly";
darkly.inputs.nixpkgs.follows = "nixpkgs";
stylix.url = "github:danth/stylix";
stylix.inputs.nixpkgs.follows = "nixpkgs";
# go-musicfox
go-musicfox.url = "github:imxyy1soope1/go-musicfox/master";
go-musicfox.inputs.nixpkgs.follows = "nixpkgs";
home-manager = {
url = "github:nix-community/home-manager/master";
inputs.nixpkgs.follows = "nixpkgs";
};
# NixOS-WSL
nixos-wsl.url = "github:nix-community/NixOS-WSL";
nixos-wsl.inputs.nixpkgs.follows = "nixpkgs";
nixos-wsl = {
url = "github:nix-community/NixOS-WSL";
inputs.nixpkgs.follows = "nixpkgs";
};
fenix.url = "github:nix-community/fenix";
fenix.inputs.nixpkgs.follows = "nixpkgs";
# Flake organization tools
# keep-sorted start block=yes
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
haumea = {
url = "github:nix-community/haumea/v0.2.2";
inputs.nixpkgs.follows = "nixpkgs";
};
infuse = {
url = "git+https://codeberg.org/amjoseph/infuse.nix";
flake = false;
};
# keep-sorted end
# Useful modules
# keep-sorted start block=yes
catppuccin = {
url = "github:catppuccin/nix";
inputs.nixpkgs.follows = "nixpkgs";
};
impermanence.url = "github:nix-community/impermanence";
# TODO: sops-nix: remove pr patch once merged
# https://github.com/Mic92/sops-nix/pull/779
sops-nix = {
url = "github:Mic92/sops-nix/pull/779/merge";
inputs.nixpkgs.follows = "nixpkgs";
};
stylix = {
url = "github:danth/stylix";
inputs.nixpkgs.follows = "nixpkgs";
};
system76-scheduler-niri = {
url = "github:Kirottu/system76-scheduler-niri";
inputs.nixpkgs.follows = "nixpkgs";
};
# keep-sorted end
# Useful software
# keep-sorted start block=yes
angrr = {
url = "github:linyinfeng/angrr";
inputs.nixpkgs.follows = "nixpkgs";
};
darkly = {
url = "github:Bali10050/Darkly";
inputs.nixpkgs.follows = "nixpkgs";
};
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
go-musicfox = {
url = "github:imxyy1soope1/go-musicfox";
inputs.nixpkgs.follows = "nixpkgs";
};
niri.url = "github:sodiboo/niri-flake";
noctalia = {
url = "github:noctalia-dev/noctalia-shell/v4.5.0";
inputs.nixpkgs.follows = "nixpkgs";
};
zen.inputs.nixpkgs.follows = "nixpkgs";
zen.url = "github:0xc000022070/zen-browser-flake";
# keep-sorted end
# Misc
treefmt = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
plant = {
url = "git+ssh://git@git.imxyy.top:2222/imxyy1soope1/HF-plant.git?rev=08dc0b3889797eb3618c7475c3c367ec0e5fdf40";
flake = false;
};
my-templates.url = "git+https://git.imxyy.top/imxyy1soope1/flake-templates";
};
outputs =
{
self,
nixpkgs,
nixos-wsl,
flake-parts,
...
}@inputs:
let
inherit (self) outputs;
variables = import ./variables.nix;
forAllSystems = nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed;
forAllHosts =
gen:
nixpkgs.lib.attrsets.mergeAttrsList (
builtins.map (
{ hostname, ... }@host:
flake-parts.lib.mkFlake
{
${hostname} = gen host;
inherit inputs;
specialArgs.lib = import ./lib {
inherit (inputs.nixpkgs) lib;
inherit inputs;
};
}
) variables.hosts
);
in
{
packages = forAllSystems (system: import ./pkgs nixpkgs.legacyPackages.${system});
formatter = forAllSystems (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
pkgs.writeShellApplication {
name = "nixfmt-wrapper";
systems = [ "x86_64-linux" ];
runtimeInputs = [
pkgs.fd
pkgs.nixfmt-rfc-style
imports = [
./flake/hosts.nix
./flake/pkgs.nix
./treefmt.nix
./overlays
];
text = ''
fd "$@" -t f -e nix -x nixfmt '{}'
'';
}
);
overlays = import ./overlays { inherit inputs; };
# Available through 'nixos-rebuild --flake .#{hostname}'
nixosConfigurations = forAllHosts (
{ hostname, system }:
let
lib = import ./lib/stdlib-extended.nix (
nixpkgs.lib.extend (
final: prev: {
inherit (inputs.home-manager.lib) hm;
}
)
);
overlays = builtins.attrValues self.overlays ++ [
inputs.go-musicfox.overlays.default
inputs.omz.overlays.default
inputs.dwm.overlays.default
inputs.niri.overlays.niri
# inputs.neovim-nightly.overlays.default
inputs.fenix.overlays.default
inputs.nix-vscode-extensions.overlays.default
(final: prev: {
darkly-qt5 = inputs.darkly.packages.${final.system}.darkly-qt5;
darkly-qt6 = inputs.darkly.packages.${final.system}.darkly-qt6;
})
(final: prev: {
quickshell = inputs.quickshell.packages.${final.system}.default.override {
withJemalloc = true;
withQtSvg = true;
withWayland = true;
withPipewire = false;
withPam = false;
withX11 = false;
withHyprland = false;
nixosHosts = {
imxyy-nix = {
profiles = [ "desktop" ];
};
})
];
pkgs = import nixpkgs {
inherit system overlays;
config.allowUnfree = true;
};
specialArgs = {
inherit (variables)
username
userdesc
userfullname
useremail
;
inherit
inputs
outputs
nixos-wsl
system
hostname
;
sopsRoot = ./secrets;
imxyy-nix-server = {
profiles = [ "server" ];
};
in
lib.nixosSystem {
inherit specialArgs;
imxyy-nix-wsl = {
profiles = [ "wsl" ];
modules = [
./modules
./config/base.nix
./config/hosts/${hostname}
{
nixpkgs = {
inherit pkgs;
inputs.nixos-wsl.nixosModules.default
];
};
}
inputs.sops-nix.nixosModules.sops
inputs.impermanence.nixosModules.impermanence
inputs.home-manager.nixosModules.default
{
home-manager = {
sharedModules = [
inputs.sops-nix.homeManagerModules.sops
inputs.impermanence.nixosModules.home-manager.impermanence
inputs.stylix.homeManagerModules.stylix
inputs.niri.homeModules.niri
(
{ lib, ... }:
{
nixpkgs.overlays = lib.mkForce null;
}
)
];
useGlobalPkgs = true;
};
}
];
}
);
imxyy-nix-x16 = {
profiles = [ "desktop" ];
};
};
};
}

144
flake/hosts.nix Normal file
View File

@@ -0,0 +1,144 @@
{
self,
lib,
inputs,
withSystem,
config,
pkgsParams,
...
}:
let
vars = import ../vars.nix;
pkgsModule = {
nixpkgs = pkgsParams;
};
hmModule = {
home-manager = {
sharedModules = [
# keep-sorted start
inputs.noctalia.homeModules.default
inputs.sops-nix.homeManagerModules.sops
inputs.stylix.homeModules.stylix
inputs.system76-scheduler-niri.homeModules.default
inputs.zen.homeModules.beta
# keep-sorted end
{
stylix.overlays.enable = lib.mkForce false;
}
];
useGlobalPkgs = true;
};
};
in
{
options.nixosHosts = lib.mkOption {
type = lib.types.attrsOf (
lib.types.submodule (
{ name, ... }:
{
options = {
system = lib.mkOption {
type = lib.types.str;
default = "x86_64-linux";
description = "System architecture";
};
profiles = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "List of profile names (e.g., 'desktop', 'server', 'wsl')";
};
modules = lib.mkOption {
type = lib.types.listOf lib.types.deferredModule;
default = (
lib.umport {
paths = [ ../hosts/${name} ];
extraExcludePredicate = path: lib.hasInfix "/_" (toString path);
recursive = true;
}
);
description = "Additional NixOS modules specific to this host";
};
extraSpecialArgs = lib.mkOption {
type = lib.types.attrs;
default = { };
description = "Extra special arguments to pass to modules";
};
};
}
)
);
default = { };
description = "Declarative host definitions";
};
config = {
# Generate nixosConfigurations from declarative host definitions
flake.nixosConfigurations = lib.mapAttrs (
hostname: hostConfig:
withSystem hostConfig.system (
{ ... }:
lib.nixosSystem {
inherit (hostConfig) system;
specialArgs = {
inherit
inputs
self
hostname
;
assets =
with lib.haumea;
load {
src = ../assets;
loader = [ (matchers.always loaders.path) ];
};
secrets =
with lib.haumea;
load {
src = ../secrets;
loader = [ (matchers.always loaders.path) ];
};
}
// vars
// hostConfig.extraSpecialArgs;
modules =
# Automatically import all feature modules
(lib.umport {
paths = [ ../modules ];
extraExcludePredicate = path: lib.hasInfix "/_" (toString path);
recursive = true;
})
++ [
# Base profile (always included)
../profiles/base.nix
]
# Add requested profiles
++ (map (profile: ../profiles/${profile}.nix) hostConfig.profiles)
# Add host-specific modules
++ hostConfig.modules
++ [
(lib.mkAliasOptionModule [ "my" "hm" ] [ "home-manager" "users" vars.username ])
# Upstream modules
# keep-sorted start
inputs.angrr.nixosModules.angrr
inputs.catppuccin.nixosModules.catppuccin
inputs.home-manager.nixosModules.default
inputs.impermanence.nixosModules.impermanence
inputs.niri.nixosModules.niri
inputs.sops-nix.nixosModules.sops
# keep-sorted end
# pkgs and home-manager configuration
pkgsModule
hmModule
];
}
)
) config.nixosHosts;
};
}

55
flake/pkgs.nix Normal file
View File

@@ -0,0 +1,55 @@
{
inputs,
lib,
config,
pkgsParams,
...
}:
{
_module.args = {
pkgsParams = {
overlays = builtins.attrValues config.flake.overlays ++ [
inputs.go-musicfox.overlays.default
inputs.niri.overlays.niri
inputs.fenix.overlays.default
inputs.angrr.overlays.default
(final: prev: {
darkly-qt5 = inputs.darkly.packages.${final.stdenv.hostPlatform.system}.darkly-qt5;
darkly-qt6 = inputs.darkly.packages.${final.stdenv.hostPlatform.system}.darkly-qt6;
noctalia-shell = inputs.noctalia.packages.${final.stdenv.hostPlatform.system}.default;
})
];
config.allowUnfree = true;
flake.setNixPath = false;
};
};
perSystem =
{
system,
pkgs,
...
}:
{
_module.args.pkgs = import inputs.nixpkgs (pkgsParams // { inherit system; });
legacyPackages = pkgs;
packages = lib.genAttrs (builtins.attrNames (config.flake.overlays.additions pkgs pkgs)) (
pkg: pkgs.${pkg}
);
};
flake.overlays.additions =
final: prev:
with lib.haumea;
load {
src = ../pkgs;
loader = [
{
matches = str: builtins.match ".*\\.nix" str != null;
loader = _: path: final.callPackage path { };
}
];
transformer = transformers.liftDefault;
};
}

View File

@@ -0,0 +1,42 @@
{
lib,
config,
pkgs,
secrets,
hosts,
...
}:
{
sops.secrets.et-imxyy-nix-server-nixremote = {
sopsFile = secrets.et-imxyy-nix-server-nixremote;
restartUnits = [ "easytier-nixremote.service" ];
format = "binary";
};
environment.systemPackages = [ pkgs.easytier ];
systemd.services."easytier-nixremote" = {
enable = true;
script = "${pkgs.easytier}/bin/easytier-core -c ${config.sops.secrets.et-imxyy-nix-server-nixremote.path}";
serviceConfig = {
Restart = "always";
RestartSec = 30;
User = "root";
};
wantedBy = [ "multi-user.target" ];
after = [
"network.target"
"sops-nix.service"
];
};
users.groups.nixremote = { };
users.users.nixremote = {
isSystemUser = true;
description = "nix remote build user";
group = "nixremote";
openssh.authorizedKeys.keys = (lib.mapAttrsToList (host: key: "${key} ${host}") hosts) ++ [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIENauvvhVMLsUwH9cPYsvnOg7VCL3a4yEiKm8I524TE efl@efl-nix"
];
};
nix.settings.trusted-users = [
"nixremote"
];
}

View File

@@ -1,4 +1,3 @@
{ ... }:
{
services.caddy = {
enable = true;

View File

@@ -0,0 +1,15 @@
{
services.coder = {
enable = true;
accessUrl = "https://coder.imxyy.top";
listenAddress = "127.0.0.1:8086";
};
users.users.coder.extraGroups = [ "podman" ];
services.caddy.virtualHosts."coder.imxyy.top" = {
extraConfig = ''
reverse_proxy :8086 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -5,5 +5,10 @@
enable = true;
dockerCompat = true;
dockerSocket.enable = true;
defaultNetwork.settings.dns_enabled = true;
};
# avoid collision with dnsmasq
virtualisation.containers = {
containersConf.settings.network.dns_bind_port = 5353;
};
}

View File

@@ -0,0 +1,56 @@
{ config, secrets, ... }:
{
sops.secrets.efl-tuwunel-env = {
sopsFile = secrets.efl-tuwunel;
restartUnits = [ "podman-tuwunel.service" ];
format = "dotenv";
};
virtualisation.oci-containers.containers = {
tuwunel = {
image = "ghcr.io/matrix-construct/tuwunel:latest";
volumes = [
"tuwunel_db:/var/lib/tuwunel"
];
ports = [ "6167:6167" ];
networks = [ "podman" ];
extraOptions = [ "--pids-limit=-1" ];
environment = {
TUWUNEL_SERVER_NAME = "mtx.eflx.top";
TUWUNEL_PORT = "6167";
TUWUNEL_ADDRESS = "0.0.0.0";
TUWUNEL_WELL_KNOWN__SERVER = "mtx.eflx.top:443";
TUWUNEL_WELL_KNOWN__CLIENT = "https://mtx.eflx.top";
};
environmentFiles = [
config.sops.secrets.efl-tuwunel-env.path
];
};
mautrix-telegram = {
image = "dock.mau.dev/mautrix/telegram:latest";
ports = [ "8099:8099" ];
networks = [ "podman" ];
extraOptions = [ "--ip=10.88.0.254" ];
volumes = [ "/var/lib/efl-mautrix-telegram:/data" ];
};
send = {
image = "lanol/filecodebox:latest";
ports = [ "12345:12345" ];
volumes = [ "/var/lib/send:/app/data:rw" ];
};
};
services.caddy.virtualHosts."mtx.eflx.top" = {
extraConfig = ''
reverse_proxy :6167 {
header_up X-Real-IP {remote_host}
}
'';
};
services.caddy.virtualHosts."send.eflx.top" = {
extraConfig = ''
reverse_proxy :12345 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -1,4 +1,3 @@
{ ... }:
{
services.caddy.virtualHosts."git.imxyy.top" = {
extraConfig = ''

View File

@@ -4,7 +4,9 @@
pkgs,
...
}:
let
btrfs = "/dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0";
in
{
boot.initrd.availableKernelModules = [
"xhci_pci"
@@ -16,11 +18,12 @@
];
boot.initrd.kernelModules = [ "amdgpu" ];
boot.kernelModules = [ "kvm-amd" ];
boot.kernelPackages = lib.mkForce pkgs.stable.linuxKernel.packages.linux_zen;
boot.kernelPackages = lib.mkForce pkgs.linuxPackages_xanmod_stable;
boot.extraModulePackages = [ ];
boot.tmp.useTmpfs = true;
boot.supportedFilesystems = [ "zfs" ];
boot.zfs = {
package = pkgs.zfs_unstable;
extraPools = [ "data" ];
forceImportRoot = false;
};
@@ -29,7 +32,7 @@
networking.hostId = "10ca95b4";
fileSystems."/" = {
device = "/dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0";
device = btrfs;
fsType = "btrfs";
options = [
"compress=zstd"
@@ -38,7 +41,7 @@
};
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0";
device = btrfs;
fsType = "btrfs";
options = [
"compress=zstd"
@@ -46,8 +49,9 @@
];
};
fileSystems."/persistent" = {
device = "/dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0";
my.persist.location = "/nix/persist";
fileSystems."/nix/persist" = {
device = btrfs;
fsType = "btrfs";
options = [
"compress=zstd"
@@ -58,7 +62,7 @@
boot.initrd.postDeviceCommands = lib.mkAfter ''
mkdir /btrfs_tmp
mount /dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0 /btrfs_tmp
mount ${btrfs} /btrfs_tmp
mkdir -p /btrfs_tmp/old_roots
if [[ -e /btrfs_tmp/root ]]; then
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S")
@@ -84,6 +88,12 @@
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/32AA-2998";
fsType = "vfat";
options = [
"uid=0"
"gid=0"
"fmask=0077"
"dmask=0077"
];
};
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking

View File

@@ -0,0 +1,25 @@
{ lib, ... }:
{
my = {
cli.all.enable = true;
cli.media.all.enable = lib.mkForce false;
coding.editor.neovim.enable = true;
coding.misc.enable = true;
coding.langs.lua.enable = true;
coding.langs.rust.enable = true;
coding.langs.js.enable = true;
fonts.enable = lib.mkForce false;
persist = {
enable = true;
homeDirs = [
"workspace"
"Virt"
".local/state"
".cache"
".ollama"
];
};
};
}

View File

@@ -0,0 +1,14 @@
{
virtualisation.oci-containers.containers.sun-panel = {
image = "hslr/sun-panel:latest";
volumes = [
"/var/lib/sun-panel:/app/conf"
];
ports = [ "8085:3002" ];
};
services.caddy.virtualHosts."home.imxyy.top" = {
extraConfig = ''
reverse_proxy :8085
'';
};
}

View File

@@ -0,0 +1,21 @@
{ ... }:
{
users.users.immich = {
home = "/mnt/nas/immich";
createHome = true;
};
services.immich = {
enable = true;
host = "127.0.0.1";
port = 8096;
mediaLocation = "/mnt/nas/immich";
group = "nextcloud";
};
services.caddy.virtualHosts."immich.imxyy.top" = {
extraConfig = ''
reverse_proxy :8096 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -0,0 +1,107 @@
{
config,
secrets,
...
}:
{
nixpkgs.config.permittedInsecurePackages = [
"olm-3.2.16"
];
sops.secrets.tuwunel-reg-token = {
sopsFile = secrets.tuwunel-reg-token;
restartUnits = [ "tuwunel.service" ];
format = "binary";
owner = config.services.matrix-tuwunel.user;
group = config.services.matrix-tuwunel.group;
};
sops.secrets.tuwunel-turn-secret = {
sopsFile = secrets.tuwunel-turn-secret;
restartUnits = [ "tuwunel.service" ];
format = "binary";
owner = config.services.matrix-tuwunel.user;
group = config.services.matrix-tuwunel.group;
};
services.matrix-tuwunel = {
enable = true;
settings.global = {
address = [ "127.0.0.1" ];
port = [ 8094 ];
server_name = "imxyy.top";
well_known = {
server = "matrix.imxyy.top:443";
client = "https://matrix.imxyy.top";
};
allow_registration = true;
registration_token_file = config.sops.secrets.tuwunel-reg-token.path;
suppress_push_when_active = true;
turn_uris = [
"turn:hk.vkvm.imxyy.top?transport=udp"
"turn:hk.vkvm.imxyy.top?transport=tcp"
];
turn_secret_file = config.sops.secrets.tuwunel-turn-secret.path;
new_user_displayname_suffix = "";
};
};
services.caddy.virtualHosts."imxyy.top" = {
extraConfig = ''
handle /.well-known/matrix/server {
header Content-Type application/json
header "Access-Control-Allow-Origin" "*"
respond `{"m.server": "matrix.imxyy.top:443"}` 200
}
handle /.well-known/matrix/client {
header Content-Type application/json
header "Access-Control-Allow-Origin" "*"
respond `{"m.homeserver": {"base_url": "https://matrix.imxyy.top/"}}` 200
}
'';
};
services.caddy.virtualHosts."matrix.imxyy.top" = {
extraConfig = ''
reverse_proxy :8094
'';
};
sops.secrets.mautrix-telegram = {
sopsFile = secrets.mautrix-telegram;
restartUnits = [ "mautrix-telegram.service" ];
format = "dotenv";
owner = "mautrix-telegram";
group = "mautrix-telegram";
};
services.mautrix-telegram = {
enable = true;
environmentFile = config.sops.secrets.mautrix-telegram.path;
settings = {
homeserver = {
address = "http://127.0.0.1:8094";
domain = "imxyy.top";
};
appservice = {
address = "http://127.0.0.1:8098";
hostname = "127.0.0.1";
port = "8098";
bot_username = "telegrambot";
};
bridge = {
username_template = "telegram_{userid}";
alias_template = "telegram_{groupname}";
displayname_template = "{displayname} (Telegram)";
permissions = {
"@imxyy_soope_:imxyy.top" = "admin";
};
};
telegram = {
# borrowed from https://github.com/telegramdesktop/tdesktop/blob/9bdc19e2fd4d497c8f403891848383a88faadc25/snap/snapcraft.yaml#L134-L135
api_id = "611335";
api_hash = "d524b414d21f4d37f08684c1df41ac9c";
};
};
};
}

View File

@@ -8,9 +8,10 @@
WorkingDirectory = "/opt/minecraft/fabric1.20.6";
ExecStart = "${lib.getExe' pkgs.openjdk21 "java"} -Xms1G -Xmx5G -jar fabric-server-mc.1.20.6-loader.0.15.11-launcher.1.0.1.jar";
Restart = "always";
RestartSec = "10s";
RestartSec = 120;
};
};
my.persist = {
nixosDirs = [
"/opt/minecraft"

View File

@@ -1,7 +1,8 @@
{ config, sopsRoot, ... }:
{ config, secrets, ... }:
{
sops.secrets.minio-env = {
sopsFile = sopsRoot + /minio.env;
sopsFile = secrets.minio;
restartUnits = [ "minio.service" ];
format = "dotenv";
};
services.minio = {
@@ -16,11 +17,4 @@
];
rootCredentialsFile = config.sops.secrets.minio-env.path;
};
services.caddy.virtualHosts."minio.imxyy.top" = {
extraConfig = ''
handle_path /* {
reverse_proxy :9000
}
'';
};
}

View File

@@ -0,0 +1,511 @@
{
config,
lib,
pkgs,
username,
hosts,
secrets,
...
}:
{
boot.kernelParams = [
"biosdevname=0"
"net.ifnames=0"
];
networking = {
useDHCP = lib.mkForce false;
dhcpcd = {
wait = "background";
IPv6rs = true;
extraConfig = ''
interface mac0
noipv4
'';
};
interfaces = {
eth0.wakeOnLan.enable = true;
eth1.wakeOnLan.enable = true;
mac0 = {
useDHCP = true;
ipv4.addresses = [
{
address = "192.168.3.2";
prefixLength = 24;
}
];
};
};
macvlans."mac0" = {
interface = "eth0";
mode = "bridge";
};
defaultGateway = {
address = "192.168.3.1";
interface = "mac0";
};
nameservers = [
"192.168.3.2"
];
firewall.enable = false;
nftables = {
enable = true;
flushRuleset = true;
ruleset = ''
table inet firewall {
set LANv4 {
type ipv4_addr
flags interval
elements = { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 }
}
set LANv6 {
type ipv6_addr
flags interval
elements = { fd00::/8, fe80::/10 }
}
set tcp_ports {
type inet_service
flags interval
elements = {
http,
https,
2222,
25565
}
}
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
ip daddr @LANv4 accept
ip6 daddr @LANv6 accept
}
chain output {
type filter hook output priority 100; policy accept;
ip daddr @LANv4 accept
ip6 daddr @LANv6 accept
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state invalid drop
ct state established,related accept
ip protocol { icmp, igmp } accept
ip saddr @LANv4 accept
ip6 saddr @LANv6 accept
tcp dport 2222 ct state new limit rate 15/minute counter accept
tcp dport @tcp_ports counter accept
}
chain forward {
type filter hook forward priority 0; policy accept;
}
chain nat {
type nat hook postrouting priority 0; policy accept;
ip saddr 192.168.3.0/24 masquerade
}
}
'';
};
};
services.openssh = {
enable = true;
settings = {
# PermitRootLogin = "yes";
PermitRootLogin = "prohibit-password";
PasswordAuthentication = true;
};
};
users.users.root.openssh.authorizedKeys.keys = lib.mapAttrsToList (
host: key: "${key} ${host}"
) hosts;
users.users.${username}.openssh.authorizedKeys.keys = lib.mapAttrsToList (
host: key: "${key} ${host}"
) hosts;
sops.secrets.dae-imxyy-nix-server = {
sopsFile = secrets.dae-imxyy-nix-server;
restartUnits = [ "dae.service" ];
format = "binary";
};
services.dae = {
enable = true;
configFile = config.sops.secrets.dae-imxyy-nix-server.path;
};
systemd.services.dae = {
after = [ "sops-nix.service" ];
serviceConfig.MemoryMax = "1G";
};
sops.secrets.mihomo = {
sopsFile = secrets.mihomo;
restartUnits = [ "mihomo.service" ];
format = "yaml";
key = "";
};
systemd.services.mihomo.after = [ "sops-nix.service" ];
services.mihomo = {
enable = true;
configFile = config.sops.secrets.mihomo.path;
webui = pkgs.metacubexd;
};
sops.secrets.frp-env = {
sopsFile = secrets.frp;
restartUnits = [ "frp.service" ];
format = "dotenv";
};
systemd.services.frp.serviceConfig.EnvironmentFile = [
config.sops.secrets.frp-env.path
];
services.frp = {
instances."" = {
enable = true;
role = "client";
settings = {
serverAddr = "{{ .Envs.FRP_SERVER_ADDR }}";
serverPort = 7000;
auth.token = "{{ .Envs.FRP_AUTH_TOKEN }}";
proxies = [
{
name = "nextcloud-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "nextcloud.imxyy.top" ];
}
{
name = "nextcloud-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "nextcloud.imxyy.top" ];
}
{
name = "oidc-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "oidc.imxyy.top" ];
}
{
name = "oidc-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "oidc.imxyy.top" ];
}
{
name = "mail-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "mail.imxyy.top" ];
}
{
name = "mail-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "mail.imxyy.top" ];
}
{
name = "gitea-ssh";
type = "tcp";
localIP = "127.0.0.1";
localPort = 2222;
remotePort = 2222;
}
{
name = "gitea-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "git.imxyy.top" ];
}
{
name = "gitea-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "git.imxyy.top" ];
}
{
name = "vault-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "vault.imxyy.top" ];
}
{
name = "vault-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "vault.imxyy.top" ];
}
{
name = "home-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "home.imxyy.top" ];
}
{
name = "home-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "home.imxyy.top" ];
}
{
name = "coder-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "coder.imxyy.top" ];
}
{
name = "coder-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "coder.imxyy.top" ];
}
{
name = "siyuan-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "sy.imxyy.top" ];
}
{
name = "siyuan-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "sy.imxyy.top" ];
}
{
name = "matrix-root-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "imxyy.top" ];
}
{
name = "matrix-root-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "imxyy.top" ];
}
{
name = "matrix-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "matrix.imxyy.top" ];
}
{
name = "matrix-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "matrix.imxyy.top" ];
}
{
name = "immich-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "immich.imxyy.top" ];
}
{
name = "immich-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "immich.imxyy.top" ];
}
{
name = "memo-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "memo.imxyy.top" ];
}
{
name = "memo-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "memo.imxyy.top" ];
}
{
name = "efl-matrix-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "mtx.eflx.top" ];
}
{
name = "efl-matrix-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "mtx.eflx.top" ];
}
{
name = "efl-send-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "send.eflx.top" ];
}
{
name = "efl-send-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "send.eflx.top" ];
}
];
};
};
};
sops.secrets.et-imxyy-nix-server = {
sopsFile = secrets.et-imxyy-nix-server;
restartUnits = [ "easytier.service" ];
format = "binary";
};
environment.systemPackages = [ pkgs.easytier ];
systemd.services."easytier" = {
enable = true;
script = "${pkgs.easytier}/bin/easytier-core -c ${config.sops.secrets.et-imxyy-nix-server.path}";
serviceConfig = {
Restart = "always";
RestartSec = 30;
User = "root";
};
wantedBy = [ "multi-user.target" ];
after = [
"network.target"
"sops-nix.service"
];
};
virtualisation.oci-containers.containers.obligator = {
image = "anderspitman/obligator:latest";
volumes = [
"/var/lib/obligator:/data"
"/var/lib/obligator:/api"
];
ports = [ "8081:1616" ];
cmd = [
"-storage-dir"
"/data"
"-api-socket-dir"
"/api"
"-root-uri"
"https://oidc.imxyy.top"
"-port"
"1616"
];
};
services.caddy.virtualHosts."oidc.imxyy.top" = {
extraConfig = ''
reverse_proxy :8081 {
header_up X-Real-IP {remote_host}
}
'';
};
systemd.services.ddns-go =
let
version = "6.6.7";
ddns-go = pkgs.buildGoModule {
inherit version;
pname = "ddns-go";
src = pkgs.fetchFromGitHub {
owner = "jeessy2";
repo = "ddns-go";
rev = "v${version}";
hash = "sha256-Ejoe6e9GFhHxQ9oIBDgDRQW9Xx1XZK+qSAXiRXLdn+c=";
};
meta.mainProgram = "ddns-go";
vendorHash = "sha256-XZii7gV3DmTunYyGYzt5xXhv/VpTPIoYKbW4LnmlAgs=";
doCheck = false;
};
in
{
description = "Go Dynamic DNS";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${lib.getExe ddns-go} -l :9876 -f 10 -cacheTimes 180 -c /var/lib/ddns-go/config.yaml";
Restart = "always";
RestartSec = 120;
};
path = [
pkgs.bash
];
};
services.dnsmasq =
let
subDomains = [
"home"
"nextcloud"
"mail"
"git"
"vault"
"coder"
"matrix"
"note"
"oidc"
"mc"
"music"
"sy"
"immich"
];
in
{
enable = true;
resolveLocalQueries = false;
settings = {
no-resolv = true;
server = [ "192.168.3.1" ];
address = map (sub: "/${sub}.imxyy.top/192.168.3.2") subDomains ++ [
"/imxyy-nix-server/192.168.3.2"
"/imxyy-cloudwin/192.168.3.4"
"/printer.home/192.168.3.53"
];
cache-size = 0;
log-queries = "extra";
};
};
}

View File

@@ -17,9 +17,9 @@ in
services.nextcloud = {
enable = true;
package = pkgs.nextcloud31;
package = pkgs.nextcloud32;
extraApps = {
inherit (pkgs.nextcloud31.packages.apps)
inherit (pkgs.nextcloud32.packages.apps)
bookmarks
previewgenerator
spreed
@@ -31,20 +31,26 @@ in
hostName = nextcloud;
home = "/mnt/nas/nextcloud";
https = true;
nginx.recommendedHttpHeaders = true;
caching.redis = true;
configureRedis = true;
database.createLocally = true;
notify_push.enable = true;
config = {
dbtype = "pgsql";
adminpassFile = toString (pkgs.writeText "nextcloud-pass" "admin12345!");
adminuser = "admin";
};
settings.trusted_domains = [
settings = {
trusted_domains = [
hostname
"192.168.3.2"
"10.0.0.1"
];
trusted_proxies = [
"127.0.0.1"
"192.168.3.0/24"
];
};
phpExtraExtensions =
all: with all; [
pdlib
@@ -53,7 +59,7 @@ in
phpOptions = {
"opcache.enable" = 1;
"opcache.enable_cli" = 1;
"opcache.interned_strings_buffer" = 8;
"opcache.interned_strings_buffer" = 23;
"opcache.max_accelerated_files" = 10000;
"opcache.memory_consumption" = 128;
"opcache.save_comments" = 1;
@@ -94,9 +100,12 @@ in
*/
services.caddy.virtualHosts."nextcloud.imxyy.top" = {
extraConfig = ''
reverse_proxy :8084 {
header_up X-Real-IP {remote_host}
reverse_proxy http://127.0.0.1:8084 {
trusted_proxies 192.168.3.0/24
}
redir /.well-known/carddav /remote.php/dav/ 301
redir /.well-known/caldav /remote.php/dav/ 301
'';
};

View File

@@ -1,4 +1,3 @@
{ ... }:
{
services.nginx = {
enable = true;

View File

@@ -0,0 +1,17 @@
{
lib,
config,
username,
secrets,
...
}:
{
sops.secrets.imxyy-nix-server-hashed-password = {
sopsFile = secrets.imxyy-nix-server-hashed-password;
format = "binary";
neededForUsers = true;
};
users.users.${username}.hashedPasswordFile =
lib.mkForce config.sops.secrets.imxyy-nix-server-hashed-password.path;
users.users.root.hashedPasswordFile = lib.mkForce config.sops.secrets.imxyy-nix-server-hashed-password.path;
}

View File

@@ -0,0 +1,51 @@
{
config,
secrets,
...
}:
{
sops.secrets.siyuan-env = {
sopsFile = secrets.siyuan;
restartUnits = [ "siyuan.service" ];
format = "dotenv";
};
virtualisation.oci-containers.containers = {
siyuan = {
image = "apkdv/siyuan-unlock:v3.1.30";
volumes = [
"/mnt/nas/siyuan/workspace:/workspace"
"/mnt/nas/siyuan:/home/siyuan"
];
cmd = [
"--workspace=/workspace"
];
environment = {
PUID = "0";
PGID = "0";
};
environmentFiles = [
"${config.sops.secrets.siyuan-env.path}"
];
ports = [ "8095:6806" ];
};
memos = {
image = "neosmemo/memos:stable";
volumes = [
"/mnt/nas/memos:/var/opt/memos"
];
ports = [ "8097:5230" ];
};
};
services.caddy.virtualHosts = {
"sy.imxyy.top" = {
extraConfig = ''
reverse_proxy :8095
'';
};
"memo.imxyy.top" = {
extraConfig = ''
reverse_proxy :8097
'';
};
};
}

View File

@@ -0,0 +1,74 @@
{
inputs,
pkgs,
lib,
...
}:
let
app = pkgs.buildNpmPackage (finalAttrs: {
pname = "HF-plant";
version = "unstable-2025-09-21";
src = inputs.plant;
buildPhase = ''
runHook preBuild
npm run build
npm run build:proxy
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir $out
mv dist $out
cp .env proxy-server-bundled.js $out
runHook postInstall
'';
npmDepsHash = "sha256-ret4BtjrEt8L1nlvJmFiejAKmbz89Z7NSiKs+qlB51w=";
});
in
{
systemd.services.HF-plant-proxy = {
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${lib.getExe pkgs.bash} -c 'source ${app}/.env; export FEISHU_APP_ID FEISHU_APP_SECRET AMAP_JSCODE; ${lib.getExe pkgs.nodejs} ${app}/proxy-server-bundled.js'";
Restart = "always";
RestartSec = 120;
};
};
services.caddy.virtualHosts."plant.imxyy.top" = {
extraConfig = ''
handle /api/* {
reverse_proxy localhost:3001
}
handle /* {
root * ${app}/dist
try_files {path} /index.html
file_server
}
'';
};
services.frp.instances."".settings.proxies = [
{
name = "plant-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "plant.imxyy.top" ];
}
{
name = "plant-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "plant.imxyy.top" ];
}
];
}

View File

@@ -0,0 +1,55 @@
{ config, secrets, ... }:
let
redisUrl = config.services.redis.servers.rsshub.unixSocket;
in
{
sops.secrets.rsshub-env = {
sopsFile = secrets.rsshub;
restartUnits = [ "podman-rsshub.service" ];
format = "dotenv";
};
users.users.rsshub = {
home = "/var/empty";
group = "rsshub";
isSystemUser = true;
};
users.groups.rsshub.members = [ "rsshub" ];
services.redis.servers.rsshub = {
enable = true;
user = "rsshub";
};
virtualisation.oci-containers.containers.rsshub = {
image = "diygod/rsshub";
volumes = [
"${redisUrl}:${redisUrl}"
];
ports = [ "8100:1200" ];
networks = [ "podman" ];
environment = {
CACHE_TYPE = "redis";
REDIS_URL = "${redisUrl}";
};
environmentFiles = [ config.sops.secrets.rsshub-env.path ];
};
services.caddy.virtualHosts."rss.imxyy.top" = {
extraConfig = ''
reverse_proxy :8100
'';
};
services.frp.instances."".settings.proxies = [
{
name = "rsshub-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "rss.imxyy.top" ];
}
{
name = "rsshub-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "rss.imxyy.top" ];
}
];
}

View File

@@ -1,4 +1,3 @@
{ ... }:
{
services.samba = {
enable = true;
@@ -10,7 +9,7 @@
};
share = {
path = "/mnt/nas/share";
browseable = "yes";
browsable = "yes";
"read only" = "no";
"guest ok" = "no";
"create mask" = "0664";
@@ -27,9 +26,8 @@
];
users = {
users.nas = {
isNormalUser = true;
home = "/var/empty";
description = "nas user";
isSystemUser = true;
description = "NAS user";
group = "nextcloud";
};
};

View File

@@ -0,0 +1,49 @@
{ config, secrets, ... }:
{
sops.secrets.sshwifty = {
sopsFile = secrets.sshwifty;
format = "binary";
};
services.sshwifty = {
enable = true;
sharedKeyFile = config.sops.secrets.sshwifty.path;
settings = {
Servers = [
{
ListenInterface = "0.0.0.0";
ListenPort = 8101;
InitialTimeout = 10;
ReadTimeout = 120;
WriteTimeout = 120;
HeartbeatTimeout = 10;
ReadDelay = 10;
WriteDelay = 10;
TLSCertificateFile = "";
TLSCertificateKeyFile = "";
ServerMessage = "";
}
];
};
};
services.caddy.virtualHosts."ssh.imxyy.top" = {
extraConfig = ''
reverse_proxy :8101
'';
};
services.frp.instances."".settings.proxies = [
{
name = "sshwifty-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "ssh.imxyy.top" ];
}
{
name = "sshwifty-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "ssh.imxyy.top" ];
}
];
}

View File

@@ -1,7 +1,8 @@
{ config, sopsRoot, ... }:
{ config, secrets, ... }:
{
sops.secrets.vaultwarden-env = {
sopsFile = sopsRoot + /vaultwarden.env;
sopsFile = secrets.vaultwarden;
restartUnits = [ "vaultwarden.service" ];
format = "dotenv";
};
services.postgresql.ensureUsers = [

View File

@@ -3,16 +3,17 @@ let
# T400
gpuIDs = [
"8086:56a0" # A770
"8086:4f90"
"10de:1f82" # 1650
"10de:10fa" # 1650
"10de:10fa"
"10de:1fb2" # T400
];
in
{
boot = {
initrd.kernelModules = [
initrd.kernelModules = lib.mkBefore [
"vfio_pci"
"vfio"
"vfio_iommu_type1"
@@ -22,6 +23,10 @@ in
"amd_iommu=on"
"vfio-pci.ids=${lib.concatStringsSep "," gpuIDs}"
];
extraModprobeConfig = ''
options kvm ignore_msrs=Y
options kvm report_ignored_msrs=N
'';
};
virtualisation.spiceUSBRedirection.enable = true;
my.virt.enable = true;

View File

@@ -0,0 +1,19 @@
{ lib, username, ... }:
{
my.hm = {
programs.zsh.shellAliases = {
localproxy_on = "export http_proxy=http://192.168.128.1:7890 https_proxy=http://192.168.128.1:7890 all_proxy=socks://192.168.128.1:7890";
};
programs.fish.shellAliases = {
localproxy_on = "export http_proxy=http://192.168.128.1:7890 https_proxy=http://192.168.128.1:7890 all_proxy=socks://192.168.128.1:7890";
};
};
my = {
sops.sshKeyFile = "/home/${username}/.ssh/id_ed25519";
coding.all.enable = true;
coding.editor.vscode.enable = lib.mkForce false;
cli.misc.enable = true;
xdg.enable = true;
cli.media.all.enable = true;
};
}

View File

@@ -1,10 +1,15 @@
{ username, nixos-wsl, ... }:
{
lib,
username,
inputs,
...
}:
{
imports = [
nixos-wsl.nixosModules.wsl
inputs.nixos-wsl.nixosModules.wsl
];
wsl.enable = true;
wsl.defaultUser = "${username}";
wsl.defaultUser = username;
services.openssh = {
enable = true;
@@ -17,4 +22,6 @@
# fix vscode remote
programs.nix-ld.enable = true;
nixpkgs.hostPlatform = lib.mkForce "x86_64-linux";
}

View File

@@ -0,0 +1,104 @@
{
config,
lib,
pkgs,
...
}:
let
btrfs = "/dev/disk/by-uuid/69ab72d4-6ced-4f70-8b5e-aa2daa8c0b6b";
in
{
boot = {
initrd = {
kernelModules = [ "amdgpu" ];
availableKernelModules = [
"nvme"
"xhci_pci"
"thunderbolt"
"uas"
"sd_mod"
];
verbose = false;
};
kernelPackages = lib.mkForce pkgs.linuxPackages_xanmod_latest;
kernelModules = [ "kvm-amd" ];
tmp.useTmpfs = true;
kernel.sysctl = {
"fs.file-max" = 9223372036854775807;
};
};
fileSystems."/" = {
device = btrfs;
fsType = "btrfs";
options = [
"compress=zstd"
"subvol=root"
];
};
fileSystems."/nix" = {
device = btrfs;
fsType = "btrfs";
options = [
"compress=zstd"
"subvol=nix"
];
};
my.persist.location = "/nix/persist";
fileSystems."/nix/persist" = {
device = btrfs;
fsType = "btrfs";
options = [
"compress=zstd"
"subvol=persist"
];
neededForBoot = true;
};
boot.initrd.postDeviceCommands = lib.mkAfter ''
mkdir /btrfs_tmp
mount ${btrfs} /btrfs_tmp
mkdir -p /btrfs_tmp/old_roots
if [[ -e /btrfs_tmp/root ]]; then
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S")
mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp"
fi
delete_subvolume_recursively() {
IFS=$'\n'
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
delete_subvolume_recursively "/btrfs_tmp/$i"
done
btrfs subvolume delete "$1"
}
for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +14); do
delete_subvolume_recursively "$i"
done
btrfs subvolume create /btrfs_tmp/root
umount /btrfs_tmp
'';
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/96D3-93B0";
fsType = "vfat";
options = [
"uid=0"
"gid=0"
"fmask=0077"
"dmask=0077"
];
};
networking.useDHCP = lib.mkDefault false;
hardware.enableRedistributableFirmware = lib.mkDefault true;
hardware.cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware;
nixpkgs.hostPlatform = lib.mkForce "x86_64-linux";
}

View File

@@ -0,0 +1,144 @@
{
config,
pkgs,
username,
...
}:
{
my.hm = {
home.packages = with pkgs; [
localsend
wpsoffice-cn
wps-office-fonts
ttf-wps-fonts
papers
anki
ayugram-desktop
signal-desktop-wayland
element-desktop
fractal
qq-wayland
wechat
gnome-clocks
];
programs.zsh = {
sessionVariables = {
PATH = "/home/${username}/bin:$PATH";
};
};
programs.fish.interactiveShellInit = ''
set -gp PATH $HOME/bin
'';
programs.niri.settings = {
environment.STEAM_FORCE_DESKTOPUI_SCALING = "1.25";
outputs = {
eDP-1 = {
enable = true;
mode = {
width = 1920;
height = 1200;
refresh = 60.002;
};
scale = 1.25;
};
};
};
};
my = {
gpg.enable = true;
cli.all.enable = true;
coding.all.enable = true;
desktop.all.enable = true;
virt.moonlight.enable = true;
i18n.fcitx5.enable = true;
xdg = {
enable = true;
defaultApplications =
let
browser = [ config.my.desktop.browser.default.desktop ];
editor = [ "nvim.desktop" ];
imageviewer = [ "org.gnome.Loupe.desktop" ];
in
{
"inode/directory" = [ "org.gnome.Nautilus.desktop" ];
"application/pdf" = [ "org.gnome.Papers.desktop" ];
"text/*" = editor;
"application/json" = editor;
"text/xml" = editor;
"application/xml" = editor;
"application/xhtml+xml" = editor;
"application/xhtml_xml" = editor;
"application/rdf+xml" = editor;
"application/rss+xml" = editor;
"application/x-extension-htm" = editor;
"application/x-extension-html" = editor;
"application/x-extension-shtml" = editor;
"application/x-extension-xht" = editor;
"application/x-extension-xhtml" = editor;
"text/html" = browser;
"x-scheme-handler/about" = browser;
"x-scheme-handler/ftp" = browser;
"x-scheme-handler/http" = browser;
"x-scheme-handler/https" = browser;
"x-scheme-handler/unknown" = browser;
"audio/*" = imageviewer;
"video/*" = imageviewer;
"image/*" = imageviewer;
"image/gif" = imageviewer;
"image/jpeg" = imageviewer;
"image/png" = imageviewer;
"image/webp" = imageviewer;
};
};
persist = {
enable = true;
homeDirs = [
"Documents"
"Downloads"
"Videos"
"Music"
"Pictures"
"bin"
"workspace"
".cache"
".local/state"
".local/share/Anki2"
".local/share/shotwell"
".local/share/Kingsoft"
".local/share/AyuGramDesktop"
".local/share/fractal"
".config/Signal"
".config/Element"
".config/QQ"
".xwechat"
".config/Kingsoft"
".config/dconf"
".config/pip"
".config/sunshine"
".gemini"
".claude"
".claude-code-router"
];
homeFiles = [
".claude.json"
];
};
};
}

101
hosts/imxyy-nix-x16/net.nix Normal file
View File

@@ -0,0 +1,101 @@
{
config,
pkgs,
secrets,
...
}:
{
boot.kernelParams = [
"biosdevname=0"
"net.ifnames=0"
];
my.persist.nixosDirs = [ "/etc/NetworkManager/system-connections" ];
networking = {
networkmanager.enable = true;
firewall.enable = false;
nftables = {
enable = true;
flushRuleset = true;
ruleset = ''
table inet firewall {
set LANv4 {
type ipv4_addr
flags interval
elements = { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 }
}
set LANv6 {
type ipv6_addr
flags interval
elements = { fd00::/8, fe80::/10 }
}
chain output {
type filter hook output priority 100; policy accept;
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state invalid drop
ct state established,related accept
ip saddr @LANv4 accept
ip6 saddr @LANv6 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
}
'';
};
};
sops.secrets.dae-imxyy-nix-x16 = {
sopsFile = secrets.dae-imxyy-nix-x16;
restartUnits = [ "dae.service" ];
format = "binary";
};
services.dae = {
enable = true;
configFile = config.sops.secrets.dae-imxyy-nix-x16.path;
};
systemd.services.dae.after = [ "sops-nix.service" ];
sops.secrets.mihomo = {
sopsFile = secrets.mihomo;
restartUnits = [ "mihomo.service" ];
format = "yaml";
key = "";
};
systemd.services.mihomo.after = [ "sops-nix.service" ];
services.mihomo = {
enable = true;
configFile = config.sops.secrets.mihomo.path;
webui = pkgs.metacubexd;
};
sops.secrets.et-imxyy-nix-x16 = {
sopsFile = secrets.et-imxyy-nix-x16;
restartUnits = [ "easytier.service" ];
format = "binary";
};
environment.systemPackages = with pkgs; [
easytier
];
systemd.services."easytier" = {
enable = true;
script = "${pkgs.easytier}/bin/easytier-core -c ${config.sops.secrets.et-imxyy-nix-x16.path}";
serviceConfig = {
Restart = "always";
RestartSec = 30;
User = "root";
};
wantedBy = [ "multi-user.target" ];
after = [
"network.target"
"sops-nix.service"
];
};
}

View File

@@ -0,0 +1,67 @@
{
pkgs,
config,
username,
secrets,
...
}:
{
boot.kernelParams = [
"usbcore.autosuspend=-1" # Avoid usb autosuspend (for usb bluetooth adapter)
];
services.upower.enable = true;
services.power-profiles-daemon.enable = true;
services.keyd = {
enable = true;
keyboards.default.settings = {
main = {
capslock = "overload(control, esc)";
home = "end";
};
shift = {
home = "home";
};
control = {
delete = "print";
};
};
};
services.openssh = {
enable = true;
settings = {
# Forbid root login through SSH.
PermitRootLogin = null;
PasswordAuthentication = true;
};
};
environment.systemPackages = [
pkgs.rclone
];
sops.secrets.imxyy-nix-rclone = {
sopsFile = secrets.imxyy-nix-rclone;
format = "binary";
};
fileSystems = {
"/home/${username}/Nextcloud" = {
device = "Nextcloud:";
fsType = "rclone";
options = [
"nodev"
"nofail"
"allow_other"
"args2env"
"config=${config.sops.secrets.imxyy-nix-rclone.path}"
"uid=1000"
"gid=100"
"rw"
"no-check-certificate"
"vfs-cache-mode=full"
];
};
};
}

View File

@@ -5,7 +5,9 @@
username,
...
}:
let
btrfs = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c";
in
{
boot = {
initrd = {
@@ -21,7 +23,7 @@
verbose = false;
};
kernelPackages = lib.mkForce pkgs.linuxKernel.packages.linux_zen;
kernelPackages = lib.mkForce pkgs.linuxPackages_xanmod_latest;
kernelModules = [ "kvm-amd" ];
tmp.useTmpfs = true;
@@ -29,27 +31,14 @@
"fs.file-max" = 9223372036854775807;
};
resumeDevice = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c";
resumeDevice = btrfs;
kernelParams = [
"resume_offset=6444127"
# "quiet"
# "splash"
# "log_level=3"
];
consoleLogLevel = 3;
/*
plymouth = {
enable = true;
theme = "bgrt";
themePackages = [ pkgs.nixos-bgrt-plymouth ];
};
*/
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c";
device = btrfs;
fsType = "btrfs";
options = [
"compress=zstd"
@@ -63,8 +52,9 @@
options = [ "compress=zstd" ];
};
fileSystems."/persistent" = {
device = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c";
my.persist.location = "/nix/persist";
fileSystems."/nix/persist" = {
device = btrfs;
fsType = "btrfs";
options = [
"compress=zstd"
@@ -74,7 +64,7 @@
};
fileSystems."/swap" = {
device = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c";
device = btrfs;
fsType = "btrfs";
options = [
"compress=zstd"
@@ -85,7 +75,7 @@
boot.initrd.postDeviceCommands = lib.mkAfter ''
mkdir /btrfs_tmp
mount /dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c /btrfs_tmp
mount ${btrfs} /btrfs_tmp
mkdir -p /btrfs_tmp/old_roots
if [[ -e /btrfs_tmp/root ]]; then
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S")
@@ -111,6 +101,12 @@
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/B7DC-E9AC";
fsType = "vfat";
options = [
"uid=0"
"gid=0"
"fmask=0077"
"dmask=0077"
];
};
fileSystems."/home/${username}/Documents" = {

174
hosts/imxyy-nix/home.nix Normal file
View File

@@ -0,0 +1,174 @@
{
config,
pkgs,
username,
...
}:
{
my.hm = {
home.packages = with pkgs; [
localsend
wpsoffice-cn
wps-office-fonts
ttf-wps-fonts
papers
anki
ayugram-desktop
signal-desktop-wayland
element-desktop
fractal
qq-wayland
wechat
gnome-clocks
];
programs.zsh = {
shellAliases = {
cageterm = "cage -m DP-1 -s -- alacritty -o font.size=20";
cagefoot = "cage -m DP-1 -s -- foot --font=monospace:size=20";
cagekitty = "cage -m DP-1 -s -- kitty -o font_size=20";
};
sessionVariables = {
no_proxy = "192.168.3.0/24";
PATH = "/home/${username}/bin:$PATH";
};
};
programs.fish = {
shellAliases = {
cageterm = "cage -m DP-1 -s -- alacritty -o font.size=20";
cagefoot = "cage -m DP-1 -s -- foot --font=monospace:size=20";
cagekitty = "cage -m DP-1 -s -- kitty -o font_size=20";
};
interactiveShellInit = ''
set -g no_proxy "192.168.3.0/24"
set -gp PATH $HOME/bin
'';
};
programs.niri.settings = {
environment.STEAM_FORCE_DESKTOPUI_SCALING = "1.25";
outputs = {
DP-1 = {
enable = true;
mode = {
width = 2560;
height = 1440;
refresh = 75.033;
};
scale = 1.25;
position = {
x = 0;
y = 0;
};
};
DP-2 = {
enable = true;
mode = {
width = 2560;
height = 1440;
refresh = 75.033;
};
scale = 1.25;
};
};
};
};
my = {
autologin = {
enable = true;
user = username;
ttys = [ 6 ];
};
gpg.enable = true;
cli.all.enable = true;
coding.all.enable = true;
desktop.all.enable = true;
i18n.fcitx5.enable = true;
xdg = {
enable = true;
defaultApplications =
let
browser = [ config.my.desktop.browser.default.desktop ];
editor = [ "nvim.desktop" ];
imageviewer = [ "org.gnome.Loupe.desktop" ];
in
{
"inode/directory" = [ "org.gnome.Nautilus.desktop" ];
"application/pdf" = [ "org.gnome.Papers.desktop" ];
"text/*" = editor;
"application/json" = editor;
"text/xml" = editor;
"application/xml" = editor;
"application/xhtml+xml" = editor;
"application/xhtml_xml" = editor;
"application/rdf+xml" = editor;
"application/rss+xml" = editor;
"application/x-extension-htm" = editor;
"application/x-extension-html" = editor;
"application/x-extension-shtml" = editor;
"application/x-extension-xht" = editor;
"application/x-extension-xhtml" = editor;
"text/html" = browser;
"x-scheme-handler/about" = browser;
"x-scheme-handler/ftp" = browser;
"x-scheme-handler/http" = browser;
"x-scheme-handler/https" = browser;
"x-scheme-handler/unknown" = browser;
"audio/*" = imageviewer;
"video/*" = imageviewer;
"image/*" = imageviewer;
"image/gif" = imageviewer;
"image/jpeg" = imageviewer;
"image/png" = imageviewer;
"image/webp" = imageviewer;
};
};
persist = {
enable = true;
homeDirs = [
".android"
"Android"
"bin"
"workspace"
"Virt"
".cache"
".local/state"
".local/share/Anki2"
".local/share/shotwell"
".local/share/Kingsoft"
".local/share/AyuGramDesktop"
".local/share/fractal"
".config/Signal"
".config/Element"
".config/QQ"
".xwechat"
".config/Kingsoft"
".config/dconf"
".config/pip"
".config/sunshine"
".gemini"
".claude"
".claude-code-router"
];
homeFiles = [
".claude.json"
];
};
};
}

View File

@@ -2,7 +2,7 @@
config,
lib,
pkgs,
sopsRoot,
secrets,
...
}:
{
@@ -69,6 +69,7 @@
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
iifname waydroid0 accept
ct state invalid drop
ct state established,related accept
@@ -78,6 +79,9 @@
chain forward {
type filter hook forward priority 0; policy drop;
iifname waydroid0 accept
oifname waydroid0 accept
}
}
'';
@@ -85,7 +89,8 @@
};
sops.secrets.dae-imxyy-nix = {
sopsFile = sopsRoot + /dae-imxyy-nix.dae;
sopsFile = secrets.dae-imxyy-nix;
restartUnits = [ "dae.service" ];
format = "binary";
};
services.dae = {
@@ -94,7 +99,8 @@
};
systemd.services.dae.after = [ "sops-nix.service" ];
sops.secrets.mihomo = {
sopsFile = sopsRoot + /mihomo.yaml;
sopsFile = secrets.mihomo;
restartUnits = [ "mihomo.service" ];
format = "yaml";
key = "";
};
@@ -105,21 +111,18 @@
webui = pkgs.metacubexd;
};
services.tailscale.enable = true;
sops.secrets.et-imxyy-nix = {
sopsFile = sopsRoot + /et-imxyy-nix.toml;
sopsFile = secrets.et-imxyy-nix;
restartUnits = [ "easytier.service" ];
format = "binary";
};
environment.systemPackages = [ pkgs.easytier ];
systemd.services."easytier" = {
enable = true;
script = "easytier-core -c ${config.sops.secrets.et-imxyy-nix.path}";
script = "${pkgs.easytier}/bin/easytier-core -c ${config.sops.secrets.et-imxyy-nix.path}";
serviceConfig = {
Restart = lib.mkOverride 500 "always";
RestartMaxDelaySec = lib.mkOverride 500 "1m";
RestartSec = lib.mkOverride 500 "100ms";
RestartSteps = lib.mkOverride 500 9;
Restart = "always";
RestartSec = 30;
User = "root";
};
wantedBy = [ "multi-user.target" ];
@@ -127,10 +130,5 @@
"network.target"
"sops-nix.service"
];
path = with pkgs; [
easytier
iproute2
bash
];
};
}

130
hosts/imxyy-nix/nixos.nix Normal file
View File

@@ -0,0 +1,130 @@
{
lib,
pkgs,
config,
username,
secrets,
...
}:
let
btreset = pkgs.writeShellScriptBin "btreset" ''
LOCKFILE="/tmp/.btreseted"
SYM="BT"
if [ -f "$LOCKFILE" ] && [ "$1" != "-f" ]; then
exit 0
fi
${lib.getExe' pkgs.usbutils "lsusb"} | grep "$SYM" | while read -r line; do
bus=$(echo "$line" | awk '{print $2}')
dev=$(echo "$line" | awk '{print $4}' | tr -d ':')
${lib.getExe' pkgs.usbutils "usbreset"} "$bus/$dev"
touch "$LOCKFILE"
done
'';
in
{
systemd.services.btreset = {
script = lib.getExe btreset;
wantedBy = [ "multi-user.target" ];
serviceConfig.Type = "oneshot";
};
boot.kernelParams = [
"usbcore.autosuspend=-1" # Avoid usb autosuspend (for usb bluetooth adapter)
"fsck.mode=skip"
];
services.keyd = {
enable = true;
keyboards = {
default.settings = {
main = {
capslock = "overload(control, esc)";
home = "end";
};
shift = {
home = "home";
};
control = {
delete = "print";
};
};
kone-pro-owl-eye = {
ids = [ "1e7d:2dcd" ];
settings.main.mouse2 = "rightmouse";
};
};
};
programs.wireshark.enable = true;
programs.wireshark.package = pkgs.wireshark;
users.users.${username}.extraGroups = [ "wireshark" ];
virtualisation.waydroid.enable = true;
my.persist.homeDirs = [ ".local/share/waydroid" ];
services.sunshine = {
enable = true;
autoStart = true;
capSysAdmin = true;
applications.apps = [
{
name = "Desktop";
image-path = "desktop.png";
}
];
};
services.openssh = {
enable = true;
settings = {
# Forbid root login through SSH.
PermitRootLogin = null;
PasswordAuthentication = true;
};
};
environment.systemPackages = [
pkgs.rclone
btreset
];
sops.secrets.imxyy-nix-rclone = {
sopsFile = secrets.imxyy-nix-rclone;
format = "binary";
};
fileSystems = {
"/home/${username}/Nextcloud" = {
device = "Nextcloud:";
fsType = "rclone";
options = [
"nodev"
"nofail"
"allow_other"
"args2env"
"config=${config.sops.secrets.imxyy-nix-rclone.path}"
"uid=1000"
"gid=100"
"rw"
"no-check-certificate"
"vfs-cache-mode=full"
];
};
"/home/${username}/NAS" = {
device = "//192.168.3.2/share";
fsType = "cifs";
options = [
"username=nas"
"password=nasshare"
"x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s"
"nodev"
"nofail"
"uid=1000"
"gid=100"
"vers=3"
"rw"
];
};
};
}

View File

@@ -0,0 +1,36 @@
{
lib,
pkgs,
username,
...
}:
{
virtualisation.podman = {
enable = true;
dockerCompat = true;
dockerSocket.enable = true;
};
users.users.${username}.extraGroups = [ "podman" ];
environment.systemPackages = [ pkgs.distrobox ];
my.hm.programs.distrobox = {
enable = true;
settings = {
container_image_default = "docker.io/archlinux:latest";
};
containers = {
archlinux = {
image = "archlinux:latest";
additional_packages = "nvim";
};
};
};
my.hm.programs.zsh.initContent = lib.mkBefore ''
if [ -n "''${CONTAINER_ID+1}" ]; then
export ZSH_DISABLE_COMPFIX=true
fi
'';
my.persist.homeDirs = [
".config/containers"
".local/share/containers"
];
}

View File

@@ -1,102 +1,9 @@
{ lib }:
{
makeSwitch =
{
default ? false,
config,
optionPath,
optionName,
config',
}:
let
cfg = lib.getAttrFromPath optionPath config.my;
in
{
options.my = lib.setAttrByPath (optionPath) {
enable = (lib.mkEnableOption optionName) // {
inherit default;
};
};
config = lib.mkIf cfg.enable config';
};
makeHomePackageConfig =
{
config,
pkgs,
packageName,
packagePath,
optionPath,
extraConfig ? { },
}:
lib.my.makeSwitch {
inherit config optionPath;
optionName = packageName;
config' = lib.mkMerge [
{
my.home.home.packages = [ (lib.getAttrFromPath packagePath pkgs) ];
}
extraConfig
];
};
makeHomeProgramConfig =
{
config,
programName,
optionPath,
extraConfig ? { },
}:
lib.my.makeSwitch {
inherit config optionPath;
optionName = programName;
config' = lib.mkMerge [
{
my.home.programs = lib.setAttrByPath [ programName "enable" ] true;
}
extraConfig
];
};
makeNixosPackageConfig =
{
config,
pkgs,
packageName,
packagePath,
optionPath,
extraConfig ? { },
}:
lib.my.makeSwitch {
inherit config optionPath;
optionName = packageName;
config' = lib.mkMerge [
{
environment.systemPackages = [ (lib.getAttrFromPath packagePath pkgs) ];
}
extraConfig
];
};
makeNixosProgramConfig =
{
config,
programName,
optionPath,
extraConfig ? { },
}:
lib.my.makeSwitch {
inherit config optionPath;
optionName = programName;
config' = lib.mkMerge [
{
programs = lib.setAttrByPath [ programName "enable" ] true;
}
extraConfig
];
};
{ lib, inputs }:
lib.extend (
self: super: {
inherit (inputs.home-manager.lib) hm;
umport = import ./umport.nix { lib = self; };
haumea = inputs.haumea.lib;
infuse = (import inputs.infuse { inherit lib; }).v1.infuse;
}
)

View File

@@ -1,13 +0,0 @@
# Just a convenience function that returns the given Nixpkgs standard
# library extended with the imxyy library.
stdlib:
let
mkMyLib = import ./.;
in
stdlib.extend (
self: super: {
my = mkMyLib { lib = self; };
}
)

45
lib/umport.nix Normal file
View File

@@ -0,0 +1,45 @@
# This function is modified from:
# https://github.com/yunfachi/nypkgs/blob/master/lib/umport.nix
#
# !!! REMOVING THIS NOTICE VIOLATES THE MIT LICENSE OF THE UMPORT PROJECT !!!
# This notice must be retained in all copies of this function, including modified versions!
# The MIT License can be found here:
# https://github.com/yunfachi/nypkgs/blob/master/LICENSE
{ lib, ... }:
let
umport =
{
path ? null,
paths ? [ ],
include ? [ ],
exclude ? [ ],
extraExcludePredicate ? _: true,
recursive ? true,
}:
with lib;
with fileset;
let
excludedFiles = filter (path: pathIsRegularFile path) exclude;
excludedDirs = filter (path: pathIsDirectory path) exclude;
isExcluded =
path:
(elem path excludedFiles)
|| ((filter (excludedDir: lib.path.hasPrefix excludedDir path) excludedDirs) != [ ])
|| extraExcludePredicate path;
in
unique (
(filter (file: pathIsRegularFile file && hasSuffix ".nix" (toString file) && !isExcluded file) (
concatMap (
path:
if recursive then
toList path
else
mapAttrsToList (
name: type: path + (if type == "directory" then "/${name}/default.nix" else "/${name}")
) (builtins.readDir path)
) (unique (if path == null then paths else [ path ] ++ paths))
))
++ (if recursive then concatMap (path: toList path) (unique include) else unique include)
);
in
umport

29
modules/audio.nix Normal file
View File

@@ -0,0 +1,29 @@
{
config,
lib,
pkgs,
username,
...
}:
let
cfg = config.my.audio;
in
{
options.my.audio = {
enable = lib.mkEnableOption "default audio settings";
};
config = lib.mkIf cfg.enable {
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
audio.enable = true;
};
users.extraUsers.${username}.extraGroups = [ "audio" ];
my.persist.homeDirs = [ ".local/state/wireplumber" ];
my.hm.home.packages = [ pkgs.pwvucontrol ];
};
}

23
modules/bluetooth.nix Normal file
View File

@@ -0,0 +1,23 @@
{ config, lib, ... }:
let
cfg = config.my.bluetooth;
in
{
options.my.bluetooth = {
enable = lib.mkEnableOption "default bluetooth settings";
};
config = lib.mkIf cfg.enable {
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
settings = {
General = {
Enable = "Source,Sink,Media,Socket";
Disable = "HeadSet";
MultiProfile = "multiple";
};
};
};
};
}

22
modules/cli/all.nix Normal file
View File

@@ -0,0 +1,22 @@
{ config, lib, ... }:
let
cfg = config.my.cli.all;
in
{
options.my.cli.all = {
enable = lib.mkEnableOption "all command line tools";
};
config = lib.mkIf cfg.enable {
my.cli = {
media.all.enable = true;
misc.enable = true;
monitor.all.enable = true;
shell.all.enable = true;
vcs.all.enable = true;
shpool.enable = true;
tmux.enable = true;
};
};
}

16
modules/cli/media/all.nix Normal file
View File

@@ -0,0 +1,16 @@
{ config, lib, ... }:
let
cfg = config.my.cli.media.all;
in
{
options.my.cli.media.all = {
enable = lib.mkEnableOption "all command line media tools";
};
config = lib.mkIf cfg.enable {
my.cli.media = {
go-musicfox.enable = true;
ffmpeg.enable = true;
};
};
}

View File

@@ -0,0 +1,18 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.cli.media.ffmpeg;
in
{
options.my.cli.media.ffmpeg = {
enable = lib.mkEnableOption "ffmpeg";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = [ pkgs.ffmpeg ];
};
}

View File

@@ -0,0 +1,39 @@
{
config,
lib,
pkgs,
secrets,
...
}:
let
cfg = config.my.cli.media.go-musicfox;
in
{
options.my.cli.media.go-musicfox = {
enable = lib.mkEnableOption "go-musicfox";
};
config = lib.mkIf cfg.enable {
my = {
hm = {
home.packages = [
pkgs.go-musicfox
];
sops.secrets.go-musicfox = {
sopsFile = secrets.go-musicfox;
format = "binary";
path = "${config.my.hm.xdg.configHome}/go-musicfox/config.toml";
};
};
desktop.media.mpv.enable = lib.mkForce true;
persist.homeDirs = [
".local/share/go-musicfox/db"
];
persist.homeFiles = [
".local/share/go-musicfox/cookie"
];
};
};
}

208
modules/cli/misc.nix Normal file
View File

@@ -0,0 +1,208 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.cli.misc;
in
{
options.my.cli.misc = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable misc command line tools";
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
vim
wget
file
gnused
gnutar
zip
unzip
xz
p7zip
unrar-free
ouch
pciutils
usbutils
dust
dysk
lsof
nmap
traceroute
tcping-go
dnsutils
killall
];
programs.dconf.enable = true;
my.persist.homeDirs = [
".local/share/zoxide"
".config/television/cable"
];
my.hm = {
programs.fish.shellAliases = {
x = "ouch d";
};
programs.zsh.shellAliases = {
x = "ouch d";
};
home.packages = with pkgs; [
# keep-sorted start
aria2
bat
comma
fastfetch
fd
fzf
jq
keep-sorted
lsd
neofetch
ripgrep
socat
typos
# keep-sorted end
];
programs.tealdeer = {
enable = true;
enableAutoUpdates = true;
settings.updates.auto_update = true;
};
programs.television = {
enable = true;
enableZshIntegration = true;
enableFishIntegration = true;
};
programs.zoxide = {
enable = true;
enableZshIntegration = true;
enableFishIntegration = true;
};
xdg.configFile."fastfetch/config.jsonc".text = ''
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"display": {
"separator": " "
},
"modules": [
// Title
{
"type": "title",
"format": "{user-name-colored}{#}@{host-name-colored}"
},
{
"type": "custom",
"format": "---------------"
},
// System Information
{
"type": "custom",
"format": "{#}System Information"
},
{
"type": "os",
"key": "{#keys}󰍹 OS"
},
{
"type": "kernel",
"key": "{#keys}󰒋 Kernel"
},
{
"type": "uptime",
"key": "{#keys}󰅐 Uptime"
},
{
"type": "packages",
"key": "{#keys}󰏖 Packages",
"format": "{all}"
},
{
"type": "custom",
"format": ""
},
// Desktop Environment
{
"type": "custom",
"format": "{#}Desktop Environment"
},
{
"type": "de",
"key": "{#keys}󰧨 DE"
},
{
"type": "wm",
"key": "{#keys}󱂬 WM"
},
{
"type": "wmtheme",
"key": "{#keys}󰉼 Theme"
},
{
"type": "display",
"key": "{#keys}󰹑 Resolution"
},
{
"type": "shell",
"key": "{#keys}󰞷 Shell"
},
{
"type": "terminalfont",
"key": "{#keys}󰛖 Font"
},
{
"type": "custom",
"format": ""
},
// Hardware Information
{
"type": "custom",
"format": "{#}Hardware Information"
},
{
"type": "cpu",
"key": "{#keys}󰻠 CPU"
},
{
"type": "gpu",
"key": "{#keys}󰢮 GPU"
},
{
"type": "memory",
"key": "{#keys}󰍛 Memory"
},
{
"type": "disk",
"key": "{#keys}󰋊 Disk (/)",
"folders": "/"
},
{
"type": "custom",
"format": ""
},
// Colors
{
"type": "colors",
"symbol": "circle"
},
]
}
'';
};
};
}

View File

@@ -0,0 +1,15 @@
{ config, lib, ... }:
let
cfg = config.my.cli.monitor.all;
in
{
options.my.cli.monitor.all = {
enable = lib.mkEnableOption "all command line monitor tools";
};
config = lib.mkIf cfg.enable {
my.cli.monitor = {
btop.enable = true;
};
};
}

View File

@@ -18,7 +18,7 @@ theme[main_fg]="#D8DEE9"
# Title color for boxes
theme[title]="#8FBCBB"
# Higlight color for keyboard shortcuts
# Highlight color for keyboard shortcuts
theme[hi_fg]="#5E81AC"
# Background color of selected item in processes box

View File

@@ -0,0 +1,22 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.cli.monitor.btop;
in
{
options.my.cli.monitor.btop = {
enable = lib.mkEnableOption "btop";
};
config = lib.mkIf cfg.enable {
my.hm.home.packages = [ pkgs.btop ];
my.hm.xdg.configFile."btop" = {
source = ./config;
recursive = true;
};
};
}

17
modules/cli/shell/all.nix Normal file
View File

@@ -0,0 +1,17 @@
{ config, lib, ... }:
let
cfg = config.my.cli.shell.all;
in
{
options.my.cli.shell.all = {
enable = lib.mkEnableOption "all shells";
};
config = lib.mkIf cfg.enable {
my.cli.shell = {
zsh.enable = true;
fish.enable = true;
starship.enable = true;
};
};
}

View File

@@ -0,0 +1,34 @@
{
lib,
config,
username,
...
}:
let
cfg = config.my.cli.shell;
in
{
options.my.cli.shell.default = lib.mkOption {
type = lib.types.enum [
"fish"
"zsh"
];
default = "fish";
};
config = lib.mkMerge [
(lib.mkIf (cfg.default == "fish") {
my.cli.shell.fish.enable = true;
users.users.${username} = {
shell = config.my.hm.programs.fish.package;
# do not need `programs.fish.enable = true` since fish is managed by home-manager
ignoreShellProgramCheck = true;
};
})
(lib.mkIf (cfg.default == "zsh") {
my.cli.shell.zsh.enable = true;
users.users.${username}.shell = config.my.hm.programs.zsh.package;
})
];
}

View File

@@ -0,0 +1,96 @@
{
config,
lib,
...
}:
let
cfg = config.my.cli.shell.fish;
in
{
options.my.cli.shell.fish = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable default fish settings";
};
};
config = lib.mkIf cfg.enable {
my.persist = {
homeDirs = [
".local/share/fish"
];
};
my.hm = {
xdg.configFile."fish/themes/tokyonight_storm.theme".source = builtins.fetchurl {
url = "https://raw.githubusercontent.com/folke/tokyonight.nvim/refs/tags/v4.14.1/extras/fish_themes/tokyonight_storm.theme";
sha256 = "02n1w5x65683c8mlwg1rav06iqm3xk90zq45qmygpm7pzyn8dqh1";
};
programs.starship.enableFishIntegration = false;
programs.fish = {
enable = true;
shellAliases = {
la = "lsd -lah";
ls = "lsd";
svim = "doasedit";
nf = "fastfetch";
};
interactiveShellInit = lib.mkBefore ''
fish_vi_key_bindings
fish_config theme choose tokyonight_storm
${lib.optionalString config.my.cli.shell.starship.enable "source ${./starship.fish}"}
'';
functions = {
fish_greeting = "";
yank_to_clipboard = {
description = "Insert latest killring entry into the system clipboard";
body = ''printf "%s" "$fish_killring[1]" | fish_clipboard_copy'';
};
fish_user_key_bindings = ''
# make vi mode yanks copy to clipboard
bind yy kill-whole-line yank_to_clipboard yank
bind Y kill-whole-line yank_to_clipboard yank
bind y,\$ kill-line yank_to_clipboard yank
bind y,\^ backward-kill-line yank_to_clipboard yank
bind y,0 backward-kill-line yank_to_clipboard yank
bind y,w kill-word yank_to_clipboard yank
bind y,W kill-bigword yank_to_clipboard yank
bind y,i,w forward-single-char forward-single-char backward-word kill-word yank_to_clipboard yank
bind y,i,W forward-single-char forward-single-char backward-bigword kill-bigword yank_to_clipboard yank
bind y,a,w forward-single-char forward-single-char backward-word kill-word yank_to_clipboard yank
bind y,a,W forward-single-char forward-single-char backward-bigword kill-bigword yank_to_clipboard yank
bind y,e kill-word yank_to_clipboard yank
bind y,E kill-bigword yank_to_clipboard yank
bind y,b backward-kill-word yank_to_clipboard yank
bind y,B backward-kill-bigword yank_to_clipboard yank
bind y,g,e backward-kill-word yank_to_clipboard yank
bind y,g,E backward-kill-bigword yank_to_clipboard yank
bind y,f begin-selection forward-jump kill-selection yank_to_clipboard yank end-selection
bind y,t begin-selection forward-jump-till kill-selection yank_to_clipboard yank end-selection
bind y,F begin-selection backward-jump kill-selection yank_to_clipboard yank end-selection
bind y,T begin-selection backward-jump-till kill-selection yank_to_clipboard yank end-selection
bind y,h backward-char begin-selection kill-selection yank_to_clipboard yank end-selection
bind y,l begin-selection kill-selection yank_to_clipboard yank end-selection
bind y,i,b jump-till-matching-bracket and jump-till-matching-bracket and begin-selection jump-till-matching-bracket kill-selection yank_to_clipboard yank end-selection
bind y,a,b jump-to-matching-bracket and jump-to-matching-bracket and begin-selection jump-to-matching-bracket kill-selection yank_to_clipboard yank end-selection
bind y,i backward-jump-till and repeat-jump-reverse and begin-selection repeat-jump kill-selection yank_to_clipboard yank end-selection
bind y,a backward-jump and repeat-jump-reverse and begin-selection repeat-jump kill-selection yank_to_clipboard yank end-selection
bind -M visual -m default y kill-selection yank_to_clipboard yank end-selection repaint-mode
# use system clipboard for vi mode pastes
bind -s p 'set -g fish_cursor_end_mode exclusive' forward-char 'set -g fish_cursor_end_mode inclusive' fish_clipboard_paste
bind -s P fish_clipboard_paste
'';
nix-closure-size = {
body = ''
nix path-info --recursive --size --closure-size \
--human-readable $(readlink -f $(which $program))
'';
argumentNames = [ "program" ];
};
};
};
};
};
}

View File

@@ -0,0 +1,190 @@
[aws]
symbol = " "
[buf]
symbol = " "
[bun]
symbol = " "
[c]
symbol = " "
[cpp]
symbol = " "
[cmake]
symbol = " "
[conda]
symbol = " "
[crystal]
symbol = " "
[dart]
symbol = " "
[deno]
symbol = " "
[directory]
read_only = " 󰌾"
[docker_context]
symbol = " "
[elixir]
symbol = " "
[elm]
symbol = " "
[fennel]
symbol = " "
[fossil_branch]
symbol = " "
[gcloud]
symbol = " "
[git_branch]
symbol = " "
[git_commit]
tag_symbol = '  '
[golang]
symbol = " "
[guix_shell]
symbol = " "
[haskell]
symbol = " "
[haxe]
symbol = " "
[hg_branch]
symbol = " "
[hostname]
ssh_symbol = " "
[java]
symbol = " "
[julia]
symbol = " "
[kotlin]
symbol = " "
[lua]
symbol = " "
[memory_usage]
symbol = "󰍛 "
[meson]
symbol = "󰔷 "
[nim]
symbol = "󰆥 "
[nix_shell]
symbol = " "
[nodejs]
symbol = " "
[ocaml]
symbol = " "
[os.symbols]
Alpaquita = " "
Alpine = " "
AlmaLinux = " "
Amazon = " "
Android = " "
Arch = " "
Artix = " "
CachyOS = " "
CentOS = " "
Debian = " "
DragonFly = " "
Emscripten = " "
EndeavourOS = " "
Fedora = " "
FreeBSD = " "
Garuda = "󰛓 "
Gentoo = " "
HardenedBSD = "󰞌 "
Illumos = "󰈸 "
Kali = " "
Linux = " "
Mabox = " "
Macos = " "
Manjaro = " "
Mariner = " "
MidnightBSD = " "
Mint = " "
NetBSD = " "
NixOS = " "
Nobara = " "
OpenBSD = "󰈺 "
openSUSE = " "
OracleLinux = "󰌷 "
Pop = " "
Raspbian = " "
Redhat = " "
RedHatEnterprise = " "
RockyLinux = " "
Redox = "󰀘 "
Solus = "󰠳 "
SUSE = " "
Ubuntu = " "
Unknown = " "
Void = " "
Windows = "󰍲 "
[package]
symbol = "󰏗 "
[perl]
symbol = " "
[php]
symbol = " "
[pijul_channel]
symbol = " "
[pixi]
symbol = "󰏗 "
[python]
symbol = " "
[rlang]
symbol = "󰟔 "
[ruby]
symbol = " "
[rust]
symbol = "󱘗 "
[scala]
symbol = " "
[swift]
symbol = " "
[zig]
symbol = " "
[gradle]
symbol = " "

View File

@@ -0,0 +1,143 @@
# This file is modified from:
# https://github.com/tyler-stefani/starship/blob/main/conf.d/starship.fish
# The MIT License can be found here:
# https://github.com/tyler-stefani/starship/blob/main/LICENSE
status is-interactive
or exit 0
# set temp file and signal for async prompts
if test -n "$XDG_RUNTIME_DIR"
set -g starship_temp_dir "$XDG_RUNTIME_DIR"/fish-async-prompt
else
set -g starship_temp_dir /tmp/fish-async-prompt
end
mkdir -p "$starship_temp_dir"
set -g starship_temp_file "$starship_temp_dir"/"$fish_pid"_last_prompt
set -g starship_async_signal SIGUSR1
function fish_prompt
if test "$TRANSIENT" = "1"
starship_transient_prompt_func
else if test -e $starship_temp_file
cat $starship_temp_file
else
starship_transient_prompt_func
end
end
function starship_transient_prompt_func
# Clear from cursor to end of screen as `commandline -f repaint` does not do this
# See https://github.com/fish-shell/fish-shell/issues/8418
printf \e\[0J
starship module character
end
function fish_right_prompt
switch "$fish_key_bindings"
case fish_hybrid_key_bindings fish_vi_key_bindings
set STARSHIP_KEYMAP "$fish_bind_mode"
case '*'
set STARSHIP_KEYMAP insert
end
set STARSHIP_CMD_PIPESTATUS $pipestatus
set STARSHIP_CMD_STATUS $status
# Account for changes in variable name between v2.7 and v3.0
set STARSHIP_DURATION "$CMD_DURATION$cmd_duration"
set STARSHIP_JOBS (count (jobs -p))
if test "$TRANSIENT" = "1"
if type -q starship_transient_rprompt_func
starship_transient_rprompt_func
else
printf ""
end
else
starship prompt --right --terminal-width="$COLUMNS" --status=$STARSHIP_CMD_STATUS --pipestatus="$STARSHIP_CMD_PIPESTATUS" --keymap=$STARSHIP_KEYMAP --cmd-duration=$STARSHIP_DURATION --jobs=$STARSHIP_JOBS
end
end
# Disable virtualenv prompt, it breaks starship
set -g VIRTUAL_ENV_DISABLE_PROMPT 1
# Remove default mode prompt
builtin functions -e fish_mode_prompt
set -gx STARSHIP_SHELL fish
# Transience related functions
function reset-transient --on-event fish_postexec
set -g TRANSIENT 0
end
function transient_execute
if commandline --is-valid
set -g TRANSIENT 1
commandline -f repaint
else
set -g TRANSIENT 0
end
commandline -f execute
end
function transient_cancel
if string length -q -- (commandline)
set -g TRANSIENT 1
commandline -f repaint
end
commandline -f cancel-commandline
end
# --user is the default, but listed anyway to make it explicit.
function enable_transience --description 'enable transient prompt keybindings'
bind --user \r transient_execute
bind --user -M insert \r transient_execute
bind --user \cc transient_cancel
end
# Erase the transient prompt related key bindings.
# --user is the default, but listed anyway to make it explicit.
# Erasing a user binding will revert to the preset.
function disable_transience --description 'remove transient prompt keybindings'
bind --user -e \r
bind --user -M insert -e \r
bind --user -e \cc
end
# Set up the session key that will be used to store logs
# We don't use `random [min] [max]` because it is unavailable in older versions of fish shell
set -gx STARSHIP_SESSION_KEY (string sub -s1 -l16 (random)(random)(random)(random)(random)0000000000000000)
# async related functions
function write_prompt_to_temp --on-event fish_prompt
switch "$fish_key_bindings"
case fish_hybrid_key_bindings fish_vi_key_bindings
set STARSHIP_KEYMAP "$fish_bind_mode"
case '*'
set STARSHIP_KEYMAP insert
end
set STARSHIP_CMD_PIPESTATUS $pipestatus
set STARSHIP_CMD_STATUS $status
# Account for changes in variable name between v2.7 and v3.0
set STARSHIP_DURATION "$CMD_DURATION$cmd_duration"
set STARSHIP_JOBS (count (jobs -p))
# MODIFIED: '"$STARSHIP_CMD_PIPESTATUS"' -> '$STARSHIP_CMD_PIPESTATUS'
fish -c 'starship prompt \
--terminal-width='"$COLUMNS"' \
--status='$STARSHIP_CMD_STATUS' \
--pipestatus='$STARSHIP_CMD_PIPESTATUS' \
--keymap='$STARSHIP_KEYMAP' \
--cmd-duration='$STARSHIP_DURATION' \
--jobs='$STARSHIP_JOBS' > '$starship_temp_file' \
&& kill -s '"$starship_async_signal"' '"$fish_pid"'' &
disown
end
function repaint_prompt_on_signal --on-signal "$starship_async_signal"
commandline -f repaint
end
function remove_temp_prompt_on_exit --on-event fish_exit
rm -f $starship_temp_file
end

View File

@@ -0,0 +1,57 @@
{ config, lib, ... }:
let
cfg = config.my.cli.shell.starship;
in
{
options.my.cli.shell.starship = {
enable = lib.mkEnableOption "starship prompt";
format = lib.mkOption {
type = with lib.types; listOf singleLineStr;
};
};
config = lib.mkMerge [
(lib.mkIf cfg.enable {
my.hm = {
programs.starship = {
enable = true;
settings = lib.recursiveUpdate (with builtins; fromTOML (readFile ./starship-preset.toml)) {
add_newline = false;
command_timeout = 2000;
nix_shell.disabled = true;
format =
let
dedupDollar =
list:
let
result =
builtins.foldl'
(
acc: elem:
if lib.hasPrefix "$" elem then
if builtins.elem elem acc.seen then
acc
else
acc
// {
result = acc.result ++ [ elem ];
seen = acc.seen ++ [ elem ];
}
else
acc // { result = acc.result ++ [ elem ]; }
)
{
result = [ ];
seen = [ ];
}
(lib.reverseList list);
in
lib.reverseList result.result;
in
"$all" + lib.concatStrings (dedupDollar cfg.format);
};
};
};
})
];
}

60
modules/cli/shell/zsh.nix Normal file
View File

@@ -0,0 +1,60 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.cli.shell.zsh;
in
{
options.my.cli.shell.zsh = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable default zsh settings";
};
};
config = lib.mkIf cfg.enable {
my.hm = {
home.packages = with pkgs; [
fzf
];
programs.zsh = {
enable = true;
dotDir = "${config.my.hm.xdg.configHome}/zsh";
history = {
path = "${config.my.hm.xdg.stateHome}/zsh_history";
ignorePatterns = [
"la"
];
};
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
plugins = [
{
name = "fzf-tab";
src = pkgs.zsh-fzf-tab;
file = "share/fzf-tab/fzf-tab.plugin.zsh";
}
];
oh-my-zsh = {
enable = true;
theme = "gentoo";
plugins = [
"git"
"git-extras"
"extract"
"sudo"
];
};
shellAliases = {
ls = "lsd";
svim = "doasedit";
nf = "fastfetch";
};
};
};
};
}

43
modules/cli/shpool.nix Normal file
View File

@@ -0,0 +1,43 @@
{
config,
lib,
...
}:
let
cfg = config.my.cli.shpool;
in
{
options.my.cli.shpool = {
enable = lib.mkEnableOption "shpool";
};
config = lib.mkIf cfg.enable {
my.hm = {
services.shpool = {
enable = true;
systemd = true;
settings = {
motd = "never";
prompt_prefix = "";
forward_env = [ "PATH" ];
};
};
programs.starship = {
settings = {
custom.shpool = {
description = "Display current shpool session name";
when = ''test -n "$SHPOOL_SESSION_NAME"'';
command = "echo $SHPOOL_SESSION_NAME";
symbol = " ";
style = "fg:#dea584";
format = "[$symbol \\[$output\\] ]($style)";
};
};
};
};
my.cli.shell.starship.format = [
"\${custom.shpool}"
"$character"
];
};
}

55
modules/cli/tmux.nix Normal file
View File

@@ -0,0 +1,55 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.cli.tmux;
in
{
options.my.cli.tmux = {
enable = lib.mkEnableOption "tmux";
};
config = lib.mkIf cfg.enable {
my.hm = {
programs.tmux = {
enable = true;
extraConfig = ''
set-option -g mouse on
set-option -a terminal-features ",xterm-256color:RGB,focus,clipboard,usstyle"
'';
plugins = [
(pkgs.tmuxPlugins.mkTmuxPlugin {
pluginName = "tokyo-night-tmux";
rtpFilePath = "tokyo-night.tmux";
version = "legacy";
src = pkgs.fetchFromGitHub {
owner = "janoamaral";
repo = "tokyo-night-tmux";
rev = "16469dfad86846138f594ceec780db27039c06cd";
hash = "sha256-EKCgYan0WayXnkSb2fDJxookdBLW0XBKi2hf/YISwJE=";
};
})
];
};
programs.starship = {
settings = {
custom.tmux = {
description = "Display current tmux session name";
when = ''test -n "$TMUX"'';
command = "tmux display-message -p '#S'";
symbol = " ";
style = "bold green";
format = "[$symbol \\[$output\\] ]($style)";
};
};
};
};
my.cli.shell.starship.format = [
"\${custom.tmux}"
"$character"
];
};
}

16
modules/cli/vcs/all.nix Normal file
View File

@@ -0,0 +1,16 @@
{ config, lib, ... }:
let
cfg = config.my.cli.vcs.all;
in
{
options.my.cli.vcs.all = {
enable = lib.mkEnableOption "all command line tools";
};
config = lib.mkIf cfg.enable {
my.cli.vcs = {
git.enable = true;
jj.enable = true;
};
};
}

50
modules/cli/vcs/git.nix Normal file
View File

@@ -0,0 +1,50 @@
{
config,
lib,
pkgs,
username,
userfullname,
emails,
hosts,
...
}:
let
cfg = config.my.cli.vcs.git;
in
{
options.my.cli.vcs.git = {
enable = lib.mkEnableOption "git";
};
config = lib.mkIf cfg.enable {
my.hm = {
programs.git = {
enable = true;
settings = {
gpg.ssh.allowedSignersFile =
hosts
|> lib.mapAttrsToList (
host: key: map (email: "${email} ${key} ${host}") (builtins.attrValues emails)
)
|> lib.flatten
|> lib.concatStringsSep "\n"
|> pkgs.writeText "allowed-signers"
|> toString;
push.autoSetupRemote = true;
user = {
name = userfullname;
email = emails.default;
};
};
signing = {
format = "ssh";
signByDefault = true;
key = "/home/${username}/.ssh/id_ed25519";
};
};
programs.lazygit = {
enable = true;
};
};
};
}

100
modules/cli/vcs/jj.nix Normal file
View File

@@ -0,0 +1,100 @@
{
config,
lib,
pkgs,
username,
userfullname,
emails,
hosts,
...
}:
let
cfg = config.my.cli.vcs.jj;
in
{
options.my.cli.vcs.jj = {
enable = lib.mkEnableOption "jujutsu";
};
config = lib.mkIf cfg.enable {
my.hm = {
programs.jujutsu = {
enable = true;
settings = {
# take the closest ancestor bookmark and move them the current change.
# https://shaddy.dev/notes/jj-tug
aliases.tug = [
"bookmark"
"move"
"--from"
"heads(::@- & bookmarks())"
"--to"
"@-"
];
user = {
name = userfullname;
email = emails.default;
};
ui = {
graph.style = "square";
default-command = "status";
conflict-marker-style = "snapshot";
};
signing = {
backend = "ssh";
behavior = "own";
key = "/home/${username}/.ssh/id_ed25519";
backends.backends.ssh.allowed-signers =
hosts
|> lib.mapAttrsToList (
host: key: map (email: "${email} ${key} ${host}") (builtins.attrValues emails)
)
|> lib.flatten
|> lib.concatStringsSep "\n"
|> pkgs.writeText "allowed-signers"
|> toString;
};
};
};
programs.jjui.enable = true;
programs.starship = {
settings = {
custom = {
# Borrowed from https://github.com/jj-vcs/jj/wiki/Starship/b18afc53417848f58333b24d446b8e2522b42bd2#alternative-prompt
jj = {
ignore_timeout = true;
description = "The current jj status";
when = true;
command = ''
jj log --revisions @ --no-graph --ignore-working-copy --color always --limit 1 --template '
separate(" ",
" ",
change_id.shortest(4),
bookmarks,
"|",
concat(
if(conflict, "💥"),
if(divergent, "🚧"),
if(hidden, "👻"),
if(immutable, "🔒"),
),
raw_escape_sequence("\x1b[1;32m") ++ if(empty, "(empty)"),
raw_escape_sequence("\x1b[1;32m") ++ coalesce(
truncate_end(29, description.first_line(), ""),
"(no description set)",
) ++ raw_escape_sequence("\x1b[0m"),
)
' || {starship module git_branch && starship module git_status}
'';
};
};
git_state.disabled = true;
git_commit.disabled = true;
git_metrics.disabled = true;
git_branch.disabled = true;
git_status.disabled = true;
};
};
};
};
}

View File

@@ -1,17 +0,0 @@
{ config, lib, ... }:
lib.my.makeSwitch {
inherit config;
optionName = "all command line tools";
optionPath = [
"cmd"
"all"
];
config' = {
my.cmd = {
media.all.enable = true;
misc.enable = true;
monitor.all.enable = true;
shell.all.enable = true;
};
};
}

View File

@@ -1,10 +0,0 @@
{ ... }:
{
imports = [
./all.nix
./media
./misc
./monitor
./shell
];
}

View File

@@ -1,18 +0,0 @@
{ config, lib, ... }:
lib.my.makeSwitch {
inherit config;
optionName = "all command line media tools";
optionPath = [
"cmd"
"media"
"all"
];
config' = {
my.cmd.media = {
cava.enable = true;
go-musicfox.enable = true;
mpd.enable = true;
ffmpeg.enable = true;
};
};
}

View File

@@ -1,167 +0,0 @@
## Configuration file for CAVA. Default values are commented out. Use either ';' or '#' for commenting.
[general]
# Smoothing mode. Can be 'normal', 'scientific' or 'waves'.
mode = normal
# Accepts only non-negative values.
framerate = 60
# 'autosens' will attempt to decrease sensitivity if the bars peak. 1 = on, 0 = off
# 'overshoot' allows bars to overshoot (in % of terminal height) without initiating autosens.
; autosens = 1
; overshoot = 20
# Manual sensitivity in %. Autosens must be turned off for this to take effect.
# 200 means double height. Accepts only non-negative values.
; sensitivity = 100
# The number of bars (0-200). 0 sets it to auto (fill up console).
# Bars' width and space between bars in number of characters.
bars = 0
bar_width = 5
bar_spacing = 1
# Lower and higher cutoff frequencies for lowest and highest bars
# the bandwidth of the visualizer.
# Note: there is a minimum total bandwidth of 43Mhz x number of bars.
# Cava will automatically increase the higher cutoff if a too low band is specified.
; lower_cutoff_freq = 50
; higher_cutoff_freq = 10000
[input]
# Audio capturing method. Possible methods are: 'pulse', 'alsa' or 'fifo'.
# Defaults to 'pulse', 'alsa' or 'fifo', in that order, dependent on what support cava was built with.
#
# All input methods uses the same config variable 'source'
# to define where it should get the audio.
#
# For pulseaudio 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink
# (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them).
#
# For alsa 'source' will be the capture device.
# For fifo 'source' will be the path to fifo-file.
method = pulse
source = auto
; method = alsa
; source = hw:Loopback,1
; method = fifo
; source = /tmp/mpd.fifo
[output]
# Ouput method. Can be 'ncurses', 'noncurses' or 'raw'.
# 'noncurses' is for systems that does not suport ncurses.
# 'raw' is a 16 bit data stream of the bar heights that can be used to send to other applications.
# 'raw' defaults to 200 bars, which can be adjusted in the 'bars' option above.
method = ncurses
# Visual styles. Can be 'stereo' or 'mono'.
# 'stereo' mirrors both channels with low frequencies in center.
# 'mono' averages both channels and outputs left to right lowest to highest frequencies.
style = mono
# Raw output target. A fifo will be created if target does not exist.
; raw_target = /dev/stdout
# Raw data format. Can be 'binary' or 'ascii'.
; data_format = binary
# Binary bit format, can be '8bit' (0-255) or '16bit' (0-65530).
; bit_format = 16bit
# Ascii max value. In 'ascii' mode range will run from 0 to value specified here
; ascii_max_range = 1000
# Ascii delimiters. In ascii format each bar and frame is separated by a delimiters.
# Use decimal value in ascii table (i.e. 59 = ';' and 10 = '\n' (line feed)).
; bar_delimiter = 59
; frame_delimiter = 10
# [color]
# # Colors can be one of seven predefined: black, blue, cyan, green, magenta, red, white, yellow.
# # Or defined by hex code '#xxxxxx' (hex code must be within ''). User defined colors requires a
# # terminal that can change color definitions such as Gnome-terminal or rxvt.
# ; background = black
# ; foreground = cyan
# # Gradient mode, only hex defined colors are supported, background must also be defined in hex
# # or remain commented out. 1 = on, 0 = off. Warning: for certain terminal emulators cava will
# # not able to restore color definitions on exit, simply restart your terminal to restore colors.
# gradient = 1
# gradient_color_1 = '#0099ff'
# gradient_color_2 = '#ff3399'
[smoothing]
# Multiplier for the integral smoothing calculations. Takes values from 0-0.99.
# Higher values means smoother, but less precise. Set to 0 to disable.
; integral = 0.7
# Disables or enables the so-called "Monstercat smoothing". Set to 0 to disable.
; monstercat = 1
; waves = 1
# Set gravity multiplier for "drop off". Higher values means bars will drop faster.
# Accepts only non-negative values. 0.5 means half gravity, 2 means double. Set to 0 to disable "drop off".
; gravity = 2
# In bar height, bars that would have been lower that this will not be drawn.
; ignore = 0
[eq]
# This one is tricky. You can have as much keys as you want.
# Remember to uncomment more then one key! More keys = more precision.
# Look at readme.md on github for further explanations and examples.
#; 1 = 1 # bass
#; 2 = 1
#; 3 = 1 # midtone
#; 4 = 1
#; 5 = 1 # treble
1=1
2=1
3=2
4=1
5=1
[color]
#background = '#191724'
gradient = 1
gradient_count = 6
gradient_color_1 = '#31748f'
gradient_color_2 = '#9ccfd8'
gradient_color_3 = '#c4a7e7'
gradient_color_4 = '#ebbcba'
gradient_color_5 = '#f6c177'
gradient_color_6 = '#eb6f92'
[color]
gradient = 1
gradient_color_1 = '#94e2d5'
gradient_color_2 = '#89dceb'
gradient_color_3 = '#74c7ec'
gradient_color_4 = '#89b4fa'
gradient_color_5 = '#cba6f7'
gradient_color_6 = '#f5c2e7'
gradient_color_7 = '#eba0ac'
gradient_color_8 = '#f38ba8'

View File

@@ -1,167 +0,0 @@
## Configuration file for CAVA. Default values are commented out. Use either ';' or '#' for commenting.
[general]
# Smoothing mode. Can be 'normal', 'scientific' or 'waves'.
mode = normal
# Accepts only non-negative values.
framerate = 60
# 'autosens' will attempt to decrease sensitivity if the bars peak. 1 = on, 0 = off
# 'overshoot' allows bars to overshoot (in % of terminal height) without initiating autosens.
; autosens = 1
; overshoot = 20
# Manual sensitivity in %. Autosens must be turned off for this to take effect.
# 200 means double height. Accepts only non-negative values.
; sensitivity = 100
# The number of bars (0-200). 0 sets it to auto (fill up console).
# Bars' width and space between bars in number of characters.
bars = 0
bar_width = 2
bar_spacing = 1
# Lower and higher cutoff frequencies for lowest and highest bars
# the bandwidth of the visualizer.
# Note: there is a minimum total bandwidth of 43Mhz x number of bars.
# Cava will automatically increase the higher cutoff if a too low band is specified.
; lower_cutoff_freq = 50
; higher_cutoff_freq = 10000
[input]
# Audio capturing method. Possible methods are: 'pulse', 'alsa' or 'fifo'.
# Defaults to 'pulse', 'alsa' or 'fifo', in that order, dependent on what support cava was built with.
#
# All input methods uses the same config variable 'source'
# to define where it should get the audio.
#
# For pulseaudio 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink
# (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them).
#
# For alsa 'source' will be the capture device.
# For fifo 'source' will be the path to fifo-file.
method = pulse
source = auto
; method = alsa
; source = hw:Loopback,1
; method = fifo
; source = /tmp/mpd.fifo
[output]
# Ouput method. Can be 'ncurses', 'noncurses' or 'raw'.
# 'noncurses' is for systems that does not suport ncurses.
# 'raw' is a 16 bit data stream of the bar heights that can be used to send to other applications.
# 'raw' defaults to 200 bars, which can be adjusted in the 'bars' option above.
method = ncurses
# Visual styles. Can be 'stereo' or 'mono'.
# 'stereo' mirrors both channels with low frequencies in center.
# 'mono' averages both channels and outputs left to right lowest to highest frequencies.
style = mono
# Raw output target. A fifo will be created if target does not exist.
; raw_target = /dev/stdout
# Raw data format. Can be 'binary' or 'ascii'.
; data_format = binary
# Binary bit format, can be '8bit' (0-255) or '16bit' (0-65530).
; bit_format = 16bit
# Ascii max value. In 'ascii' mode range will run from 0 to value specified here
; ascii_max_range = 1000
# Ascii delimiters. In ascii format each bar and frame is separated by a delimiters.
# Use decimal value in ascii table (i.e. 59 = ';' and 10 = '\n' (line feed)).
; bar_delimiter = 59
; frame_delimiter = 10
# [color]
# # Colors can be one of seven predefined: black, blue, cyan, green, magenta, red, white, yellow.
# # Or defined by hex code '#xxxxxx' (hex code must be within ''). User defined colors requires a
# # terminal that can change color definitions such as Gnome-terminal or rxvt.
# ; background = black
# ; foreground = cyan
# # Gradient mode, only hex defined colors are supported, background must also be defined in hex
# # or remain commented out. 1 = on, 0 = off. Warning: for certain terminal emulators cava will
# # not able to restore color definitions on exit, simply restart your terminal to restore colors.
# gradient = 1
# gradient_color_1 = '#0099ff'
# gradient_color_2 = '#ff3399'
[smoothing]
# Multiplier for the integral smoothing calculations. Takes values from 0-0.99.
# Higher values means smoother, but less precise. Set to 0 to disable.
; integral = 0.7
# Disables or enables the so-called "Monstercat smoothing". Set to 0 to disable.
; monstercat = 1
; waves = 1
# Set gravity multiplier for "drop off". Higher values means bars will drop faster.
# Accepts only non-negative values. 0.5 means half gravity, 2 means double. Set to 0 to disable "drop off".
; gravity = 1
# In bar height, bars that would have been lower that this will not be drawn.
; ignore = 0
[eq]
# This one is tricky. You can have as much keys as you want.
# Remember to uncomment more then one key! More keys = more precision.
# Look at readme.md on github for further explanations and examples.
#; 1 = 1 # bass
#; 2 = 1
#; 3 = 1 # midtone
#; 4 = 1
#; 5 = 1 # treble
1=1
2=1
3=2
4=1
5=1
[color]
#background = '#191724'
gradient = 1
gradient_count = 6
gradient_color_1 = '#31748f'
gradient_color_2 = '#9ccfd8'
gradient_color_3 = '#c4a7e7'
gradient_color_4 = '#ebbcba'
gradient_color_5 = '#f6c177'
gradient_color_6 = '#eb6f92'
[color]
gradient = 1
gradient_color_1 = '#94e2d5'
gradient_color_2 = '#89dceb'
gradient_color_3 = '#74c7ec'
gradient_color_4 = '#89b4fa'
gradient_color_5 = '#cba6f7'
gradient_color_6 = '#f5c2e7'
gradient_color_7 = '#eba0ac'
gradient_color_8 = '#f38ba8'

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