Compare commits

...

411 Commits

Author SHA1 Message Date
4b99607f7b scripts/check-uninsane: annotate the OVPNS/DOOF checks 2024-06-17 09:25:10 +00:00
0d99293b2f servo: split the doof/ovpns netns config into its own module
a big thing this gets me is that the attributes (like IP addresses) are now accessible via 'config' an i won't have to hardcode them so much
2024-06-17 09:25:10 +00:00
b3890b82dc servo: http/https: expose to doof 2024-06-17 07:55:53 +00:00
3fc96a3e32 check-uninsane: also test http://uninsane.org, over OVPN connection 2024-06-17 07:50:15 +00:00
1af7b613bd servo: doof: respond to DNS queries 2024-06-17 07:39:52 +00:00
4c8695aae8 servo: fix missing route table for doof 2024-06-17 07:31:28 +00:00
d45e3fda5e servo: trust-dns: enable on doof-net 2024-06-17 07:20:23 +00:00
456e0de872 servo: doof net: add the capability to forward ports 2024-06-17 07:20:23 +00:00
7825ddc123 servo: split out a "bridgedWireguardNamespace" helper for configuring ovpns VPN
i can re-use this to forward traffic over doof
2024-06-17 07:20:23 +00:00
dd47a5083c servo: only forward ports to OVPN which are actually marked for visiblity 2024-06-17 06:29:09 +00:00
14d5d9eb5a servo: net: remove dead Hurricane Electric code 2024-06-17 06:04:29 +00:00
1f6f2399d6 nwg-panel: fix swaync icon 2024-06-16 06:35:32 +00:00
b0ee12ba7b modules/users: export HOME in environment.d because some services (nwg-panel) need it 2024-06-16 06:01:20 +00:00
a6d268ca72 nwg-panel: disable the brightness indicator 2024-06-16 05:42:58 +00:00
1ecc033ff5 nwg-panel: re-add missing style.css 2024-06-16 05:27:32 +00:00
c87dab93b3 scripts/deploy: allow specifying multiple hosts or multiple variants 2024-06-16 05:15:12 +00:00
53139a7cdf nwg-panel: address some TODOs 2024-06-16 04:59:23 +00:00
f37014a856 nwg-panel: minor tweaks & simplifications 2024-06-15 22:52:52 +00:00
0237d3a144 nwg-panel: fix broken JSON generation
heh, whoops
2024-06-15 22:24:41 +00:00
656ad76f25 nwg-panel/config: sort keys 2024-06-15 22:04:08 +00:00
b7c71dc67b nwg-panel: add a few comments/TODOs to the config 2024-06-15 21:56:41 +00:00
aaa40eae04 nwg-panel: port config to Nix
this makes it easier to plumb config into it, and also to comment it
2024-06-15 21:52:38 +00:00
d8ed82cfdf cross: remove upstreamed libvpx patch 2024-06-15 11:37:20 +00:00
0e73f95ab1 nixpkgs: 2024-06-14 -> 2024-06-15 2024-06-15 11:16:40 +00:00
b1ba0cad03 nixpkgs-wayland: minor bump 2024-06-15 11:16:32 +00:00
4bcbfbc8aa uassets: 2024-06-14 -> 2024-06-15 2024-06-15 11:16:16 +00:00
0f6c9f3cde sane-sysinfo: add a way to render memory use 2024-06-15 11:12:45 +00:00
f4d806c0c2 sane-sysinfo: handle the case of no battery 2024-06-15 10:35:32 +00:00
6963998519 refactor: sane-sysinfo: more cleanups 2024-06-15 10:34:39 +00:00
a63f6281c5 refactor: sane-sysinfo: clean up a bit more 2024-06-15 10:26:22 +00:00
df0a8cf900 refactor: sane-sysinfo: split out a BatteryInfo class 2024-06-15 09:46:58 +00:00
a4f5343fb5 sane-sysinfo: port to Python
it's a pretty literal port; probably has some bugs
2024-06-15 08:59:50 +00:00
c50a4d1d71 static-nix-shell: fix mkBash scripts to actually be invokable from the CLI
they need the `bash` package! how did this work before?
2024-06-15 07:42:04 +00:00
aadbeab3ac doc: nwg-panel: point out that it really is ok to build w/o wlr-randr 2024-06-15 06:53:38 +00:00
aafcf7b478 lift sane-battery-estimate out of conky, rename to sane-sysinfo 2024-06-15 06:52:54 +00:00
a78b840215 nwg-panel: enable per-app volume controls 2024-06-15 03:59:36 +00:00
3c2347faba nwg-panel: fixup the formatting
especially, make it fit on moby
2024-06-15 03:49:01 +00:00
ebff35a378 add missing sane-nix-files
hmm. not great that i could deploy even without this being checked into git....
2024-06-15 03:37:19 +00:00
1515f01384 zsh: add alias: :fg -> fg 2024-06-15 03:26:36 +00:00
60a5c61500 default.nix: pass through host config and fs 2024-06-15 03:18:16 +00:00
417b85450c tod.md: notes about nwg-panel cleanup 2024-06-15 00:54:01 +00:00
2e0a3dc8ef nwg-panel: fix cross-compiled result to not ship build-time dependencies 2024-06-15 00:52:31 +00:00
3165c95d0f sysvol: 2024-06-09 -> 2024-06-13 2024-06-15 00:28:03 +00:00
6dd4d9da3e uassets: 2024-06-12 -> 2024-06-14 2024-06-15 00:19:40 +00:00
5a086b359d nixpkgs-wayland: 2024-06-12 -> 2024-06-14 2024-06-15 00:19:25 +00:00
a204f0a987 nixpkgs: 2024-06-12 -> 2024-06-14 2024-06-15 00:18:41 +00:00
317251338c todo.md: note that s6 is not re-entrant 2024-06-14 20:26:30 +00:00
01cfed2438 scripts/deploy: swap the iteration order: build all hosts at -min variant, then -light, etc; then also do the -next variants 2024-06-14 20:24:50 +00:00
ba0524d193 scripts/update: dont update feeds by default 2024-06-14 18:29:06 +00:00
26a4f20f6c scripts/deploy: factor out a deployHelper to make variant=all usable *without* host=all 2024-06-14 18:28:52 +00:00
46f5a7e37d nwg-panel: patch it to cross compile (by purging bluetooth/randr) 2024-06-14 09:34:17 +00:00
88a487f565 /etc/nixos: link in such a way that i dont pick up a whole bunch of garbage
it seemed to also be causing some non-determinism when deploying to crappy

ideally i would seal the whole nix build, by only evaluating all this config *after* building 'sane-nix-files'
2024-06-14 09:18:15 +00:00
d037afd75c sane-nix-files: define this repo as a package
setup as a dirty git repo, intentionally
2024-06-14 09:18:15 +00:00
654858f8ff nwg-panel: theme the calendar 2024-06-14 09:17:46 +00:00
5abcc7d399 nwg-panel: fix @workspaceNumbers typo 2024-06-14 08:50:28 +00:00
65823507ad nwg-panel: make workspace numbers/hiding configurable 2024-06-14 08:47:24 +00:00
63a88da3b4 moby: switch from waybar -> nwg-panel 2024-06-14 08:47:24 +00:00
734da36639 nwg-panel: make configurable through nix 2024-06-14 08:47:24 +00:00
49ccf95fb3 nwg-panel: style.css: fix line endings?
idk, i just copied + pasted the contents back, and now the file is 200B smaller and i dont see ^M in git
2024-06-14 08:47:24 +00:00
e70d0f3c8e nwg-panel: style.css: fix indentation 2024-06-14 08:47:24 +00:00
c00cccd429 nwg-panel: disable the green border hover for *all* items 2024-06-14 08:47:24 +00:00
02fdc91237 sway: switch from waybar -> nwg-panel (except for moby) 2024-06-14 08:47:24 +00:00
14616f9b61 nwg-panel: stylize 2024-06-14 08:47:24 +00:00
f9d856b3bb waybar: fix typo 2024-06-14 08:47:24 +00:00
d52db06ffe nwg-panel: implement, but dont ship by default 2024-06-14 08:47:24 +00:00
Shelvacu
dc2c31f220 gitea: keep login session alive for 30 days 2024-06-14 03:34:42 +00:00
52322e3207 switchboard: fix cross compilation 2024-06-14 03:29:02 +00:00
26f1f2b581 remove unused flake.lock file 2024-06-14 03:08:07 +00:00
74c188012a todo.md: install folio 2024-06-13 20:53:16 +00:00
e0c741427e ship "switchboard" program, for configuring bluetooth/network/sound 2024-06-13 19:51:19 +00:00
999a173001 sane-tag-music: --trackno "" fix-tags FOO can be used to clear FOOs track number field 2024-06-13 08:22:57 +00:00
330a64d820 feeds: add xorvoid.com 2024-06-13 04:46:12 +00:00
2e2f5dd373 scripts/sync: remove unnecessary sudo calls when mounting 2024-06-13 03:15:58 +00:00
5561dde31d readme: update for a flake-free world 2024-06-13 03:14:27 +00:00
c3ae60d71b flake.nix: remove (no longer used) 2024-06-13 03:09:45 +00:00
1c79209e23 scripts/sync: lift out of flake 2024-06-13 03:09:02 +00:00
6d1db1ee67 feeds: update metadata 2024-06-13 03:03:15 +00:00
88d462764f feeds: fix to work with scripts/update 2024-06-13 02:18:30 +00:00
8f634d9bb0 todo.md: address the sudo-related items 2024-06-13 01:30:44 +00:00
3e35210e4b systemd: allow wheel users to start/stop any service 2024-06-13 01:30:18 +00:00
04f4d330a8 programs: enable free 2024-06-13 01:09:48 +00:00
ce60e53b9a programs: add ps 2024-06-13 01:04:24 +00:00
3ff9f974a6 programs: enable watch 2024-06-13 00:59:34 +00:00
11e9ad5eca unl0kr.conf: fix formatting 2024-06-13 00:13:33 +00:00
bf99a64b89 unl0kr: fix that unl0kr wasnt always visible (so, wait for /dev/fb0 to appear before launch) 2024-06-13 00:13:19 +00:00
3b43562841 todo.md: address completed moby input-still-enabled-when-screen-off issue 2024-06-13 00:12:26 +00:00
131e43e975 scripts/deploy: avoid ssh-based copies to self 2024-06-13 00:12:00 +00:00
e34a9957e3 hosts/common/nix: migrate the nixpkgs-overlay integration point (part 2) 2024-06-12 23:32:18 +00:00
ea1a0b72b5 hosts/common/nix: migrate the nixpkgs-overlay integration point (part 1)
this has to be done in two steps to avoid nix-daemon bugs
2024-06-12 23:20:37 +00:00
aab9ed0d35 zsh: switch: pass through args 2024-06-12 23:09:35 +00:00
f477370e4c scripts/deploy: add more logging 2024-06-12 23:09:32 +00:00
b5fc8cfd4e scripts/deploy: when deploying all machines, dont let one failed deployment abort the whole job 2024-06-12 23:09:27 +00:00
4fdaacf8ad nit: use pkg.extend in place of pkgs.appendOverlays where applicable 2024-06-12 23:09:16 +00:00
f1705686b8 fix: dont double-apply overlays
previous behavior was that overlays were *implicitly* applied when i
imported nixpkgs, and then explicitly applied again later in the config.

for some reason i can't remove (or adjust?) the implicit application
without causing evals to hang w/o so much as any error message.
2024-06-12 23:08:04 +00:00
0d0fa8b37f nixpkgs: 2024-06-11 -> 2024-06-12 2024-06-12 09:42:55 +00:00
b5b39d1500 scripts/deploy: add the equivalent of my "pre-deploy" functionality 2024-06-12 09:04:17 +00:00
86482e922c scripts/update: add a --dry-run option 2024-06-12 08:44:02 +00:00
111c69b368 firefox.extensions.metamask: 11.16.8 -> 11.16.9 2024-06-12 08:37:59 +00:00
60c13d34a7 nixpkgs-wayland: 2024-06-08 -> 2024-06-12 2024-06-12 08:37:35 +00:00
823d064ab0 sops-nix: 2024-06-03 -> 2024-06-11 2024-06-12 08:35:54 +00:00
3f88d750c6 uassets: 2024-06-08 -> 2024-06-12 2024-06-12 08:35:34 +00:00
05f29ba01e sysvol: 2024-06-07 -> 2024-06-09 2024-06-12 08:35:22 +00:00
2b11bac1eb scripts: add an "update" script to update all my packages
it probably doesnt update feeds yet, though
2024-06-12 08:29:45 +00:00
86adc38537 zsh: fix switch alias for a post-flake world 2024-06-12 08:29:08 +00:00
b787289b39 scripts/deploy: if no host is specified, then deploy to the current host 2024-06-12 07:44:21 +00:00
63f3b8e89b handbrake: disable until i fix the build 2024-06-12 07:40:29 +00:00
448b8007ca scripts: remove outdated flake update script 2024-06-12 07:11:41 +00:00
9fc4119275 mesa-demos: deploy 2024-06-12 07:11:41 +00:00
8f1332797d crappy: dont auto-start messengers 2024-06-12 07:11:41 +00:00
368184e24f flake: add a crappy-min-next deploy target 2024-06-12 07:11:41 +00:00
c8e73d3f76 crappy: add user to "render" group 2024-06-12 07:11:41 +00:00
43da4955b7 crappy: deploy linux-exynos5-mainline kernel 2024-06-12 07:11:41 +00:00
46e9d5f758 programs: fix s6 deps when dbus isnt enabled 2024-06-12 07:11:41 +00:00
66a012b555 nixpkgs: 2024-06-08 -> 2024-06-11
i haven't actually deployed this yet: i'm pulling it for crappy-staging, but had to update all branches because the trust-dns patch didn't apply cleanly
2024-06-12 07:11:41 +00:00
fff965ab9b linux-postmarketos-exynos5: build with LIMA/MALI enabled as well (experimental) 2024-06-12 07:11:41 +00:00
406adde549 scripts/deploy: skip the signing step if we have no signing key 2024-06-12 07:11:14 +00:00
c9b2699c9f nixpkgs: fix sysvol patch hash 2024-06-12 07:03:23 +00:00
f91d3e35f3 flake: port deploy script to its own thing 2024-06-12 05:48:03 +00:00
4712ba9f2d check-nur: extract from the flake 2024-06-12 02:50:51 +00:00
03b2f2a433 rename health-check -> check-uninsane so i can expand the checks 2024-06-12 02:35:07 +00:00
51b1a6e679 default.nix: define attributes necessary to build any of my hosts or their packages 2024-06-12 02:21:50 +00:00
f148e5a580 pkgs: fix infinite recursion when evaluating nix-build -A MY_PKG 2024-06-12 01:18:17 +00:00
079f945f38 unl0kr: 2.0.0 -> 3.2.0 2024-06-12 00:49:26 +00:00
29cc7e4676 flake: add targets to deploy to crappy 2024-06-12 00:49:14 +00:00
11c97fd4c0 crappy: actually enable landlock 2024-06-11 00:47:30 +00:00
a5cb989c59 hosts/common: add remote /mnt/crappy/home mount 2024-06-11 00:36:18 +00:00
3d77a7cbc9 secrets/common: allow crappy to access these secrets 2024-06-11 00:27:37 +00:00
8e7401955f hosts/common: add crappy's pubkey/lan IP 2024-06-11 00:27:14 +00:00
fa605768e7 hosts/common: enable ALL firmware -- not just the "redistributable" stuff 2024-06-11 00:26:52 +00:00
3c279edd31 feeds: unsubscribe from Vsauce 2024-06-11 00:26:17 +00:00
a736d6d77b crappy: get it to load the firmware required for its wifi chipset (mwifiex_sdio) 2024-06-11 00:26:02 +00:00
8ad118162e doc: how to recover or add new hosts 2024-06-11 00:25:00 +00:00
5c13bb20d7 crappy: test (but dont deploy) a linux_latest kernel w/ panel patch
it doesn't boot, not sure why
2024-06-10 21:26:59 +00:00
170d36fc05 crappy: fix u-boot boot order to include usb 2024-06-10 06:07:53 +00:00
b828edf3c7 hal/samsung: remove some dead code 2024-06-10 03:49:43 +00:00
e10dfaefe9 hal/samsung: test a bunch of different kernels; enable linux_latest which works if i patch it 2024-06-10 03:48:31 +00:00
49e1a85afb linux-postmarketos-exynos5: test some patches for enabling graphics output on later kernels 2024-06-10 03:47:35 +00:00
56dfe8baa8 linux-exynos5-mainline: init
it builds, but is not bootable on samsung chromebook
2024-06-09 20:35:13 +00:00
95685fe91f linux-postmarketos-*: factor out a sane-kernel-tools helper set 2024-06-09 19:34:07 +00:00
8f6b4cc551 refactor/rename: linux-postmarketos -> linux-postmarketos-allwinner 2024-06-09 18:43:38 +00:00
89c9733ed2 linux-postmarketos-exynos5: add "optimizeForSize" option 2024-06-09 18:40:38 +00:00
ec29ec76f0 swayidle: fix that input events werent suppressed during screen-off 2024-06-09 18:36:57 +00:00
0f97e3d7ed sane-input-handler: fix that input events werent suppressed during screen-off
note that this doesn't fix input gating during the
screenoff-after-inactivity case.
2024-06-09 18:28:31 +00:00
6fb5cedd69 linux-postmarketos-exynos5: allow overriding the linux version 2024-06-09 17:48:46 +00:00
0382af1fae linux-postmarketos-exynos5: actually, i dont need to build with CC_OPTIMIZE_FOR_SIZE=y 2024-06-09 07:00:26 +00:00
b24b68a6bd mpv: switch to mainline mpv 2024-06-09 06:48:43 +00:00
952da0f314 sysvol: build via the package as it will appear in nixpkgs 2024-06-09 06:34:09 +00:00
cb32dc99cd sysvol: fix background transparency 2024-06-09 01:50:39 +00:00
5e7a05c183 sysvol: remove unused finalAttrs 2024-06-09 01:11:54 +00:00
656b478cc0 nixpkgs: remove ancient commented-out patches 2024-06-09 00:55:28 +00:00
fbbc0eb294 nixpkgs: cleanup patching implementation 2024-06-09 00:52:01 +00:00
502c9d1db3 nixpkgs: 24.05-unstable-2024-06-xx -> 24.05-unstable-2024-06-08 2024-06-09 00:48:52 +00:00
36934eedfd nixpkgs-wayland: 0-unstable-2024-06-xx -> 0-unstable-2024-06-08 2024-06-09 00:48:26 +00:00
56f982e214 delfin: remove
it's in nixpkgs now, and the co-maintainer is doing a very good job with it
2024-06-09 00:17:04 +00:00
54c4cd53b3 firefox-extensions: ether-metamask, sponsorblock, ublacklist -> latest 2024-06-09 00:01:12 +00:00
1c4fc335b3 uassets: 0-unstable-2024-05-27 -> 0-unstable-2024-06-08 2024-06-09 00:00:44 +00:00
21d3f41b38 signal-desktop-from-src: 7.8.0 -> 7.11.1 2024-06-09 00:00:27 +00:00
031ce236f3 firefox-extensions: fix the update script to not grab betas for u-block 2024-06-08 23:43:35 +00:00
a4eb073918 signal-desktop-from-src: fix the update script to ignore betas 2024-06-08 23:13:56 +00:00
75ae868bde nixpkgs: don't fail build if a patch has already been applied 2024-06-08 22:49:55 +00:00
b6d9d58a14 firefox-extensions.bypass-paywalls-clean: disable updateScript 2024-06-08 22:08:25 +00:00
14a5b8d9f2 nixpkgs: get the updateScripts to be populated into me update.pkgs.* attrs 2024-06-08 22:01:33 +00:00
ede68b563e nixpkgs-{staging,next}: add an update script 2024-06-08 21:15:47 +00:00
33f4db254d nixpkgs: add an update script
this only updates the master branch -- for now
2024-06-08 20:44:23 +00:00
6e8cb1bbb2 nixpkgs-wayland: add an update script 2024-06-08 20:24:56 +00:00
b00fb22137 sops-nix: add an update script 2024-06-08 20:22:04 +00:00
4d74c2ede6 sysvol: 0-unstable-2024-04-11 -> 0-unstable-2024-06-07 2024-06-08 20:11:07 +00:00
c4c5a640ce sysvol: add an update script 2024-06-08 19:58:29 +00:00
514fbca3f1 gitea: enable push-to-create for new repositories 2024-06-08 03:46:52 +00:00
71a19e247f fix check.nur (dont use builtin fetchers when stdenv ones are available) 2024-06-08 03:28:47 +00:00
Shelvacu
bcab89dbfb gitea: enable push-to-create for new repositories 2024-06-07 20:27:43 -07:00
f219c59ad5 nixpkgs: acquire via builtins.fetchGit instead of flake
i'll probably delete this toplevel flake at some point as well
2024-06-08 01:37:47 +00:00
197df696be uninsane-dot-org: acquire by fetchFromGitea instead of flake 2024-06-07 22:52:07 +00:00
c9b7f58f3d sops-nix: acquire via fetchFromGitHub instead of flake
i don't like the hacks i have to do to mix `fetchFromGitHub` and nixos
modules though.
2024-06-07 22:40:53 +00:00
6b8371c32b nixpkgs-wayland: import by fetchFromGitHub instead of via flake 2024-06-07 21:29:45 +00:00
11cdac0357 mobile-nixos: import by fetchFromGitHub instead of via flake 2024-06-07 21:15:54 +00:00
8b607ddefd nixpkgs: 2024-06-05 ->2024-06-07; nixpkgs-wayland
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/f1f4d07f9015e5da5fe416e87c6bbd9f569a5c60' (2024-06-05)
  → 'github:nixos/nixpkgs/5aa86ae5585cd46299ee46682fda8a9b76baf2ae' (2024-06-07)
• Updated input 'nixpkgs-staging-unpatched':
    'github:nixos/nixpkgs/d7993cebbcd4f9f3a07a8d418853b586d301be56' (2024-06-05)
  → 'github:nixos/nixpkgs/da9d22446697971278edcd4af92f63221f7d21f6' (2024-06-07)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/c3759101288ea92aec42ab7b8aed4e967cfb8eb3' (2024-06-04)
  → 'github:nixos/nixpkgs/716a7056386dcc67eb3b813289499d6329d4befc' (2024-06-07)
• Updated input 'nixpkgs-wayland':
    'github:nix-community/nixpkgs-wayland/93b225ddba91179248b378913a91defbc6aeb899' (2024-05-31)
  → 'github:nix-community/nixpkgs-wayland/8e2d180329f4009ac06042b50ca0a356722aea19' (2024-06-07)
• Updated input 'nixpkgs-wayland/flake-compat':
    'github:nix-community/flake-compat/8bf105319d44f6b9f0d764efa4fdef9f1cc9ba1c' (2023-06-29)
  → 'github:nix-community/flake-compat/38fd3954cf65ce6faf3d0d45cd26059e059f07ea' (2024-06-02)
• Updated input 'nixpkgs-wayland/lib-aggregate':
    'github:nix-community/lib-aggregate/dbc9130fe1455e0f6ee4d8f5f799f9be551f866b' (2024-05-26)
  → 'github:nix-community/lib-aggregate/64d43e2bbc6eab8d1cbdfba96d90a71e15a847d7' (2024-06-02)
• Updated input 'nixpkgs-wayland/lib-aggregate/nixpkgs-lib':
    'github:nix-community/nixpkgs.lib/d0d27192931680482081aa1c38389da2af84a651' (2024-05-26)
  → 'github:nix-community/nixpkgs.lib/e090cb30ae82f4b4461aafdb808847c6c97b08c2' (2024-06-02)
• Updated input 'nixpkgs-wayland/nix-eval-jobs':
    'github:nix-community/nix-eval-jobs/bb95091f6c6f38f6cfc215a1797a2dd466312c8b' (2024-05-15)
  → 'github:nix-community/nix-eval-jobs/b6169e08e76e10b673d1b54f944cddb1e7cbea97' (2024-06-06)
```
2024-06-07 09:08:24 +00:00
10158bb444 rename snowy -> crappy
get it? it's the crappy version of lappy
2024-06-07 08:04:57 +00:00
1dd10450f2 modules/image: remove extraneous sane.image.enable option 2024-06-07 07:42:47 +00:00
e104499636 modules/hal/samsung: cleanup 2024-06-07 07:39:30 +00:00
56cd1f211c scripts/update: expand 2024-06-07 07:34:51 +00:00
14f4f1e80d hosts: add snowy
the Samsung Chromebook thing
2024-06-07 07:34:35 +00:00
52a0e8cf53 modules/hal/samsung: init
this can be used to get baseline support for samsung exynos5 chromebook

i should probably rename it, in time
2024-06-07 07:33:46 +00:00
50450fe7fe brave: fix eval error on armv7l 2024-06-07 07:32:24 +00:00
4a4ffadc64 fractal-nixified: fix cross to armv7l 2024-06-07 07:32:08 +00:00
8807140c83 neovim: fix cross to armv7l 2024-06-07 07:31:44 +00:00
adc811efa1 libvpx: fix cross to armv7l 2024-06-07 07:31:27 +00:00
d8fed884d0 programs: steam: move from pcGuiApps -> pcGameApps 2024-06-07 07:30:56 +00:00
d75f59ba06 modules/image: increase the default boot partition size from 512 MiB -> 1024 MiB 2024-06-07 07:29:50 +00:00
aa0a395353 nit: fix image output to be a file, not an item inside a folder 2024-06-07 07:28:56 +00:00
56d84dea4d hosts: remove unused (defaulted) option: boot.loader.efi.canTouchEfiVariables 2024-06-07 07:27:34 +00:00
3aa2ece59b modules/programs: convert lib.optionalAttrs to mkIf
this allows stuff to be lazier
2024-06-07 07:26:07 +00:00
07239d2a75 nixpatches: link to outstanding libvpx fix 2024-06-07 07:25:36 +00:00
3fd5e15e93 linux-postmarketos-exynos5: init
i'll need this for a default chromebook install
2024-06-07 07:24:48 +00:00
97d56b0314 flake: add a pkgs.python template 2024-06-07 07:23:35 +00:00
c18554dfbd depthcharge-tools: init at 0.6.2 2024-06-07 07:22:18 +00:00
8105e00b39 refactor: make system.stateVersion common across all hosts.
otherwise it's hairy to share nixos configs/modules between them

note that this alters the stateVersion for desko/lappy/rescue, but unlikely to matter
2024-06-04 15:58:53 +00:00
7e32fab5d4 refactor: moby: split more stuff out of the toplevel config and hide behind roles/etc 2024-06-04 15:58:51 +00:00
25298c9be6 lappy: remove unused xkb_mobile_normal_buttons 2024-06-04 14:40:03 +00:00
e61549d917 moby: split remaining polyfill into roles.handheld 2024-06-04 14:38:32 +00:00
eca14a644b refactor: moby: lift some of the polyfill out to pine64 hal 2024-06-04 14:36:46 +00:00
3937121522 refactor: moby: split pinephone-specific stuff into sane.hal.pine64 2024-06-04 14:35:34 +00:00
b334db28c6 refactor: hide x86_64-specific host config in a module 2024-06-04 14:26:24 +00:00
b52057e317 refactor: split "quirks.nix" out of hosts/common/hardware/default.nix 2024-06-04 14:14:22 +00:00
414ab85e20 refactor: move hosts/common/hardware/default.nix into hosts/common/boot.nix 2024-06-04 14:12:28 +00:00
82133a8f16 refactor: move logind config into systemd.nix 2024-06-04 14:09:58 +00:00
43a63d4f6e hosts/modules: remove unused yggdrasil 2024-06-04 13:58:49 +00:00
9f9fc7d65b moby: also sync books from servo 2024-06-04 10:08:25 +00:00
79d395e01c nixpkgs: 2024-06-03 -> 2024-06-04, sops-nix
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/c987c730bbf2121264ebd68921b443db5bb28543' (2024-06-03)
  → 'github:nixos/nixpkgs/6a56765581a4dcf961a90faf54d32edb991bd315' (2024-06-04)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/77a51024c0f953d503eb3ed364aa4bff378649f8' (2024-06-03)
  → 'github:nixos/nixpkgs/c3759101288ea92aec42ab7b8aed4e967cfb8eb3' (2024-06-04)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/ab2a43b0d21d1d37d4d5726a892f714eaeb4b075' (2024-06-02)
  → 'github:Mic92/sops-nix/d4555e80d80d2fa77f0a44201ca299f9602492a0' (2024-06-03)
```
2024-06-04 06:35:29 +00:00
394259fe21 modemmanager: harden systemd service 2024-06-03 16:41:51 +00:00
8c256c629b networkmanager: harden further with NoNewPrivileges and PrivateTmp 2024-06-03 16:23:22 +00:00
0e2d86ac96 NetworkManager-dispatcher: note why we cant use DynamicUser 2024-06-03 15:57:41 +00:00
e2a1e6730d NetworkManager-dispatcher: harden systemd service 2024-06-03 15:44:22 +00:00
a1e923f999 networkmanager: tighten ProtectSystem to "strict" 2024-06-03 15:10:14 +00:00
09333c992c wpa_supplicant: harden systemd service 2024-06-03 15:09:32 +00:00
80eb385c64 networkmanager: restrict service (using systemd options) 2024-06-03 14:27:00 +00:00
f6725f60b9 networkmanager: re-introduce my polkit patches 2024-06-03 13:04:48 +00:00
2f1592376d document more sandbox limitations 2024-06-03 11:59:44 +00:00
42fed64b75 NetworkManager: split specific config options out of my main net/default.nix file 2024-06-03 11:24:38 +00:00
682143d47f NetworkManager: 1.46.0 -> 1.48.0
mostly so i can review the PR and get this update mainlined sooner :)
2024-06-03 11:23:33 +00:00
1448cb4444 sane-reboot: fix operation on servo 2024-06-03 09:33:35 +00:00
2d07ff966b health-check: mention failed systemd services 2024-06-03 09:30:02 +00:00
83404f6769 nixos/networkmanager patch: grab via PR 2024-06-03 07:49:53 +00:00
c6bb6e2e3c megapixels-next: fix broken eval of metadata 2024-06-03 05:35:09 +00:00
9d109644b7 nixpkgs: 2024-06-01 -> 2024-06-03; sops-nix -> 2024-06-02
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/f7de25c01e4c073c06e0525226a0c2311d530cee' (2024-06-01)
  → 'github:nixos/nixpkgs/c987c730bbf2121264ebd68921b443db5bb28543' (2024-06-03)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/61c1d282153dbfcb5fe413c228d172d0fe7c2a7e' (2024-06-01)
  → 'github:nixos/nixpkgs/77a51024c0f953d503eb3ed364aa4bff378649f8' (2024-06-03)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/962797a8d7f15ed7033031731d0bb77244839960' (2024-05-26)
  → 'github:Mic92/sops-nix/ab2a43b0d21d1d37d4d5726a892f714eaeb4b075' (2024-06-02)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/59a450646ec8ee0397f5fa54a08573e8240eb91f' (2024-05-25)
  → 'github:NixOS/nixpkgs/3b1b4895b2c5f9f5544d02132896aeb9ceea77bc' (2024-06-01)
```
2024-06-03 05:31:28 +00:00
0050403b31 scripts: add an update helper
someday i can extend this for updating packages and feeds too
2024-06-03 05:30:03 +00:00
e4bcbab224 hosts: networking: switch to using nixos NetworkManager/ModemManager/etc, just patched for hardening 2024-06-02 11:22:03 +00:00
1b85aa0441 networkmanager/modemmanager: get closer to nixpkgs upstream
i've seen enough, that there's a path toward getting nixos proper to sandbox this in a way i'm happy with -- in time
2024-06-02 08:56:38 +00:00
f5e5d1bcc4 networkmanager: fix polkit integrations when running not as root
now nmcli/etc work
2024-06-02 05:10:11 +00:00
30d41f82f2 refactor: networkmanager: use substitute instead of sed when patching 2024-06-01 22:16:18 +00:00
62dbad3486 polyunfill: remove a few more default systemPackages 2024-06-01 21:06:40 +00:00
4287ecf0ed polyfill: don't ship unused mtools package 2024-06-01 20:15:04 +00:00
b13ca92b72 polyfill: remove boot.{enableContainers,bcache} 2024-06-01 20:14:49 +00:00
45e121eb1c make-sandboxed: preserve meta.mainProgram 2024-06-01 20:01:24 +00:00
53bbd611da nixpkgs-review: persist the ~/.cache/nixpkgs-review directory 2024-06-01 17:15:54 +00:00
f0128b9496 apply patch for when trust-dns is renamed to hickory-dns 2024-06-01 17:07:44 +00:00
368169d48d todo.md: start documenting sudo issues 2024-06-01 17:06:36 +00:00
cb1d5d53c6 feeds: add mintcast podcast 2024-06-01 16:28:42 +00:00
a5a635f00b sftpgo: simplify my package override now that sftpgo 2.6.0 is merged 2024-06-01 16:22:22 +00:00
6fe3d26b30 modemmanager: fix missing mmcli binary in service definition 2024-06-01 15:41:14 +00:00
8340cf059f nixpkgs-review: fix sandboxing 2024-06-01 15:26:23 +00:00
e0da3ece60 errno: simplify 2024-06-01 14:48:55 +00:00
8ea379d53b errno: ship on all platforms 2024-06-01 14:04:45 +00:00
c7dd49af91 errno: fix cross compilation by not building *all* of moreutils 2024-06-01 14:03:59 +00:00
e8b900c722 todo.md: add media looping controls 2024-06-01 13:37:51 +00:00
36f4fa3018 checkSandboxed: fix so that cross-built scripts can be checked again
how did this work earlier? does lappy have binfmt enabled??
2024-06-01 13:24:41 +00:00
d8d11de9bc sftpgo: replace deprecated "crypt" with "passlib" 2024-06-01 13:01:19 +00:00
07194d062a servo: nfs: disable 2024-06-01 12:45:10 +00:00
24c49df75f health-check: add a check that ftp://uninsane.org is operational 2024-06-01 12:42:53 +00:00
9f7e143d5e todo.md: add some kernel work to be done 2024-06-01 12:38:28 +00:00
0a382ae8a3 todo.md: remove completed "landlock sandboxer prints garbage" item 2024-06-01 12:35:46 +00:00
96f177ceb2 docs: overlays/cross: slightly tidy up the "outstanding issues" part 2024-06-01 12:24:00 +00:00
2aa3fa35b8 nixpkgs: 2024-05-31 -> 2024-06-01; nixpkgs-wayland -> 2024-05-31
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/8a0a33b56d6279fec4827da602882561ef00f2fb' (2024-05-31)
  → 'github:nixos/nixpkgs/f7de25c01e4c073c06e0525226a0c2311d530cee' (2024-06-01)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/7ccd1516effbc5510391d3b498a7a3bef92a090b' (2024-05-31)
  → 'github:nixos/nixpkgs/61c1d282153dbfcb5fe413c228d172d0fe7c2a7e' (2024-06-01)
• Updated input 'nixpkgs-wayland':
    'github:nix-community/nixpkgs-wayland/1db9b79a45c8e346e03480767e6d9749fabfaf10' (2024-05-31)
  → 'github:nix-community/nixpkgs-wayland/93b225ddba91179248b378913a91defbc6aeb899' (2024-05-31)
```
2024-06-01 12:20:45 +00:00
8657cf1fcf ship ausyscall binary 2024-06-01 12:17:08 +00:00
f875db916d sandboxing: fix checkSandboxed to handle packages with multiple outputs 2024-06-01 12:12:46 +00:00
e3e86a43a9 brightnessctl: disable unused dbus access 2024-06-01 12:09:51 +00:00
05986d363d brightnessctl: fix udev rules so i can run it again 2024-06-01 12:02:24 +00:00
539d9e45a2 networkmanager/modemmanager: ship separate packages for the daemon and CLI tools
they require fundamentally different sandboxing approaches. the daemon *can't* always use bwrap if it wants to run as non-root. meanwhile the CLI tools would mostly *prefer* to run under bwrap.

in the long term i'll maybe upstream the systemd sandboxing into nixpkgs, where there looks to be desire for it
2024-05-31 23:26:16 +00:00
a380bd04c4 trivial-builders: init deepLinkIntoOwnPackage 2024-05-31 23:26:16 +00:00
f296d8df93 make-sandboxed: fix multi-output packages and sandbox *all* their outputs
this mostly applies to the wrapperType = 'inplace' users
2024-05-31 23:26:16 +00:00
326bf045b0 networkmanager/wpa_supplicant: switch user back to "networkmanager"
root gives too much power, even with bwrap/namespaces
2024-05-31 23:26:16 +00:00
a1181a10ea networkmanager: install parallel dbus .conf files to allow the services to be run as *either* networkmanager or root user (hopefully!) 2024-05-31 23:26:16 +00:00
9bb6a903bb wpa_supplicant: get it to run under bwrap 2024-05-31 23:26:16 +00:00
214f963d89 networkmanager: run all services as root instead of networkmanager user
i believe this may allow using bwrap instead of landlock
2024-05-31 23:26:16 +00:00
c7eb4b66a5 polyunfill: remove unused su and sg security wrappers 2024-05-31 14:59:23 +00:00
452543e6f3 fix rescue host build 2024-05-31 10:37:03 +00:00
d692ac9851 overlays/cross: remove broken cdrtools fix (that project is INSANE) 2024-05-31 09:40:44 +00:00
5cba283859 overlays/cross: update upstreaming status
my part of the gnome2.GConf fix was actually upstreamed a year ago; the package fails for a different reason
2024-05-31 09:04:16 +00:00
7a701f92eb nixpkgs: bump
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/d3d81af60c22e9e93a3930a9630b210362341ab9' (2024-05-31)
  → 'github:nixos/nixpkgs/8a0a33b56d6279fec4827da602882561ef00f2fb' (2024-05-31)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/4e60a4d94bdc1abafeefc1928aa3cda6ce6c4210' (2024-05-31)
  → 'github:nixos/nixpkgs/7ccd1516effbc5510391d3b498a7a3bef92a090b' (2024-05-31)
```
2024-05-31 08:44:53 +00:00
3c3a32e436 nixpatches: grab libphonenumber cross patch from PR 2024-05-31 08:43:27 +00:00
07aec3ca3c apps: explain why i ship both engrampa and xarchiver archive managers 2024-05-31 08:39:23 +00:00
58d5f11c7a overlays/cross: disable patches which im not actively using 2024-05-31 08:21:23 +00:00
ed2d4ef488 overlays/cross: update upstreaming status 2024-05-31 08:02:25 +00:00
e8f8866032 overlays/cross: remove old emulated package set and buildInQemu, etc 2024-05-31 06:59:32 +00:00
a2dfd8f08e libphonenumber: use a better patch for cross (CMAKE_CROSSCOMPILING_EMULATOR) 2024-05-31 06:27:10 +00:00
c7fd3d2217 nixpkgs: 2024-05-26 -> 2024-05-31, nixpkgs-wayland -> 2024-05-31
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/2baa940f86e1fc54757fd7d1ed551c0a38904bf2' (2024-05-26)
  → 'github:nixos/nixpkgs/d3d81af60c22e9e93a3930a9630b210362341ab9' (2024-05-31)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/7780e5160e011b39019797a4c4b1a4babc80d1bf' (2024-05-26)
  → 'github:nixos/nixpkgs/4e60a4d94bdc1abafeefc1928aa3cda6ce6c4210' (2024-05-31)
• Updated input 'nixpkgs-wayland':
    'github:nix-community/nixpkgs-wayland/397c85d463aef789a8dd24c4db467e9ad787907b' (2024-05-26)
  → 'github:nix-community/nixpkgs-wayland/1db9b79a45c8e346e03480767e6d9749fabfaf10' (2024-05-31)
```
2024-05-31 06:09:03 +00:00
0fcc3f8d5d ModemManager: make the sandbox more strict 2024-05-30 21:32:35 +00:00
0bb887158b implement a dropbear SSH module 2024-05-30 20:58:01 +00:00
6570c5ed84 modemmanager: sandbox with bwrap instead of landlock 2024-05-30 18:47:09 +00:00
820fdecfd5 modemmanager: minimal (working) sandbox 2024-05-30 18:27:34 +00:00
8d43565f31 sane-theme: disable sandbox 2024-05-30 16:54:10 +00:00
18364761dd wireplumber: undo the enableSystemd=false patch 2024-05-30 16:50:53 +00:00
d3937487e6 moby: cleanup bonsai <-> sway circular dependency (slightly) 2024-05-30 12:43:09 +00:00
3fdeacc336 sane-input-handler: add a --help command 2024-05-30 12:30:41 +00:00
847414ac1f health-check: add a test that git is online 2024-05-30 12:18:57 +00:00
84f2006115 servo: fix gitea 2024-05-30 12:12:06 +00:00
7f5e12da8d dbus: dont consider the service "up" until the unix pipe actually appears 2024-05-30 11:04:02 +00:00
afa8a3c52e activationScripts.notifyActive: future-proof for if ever DBUS_SESSION_BUS_ADDRESS changes 2024-05-30 11:03:35 +00:00
bfbcb4789b activationScripts.notifyActive: fix forrenamed XDG_RUNTIME_DIR 2024-05-30 10:56:17 +00:00
2531cc1cf6 bonsai: place the socket in a subdirectory to improve sandboxing 2024-05-30 09:54:28 +00:00
e55b75c333 wireplumber: build without systemd 2024-05-30 09:46:29 +00:00
adb54657d4 sway: fix bonsai to be visible in the sandbox 2024-05-30 09:46:04 +00:00
6eefb9ce20 wireplumber: build against the same pipewire i deploy 2024-05-30 09:06:41 +00:00
2233622bb7 landlock-sandboxer: remove startup messages for 6.9 2024-05-30 08:55:13 +00:00
274a7821a7 wireplumber: remove no-longer-needed /run/systemd directory
not necessary when using seatd/when a member of the 'audio' group
2024-05-30 08:54:41 +00:00
4c84d1a727 doc: modules/users: show what XDG_SESSION_{ID,CLASS,TYPE} could look like if set 2024-05-30 08:44:26 +00:00
175acf6442 pipewire: build without systemd 2024-05-30 08:44:11 +00:00
0761b6135a users/colin: add myself to "audio" group so that wireplumber can access audio devices w/o systemd/logind 2024-05-30 08:44:11 +00:00
66c899d099 callaudiod: fix to not start before dbus/pipewire are up (avoids coredump on boot) 2024-05-30 06:07:08 +00:00
4aeb3360d3 cleanup: programs: dont assume sway is always the wayland/x11 provider 2024-05-30 06:00:32 +00:00
0c456d11d8 programs: ensure things which depend on sound or wayland are ordered after it 2024-05-30 04:55:05 +00:00
3b73773169 programs: ensure things which depend on dbus are ordered after it 2024-05-30 03:48:45 +00:00
9ba8ff738b refactor: sane.programs.$foo.service: specify type concretely 2024-05-30 03:39:32 +00:00
f1d397940f seatd: patch sandboxing for desko 2024-05-29 19:42:45 +00:00
fa94fa8e6c seatd: sandbox with bwrap
it always surprises my that you can sandbox something with cap_sys_admin like this...

i think this works *only* because the user is root
2024-05-29 19:09:57 +00:00
4b9c125c8c seatd: sandbox 2024-05-29 18:58:38 +00:00
0f7d25d8a5 doc: sway: say why i wrapperType = "inplace" 2024-05-29 18:58:05 +00:00
140641729e gvfs: disable (it was broken) 2024-05-29 18:39:31 +00:00
32124d76bf cups: disable (not currently used, and not sandboxed) 2024-05-29 18:33:17 +00:00
c5c174f988 sway: patch to use a narrower sandbox 2024-05-29 18:24:59 +00:00
29bc1608aa sway: remove sandbox input which are no longer necessary 2024-05-29 17:07:18 +00:00
635ca1e5d8 seatd: pull the service definition into my own repo
this will allow me to configure the package
2024-05-29 16:34:32 +00:00
2789868703 seatd: split out of sway conf 2024-05-29 16:22:52 +00:00
c40ec1990a sshd: disable systemd integration 2024-05-29 15:57:19 +00:00
d4dfcd6510 login: remove systemd pam integration (so it doesnt try, and fail, to start the user manager) 2024-05-29 15:42:39 +00:00
d865be952a refactor: sandboxing: replace manual --sanebox-keep-namespace pid config with isolatePids = false 2024-05-29 12:56:46 +00:00
7c8a18ecbd systemd: remove no-longer-used user@1000 override 2024-05-29 12:56:19 +00:00
35ff7de06e dbus: manage it ourselves instead of having systemd do it 2024-05-29 12:55:51 +00:00
00d06db66a make-sandboxed: handle more systemd service files 2024-05-29 12:54:44 +00:00
c570b7bf5d dbus: manage it ourselves instead of having systemd do it 2024-05-29 11:30:33 +00:00
770fc2e574 systemd: fix typod IgnoreOnIsolate option 2024-05-29 11:30:33 +00:00
0ed7eb24fb programs: assorted: remove legacy programs.feedback setting 2024-05-29 11:30:33 +00:00
ad8e75b6a3 programs: assorted: remove /var/lib/alsa persistence; doesnt seem to be needed 2024-05-29 11:30:33 +00:00
e8dbe0750d networkmanager: fix sandbox to actually work with systemd-resolved 2024-05-29 10:34:24 +00:00
1378988f21 desko: *really* disable wpa_supplicant 2024-05-29 10:34:03 +00:00
b88467771e doc: trust-dns: fix wan.txt example path 2024-05-29 09:33:59 +00:00
4309d887da wpa_supplicant: remove unused services 2024-05-29 09:33:25 +00:00
1ee21c4795 NetworkManager: run as user instead of root 2024-05-29 09:16:30 +00:00
fb7bcbb5f5 NetworkManager-wait-online: fix missing sanebox path 2024-05-29 01:37:15 +00:00
0013e8305e networkmanager: cleanup 2024-05-29 01:35:38 +00:00
7dedfcebb9 networkmanager: sandbox 2024-05-29 01:33:15 +00:00
753b97ffb4 todo.md: mark hosts/modules/gui cleanup as complete 2024-05-28 16:51:29 +00:00
247fc1f887 hosts/modules/gui: fold into hosts/common/programs 2024-05-28 16:51:02 +00:00
3c2ca46ef9 hosts/modules/gui/gtk: hoist to sane.programs.sane-theme 2024-05-28 16:44:27 +00:00
95dc395925 hosts/modules/gui/theme: lift my sway background up into its own package 2024-05-28 15:48:37 +00:00
cefd6c0534 documentation improvements 2024-05-28 13:36:01 +00:00
05efec8fd7 wg-home: decrease the refresh timeout 2024-05-28 13:36:01 +00:00
e8846b2d6b wpa_supplicant: sandbox 2024-05-28 13:36:01 +00:00
be38d56717 make-sandboxed: handle more systemd/dbus service file locations 2024-05-28 13:36:01 +00:00
7d242ab02c sane-battery-estimate: sandbox 2024-05-28 09:41:04 +00:00
47611eaa26 sane-weather: sandbox 2024-05-28 09:38:04 +00:00
9719f0f785 mpv: relax sandboxing for the sake of subtitle downloading 2024-05-28 09:37:57 +00:00
8042ea76e6 assorted programs: specify sandbox.autodetectCliPaths variant more precisely than just true 2024-05-28 07:14:27 +00:00
c59236509b sane-cast: sandbox 2024-05-28 07:07:11 +00:00
50e5206b0e todo.md: document that moby touchscreen stays on even when the screen is disabled 2024-05-28 05:27:37 +00:00
4ba0343315 networkmanager: hoist some lib.mkIfs up a few levels
would you believe one of these attributes was being set without a mkIf cfg.enabled guard :)
2024-05-28 05:27:23 +00:00
cbe6072c03 polyunfill: remove policykit suid wrappers 2024-05-28 05:24:37 +00:00
bea1fd95e5 polyunfill: disable dbus-daemon-launch-helper suid wrapper 2024-05-28 05:14:06 +00:00
ae544c0649 polyunfill: disable mount/umount suid wrappers 2024-05-28 05:02:26 +00:00
b571f70988 polyunfill: remove fusermount suid wrapper 2024-05-28 04:56:14 +00:00
e6498ad152 notejot: fix sandboxing 2024-05-28 03:59:31 +00:00
976b8ae45e rofi-snippets: make the filtering case insensitive, and improve ellipsis placement come 1.7.6 2024-05-28 03:38:36 +00:00
ab7c4d7410 rofi-snippets: remove the subshell and just use a pipe
i expect that this is faster, particularly because bash should stand up each section of the pipeline in parallel, right?
2024-05-28 03:23:04 +00:00
d2c3bec98e rofi-snippets: remove an extraneous layer of sandbox 2024-05-28 03:04:57 +00:00
3c5e5632ee wtype: sandbox 2024-05-28 03:04:26 +00:00
dcedb8d3f0 sanebox: handle --flag=path style of autodetected paths 2024-05-28 03:04:02 +00:00
8586db59f1 todo.md: sync 2024-05-28 02:14:10 +00:00
1f4d500b02 snippets: update 2024-05-28 02:11:49 +00:00
56b846023b update snippets 2024-05-28 01:27:59 +00:00
747d6c876d sane-vpn: add a "dns-fix" subcommand to open a shell using an external DNS resolver
this is hopefully temporary, until i can cleanup my trust-dns recursive resolver
2024-05-28 01:23:22 +00:00
f38d2d52d2 alsa-ucm-pinephone-pmos: prefer the earpiece over the "internal speaker" 2024-05-27 14:13:56 +00:00
04bbf54385 alsa-ucm-conf: switch to postmarketos version 2024-05-27 13:41:03 +00:00
f2271180dd alsa-ucm-conf: split the patched alsa confs out into their own package 2024-05-27 12:53:33 +00:00
60b1ab1429 conky: split sane-battery-estimate out into its own program 2024-05-27 11:33:40 +00:00
db3636641d sxmo-utils: disable update script 2024-05-27 07:51:56 +00:00
54a891504d delfin: 0.4.2 -> 0.4.4 2024-05-27 07:51:56 +00:00
8ea5061bef firefox-extensions: update to latest 2024-05-27 07:51:56 +00:00
b6d19a7a09 firefox-extensions.ctrl-shift-c-should-copy: update version field to use unstable idioms 2024-05-27 07:51:56 +00:00
439be20be7 lemmy-lemonade: 2024.03.20 -> 2024.04.22 2024-05-27 07:51:56 +00:00
a024f685c3 firefox: replace i-still-dont-care-about-cookies extension with a uBlock filter list
simpler that way; fewer extensions to trust
2024-05-27 07:43:55 +00:00
9c20cef6ea firefox: ublacklist: disable (i wasnt using any rules; it wasnt blocking anything from google search results) 2024-05-27 07:22:47 +00:00
abb65e55c6 uassets: fix updateScript 2024-05-27 07:16:50 +00:00
a2d385708f flake: echo the update command before running it 2024-05-27 07:16:42 +00:00
f6f1a6e136 firefox: uBlock Origin: ship filter lists statically 2024-05-27 06:54:52 +00:00
7941a8b1ed refactor: firefox: fix uBlock json indentation 2024-05-27 04:46:38 +00:00
bbcf8841ea todo.md: sync 2024-05-27 00:49:51 +00:00
063b0be5b6 hosts/modules/gui/greetd: remove 2024-05-27 00:44:01 +00:00
7e490f5c07 remove lingering references to sxmo 2024-05-27 00:38:30 +00:00
10a985e7f9 hosts/modules/gui/sxmo: remove 2024-05-27 00:27:53 +00:00
f3c3df2ca7 sxmo_suspend.sh: lift out of hosts/modules/gui/sxmo/hooks
i want to preserve this script for the future, while deleting the rest of my (unused) SXMO config
2024-05-27 00:23:50 +00:00
f477604063 hosts/modules/gui: remove gnome 2024-05-27 00:13:19 +00:00
d46fa8a242 swaync-fbcli: sandbox (experimental) 2024-05-27 00:11:20 +00:00
62b2eb874c swaync-service-dispatcher: sandbox 2024-05-27 00:07:30 +00:00
133c1b3699 swaync: remove unused systemd integrations
it's all s6 now
2024-05-27 00:06:03 +00:00
1b4300dbeb swaync: remove unused vpn button 2024-05-27 00:00:44 +00:00
a1c1a87dd8 nixpkgs: 2024-05-24 -> 2024-05-26; nixpkgs-wayland, sops-nix
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/cc5c0d369b5e8f49705e2a2d7464e4b162804805' (2024-05-24)
  → 'github:nixos/nixpkgs/2baa940f86e1fc54757fd7d1ed551c0a38904bf2' (2024-05-26)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/2baa58d3488bd9cc4d53d6812509edc34a1c7e2a' (2024-05-24)
  → 'github:nixos/nixpkgs/7780e5160e011b39019797a4c4b1a4babc80d1bf' (2024-05-26)
• Updated input 'nixpkgs-wayland':
    'github:nix-community/nixpkgs-wayland/8746004cd97164c89f0997ea06642b819e5bc3fb' (2024-05-24)
  → 'github:nix-community/nixpkgs-wayland/397c85d463aef789a8dd24c4db467e9ad787907b' (2024-05-26)
• Updated input 'nixpkgs-wayland/lib-aggregate':
    'github:nix-community/lib-aggregate/5fa64b174daa22fe0d20ebbcc0ec2c7905b503f1' (2024-05-19)
  → 'github:nix-community/lib-aggregate/dbc9130fe1455e0f6ee4d8f5f799f9be551f866b' (2024-05-26)
• Updated input 'nixpkgs-wayland/lib-aggregate/nixpkgs-lib':
    'github:nix-community/nixpkgs.lib/0df131b5ee4d928a4b664b6d0cd99cf134d6ab6b' (2024-05-19)
  → 'github:nix-community/nixpkgs.lib/d0d27192931680482081aa1c38389da2af84a651' (2024-05-26)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/b549832718b8946e875c016a4785d204fcfc2e53' (2024-05-22)
  → 'github:Mic92/sops-nix/962797a8d7f15ed7033031731d0bb77244839960' (2024-05-26)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/e7cc61784ddf51c81487637b3031a6dd2d6673a2' (2024-05-18)
  → 'github:NixOS/nixpkgs/59a450646ec8ee0397f5fa54a08573e8240eb91f' (2024-05-25)
```
2024-05-26 15:07:25 +00:00
92b9a56894 cleanup: remove unused secrets/common/wg/* 2024-05-26 14:37:33 +00:00
b159240b7f servo: import ovpn privkey 2024-05-26 14:37:33 +00:00
8a9f96eefc moby: import own OVPN privkey 2024-05-26 14:31:08 +00:00
af5aa15c23 cross: get passt to cross compile 2024-05-26 14:26:56 +00:00
a03099569c sanebox: fix bwrap+pasta DNS forwarding for hosts not using trust-dns 2024-05-26 14:26:56 +00:00
b1c7061b21 vpn: fix typos from previous 2 commits 2024-05-26 14:26:47 +00:00
c528bb3ec9 desko: add to OVPN 2024-05-26 14:07:32 +00:00
002639cc76 ovpn: use a single key per-device
this should fix the traffic collisions i'm seeing with the existing setup
2024-05-26 14:04:52 +00:00
45967fde7b brave: fix sandboxing under pasta/netns 2024-05-26 13:05:44 +00:00
ed97a81ef3 sane-vpn: use bwrap instead of just pasta so that the uids get mapped and programs can be happy 2024-05-26 13:04:13 +00:00
f158842c70 sanebox: fix uid mapping when bwrap uses the pasta backend 2024-05-26 13:03:50 +00:00
90d428be7f sane-vpn: allow sane-vpn do to work with no additional arguments 2024-05-26 11:33:12 +00:00
9d7b68eeb4 sane-tag-music: rewrite empty tracknumber tag to delete the tracknumber tag 2024-05-26 10:44:25 +00:00
8951df2e2c sane-scripts: set vim tags for python scripts 2024-05-26 10:42:12 +00:00
3a045f4d88 doc: polyunfill: point to https://github.com/NixOS/nixpkgs/pull/314791 2024-05-26 08:00:18 +00:00
57d6a9a4c3 polyunfill: simplify pam hacks 2024-05-26 07:04:12 +00:00
2ee39ca0cc poly_unfill: remove /run/wrappers/bin/unix_chkpwd
non-privileged users don't need to check passwords

well, maybe they do (for desktop unlockers), but i've already solved that :)
2024-05-26 06:37:59 +00:00
9d9211c5fa polyunfill: distribute /run/wrappers/bin/unix_chkpwd without suid bit 2024-05-26 01:18:30 +00:00
9ce7dcd57a /run/wrappers: remove unused newgidmap,newuidmap,newgrp binaries 2024-05-26 01:18:30 +00:00
af72f312d3 sandbox: remove /run/wrappers: SUID wrappers dont really accomplish much inside a namespace 2024-05-26 01:18:30 +00:00
efa1ee6c69 iproute2: disable sandbox and fix ip commands 2024-05-26 01:18:30 +00:00
6a15434cc6 net/vpn: remove the bridge devices from my VPN setup 2024-05-26 01:18:30 +00:00
59e4256dd8 sane-vpn: lint 2024-05-26 01:18:30 +00:00
6365bb7594 desko: disable wpa_supplicant/wireless networking again 2024-05-26 01:18:17 +00:00
8cb73687ce unl0kr: don't add extra deps to user's PATH 2024-05-26 01:17:42 +00:00
312 changed files with 13516 additions and 6568 deletions

View File

@@ -3,6 +3,7 @@ keys:
- &user_lappy_colin age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g - &user_lappy_colin age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g
- &user_servo_colin age1z8fauff34cdecr6sjkre260luzxcca05kpcwvhx988d306tpcejsp63znu - &user_servo_colin age1z8fauff34cdecr6sjkre260luzxcca05kpcwvhx988d306tpcejsp63znu
- &user_moby_colin age1zsrsvd7j6l62fjxpfd2qnhqlk8wk4p8r0dtxpe4sdgnh2474095qdu7xj9 - &user_moby_colin age1zsrsvd7j6l62fjxpfd2qnhqlk8wk4p8r0dtxpe4sdgnh2474095qdu7xj9
- &host_crappy age1hl50ufuxnqy0jnk8fqeu4tclh4vte2xn2d59pxff0gun20vsmv5sp78chj
- &host_desko age1vnw7lnfpdpjn62l3u5nyv5xt2c965k96p98kc43mcnyzpetrts9q54mc9v - &host_desko age1vnw7lnfpdpjn62l3u5nyv5xt2c965k96p98kc43mcnyzpetrts9q54mc9v
- &host_lappy age1w7mectcjku6x3sd8plm8wkn2qfrhv9n6zhzlf329e2r2uycgke8qkf9dyn - &host_lappy age1w7mectcjku6x3sd8plm8wkn2qfrhv9n6zhzlf329e2r2uycgke8qkf9dyn
- &host_servo age1tzlyex2z6t88tg9h82943e39shxhmqeyr7ywhlwpdjmyqsndv3qq27x0rf - &host_servo age1tzlyex2z6t88tg9h82943e39shxhmqeyr7ywhlwpdjmyqsndv3qq27x0rf
@@ -15,6 +16,7 @@ creation_rules:
- *user_lappy_colin - *user_lappy_colin
- *user_servo_colin - *user_servo_colin
- *user_moby_colin - *user_moby_colin
- *host_crappy
- *host_desko - *host_desko
- *host_lappy - *host_lappy
- *host_servo - *host_servo

View File

@@ -2,6 +2,8 @@
# .❄≡We|_c0m3 7o m`/ f14k≡❄. # .❄≡We|_c0m3 7o m`/ f14k≡❄.
(er, it's not a flake anymore. welcome to my nix files.)
## What's Here ## What's Here
this is the top-level repo from which i configure/deploy all my NixOS machines: this is the top-level repo from which i configure/deploy all my NixOS machines:
@@ -16,7 +18,6 @@ building [hosts/](./hosts/) will require [sops][sops].
you might specifically be interested in these files (elaborated further in #key-points-of-interest): you might specifically be interested in these files (elaborated further in #key-points-of-interest):
- ~~[`sxmo-utils`](./pkgs/additional/sxmo-utils/default.nix)~~ - ~~[`sxmo-utils`](./pkgs/additional/sxmo-utils/default.nix)~~
- ~~[example SXMO deployment](./hosts/modules/gui/sxmo/default.nix)~~
- these files will remain until my config settles down, but i no longer use or maintain SXMO. - these files will remain until my config settles down, but i no longer use or maintain SXMO.
- [my implementation of impermanence](./modules/persist/default.nix) - [my implementation of impermanence](./modules/persist/default.nix)
- my way of deploying dotfiles/configuring programs per-user: - my way of deploying dotfiles/configuring programs per-user:
@@ -30,11 +31,7 @@ you might specifically be interested in these files (elaborated further in #key-
## Using This Repo In Your Own Config ## Using This Repo In Your Own Config
this should be a pretty "standard" flake. just reference it, and import either follow the instructions [here][NUR] to access my packages through the Nix User Repositories.
- `nixosModules.sane` (for the modules)
- `overlays.pkgs` (for the packages)
or follow the instructions [here][NUR] to use it via the Nix User Repositories.
[NUR]: https://nur.nix-community.org/ [NUR]: https://nur.nix-community.org/
@@ -42,19 +39,15 @@ or follow the instructions [here][NUR] to use it via the Nix User Repositories.
- `doc/` - `doc/`
- instructions for tasks i find myself doing semi-occasionally in this repo. - instructions for tasks i find myself doing semi-occasionally in this repo.
- `hosts/` - `hosts/`
- the bulk of config which isn't factored with external use in mind. - configs which aren't factored with external use in mind.
- that is, if you were to add this repo to a flake.nix for your own use, - that is, if you were to add this repo to a flake.nix for your own use,
you won't likely be depending on anything in this directory. you won't likely be depending on anything in this directory.
- `integrations/` - `integrations/`
- code intended for consumption by external tools (e.g. the Nix User Repos) - code intended for consumption by external tools (e.g. the Nix User Repos).
- `modules/` - `modules/`
- config which is gated behind `enable` flags, in similar style to nixpkgs' - config which is gated behind `enable` flags, in similar style to nixpkgs' `nixos/` directory.
`nixos/` directory. - if you depend on this repo for anything besides packages, it's most likely for something in this directory.
- if you depend on this repo, it's most likely for something in this directory.
- `nixpatches/`
- literally, diffs i apply atop upstream nixpkgs before performing further eval.
- `overlays/` - `overlays/`
- exposed via the `overlays` output in `flake.nix`.
- predominantly a list of `callPackage` directives. - predominantly a list of `callPackage` directives.
- `pkgs/` - `pkgs/`
- derivations for things not yet packaged in nixpkgs. - derivations for things not yet packaged in nixpkgs.
@@ -62,13 +55,12 @@ or follow the instructions [here][NUR] to use it via the Nix User Repositories.
- inline code for wholly custom packages (e.g. `pkgs/additional/sane-scripts/` for CLI tools - inline code for wholly custom packages (e.g. `pkgs/additional/sane-scripts/` for CLI tools
that are highly specific to my setup). that are highly specific to my setup).
- `scripts/` - `scripts/`
- scripts which aren't reachable on a deployed system, but may aid manual deployments - scripts which aren't reachable on a deployed system, but may aid manual deployments.
- `secrets/` - `secrets/`
- encrypted keys, API tokens, anything which one or more of my machines needs - encrypted keys, API tokens, anything which one or more of my machines needs
read access to but shouldn't be world-readable. read access to but shouldn't be world-readable.
- not much to see here - not much to see here.
- `templates/` - `templates/`
- exposed via the `templates` output in `flake.nix`.
- used to instantiate short-lived environments. - used to instantiate short-lived environments.
- used to auto-fill the boiler-plate portions of new packages. - used to auto-fill the boiler-plate portions of new packages.

34
TODO.md
View File

@@ -1,13 +1,12 @@
## BUGS ## BUGS
- moby: megapixels doesn't load in sandbox - `rmDbusServices` may break sandboxing
- e.g. if the package ships a systemd unit which references $out, then make-sandboxed won't properly update that unit.
- `rmDbusServicesInPlace` is not affected
- when moby wlan is explicitly set down (via ip link set wlan0 down), /var/lib/trust-dns/dhcp-configs doesn't get reset - when moby wlan is explicitly set down (via ip link set wlan0 down), /var/lib/trust-dns/dhcp-configs doesn't get reset
- `ip monitor` can detect those manual link state changes (NM-dispatcher it seems cannot) - `ip monitor` can detect those manual link state changes (NM-dispatcher it seems cannot)
- or try dnsmasq? - or try dnsmasq?
- trust-dns: can't recursively resolve api.mangadex.org - trust-dns: can't recursively resolve api.mangadex.org
- and *sometimes* apple.com fails - and *sometimes* apple.com fails
- wg-ovpnd-* interfaces don't work, because i use the same keys across all hosts...
- and if i had them differ and simultaneously online, then i'd exceed the OVPN machine count.
- i should at least have them be up'd only on-demand.
- sandbox: link cache means that if i update ~/.config/... files inline, sandboxed programs still see the old version - sandbox: link cache means that if i update ~/.config/... files inline, sandboxed programs still see the old version
- mpv: audiocast has mpv sending its output to the builtin speakers unless manually changed - mpv: audiocast has mpv sending its output to the builtin speakers unless manually changed
- mpv: no way to exit fullscreen video on moby - mpv: no way to exit fullscreen video on moby
@@ -16,7 +15,6 @@
- decrease s6 restart time? - decrease s6 restart time?
- `ssh` access doesn't grant same linux capabilities as login - `ssh` access doesn't grant same linux capabilities as login
- ringer (i.e. dino incoming call) doesn't prevent moby from sleeping - ringer (i.e. dino incoming call) doesn't prevent moby from sleeping
- sway mouse/kb hotplug doesn't work
- sysvol (volume overlay): when casting with `blast`, sysvol doesn't react to volume changes - sysvol (volume overlay): when casting with `blast`, sysvol doesn't react to volume changes
- moby: kaslr is effectively disabled - moby: kaslr is effectively disabled
- `dmesg | grep "KASLR disabled due to lack of seed"` - `dmesg | grep "KASLR disabled due to lack of seed"`
@@ -26,9 +24,11 @@
- moby: bpf is effectively disabled? - moby: bpf is effectively disabled?
- `dmesg | grep 'systemd[1]: bpf-lsm: Failed to load BPF object: No such process'` - `dmesg | grep 'systemd[1]: bpf-lsm: Failed to load BPF object: No such process'`
- `dmesg | grep 'hid_bpf: error while preloading HID BPF dispatcher: -22'` - `dmesg | grep 'hid_bpf: error while preloading HID BPF dispatcher: -22'`
- `s6` is not re-entrant
- so if the desktop crashes, the login process from `unl0kr` fails to re-launch the GUI
## REFACTORING: ## REFACTORING:
- REMOVE DEPRECATED `crypt` from sftpgo_auth_hook - add import checks to my Python nix-shell scripts
- consolidate ~/dev and ~/ref - consolidate ~/dev and ~/ref
- ~/dev becomes a link to ~/ref/cat/mine - ~/dev becomes a link to ~/ref/cat/mine
- fold hosts/common/home/ssh.nix -> hosts/common/users/colin.nix - fold hosts/common/home/ssh.nix -> hosts/common/users/colin.nix
@@ -53,6 +53,10 @@
## IMPROVEMENTS: ## IMPROVEMENTS:
- systemd/journalctl: use a less shit pager - systemd/journalctl: use a less shit pager
- there's an env var for it: SYSTEMD_PAGER? and a flag for journalctl - there's an env var for it: SYSTEMD_PAGER? and a flag for journalctl
- kernels: ship the same kernel on every machine
- then i can tune the kernels for hardening, without duplicating that work 4 times
- zfs: replace this with something which doesn't require a custom kernel build
- mpv: add media looping controls (e.g. loop song, loop playlist)
### security/resilience ### security/resilience
- validate duplicity backups! - validate duplicity backups!
@@ -73,10 +77,9 @@
- limit access to `~/knowledge/secrets` through an agent that requires GUI approval, so a firefox exploit can't steal all my logins - limit access to `~/knowledge/secrets` through an agent that requires GUI approval, so a firefox exploit can't steal all my logins
- port sanebox to a compiled language (hare?) - port sanebox to a compiled language (hare?)
- it adds like 50-70ms launch time _on my laptop_. i'd hate to know how much that is on the pinephone. - it adds like 50-70ms launch time _on my laptop_. i'd hate to know how much that is on the pinephone.
- remove /run/wrappers from the sandbox path
- they're mostly useless when using no-new-privs, just an opportunity to forget to specify deps
- make dconf stuff less monolithic - make dconf stuff less monolithic
- i.e. per-app dconf profiles for those which need it. possible static config. - i.e. per-app dconf profiles for those which need it. possible static config.
- flatpak/spectrum has some stuff to proxy dconf per-app
- canaries for important services - canaries for important services
- e.g. daily email checks; daily backup checks - e.g. daily email checks; daily backup checks
- integrate `nix check` into Gitea actions? - integrate `nix check` into Gitea actions?
@@ -87,7 +90,10 @@
- *maybe* a job for `setsid -f`? - *maybe* a job for `setsid -f`?
- replace starship prompt with something more efficient - replace starship prompt with something more efficient
- watch `forkstat`: it does way too much - watch `forkstat`: it does way too much
- cleanup waybar so that it's not invoking playerctl every 2 seconds - cleanup waybar/nwg-panel so that it's not invoking playerctl every 2 seconds
- nwg-panel: swaync icon is stuck as the refresh icon
- nwg-panel: doesn't appear on all desktops
- nwg-panel: doesn't know that virtual-desktop 10/TV exists
- install apps: - install apps:
- display QR codes for WiFi endpoints: <https://linuxphoneapps.org/apps/noappid.wisperwind.wifi2qr/> - display QR codes for WiFi endpoints: <https://linuxphoneapps.org/apps/noappid.wisperwind.wifi2qr/>
- shopping list (not in nixpkgs): <https://linuxphoneapps.org/apps/ro.hume.cosmin.shoppinglist/> - shopping list (not in nixpkgs): <https://linuxphoneapps.org/apps/ro.hume.cosmin.shoppinglist/>
@@ -95,8 +101,9 @@
- offline docs viewer (gtk): <https://github.com/workbenchdev/Biblioteca> - offline docs viewer (gtk): <https://github.com/workbenchdev/Biblioteca>
- some type of games manager/launcher - some type of games manager/launcher
- Gnome Highscore (retro games)?: <https://gitlab.gnome.org/World/highscore> - Gnome Highscore (retro games)?: <https://gitlab.gnome.org/World/highscore>
- better maps for mobile (Osmin (QtQuick)? Pure Maps (Qt/Kirigami)? Gnome Maps is improved in 45) - better maps for mobile (Osmin (QtQuick)? Pure Maps (Qt/Kirigami)?
- note-taking app: <https://linuxphoneapps.org/categories/note-taking/> - note-taking app: <https://linuxphoneapps.org/categories/note-taking/>
- Folio is nice, uses standard markdown, though it only supports flat repos
- OSK overlay specifically for mobile gaming - OSK overlay specifically for mobile gaming
- i.e. mock joysticks, for use with SuperTux and SuperTuxKart - i.e. mock joysticks, for use with SuperTux and SuperTuxKart
- install mobile-friendly games: - install mobile-friendly games:
@@ -124,6 +131,7 @@
- direct mepo to prefer gpsd, with fallback to geoclue, for better accuracy? - direct mepo to prefer gpsd, with fallback to geoclue, for better accuracy?
- configure geoclue to do some smoothing? - configure geoclue to do some smoothing?
- manually do smoothing, as some layer between mepo and geoclue/gpsd? - manually do smoothing, as some layer between mepo and geoclue/gpsd?
- moby: port `freshen-agps` timer service to s6 (maybe i want some `s6-cron` or something)
- moby: show battery state on ssh login - moby: show battery state on ssh login
- moby: improve gPodder launch time - moby: improve gPodder launch time
- moby: theme GTK apps (i.e. non-adwaita styles) - moby: theme GTK apps (i.e. non-adwaita styles)
@@ -131,8 +139,6 @@
- try Gradience tool specifically for theming adwaita? <https://linuxphoneapps.org/apps/com.github.gradienceteam.gradience/> - try Gradience tool specifically for theming adwaita? <https://linuxphoneapps.org/apps/com.github.gradienceteam.gradience/>
#### non-moby #### non-moby
- sane-tag-music: integrate `beets`/<https://beets.io/>
- this should be able to auto-tag a large part of my library
- RSS: integrate a paywall bypass - RSS: integrate a paywall bypass
- e.g. self-hosted [ladder](https://github.com/everywall/ladder) (like 12ft.io) - e.g. self-hosted [ladder](https://github.com/everywall/ladder) (like 12ft.io)
- neovim: set up language server (lsp; rnix-lsp; nvim-lspconfig) - neovim: set up language server (lsp; rnix-lsp; nvim-lspconfig)
@@ -154,6 +160,10 @@
### perf ### perf
- debug nixos-rebuild times - debug nixos-rebuild times
- use `systemctl list-jobs` to show what's being waited on
- i think it's `systemd-networkd-wait-online.service` that's blocking this?
- i wonder what interface it's waiting for. i should use `--ignore=...` to ignore interfaces i don't care about.
- also `wireguard-wg-home.target` when net is offline
- add `pkgs.impure-cached.<foo>` package set to build things with ccache enabled - add `pkgs.impure-cached.<foo>` package set to build things with ccache enabled
- every package here can be auto-generated, and marked with some env var so that it doesn't pollute the pure package set - every package here can be auto-generated, and marked with some env var so that it doesn't pollute the pure package set
- would be super handy for package prototyping! - would be super handy for package prototyping!

View File

@@ -3,7 +3,65 @@
# #
# the primary purpose of this file is so i can run `updateScript`s which expect # the primary purpose of this file is so i can run `updateScript`s which expect
# the root to be `default.nix` # the root to be `default.nix`
{ pkgs ? import <nixpkgs> {} }: { }:
pkgs.appendOverlays [ let
(import ./overlays/all.nix) mkPkgs = args: (import ./pkgs/additional/nixpkgs args).extend
(import ./overlays/all.nix);
inherit (mkPkgs {}) lib;
evalHost = { name, system, branch ? "master", variant ? null }:
let
pkgs = mkPkgs { inherit system; variant = branch; };
in pkgs.nixos (
[
(lib.optionalAttrs (variant == "light") {
sane.maxBuildCost = 2;
})
(lib.optionalAttrs (variant == "min") {
sane.maxBuildCost = 0;
})
(import ./hosts/instantiate.nix { hostName = name; })
(import ./modules)
pkgs.sops-nix.nixosModules.sops
] ]
);
mkFlavoredHost = args: let
host = evalHost args;
# expose the toplevel nixos system as the toplevel attribute itself,
# with nested aliases for other common build targets
in host.config.system.build.toplevel.overrideAttrs (base: {
passthru = (base.passthru or {}) // {
config = host.config;
fs = host.config.sane.fs;
img = host.config.system.build.img;
pkgs = host.config.system.build.pkgs;
programs = lib.mapAttrs (_: p: p.package) host.config.sane.programs;
toplevel = host.config.system.build.toplevel; #< self
};
});
mkHost = args: {
# TODO: swap order: $host-{next,staging}-{min,light}:
# then lexicographically-adjacent targets would also have the minimal difference in closure,
# and the order in which each target should be built is more evident
"${args.name}" = mkFlavoredHost args;
"${args.name}-next" = mkFlavoredHost args // { branch = "staging-next"; };
"${args.name}-staging" = mkFlavoredHost args // { branch = "staging"; };
"${args.name}-light" = mkFlavoredHost args // { variant = "light"; };
"${args.name}-light-next" = mkFlavoredHost args // { variant = "light"; branch = "staging-next"; };
"${args.name}-light-staging" = mkFlavoredHost args // { variant = "light"; branch = "staging"; };
"${args.name}-min" = mkFlavoredHost args // { variant = "min"; };
"${args.name}-min-next" = mkFlavoredHost args // { variant = "min"; branch = "staging-next"; };
"${args.name}-min-staging" = mkFlavoredHost args // { variant = "min"; branch = "staging-staging"; };
};
hosts = lib.foldl' (acc: host: acc // (mkHost host)) {} [
{ name = "crappy"; system = "armv7l-linux"; }
{ name = "desko"; system = "x86_64-linux"; }
{ name = "lappy"; system = "x86_64-linux"; }
{ name = "moby"; system = "aarch64-linux"; }
{ name = "rescue"; system = "x86_64-linux"; }
{ name = "servo"; system = "x86_64-linux"; }
];
in {
inherit hosts;
} // (mkPkgs {})

25
doc/adding-a-host.md Normal file
View File

@@ -0,0 +1,25 @@
to add a host:
- create the new nix targets
- hosts/by-name/HOST
- let the toplevel (flake.nix) know about HOST
- build and flash an image
- optionally expand the rootfs
- `cfdisk /dev/sda2` -> resize partition
- `mount /dev/sda2 boot`
- `btrfs filesystem resize max root`
- setup required persistent directories
- `mkdir -p root/persist/private`
- `gocryptfs -init root/persist/private`
- then boot the device, and for every dangling symlink in ~/.local/share, ~/.cache, do `mkdir -p` on it
- setup host ssh
- `mkdir -p root/persist/plaintext/etc/ssh/host_keys`
- boot the machine and let it create its own ssh keys
- add the pubkey to `hosts/common/hosts.nix`
- setup user ssh
- `ssh-keygen`. don't enter any password; it's stored in a password-encrypted fs.
- add the pubkey to `hosts/common/hosts.nix`
- allow the new host to view secrets
- instructions in hosts/common/secrets.nix
- run `ssh-to-age` on user/host pubkeys
- add age key to .sops.yaml
- update encrypted secrets: `sops updatekeys path/to/secret.yaml`

12
doc/recovery.md Normal file
View File

@@ -0,0 +1,12 @@
## deploying to SD card
- build a toplevel config: `nix build '.#hostSystems.moby'`
- mount a system:
- `mkdir -p root/{nix,boot}`
- `mount /dev/sdX1 root/boot`
- `mount /dev/sdX2 root/nix`
- copy the config:
- `sudo nix copy --no-check-sigs --to root/ $(readlink result)`
- nix will copy stuff to `root/nix/store`
- install the boot files:
- `sudo /nix/store/sbwpwngjlgw4f736ay9hgi69pj3fdwk5-extlinux-conf-builder.sh -d ./root/boot -t 5 -c $(readlink ./result)`
- extlinux-conf-builder can be found in `/run/current-system/bin/switch-to-configuration`

330
flake.lock generated
View File

@@ -1,330 +0,0 @@
{
"nodes": {
"flake-compat": {
"locked": {
"lastModified": 1688025799,
"narHash": "sha256-ktpB4dRtnksm9F5WawoIkEneh1nrEvuxb5lJFt1iOyw=",
"owner": "nix-community",
"repo": "flake-compat",
"rev": "8bf105319d44f6b9f0d764efa4fdef9f1cc9ba1c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs-wayland",
"nix-eval-jobs",
"nixpkgs"
]
},
"locked": {
"lastModified": 1712014858,
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"lib-aggregate": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1716120557,
"narHash": "sha256-rvNq9YolMY1DRMgwdAti8qwNDjkhTsotSWa15/Ch7+A=",
"owner": "nix-community",
"repo": "lib-aggregate",
"rev": "5fa64b174daa22fe0d20ebbcc0ec2c7905b503f1",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "lib-aggregate",
"type": "github"
}
},
"mobile-nixos": {
"flake": false,
"locked": {
"lastModified": 1694749521,
"narHash": "sha256-MiVokKlpcJmfoGuWAMeW1En7gZ5hk0rCQArYm6P9XCc=",
"owner": "nixos",
"repo": "mobile-nixos",
"rev": "d25d3b87e7f300d8066e31d792337d9cd7ecd23b",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "d25d3b87e7f300d8066e31d792337d9cd7ecd23b",
"repo": "mobile-nixos",
"type": "github"
}
},
"nix-eval-jobs": {
"inputs": {
"flake-parts": "flake-parts",
"nix-github-actions": "nix-github-actions",
"nixpkgs": "nixpkgs",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1715804156,
"narHash": "sha256-GtIHP86Cz1kD9xZO/cKbNQACHKdoT9WFbLJAq6W2EDY=",
"owner": "nix-community",
"repo": "nix-eval-jobs",
"rev": "bb95091f6c6f38f6cfc215a1797a2dd466312c8b",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-eval-jobs",
"type": "github"
}
},
"nix-github-actions": {
"inputs": {
"nixpkgs": [
"nixpkgs-wayland",
"nix-eval-jobs",
"nixpkgs"
]
},
"locked": {
"lastModified": 1703863825,
"narHash": "sha256-rXwqjtwiGKJheXB43ybM8NwWB8rO2dSRrEqes0S7F5Y=",
"owner": "nix-community",
"repo": "nix-github-actions",
"rev": "5163432afc817cf8bd1f031418d1869e4c9d5547",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-github-actions",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1715037484,
"narHash": "sha256-OUt8xQFmBU96Hmm4T9tOWTu4oCswCzoVl+pxSq/kiFc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ad7efee13e0d216bf29992311536fce1d3eefbef",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1716079763,
"narHash": "sha256-DGRfb7fO7c3XDS3twmuaV5NAGPPdU3W7Q35fjIZc8iY=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "0df131b5ee4d928a4b664b6d0cd99cf134d6ab6b",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-next-unpatched": {
"locked": {
"lastModified": 1716573668,
"narHash": "sha256-K+8vYJtu7X+qQ1Q66kYTheq0IKKVyPMOMclY9oJYnS8=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "cc5c0d369b5e8f49705e2a2d7464e4b162804805",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "staging-next",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1716061101,
"narHash": "sha256-H0eCta7ahEgloGIwE/ihkyGstOGu+kQwAiHvwVoXaA0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e7cc61784ddf51c81487637b3031a6dd2d6673a2",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "release-23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unpatched": {
"locked": {
"lastModified": 1716592782,
"narHash": "sha256-aGafFFAkQwkiBXo+ocx4sCco+L233JqlUZhVfXceaQY=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "2baa58d3488bd9cc4d53d6812509edc34a1c7e2a",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "master",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-wayland": {
"inputs": {
"flake-compat": "flake-compat",
"lib-aggregate": "lib-aggregate",
"nix-eval-jobs": "nix-eval-jobs",
"nixpkgs": [
"nixpkgs-unpatched"
]
},
"locked": {
"lastModified": 1716589021,
"narHash": "sha256-m7+ogvgw6tCk5P1H9OqS2yTFlZOus9I+Genv3PUWkno=",
"owner": "nix-community",
"repo": "nixpkgs-wayland",
"rev": "8746004cd97164c89f0997ea06642b819e5bc3fb",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs-wayland",
"type": "github"
}
},
"root": {
"inputs": {
"mobile-nixos": "mobile-nixos",
"nixpkgs-next-unpatched": "nixpkgs-next-unpatched",
"nixpkgs-unpatched": "nixpkgs-unpatched",
"nixpkgs-wayland": "nixpkgs-wayland",
"sops-nix": "sops-nix",
"uninsane-dot-org": "uninsane-dot-org"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs-unpatched"
],
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1716400300,
"narHash": "sha256-0lMkIk9h3AzOHs1dCL9RXvvN4PM8VBKb+cyGsqOKa4c=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "b549832718b8946e875c016a4785d204fcfc2e53",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs-wayland",
"nix-eval-jobs",
"nixpkgs"
]
},
"locked": {
"lastModified": 1711963903,
"narHash": "sha256-N3QDhoaX+paWXHbEXZapqd1r95mdshxToGowtjtYkGI=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "49dc4a92b02b8e68798abd99184f228243b6e3ac",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"uninsane-dot-org": {
"inputs": {
"nixpkgs": [
"nixpkgs-unpatched"
]
},
"locked": {
"lastModified": 1715894399,
"narHash": "sha256-h1EdA/h74zgNPNEYbH+0mgOMlJgLVcxuZ8/ewsZlgEc=",
"ref": "refs/heads/master",
"rev": "e6f88f563bdd1700c04018951de4f69862646dd1",
"revCount": 240,
"type": "git",
"url": "https://git.uninsane.org/colin/uninsane"
},
"original": {
"type": "git",
"url": "https://git.uninsane.org/colin/uninsane"
}
}
},
"root": "root",
"version": 7
}

658
flake.nix
View File

@@ -1,658 +0,0 @@
# FLAKE FEEDBACK:
# - if flake inputs are meant to be human-readable, a human should be able to easily track them down given the URL.
# - this is not the case with registry URLs, like `nixpkgs/nixos-22.11`.
# - this is marginally the case with schemes like `github:nixos/nixpkgs`.
# - given the *existing* `git+https://` scheme, i propose expressing github URLs similarly:
# - `github+https://github.com/nixos/nixpkgs/tree/nixos-22.11`
# - this would allow for the same optimizations as today's `github:nixos/nixpkgs`, but without obscuring the source.
# a code reader could view the source being referenced simply by clicking the https:// portion of that URI.
# - need some way to apply local patches to inputs.
#
#
# DEVELOPMENT DOCS:
# - Flake docs: <https://nixos.wiki/wiki/Flakes>
# - Flake RFC: <https://github.com/tweag/rfcs/blob/flakes/rfcs/0049-flakes.md>
# - Discussion: <https://github.com/NixOS/rfcs/pull/49>
# - <https://serokell.io/blog/practical-nix-flakes>
#
#
# COMMON OPERATIONS:
# - update a specific flake input:
# - `nix flake lock --update-input nixpkgs`
{
# XXX: use the `github:` scheme instead of the more readable git+https: because it's *way* more efficient
# preferably, i would rewrite the human-readable https URLs to nix-specific github: URLs with a helper,
# but `inputs` is required to be a strict attrset: not an expression.
inputs = {
# branch workflow:
# - daily:
# - nixos-unstable cut from master after enough packages have been built in caches.
# - every 6 hours:
# - master auto-merged into staging and staging-next
# - staging-next auto-merged into staging.
# - manually, approximately once per month:
# - staging-next is cut from staging.
# - staging-next merged into master.
#
# which branch to source from?
# - nixos-unstable: for everyday development; it provides good caching
# - master: temporarily if i'm otherwise cherry-picking lots of already-applied patches
# - staging-next: if testing stuff that's been PR'd into staging, i.e. base library updates.
# - staging: maybe if no staging-next -> master PR has been cut yet?
#
# <https://github.com/nixos/nixpkgs/tree/nixos-unstable>
# nixpkgs-unpatched.url = "github:nixos/nixpkgs?ref=nixos-unstable";
nixpkgs-unpatched.url = "github:nixos/nixpkgs?ref=master";
# nixpkgs-unpatched.url = "github:nixos/nixpkgs?ref=nixos-staging";
# nixpkgs-unpatched.url = "github:nixos/nixpkgs?ref=nixos-staging-next";
nixpkgs-next-unpatched.url = "github:nixos/nixpkgs?ref=staging-next";
nixpkgs-wayland = {
url = "github:nix-community/nixpkgs-wayland";
inputs.nixpkgs.follows = "nixpkgs-unpatched";
};
mobile-nixos = {
# <https://github.com/nixos/mobile-nixos>
# only used for building disk images, not relevant after deployment
# TODO: replace with something else. commit `0f3ac0bef1aea70254a3bae35e3cc2561623f4c1`
# replaces the imageBuilder with a "new implementation from celun" and wildly breaks my use.
# pinning to d25d3b... is equivalent to holding at 2023-09-15
url = "github:nixos/mobile-nixos?ref=d25d3b87e7f300d8066e31d792337d9cd7ecd23b";
flake = false;
};
sops-nix = {
# <https://github.com/Mic92/sops-nix>
# used to distribute secrets to my hosts
url = "github:Mic92/sops-nix";
# inputs.nixpkgs.follows = "nixpkgs";
inputs.nixpkgs.follows = "nixpkgs-unpatched";
};
uninsane-dot-org = {
# provides the package to deploy <https://uninsane.org>, used only when building the servo host
url = "git+https://git.uninsane.org/colin/uninsane";
# inputs.nixpkgs.follows = "nixpkgs";
inputs.nixpkgs.follows = "nixpkgs-unpatched";
};
};
outputs = {
self,
nixpkgs-unpatched,
nixpkgs-next-unpatched ? nixpkgs-unpatched,
nixpkgs-wayland,
mobile-nixos,
sops-nix,
uninsane-dot-org,
...
}@inputs:
let
inherit (builtins) attrNames elem listToAttrs map mapAttrs;
# redefine some nixpkgs `lib` functions to avoid the infinite recursion
# of if we tried to use patched `nixpkgs.lib` as part of the patching process.
mapAttrs' = f: set:
listToAttrs (map (attr: f attr set.${attr}) (attrNames set));
optionalAttrs = cond: attrs: if cond then attrs else {};
# mapAttrs but without the `name` argument
mapAttrValues = f: mapAttrs (_: f);
# rather than apply our nixpkgs patches as a flake input, do that here instead.
# this (temporarily?) resolves the bad UX wherein a subflake residing in the same git
# repo as the main flake causes the main flake to have an unstable hash.
patchNixpkgs = variant: nixpkgs: (import ./nixpatches/flake.nix).outputs {
inherit variant nixpkgs;
self = patchNixpkgs variant nixpkgs;
};
nixpkgs' = patchNixpkgs "master" nixpkgs-unpatched;
nixpkgsCompiledBy = system: nixpkgs'.legacyPackages."${system}";
evalHost = { name, local, target, variant ? null, nixpkgs ? nixpkgs' }: nixpkgs.lib.nixosSystem {
system = target;
modules = [
{
nixpkgs.buildPlatform.system = local;
}
(optionalAttrs (local != target) {
# XXX(2023/12/11): cache.nixos.org uses `system = ...` instead of `hostPlatform.system`, and that choice impacts the closure of every package.
# so avoid specifying hostPlatform.system on non-cross builds, so i can use upstream caches.
nixpkgs.hostPlatform.system = target;
})
(optionalAttrs (variant == "light") {
sane.maxBuildCost = 2;
})
(optionalAttrs (variant == "min") {
sane.maxBuildCost = 0;
})
(import ./hosts/instantiate.nix { hostName = name; })
self.nixosModules.default
self.nixosModules.passthru
{
nixpkgs.overlays = [
self.overlays.passthru
self.overlays.sane-all
];
}
];
};
in {
nixosConfigurations = let
hosts = {
servo = { name = "servo"; local = "x86_64-linux"; target = "x86_64-linux"; };
desko = { name = "desko"; local = "x86_64-linux"; target = "x86_64-linux"; };
desko-light = { name = "desko"; local = "x86_64-linux"; target = "x86_64-linux"; variant = "light"; };
lappy = { name = "lappy"; local = "x86_64-linux"; target = "x86_64-linux"; };
lappy-light = { name = "lappy"; local = "x86_64-linux"; target = "x86_64-linux"; variant = "light"; };
lappy-min = { name = "lappy"; local = "x86_64-linux"; target = "x86_64-linux"; variant = "min"; };
moby = { name = "moby"; local = "x86_64-linux"; target = "aarch64-linux"; };
moby-light = { name = "moby"; local = "x86_64-linux"; target = "aarch64-linux"; variant = "light"; };
moby-min = { name = "moby"; local = "x86_64-linux"; target = "aarch64-linux"; variant = "min"; };
rescue = { name = "rescue"; local = "x86_64-linux"; target = "x86_64-linux"; };
};
hostsNext = mapAttrs' (h: v: {
name = "${h}-next";
value = v // { nixpkgs = patchNixpkgs "staging-next" nixpkgs-next-unpatched; };
}) hosts;
in mapAttrValues evalHost (
hosts // hostsNext
);
# unofficial output
# this produces a EFI-bootable .img file (GPT with a /boot partition and a system (/ or /nix) partition).
# after building this:
# - flash it to a bootable medium (SD card, flash drive, HDD)
# - resize the root partition (use cfdisk)
# - mount the part
# - chown root:nixbld <part>/nix/store
# - chown root:root -R <part>/nix/store/*
# - chown root:root -R <part>/persist # if using impermanence
# - populate any important things (persist/, home/colin/.ssh, etc)
# - boot
# - if fs wasn't resized automatically, then `sudo btrfs filesystem resize max /`
# - checkout this flake into /etc/nixos AND UPDATE THE FS UUIDS.
# - `nixos-rebuild --flake './#<host>' switch`
imgs = mapAttrValues (host: host.config.system.build.img) self.nixosConfigurations;
# unofficial output
hostConfigs = mapAttrValues (host: host.config) self.nixosConfigurations;
hostSystems = mapAttrValues (host: host.config.system.build.toplevel) self.nixosConfigurations;
hostPkgs = mapAttrValues (host: host.config.system.build.pkgs) self.nixosConfigurations;
hostPrograms = mapAttrValues (host: mapAttrValues (p: p.package) host.config.sane.programs) self.nixosConfigurations;
patched.nixpkgs = nixpkgs';
overlays = {
# N.B.: `nix flake check` requires every overlay to take `final: prev:` at defn site,
# hence the weird redundancy.
default = final: prev: self.overlays.pkgs final prev;
sane-all = final: prev: import ./overlays/all.nix final prev;
pkgs = final: prev: import ./overlays/pkgs.nix final prev;
pins = final: prev: import ./overlays/pins.nix final prev;
preferences = final: prev: import ./overlays/preferences.nix final prev;
passthru = final: prev:
let
mobile = (import "${mobile-nixos}/overlay/overlay.nix");
uninsane = uninsane-dot-org.overlays.default;
wayland = final: prev: {
# default is to dump the packages into `waylandPkgs` *and* the toplevel.
# but i just want the `waylandPkgs` set
inherit (nixpkgs-wayland.overlays.default final prev)
waylandPkgs
new-wayland-protocols #< 2024/03/10: nixpkgs-wayland assumes this will be in the toplevel
;
};
in
(mobile final prev)
// (uninsane final prev)
// (wayland final prev)
;
};
nixosModules = rec {
default = sane;
sane = import ./modules;
passthru = { ... }: {
imports = [
sops-nix.nixosModules.sops
];
};
};
# this includes both our native packages and all the nixpkgs packages.
legacyPackages =
let
allPkgsFor = sys: (nixpkgsCompiledBy sys).appendOverlays [
self.overlays.passthru self.overlays.pkgs
];
in {
x86_64-linux = allPkgsFor "x86_64-linux";
aarch64-linux = allPkgsFor "aarch64-linux";
};
# extract only our own packages from the full set.
# because of `nix flake check`, we flatten the package set and only surface x86_64-linux packages.
packages = mapAttrs
(system: passthruPkgs: passthruPkgs.lib.filterAttrs
(name: pkg:
# keep only packages which will pass `nix flake check`, i.e. keep only:
# - derivations (not package sets)
# - packages that build for the given platform
(! elem name [ "feeds" "pythonPackagesExtensions" ])
&& (passthruPkgs.lib.meta.availableOn passthruPkgs.stdenv.hostPlatform pkg)
)
(
# expose sane packages and chosen inputs (uninsane.org)
(import ./pkgs { pkgs = passthruPkgs; }) // {
inherit (passthruPkgs) uninsane-dot-org;
}
)
)
# self.legacyPackages;
{
x86_64-linux = (nixpkgsCompiledBy "x86_64-linux").appendOverlays [
self.overlays.passthru
];
}
;
apps."x86_64-linux" =
let
pkgs = self.legacyPackages."x86_64-linux";
sanePkgs = import ./pkgs { inherit pkgs; };
deployScript = host: addr: action: pkgs.writeShellScript "deploy-${host}" ''
set -e
host="${host}"
addr="${addr}"
action="${if action != null then action else ""}"
runOnTarget() {
# run the command ($@) on the machine we're deploying to.
# if that's a remote machine, then do it via ssh, else local shell.
if [ -n "$addr" ]; then
ssh "$addr" "$@"
else
"$@"
fi
}
nix build ".#nixosConfigurations.$host.config.system.build.toplevel" --out-link "./build/result-$host" "$@"
storePath="$(readlink ./build/result-$host)"
# mimic `nixos-rebuild --target-host`, in effect:
# - nix-copy-closure ...
# - nix-env --set ...
# - switch-to-configuration <boot|dry-activate|switch|test|>
# avoid the actual `nixos-rebuild` for a few reasons:
# - fewer nix evals
# - more introspectability and debuggability
# - sandbox friendliness (especially: `git` doesn't have to be run as root)
if [ -n "$addr" ]; then
sudo nix store sign -r -k /run/secrets/nix_signing_key "$storePath"
# add more `-v` for more verbosity (up to 5).
# builders-use-substitutes false: optimizes so that the remote machine doesn't try to get paths from its substituters.
# we already have all paths here, and the remote substitution is slow to check and SERIOUSLY flaky on moby in particular.
nix copy -vv --option builders-use-substitutes false --to "ssh-ng://$addr" "$storePath"
fi
if [ -n "$action" ]; then
runOnTarget sudo nix-env -p /nix/var/nix/profiles/system --set "$storePath"
runOnTarget sudo "$storePath/bin/switch-to-configuration" "$action"
fi
'';
deployApp = host: addr: action: {
type = "app";
program = ''${deployScript host addr action}'';
};
# pkg updating.
# a cleaner alternative lives here: <https://discourse.nixos.org/t/how-can-i-run-the-updatescript-of-personal-packages/25274/2>
# mkUpdater :: [ String ] -> { type = "app"; program = path; }
mkUpdater = attrPath: {
type = "app";
program = let
pkg = pkgs.lib.getAttrFromPath attrPath sanePkgs;
strAttrPath = pkgs.lib.concatStringsSep "." attrPath;
commandArgv = pkg.updateScript.command or pkg.updateScript;
command = pkgs.lib.escapeShellArgs commandArgv;
in builtins.toString (pkgs.writeShellScript "update-${strAttrPath}" ''
export UPDATE_NIX_NAME=${pkg.name}
export UPDATE_NIX_PNAME=${pkg.pname}
export UPDATE_NIX_OLD_VERSION=${pkg.version}
export UPDATE_NIX_ATTR_PATH=${strAttrPath}
${command}
'');
};
mkUpdatersNoAliases = opts: basePath: pkgs.lib.concatMapAttrs
(name: pkg:
if pkg.recurseForDerivations or false then {
"${name}" = mkUpdaters opts (basePath ++ [ name ]);
} else if pkg.updateScript or null != null then {
"${name}" = mkUpdater (basePath ++ [ name ]);
} else {}
)
(pkgs.lib.getAttrFromPath basePath sanePkgs);
mkUpdaters = { ignore ? [], flakePrefix ? [] }@opts: basePath:
let
updaters = mkUpdatersNoAliases opts basePath;
invokeUpdater = name: pkg:
let
fullPath = basePath ++ [ name ];
doUpdateByDefault = !builtins.elem fullPath ignore;
# in case `name` has a `.` in it, we have to quote it
escapedPath = builtins.map (p: ''"${p}"'') fullPath;
updatePath = builtins.concatStringsSep "." (flakePrefix ++ escapedPath);
in pkgs.lib.optionalString doUpdateByDefault (
pkgs.lib.escapeShellArgs [
"nix" "run" ".#${updatePath}"
]
);
in {
type = "app";
# top-level app just invokes the updater of everything one layer below it
program = builtins.toString (pkgs.writeShellScript
(builtins.concatStringsSep "-" (flakePrefix ++ basePath))
(builtins.concatStringsSep
"\n"
(pkgs.lib.mapAttrsToList invokeUpdater updaters)
)
);
} // updaters;
in {
help = {
type = "app";
program = let
helpMsg = builtins.toFile "nixos-config-help-message" ''
commands:
- `nix run '.#help'`
- show this message
- `nix run '.#update.pkgs'`
- updates every package
- `nix run '.#update.feeds'`
- updates metadata for all feeds
- `nix run '.#init-feed' <url>`
- `nix run '.#deploy.{desko,lappy,moby,servo}[-light|-test]' [nix args ...]`
- build and deploy the host
- `nix run '.#preDeploy.{desko,lappy,moby,servo}[-light]' [nix args ...]`
- copy closures to a host, but don't activate it
- or `nix run '.#preDeploy'` to target all hosts
- `nix run '.#check'`
- make sure all systems build; NUR evaluates
- `nix run '.#bench'`
- benchmark the eval time of common targets this flake provides
specific build targets of interest:
- `nix build '.#imgs.rescue'`
'';
in builtins.toString (pkgs.writeShellScript "nixos-config-help" ''
cat ${helpMsg}
echo ""
echo "complete flake structure:"
nix flake show --option allow-import-from-derivation true
'');
};
# wrangle some names to get package updaters which refer back into the flake, but also conditionally ignore certain paths (e.g. sane.feeds).
# TODO: better design
update = rec {
_impl.pkgs.sane = mkUpdaters { flakePrefix = [ "update" "_impl" "pkgs" ]; ignore = [ [ "sane" "feeds" ] ]; } [ "sane" ];
pkgs = _impl.pkgs.sane;
_impl.feeds.sane.feeds = mkUpdaters { flakePrefix = [ "update" "_impl" "feeds" ]; } [ "sane" "feeds" ];
feeds = _impl.feeds.sane.feeds;
};
init-feed = {
type = "app";
program = "${pkgs.feeds.init-feed}";
};
deploy = {
desko = deployApp "desko" "desko" "switch";
desko-light = deployApp "desko-light" "desko" "switch";
lappy = deployApp "lappy" "lappy" "switch";
lappy-light = deployApp "lappy-light" "lappy" "switch";
lappy-min = deployApp "lappy-min" "lappy" "switch";
moby = deployApp "moby" "moby" "switch";
moby-light = deployApp "moby-light" "moby" "switch";
moby-min = deployApp "moby-min" "moby" "switch";
moby-test = deployApp "moby" "moby" "test";
servo = deployApp "servo" "servo" "switch";
# like `nixos-rebuild --flake . switch`
self = deployApp "$(hostname)" "" "switch";
self-light = deployApp "$(hostname)-light" "" "switch";
self-min = deployApp "$(hostname)-min" "" "switch";
type = "app";
program = builtins.toString (pkgs.writeShellScript "deploy-all" ''
nix run '.#deploy.lappy'
nix run '.#deploy.moby'
nix run '.#deploy.desko'
nix run '.#deploy.servo'
'');
};
preDeploy = {
# build the host and copy the runtime closure to that host, but don't activate it.
desko = deployApp "desko" "desko" null;
desko-light = deployApp "desko-light" "desko" null;
lappy = deployApp "lappy" "lappy" null;
lappy-light = deployApp "lappy-light" "lappy" null;
lappy-min = deployApp "lappy-min" "lappy" null;
moby = deployApp "moby" "moby" null;
moby-light = deployApp "moby-light" "moby" null;
moby-min = deployApp "moby-min" "moby" null;
servo = deployApp "servo" "servo" null;
type = "app";
program = builtins.toString (pkgs.writeShellScript "predeploy-all" ''
# copy the -min/-light variants first; this might be run while waiting on a full build. or the full build failed.
nix run '.#preDeploy.moby-min' -- "$@"
nix run '.#preDeploy.lappy-min' -- "$@"
nix run '.#preDeploy.moby-light' -- "$@"
nix run '.#preDeploy.lappy-light' -- "$@"
nix run '.#preDeploy.desko-light' -- "$@"
nix run '.#preDeploy.lappy' -- "$@"
nix run '.#preDeploy.servo' -- "$@"
nix run '.#preDeploy.moby' -- "$@"
nix run '.#preDeploy.desko' -- "$@"
'');
};
sync = {
type = "app";
program = builtins.toString (pkgs.writeShellScript "sync-all" ''
RC_lappy=$(nix run '.#sync.lappy' -- "$@")
RC_moby=$(nix run '.#sync.moby' -- "$@")
RC_desko=$(nix run '.#sync.desko' -- "$@")
echo "lappy: $RC_lappy"
echo "moby: $RC_moby"
echo "desko: $RC_desko"
'');
};
sync.desko = {
# copy music from servo to desko
# can run this from any device that has ssh access to desko and servo
type = "app";
program = builtins.toString (pkgs.writeShellScript "sync-to-desko" ''
sudo mount /mnt/desko/home
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music --compat /mnt/servo/media/Music /mnt/desko/home/Music "$@"
'');
};
sync.lappy = {
# copy music from servo to lappy
# can run this from any device that has ssh access to lappy and servo
type = "app";
program = builtins.toString (pkgs.writeShellScript "sync-to-lappy" ''
sudo mount /mnt/lappy/home
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music --compress --compat /mnt/servo/media/Music /mnt/lappy/home/Music "$@"
'');
};
sync.moby = {
# copy music from servo to moby
# can run this from any device that has ssh access to moby and servo
type = "app";
program = builtins.toString (pkgs.writeShellScript "sync-to-moby" ''
sudo mount /mnt/moby/home
sudo mount /mnt/desko/home
${pkgs.rsync}/bin/rsync -arv --exclude servo-macros /mnt/moby/home/Pictures/ /mnt/desko/home/Pictures/moby/
# N.B.: limited by network/disk -> reduce job count to improve pause/resume behavior
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music --compress --compat --jobs 4 /mnt/servo/media/Music /mnt/moby/home/Music "$@"
'');
};
check = {
type = "app";
program = builtins.toString (pkgs.writeShellScript "check-all" ''
nix run '.#check.nur'
RC0=$?
nix run '.#check.hostConfigs'
RC1=$?
nix run '.#check.rescue'
RC2=$?
echo "nur: $RC0"
echo "hostConfigs: $RC1"
echo "rescue: $RC2"
exit $(($RC0 | $RC1 | $RC2))
'');
};
check.nur = {
# `nix run '.#check-nur'`
# validates that my repo can be included in the Nix User Repository
type = "app";
program = builtins.toString (pkgs.writeShellScript "check-nur" ''
cd ${./.}/integrations/nur
NIX_PATH= NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM=1 nix-env -f . -qa \* --meta --xml \
--allowed-uris https://static.rust-lang.org \
--option restrict-eval true \
--option allow-import-from-derivation true \
--drv-path --show-trace \
-I nixpkgs=${nixpkgs-unpatched} \
-I nixpkgs-overlays=${./.}/hosts/common/nix/overlay \
-I ../../ \
| tee # tee to prevent interactive mode
'');
};
check.hostConfigs = {
type = "app";
program = let
checkHost = host: let
shellHost = pkgs.lib.replaceStrings [ "-" ] [ "_" ] host;
in ''
nix build -v '.#nixosConfigurations.${host}.config.system.build.toplevel' --out-link ./build/result-${host} -j2 "$@"
RC_${shellHost}=$?
'';
in builtins.toString (pkgs.writeShellScript
"check-host-configs"
''
# build minimally-usable hosts first, then their full image.
# this gives me a minimal image i can deploy or copy over, early.
${checkHost "lappy-min"}
${checkHost "moby-min"}
${checkHost "desko-light"}
${checkHost "moby-light"}
${checkHost "lappy-light"}
${checkHost "desko"}
${checkHost "lappy"}
${checkHost "servo"}
${checkHost "moby"}
${checkHost "rescue"}
# still want to build the -light variants first so as to avoid multiple simultaneous webkitgtk builds
${checkHost "desko-light-next"}
${checkHost "moby-light-next"}
${checkHost "desko-next"}
${checkHost "lappy-next"}
${checkHost "servo-next"}
${checkHost "moby-next"}
${checkHost "rescue-next"}
echo "desko: $RC_desko"
echo "lappy: $RC_lappy"
echo "servo: $RC_servo"
echo "moby: $RC_moby"
echo "rescue: $RC_rescue"
echo "desko-next: $RC_desko_next"
echo "lappy-next: $RC_lappy_next"
echo "servo-next: $RC_servo_next"
echo "moby-next: $RC_moby_next"
echo "rescue-next: $RC_rescue_next"
# i don't really care if the -next hosts fail. i build them mostly to keep the cache fresh/ready
exit $(($RC_desko | $RC_lappy | $RC_servo | $RC_moby | $RC_rescue))
''
);
};
check.rescue = {
type = "app";
program = builtins.toString (pkgs.writeShellScript "check-rescue" ''
nix build -v '.#imgs.rescue' --out-link ./build/result-rescue-img -j2
'');
};
bench = {
type = "app";
program = builtins.toString (pkgs.writeShellScript "bench" ''
doBench() {
attrPath="$1"
shift
echo -n "benchmarking eval of '$attrPath'... "
/run/current-system/sw/bin/time -f "%e sec" -o /dev/stdout \
nix eval --no-eval-cache --quiet --raw ".#$attrPath" --apply 'result: if result != null then "" else "unexpected null"' $@ 2> /dev/null
}
if [ -n "$1" ]; then
doBench "$@"
else
doBench hostConfigs
doBench hostConfigs.lappy
doBench hostConfigs.lappy.sane.programs
doBench hostConfigs.lappy.sane.users.colin
doBench hostConfigs.lappy.sane.fs
doBench hostConfigs.lappy.environment.systemPackages
fi
'');
};
};
templates = {
env.python-data = {
# initialize with:
# - `nix flake init -t '/home/colin/dev/nixos/#env.python-data'`
# then enter with:
# - `nix develop`
path = ./templates/env/python-data;
description = "python environment for data processing";
};
pkgs.rust-inline = {
# initialize with:
# - `nix flake init -t '/home/colin/dev/nixos/#pkgs.rust-inline'`
path = ./templates/pkgs/rust-inline;
description = "rust package and development environment (inline rust sources)";
};
pkgs.rust = {
# initialize with:
# - `nix flake init -t '/home/colin/dev/nixos/#pkgs.rust'`
path = ./templates/pkgs/rust;
description = "rust package fit to ship in nixpkgs";
};
pkgs.make = {
# initialize with:
# - `nix flake init -t '/home/colin/dev/nixos/#pkgs.make'`
path = ./templates/pkgs/make;
description = "default Makefile-based derivation";
};
};
};
}

View File

@@ -0,0 +1,44 @@
# Samsung chromebook XE303C12
# - <https://wiki.postmarketos.org/wiki/Samsung_Chromebook_(google-snow)>
{ ... }:
{
imports = [
./fs.nix
];
sane.hal.samsung.enable = true;
sane.roles.client = true;
# sane.roles.pc = true;
users.users.colin.initialPassword = "147147";
sane.programs.sway.enableFor.user.colin = true;
sane.programs.calls.enableFor.user.colin = false;
sane.programs.consoleMediaUtils.enableFor.user.colin = true;
sane.programs.epiphany.enableFor.user.colin = true;
sane.programs."gnome.geary".enableFor.user.colin = false;
# sane.programs.firefox.enableFor.user.colin = true;
sane.programs.portfolio-filemanager.enableFor.user.colin = true;
sane.programs.signal-desktop.enableFor.user.colin = false;
sane.programs.wike.enableFor.user.colin = true;
sane.programs.dino.config.autostart = false;
sane.programs.dissent.config.autostart = false;
sane.programs.fractal.config.autostart = false;
# sane.programs.guiApps.enableFor.user.colin = false;
# sane.programs.pcGuiApps.enableFor.user.colin = false; #< errors!
sane.programs.blueberry.enableFor.user.colin = false; # bluetooth manager: doesn't cross compile!
# sane.programs.brave.enableFor.user.colin = false; # 2024/06/03: fails eval if enabled on cross
# sane.programs.firefox.enableFor.user.colin = false; # 2024/06/03: this triggers an eval error in yarn stuff -- i'm doing IFD somewhere!!?
sane.programs.mepo.enableFor.user.colin = false; # 2024/06/04: doesn't cross compile (nodejs)
sane.programs.mercurial.enableFor.user.colin = false; # 2024/06/03: does not cross compile
sane.programs.nixpkgs-review.enableFor.user.colin = false; # 2024/06/03: OOMs when cross compiling
sane.programs.ntfy-sh.enableFor.user.colin = false; # 2024/06/04: doesn't cross compile (nodejs)
sane.programs.pwvucontrol.enableFor.user.colin = false; # 2024/06/03: doesn't cross compile (libspa-sys)
sane.programs."sane-scripts.bt-search".enableFor.user.colin = false; # 2024/06/03: does not cross compile
sane.programs.sequoia.enableFor.user.colin = false; # 2024/06/03: does not cross compile
sane.programs.zathura.enableFor.user.colin = false; # 2024/06/03: does not cross compile
}

View File

@@ -0,0 +1,16 @@
{ ... }:
{
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/55555555-0303-0c12-86df-eda9e9311526";
fsType = "btrfs";
options = [
"compress=zstd"
"defaults"
];
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/303C-5A37";
fsType = "vfat";
};
}

View File

@@ -1,4 +1,4 @@
{ config, pkgs, ... }: { config, lib, pkgs, ... }:
{ {
imports = [ imports = [
./fs.nix ./fs.nix
@@ -11,6 +11,8 @@
# don't enable wifi by default: it messes with connectivity. # don't enable wifi by default: it messes with connectivity.
# systemd.services.iwd.enable = false; # systemd.services.iwd.enable = false;
# systemd.services.wpa_supplicant.enable = false; # systemd.services.wpa_supplicant.enable = false;
sane.programs.wpa_supplicant.enableFor.user.colin = lib.mkForce false;
sane.programs.wpa_supplicant.enableFor.system = lib.mkForce false;
sops.secrets.colin-passwd.neededForUsers = true; sops.secrets.colin-passwd.neededForUsers = true;
@@ -20,11 +22,12 @@
sane.roles.pc = true; sane.roles.pc = true;
sane.services.wg-home.enable = true; sane.services.wg-home.enable = true;
sane.services.wg-home.ip = config.sane.hosts.by-name."desko".wg-home.ip; sane.services.wg-home.ip = config.sane.hosts.by-name."desko".wg-home.ip;
sane.ovpn.addrV4 = "172.26.55.21";
# sane.ovpn.addrV6 = "fd00:0000:1337:cafe:1111:1111:20c1:a73c";
sane.services.duplicity.enable = true; sane.services.duplicity.enable = true;
sane.nixcache.remote-builders.desko = false; sane.nixcache.remote-builders.desko = false;
sane.programs.cups.enableFor.user.colin = true;
sane.programs.sway.enableFor.user.colin = true; sane.programs.sway.enableFor.user.colin = true;
sane.programs.iphoneUtils.enableFor.user.colin = true; sane.programs.iphoneUtils.enableFor.user.colin = true;
sane.programs.steam.enableFor.user.colin = true; sane.programs.steam.enableFor.user.colin = true;
@@ -32,7 +35,11 @@
sane.programs."gnome.geary".config.autostart = true; sane.programs."gnome.geary".config.autostart = true;
sane.programs.signal-desktop.config.autostart = true; sane.programs.signal-desktop.config.autostart = true;
boot.loader.efi.canTouchEfiVariables = false; sane.programs.nwg-panel.config = {
battery = false;
brightness = false;
};
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ]; sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
# needed to use libimobiledevice/ifuse, for iphone sync # needed to use libimobiledevice/ifuse, for iphone sync
@@ -49,7 +56,4 @@
# TODO: ALLOW_USERS doesn't seem to work. still need `sudo snapper -c nix list` # TODO: ALLOW_USERS doesn't seem to work. still need `sudo snapper -c nix list`
ALLOW_USERS = [ "colin" ]; ALLOW_USERS = [ "colin" ];
}; };
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
system.stateVersion = "21.05";
} }

View File

@@ -9,12 +9,12 @@
sane.roles.pc = true; sane.roles.pc = true;
sane.services.wg-home.enable = true; sane.services.wg-home.enable = true;
sane.services.wg-home.ip = config.sane.hosts.by-name."lappy".wg-home.ip; sane.services.wg-home.ip = config.sane.hosts.by-name."lappy".wg-home.ip;
sane.ovpn.addrV4 = "172.23.119.72";
# sane.ovpn.addrV6 = "fd00:0000:1337:cafe:1111:1111:0332:aa96/128";
# sane.guest.enable = true; # sane.guest.enable = true;
boot.loader.efi.canTouchEfiVariables = false;
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ]; sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
sane.programs.cups.enableFor.user.colin = true;
sane.programs.stepmania.enableFor.user.colin = true; sane.programs.stepmania.enableFor.user.colin = true;
sane.programs.sway.enableFor.user.colin = true; sane.programs.sway.enableFor.user.colin = true;
@@ -33,7 +33,4 @@
SUBVOLUME = "/nix"; SUBVOLUME = "/nix";
ALLOW_USERS = [ "colin" ]; ALLOW_USERS = [ "colin" ];
}; };
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
system.stateVersion = "21.05";
} }

View File

@@ -1,7 +0,0 @@
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compat { include "complete" };
xkb_symbols { include "pc+us+inet(evdev)" };
xkb_geometry { include "pc(pc105)" };
};

View File

@@ -1,22 +0,0 @@
# tow-boot: <https://tow-boot.org>
# docs (pinephone specific): <https://github.com/Tow-Boot/Tow-Boot/tree/development/boards/pine64-pinephoneA64>
# LED and button behavior is defined here: <https://github.com/Tow-Boot/Tow-Boot/blob/development/modules/tow-boot/phone-ux.nix>
# - hold VOLDOWN: enter recovery mode
# - LED will turn aqua instead of yellow
# - recovery mode would ordinarily allow a selection of entries, but for pinephone i guess it doesn't do anything?
# - hold VOLUP: force it to load the OS from eMMC?
# - LED will turn blue instead of yellow
# boot LEDs:
# - yellow = entered tow-boot
# - 10 red flashes => poweroff means tow-boot couldn't boot into the next stage (i.e. distroboot)
# - distroboot: <https://source.denx.de/u-boot/u-boot/-/blob/v2022.04/doc/develop/distro.rst>)
{ config, pkgs, ... }:
{
# we need space in the GPT header to place tow-boot.
# only actually need 1 MB, but better to over-allocate than under-allocate
sane.image.extraGPTPadding = 16 * 1024 * 1024;
sane.image.firstPartGap = 0;
sane.image.installBootloader = ''
dd if=${pkgs.tow-boot-pinephone}/Tow-Boot.noenv.bin of=$out/nixos.img bs=1024 seek=8 conv=notrunc
'';
}

View File

@@ -1,7 +1,4 @@
# Pinephone # Pinephone
# other setups to reference:
# - <https://hamblingreen.gitlab.io/2022/03/02/my-pinephone-setup.html>
# - sxmo Arch user. lots of app recommendations
# #
# wikis, resources, ...: # wikis, resources, ...:
# - Linux Phone Apps: <https://linuxphoneapps.org/> # - Linux Phone Apps: <https://linuxphoneapps.org/>
@@ -12,18 +9,17 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
{ {
imports = [ imports = [
./bootloader.nix
./fs.nix ./fs.nix
./gps.nix ./gps.nix
./kernel.nix
./polyfill.nix
]; ];
sane.hal.pine64.enable = true;
sane.roles.client = true; sane.roles.client = true;
sane.roles.handheld = true; sane.roles.handheld = true;
sane.programs.zsh.config.showDeadlines = false; # unlikely to act on them when in shell
sane.services.wg-home.enable = true; sane.services.wg-home.enable = true;
sane.services.wg-home.ip = config.sane.hosts.by-name."moby".wg-home.ip; sane.services.wg-home.ip = config.sane.hosts.by-name."moby".wg-home.ip;
sane.ovpn.addrV4 = "172.24.87.255";
# sane.ovpn.addrV6 = "fd00:0000:1337:cafe:1111:1111:18cd:a72b";
# XXX colin: phosh doesn't work well with passwordless login, # XXX colin: phosh doesn't work well with passwordless login,
# so set this more reliable default password should anything go wrong # so set this more reliable default password should anything go wrong
@@ -32,13 +28,7 @@
sops.secrets.colin-passwd.neededForUsers = true; sops.secrets.colin-passwd.neededForUsers = true;
# sane.gui.sxmo.enable = true;
sane.programs.sway.enableFor.user.colin = true; sane.programs.sway.enableFor.user.colin = true;
sane.programs.swaylock.enableFor.user.colin = false; #< not usable on touch
sane.programs.schlock.enableFor.user.colin = true;
sane.programs.swayidle.config.actions.screenoff.delay = 300;
sane.programs.swayidle.config.actions.screenoff.enable = true;
sane.programs.sane-input-handler.enableFor.user.colin = true;
sane.programs.blueberry.enableFor.user.colin = false; # bluetooth manager: doesn't cross compile! sane.programs.blueberry.enableFor.user.colin = false; # bluetooth manager: doesn't cross compile!
sane.programs.fcitx5.enableFor.user.colin = false; # does not cross compile sane.programs.fcitx5.enableFor.user.colin = false; # does not cross compile
sane.programs.mercurial.enableFor.user.colin = false; # does not cross compile sane.programs.mercurial.enableFor.user.colin = false; # does not cross compile
@@ -54,10 +44,6 @@
# sane.programs."gnome.geary".config.autostart = true; # sane.programs."gnome.geary".config.autostart = true;
# sane.programs.calls.config.autostart = true; # sane.programs.calls.config.autostart = true;
sane.programs.firefox.mime.priority = 300; # prefer other browsers when possible
# HACK/TODO: make `programs.P.env.VAR` behave according to `mime.priority`
sane.programs.firefox.env = lib.mkForce {};
sane.programs.epiphany.env.BROWSER = "epiphany";
sane.programs.pipewire.config = { sane.programs.pipewire.config = {
# tune so Dino doesn't drop audio # tune so Dino doesn't drop audio
# there's seemingly two buffers for the mic (see: <https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/FAQ#pipewire-buffering-explained>) # there's seemingly two buffers for the mic (see: <https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/FAQ#pipewire-buffering-explained>)
@@ -74,53 +60,7 @@
max-quantum = 8192; max-quantum = 8192;
}; };
boot.loader.efi.canTouchEfiVariables = false;
# /boot space is at a premium. default was 20. # /boot space is at a premium. default was 20.
# even 10 can be too much # even 10 can be too much
boot.loader.generic-extlinux-compatible.configurationLimit = 8; boot.loader.generic-extlinux-compatible.configurationLimit = 8;
# mobile.bootloader.enable = false;
# mobile.boot.stage-1.enable = false;
# boot.initrd.systemd.enable = false;
# boot.initrd.services.swraid.enable = false; # attempt to fix dm_mod stuff
# hardware.firmware makes the referenced files visible to the kernel, for whenever a driver explicitly asks for them.
# these files are visible from userspace by following `/sys/module/firmware_class/parameters/path`
#
# mobile-nixos' /lib/firmware includes:
# rtl_bt (bluetooth)
# anx7688-fw.bin (USB-C chip: power negotiation, HDMI/dock)
# ov5640_af.bin (camera module)
# hardware.firmware = [ config.mobile.device.firmware ];
# hardware.firmware = [ pkgs.rtl8723cs-firmware ];
hardware.firmware = [
(pkgs.linux-firmware-megous.override {
# rtl_bt = false probably means no bluetooth connectivity.
# N.B.: DON'T RE-ENABLE without first confirming that wake-on-lan works during suspend (rtcwake).
# it seems the rtl_bt stuff ("bluetooth coexist") might make wake-on-LAN radically more flaky.
rtl_bt = false;
})
];
system.stateVersion = "21.11";
# defined: https://www.freedesktop.org/software/systemd/man/machine-info.html
# XXX colin: not sure which, if any, software makes use of this
environment.etc."machine-info".text = ''
CHASSIS="handset"
'';
# enable rotation sensor
# hardware.sensor.iio.enable = true;
services.udev.extraRules = let
chmod = "${pkgs.coreutils}/bin/chmod";
chown = "${pkgs.coreutils}/bin/chown";
in ''
# make Pinephone flashlight writable by user.
# taken from postmarketOS: <repo:postmarketOS/pmaports:device/main/device-pine64-pinephone/60-flashlight.rules>
SUBSYSTEM=="leds", DEVPATH=="*/*:flash", RUN+="${chmod} g+w /sys%p/brightness /sys%p/flash_strobe", RUN+="${chown} :video /sys%p/brightness /sys%p/flash_strobe"
# make Pinephone front LEDs writable by user.
SUBSYSTEM=="leds", DEVPATH=="*/*:indicator", RUN+="${chmod} g+w /sys%p/brightness", RUN+="${chown} :video /sys%p/brightness"
'';
} }

View File

@@ -1,273 +0,0 @@
{ pkgs, ... }:
let
dmesg = "${pkgs.util-linux}/bin/dmesg";
grep = "${pkgs.gnugrep}/bin/grep";
modprobe = "${pkgs.kmod}/bin/modprobe";
ensureHWReady = ''
# common boot failure:
# blank screen (no backlight even), with the following log:
# ```syslog
# sun8i-dw-hdmi 1ee0000.hdmi: Couldn't get the HDMI PHY
# ...
# sun4i-drm display-engine: Couldn't bind all pipelines components
# ...
# sun8i-dw-hdmi: probe of 1ee0000.hdmi failed with error -17
# ```
#
# in particular, that `probe ... failed` occurs *only* on failed boots
# (the other messages might sometimes occur even on successful runs?)
#
# reloading the sun8i hdmi driver usually gets the screen on, showing boot text.
# then restarting display-manager.service gets us to the login.
#
# NB: the above log is default level. though less specific, there's a `err` level message that also signals this:
# sun4i-drm display-engine: failed to bind 1ee0000.hdmi (ops sun8i_dw_hdmi_ops [sun8i_drm_hdmi]): -17
# NB: this is the most common, but not the only, failure mode for `display-manager`.
# another error seems characterized by these dmesg logs, in which reprobing sun8i_drm_hdmi does not fix:
# ```syslog
# sun6i-mipi-dsi 1ca0000.dsi: Couldn't get the MIPI D-PHY
# sun4i-drm display-engine: Couldn't bind all pipelines components
# sun6i-mipi-dsi 1ca0000.dsi: Couldn't register our component
# ```
if (${dmesg} --kernel --level err --color=never --notime | ${grep} -q 'sun4i-drm display-engine: failed to bind 1ee0000.hdmi')
then
echo "reprobing sun8i_drm_hdmi"
# if a command here fails it errors the whole service, so prefer to log instead
${modprobe} -r sun8i_drm_hdmi || echo "failed to unload sun8i_drm_hdmi"
${modprobe} sun8i_drm_hdmi || echo "failed to load sub8i_drm_hdmi"
fi
'';
in
{
# kernel compatibility (2024/05/22: 03dab630)
# - linux-megous: boots to ssh, desktop
# - camera apps: megapixels (no cameras found), snapshot (no cameras found)
# - linux-postmarketos: boots to ssh. desktop ONLY if "anx7688" is in the initrd.availableKernelModules.
# - camera apps: megapixels (both rear and front cameras work), `cam -l` (finds only the rear camera), snapshot (no cameras found)
# - linux-megous.override { withMegiPinephoneConfig = true; }: NO SSH, NO SIGNS OF LIFE
# - linux-megous.override { withFullConfig = false; }: boots to ssh, no desktop
#
boot.kernelPackages = pkgs.linuxPackagesFor (pkgs.linux-postmarketos.override {
withModemPower = true;
});
# boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux-megous;
# boot.kernelPackages = pkgs.linuxPackagesFor (pkgs.linux-megous.override {
# withFullConfig = false;
# });
# boot.kernelPackages = pkgs.linuxPackagesFor (pkgs.linux-megous.override {
# withMegiPinephoneConfig = true; #< N.B.: does not boot as of 2024/05/22!
# });
# boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux-manjaro;
# boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux_latest;
# nixpkgs.hostPlatform.linux-kernel becomes stdenv.hostPlatform.linux-kernel
nixpkgs.hostPlatform.linux-kernel = {
# defaults:
name = "aarch64-multiplatform";
# baseConfig: defaults to "defconfig";
# baseConfig = "pinephone_defconfig"; #< N.B.: ignored by `pkgs.linux-megous`
DTB = true; #< DTB: compile device tree blobs
# autoModules (default: true): for config options not manually specified, answer `m` to anything which supports it.
# - this effectively builds EVERY MODULE SUPPORTED.
autoModules = true; #< N.B.: ignored by `pkgs.linux-megous`
# preferBuiltin (default: false; true for rpi): for config options which default to `Y` upstream, build them as `Y` (overriding `autoModules`)
# preferBuiltin = false;
# build a compressed kernel image: without this i run out of /boot space in < 10 generations
# target = "Image"; # <-- default
target = "Image.gz"; # <-- compress the kernel image
# target = "zImage"; # <-- confuses other parts of nixos :-(
};
# boot.initrd.kernelModules = [
# "drm" #< force drm to be plugged
# ];
boot.initrd.availableKernelModules = [
# see <repo:postmarketOS/pmaports:device/main/device-pine64-pinephone/modules-initfs>
# - they include sun6i_mipi_dsi sun4i_drm pwm_sun4i sun8i_mixer anx7688 gpio_vibra pinephone_keyboard
"anx7688" #< required for display initialization and functional cameras
# full list of modules active post-boot with the linux-megous kernel + autoModules=true:
# - `lsmod | sort | cut -d ' ' -f 1`
# "8723cs"
# "axp20x_adc" #< NOT FOUND in megous-no-autoModules
# "axp20x_battery"
# "axp20x_pek"
# "axp20x_usb_power"
# "backlight"
# "blake2b_generic"
# "bluetooth"
# "bridge"
# "btbcm"
# "btqca"
# "btrfs"
# "btrtl"
# "cec"
# "cfg80211"
# "chacha_neon"
# "crc_ccitt"
# "crct10dif_ce"
# "crypto_engine"
# "display_connector" #< NOT FOUND in pmos
# "drm"
# "drm_display_helper"
# "drm_dma_helper"
# "drm_kms_helper"
# "drm_shmem_helper"
# "dw_hdmi"
# "dw_hdmi_cec" #< NOT FOUND in pmos
# "dw_hdmi_i2s_audio"
# "ecc"
# "ecdh_generic"
# "fuse"
# "gc2145" #< NOT FOUND in megous-no-autoModules
# "goodix_ts"
# "gpio_vibra" #< NOT FOUND in megous-no-autoModules
# "gpu_sched"
# "hci_uart"
# "i2c_gpio"
# "inv_mpu6050" #< NOT FOUND in megous-no-autoModules
# "inv_mpu6050_i2c" #< NOT FOUND in megous-no-autoModules
# "inv_sensors_timestamp" #< NOT FOUND in megous-no-autoModules
# "ip6t_rpfilter"
# "ip6_udp_tunnel"
# "ip_set"
# "ip_set_hash_ipport"
# "ip_tables"
# "ipt_rpfilter"
# "joydev"
# "led_class_flash" #< NOT FOUND in megous-no-autoModules
# "leds_sgm3140" #< NOT FOUND in megous-no-autoModules
# "ledtrig_pattern" #< NOT FOUND in megous-no-autoModules
# "libarc4"
# "libchacha"
# "libchacha20poly1305"
# "libcrc32c"
# "libcurve25519_generic"
# "lima"
# "llc"
# "mac80211"
# "macvlan"
# "mc"
# "modem_power"
# "mousedev"
# "nf_conntrack"
# "nf_defrag_ipv4"
# "nf_defrag_ipv6"
# "nf_log_syslog"
# "nf_nat"
# "nfnetlink"
# "nf_tables"
# "nft_chain_nat"
# "nft_compat"
# "nls_cp437"
# "nls_iso8859_1"
# "nvmem_reboot_mode"
# "ov5640"
# "panel_sitronix_st7703"
# "phy_sun6i_mipi_dphy"
# "pinctrl_axp209" #< NOT FOUND in pmos
# "pinephone_keyboard" #< NOT FOUND in megous-no-autoModules
# "poly1305_neon"
# "polyval_ce"
# "polyval_generic"
# "ppkb_manager" #< NOT FOUND in megous-no-autoModules
# "pwm_bl"
# "pwm_sun4i"
# "qrtr"
# "raid6_pq"
# "rfkill"
# "rtw88_8703b"
# "rtw88_8723cs"
# "rtw88_8723x"
# "rtw88_core"
# "rtw88_sdio"
# "sch_fq_codel"
# "sm4"
# "snd_soc_bt_sco"
# "snd_soc_ec25" #< NOT FOUND in megous-no-autoModules
# "snd_soc_hdmi_codec"
# "snd_soc_simple_amplifier"
# "snd_soc_simple_card"
# "snd_soc_simple_card_utils"
# "stk3310" #< NOT FOUND in megous-no-autoModules
# "st_magn"
# "st_magn_i2c"
# "st_magn_spi" #< NOT FOUND in pmos
# "stp"
# "st_sensors"
# "st_sensors_i2c"
# "st_sensors_spi" #< NOT FOUND in pmos
# "sun4i_drm"
# "sun4i_i2s"
# "sun4i_lradc_keys" #< NOT FOUND in megous-no-autoModules
# "sun4i_tcon"
# "sun50i_codec_analog"
# "sun6i_csi"
# "sun6i_dma"
# "sun6i_mipi_dsi"
# "sun8i_a33_mbus" #< NOT FOUND in megous-no-autoModules
# "sun8i_adda_pr_regmap"
# "sun8i_ce" #< NOT FOUND in pmos
# "sun8i_codec" #< NOT FOUND in megous-no-autoModules
# "sun8i_di" #< NOT FOUND in megous-no-autoModules
# "sun8i_drm_hdmi"
# "sun8i_mixer"
# "sun8i_rotate" #< NOT FOUND in megous-no-autoModules
# "sun8i_tcon_top"
# "sun9i_hdmi_audio" #< NOT FOUND in megous-no-autoModules
# "sunxi_wdt" #< NOT FOUND in pmos
# "tap"
# "typec" #< NOT FOUND in pmos
# "udp_tunnel"
# "uio" #< NOT FOUND in pmos
# "uio_pdrv_genirq"
# "v4l2_async"
# "v4l2_cci" #< NOT FOUND in pmos
# "v4l2_flash_led_class" #< NOT FOUND in megous-no-autoModules
# "v4l2_fwnode"
# "v4l2_mem2mem"
# "videobuf2_common"
# "videobuf2_dma_contig"
# "videobuf2_memops"
# "videobuf2_v4l2"
# "videodev"
# "wireguard"
# "xor"
# "x_tables"
# "xt_conntrack"
# "xt_LOG"
# "xt_nat"
# "xt_pkttype"
# "xt_set"
# "xt_tcpudp"
# "zram"
];
# disable proximity sensor.
# the filtering/calibration is bad that it causes the screen to go fully dark at times.
# boot.blacklistedKernelModules = [ "stk3310" ];
boot.kernelParams = [
# without this some GUI apps fail: `DRM_IOCTL_MODE_CREATE_DUMB failed: Cannot allocate memory`
# this is because they can't allocate enough video ram.
# see related nixpkgs issue: <https://github.com/NixOS/nixpkgs/issues/260222>
# TODO(2023/12/03): remove once mesa 23.3.1 lands: <https://github.com/NixOS/nixpkgs/pull/265740>
#
# the default CMA seems to be 32M.
# i was running fine with 256MB from 2022/07-ish through 2022/12-ish, but then the phone quit reliably coming back from sleep (phosh): maybe a memory leak?
# bumped to 512M on 2023/01
# bumped to 1536M on 2024/05
# `cat /proc/meminfo` to see CmaTotal/CmaFree if interested in tuning this.
# kernel param mentioned here: <https://cateee.net/lkddb/web-lkddb/CMA_SIZE_PERCENTAGE.html>
# i think cma mem isn't exclusive -- it can be used as ordinary `malloc`, still. i heard someone suggest the OS default should just be 50% memory to CMA.
"cma=1536M"
# 2023/10/20: potential fix for the lima (GPU) timeout bugs:
# - <https://gitlab.com/postmarketOS/pmaports/-/issues/805#note_890467824>
"lima.sched_timeout_ms=2000"
];
# services.xserver.displayManager.job.preStart = ensureHWReady;
# systemd.services.greetd.preStart = ensureHWReady;
systemd.services.unl0kr.preStart = ensureHWReady;
}

View File

@@ -1,45 +0,0 @@
# this file configures preferences per program, without actually enabling any programs.
# the goal is to separate the place where we decide *what* to use (i.e. `sane.programs.firefox.enable = true` -- at the toplevel)
# from where we specific how that thing should behave *if* it's in use.
#
# NixOS backgrounds:
# - <https://github.com/NixOS/nixos-artwork>
# - <https://github.com/NixOS/nixos-artwork/issues/50> (colorful; unmerged)
# - <https://github.com/NixOS/nixos-artwork/pull/60/files> (desktop-oriented; clean; unmerged)
# - <https://itsfoss.com/content/images/2023/04/nixos-tutorials.png>
{ lib, pkgs, sane-lib, ... }:
{
sane.programs.firefox.config = {
# compromise impermanence for the sake of usability
persistCache = "private";
persistData = "private";
# i don't do crypto stuff on moby
addons.ether-metamask.enable = false;
# sidebery UX doesn't make sense on small screen
addons.sidebery.enable = false;
};
sane.programs.swaynotificationcenter.config = {
backlight = "backlight"; # /sys/class/backlight/*backlight*/brightness
};
sane.programs.alacritty.config.fontSize = 9;
sane.programs.sway.config = {
font = "pango:monospace 10";
mod = "Mod1"; # prefer Alt
workspace_layout = "tabbed";
};
sane.programs.waybar.config = {
fontSize = 14;
height = 26;
persistWorkspaces = [ "1" "2" "3" "4" "5" ];
modules.media = false;
modules.network = false;
modules.perf = false;
modules.windowTitle = false;
# TODO: show modem state
};
}

View File

@@ -4,7 +4,6 @@
./fs.nix ./fs.nix
]; ];
boot.loader.efi.canTouchEfiVariables = false;
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ]; sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
sane.persist.enable = false; # what we mean here is that the image is immutable; `/` is still tmpfs. sane.persist.enable = false; # what we mean here is that the image is immutable; `/` is still tmpfs.
sane.nixcache.enable = false; # don't want to be calling out to dead machines that we're *trying* to rescue sane.nixcache.enable = false; # don't want to be calling out to dead machines that we're *trying* to rescue
@@ -12,7 +11,4 @@
# auto-login at shell # auto-login at shell
services.getty.autologinUser = "colin"; services.getty.autologinUser = "colin";
# users.users.colin.initialPassword = "colin"; # users.users.colin.initialPassword = "colin";
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
system.stateVersion = "21.05";
} }

View File

@@ -28,6 +28,8 @@
sane.services.wg-home.forwardToWan = true; sane.services.wg-home.forwardToWan = true;
sane.services.wg-home.routeThroughServo = false; sane.services.wg-home.routeThroughServo = false;
sane.services.wg-home.ip = config.sane.hosts.by-name."servo".wg-home.ip; sane.services.wg-home.ip = config.sane.hosts.by-name."servo".wg-home.ip;
sane.ovpn.addrV4 = "172.23.174.114";
# sane.ovpn.addrV6 = "fd00:0000:1337:cafe:1111:1111:8df3:14b0";
sane.nixcache.remote-builders.desko = false; sane.nixcache.remote-builders.desko = false;
sane.nixcache.remote-builders.servo = false; sane.nixcache.remote-builders.servo = false;
# sane.services.duplicity.enable = true; # TODO: re-enable after HW upgrade # sane.services.duplicity.enable = true; # TODO: re-enable after HW upgrade
@@ -36,7 +38,6 @@
# using root here makes sure we always have an escape hatch # using root here makes sure we always have an escape hatch
services.getty.autologinUser = "root"; services.getty.autologinUser = "root";
boot.loader.efi.canTouchEfiVariables = false;
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ]; sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
# both transmission and ipfs try to set different net defaults. # both transmission and ipfs try to set different net defaults.
@@ -44,13 +45,5 @@
boot.kernel.sysctl = { boot.kernel.sysctl = {
"net.core.rmem_max" = 4194304; # 4MB "net.core.rmem_max" = 4194304; # 4MB
}; };
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "21.11";
} }

View File

@@ -3,9 +3,19 @@
let let
portOpts = with lib; types.submodule { portOpts = with lib; types.submodule {
options = { options = {
visibleTo.ovpn = mkOption { visibleTo.ovpns = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
description = ''
whether to forward inbound traffic on the OVPN vpn port to the corresponding localhost port.
'';
};
visibleTo.doof = mkOption {
type = types.bool;
default = false;
description = ''
whether to forward inbound traffic on the doofnet vpn port to the corresponding localhost port.
'';
}; };
}; };
}; };
@@ -13,7 +23,7 @@ in
{ {
options = with lib; { options = with lib; {
sane.ports.ports = mkOption { sane.ports.ports = mkOption {
# add the `visibleTo.ovpn` option # add the `visibleTo.{doof,ovpns}` options
type = types.attrsOf portOpts; type = types.attrsOf portOpts;
}; };
}; };
@@ -40,18 +50,16 @@ in
# tun-sea config # tun-sea config
sane.dns.zones."uninsane.org".inet.A."doof.tunnel" = "205.201.63.12"; sane.dns.zones."uninsane.org".inet.A."doof.tunnel" = "205.201.63.12";
sane.dns.zones."uninsane.org".inet.AAAA."doof.tunnel" = "2602:fce8:106::51"; # sane.dns.zones."uninsane.org".inet.AAAA."doof.tunnel" = "2602:fce8:106::51"; #< TODO: enable IPv6
networking.wireguard.interfaces.wg-doof = let networking.wireguard.interfaces.wg-doof = {
ip = "${pkgs.iproute2}/bin/ip";
in {
privateKeyFile = config.sops.secrets.wg_doof_privkey.path; privateKeyFile = config.sops.secrets.wg_doof_privkey.path;
# wg is active only in this namespace. # wg is active only in this namespace.
# run e.g. ip netns exec doof <some command like ping/curl/etc, it'll go through wg> # run e.g. ip netns exec doof <some command like ping/curl/etc, it'll go through wg>
# sudo ip netns exec doof ping www.google.com # sudo ip netns exec doof ping www.google.com
interfaceNamespace = "doof"; interfaceNamespace = "doof";
ips = [ ips = [
"205.201.63.12/32" "205.201.63.12"
"2602:fce8:106::51/128" # "2602:fce8:106::51/128" #< TODO: enable IPv6
]; ];
peers = [ peers = [
{ {
@@ -63,45 +71,24 @@ in
persistentKeepalive = 25; #< keep the NAT alive persistentKeepalive = 25; #< keep the NAT alive
} }
]; ];
preSetup = ''
${ip} netns add doof || (test -e /run/netns/doof && echo "doof already exists")
'';
postShutdown = ''
${ip} netns delete doof || echo "couldn't delete doof"
'';
}; };
sane.netns.doof.hostVethIpv4 = "10.0.2.5";
sane.netns.doof.netnsVethIpv4 = "10.0.2.6";
sane.netns.doof.netnsPubIpv4 = "205.201.63.12";
sane.netns.doof.routeTable = 12;
# OVPN CONFIG (https://www.ovpn.com): # OVPN CONFIG (https://www.ovpn.com):
# DOCS: https://nixos.wiki/wiki/WireGuard # DOCS: https://nixos.wiki/wiki/WireGuard
# if you `systemctl restart wireguard-wg-ovpns`, make sure to also restart any other services in `NetworkNamespacePath = .../ovpns`. # if you `systemctl restart wireguard-wg-ovpns`, make sure to also restart any other services in `NetworkNamespacePath = .../ovpns`.
# TODO: why not create the namespace as a seperate operation (nix config for that?) # TODO: why not create the namespace as a seperate operation (nix config for that?)
networking.wireguard.enable = true; networking.wireguard.enable = true;
networking.wireguard.interfaces.wg-ovpns = let networking.wireguard.interfaces.wg-ovpns = {
ip = "${pkgs.iproute2}/bin/ip";
in-ns = "${ip} netns exec ovpns";
iptables = "${pkgs.iptables}/bin/iptables";
veth-host-ip = "10.0.1.5";
veth-local-ip = "10.0.1.6";
vpn-ip = "185.157.162.178";
# DNS = 46.227.67.134, 192.165.9.158, 2a07:a880:4601:10f0:cd45::1, 2001:67c:750:1:cafe:cd45::1
vpn-dns = "46.227.67.134";
bridgePort = port: proto: ''
${in-ns} ${iptables} -A PREROUTING -t nat -p ${proto} --dport ${port} -m iprange --dst-range ${vpn-ip} \
-j DNAT --to-destination ${veth-host-ip}
'';
bridgeStatements = lib.foldlAttrs
(acc: port: portCfg: acc ++ (builtins.map (bridgePort port) portCfg.protocol))
[]
config.sane.ports.ports;
in {
privateKeyFile = config.sops.secrets.wg_ovpns_privkey.path; privateKeyFile = config.sops.secrets.wg_ovpns_privkey.path;
# wg is active only in this namespace. # wg is active only in this namespace.
# run e.g. ip netns exec ovpns <some command like ping/curl/etc, it'll go through wg> # run e.g. ip netns exec ovpns <some command like ping/curl/etc, it'll go through wg>
# sudo ip netns exec ovpns ping www.google.com # sudo ip netns exec ovpns ping www.google.com
interfaceNamespace = "ovpns"; interfaceNamespace = "ovpns";
ips = [ ips = [ "185.157.162.178" ];
"185.157.162.178/32"
];
peers = [ peers = [
{ {
publicKey = "SkkEZDCBde22KTs/Hc7FWvDBfdOCQA4YtBEuC3n5KGs="; publicKey = "SkkEZDCBde22KTs/Hc7FWvDBfdOCQA4YtBEuC3n5KGs=";
@@ -119,99 +106,11 @@ in
# dynamicEndpointRefreshRestartSeconds = 5; # dynamicEndpointRefreshRestartSeconds = 5;
} }
]; ];
preSetup = ''
${ip} netns add ovpns || (test -e /run/netns/ovpns && echo "ovpns already exists")
'';
postShutdown = ''
${in-ns} ip link del ovpns-veth-b || echo "couldn't delete ovpns-veth-b"
${ip} link del ovpns-veth-a || echo "couldn't delete ovpns-veth-a"
${ip} netns delete ovpns || echo "couldn't delete ovpns"
# restore rules/routes
${ip} rule del from ${veth-host-ip} lookup ovpns pref 50 || echo "couldn't delete init -> ovpns rule"
${ip} route del default via ${veth-local-ip} dev ovpns-veth-a proto kernel src ${veth-host-ip} metric 1002 table ovpns || echo "couldn't delete init -> ovpns route"
${ip} rule add from all lookup local pref 0
${ip} rule del from all lookup local pref 100
'';
postSetup = ''
# DOCS:
# - some of this approach is described here: <https://josephmuia.ca/2018-05-16-net-namespaces-veth-nat/>
# - iptables primer: <https://danielmiessler.com/study/iptables/>
# create veth pair
${ip} link add ovpns-veth-a type veth peer name ovpns-veth-b
${ip} addr add ${veth-host-ip}/24 dev ovpns-veth-a
${ip} link set ovpns-veth-a up
# mv veth-b into the ovpns namespace
${ip} link set ovpns-veth-b netns ovpns
${in-ns} ip addr add ${veth-local-ip}/24 dev ovpns-veth-b
${in-ns} ip link set ovpns-veth-b up
# make it so traffic originating from the host side of the veth
# is sent over the veth no matter its destination.
${ip} rule add from ${veth-host-ip} lookup ovpns pref 50
# for traffic originating at the host veth to the WAN, use the veth as our gateway
# not sure if the metric 1002 matters.
${ip} route add default via ${veth-local-ip} dev ovpns-veth-a proto kernel src ${veth-host-ip} metric 1002 table ovpns
# give the default route lower priority
${ip} rule add from all lookup local pref 100
${ip} rule del from all lookup local pref 0
# in order to access DNS in this netns, we need to route it to the VPN's nameservers
# - alternatively, we could fix DNS servers like 1.1.1.1.
${in-ns} ${iptables} -A OUTPUT -t nat -p udp --dport 53 -m iprange --dst-range 127.0.0.53 \
-j DNAT --to-destination ${vpn-dns}:53
'' + (lib.concatStringsSep "\n" bridgeStatements);
}; };
sane.netns.ovpns.hostVethIpv4 = "10.0.1.5";
# create a new routing table that we can use to proxy traffic out of the root namespace sane.netns.ovpns.netnsVethIpv4 = "10.0.1.6";
# through the ovpns namespace, and to the WAN via VPN. sane.netns.ovpns.netnsPubIpv4 = "185.157.162.178";
networking.iproute2.rttablesExtraConfig = '' sane.netns.ovpns.routeTable = 11;
5 ovpns sane.netns.ovpns.dns = "46.227.67.134"; #< DNS requests inside the namespace are forwarded here
'';
networking.iproute2.enable = true;
# HURRICANE ELECTRIC CONFIG:
# networking.sits = {
# hurricane = {
# remote = "216.218.226.238";
# local = "192.168.0.5";
# # local = "10.0.0.5";
# # remote = "10.0.0.1";
# # local = "10.0.0.22";
# dev = "eth0";
# ttl = 255;
# };
# };
# networking.interfaces."hurricane".ipv6 = {
# addresses = [
# # mx.uninsane.org (publically routed /64)
# {
# address = "2001:470:b:465::1";
# prefixLength = 128;
# }
# # client addr
# # {
# # address = "2001:470:a:466::2";
# # prefixLength = 64;
# # }
# ];
# routes = [
# {
# address = "::";
# prefixLength = 0;
# # via = "2001:470:a:466::1";
# }
# ];
# };
# # after configuration, we want the hurricane device to look like this:
# # hurricane: flags=209<UP,POINTOPOINT,RUNNING,NOARP> mtu 1480
# # inet6 2001:470:a:450::2 prefixlen 64 scopeid 0x0<global>
# # inet6 fe80::c0a8:16 prefixlen 64 scopeid 0x20<link>
# # sit txqueuelen 1000 (IPv6-in-IPv4)
# # test with:
# # curl --interface hurricane http://[2607:f8b0:400a:80b::2004]
# # ping 2607:f8b0:400a:80b::2004
}; };
} }

View File

@@ -55,7 +55,7 @@ in
# protocol = [ "tcp" "udp" ]; # protocol = [ "tcp" "udp" ];
# # visibleTo.lan = true; # # visibleTo.lan = true;
# # visibleTo.wan = true; # # visibleTo.wan = true;
# visibleTo.ovpn = true; # forward traffic from the VPN to the root NS # visibleTo.ovpns = true; # forward traffic from the VPN to the root NS
# description = "colin-stun-turn"; # description = "colin-stun-turn";
# }; # };
# "5349" = { # "5349" = {
@@ -63,7 +63,7 @@ in
# protocol = [ "tcp" ]; # protocol = [ "tcp" ];
# # visibleTo.lan = true; # # visibleTo.lan = true;
# # visibleTo.wan = true; # # visibleTo.wan = true;
# visibleTo.ovpn = true; # visibleTo.ovpns = true;
# description = "colin-stun-turn-over-tls"; # description = "colin-stun-turn-over-tls";
# }; # };
# } # }
@@ -76,7 +76,7 @@ in
# protocol = [ "tcp" "udp" ]; # protocol = [ "tcp" "udp" ];
# # visibleTo.lan = true; # # visibleTo.lan = true;
# # visibleTo.wan = true; # # visibleTo.wan = true;
# visibleTo.ovpn = true; # visibleTo.ovpns = true;
# description = "colin-turn-${builtins.toString count}-of-${builtins.toString numPorts}"; # description = "colin-turn-${builtins.toString count}-of-${builtins.toString numPorts}";
# }; # };
# }) # })

View File

@@ -15,6 +15,7 @@
# - could maybe be done with some mount option? # - could maybe be done with some mount option?
{ config, lib, ... }: { config, lib, ... }:
lib.mkIf false #< TODO: remove nfs altogether! it's not exactly the most secure
{ {
services.nfs.server.enable = true; services.nfs.server.enable = true;

View File

@@ -12,6 +12,7 @@ let
external_auth_hook = pkgs.static-nix-shell.mkPython3Bin { external_auth_hook = pkgs.static-nix-shell.mkPython3Bin {
pname = "external_auth_hook"; pname = "external_auth_hook";
srcRoot = ./.; srcRoot = ./.;
pyPkgs = [ "passlib" ];
}; };
# Client initiates a FTP "control connection" on port 21. # Client initiates a FTP "control connection" on port 21.
# - this handles the client -> server commands, and the server -> client status, but not the actual data # - this handles the client -> server commands, and the server -> client status, but not the actual data
@@ -59,18 +60,8 @@ in
enable = true; enable = true;
group = "export"; group = "export";
package = lib.warnIf (lib.versionOlder "2.5.6" pkgs.sftpgo.version) "sftpgo update: safe to use nixpkgs' sftpgo but keep my own `patches`" pkgs.buildGoModule { package = pkgs.sftpgo.overrideAttrs (upstream: {
inherit (pkgs.sftpgo) name ldflags nativeBuildInputs doCheck subPackages postInstall passthru meta; patches = (upstream.patches or []) ++ [
version = "2.5.6-unstable-2024-04-18";
src = pkgs.fetchFromGitHub {
# need to use > 2.5.6 for sftpgo_safe_fileinfo.patch to apply
owner = "drakkan";
repo = "sftpgo";
rev = "950cf67e4c03a12c7e439802cabbb0b42d4ee5f5";
hash = "sha256-UfiFd9NK3DdZ1J+FPGZrM7r2mo9xlKi0dsSlLEinYXM=";
};
vendorHash = "sha256-n1/9A2em3BCtFX+132ualh4NQwkwewMxYIMOphJEamg=";
patches = (pkgs.sftpgo.patches or []) ++ [
# fix for compatibility with kodi: # fix for compatibility with kodi:
# ftp LIST operation returns entries over-the-wire like: # ftp LIST operation returns entries over-the-wire like:
# - dgrwxrwxr-x 1 ftp ftp 9 Apr 9 15:05 Videos # - dgrwxrwxr-x 1 ftp ftp 9 Apr 9 15:05 Videos
@@ -79,7 +70,7 @@ in
# the full set of bits, from which i filter, is found here: <https://pkg.go.dev/io/fs#FileMode> # the full set of bits, from which i filter, is found here: <https://pkg.go.dev/io/fs#FileMode>
./safe_fileinfo.patch ./safe_fileinfo.patch
]; ];
}; });
settings = { settings = {
ftpd = { ftpd = {

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell #!/usr/bin/env nix-shell
#!nix-shell -i python3 -p "python3.withPackages (ps: [ ])" #!nix-shell -i python3 -p "python3.withPackages (ps: [ ps.passlib ])"
# vim: set filetype=python : # vim: set filetype=python :
# #
# available environment variables: # available environment variables:
@@ -37,9 +37,9 @@
# - it seems (empirically) that a user can't cd above their home directory. # - it seems (empirically) that a user can't cd above their home directory.
# though i don't have a reference for that in the docs. # though i don't have a reference for that in the docs.
import crypt
import json import json
import os import os
import passlib.hosts
from hmac import compare_digest from hmac import compare_digest
@@ -112,9 +112,7 @@ def isWireguard(ip: str) -> bool:
def isTrustedCred(password: str) -> bool: def isTrustedCred(password: str) -> bool:
for cred in TRUSTED_CREDS: for cred in TRUSTED_CREDS:
_, method, salt, hash_ = cred.split("$") if passlib.hosts.linux_context.verify(password, cred):
# assert method == "6", f"unrecognized crypt entry: {cred}"
if crypt.crypt(password, f"${method}${salt}") == cred:
return True return True
return False return False

View File

@@ -50,9 +50,15 @@
ENABLE_CAPTCHA = true; ENABLE_CAPTCHA = true;
NOREPLY_ADDRESS = "noreply.anonymous.git@uninsane.org"; NOREPLY_ADDRESS = "noreply.anonymous.git@uninsane.org";
}; };
session.COOKIE_SECURE = true; session = {
COOKIE_SECURE = true;
# keep me logged in for 30 days
SESSION_LIFE_TIME = 60 * 60 * 24 * 30;
};
repository = { repository = {
DEFAULT_BRANCH = "master"; DEFAULT_BRANCH = "master";
ENABLE_PUSH_CREATE_USER = true;
ENABLE_PUSH_CREATE_ORG = true;
}; };
other = { other = {
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false; SHOW_FOOTER_TEMPLATE_LOAD_TIME = false;
@@ -90,6 +96,8 @@
]; ];
}; };
services.openssh.settings.UsePAM = true; #< required for `git` user to authenticate
# hosted git (web view and for `git <cmd>` use # hosted git (web view and for `git <cmd>` use
# TODO: enable publog? # TODO: enable publog?
services.nginx.virtualHosts."git.uninsane.org" = { services.nginx.virtualHosts."git.uninsane.org" = {

View File

@@ -18,13 +18,15 @@ in
protocol = [ "tcp" ]; protocol = [ "tcp" ];
visibleTo.lan = true; visibleTo.lan = true;
visibleTo.wan = true; visibleTo.wan = true;
visibleTo.ovpn = true; # so that letsencrypt can procure a cert for the mx record visibleTo.ovpns = true; # so that letsencrypt can procure a cert for the mx record
visibleTo.doof = true;
description = "colin-http-uninsane.org"; description = "colin-http-uninsane.org";
}; };
sane.ports.ports."443" = { sane.ports.ports."443" = {
protocol = [ "tcp" ]; protocol = [ "tcp" ];
visibleTo.lan = true; visibleTo.lan = true;
visibleTo.wan = true; visibleTo.wan = true;
visibleTo.doof = true;
description = "colin-https-uninsane.org"; description = "colin-https-uninsane.org";
}; };

View File

@@ -22,8 +22,7 @@
sane.ports.ports."50300" = { sane.ports.ports."50300" = {
protocol = [ "tcp" ]; protocol = [ "tcp" ];
# not visible to WAN: i run this in a separate netns # visibleTo.ovpns = true; #< not needed: it runs in the ovpns namespace
visibleTo.ovpn = true;
description = "colin-soulseek"; description = "colin-soulseek";
}; };

View File

@@ -197,7 +197,7 @@ lib.mkIf false #< TODO: re-enable once confident of sandboxing
sane.dns.zones."uninsane.org".inet.CNAME."bt" = "native"; sane.dns.zones."uninsane.org".inet.CNAME."bt" = "native";
sane.ports.ports."51413" = { sane.ports.ports."51413" = {
protocol = [ "tcp" "udp" ]; protocol = [ "tcp" "udp" ];
visibleTo.ovpn = true; # visibleTo.ovpns = true; #< not needed: it runs in the ovpns namespace
description = "colin-bittorrent"; description = "colin-bittorrent";
}; };
} }

View File

@@ -5,13 +5,15 @@ let
dyn-dns = config.sane.services.dyn-dns; dyn-dns = config.sane.services.dyn-dns;
nativeAddrs = lib.mapAttrs (_name: builtins.head) config.sane.dns.zones."uninsane.org".inet.A; nativeAddrs = lib.mapAttrs (_name: builtins.head) config.sane.dns.zones."uninsane.org".inet.A;
bindOvpn = "10.0.1.5"; bindOvpn = "10.0.1.5";
bindDoof = "10.0.2.5";
in in
{ {
sane.ports.ports."53" = { sane.ports.ports."53" = {
protocol = [ "udp" "tcp" ]; protocol = [ "udp" "tcp" ];
visibleTo.lan = true; visibleTo.lan = true;
visibleTo.wan = true; visibleTo.wan = true;
visibleTo.ovpn = true; visibleTo.ovpns = true;
visibleTo.doof = true;
description = "colin-dns-hosting"; description = "colin-dns-hosting";
}; };
@@ -99,6 +101,7 @@ in
listenAddrsIpv4 = [ listenAddrsIpv4 = [
nativeAddrs."servo.lan" nativeAddrs."servo.lan"
bindOvpn bindOvpn
bindDoof
]; ];
}; };
lan = { lan = {

50
hosts/common/boot.nix Normal file
View File

@@ -0,0 +1,50 @@
{ lib, pkgs, ... }:
{
boot.initrd.supportedFilesystems = [ "ext4" "btrfs" "ext2" "ext3" "vfat" ];
# useful emergency utils
boot.initrd.extraUtilsCommands = ''
copy_bin_and_libs ${pkgs.btrfs-progs}/bin/btrfstune
copy_bin_and_libs ${pkgs.util-linux}/bin/{cfdisk,lsblk,lscpu}
copy_bin_and_libs ${pkgs.gptfdisk}/bin/{cgdisk,gdisk}
copy_bin_and_libs ${pkgs.smartmontools}/bin/smartctl
copy_bin_and_libs ${pkgs.e2fsprogs}/bin/resize2fs
'' + lib.optionalString pkgs.stdenv.hostPlatform.isx86_64 ''
copy_bin_and_libs ${pkgs.nvme-cli}/bin/nvme # doesn't cross compile
'';
boot.kernelParams = [
"boot.shell_on_fail"
#v experimental full pre-emption for hopefully better call/audio latency on moby.
# also toggleable at runtime via /sys/kernel/debug/sched/preempt
# defaults to preempt=voluntary
# "preempt=full"
];
# other kernelParams:
# "boot.trace"
# "systemd.log_level=debug"
# "systemd.log_target=console"
# moby has to run recent kernels (defined elsewhere).
# meanwhile, kernel variation plays some minor role in things like sandboxing (landlock) and capabilities.
# simpler to keep near the latest kernel on all devices,
# and also makes certain that any weird system-level bugs i see aren't likely to be stale kernel bugs.
# servo needs zfs though, which doesn't support every kernel.
boot.kernelPackages = lib.mkDefault pkgs.zfs.latestCompatibleLinuxPackages;
# hack in the `boot.shell_on_fail` arg since that doesn't always seem to work.
boot.initrd.preFailCommands = "allowShell=1";
# default: 4 (warn). 7 is debug
boot.consoleLogLevel = 7;
boot.loader.grub.enable = lib.mkDefault false;
boot.loader.generic-extlinux-compatible.enable = lib.mkDefault true;
hardware.enableAllFirmware = true; # firmware with licenses that don't allow for redistribution. fuck lawyers, fuck IP, give me the goddamn firmware.
# hardware.enableRedistributableFirmware = true; # proprietary but free-to-distribute firmware (extraneous to `enableAllFirmware` option)
# default is 252274, which is too low particularly for servo.
# manifests as spurious "No space left on device" when trying to install watches,
# e.g. in dyn-dns by `systemctl start dyn-dns-watcher.path`.
# see: <https://askubuntu.com/questions/828779/failed-to-add-run-systemd-ask-password-to-directory-watch-no-space-left-on-dev>
boot.kernel.sysctl."fs.inotify.max_user_watches" = 1048576;
}

View File

@@ -1,24 +1,30 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
{ {
imports = [ imports = [
./boot.nix
./feeds.nix ./feeds.nix
./fs.nix ./fs.nix
./hardware
./home ./home
./hosts.nix ./hosts.nix
./ids.nix ./ids.nix
./machine-id.nix ./machine-id.nix
./net ./net
./nix ./nix.nix
./persist.nix ./persist.nix
./polyunfill.nix ./polyunfill.nix
./programs ./programs
./quirks.nix
./secrets.nix ./secrets.nix
./ssh.nix ./ssh.nix
./systemd.nix ./systemd.nix
./users ./users
]; ];
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
# this affects where nixos modules look for stateful data which might have been migrated across releases.
system.stateVersion = "21.11";
sane.nixcache.enable-trusted-keys = true; sane.nixcache.enable-trusted-keys = true;
sane.nixcache.enable = lib.mkDefault true; sane.nixcache.enable = lib.mkDefault true;
sane.persist.enable = lib.mkDefault true; sane.persist.enable = lib.mkDefault true;
@@ -26,9 +32,6 @@
sane.programs.sysadminUtils.enableFor.system = lib.mkDefault true; sane.programs.sysadminUtils.enableFor.system = lib.mkDefault true;
sane.programs.consoleUtils.enableFor.user.colin = lib.mkDefault true; sane.programs.consoleUtils.enableFor.user.colin = lib.mkDefault true;
nixpkgs.config.allowUnfree = true; # NIXPKGS_ALLOW_UNFREE=1
nixpkgs.config.allowBroken = true; # NIXPKGS_ALLOW_BROKEN=1
# time.timeZone = "America/Los_Angeles"; # time.timeZone = "America/Los_Angeles";
time.timeZone = "Etc/UTC"; # DST is too confusing for me => use a stable timezone time.timeZone = "Etc/UTC"; # DST is too confusing for me => use a stable timezone

View File

@@ -86,6 +86,7 @@ let
(fromDb "lexfridman.com/podcast" // rat) (fromDb "lexfridman.com/podcast" // rat)
(fromDb "mapspodcast.libsyn.com" // uncat) # Multidisciplinary Association for Psychedelic Studies (fromDb "mapspodcast.libsyn.com" // uncat) # Multidisciplinary Association for Psychedelic Studies
(fromDb "microarch.club" // tech) (fromDb "microarch.club" // tech)
(fromDb "mintcast.org" // tech)
(fromDb "omegataupodcast.net" // tech) # 3/4 German; 1/4 eps are English (fromDb "omegataupodcast.net" // tech) # 3/4 German; 1/4 eps are English
(fromDb "omny.fm/shows/cool-people-who-did-cool-stuff" // pol) # Maggie Killjoy -- referenced by Cory Doctorow (fromDb "omny.fm/shows/cool-people-who-did-cool-stuff" // pol) # Maggie Killjoy -- referenced by Cory Doctorow
(fromDb "omny.fm/shows/money-stuff-the-podcast") # Matt Levine (fromDb "omny.fm/shows/money-stuff-the-podcast") # Matt Levine
@@ -194,6 +195,7 @@ let
(fromDb "weekinethereumnews.com" // tech) (fromDb "weekinethereumnews.com" // tech)
(fromDb "willow.phantoma.online") # wizard@xyzzy.link (fromDb "willow.phantoma.online") # wizard@xyzzy.link
(fromDb "xn--gckvb8fzb.com" // tech) (fromDb "xn--gckvb8fzb.com" // tech)
(fromDb "xorvoid.com" // tech)
(mkSubstack "astralcodexten" // rat // daily) # Scott Alexander (mkSubstack "astralcodexten" // rat // daily) # Scott Alexander
(mkSubstack "eliqian" // rat // weekly) (mkSubstack "eliqian" // rat // weekly)
(mkSubstack "oversharing" // pol // daily) (mkSubstack "oversharing" // pol // daily)
@@ -237,7 +239,7 @@ let
(fromDb "youtube.com/@TomScottGo") (fromDb "youtube.com/@TomScottGo")
(fromDb "youtube.com/@Vihart") (fromDb "youtube.com/@Vihart")
(fromDb "youtube.com/@Vox") (fromDb "youtube.com/@Vox")
(fromDb "youtube.com/@Vsauce") # (fromDb "youtube.com/@Vsauce") # they're all like 1-minute long videos now? what happened @Vsauce?
# (fromDb "youtube.com/@rossmanngroup" // pol // tech) # Louis Rossmann # (fromDb "youtube.com/@rossmanngroup" // pol // tech) # Louis Rossmann
]; ];

View File

@@ -216,6 +216,7 @@ lib.mkMerge [
programs.fuse.userAllowOther = true; #< necessary for `allow_other` or `allow_root` options. programs.fuse.userAllowOther = true; #< necessary for `allow_other` or `allow_root` options.
} }
(remoteHome "crappy")
(remoteHome "desko") (remoteHome "desko")
(remoteHome "lappy") (remoteHome "lappy")
(remoteHome "moby") (remoteHome "moby")

View File

@@ -1,99 +0,0 @@
{ config, lib, pkgs, ... }:
{
imports = [
./x86_64.nix
];
boot.initrd.supportedFilesystems = [ "ext4" "btrfs" "ext2" "ext3" "vfat" ];
# useful emergency utils
boot.initrd.extraUtilsCommands = ''
copy_bin_and_libs ${pkgs.btrfs-progs}/bin/btrfstune
copy_bin_and_libs ${pkgs.util-linux}/bin/{cfdisk,lsblk,lscpu}
copy_bin_and_libs ${pkgs.gptfdisk}/bin/{cgdisk,gdisk}
copy_bin_and_libs ${pkgs.smartmontools}/bin/smartctl
copy_bin_and_libs ${pkgs.e2fsprogs}/bin/resize2fs
'' + lib.optionalString pkgs.stdenv.hostPlatform.isx86_64 ''
copy_bin_and_libs ${pkgs.nvme-cli}/bin/nvme # doesn't cross compile
'';
boot.kernelParams = [
"boot.shell_on_fail"
#v experimental full pre-emption for hopefully better call/audio latency on moby.
# also toggleable at runtime via /sys/kernel/debug/sched/preempt
# defaults to preempt=voluntary
# "preempt=full"
];
# other kernelParams:
# "boot.trace"
# "systemd.log_level=debug"
# "systemd.log_target=console"
# moby has to run recent kernels (defined elsewhere).
# meanwhile, kernel variation plays some minor role in things like sandboxing (landlock) and capabilities.
# simpler to keep near the latest kernel on all devices,
# and also makes certain that any weird system-level bugs i see aren't likely to be stale kernel bugs.
# servo needs zfs though, which doesn't support every kernel.
boot.kernelPackages = lib.mkDefault pkgs.zfs.latestCompatibleLinuxPackages;
# TODO: remove after linux 6.9. see: <https://github.com/axboe/liburing/issues/1113>
# - <https://github.com/neovim/neovim/issues/28149>
# - <https://git.kernel.dk/cgit/linux/commit/?h=io_uring-6.9&id=e5444baa42e545bb929ba56c497e7f3c73634099>
# when removing, try starting and suspending (ctrl+z) two instances of neovim simultaneously.
# if the system doesn't freeze, then this is safe to remove.
# added 2024-04-04
sane.user.fs.".profile".symlink.text = lib.mkBefore ''
export UV_USE_IO_URING=0
'';
# hack in the `boot.shell_on_fail` arg since that doesn't always seem to work.
boot.initrd.preFailCommands = "allowShell=1";
# default: 4 (warn). 7 is debug
boot.consoleLogLevel = 7;
boot.loader.grub.enable = lib.mkDefault false;
boot.loader.generic-extlinux-compatible.enable = lib.mkDefault true;
# non-free firmware
hardware.enableRedistributableFirmware = true;
# default is 252274, which is too low particularly for servo.
# manifests as spurious "No space left on device" when trying to install watches,
# e.g. in dyn-dns by `systemctl start dyn-dns-watcher.path`.
# see: <https://askubuntu.com/questions/828779/failed-to-add-run-systemd-ask-password-to-directory-watch-no-space-left-on-dev>
boot.kernel.sysctl."fs.inotify.max_user_watches" = 1048576;
# powertop will default to putting USB devices -- including HID -- to sleep after TWO SECONDS
powerManagement.powertop.enable = false;
# linux CPU governor: <https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt>
# - options:
# - "powersave" => force CPU to always run at lowest supported frequency
# - "performance" => force CPU to always run at highest frequency
# - "ondemand" => adjust frequency based on load
# - "conservative" (ondemand but slower to adjust)
# - "schedutil"
# - "userspace"
# - not all options are available for all platforms
# - intel (intel_pstate) appears to manage scaling w/o intervention/control from the OS.
# - AMD (acpi-cpufreq) appears to manage scaling via the OS *or* HW. but the ondemand defaults never put it to max hardware frequency.
# - qualcomm (cpufreq-dt) appears to manage scaling *only* via the OS. ondemand governor exercises the full range.
# - query details with `sudo cpupower frequency-info`
powerManagement.cpuFreqGovernor = "ondemand";
# see: `man logind.conf`
# dont shutdown when power button is short-pressed (commonly done an accident, or by cats).
# but do on long-press: useful to gracefully power-off server.
services.logind.powerKey = "lock";
services.logind.powerKeyLongPress = "poweroff";
services.logind.lidSwitch = "lock";
# services.snapper.configs = {
# root = {
# subvolume = "/";
# extraConfig = {
# ALLOW_USERS = "colin";
# };
# };
# };
# services.snapper.snapshotInterval = "daily";
}

View File

@@ -23,11 +23,5 @@
# see <https://manpages.ubuntu.com/manpages/bionic/man5/user-dirs.conf.5.html> # see <https://manpages.ubuntu.com/manpages/bionic/man5/user-dirs.conf.5.html>
sane.user.fs.".config/user-dirs.conf".symlink.text = "enabled=False"; sane.user.fs.".config/user-dirs.conf".symlink.text = "enabled=False";
sane.user.fs.".profile".symlink.text = '' sane.user.fs.".config/environment.d/30-user-dirs.conf".symlink.target = "../user-dirs.dirs";
# configure XDG_<type>_DIR preferences (e.g. for downloads, screenshots, etc)
# surround with `set -o allexport` since user-dirs.dirs doesn't `export` its vars
set -a
source $HOME/.config/user-dirs.dirs
set +a
'';
} }

View File

@@ -2,6 +2,14 @@
{ {
# TODO: this should be populated per-host # TODO: this should be populated per-host
sane.hosts.by-name."crappy" = {
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMIvSQAGKqmymXIL4La9B00LPxBIqWAr5AsJxk3UQeY5";
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMN0cpRAloCBOE5/2wuzgik35iNDv5KLceWMCVaa7DIQ";
# wg-home.pubkey = "TODO";
# wg-home.ip = "10.0.10.55";
lan-ip = "10.78.79.55";
};
sane.hosts.by-name."desko" = { sane.hosts.by-name."desko" = {
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX"; ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX";
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk"; ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk";

View File

@@ -4,6 +4,9 @@
{ ... }: { ... }:
{ {
# partially supported in nixpkgs <repo:nixos/nixpkgs:nixos/modules/misc/ids.nix>
sane.ids.networkmanager.uid = 57; #< nixpkgs unofficially reserves this, to match networkmanager's gid
# legacy servo users, some are inconvenient to migrate # legacy servo users, some are inconvenient to migrate
sane.ids.dhcpcd.gid = 991; sane.ids.dhcpcd.gid = 991;
sane.ids.dhcpcd.uid = 992; sane.ids.dhcpcd.uid = 992;
@@ -18,7 +21,7 @@
sane.ids.matrix-appservice-irc.uid = 993; sane.ids.matrix-appservice-irc.uid = 993;
sane.ids.matrix-appservice-irc.gid = 992; sane.ids.matrix-appservice-irc.gid = 992;
# greetd (used by sway) # greetd (legacy)
sane.ids.greeter.uid = 999; sane.ids.greeter.uid = 999;
sane.ids.greeter.gid = 999; sane.ids.greeter.gid = 999;
@@ -78,6 +81,7 @@
# found on graphical hosts # found on graphical hosts
sane.ids.nm-iodine.uid = 2101; # desko/moby/lappy sane.ids.nm-iodine.uid = 2101; # desko/moby/lappy
sane.ids.seat.gid = 2102;
# found on desko host # found on desko host
# from services.usbmuxd # from services.usbmuxd

View File

@@ -4,6 +4,8 @@
imports = [ imports = [
./dns.nix ./dns.nix
./hostnames.nix ./hostnames.nix
./modemmanager.nix
./networkmanager.nix
./upnp.nix ./upnp.nix
./vpn.nix ./vpn.nix
]; ];
@@ -24,41 +26,4 @@
# this is required separately by servo and by any `sane-vpn` users, # this is required separately by servo and by any `sane-vpn` users,
# however Nix requires this be set centrally, in only one location (i.e. here) # however Nix requires this be set centrally, in only one location (i.e. here)
boot.kernel.sysctl."net.ipv4.ip_forward" = 1; boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
# the default backend is "wpa_supplicant".
# wpa_supplicant reliably picks weak APs to connect to.
# see: <https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/474>
# iwd is an alternative that shouldn't have this problem
# docs:
# - <https://nixos.wiki/wiki/Iwd>
# - <https://iwd.wiki.kernel.org/networkmanager>
# - `man iwd.config` for global config
# - `man iwd.network` for per-SSID config
# use `iwctl` to control
# networking.networkmanager.wifi.backend = "iwd";
# networking.wireless.iwd.enable = true;
# networking.wireless.iwd.settings = {
# # auto-connect to a stronger network if signal drops below this value
# # bedroom -> bedroom connection is -35 to -40 dBm
# # bedroom -> living room connection is -60 dBm
# General.RoamThreshold = "-52"; # default -70
# General.RoamThreshold5G = "-52"; # default -76
# };
# plugins mostly add support for establishing different VPN connections.
# the default plugin set includes mostly proprietary VPNs:
# - fortisslvpn (Fortinet)
# - iodine (DNS tunnels)
# - l2tp
# - openconnect (Cisco Anyconnect / Juniper / ocserv)
# - openvpn
# - vpnc (Cisco VPN)
# - sstp
#
# i don't use these, and notably they drag in huge dependency sets and don't cross compile well.
# e.g. openconnect drags in webkitgtk (for SSO)!
networking.networkmanager.plugins = lib.mkForce [];
# keyfile.path = where networkmanager should look for connection credentials
networking.networkmanager.settings.keyfile.path = "/var/lib/NetworkManager/system-connections";
} }

View File

@@ -0,0 +1,78 @@
{ config, lib, pkgs, ... }:
{
networking.modemmanager.package = pkgs.modemmanager-split.daemon.overrideAttrs (upstream: {
# patch to allow the dbus endpoints to be owned by networkmanager user
postInstall = (upstream.postInstall or "") + ''
substitute $out/share/dbus-1/system.d/org.freedesktop.ModemManager1.conf \
$out/share/dbus-1/system.d/networkmanager-org.freedesktop.ModemManager1.conf \
--replace-fail 'user="root"' 'group="networkmanager"'
'';
});
systemd.services.ModemManager = {
# aliases = [ "dbus-org.freedesktop.ModemManager1.service" ];
# after = [ "polkit.service" ];
# requires = [ "polkit.service" ];
wantedBy = [ "network.target" ]; #< default is `multi-user.target`, somehow it doesn't auto-start with that...
# path = [ "/run/current-system/sw" ]; #< so it can find `sanebox`
# serviceConfig.Type = "dbus";
# serviceConfig.BusName = "org.freedesktop.ModemManager1";
# only if started with `--debug` does mmcli let us issue AT commands like
# `mmcli --modem any --command=<AT_CMD>`
serviceConfig.ExecStart = [
"" # first blank line is to clear the upstream `ExecStart` field.
"${lib.getExe' config.networking.modemmanager.package "ModemManager"} --debug"
];
# --debug sets DEBUG level logging: so reset
serviceConfig.ExecStartPost = "${lib.getExe config.sane.programs.mmcli.package} --set-logging=INFO";
# v this is what upstream ships
# serviceConfig.Restart = "on-abort";
# serviceConfig.StandardError = "null";
# serviceConfig.CapabilityBoundingSet = "CAP_SYS_ADMIN CAP_NET_ADMIN";
# serviceConfig.ProtectSystem = true; # makes empty: /boot, /usr
# serviceConfig.ProtectHome = true; # makes empty: /home, /root, /run/user
# serviceConfig.PrivateTmp = true;
# serviceConfig.RestrictAddressFamilies = "AF_NETLINK AF_UNIX AF_QIPCRTR";
# serviceConfig.NoNewPrivileges = true;
serviceConfig.CapabilityBoundingSet = [ "CAP_NET_ADMIN" ]; #< TODO: make sure this is *really* taking effect, and isn't supplemental to upstream's `CAP_SYS_ADMIN` setting
serviceConfig.LockPersonality = true;
# serviceConfig.PrivateUsers = true; #< untried, not likely to work since it needs capabilities
serviceConfig.PrivateTmp = true;
serviceConfig.ProtectClock = true; # syscall filter to prevent changing the RTC
serviceConfig.ProtectControlGroups = true;
serviceConfig.ProtectHome = true; # makes empty: /home, /root, /run/user
serviceConfig.ProtectHostname = true; # prevents changing hostname
serviceConfig.ProtectKernelLogs = true; # disable /proc/kmsg, /dev/kmsg
serviceConfig.ProtectKernelModules = true; # syscall filter to prevent module calls
serviceConfig.ProtectKernelTunables = true;
serviceConfig.ProtectSystem = "strict"; # makes read-only all but /dev, /proc, /sys
serviceConfig.RestrictAddressFamilies = [
"AF_NETLINK"
"AF_QIPCRTR"
"AF_UNIX"
];
serviceConfig.RestrictSUIDSGID = true;
serviceConfig.SystemCallArchitectures = "native"; # prevents e.g. aarch64 syscalls in the event that the kernel is multi-architecture.
# from earlier `landlock` sandboxing, i know it needs these directories:
# - # "/"
# - "/dev" #v modem-power + net are not enough
# - # "/dev/modem-power"
# - # "/dev/net"
# - "/proc"
# - # /run #v can likely be reduced more
# - "/run/dbus"
# - "/run/NetworkManager"
# - "/run/resolvconf"
# - "/run/systemd"
# - "/run/udev"
# - "/sys"
};
# so that ModemManager can discover when the modem appears
# services.udev.packages = lib.mkIf cfg.enabled [ cfg.package ];
}

View File

@@ -0,0 +1,268 @@
{ config, pkgs, ... }:
let
# networkmanager = pkgs.networkmanager;
networkmanager = pkgs.networkmanager.overrideAttrs (upstream: {
src = pkgs.fetchFromGitea {
domain = "git.uninsane.org";
owner = "colin";
repo = "NetworkManager";
# patched to fix polkit permissions (with `nmcli`) when NetworkManager runs as user networkmanager
rev = "dev-sane-1.48.0";
hash = "sha256-vGmOKtwVItxjYioZJlb1og3K6u9s4rcmDnjAPLBC3ao=";
};
# patches = [];
});
# split the package into `daemon` and `nmcli` outputs, because the networkmanager *service*
# doesn't need `nmcli`/`nmtui` tooling
networkmanager-split = pkgs.networkmanager-split.override { inherit networkmanager; };
in {
networking.networkmanager.enable = true;
# plugins mostly add support for establishing different VPN connections.
# the default plugin set includes mostly proprietary VPNs:
# - fortisslvpn (Fortinet)
# - iodine (DNS tunnels)
# - l2tp
# - openconnect (Cisco Anyconnect / Juniper / ocserv)
# - openvpn
# - vpnc (Cisco VPN)
# - sstp
#
# i don't use these, and notably they drag in huge dependency sets and don't cross compile well.
# e.g. openconnect drags in webkitgtk (for SSO)!
# networking.networkmanager.plugins = lib.mkForce [];
networking.networkmanager.enableDefaultPlugins = false;
networking.networkmanager.package = networkmanager-split.daemon.overrideAttrs (upstream: {
# postPatch = (upstream.postPatch or "") + ''
# substituteInPlace src/{core/org.freedesktop.NetworkManager,nm-dispatcher/nm-dispatcher}.conf --replace-fail \
# 'user="root"' 'user="networkmanager"'
# '';
postInstall = (upstream.postInstall or "") + ''
# allow the bus to owned by either root or networkmanager users
# use the group here, that way ordinary users can be elevated to control networkmanager
# (via e.g. `nmcli`)
for f in org.freedesktop.NetworkManager.conf nm-dispatcher.conf ; do
substitute $out/share/dbus-1/system.d/$f \
$out/share/dbus-1/system.d/networkmanager-$f \
--replace-fail 'user="root"' 'group="networkmanager"'
done
# remove unused services to prevent any unexpected interactions
rm $out/etc/systemd/system/{nm-cloud-setup.service,nm-cloud-setup.timer,nm-priv-helper.service}
'';
});
# fixup the services to run as `networkmanager` and with less permissions
systemd.services.NetworkManager = {
serviceConfig.RuntimeDirectory = "NetworkManager"; #< tells systemd to create /run/NetworkManager
# serviceConfig.StateDirectory = "NetworkManager"; #< tells systemd to create /var/lib/NetworkManager
serviceConfig.User = "networkmanager";
serviceConfig.Group = "networkmanager";
serviceConfig.AmbientCapabilities = [
# "CAP_DAC_OVERRIDE"
"CAP_NET_ADMIN"
"CAP_NET_RAW" #< required, else `libndp: ndp_sock_open: Failed to create ICMP6 socket.`
"CAP_NET_BIND_SERVICE" #< this *does* seem to be necessary, though i don't understand why. DHCP?
# "CAP_SYS_MODULE"
# "CAP_AUDIT_WRITE" #< allow writing to the audit log (optional)
# "CAP_KILL"
];
serviceConfig.LockPersonality = true;
serviceConfig.NoNewPrivileges = true;
serviceConfig.PrivateDevices = true; # remount /dev with just the basics, syscall filter to block @raw-io
serviceConfig.PrivateIPC = true;
serviceConfig.PrivateTmp = true;
# serviceConfig.PrivateUsers = true; #< BREAKS NetworkManager (presumably, it causes a new user namespace, breaking CAP_NET_ADMIN & others). "platform-linux: do-change-link[3]: failure 1 (Operation not permitted)"
serviceConfig.ProtectClock = true; # syscall filter to prevent changing the RTC
serviceConfig.ProtectControlGroups = true;
serviceConfig.ProtectHome = true; # makes empty: /home, /root, /run/user
serviceConfig.ProtectHostname = true; # probably not upstreamable: prevents changing hostname
serviceConfig.ProtectKernelLogs = true; # disable /proc/kmsg, /dev/kmsg
serviceConfig.ProtectKernelModules = true; # syscall filter to prevent module calls (probably not upstreamable: NM will want to load modules like `ppp`)
serviceConfig.ProtectKernelTunables = true; # but NM might need to write /proc/sys/net/...
serviceConfig.ProtectSystem = "strict"; # makes read-only: all but /dev, /proc, /sys.
serviceConfig.RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_NETLINK" # breaks near DHCP without this
"AF_PACKET" # for DHCP
"AF_UNIX"
# AF_ALG ?
# AF_BLUETOOTH ?
# AF_BRIDGE ?
];
serviceConfig.RestrictSUIDSGID = true;
serviceConfig.SystemCallArchitectures = "native"; # prevents e.g. aarch64 syscalls in the event that the kernel is multi-architecture.
# from earlier `landlock` sandboxing, i know it needs these directories:
# - "/proc/net"
# - "/proc/sys/net"
# - "/run/NetworkManager"
# - "/run/systemd" # for trust-dns-nmhook
# - "/run/udev"
# - # "/run/wg-home.priv"
# - "/sys/class"
# - "/sys/devices"
# - "/var/lib/NetworkManager"
# - "/var/lib/trust-dns" #< for trust-dns-nmhook
# - "/run/systemd"
};
systemd.services.NetworkManager-wait-online = {
serviceConfig.User = "networkmanager";
serviceConfig.Group = "networkmanager";
};
# fix NetworkManager-dispatcher to actually run as a daemon,
# and sandbox it a bit
systemd.services.NetworkManager-dispatcher = {
after = [ "trust-dns-localhost.service" ]; #< so that /var/lib/trust-dns will exist
# serviceConfig.ExecStart = [
# "" # first blank line is to clear the upstream `ExecStart` field.
# "${cfg.package}/libexec/nm-dispatcher --persist" # --persist is needed for it to actually run as a daemon
# ];
# serviceConfig.Restart = "always";
# serviceConfig.RestartSec = "1s";
# serviceConfig.DynamicUser = true; #< not possible, else we lose group perms (so can't write to `trust-dns`'s files in the nm hook)
serviceConfig.User = "networkmanager"; # TODO: should arguably use `DynamicUser`
serviceConfig.Group = "networkmanager";
serviceConfig.LockPersonality = true;
serviceConfig.NoNewPrivileges = true;
serviceConfig.PrivateDevices = true; # remount /dev with just the basics, syscall filter to block @raw-io
serviceConfig.PrivateIPC = true;
serviceConfig.PrivateTmp = true;
serviceConfig.PrivateUsers = true;
serviceConfig.ProtectClock = true; # syscall filter to prevent changing the RTC
serviceConfig.ProtectControlGroups = true;
serviceConfig.ProtectHome = true; # makes empty: /home, /root, /run/user
serviceConfig.ProtectHostname = true; # probably not upstreamable: prevents changing hostname
serviceConfig.ProtectKernelLogs = true; # disable /proc/kmsg, /dev/kmsg
serviceConfig.ProtectKernelModules = true; # syscall filter to prevent module calls
serviceConfig.ProtectKernelTunables = true;
serviceConfig.ProtectSystem = "full"; # makes read-only: /boot, /etc/, /usr. `strict` isn't possible due to trust-dns hook
serviceConfig.RestrictAddressFamilies = [
"AF_UNIX" # required, probably for dbus or systemd connectivity
];
serviceConfig.RestrictSUIDSGID = true;
serviceConfig.SystemCallArchitectures = "native"; # prevents e.g. aarch64 syscalls in the event that the kernel is multi-architecture.
};
# harden wpa_supplicant (used by NetworkManager)
systemd.services.wpa_supplicant = {
serviceConfig.User = "networkmanager";
serviceConfig.Group = "networkmanager";
serviceConfig.AmbientCapabilities = [
"CAP_NET_ADMIN"
"CAP_NET_RAW"
];
serviceConfig.LockPersonality = true;
serviceConfig.NoNewPrivileges = true;
# serviceConfig.PrivateDevices = true; # untried, not likely to work. remount /dev with just the basics, syscall filter to block @raw-io
serviceConfig.PrivateIPC = true;
serviceConfig.PrivateTmp = true;
# serviceConfig.PrivateUsers = true; #< untried, not likely to work
serviceConfig.ProtectClock = true; # syscall filter to prevent changing the RTC
serviceConfig.ProtectControlGroups = true;
serviceConfig.ProtectHome = true; # makes empty: /home, /root, /run/user
serviceConfig.ProtectHostname = true; # prevents changing hostname
serviceConfig.ProtectKernelLogs = true; # disable /proc/kmsg, /dev/kmsg
serviceConfig.ProtectKernelModules = true; # syscall filter to prevent module calls
serviceConfig.ProtectKernelTunables = true; #< N.B.: i think this makes certain /proc writes fail
serviceConfig.ProtectSystem = "strict"; # makes read-only: all but /dev, /proc, /sys.
serviceConfig.RestrictAddressFamilies = [
"AF_INET" #< required
"AF_INET6"
"AF_NETLINK" #< required
"AF_PACKET" #< required
"AF_UNIX" #< required (wpa_supplicant wants to use dbus)
];
serviceConfig.RestrictSUIDSGID = true;
serviceConfig.SystemCallArchitectures = "native"; # prevents e.g. aarch64 syscalls in the event that the kernel is multi-architecture.
# from earlier `landlock` sandboxing, i know it needs only these paths:
# - "/dev/net"
# - "/dev/rfkill"
# - "/proc/sys/net"
# - "/sys/class/net"
# - "/sys/devices"
# - "/run/systemd"
};
networking.networkmanager.settings = {
# keyfile.path = where networkmanager should look for connection credentials
keyfile.path = "/var/lib/NetworkManager/system-connections";
# wifi.backend = "wpa_supplicant"; #< default
# wifi.scan-rand-mac-address = true; #< default
# logging.audit = false; #< default
logging.level = "INFO";
# main.dhcp = "internal"; #< default
main.dns = if config.services.resolved.enable then
"systemd-resolved"
else if config.sane.services.trust-dns.enable && config.sane.services.trust-dns.asSystemResolver then
"none"
else
"internal"
;
main.systemd-resolved = false;
};
environment.etc."NetworkManager/system-connections".source = "/var/lib/NetworkManager/system-connections";
# the default backend is "wpa_supplicant".
# wpa_supplicant reliably picks weak APs to connect to.
# see: <https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/474>
# iwd is an alternative that shouldn't have this problem
# docs:
# - <https://nixos.wiki/wiki/Iwd>
# - <https://iwd.wiki.kernel.org/networkmanager>
# - `man iwd.config` for global config
# - `man iwd.network` for per-SSID config
# use `iwctl` to control
# networking.networkmanager.wifi.backend = "iwd";
# networking.wireless.iwd.enable = true;
# networking.wireless.iwd.settings = {
# # auto-connect to a stronger network if signal drops below this value
# # bedroom -> bedroom connection is -35 to -40 dBm
# # bedroom -> living room connection is -60 dBm
# General.RoamThreshold = "-52"; # default -70
# General.RoamThreshold5G = "-52"; # default -76
# };
# allow networkmanager to control systemd-resolved,
# which it needs to do to apply new DNS settings when using systemd-resolved.
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {
if (subject.isInGroup("networkmanager") && action.id.indexOf("org.freedesktop.resolve1.") == 0) {
return polkit.Result.YES;
}
});
'';
users.users.networkmanager = {
isSystemUser = true;
group = "networkmanager";
extraGroups = [ "trust-dns" ];
};
# there is, unfortunately, no proper interface by which to plumb wpa_supplicant into the NixOS service, except by overlay.
nixpkgs.overlays = [(self: super: {
wpa_supplicant = super.wpa_supplicant.overrideAttrs (upstream: {
# postPatch = (upstream.postPatch or "") + ''
# substituteInPlace wpa_supplicant/dbus/dbus-wpa_supplicant.conf --replace-fail \
# 'user="root"' 'user="networkmanager"'
# '';
postInstall = (upstream.postInstall or "") + ''
substitute $out/share/dbus-1/system.d/dbus-wpa_supplicant.conf \
$out/share/dbus-1/system.d/networkmanager-wpa_supplicant.conf \
--replace-fail 'user="root"' 'group="networkmanager"'
'';
postFixup = (upstream.postFixup or "") + ''
# remove unused services to avoid unexpected interactions
rm $out/etc/systemd/system/{wpa_supplicant-nl80211@,wpa_supplicant-wired@,wpa_supplicant@}.service
'';
});
})];
}

View File

@@ -7,50 +7,62 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
def-ovpn = name: { endpoint, publicKey, addrV4, id }: { # N.B.: OVPN issues each key (i.e. device) a different IP (addrV4), and requires you use it.
sane.vpn."ovpnd-${name}" = { # the IP it issues can be used to connect to any of their VPNs.
inherit endpoint publicKey addrV4 id; # effectively the IP and key map 1-to-1.
privateKeyFile = config.sops.secrets."wg/ovpnd_${name}_privkey".path; # it seems to still be possible to keep two active tunnels on one device, using the same key/IP address, though.
def-ovpn = name: { endpoint, publicKey, id }: let
inherit (config.sane.ovpn) addrV4;
in {
sane.vpn."ovpnd-${name}" = lib.mkIf (addrV4 != null) {
inherit addrV4 endpoint publicKey id;
privateKeyFile = config.sops.secrets."ovpn_privkey".path;
dns = [ dns = [
"46.227.67.134" "46.227.67.134"
"192.165.9.158" "192.165.9.158"
# "2a07:a880:4601:10f0:cd45::1"
# "2001:67c:750:1:cafe:cd45::1"
]; ];
}; };
sops.secrets."wg/ovpnd_${name}_privkey" = { sops.secrets."ovpn_privkey" = lib.mkIf (addrV4 != null) {
# needs to be readable by systemd-network or else it says "Ignoring network device" and doesn't expose it to networkctl. # needs to be readable by systemd-network or else it says "Ignoring network device" and doesn't expose it to networkctl.
owner = "systemd-network"; owner = "systemd-network";
}; };
}; };
in lib.mkMerge [ in {
options = with lib; {
sane.ovpn.addrV4 = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
ovpn issues one IP address per device.
set `null` to disable OVPN for this host.
'';
};
};
config = lib.mkMerge [
(def-ovpn "us" { (def-ovpn "us" {
endpoint = "vpn31.prd.losangeles.ovpn.com:9929"; endpoint = "vpn31.prd.losangeles.ovpn.com:9929";
publicKey = "VW6bEWMOlOneta1bf6YFE25N/oMGh1E1UFBCfyggd0k="; publicKey = "VW6bEWMOlOneta1bf6YFE25N/oMGh1E1UFBCfyggd0k=";
id = 1; id = 1;
addrV4 = "172.27.237.218";
# addrV6 = "fd00:0000:1337:cafe:1111:1111:ab00:4c8f";
}) })
# TODO: us-atl disabled until i can give it a different link-local address and wireguard key than us-mi
# (def-ovpn "us-atl" {
# endpoint = "vpn18.prd.atlanta.ovpn.com:9929";
# publicKey = "Dpg/4v5s9u0YbrXukfrMpkA+XQqKIFpf8ZFgyw0IkE0=";
# address = [
# "172.21.182.178/32"
# "fd00:0000:1337:cafe:1111:1111:cfcb:27e3/128"
# ];
# })
(def-ovpn "us-mi" { (def-ovpn "us-mi" {
endpoint = "vpn34.prd.miami.ovpn.com:9929"; endpoint = "vpn34.prd.miami.ovpn.com:9929";
publicKey = "VtJz2irbu8mdkIQvzlsYhU+k9d55or9mx4A2a14t0V0="; publicKey = "VtJz2irbu8mdkIQvzlsYhU+k9d55or9mx4A2a14t0V0=";
id = 2; id = 2;
addrV4 = "172.21.182.178";
# addrV6 = "fd00:0000:1337:cafe:1111:1111:cfcb:27e3";
}) })
(def-ovpn "ukr" { (def-ovpn "ukr" {
endpoint = "vpn96.prd.kyiv.ovpn.com:9929"; endpoint = "vpn96.prd.kyiv.ovpn.com:9929";
publicKey = "CjZcXDxaaKpW8b5As1EcNbI6+42A6BjWahwXDCwfVFg="; publicKey = "CjZcXDxaaKpW8b5As1EcNbI6+42A6BjWahwXDCwfVFg=";
id = 3; id = 3;
addrV4 = "172.18.180.159";
# addrV6 = "fd00:0000:1337:cafe:1111:1111:ec5c:add3";
}) })
] # TODO: us-atl disabled until i need it again, i guess.
# (def-ovpn "us-atl" {
# endpoint = "vpn18.prd.atlanta.ovpn.com:9929";
# publicKey = "Dpg/4v5s9u0YbrXukfrMpkA+XQqKIFpf8ZFgyw0IkE0=";
# id = 4;
# })
];
}

View File

@@ -59,14 +59,18 @@
# note the import starts at repo root: this allows `./overlay/default.nix` to access the stuff at the root # note the import starts at repo root: this allows `./overlay/default.nix` to access the stuff at the root
# "nixpkgs-overlays=${../../..}/hosts/common/nix-path/overlay" # "nixpkgs-overlays=${../../..}/hosts/common/nix-path/overlay"
# as long as my system itself doesn't rely on NIXPKGS at runtime, we can point the overlays to git # as long as my system itself doesn't rely on NIXPKGS at runtime, we can point the overlays to git
# to avoid switching so much during development # to avoid `switch`ing so much during development.
"nixpkgs-overlays=/home/colin/dev/nixos/hosts/common/nix/overlay" # TODO: it would be nice to remove this someday!
# it's an impurity that touches way more than i need and tends to cause hard-to-debug eval issues
# when it goes wrong. should i port my `nix-shell` scripts to something more tailored to my uses
# and then delete `nixpkgs-overlays`?
"nixpkgs-overlays=/home/colin/dev/nixos/integrations/nixpkgs/nixpkgs-overlays.nix"
]; ];
# ensure new deployments have a source of this repo with which they can bootstrap. # ensure new deployments have a source of this repo with which they can bootstrap.
# this however changes on every commit and can be slow to copy for e.g. `moby`. # this however changes on every commit and can be slow to copy for e.g. `moby`.
environment.etc."nixos" = lib.mkIf (config.sane.maxBuildCost >= 3) { environment.etc."nixos" = lib.mkIf (config.sane.maxBuildCost >= 3) {
source = ../../..; source = pkgs.sane-nix-files;
}; };
environment.etc."nix/registry.json" = lib.mkIf (config.sane.maxBuildCost < 3) { environment.etc."nix/registry.json" = lib.mkIf (config.sane.maxBuildCost < 3) {
enable = false; enable = false;

View File

@@ -1,4 +0,0 @@
# XXX: NIX_PATH=...:nixpkgs-overlays=... will import every overlay in the directory
# so we prefer to give it a directory with just this *one* overlay, otherwise it imports conflicting overlays
# and gets stuck in a loop until it OOMs
import ../../../../overlays/all.nix

View File

@@ -1,7 +1,127 @@
# strictly *decrease* the scope of the default nixos installation/config # strictly *decrease* the scope of the default nixos installation/config
{ lib, ... }: { lib, pkgs, ... }:
let
suidlessPam = pkgs.pam.overrideAttrs (upstream: {
# nixpkgs' pam hardcodes unix_chkpwd path to the /run/wrappers one,
# but i don't want the wrapper, so undo that.
# ideally i would patch this via an overlay, but pam is in the bootstrap so that forces a full rebuild.
# TODO: add a `package` option to the nixos' pam module and substitute it that way.
postPatch = (if upstream.postPatch != null then upstream.postPatch else "") + ''
substituteInPlace modules/pam_unix/Makefile.am --replace-fail \
"/run/wrappers/bin/unix_chkpwd" "$out/bin/unix_chkpwd"
'';
});
in
{ {
# remove a few items from /run/wrappers we don't need.
options.security.wrappers = lib.mkOption {
apply = lib.filterAttrs (name: _: !(builtins.elem name [
# from <repo:nixos/nixpkgs:nixos/modules/security/polkit.nix>
"pkexec"
"polkit-agent-helper-1" #< used by systemd; without this you'll have to `sudo systemctl daemon-reload` instead of unauth'd `systemctl daemon-reload`
# from <repo:nixos/nixpkgs:nixos/modules/services/system/dbus.nix>
"dbus-daemon-launch-helper"
# from <repo:nixos/nixpkgs:nixos/modules/security/wrappers/default.nix>
"fusermount" #< only needed if you want to mount entries declared in /etc/fstab or mtab as unprivileged user
"fusermount3"
"mount" #< only needed if you want to mount entries declared in /etc/fstab or mtab as unprivileged user
"umount"
# from <repo:nixos/nixpkgs:nixos/modules/programs/shadow.nix>
"newgidmap"
"newgrp"
"newuidmap"
"sg"
"su"
# from: <repo:nixos/nixpkgs:nixos/modules/security/pam.nix>
# requires associated `pam` patch to not hardcode unix_chkpwd path
"unix_chkpwd"
]));
};
options.security.pam.services = lib.mkOption {
apply = services: let
filtered = lib.filterAttrs (name: _: !(builtins.elem name [
# from <repo:nixos/nixpkgs:nixos/modules/security/pam.nix>
"i3lock"
"i3lock-color"
"vlock"
"xlock"
"xscreensaver"
"runuser"
"runuser-l"
# from ??
"chfn"
"chpasswd"
"chsh"
"groupadd"
"groupdel"
"groupmems"
"groupmod"
"useradd"
"userdel"
"usermod"
# from <repo:nixos/nixpkgs:nixos/modules/system/boot/systemd/user.nix>
"systemd-user" #< N.B.: this causes the `systemd --user` service manager to not be started!
])) services;
in lib.mapAttrs (_serviceName: service: service // {
# replace references with the old pam_unix, which calls into /run/wrappers/bin/unix_chkpwd,
# with a pam_unix that calls into unix_chkpwd via the nix store.
# TODO: use `security.pam.package` instead once <https://github.com/NixOS/nixpkgs/pull/314791> lands.
text = lib.replaceStrings [" pam_unix.so" ] [ " ${suidlessPam}/lib/security/pam_unix.so" ] service.text;
}) filtered;
};
options.environment.systemPackages = lib.mkOption {
# see: <repo:nixos/nixpkgs:nixos/modules/config/system-path.nix>
# it's 31 "requiredPackages", with no explanation of why they're "required"...
# most of these can be safely removed without breaking the *boot*,
# but some core system services DO implicitly depend on them.
# TODO: see which more of these i can remove (or shadow/sandbox)
apply = let
requiredPackages = builtins.map (pkg: lib.setPrio ((pkg.meta.priority or 5) + 3) pkg) [
# pkgs.acl
# pkgs.attr
# pkgs.bashInteractive
# pkgs.bzip2
# pkgs.coreutils-full
# pkgs.cpio
# pkgs.curl
# pkgs.diffutils
# pkgs.findutils
# pkgs.gawk
# pkgs.stdenv.cc.libc
# pkgs.getent
# pkgs.getconf
# pkgs.gnugrep
# pkgs.gnupatch
# pkgs.gnused
# pkgs.gnutar
# pkgs.gzip
# pkgs.xz
pkgs.less
# pkgs.libcap #< implicitly required by NetworkManager/wpa_supplicant!
# pkgs.ncurses
pkgs.netcat
# config.programs.ssh.package
# pkgs.mkpasswd
pkgs.procps
# pkgs.su
# pkgs.time
# pkgs.util-linux
# pkgs.which
# pkgs.zstd
];
in lib.filter (p: ! builtins.elem p requiredPackages);
};
options.system.fsPackages = lib.mkOption {
# <repo:nixos/nixpkgs:nixos/modules/tasks/filesystems/vfat.nix> adds `mtools` and `dosfstools`
# dosfstools actually makes its way into the initrd (`fsck.vfat`).
# mtools is like "MS-DOS for Linux", ancient functionality i'll never use.
apply = lib.filter (p: p != pkgs.mtools);
};
config = {
# disable non-required packages like nano, perl, rsync, strace # disable non-required packages like nano, perl, rsync, strace
environment.defaultPackages = []; environment.defaultPackages = [];
@@ -74,6 +194,10 @@
# it was enabled by default before 23.11 # it was enabled by default before 23.11
boot.swraid.enable = lib.mkDefault false; boot.swraid.enable = lib.mkDefault false;
# see: <nixos/modules/tasks/bcache.nix>
# these allow you to use the Linux block cache (cool! doesn't need to be a default though)
boot.bcache.enable = lib.mkDefault false;
# see: <nixos/modules/system/boot/kernel.nix> # see: <nixos/modules/system/boot/kernel.nix>
# by default, it adds to boot.initrd.availableKernelModules: # by default, it adds to boot.initrd.availableKernelModules:
# - SATA: "ahci" "sata_nv" "sata_via" "sata_sis" "sata_uli" "ata_piix" "pata_marvell" # - SATA: "ahci" "sata_nv" "sata_via" "sata_sis" "sata_uli" "ata_piix" "pata_marvell"
@@ -85,4 +209,8 @@
# - on x86 only: more keyboard stuff: "pcips2" "atkbd" "i8042" # - on x86 only: more keyboard stuff: "pcips2" "atkbd" "i8042"
boot.initrd.includeDefaultModules = lib.mkDefault false; boot.initrd.includeDefaultModules = lib.mkDefault false;
# see: <repo:nixos/nixpkgs:nixos/modules/virtualisation/nixos-containers.nix>
boot.enableContainers = lib.mkDefault false;
};
} }

View File

@@ -15,39 +15,33 @@ in
}; };
# upstream alsa ships with PinePhone audio configs, but they don't actually produce sound. # upstream alsa ships with PinePhone audio configs, but they don't actually produce sound.
# see: <https://github.com/alsa-project/alsa-ucm-conf/pull/134> # - still true as of 2024-05-26
# these audio files come from some revision of: # - see: <https://github.com/alsa-project/alsa-ucm-conf/pull/134>
# - <https://gitlab.manjaro.org/manjaro-arm/packages/community/phosh/alsa-ucm-pinephone>
# #
# alternative to patching is to plumb `ALSA_CONFIG_UCM2 = "${./ucm2}"` environment variable into the relevant places # we can substitute working UCM conf in two ways:
# e.g. `systemd.services.pulseaudio.environment`. # 1. nixpkgs' override for the `alsa-ucm-conf` package
# that leaves more opportunity for gaps (i.e. missing a service), # - that forces a rebuild of ~500 packages (including webkitgtk).
# on the other hand this method causes about 500 packages to be rebuilt (including qt5 and webkitgtk). # 2. set ALSA_CONFIG_UCM2 = /path/to/ucm2 in the relevant places
# - e.g. pulsewire service.
# - easy to miss places, though.
# #
# note that with these files, the following audio device support: # alsa-ucm-pinephone-manjaro (2024-05-26):
# - headphones work. # - headphones work
# - "internal earpiece" works. # - "internal earpiece" works
# - "internal speaker" doesn't work (but that's probably because i broke the ribbon cable) # - "internal speaker" is silent (maybe hardware issue)
# - "analog output" doesn't work. # - 3.5mm connection is flapping when playing to my car, which eventually breaks audio and requires restarting wireplumber
packageUnwrapped = pkgs.alsa-ucm-conf.overrideAttrs (upstream: { # packageUnwrapped = pkgs.alsa-ucm-pinephone-manjaro.override {
postPatch = (upstream.postPatch or "") + '' # inherit (cfg.config) preferEarpiece;
cp ${./ucm2/PinePhone}/* ucm2/Allwinner/A64/PinePhone/ # };
# alsa-ucm-pinephone-pmos (2024-05-26):
# - headphones work
# - "internal earpiece" works
# - "internal speaker" is silent (maybe hardware issue)
packageUnwrapped = pkgs.alsa-ucm-pinephone-pmos.override {
inherit (cfg.config) preferEarpiece;
};
# fix the self-contained ucm files i source from to have correct path within the alsa-ucm-conf source tree sandbox.enable = false; #< only provides $out/share/alsa
substituteInPlace ucm2/Allwinner/A64/PinePhone/PinePhone.conf \
--replace-fail 'HiFi.conf' '/Allwinner/A64/PinePhone/HiFi.conf'
substituteInPlace ucm2/Allwinner/A64/PinePhone/PinePhone.conf \
--replace-fail 'VoiceCall.conf' '/Allwinner/A64/PinePhone/VoiceCall.conf'
'' + lib.optionalString cfg.config.preferEarpiece ''
# decrease the priority of the internal speaker so that sounds are routed
# to the earpiece by default.
# this is just personal preference.
substituteInPlace ucm2/Allwinner/A64/PinePhone/{HiFi.conf,VoiceCall.conf} \
--replace-fail 'PlaybackPriority 300' 'PlaybackPriority 100'
'';
});
sandbox.enable = false; #< only provides #out/share/alsa
# alsa-lib package only looks in its $out/share/alsa to find runtime config data, by default. # alsa-lib package only looks in its $out/share/alsa to find runtime config data, by default.
# but ALSA_CONFIG_UCM2 is an env var that can override that. # but ALSA_CONFIG_UCM2 is an env var that can override that.

View File

@@ -34,6 +34,7 @@ in
]; ];
sysadminUtils = declPackageSet [ sysadminUtils = declPackageSet [
"ausyscall"
"bridge-utils" # for brctl; debug linux "bridge" inet devices "bridge-utils" # for brctl; debug linux "bridge" inet devices
"btrfs-progs" "btrfs-progs"
"cacert.unbundled" # some services require unbundled /etc/ssl/certs "cacert.unbundled" # some services require unbundled /etc/ssl/certs
@@ -43,11 +44,13 @@ in
"dtc" # device tree [de]compiler "dtc" # device tree [de]compiler
"e2fsprogs" # resize2fs "e2fsprogs" # resize2fs
"efibootmgr" "efibootmgr"
"errno"
"ethtool" "ethtool"
"fatresize" "fatresize"
"fd" "fd"
"file" "file"
"forkstat" # monitor every spawned/forked process "forkstat" # monitor every spawned/forked process
"free"
# "fwupd" # "fwupd"
"gawk" "gawk"
"gdb" # to debug segfaults "gdb" # to debug segfaults
@@ -69,17 +72,20 @@ in
"man-pages" "man-pages"
"man-pages-posix" "man-pages-posix"
# "miniupnpc" # "miniupnpc"
"mmcli"
"nano" "nano"
# "ncdu" # ncurses disk usage. doesn't cross compile (zig) # "ncdu" # ncurses disk usage. doesn't cross compile (zig)
"neovim" "neovim"
"netcat" "netcat"
"nethogs" "nethogs"
"nmap" "nmap"
"nmcli"
"nvme-cli" # nvme "nvme-cli" # nvme
# "openssl" # "openssl"
"parted" "parted"
"pciutils" "pciutils"
"powertop" "powertop"
"ps"
"pstree" "pstree"
"ripgrep" "ripgrep"
"s6-rc" # service manager "s6-rc" # service manager
@@ -93,6 +99,7 @@ in
"usbutils" # lsusb "usbutils" # lsusb
"util-linux" # lsblk, lscpu, etc "util-linux" # lsblk, lscpu, etc
"valgrind" "valgrind"
"watch"
"wget" "wget"
"wirelesstools" # iwlist "wirelesstools" # iwlist
# "xq" # jq for XML # "xq" # jq for XML
@@ -165,7 +172,6 @@ in
]; ];
pcConsoleUtils = declPackageSet [ pcConsoleUtils = declPackageSet [
"errno" # 2024/05/18: doesn't cross compile (perl File-ShareDir / Module-Build-Tiny)
# "gh" # MS GitHub cli # "gh" # MS GitHub cli
"nix-index" "nix-index"
"nixpkgs-review" "nixpkgs-review"
@@ -210,6 +216,176 @@ in
# "tree-sitter" # "tree-sitter"
]; ];
gameApps = declPackageSet [
"animatch"
"gnome-2048"
"gnome.hitori" # like sudoku
];
pcGameApps = declPackageSet [
# "andyetitmoves" # TODO: fix build!
# "armagetronad" # tron/lightcycles; WAN and LAN multiplayer
"celeste64"
# "cutemaze" # meh: trivial maze game; qt6 and keyboard-only
# "cuyo" # trivial puyo-puyo clone
"endless-sky" # space merchantilism/exploration
# "factorio"
"frozen-bubble" # WAN + LAN + 1P/2P bubble bobble
"hase" # WAN worms game
# "hedgewars" # WAN + LAN worms game (5~10 people online at any moment; <https://hedgewars.org>)
# "libremines" # meh: trivial minesweeper; qt6
# "mario0" # SMB + portal
# "mindustry"
# "minesweep-rs" # CLI minesweeper
# "nethack"
# "osu-lazer"
# "pinball" # 3d pinball; kb/mouse. old sourceforge project
# "powermanga" # STYLISH space invaders derivative (keyboard-only)
"shattered-pixel-dungeon" # doesn't cross compile
"space-cadet-pinball" # LMB/RMB controls (bindable though. volume buttons?)
"steam"
"superTux" # keyboard-only controls
"superTuxKart" # poor FPS on pinephone
"tumiki-fighters" # keyboard-only
"vvvvvv" # keyboard-only controls
# "wine"
];
guiApps = declPackageSet [
# package sets
"gameApps"
"guiBaseApps"
];
guiBaseApps = declPackageSet [
# "abaddon" # discord client
"alacritty" # terminal emulator
"calls" # gnome calls (dialer/handler)
"dbus"
"dconf" # required by many packages, but not well-documented :(
# "delfin" # Jellyfin client
"dialect" # language translation
"dino" # XMPP client
"dissent" # Discord client (formerly known as: gtkcord4)
# "emote"
# "evince" # PDF viewer
# "flare-signal" # gtk4 signal client
# "foliate" # e-book reader
"fractal" # matrix client
"g4music" # local music player
# "gnome.cheese"
# "gnome-feeds" # RSS reader (with claimed mobile support)
# "gnome.file-roller"
"gnome.geary" # adaptive e-mail client; uses webkitgtk 4.1
"gnome.gnome-calculator"
"gnome.gnome-calendar"
"gnome.gnome-clocks"
"gnome.gnome-maps"
# "gnome-podcasts"
# "gnome.gnome-system-monitor"
# "gnome.gnome-terminal" # works on phosh
"gnome.gnome-weather"
# "gnome.seahorse" # keyring/secret manager
"gnome-frog" # OCR/QR decoder
"gpodder"
"gst-device-monitor" # for debugging audio/video
# "gthumb"
# "lemoa" # lemmy app
"libcamera" # for `cam` binary (useful for debugging cameras)
"libnotify" # for notify-send; debugging
# "lollypop"
"loupe" # image viewer
"mate.engrampa" # archive manager
"mepo" # maps viewer
"mesa-demos" # for eglinfo, glxinfo & other testing tools
"mpv"
"networkmanagerapplet" # for nm-connection-editor: it's better than not having any gui!
"ntfy-sh" # notification service
# "newsflash" # RSS viewer
"pavucontrol"
"pwvucontrol" # pipewire version of pavu
# "picard" # music tagging
# "libsForQt5.plasmatube" # Youtube player
"signal-desktop"
"snapshot" # camera app
"spot" # Gnome Spotify client
# "sublime-music"
# "tdesktop" # broken on phosh
# "tokodon"
"tuba" # mastodon/pleroma client (stores pw in keyring)
"vulkan-tools" # vulkaninfo
# "whalebird" # pleroma client (Electron). input is broken on phosh.
"xdg-terminal-exec"
"zathura" # PDF/CBZ/ePUB viewer
];
handheldGuiApps = declPackageSet [
# "celluloid" # mpv frontend
# "chatty" # matrix/xmpp/irc client (2023/12/29: disabled because broken cross build)
"cozy" # audiobook player
"epiphany" # gnome's web browser
# "iotas" # note taking app
"komikku"
"koreader"
"megapixels" # camera app
"notejot" # note taking, e.g. shopping list
"planify" # todo-tracker/planner
"portfolio-filemanager"
"tangram" # web browser
"wike" # Wikipedia Reader
"xarchiver" # archiver, backup option for when engrampa UI overflows screen and is unusale (xarchiver UI fails in different ways)
];
pcGuiApps = declPackageSet [
# package sets
"pcGameApps"
"pcTuiApps"
####
"audacity"
# "blanket" # ambient noise generator
"brave" # for the integrated wallet -- as a backup
# "cantata" # music player (mpd frontend)
# "chromium" # chromium takes hours to build. brave is chromium-based, distributed in binary form, so prefer it.
# "cups"
"discord" # x86-only
"electrum"
"element-desktop"
"firefox"
"font-manager"
# "gajim" # XMPP client. cross build tries to import host gobject-introspection types (2023/09/01)
"gimp" # broken on phosh
# "gnome.dconf-editor"
# "gnome.file-roller"
"gnome.gnome-disk-utility"
"gnome.nautilus" # file browser
# "gnome.totem" # video player, supposedly supports UPnP
# "handbrake" #< TODO: fix build
"inkscape"
# "jellyfin-media-player"
"kdenlive"
# "kid3" # audio tagging
"krita"
"libreoffice" # TODO: replace with an office suite that uses saner packaging?
"losslesscut-bin" # x86-only
# "makemkv" # x86-only
# "monero-gui" # x86-only
# "mumble"
# "nheko" # Matrix chat client
# "nicotine-plus" # soulseek client. before re-enabling this make sure it's properly sandboxed!
# "obsidian"
# "openscad" # 3d modeling
# "rhythmbox" # local music player
# "slic3r"
"soundconverter"
"spotify" # x86-only
"tor-browser" # x86-only
# "vlc"
"wireshark" # could maybe ship the cli as sysadmin pkg
# "xterm" # requires Xwayland
# "zecwallet-lite" # x86-only
# "zulip"
];
# INDIVIDUAL PACKAGE DEFINITIONS # INDIVIDUAL PACKAGE DEFINITIONS
@@ -237,14 +413,6 @@ in
bridge-utils.sandbox.method = "bwrap"; #< bwrap, landlock: both work bridge-utils.sandbox.method = "bwrap"; #< bwrap, landlock: both work
bridge-utils.sandbox.net = "all"; bridge-utils.sandbox.net = "all";
brightnessctl.sandbox.method = "landlock"; # also bwrap, but landlock is more responsive
brightnessctl.sandbox.extraPaths = [
"/sys/class/backlight"
"/sys/class/leds"
"/sys/devices"
];
brightnessctl.sandbox.whitelistDbus = [ "system" ];
btrfs-progs.sandbox.method = "bwrap"; #< bwrap, landlock: both work btrfs-progs.sandbox.method = "bwrap"; #< bwrap, landlock: both work
btrfs-progs.sandbox.autodetectCliPaths = "existing"; # e.g. `btrfs filesystem df /my/fs` btrfs-progs.sandbox.autodetectCliPaths = "existing"; # e.g. `btrfs filesystem df /my/fs`
@@ -305,7 +473,7 @@ in
]; ];
dtc.sandbox.method = "bwrap"; dtc.sandbox.method = "bwrap";
dtc.sandbox.autodetectCliPaths = true; # TODO:sandbox: untested dtc.sandbox.autodetectCliPaths = "existingFile"; # TODO:sandbox: untested
duplicity = {}; duplicity = {};
@@ -341,10 +509,9 @@ in
ethtool.sandbox.capabilities = [ "net_admin" ]; ethtool.sandbox.capabilities = [ "net_admin" ];
# eza `ls` replacement # eza `ls` replacement
# landlock is OK, only `whitelistPwd` doesn't make the intermediate symlinks traversable, so it breaks on e.g. ~/Videos/servo/Shows/foo
# eza.sandbox.method = "landlock"; # eza.sandbox.method = "landlock";
eza.sandbox.method = "bwrap"; eza.sandbox.method = "bwrap"; #< note that bwrap causes `/proc` files to be listed differently (e.g. `eza /proc/sys/net/ipv6/conf/`)
eza.sandbox.autodetectCliPaths = true; eza.sandbox.autodetectCliPaths = "existing";
eza.sandbox.whitelistPwd = true; eza.sandbox.whitelistPwd = true;
eza.sandbox.extraHomePaths = [ eza.sandbox.extraHomePaths = [
# so that e.g. `eza -l ~` can show which symlink exist # so that e.g. `eza -l ~` can show which symlink exist
@@ -356,7 +523,7 @@ in
fatresize.sandbox.autodetectCliPaths = "parent"; # /dev/sda1 -> needs /dev/sda fatresize.sandbox.autodetectCliPaths = "parent"; # /dev/sda1 -> needs /dev/sda
fd.sandbox.method = "landlock"; fd.sandbox.method = "landlock";
fd.sandbox.autodetectCliPaths = true; fd.sandbox.autodetectCliPaths = "existing";
fd.sandbox.whitelistPwd = true; fd.sandbox.whitelistPwd = true;
fd.sandbox.extraHomePaths = [ fd.sandbox.extraHomePaths = [
# let it follow symlinks to non-sensitive data # let it follow symlinks to non-sensitive data
@@ -369,10 +536,10 @@ in
ffmpeg.sandbox.autodetectCliPaths = "existingFileOrParent"; # it outputs uncreated files -> parent dir needs mounting ffmpeg.sandbox.autodetectCliPaths = "existingFileOrParent"; # it outputs uncreated files -> parent dir needs mounting
file.sandbox.method = "bwrap"; file.sandbox.method = "bwrap";
file.sandbox.autodetectCliPaths = true; file.sandbox.autodetectCliPaths = "existing"; #< file OR directory, yes
findutils.sandbox.method = "bwrap"; findutils.sandbox.method = "bwrap";
findutils.sandbox.autodetectCliPaths = true; findutils.sandbox.autodetectCliPaths = "existing";
findutils.sandbox.whitelistPwd = true; findutils.sandbox.whitelistPwd = true;
findutils.sandbox.extraHomePaths = [ findutils.sandbox.extraHomePaths = [
# let it follow symlinks to non-sensitive data # let it follow symlinks to non-sensitive data
@@ -391,9 +558,7 @@ in
}); });
forkstat.sandbox.method = "landlock"; #< doesn't seem to support bwrap forkstat.sandbox.method = "landlock"; #< doesn't seem to support bwrap
forkstat.sandbox.extraConfig = [ forkstat.sandbox.isolatePids = false;
"--sanebox-keep-namespace" "pid"
];
forkstat.sandbox.extraPaths = [ forkstat.sandbox.extraPaths = [
"/proc" "/proc"
]; ];
@@ -407,7 +572,7 @@ in
gawk.sandbox.method = "bwrap"; # TODO:sandbox: untested gawk.sandbox.method = "bwrap"; # TODO:sandbox: untested
gawk.sandbox.wrapperType = "inplace"; # /share/gawk libraries refer to /libexec gawk.sandbox.wrapperType = "inplace"; # /share/gawk libraries refer to /libexec
gawk.sandbox.autodetectCliPaths = true; gawk.sandbox.autodetectCliPaths = "existingFile";
gdb.sandbox.enable = false; # gdb doesn't sandbox well. i don't know how you could. gdb.sandbox.enable = false; # gdb doesn't sandbox well. i don't know how you could.
# gdb.sandbox.method = "landlock"; # permission denied when trying to attach, even as root # gdb.sandbox.method = "landlock"; # permission denied when trying to attach, even as root
@@ -503,7 +668,7 @@ in
"gnome.hitori".sandbox.whitelistWayland = true; "gnome.hitori".sandbox.whitelistWayland = true;
gnugrep.sandbox.method = "bwrap"; gnugrep.sandbox.method = "bwrap";
gnugrep.sandbox.autodetectCliPaths = true; gnugrep.sandbox.autodetectCliPaths = "existing";
gnugrep.sandbox.whitelistPwd = true; gnugrep.sandbox.whitelistPwd = true;
gnugrep.sandbox.extraHomePaths = [ gnugrep.sandbox.extraHomePaths = [
# let it follow symlinks to non-sensitive data # let it follow symlinks to non-sensitive data
@@ -511,7 +676,6 @@ in
".persist/plaintext" ".persist/plaintext"
]; ];
# sed: there is an edgecase of `--file=<foo>`, wherein `foo` won't be whitelisted.
gnused.sandbox.method = "bwrap"; gnused.sandbox.method = "bwrap";
gnused.sandbox.autodetectCliPaths = "existingFile"; gnused.sandbox.autodetectCliPaths = "existingFile";
gnused.sandbox.whitelistPwd = true; #< `-i` flag creates a temporary file in pwd (?) and then moves it. gnused.sandbox.whitelistPwd = true; #< `-i` flag creates a temporary file in pwd (?) and then moves it.
@@ -537,7 +701,7 @@ in
# hdparm: has to be run as sudo. e.g. `sudo hdparm -i /dev/sda` # hdparm: has to be run as sudo. e.g. `sudo hdparm -i /dev/sda`
hdparm.sandbox.method = "bwrap"; hdparm.sandbox.method = "bwrap";
hdparm.sandbox.autodetectCliPaths = true; hdparm.sandbox.autodetectCliPaths = "existingFile";
host.sandbox.method = "landlock"; host.sandbox.method = "landlock";
host.sandbox.net = "all"; #< technically, only needs to contact localhost's DNS server host.sandbox.net = "all"; #< technically, only needs to contact localhost's DNS server
@@ -572,16 +736,16 @@ in
iotop.sandbox.capabilities = [ "net_admin" ]; iotop.sandbox.capabilities = [ "net_admin" ];
# provides `ip`, `routel`, `bridge`, others. # provides `ip`, `routel`, `bridge`, others.
# landlock works fine for most of these, but `ip netns exec` uses namespaces internally, # landlock works fine for most of these, but `ip netns exec` wants to attach to an existing namespace
# and that's incompatible with landlock # and that means we can't use ANY sandboxer for it.
iproute2.sandbox.method = "bwrap"; iproute2.sandbox.enable = false;
iproute2.sandbox.net = "all"; # iproute2.sandbox.net = "all";
iproute2.sandbox.capabilities = [ "net_admin" ]; # iproute2.sandbox.capabilities = [ "net_admin" ];
iproute2.sandbox.extraPaths = [ # iproute2.sandbox.extraPaths = [
"/run/netns" # for `ip netns ...` to work, but maybe not needed anymore? # "/run/netns" # for `ip netns ...` to work, but maybe not needed anymore?
"/sys/class/net" # for `ip netns ...` to work # "/sys/class/net" # for `ip netns ...` to work
"/var/run/netns" # "/var/run/netns"
]; # ];
iptables.sandbox.method = "landlock"; iptables.sandbox.method = "landlock";
iptables.sandbox.net = "all"; iptables.sandbox.net = "all";
@@ -655,6 +819,8 @@ in
mercurial.sandbox.net = "clearnet"; mercurial.sandbox.net = "clearnet";
mercurial.sandbox.whitelistPwd = true; mercurial.sandbox.whitelistPwd = true;
mesa-demos = {};
# actual monero blockchain (not wallet/etc; safe to delete, just slow to regenerate) # actual monero blockchain (not wallet/etc; safe to delete, just slow to regenerate)
monero-gui.buildCost = 1; monero-gui.buildCost = 1;
# XXX: is it really safe to persist this? it doesn't have info that could de-anonymize if captured? # XXX: is it really safe to persist this? it doesn't have info that could de-anonymize if captured?
@@ -693,9 +859,15 @@ in
nixpkgs-review.sandbox.wrapperType = "inplace"; #< shell completions use full paths nixpkgs-review.sandbox.wrapperType = "inplace"; #< shell completions use full paths
nixpkgs-review.sandbox.net = "clearnet"; nixpkgs-review.sandbox.net = "clearnet";
nixpkgs-review.sandbox.whitelistPwd = true; nixpkgs-review.sandbox.whitelistPwd = true;
nixpkgs-review.sandbox.extraHomePaths = [
".config/git" #< it needs to know commiter name/email, even if not posting
];
nixpkgs-review.sandbox.extraPaths = [ nixpkgs-review.sandbox.extraPaths = [
"/nix" "/nix"
]; ];
nixpkgs-review.persist.byStore.cryptClearOnBoot = [
".cache/nixpkgs-review" #< help it not exhaust / tmpfs
];
nmap.sandbox.method = "bwrap"; nmap.sandbox.method = "bwrap";
nmap.sandbox.net = "all"; # clearnet and lan nmap.sandbox.net = "all"; # clearnet and lan
@@ -757,9 +929,7 @@ in
# procps: free, pgrep, pidof, pkill, ps, pwait, top, uptime, couple others # procps: free, pgrep, pidof, pkill, ps, pwait, top, uptime, couple others
procps.sandbox.method = "bwrap"; procps.sandbox.method = "bwrap";
procps.sandbox.extraConfig = [ procps.sandbox.isolatePids = false;
"--sanebox-keep-namespace" "pid"
];
pstree.sandbox.method = "landlock"; pstree.sandbox.method = "landlock";
pstree.sandbox.extraPaths = [ pstree.sandbox.extraPaths = [
@@ -797,15 +967,21 @@ in
rustc = {}; rustc = {};
sane-cast = {}; #< TODO: sandbox this the same way i sandbox go2tv sane-cast.sandbox.method = "bwrap";
sane-cast.sandbox.net = "clearnet";
sane-cast.sandbox.autodetectCliPaths = "existingFile";
sane-cast.suggestedPrograms = [ "go2tv" ];
sane-die-with-parent.sandbox.enable = false; #< it's a launcher; can't sandbox sane-die-with-parent.sandbox.enable = false; #< it's a launcher; can't sandbox
sane-weather.sandbox.method = "bwrap";
sane-weather.sandbox.net = "clearnet";
screen.sandbox.enable = false; #< tty; needs to run anything screen.sandbox.enable = false; #< tty; needs to run anything
sequoia.sandbox.method = "bwrap"; # TODO:sandbox: untested sequoia.sandbox.method = "bwrap"; # TODO:sandbox: untested
sequoia.sandbox.whitelistPwd = true; sequoia.sandbox.whitelistPwd = true;
sequoia.sandbox.autodetectCliPaths = true; sequoia.sandbox.autodetectCliPaths = "existingFileOrParent"; # supports `-o <file-to-create>`
shattered-pixel-dungeon.buildCost = 1; shattered-pixel-dungeon.buildCost = 1;
shattered-pixel-dungeon.persist.byStore.plaintext = [ ".local/share/.shatteredpixel/shattered-pixel-dungeon" ]; shattered-pixel-dungeon.persist.byStore.plaintext = [ ".local/share/.shatteredpixel/shattered-pixel-dungeon" ];
@@ -827,6 +1003,8 @@ in
smartmontools.sandbox.autodetectCliPaths = "existing"; smartmontools.sandbox.autodetectCliPaths = "existing";
smartmontools.sandbox.capabilities = [ "sys_rawio" ]; smartmontools.sandbox.capabilities = [ "sys_rawio" ];
# snapshot camera, based on libcamera
# TODO: enable dma heaps for more efficient buffer sharing: <https://gitlab.com/postmarketOS/pmaports/-/issues/2789>
snapshot = {}; snapshot = {};
sops.sandbox.method = "bwrap"; # TODO:sandbox: untested sops.sandbox.method = "bwrap"; # TODO:sandbox: untested
@@ -900,7 +1078,7 @@ in
tokodon.persist.byStore.private = [ ".cache/KDE/tokodon" ]; tokodon.persist.byStore.private = [ ".cache/KDE/tokodon" ];
tree.sandbox.method = "landlock"; tree.sandbox.method = "landlock";
tree.sandbox.autodetectCliPaths = true; tree.sandbox.autodetectCliPaths = "existing";
tree.sandbox.whitelistPwd = true; tree.sandbox.whitelistPwd = true;
tumiki-fighters.buildCost = 1; tumiki-fighters.buildCost = 1;
@@ -945,6 +1123,8 @@ in
"tmp" "tmp"
]; ];
watch.sandbox.enable = false; #< it executes the command it's given
wdisplays.sandbox.method = "bwrap"; wdisplays.sandbox.method = "bwrap";
wdisplays.sandbox.whitelistWayland = true; wdisplays.sandbox.whitelistWayland = true;
@@ -967,6 +1147,8 @@ in
wl-clipboard.sandbox.whitelistWayland = true; wl-clipboard.sandbox.whitelistWayland = true;
wtype = {}; wtype = {};
wtype.sandbox.method = "bwrap";
wtype.sandbox.whitelistWayland = true;
xwayland.sandbox.method = "bwrap"; xwayland.sandbox.method = "bwrap";
xwayland.sandbox.wrapperType = "inplace"; #< consumers use it as a library (e.g. wlroots) xwayland.sandbox.wrapperType = "inplace"; #< consumers use it as a library (e.g. wlroots)
@@ -985,7 +1167,44 @@ in
zfs = {}; zfs = {};
}; };
programs.feedbackd = lib.mkIf config.sane.programs.feedbackd.enabled { sane.persist.sys.byStore.plaintext = lib.mkIf config.sane.programs.guiApps.enabled [
# "/var/lib/alsa" # preserve output levels, default devices
{ path = "/var/lib/systemd/backlight"; method = "bind"; } # backlight brightness; bind because systemd T_T
];
systemd.services."systemd-backlight@" = lib.mkIf config.sane.programs.guiApps.enabled {
after = [
"ensure-var-lib-systemd-backlight.service"
];
wants = [
"ensure-var-lib-systemd-backlight.service"
];
};
hardware.opengl = lib.mkIf config.sane.programs.guiApps.enabled ({
enable = true; enable = true;
driSupport = lib.mkDefault true;
} // (lib.optionalAttrs pkgs.stdenv.isx86_64 {
# for 32 bit applications
# upstream nixpkgs forbids setting driSupport32Bit unless specifically x86_64 (so aarch64 isn't allowed)
driSupport32Bit = lib.mkDefault true;
}));
system.activationScripts.notifyActive = lib.mkIf config.sane.programs.guiApps.enabled {
text = lib.concatStringsSep "\n" ([
''
tryNotifyUser() {
local user="$1"
local new_path="$PATH:${pkgs.sudo}/bin:${pkgs.libnotify}/bin"
local version="$(cat $systemConfig/nixos-version)"
PATH="$new_path" sudo -u "$user" \
env PATH="$new_path" NIXOS_VERSION="$version" /bin/sh -c \
'. $HOME/.profile; dbus_file="$XDG_RUNTIME_DIR/bus"; if [ -z "$DBUS_SESSION_BUS_ADDRESS" ] && [ -e "$dbus_file" ]; then export DBUS_SESSION_BUS_ADDRESS="unix:path=$dbus_file"; fi ; if [ -n "$DBUS_SESSION_BUS_ADDRESS" ]; then notify-send "nixos activated" "version: $NIXOS_VERSION" ; fi'
}
''
] ++ lib.mapAttrsToList
(user: en: lib.optionalString en "tryNotifyUser ${user}")
config.sane.programs.guiApps.enableFor.user
);
}; };
} }

View File

@@ -19,7 +19,7 @@
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.whitelistAudio = true; sandbox.whitelistAudio = true;
sandbox.whitelistWayland = true; sandbox.whitelistWayland = true;
sandbox.autodetectCliPaths = true; sandbox.autodetectCliPaths = "existingFile";
sandbox.extraHomePaths = [ sandbox.extraHomePaths = [
# support media imports via file->open dir to some common media directories # support media imports via file->open dir to some common media directories
"tmp" "tmp"

View File

@@ -0,0 +1,10 @@
# `ausyscall --dump`: lists all syscalls by number and name
{ pkgs, ... }:
{
sane.programs.ausyscall = {
packageUnwrapped = pkgs.linkIntoOwnPackage pkgs.audit "bin/ausyscall";
sandbox.method = "landlock";
};
}

View File

@@ -87,7 +87,7 @@ let
in in
{ {
sane.programs.bemenu = { sane.programs.bemenu = {
sandbox.method = "bwrap"; # landlock works, but requires *all* of /run/user/$ID to be granted. sandbox.method = "bwrap"; # landlock works, but requires *all* of $XDG_RUNTIME_DIR to be granted.
sandbox.whitelistWayland = true; sandbox.whitelistWayland = true;
sandbox.extraHomePaths = [ sandbox.extraHomePaths = [
".cache/fontconfig" #< else it complains, and is *way* slower ".cache/fontconfig" #< else it complains, and is *way* slower

View File

@@ -39,11 +39,9 @@ in
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.whitelistAudio = true; sandbox.whitelistAudio = true;
sandbox.net = "clearnet"; sandbox.net = "clearnet";
sandbox.extraConfig = [ #v else it fails to reap its children (or, maybe, it fails to hook its parent's death signal?)
# else it fails to reap its children (or, maybe, it fails to hook its parent's death signal?) #v might be possible to remove this, but kinda hard to see a clean way.
# might be possible to remove this, but kinda hard to see a clean way. sandbox.isolatePids = false;
"--sanebox-keep-namespace" "pid"
];
suggestedPrograms = [ "blast-ugjka" "sane-die-with-parent" ]; suggestedPrograms = [ "blast-ugjka" "sane-die-with-parent" ];
}; };

View File

@@ -103,19 +103,37 @@ in
}; };
}; };
packageUnwrapped = pkgs.bonsai.overrideAttrs (upstream: {
# patch to place the socket in a subdirectory where it can be sandboxed
postPatch = (upstream.postPatch or "") + ''
substituteInPlace cmd/{bonsaictl,bonsaid}/main.ha \
--replace-fail 'path::set(&buf, statedir, "bonsai")' 'path::set(&buf, statedir, "bonsai/bonsai")'
'';
});
fs.".config/bonsai/bonsai_tree.json".symlink.text = builtins.toJSON cfg.config.transitions; fs.".config/bonsai/bonsai_tree.json".symlink.text = builtins.toJSON cfg.config.transitions;
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.extraRuntimePaths = [ sandbox.extraRuntimePaths = [
"/" #< just needs "bonsai", but needs to create it first... "bonsai"
]; ];
services.bonsaid = { services.bonsaid = {
description = "bonsai: programmable input dispatcher"; description = "bonsai: programmable input dispatcher";
dependencyOf = [ "sway" ]; # to ensure `$XDG_RUNTIME_DIR/bonsai` exists before sway binds it
partOf = [ "graphical-session" ]; partOf = [ "graphical-session" ];
# nice -n -11 chosen arbitrarily. i hope this will allow for faster response to inputs, but without audio underruns (pipewire is -21, dino -15-ish) # nice -n -11 chosen arbitrarily. i hope this will allow for faster response to inputs, but without audio underruns (pipewire is -21, dino -15-ish)
command = "nice -n -11 bonsaid -t $HOME/.config/bonsai/bonsai_tree.json"; command = pkgs.writeShellScript "bonsai-start" ''
cleanupCommand = "rm -f $XDG_RUNTIME_DIR/bonsai"; # TODO: don't create the sway directory here!
# i do it for now because sway and bonsai call into eachother; circular dependency:
# - sway -> bonsai -> sane-input-handler -> swaymsg
mkdir -p $XDG_RUNTIME_DIR/{bonsai,sway}
exec nice -n -11 bonsaid -t $HOME/.config/bonsai/bonsai_tree.json
'';
cleanupCommand = "rm -f $XDG_RUNTIME_DIR/bonsai/bonsai";
readiness.waitExists = [
"$XDG_RUNTIME_DIR/bonsai/bonsai"
];
}; };
}; };
} }

View File

@@ -1,6 +1,12 @@
{ ... }: { pkgs, ... }:
{ {
sane.programs.brave = { sane.programs.brave = {
# convert eval error to build failure
packageUnwrapped = if (builtins.tryEval pkgs.brave).success then
pkgs.brave
else
pkgs.runCommandLocal "brave-not-supported" {} "false"
;
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.wrapperType = "inplace"; # /opt/share/brave.com vendor-style packaging sandbox.wrapperType = "inplace"; # /opt/share/brave.com vendor-style packaging
sandbox.net = "all"; sandbox.net = "all";
@@ -8,6 +14,9 @@
"dev" # for developing anything web-related "dev" # for developing anything web-related
"tmp" "tmp"
]; ];
sandbox.extraPaths = [
"/tmp" # needed particularly if run from `sane-vpn do`
];
sandbox.whitelistAudio = true; sandbox.whitelistAudio = true;
sandbox.whitelistDri = true; sandbox.whitelistDri = true;
sandbox.whitelistWayland = true; sandbox.whitelistWayland = true;

View File

@@ -0,0 +1,23 @@
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.brightnessctl;
in
{
sane.programs.brightnessctl = {
sandbox.method = "landlock"; # also bwrap, but landlock is more responsive
sandbox.extraPaths = [
"/sys/class/backlight"
"/sys/class/leds"
"/sys/devices"
];
# sandbox.whitelistDbus = [ "system" ]; #< only necessary if not granting udev perms
};
services.udev.extraRules = let
chmod = "${pkgs.coreutils}/bin/chmod";
chown = "${pkgs.coreutils}/bin/chown";
in lib.mkIf cfg.enabled ''
# make backlight controllable by members of `video`
SUBSYSTEM=="backlight", RUN+="${chown} :video $sys$devpath/brightness", RUN+="${chmod} g+w $sys$devpath/brightness"
'';
}

View File

@@ -13,6 +13,10 @@
sane.programs.callaudiod = { sane.programs.callaudiod = {
packageUnwrapped = pkgs.rmDbusServices pkgs.callaudiod; packageUnwrapped = pkgs.rmDbusServices pkgs.callaudiod;
# probably more needed once i enable proper sandboxing, but for now this ensures the service isn't started too early!
sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ];
services.callaudiod = { services.callaudiod = {
description = "callaudiod: dbus service to switch audio profiles and mute microphone"; description = "callaudiod: dbus service to switch audio profiles and mute microphone";
partOf = [ "default" ]; partOf = [ "default" ];

View File

@@ -1,184 +0,0 @@
#!/bin/sh
#!/usr/bin/env nix-shell
#!nix-shell -i bash
usage() {
echo "usage: battery_estimate [options...]"
echo
echo "pretty-prints a battery estimate (icon to indicate state, and a duration estimate)"
echo
echo "options:"
echo " --debug: output additional information, to stderr"
echo " --minute-suffix <string>: use the provided string as a minutes suffix"
echo " --hour-suffix <string>: use the provided string as an hours suffix"
echo " --icon-suffix <string>: use the provided string as an icon suffix"
echo " --percent-suffix <string>: use the provided string when displaying percents"
}
# these icons come from sxmo; they only render in nerdfonts
icon_bat_chg=("󰢟" "󱊤" "󱊥" "󰂅")
icon_bat_dis=("󰂎" "󱊡" "󱊢" "󱊣")
suffix_icon="" # thin space
suffix_percent="%"
# suffix_icon=" "
# render time like: 2ʰ08ᵐ
# unicode sub/super-scripts: <https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts>
# symbol_hr="ʰ"
# symbol_min="ᵐ"
# render time like: 2ₕ08ₘ
# symbol_hr="ₕ"
# symbol_min="ₘ"
# render time like: 2h08m
# symbol_hr="h"
# symbol_min="m"
# render time like: 2:08
# symbol_hr=":"
# symbol_min=
# render time like: 208⧗
symbol_hr=""
symbol_min="⧗"
# variants:
# symbol_hr=":"
# symbol_min="⧖"
# symbol_min="⌛"
# render time like: 2'08"
# symbol_hr="'"
# symbol_min='"'
log() {
if [ "$BATTERY_ESTIMATE_DEBUG" = "1" ]; then
printf "$@" >&2
echo >&2
fi
}
render_icon() {
# args:
# 1: "chg" or "dis"
# 2: current battery percentage
level=$(($2 / 25))
level=$(($level > 3 ? 3 : $level))
level=$(($level < 0 ? 0 : $level))
log "icon: %s %d" "$1" "$level"
if [ "$1" = "dis" ]; then
printf "%s" "${icon_bat_dis[$level]}"
elif [ "$1" = "chg" ]; then
printf "%s" "${icon_bat_chg[$level]}"
fi
}
try_path() {
# assigns output variables:
# - perc, perc_from_full (0-100)
# - full, rate (pos means charging)
if [ -f "$1/capacity" ]; then
log "perc, perc_from_full from %s" "$1/capacity"
perc=$(cat "$1/capacity")
perc_from_full=$((100 - $perc))
fi
if [ -f "$1/charge_full_design" ] && [ -f "$1/current_now" ]; then
log "full, rate from %s and %s" "$1/charge_full_design" "$1/current_now"
# current is positive when charging
full=$(cat "$1/charge_full_design")
rate=$(cat "$1/current_now")
elif [ -f "$1/energy_full" ] && [ -f "$1/power_now" ]; then
log "full, rate from %s and %s" "$1/energy_full" "$1/power_now"
# power_now is positive when discharging
full=$(cat "$1/energy_full")
rate=-$(cat "$1/power_now")
elif [ -f "$1/energy_full" ] && [ -f "$1/energy_now" ]; then
log "full, rate from %s and %s" "$1/energy_full" "$1/energy_now"
log " this is a compatibility path for legacy Thinkpad batteries which do not populate the 'power_now' field, and incorrectly populate 'energy_now' with power info"
# energy_now is positive when discharging
full=$(cat "$1/energy_full")
rate=-$(cat "$1/energy_now")
fi
}
try_all_paths() {
try_path "/sys/class/power_supply/axp20x-battery" # Pinephone
try_path "/sys/class/power_supply/BAT0" # Thinkpad
log "perc: %d, perc_from_full: %d" "$perc" "$perc_from_full"
log "full: %f, rate: %f" "$full" "$rate"
log " rate > 0 means charging, else discharging"
}
fmt_minutes() {
# args:
# 1: icon to render
# 2: string to show if charge/discharge time is indefinite
# 3: minutes to stable state (i.e. to full charge or full discharge)
# - we work in minutes instead of hours for precision: bash math is integer-only
log "charge/discharge time: %f min" "$3"
# args: <battery symbol> <text if ludicrous estimate> <estimated minutes to full/empty>
if [ -n "$3" ] && [ "$3" -lt 1440 ]; then
hr=$(($3 / 60))
hr_in_min=$(($hr * 60))
min=$(($3 - $hr_in_min))
printf "%s%s%d%s%02d%s" "$1" "$suffix_icon" "$hr" "$symbol_hr" "$min" "$symbol_min"
else
log "charge/discharge duration > 1d"
printf "%s%s%s" "$1" "$suffix_icon" "$2" # more than 1d
fi
}
pretty_output() {
if [ -n "$perc" ]; then
duration=""
if [ "$rate" -gt 0 ]; then
log "charging"
icon="$(render_icon chg $perc)"
duration="$(($full * 60 * $perc_from_full / (100 * $rate)))"
else
log "discharging"
icon="$(render_icon dis $perc)"
if [ "$rate" -lt 0 ]; then
duration="$(($full * 60 * $perc / (-100 * $rate)))"
fi
fi
fmt_minutes "$icon" "$perc$suffix_percent" "$duration"
fi
}
while [ "$#" -gt 0 ]; do
case "$1" in
"--debug")
shift
BATTERY_ESTIMATE_DEBUG=1
;;
"--icon-suffix")
shift
suffix_icon="$1"
shift
;;
"--hour-suffix")
shift
symbol_hr="$1"
shift
;;
"--minute-suffix")
shift
symbol_min="$1"
shift
;;
"--percent-suffix")
shift
suffix_percent="$1"
shift
;;
*)
usage
exit 1
;;
esac
done
try_all_paths
pretty_output

View File

@@ -1,28 +1,25 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
sane.programs.conky = { sane.programs.conky = {
# TODO: non-sandboxed `conky` still ships via `sxmo-utils`, but unused
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.net = "clearnet"; #< for the scripts it calls (weather) sandbox.net = "clearnet"; #< for the scripts it calls (weather)
sandbox.extraPaths = [ sandbox.extraPaths = [
"/sys/class/power_supply" "/sys/class/power_supply"
"/sys/devices" # needed by battery_estimate "/sys/devices" # needed by sane-sysinfo
# "/sys/devices/cpu" # "/sys/devices/cpu"
# "/sys/devices/system" # "/sys/devices/system"
]; ];
sandbox.whitelistWayland = true; sandbox.whitelistWayland = true;
fs.".config/conky/conky.conf".symlink.target = suggestedPrograms = [
let "sane-sysinfo"
# TODO: make this just another `suggestedPrograms`! "sane-weather"
battery_estimate = pkgs.static-nix-shell.mkBash { ];
pname = "battery_estimate";
srcRoot = ./.; fs.".config/conky/conky.conf".symlink.target = pkgs.substituteAll {
};
in pkgs.substituteAll {
src = ./conky.conf; src = ./conky.conf;
bat = "${battery_estimate}/bin/battery_estimate"; bat = "sane-sysinfo";
weather = "timeout 20 ${pkgs.sane-weather}/bin/sane-weather"; weather = "timeout 20 sane-weather";
}; };
services.conky = { services.conky = {

View File

@@ -0,0 +1,54 @@
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.dissent;
in
{
sane.programs.dbus = {
configOption = with lib; mkOption {
default = {};
type = types.submodule {
options.autostart = mkOption {
type = types.bool;
default = true;
};
};
};
packageUnwrapped = (pkgs.dbus.override {
# remove features i don't want. mostly to avoid undesired interactions, but also it reduces the closure by 55 MB :)
enableSystemd = false;
x11Support = false;
}).overrideAttrs (upstream: {
postFixup = (upstream.postFixup or "") + ''
# the XML docs have a URI field which points to self,
# and that breaks the sandbox checker
substituteInPlace $out/share/xml/dbus-1/catalog.xml \
--replace-fail "$out" "/run/current-system/sw"
# conf file points to dbus-daemon-launch-helper by absolute path,
# which breaks sandboxing. i don't want dbus auto-launching stuff anyway though.
substituteInPlace $out/share/dbus-1/system.conf \
--replace-fail "$out/libexec/dbus-daemon-launch-helper" "false"
'';
});
sandbox.method = "bwrap";
sandbox.extraRuntimePaths = [
"/" #< it needs to create a file in the root. TODO: move the bus handle into a sandboxable subdirectory
];
sandbox.isolatePids = false; #< not actually sure *why* this is necessary, but it is
env.DBUS_SESSION_BUS_ADDRESS = "unix:path=$XDG_RUNTIME_DIR/bus";
# normally systemd would create a dbus session for us, but if you configure it not to do that
# then we can create our own. not sure if there's a dependency ordering issue here: lots
# of things depend on dbus but i don't do anything special to guarantee this is initialized
# before them.
services.dbus = {
description = "dbus user session";
partOf = lib.mkIf cfg.config.autostart [ "default" ];
command = "dbus-daemon --session --nofork --address=$DBUS_SESSION_BUS_ADDRESS";
readiness.waitExists = [ "$XDG_RUNTIME_DIR/bus" ];
};
};
}

View File

@@ -34,7 +34,7 @@ in
services.dconf = { services.dconf = {
description = "dconf configuration database/server"; description = "dconf configuration database/server";
partOf = [ "graphical-session" ]; partOf = [ "default" ];
command = "${lib.getLib cfg.package}/libexec/dconf-service"; command = "${lib.getLib cfg.package}/libexec/dconf-service";
}; };

View File

@@ -9,10 +9,12 @@
./animatch.nix ./animatch.nix
./assorted.nix ./assorted.nix
./audacity.nix ./audacity.nix
./ausyscall.nix
./bemenu.nix ./bemenu.nix
./blast-ugjka ./blast-ugjka
./bonsai.nix ./bonsai.nix
./brave.nix ./brave.nix
./brightnessctl.nix
./bubblewrap.nix ./bubblewrap.nix
./callaudiod.nix ./callaudiod.nix
./calls.nix ./calls.nix
@@ -24,6 +26,7 @@
./cozy.nix ./cozy.nix
./cups.nix ./cups.nix
./curlftpfs.nix ./curlftpfs.nix
./dbus.nix
./dconf.nix ./dconf.nix
./deadd-notification-center ./deadd-notification-center
./dialect.nix ./dialect.nix
@@ -42,6 +45,7 @@
./flare-signal.nix ./flare-signal.nix
./fontconfig.nix ./fontconfig.nix
./fractal.nix ./fractal.nix
./free.nix
./frozen-bubble.nix ./frozen-bubble.nix
./fwupd.nix ./fwupd.nix
./g4music.nix ./g4music.nix
@@ -77,27 +81,30 @@
./megapixels.nix ./megapixels.nix
./mepo.nix ./mepo.nix
./mimeo ./mimeo
./modemmanager.nix ./mmcli.nix
./mopidy.nix ./mopidy.nix
./mpv ./mpv
./msmtp.nix ./msmtp.nix
./nautilus.nix ./nautilus.nix
./neovim.nix ./neovim.nix
./networkmanager.nix
./newsflash.nix ./newsflash.nix
./nheko.nix ./nheko.nix
./nicotine-plus.nix ./nicotine-plus.nix
./nix-index.nix ./nix-index.nix
./nmcli.nix
./notejot.nix ./notejot.nix
./ntfy-sh.nix ./ntfy-sh.nix
./nwg-panel
./objdump.nix ./objdump.nix
./obsidian.nix ./obsidian.nix
./offlineimap.nix ./offlineimap.nix
./open-in-mpv.nix ./open-in-mpv.nix
./pactl.nix
./pipewire.nix ./pipewire.nix
./planify.nix ./planify.nix
./portfolio-filemanager.nix ./portfolio-filemanager.nix
./playerctl.nix ./playerctl.nix
./ps.nix
./rhythmbox.nix ./rhythmbox.nix
./ripgrep.nix ./ripgrep.nix
./rofi ./rofi
@@ -107,9 +114,13 @@
./sane-open.nix ./sane-open.nix
./sane-screenshot.nix ./sane-screenshot.nix
./sane-scripts.nix ./sane-scripts.nix
./sane-sysinfo.nix
./sane-theme.nix
./sanebox.nix ./sanebox.nix
./schlock.nix ./schlock.nix
./seatd.nix
./sfeed.nix ./sfeed.nix
./shadow.nix
./signal-desktop.nix ./signal-desktop.nix
./splatmoji.nix ./splatmoji.nix
./spot.nix ./spot.nix
@@ -124,6 +135,7 @@
./swayidle.nix ./swayidle.nix
./swaylock.nix ./swaylock.nix
./swaynotificationcenter ./swaynotificationcenter
./switchboard.nix
./sysvol.nix ./sysvol.nix
./tangram.nix ./tangram.nix
./tor-browser.nix ./tor-browser.nix
@@ -136,7 +148,6 @@
./wine.nix ./wine.nix
./wireplumber.nix ./wireplumber.nix
./wireshark.nix ./wireshark.nix
./wpa_supplicant.nix
./wvkbd.nix ./wvkbd.nix
./xarchiver.nix ./xarchiver.nix
./xdg-desktop-portal.nix ./xdg-desktop-portal.nix

View File

@@ -4,7 +4,7 @@ let
in in
{ {
sane.programs.eg25-control = { sane.programs.eg25-control = {
suggestedPrograms = [ "modemmanager" ]; suggestedPrograms = [ "mmcli" ];
services.eg25-control-powered = { services.eg25-control-powered = {
description = "eg25-control-powered: power to the Qualcomm eg25 modem used by PinePhone"; description = "eg25-control-powered: power to the Qualcomm eg25 modem used by PinePhone";

View File

@@ -1,7 +1,20 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
sane.programs.errno = { sane.programs.errno = {
packageUnwrapped = pkgs.linkIntoOwnPackage pkgs.moreutils "bin/errno"; # packageUnwrapped = pkgs.linkIntoOwnPackage pkgs.moreutils "bin/errno";
# actually, don't build all of moreutils because not all of it builds for cross targets.
# some of this can be simplified after <https://github.com/NixOS/nixpkgs/pull/316446>
packageUnwrapped = pkgs.moreutils.overrideAttrs (base: {
makeFlags = (base.makeFlags or []) ++ [
"BINS=errno"
"MANS=errno.1"
"PERLSCRIPTS=errno" #< Makefile errors if empty, but this works :)
"INSTALL_BIN=install"
];
#v disable the perl-specific stuff
propagatedBuildInputs = [];
postInstall = "";
});
sandbox.method = "landlock"; sandbox.method = "landlock";
}; };

View File

@@ -4,7 +4,7 @@
buildCost = 1; buildCost = 1;
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.autodetectCliPaths = true; sandbox.autodetectCliPaths = "existingFile";
sandbox.whitelistWayland = true; sandbox.whitelistWayland = true;
mime.associations."application/pdf" = "org.gnome.Evince.desktop"; mime.associations."application/pdf" = "org.gnome.Evince.desktop";

View File

@@ -209,7 +209,7 @@ in
}; };
i-still-dont-care-about-cookies = { i-still-dont-care-about-cookies = {
package = pkgs.firefox-extensions.i-still-dont-care-about-cookies; package = pkgs.firefox-extensions.i-still-dont-care-about-cookies;
enable = lib.mkDefault true; enable = lib.mkDefault false; #< obsoleted by uBlock Origin annoyances/cookies lists
}; };
open-in-mpv = { open-in-mpv = {
# test: `open-in-mpv 'mpv:///open?url=https://www.youtube.com/watch?v=dQw4w9WgXcQ'` # test: `open-in-mpv 'mpv:///open?url=https://www.youtube.com/watch?v=dQw4w9WgXcQ'`
@@ -226,7 +226,7 @@ in
}; };
ublacklist = { ublacklist = {
package = pkgs.firefox-extensions.ublacklist; package = pkgs.firefox-extensions.ublacklist;
enable = lib.mkDefault true; enable = lib.mkDefault false;
}; };
ublock-origin = { ublock-origin = {
package = pkgs.firefox-extensions.ublock-origin; package = pkgs.firefox-extensions.ublock-origin;
@@ -286,24 +286,35 @@ in
# env.BROWSER = "${package}/bin/${cfg.browser.libName}"; # env.BROWSER = "${package}/bin/${cfg.browser.libName}";
env.BROWSER = cfg.browser.libName; # used by misc tools like xdg-email, as fallback env.BROWSER = cfg.browser.libName; # used by misc tools like xdg-email, as fallback
# uBlock filter list configuration. # uBlock configuration:
# specifically, enable the GDPR cookie prompt blocker. fs."${cfg.browser.dotDir}/managed-storage/uBlock0@raymondhill.net.json".symlink.target = cfg.addons.ublock-origin.package.makeConfig {
# data.toOverwrite.filterLists is additive (i.e. it supplements the default filters) # more filter lists are available here:
# this configuration method is documented here: # - <https://easylist.to>
# - <https://github.com/gorhill/uBlock/issues/2986#issuecomment-364035002> # - <https://github.com/easylist/easylist.git>
# the specific attribute path is found via scraping ublock code here: # - <https://github.com/yokoffing/filterlists>
# - <https://github.com/gorhill/uBlock/blob/master/src/js/storage.js> filterFiles = let
# - <https://github.com/gorhill/uBlock/blob/master/assets/assets.json> getUasset = n: "${pkgs.uassets}/share/filters/${n}.txt";
fs."${cfg.browser.dotDir}/managed-storage/uBlock0@raymondhill.net.json".symlink.text = '' in [
{ # default ublock filters:
"name": "uBlock0@raymondhill.net", (getUasset "ublock-filters")
"description": "ignored", (getUasset "ublock-badware")
"type": "storage", (getUasset "ublock-privacy")
"data": { (getUasset "ublock-quick-fixes")
"toOverwrite": "{\"filterLists\": [\"fanboy-cookiemonster\"]}" (getUasset "ublock-unbreak")
} (getUasset "easylist")
} (getUasset "easyprivacy")
''; # (getUasset "urlhaus-1") #< TODO: i think this is the same as urlhaus-filter-online
(getUasset "urlhaus-filter-online")
# (getUasset "plowe-0") #< TODO: where does this come from?
# (getUasset "ublock-cookies-adguard") #< TODO: where does this come from?
# filters i've added:
(getUasset "easylist-annoyances") #< blocks in-page popups, "social media content" (e.g. FB like button; improves loading time)
(getUasset "easylist-cookies") #< blocks GDPR cookie consent popovers (e.g. at stackoverflow.com)
# (getUasset "ublock-annoyances-others")
# (getUasset "ublock-annoyances-cookies")
];
};
# TODO: this is better suited in `extraPrefs` during `wrapFirefox` call # TODO: this is better suited in `extraPrefs` during `wrapFirefox` call
fs."${cfg.browser.dotDir}/${cfg.browser.libName}.overrides.cfg".symlink.text = '' fs."${cfg.browser.dotDir}/${cfg.browser.libName}.overrides.cfg".symlink.text = ''
// if we can't query the revocation status of a SSL cert because the issuer is offline, // if we can't query the revocation status of a SSL cert because the issuer is offline,
@@ -327,6 +338,8 @@ in
defaultPref("widget.use-xdg-desktop-portal.open-uri", 1); defaultPref("widget.use-xdg-desktop-portal.open-uri", 1);
defaultPref("browser.toolbars.bookmarks.visibility", "never"); defaultPref("browser.toolbars.bookmarks.visibility", "never");
// configure which extensions are visible by default (TODO: requires a lot of trial and error)
// defaultPref("browser.uiCustomization.state", ...);
// auto-open mpv:// URIs without prompting. // auto-open mpv:// URIs without prompting.
// can do this with other protocols too (e.g. matrix?). see about:config for common handlers. // can do this with other protocols too (e.g. matrix?). see about:config for common handlers.

View File

@@ -16,13 +16,11 @@ let
# - 󰍦 (message bubble) # - 󰍦 (message bubble)
# - 󰏲 (phone) # - 󰏲 (phone)
# -  (weather/sun-behind-clouds) # -  (weather/sun-behind-clouds)
# used particularly by sxmo utilities, but also a few of my own (e.g. conky) # i use these icons mostly in conky, swaync.
# #
# nerdfonts is very heavy. each font is 20-900 MiB (2 MiB per "variation") # nerdfonts is very heavy. each font is 20-900 MiB (2 MiB per "variation")
# lots of redundant data inside there, but no deduplication except whatever nix or the fs does implicitly. # lots of redundant data inside there, but no deduplication except whatever nix or the fs does implicitly.
wantedNerdfonts = [ wantedNerdfonts = [
# used explicitly by SXMO
# "DejaVuSansMono" # 25 MiB
# good terminal/coding font. grab via nerdfonts for more emoji/unicode support # good terminal/coding font. grab via nerdfonts for more emoji/unicode support
"Hack" # 26 MiB "Hack" # 26 MiB
"Noto" # 861 MiB "Noto" # 861 MiB

View File

@@ -0,0 +1,9 @@
{ pkgs, ... }:
{
sane.programs.free = {
packageUnwrapped = pkgs.linkIntoOwnPackage pkgs.procps "bin/free";
sandbox.method = "bwrap";
sandbox.isolatePids = false;
};
}

View File

@@ -50,7 +50,7 @@ in
sane.programs.go2tv = { sane.programs.go2tv = {
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.net = "clearnet"; sandbox.net = "clearnet";
sandbox.autodetectCliPaths = true; sandbox.autodetectCliPaths = "existingFile";
# for GUI invocation, allow the common media directories # for GUI invocation, allow the common media directories
sandbox.extraHomePaths = [ sandbox.extraHomePaths = [
"Music" "Music"

View File

@@ -17,7 +17,7 @@
# disable expensive sambda dependency; i don't use it. # disable expensive sambda dependency; i don't use it.
packageUnwrapped = pkgs.handbrake.override { packageUnwrapped = pkgs.handbrake.override {
ffmpeg-full = pkgs.ffmpeg-full.override { ffmpeg_7-full = pkgs.ffmpeg_7-full.override {
withSamba = false; withSamba = false;
}; };
}; };

View File

@@ -8,7 +8,7 @@
packageUnwrapped = pkgs.libreoffice-fresh; packageUnwrapped = pkgs.libreoffice-fresh;
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.whitelistWayland = true; sandbox.whitelistWayland = true;
sandbox.autodetectCliPaths = true; sandbox.autodetectCliPaths = "existingFile";
sandbox.extraHomePaths = [ sandbox.extraHomePaths = [
# allow a spot to save files. # allow a spot to save files.
# with bwrap sandboxing, saving to e.g. ~/ succeeds but the data is inaccessible outside the sandbox, # with bwrap sandboxing, saving to e.g. ~/ succeeds but the data is inaccessible outside the sandbox,

View File

@@ -52,11 +52,9 @@
sandbox.extraRuntimePaths = [ sandbox.extraRuntimePaths = [
"dconf" #< else it's very spammy, and slow "dconf" #< else it's very spammy, and slow
]; ];
sandbox.extraConfig = [
# XXX(2024/04/21): without this it fails to convert .dng -> .jpg. # XXX(2024/04/21): without this it fails to convert .dng -> .jpg.
# "bwrap: open /proc/34/ns/ns failed: No such file or directory" # "bwrap: open /proc/34/ns/ns failed: No such file or directory"
"--sanebox-keep-namespace" "pid" sandbox.isolatePids = false;
];
suggestedPrograms = [ "dconf" ]; #< not sure if necessary suggestedPrograms = [ "dconf" ]; #< not sure if necessary
}; };

View File

@@ -0,0 +1,12 @@
{ pkgs, ... }:
{
sane.programs.mmcli = {
packageUnwrapped = pkgs.modemmanager-split.mmcli.overrideAttrs (upstream: {
meta = upstream.meta // {
mainProgram = "mmcli";
};
});
# TODO: sandbox
};
}

View File

@@ -1,38 +0,0 @@
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.modemmanager;
in
{
sane.programs.modemmanager = {
# mmcli needs /run/current-system/sw/share/dbus-1 files to function
enableFor.system = lib.mkIf (builtins.any (en: en) (builtins.attrValues cfg.enableFor.user)) true;
};
systemd.services.ModemManager = lib.mkIf cfg.enabled {
aliases = [ "dbus-org.freedesktop.ModemManager1.service" ];
after = [ "polkit.service" ];
requires = [ "polkit.service" ];
wantedBy = [ "network.target" ];
serviceConfig = {
Type = "dbus";
BusName = "org.freedesktop.ModemManager1";
# only if started with `--debug` does mmcli let us issue AT commands like
# `mmcli --modem any --command=<AT_CMD>`
ExecStart = "${cfg.package}/bin/ModemManager --debug";
# --debug sets DEBUG level logging: so reset
ExecStartPost = "${cfg.package}/bin/mmcli --set-logging=INFO";
Restart = "on-abort";
StandardError = "null";
CapabilityBoundingSet = "CAP_SYS_ADMIN CAP_NET_ADMIN";
ProtectSystem = true;
ProtectHome = true;
PrivateTmp = true;
RestrictAddressFamilies = "AF_NETLINK AF_UNIX AF_QIPCRTR";
NoNewPrivileges = true;
};
};
# so that ModemManager can discover when the modem appears
services.udev.packages = lib.mkIf cfg.enabled [ cfg.package ];
}

View File

@@ -135,27 +135,16 @@ let
'cycle_key = "c"' 'cycle_key = "v"' 'cycle_key = "c"' 'cycle_key = "v"'
''; '';
}); });
mpv-unwrapped = pkgs.mpv-unwrapped.overrideAttrs (upstream: {
version = "0.37.0-unstable-2024-03-31";
src = lib.warnIf (lib.versionOlder "0.37.0" upstream.version) "mpv outdated; remove patch?" pkgs.fetchFromGitHub {
owner = "mpv-player";
repo = "mpv";
rev = "4ce4bf1795e6dfd6f1ddf07fb348ce5d191ab1dc";
hash = "sha256-nOGuHq7SWDAygROV7qHtezDv1AsMpseImI8TVd3F+Oc=";
};
patches = [];
});
in in
{ {
sane.programs.mpv = { sane.programs.mpv = {
packageUnwrapped = pkgs.wrapMpv packageUnwrapped = pkgs.mpv-unwrapped.wrapper {
(mpv-unwrapped.override rec { mpv = pkgs.mpv-unwrapped.override rec {
# N.B.: populating `self` to `luajit` is necessary for the resulting `lua.withPackages` function to preserve my override. # N.B.: populating `self` to `luajit` is necessary for the resulting `lua.withPackages` function to preserve my override.
# i use enable52Compat in order to get `table.unpack`. # i use enable52Compat in order to get `table.unpack`.
# i think using `luajit` here instead of `lua` is optional, just i get better perf with it :) # i think using `luajit` here instead of `lua` is optional, just i get better perf with it :)
lua = pkgs.luajit.override { enable52Compat = true; self = lua; }; lua = pkgs.luajit.override { enable52Compat = true; self = lua; };
}) };
{
scripts = [ scripts = [
pkgs.mpvScripts.mpris pkgs.mpvScripts.mpris
pkgs.mpvScripts.mpv-playlistmanager pkgs.mpvScripts.mpv-playlistmanager
@@ -203,7 +192,7 @@ in
]; ];
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.autodetectCliPaths = true; sandbox.autodetectCliPaths = "parent"; #< especially for subtitle downloader; also nice for viewing albums
sandbox.net = "all"; sandbox.net = "all";
sandbox.whitelistAudio = true; sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ]; #< mpris sandbox.whitelistDbus = [ "user" ]; #< mpris

View File

@@ -4,7 +4,7 @@
# - properties: <https://mpv.io/manual/master/#property-list> # - properties: <https://mpv.io/manual/master/#property-list>
# let volume/power keys be interpreted by the system. # let volume/power keys be interpreted by the system.
# this is important for sxmo. # this is important for moby/bonsai.
# mpv defaults is POWER = close, VOLUME_{UP,DOWN} = adjust application-level volume # mpv defaults is POWER = close, VOLUME_{UP,DOWN} = adjust application-level volume
POWER ignore POWER ignore
VOLUME_UP ignore VOLUME_UP ignore

View File

@@ -10,9 +10,9 @@
]); ]);
})); }));
suggestedPrograms = [ # suggestedPrograms = [
"gvfs" # browse ftp://, etc # "gvfs" # browse ftp://, etc (TODO: fix!)
]; # ];
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.whitelistDbus = [ "user" ]; # for portals launching apps sandbox.whitelistDbus = [ "user" ]; # for portals launching apps
@@ -36,11 +36,11 @@
"/tmp" "/tmp"
"/var" "/var"
]; ];
sandbox.extraRuntimePaths = [ # sandbox.extraRuntimePaths = [
# not sure if these are actually necessary # # not sure if these are actually necessary
"gvfs" # "gvfs"
"gvfsd" # "gvfsd"
]; # ];
mime.priority = 150; #< default is 100, so higher means we fall-back to other apps that might be more specialized mime.priority = 150; #< default is 100, so higher means we fall-back to other apps that might be more specialized
mime.associations = { mime.associations = {

View File

@@ -14,7 +14,8 @@ let
# docs: https://github.com/nvim-treesitter/nvim-treesitter # docs: https://github.com/nvim-treesitter/nvim-treesitter
# config taken from: https://github.com/i077/system/blob/master/modules/home/neovim/default.nix # config taken from: https://github.com/i077/system/blob/master/modules/home/neovim/default.nix
# this is required for tree-sitter to even highlight # this is required for tree-sitter to even highlight
plugin = nvim-treesitter.withPlugins (_: nvim-treesitter.allGrammars ++ [ # XXX(2024/06/03): `unison` removed because it doesn't cross compile
plugin = nvim-treesitter.withPlugins (_: (lib.filter (p: p.pname != "unison-grammar") nvim-treesitter.allGrammars) ++ [
# XXX: this is apparently not enough to enable syntax highlighting! # XXX: this is apparently not enough to enable syntax highlighting!
# nvim-treesitter ships its own queries which may be distinct from e.g. helix. # nvim-treesitter ships its own queries which may be distinct from e.g. helix.
# the queries aren't included when i ship the grammar in this manner # the queries aren't included when i ship the grammar in this manner
@@ -167,9 +168,27 @@ in
vim.mpack.decode = vim.mpack.unpack vim.mpack.decode = vim.mpack.unpack
vim.lpeg = require 'lpeg' vim.lpeg = require 'lpeg'
" "
'' + lib.optionalString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform) '' ''
substituteInPlace runtime/CMakeLists.txt --replace-fail \ # + lib.optionalString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
'COMMAND $<TARGET_FILE:nvim_bin>' 'COMMAND ${pkgs.stdenv.hostPlatform.emulator pkgs.buildPackages} $<TARGET_FILE:nvim_bin>' # # required for x86_64 -> aarch64 (and probably armv7l too)
# substituteInPlace runtime/CMakeLists.txt --replace-fail \
# 'COMMAND $<TARGET_FILE:nvim_bin>' 'COMMAND ${pkgs.stdenv.hostPlatform.emulator pkgs.buildPackages} $<TARGET_FILE:nvim_bin>'
# ''
+ ''
# disable translations and syntax highlighting of .vim files because they don't cross x86_64 -> armv7l
substituteInPlace src/nvim/CMakeLists.txt --replace-fail \
'add_subdirectory(po)' '# add_subdirectory(po)'
# substituteInPlace src/nvim/po/CMakeLists.txt --replace-fail \
# 'add_dependencies(nvim nvim_translations)' '# add_dependencies(nvim nvim_translations)'
substituteInPlace runtime/CMakeLists.txt \
--replace-fail ' ''${GENERATED_SYN_VIM}' ' # ''${GENERATED_SYN_VIM}' \
--replace-fail ' ''${GENERATED_HELP_TAGS}' ' # ''${GENERATED_HELP_TAGS}' \
--replace-fail 'FILES ''${GENERATED_HELP_TAGS} ''${BUILDDOCFILES}' 'FILES ''${CMAKE_CURRENT_SOURCE_DIR}/nvim.desktop' \
--replace-fail 'FILES ''${GENERATED_SYN_VIM}' 'FILES ''${CMAKE_CURRENT_SOURCE_DIR}/nvim.desktop' \
--replace-fail 'if(''${PACKNAME}_DOC_FILES)' 'if(false)'
# --replace-fail ' ''${GENERATED_PACKAGE_TAGS}' ' # ''${GENERATED_PACKAGE_TAGS}' \
# --replace-fail 'list(APPEND BUILDDOCFILES' '# list(APPEND BUILDDOCFILES'
# --replace-fail ' FILES ''${GENERATED_HELP_TAGS} ' ' FILES ' \
''; '';
}); });
in pkgs.wrapNeovimUnstable in pkgs.wrapNeovimUnstable

View File

@@ -1,107 +0,0 @@
# Network Manager:
# i manage this myself because the nixos service is not flexible enough.
# - it unconditionally puts modemmanager onto the system path, preventing me from patching modemmanager's service file (without an overlay).
#
# XXX: it's normal to see error messages on an ethernet-only host, even when using nixos' official networkmanager service:
# - `Couldn't initialize supplicant interface: Failed to D-Bus activate wpa_supplicant service`
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.networkmanager;
in
{
sane.programs.networkmanager = {
suggestedPrograms = [ "wpa_supplicant" ];
enableFor.system = lib.mkIf (builtins.any (en: en) (builtins.attrValues cfg.enableFor.user)) true;
};
# add to systemd.packages so we get the service file it ships, then override what we need to customize (taken from nixpkgs)
systemd.packages = lib.mkIf cfg.enabled [ cfg.package ];
systemd.services.NetworkManager = lib.mkIf cfg.enabled {
wantedBy = [ "network.target" ];
aliases = [ "dbus-org.freedesktop.NetworkManager.service" ];
serviceConfig = {
StateDirectory = "NetworkManager";
StateDirectoryMode = 755; # not sure if this really needs to be 755
};
};
systemd.services.NetworkManager-wait-online = lib.mkIf cfg.enabled {
wantedBy = [ "network-online.target" ];
};
systemd.services.NetworkManager-dispatcher = lib.mkIf cfg.enabled {
wantedBy = [ "NetworkManager.service" ];
# to debug, add NM_DISPATCHER_DEBUG_LOG=1
serviceConfig.ExecStart = [
"" # first blank line is to clear the upstream `ExecStart` field.
"${cfg.package}/libexec/nm-dispatcher --persist" # --persist is needed for it to actually run as a daemon
];
serviceConfig.Restart = "always";
serviceConfig.RestartSec = "1s";
};
environment.etc = lib.mkIf cfg.enabled {
"NetworkManager/system-connections".source = "/var/lib/NetworkManager/system-connections";
"NetworkManager/NetworkManager.conf".text = ''
[device]
# wifi.backend: wpa_supplicant or iwd
wifi.backend=wpa_supplicant
wifi.scan-rand-mac-address=true
[logging]
audit=false
# level: TRACE, DEBUG, INFO, WARN, ERR, OFF
level=INFO
# domain=...
[main]
# dhcp:
# - `internal` (default)
# - `dhclient` (requires dhclient to be installed)
# - `dhcpcd` (requires dhcpcd to be installed)
dhcp=internal
# dns:
# - `default`: update /etc/resolv.conf with nameservers provided by the active connection
# - `none`: NM won't update /etc/resolv.conf
# - `systemd-resolved`: push DNS config to systemd-resolved
# - `dnsmasq`: run a local caching nameserver
dns=${if config.services.resolved.enable then
"systemd-resolved"
else if config.sane.services.trust-dns.enable && config.sane.services.trust-dns.asSystemResolver then
"none"
else
"internal"
}
plugins=keyfile
# rc-manager: how NM should write to /etc/resolv.conf
# - regardless of this setting, NM will write /var/lib/NetworkManager/resolv.conf
rc-manager=unmanaged
# systemd-resolved: send DNS config to systemd-resolved?
# this setting has no effect if dns="systemd-resolved"; it's supplementary, not absolute.
systemd-resolved=false
# debug=... (see also: NM_DEBUG env var)
'';
};
hardware.wirelessRegulatoryDatabase = lib.mkIf cfg.enabled true;
networking.useDHCP = lib.mkIf cfg.enabled false;
users.groups = lib.mkIf cfg.enabled {
networkmanager.gid = config.ids.gids.networkmanager;
};
services.udev.packages = lib.mkIf cfg.enabled [ cfg.package ];
security.polkit.enable = lib.mkIf cfg.enabled true;
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {
if (
subject.isInGroup("networkmanager")
&& (action.id.indexOf("org.freedesktop.NetworkManager.") == 0
|| action.id.indexOf("org.freedesktop.ModemManager") == 0
))
{ return polkit.Result.YES; }
});
'';
boot.kernelModules = [ "ctr" ]; #< TODO: needed (what even is this)?
# TODO: polkit?
# TODO: NetworkManager-ensure-profiles?
}

View File

@@ -0,0 +1,7 @@
{ pkgs, ... }:
{
sane.programs.nmcli = {
packageUnwrapped = pkgs.networkmanager-split.nmcli;
# TODO: sandbox
};
}

View File

@@ -3,7 +3,8 @@
sane.programs.notejot = { sane.programs.notejot = {
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.whitelistWayland = true; sandbox.whitelistWayland = true;
sandbox.extraPaths = [ ".config/dconf" ]; #< for legacy notes (moby), loaded via dconf sandbox.whitelistDri = true; #< otherwise intolerably slow on moby
sandbox.extraHomePaths = [ ".config/dconf" ]; #< for legacy notes (moby), loaded via dconf
suggestedPrograms = [ "dconf" ]; #< else it can't persist notes suggestedPrograms = [ "dconf" ]; #< else it can't persist notes
persist.byStore.private = [ persist.byStore.private = [

View File

@@ -0,0 +1,159 @@
# TODO:
# - try this PR to get custom workspace names to work:
# - <https://github.com/nwg-piotr/nwg-panel/pull/191>
# - add network/bluetooth indicator
# - <https://github.com/nwg-piotr/nwg-panel/issues/269>
# - add CPU/meminfo executor
# - use sane-sysinfo
{
components,
height,
playerctlChars,
windowIcon,
windowTitle,
workspaceHideEmpty,
workspaceNumbers,
}:
[
{
controls = "right";
css-name = "panel-top";
exclusive-zone = true;
height = height;
homogeneous = false; #< homogenous=false means to not force modules-{left,center,right} to an inflexible 33%/33%/33% real-estate split.
icons = "light";
items-padding = 0;
layer = "bottom";
margin-bottom = 0;
margin-top = 0;
menu-start = "off";
name = "panel-top";
# output = "All" => display the bar on every output.
# - documented: <https://github.com/nwg-piotr/nwg-panel/issues/48>
# alternatively, i could declare one bar per display,
# and then customize it so that the external display(s) render a less noisy bar.
# this will be easier once this is addressed: <https://github.com/nwg-piotr/nwg-panel/issues/215>
output = "All";
padding-horizontal = 0;
padding-vertical = 0;
position = "top";
sigrt = 64;
spacing = 0;
start-hidden = false;
use-sigrt = false;
width = "auto";
modules-left = [
"sway-workspaces"
];
modules-center = [
"clock"
];
modules-right = [
"playerctl"
];
clock = {
angle = 0.0;
calendar-css-name = "calendar-window";
calendar-icon-size = 24;
calendar-interval = 60;
calendar-margin-horizontal = 0;
calendar-margin-vertical = 0;
calendar-on = true;
calendar-path = "";
calendar-placement = "top";
css-name = "clock";
format = "%H:%M";
interval = 30;
on-left-click = "";
on-middle-click = "";
on-right-click = "";
on-scroll-down = "";
on-scroll-up = "";
root-css-name = "root-clock";
tooltip-date-format = true;
tooltip-text = "%a; %d %b %H:%M:%S";
};
controls-settings = {
battery-low-interval = 4; #< notify every N minutes when battery continues to remain low
battery-low-level = 15; #< notify if battery is lower than this percent
# commands.battery = ""; #< optional action to perform when battery icon is clicked in the drop-down menu
components = components;
click-closes = false;
custom-items = [];
css-name = "controls-window";
hover-opens = false;
icon-size = 16;
interval = 1;
leave-closes = false;
menu.icon = "system-shutdown-symbolic";
menu.items = [
{
# TODO: plumb through the configured locker instead of assuming `swaylock`
name = "Lock";
cmd = "swaylock -f -c 000000";
}
{
name = "Logout";
cmd = "swaymsg exit";
}
{
name = "Reboot";
cmd = "systemctl reboot";
}
{
name = "Shutdown";
cmd = "systemctl -i poweroff";
}
];
menu.name = "Exit";
output-switcher = true; #< allow changing the default audio sink
#v `show-<x>` means "show the NUMERICAL VALUE corresponding to <x>"
# e.g. show-battery means "show the battery _percentage_ next to its icon".
show-battery = true;
show-brightness = false;
show-values = false;
show-volume = false;
# window-width: should be 360 for moby, but because of weird `margin` tweaks in style.css
# we have to add 20px to both sides
window-width = 400;
};
playerctl = {
button-css-name = "playerctl-button";
buttons-position = "left";
chars = playerctlChars;
icon-size = 16;
interval = 2;
label-css-name = "playerctl-label";
scroll = false;
};
sway-workspaces = {
angle = 0.0;
custom-labels = [];
focused-labels = [];
hide-empty = workspaceHideEmpty;
image-size = 16;
mark-autotiling = true;
mark-content = false;
name-length = 40;
numbers = workspaceNumbers;
show-icon = windowIcon;
show-layout = false;
show-name = windowTitle;
};
# unused modules:
brightness-slider = {};
dwl-tags = {};
hyprland-taskbar = {};
hyprland-workspaces = {};
keyboard-layout = {};
openweather = {};
scratchpad = {};
sway-mode = {};
sway-taskbar = {}; #< windows-style taskbar, usually placed at the bottom of the screen, to show open windows & tab to them on click
tray = {};
}
]

View File

@@ -0,0 +1,132 @@
# nwg-panel: a wayland status bar (like waybar, etc)
# documentation is in the GitHub Wiki:
# - <https://github.com/nwg-piotr/nwg-panel/wiki/Configuration>
#
# interactively configure with: `nwg-panel-config`
# ^ note that this may interfere with the `nwg-panel` service
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.nwg-panel;
mkEnableOption' = default: description: lib.mkOption {
type = lib.types.bool;
inherit default description;
};
in
{
sane.programs.nwg-panel = {
configOption = with lib; mkOption {
default = {};
type = types.submodule {
options = {
clockFontSize = mkOption {
type = types.int;
# what looks good:
# - 15px on moby
# - 24px on lappy
default = lib.min 24 (cfg.config.fontSize - 1);
};
fontSize = mkOption {
type = types.int;
default = 16;
};
height = mkOption {
type = types.int;
default = 40;
description = ''
height of the top bar in px.
'';
};
battery = mkEnableOption' true "display battery status";
brightness = mkEnableOption' true "display backlight level and slider";
mediaTitle = mkEnableOption' true "display title of current song/media";
mediaPrevNext = mkEnableOption' true "display prev/next button in media";
windowIcon = mkEnableOption' true "display icon of active window";
windowTitle = mkEnableOption' true "display title of active window";
workspaceNumbers = mkOption {
type = types.listOf types.str;
default = [
# TODO: workspace 10 should be rendered as "TV"
"1" "2" "3" "4" "5" "6" "7" "8" "9" "10"
];
description = ''
workspaces to monitor
'';
};
workspaceHideEmpty = mkOption {
type = types.bool;
default = true;
};
};
};
};
packageUnwrapped = (pkgs.nwg-panel.override {
# XXX(2024/06/13): hyprland does not cross compile
hyprland = null;
# XXX(2024/06/13): wlr-randr does not cross compile
wlr-randr = null; #< only used if not on sway/hyprland; or if using dwl
}).overrideAttrs (base: {
patches = (base.patches or []) ++ lib.optionals (!cfg.config.mediaPrevNext) [
./playerctl-no-prev-next.diff
];
# - disable the drop-down chevron by the controls.
# it's precious space on moby, doesn't do much to help on lappy either.
# - disable brightness indicator for same reason.
# - *leave* the volume indicator: one *could* remove it, however on desko that would leave the controls pane empty
# making the dropdown inaccessible
postPatch = (base.postPatch or "") + ''
substituteInPlace nwg_panel/modules/controls.py --replace-fail \
'box.pack_start(self.pan_image, False, False, 4)' \
'# box.pack_start(self.pan_image, False, False, 4)'
substituteInPlace nwg_panel/modules/controls.py --replace-fail \
'box.pack_start(self.bri_image, False, False, 4)' \
'# box.pack_start(self.bri_image, False, False, 4)'
# substituteInPlace nwg_panel/modules/controls.py --replace-fail \
# 'box.pack_start(self.vol_image, False, False, 4)' \
# '# box.pack_start(self.vol_image, False, False, 4)'
'';
# XXX(2024/06/13) the bluetooth stuff doesn't cross compile, so disable it
propagatedBuildInputs = lib.filter (p: p.pname != "pybluez") base.propagatedBuildInputs;
strictDeps = true;
});
suggestedPrograms = [
"pactl" # pactl required by `per-app-volume` component.
];
fs.".config/nwg-panel/style.css".symlink.target = pkgs.substituteAll {
src = ./style.css;
inherit (cfg.config) fontSize clockFontSize;
};
fs.".config/nwg-panel/config".symlink.target = pkgs.writers.writeJSON "config" (import ./config.nix {
inherit (cfg.config) height windowIcon windowTitle workspaceHideEmpty workspaceNumbers;
# component order matters, mostly for the drop-down.
# default for most tools (e.g. swaync) is brightness control above volume.
components =
lib.optionals cfg.config.brightness [
"brightness"
] ++ [
"volume"
"per-app-volume"
] ++ lib.optionals cfg.config.battery [
"battery"
]
;
playerctlChars = if cfg.config.mediaTitle then 60 else 0;
});
services.nwg-panel = {
description = "nwg-panel status/topbar for wayland";
partOf = [ "graphical-session" ];
# to debug styling, run with GTK_DEBUG=interactive
# N.B.: G_MESSAGES_DEBUG=all causes the swaync icon to not render
# command = "env G_MESSAGES_DEBUG=all nwg-panel";
command = "nwg-panel";
};
};
}

View File

@@ -0,0 +1,36 @@
diff --git a/nwg_panel/modules/playerctl.py b/nwg_panel/modules/playerctl.py
index 9b53b4b..c4d96ae 100644
--- a/nwg_panel/modules/playerctl.py
+++ b/nwg_panel/modules/playerctl.py
@@ -180,15 +180,6 @@ class Playerctl(Gtk.EventBox):
if self.settings["angle"] != 0.0:
button_box.set_orientation(Gtk.Orientation.VERTICAL)
- img = Gtk.Image()
- update_image(img, "media-skip-backward-symbolic", self.settings["icon-size"], icons_path=self.icons_path)
- btn = Gtk.Button()
- btn.set_image(img)
- if self.settings["button-css-name"]:
- btn.set_property("name", self.settings["button-css-name"])
- btn.connect("clicked", self.launch, self.PlayerOps.PREVIOUS)
- button_box.pack_start(btn, False, False, 1)
-
self.play_pause_btn = Gtk.Button()
if self.settings["button-css-name"]:
self.play_pause_btn.set_property("name", self.settings["button-css-name"])
@@ -198,15 +189,6 @@ class Playerctl(Gtk.EventBox):
self.play_pause_btn.connect("clicked", self.launch, self.PlayerOps.PLAY_PAUSE)
button_box.pack_start(self.play_pause_btn, False, False, 1)
- img = Gtk.Image()
- update_image(img, "media-skip-forward-symbolic", self.settings["icon-size"], icons_path=self.icons_path)
- btn = Gtk.Button()
- btn.set_image(img)
- if self.settings["button-css-name"]:
- btn.set_property("name", self.settings["button-css-name"])
- btn.connect("clicked", self.launch, self.PlayerOps.NEXT)
- button_box.pack_start(btn, False, False, 1)
-
self.label = AutoScrollLabel(self.settings["scroll"],
self.settings["chars"],
self.settings["interval"])

View File

@@ -0,0 +1,215 @@
/* foreground (text)/background */
@define-color fg0 #d8d8d8;
@define-color fg1 #ffffff;
@define-color bg0 #130c0c;
@define-color bg1 #1c1716;
/* green accents */
@define-color accent-g0 #1f5e54;
@define-color accent-g1 #418379;
@define-color accent-g2 #63a89c;
/* red accents */
@define-color accent-r0 #c96262;
@define-color accent-r1 #d27871;
@define-color accent-r2 #ff968b;
/* light (teal-white) accents */
@define-color accent-l0 #e1f0ef;
@define-color accent-l1 #f9fffc;
* {
font-size: @fontSize@px;
}
button {
margin: 2px;
}
#task-box {
padding-left: 4px;
padding-right: 4px;
}
#task-box-focused {
background-color: @accent-g2;
padding-left: 4px;
padding-right: 4px;
}
#playerctl-button {
background-color: rgba(0, 0, 0, 0.08);
background-image: none;
border: none;
box-shadow: none;
margin: -1;
outline: none;
}
#panel-top {
background: @accent-g1;
color: @fg1;
}
/* increase the size of each workspace icon */
#sway-workspaces-item > label {
padding-left: 1px;
padding-right: 1px;
}
/* default config highlights hovered workspace with a gray border */
#sway-workspaces > widget:selected {
box-shadow: none;
}
/* the CSS nodes are difficult to determine.
* reference: <https://github.com/numixproject/numix-gtk-theme/blob/master/src/gtk-3.20/scss/widgets/_calendar.scss>
*/
#calendar-window {
background-color: @accent-l0;
}
calendar {
background-color: @accent-l0;
}
calendar :selected {
background-color: @accent-r1;
}
#controls-window {
border-radius: 15px;
background: @bg1;
color: @fg1;
}
/* default config highlights selected items with a green border */
widget:selected {
box-shadow: none;
background-color: @accent-g0;
}
#controls-window widget:selected {
box-shadow: none;
background-color: @accent-r0;
}
/* default config puts a *ridiculous* amount of padding around the whole controls window */
#controls-window > widget > .vertical {
margin-left: -20px;
margin-right: -20px;
}
#controls-window > widget > .vertical > .horizontal {
margin-top: -14px; /* full reset would be -20px */
margin-bottom: -20px;
}
/* add back in a little bit of padding, but in a way such that my highlights apply to it */
#controls-window .horizontal widget > box,
#controls-window > widget > .vertical > .horizontal > .vertical > .horizontal
{
padding-left: 12px;
padding-right: 12px;
}
#controls-window > widget > .vertical > .horizontal > .vertical > widget > box
{
padding-top: 6px;
padding-bottom: 6px;
}
#controls-window > widget > .vertical > .horizontal > .vertical > box > widget > box
{
padding-top: 3px;
padding-bottom: 3px;
}
/* hierarchy is .horizontal > {image, scale > { value, contents > trough > { slider, highlight } } } */
scale {
padding-right: 0px;
padding-top: 0px;
padding-bottom: 0px;
}
scale trough {
padding-left: 9px;
padding-right: 9px;
border-radius: 9px;
border-color: rgba(0, 0, 0, 0);
background: @bg0;
}
scale highlight {
border-radius: 9px;
border-color: rgba(0, 0, 0, 0);
margin: 0px;
margin-left: -9px;
background: @accent-r1;
}
scale slider {
margin-top: -3px;
margin-bottom: -3px;
background: @accent-l1;
min-height: 25px;
min-width: 25px;
}
#clock {
font-family: monospace;
font-size: @clockFontSize@px;
}
/* UNUSED IN MY CURRENT CONFIG: COPIED FROM SAMPLE CONFIG */
/* Controls window in sample config uses this name */
/* Brightness slider popup window in sample config uses this name */
#brightness-popup {
border-radius: 15px;
background: @bg1;
color: @fg1;
}
#brightness-popup box {
padding: 15px;
}
/* Executors usually behave better in monospace fonts */
#executor-label {
font-family: monospace;
}
/* Bottom panel in sample config uses this name */
#panel-bottom {
background: #101010;
color: #eeeeee;
}
/* Sample executor-weather uses "css-name": "weather" */
#weather {
font-size: 16px;
}
/* dwl-tags module */
#dwl-tag-box {
padding-top: 4px;
padding-bottom: 4px;
}
#dwl-tag-occupied {
font-family: monospace;
color: #eee;
background-color: #006699;
padding-left: 3px;
padding-right: 3px;
}
#dwl-tag-free {
font-family: monospace;
color: #eee;
background-color: rgba (32, 50, 90, 1.0);
padding-left: 3px;
padding-right: 3px;
}
#dwl-tag-urgent {
font-family: monospace;
color: #eee;
background-color: #ee6600;
padding-left: 3px;
padding-right: 3px;
}
#dwl-tag-selected {
border: solid 2px;
border-color: #81a1c1;
}

View File

@@ -0,0 +1,6 @@
{ pkgs, ... }:
{
sane.programs.pactl = {
packageUnwrapped = pkgs.linkIntoOwnPackage pkgs.pulseaudio "bin/pactl";
};
}

View File

@@ -41,6 +41,9 @@ in
}; };
}; };
# disabling systemd causes pipewire to be built with direct udev support instead
packageUnwrapped = pkgs.pipewire.override { enableSystemd = false; };
suggestedPrograms = [ suggestedPrograms = [
# "rtkit" # "rtkit"
"wireplumber" "wireplumber"
@@ -60,9 +63,7 @@ in
# "system" # "system"
# ]; # ];
sandbox.wrapperType = "inplace"; #< its config files refer to its binaries by full path sandbox.wrapperType = "inplace"; #< its config files refer to its binaries by full path
sandbox.extraConfig = [ sandbox.isolatePids = false; #< TODO: why?
"--sanebox-keep-namespace" "pid"
];
sandbox.capabilities = [ sandbox.capabilities = [
# if rtkit isn't present, and sandboxing is via landlock, these capabilities allow pipewire to claim higher scheduling priority # if rtkit isn't present, and sandboxing is via landlock, these capabilities allow pipewire to claim higher scheduling priority
"ipc_lock" "ipc_lock"
@@ -143,7 +144,7 @@ in
# ''; # '';
# see: <https://docs.pipewire.org/page_module_protocol_native.html> # see: <https://docs.pipewire.org/page_module_protocol_native.html>
# defaults to placing the socket in /run/user/$id/{pipewire-0,pipewire-0-manager,...} # defaults to placing the socket in $XDG_RUNTIME_DIR/{pipewire-0,pipewire-0-manager,...}
# but that's trickier to sandbox # but that's trickier to sandbox
env.PIPEWIRE_RUNTIME_DIR = "$XDG_RUNTIME_DIR/pipewire"; env.PIPEWIRE_RUNTIME_DIR = "$XDG_RUNTIME_DIR/pipewire";
@@ -179,6 +180,9 @@ in
]; ];
cleanupCommand = ''rm -f "$XDG_RUNTIME_DIR/pulse/{native,pid}"''; cleanupCommand = ''rm -f "$XDG_RUNTIME_DIR/pulse/{native,pid}"'';
}; };
# bring up sound by default
services."sound".partOf = [ "default" ];
}; };
# taken from nixos/modules/services/desktops/pipewire/pipewire.nix # taken from nixos/modules/services/desktops/pipewire/pipewire.nix

View File

@@ -24,11 +24,13 @@
"/tmp" "/tmp"
"/var" "/var"
]; ];
sandbox.extraRuntimePaths = [ # sandbox.extraRuntimePaths = [
# not sure if these are actually necessary # # not sure if these are actually necessary
"gvfs" # "gvfs"
"gvfsd" # "gvfsd"
]; # ];
# suggestedPrograms = [ "gvfs" ]; #< TODO: fix (ftp:// share, USB drive browsing)
mime.priority = 160; #< default is 100, so higher means we fall-back to other apps that might be more specialized mime.priority = 160; #< default is 100, so higher means we fall-back to other apps that might be more specialized
mime.associations = { mime.associations = {

View File

@@ -0,0 +1,8 @@
{ pkgs, ... }:
{
sane.programs.ps = {
packageUnwrapped = pkgs.linkIntoOwnPackage pkgs.procps "bin/ps";
sandbox.method = "bwrap";
sandbox.isolatePids = false;
};
}

View File

@@ -2,7 +2,7 @@
{ {
sane.programs.ripgrep = { sane.programs.ripgrep = {
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.autodetectCliPaths = true; sandbox.autodetectCliPaths = "existing";
sandbox.whitelistPwd = true; sandbox.whitelistPwd = true;
sandbox.extraHomePaths = [ sandbox.extraHomePaths = [
# let it follow symlinks to non-sensitive data # let it follow symlinks to non-sensitive data

View File

@@ -5,7 +5,7 @@
# - use as a launcher/file browser # - use as a launcher/file browser
# - `rofi -sidebar-mode` # - `rofi -sidebar-mode`
# - separate tabs for filebrowser, drun, etc. # - separate tabs for filebrowser, drun, etc.
# - `rofi -pid /run/user/$UID/rofi.pid -replace` # - `rofi -pid $XDG_RUNTIME_DIR/rofi.pid -replace`
# - single-instance mode # - single-instance mode
# - pid is probably optional, just need `-replace`. # - pid is probably optional, just need `-replace`.
# #
@@ -112,9 +112,7 @@ in
"/mnt/servo/media" "/mnt/servo/media"
"/mnt/servo/playground" "/mnt/servo/playground"
]; ];
sandbox.extraConfig = [ sandbox.isolatePids = false; # for sane-open to toggle keyboard
"--sanebox-keep-namespace" "pid" # for sane-open to toggle keyboard
];
fs.".config/rofi/config.rasi".symlink.target = ./config.rasi; fs.".config/rofi/config.rasi".symlink.target = ./config.rasi;
fs."Apps".symlink.target = ".local/share/applications/rofi-applications.desktop"; fs."Apps".symlink.target = ".local/share/applications/rofi-applications.desktop";
@@ -160,15 +158,15 @@ in
}) })
]; ];
}; };
# if i could remove the sed, then maybe possible to not sandbox. sandbox.enable = false; # all dependencies are sandboxed
sandbox.method = "bwrap"; # sandbox.method = "bwrap";
sandbox.whitelistWayland = true; # sandbox.whitelistWayland = true;
sandbox.extraHomePaths = [ # sandbox.extraHomePaths = [
".cache/rofi" # ".cache/rofi"
".config/rofi/config.rasi" # ".config/rofi/config.rasi"
]; # ];
suggestedPrograms = [ "rofi" ]; suggestedPrograms = [ "gnused" "rofi" "wtype" ];
fs.".config/rofi-snippets/public.txt".symlink.target = ./snippets.txt; fs.".config/rofi-snippets/public.txt".symlink.target = ./snippets.txt;
secrets.".config/rofi-snippets/private.txt" = ../../../../secrets/common/snippets.txt.bin; secrets.".config/rofi-snippets/private.txt" = ../../../../secrets/common/snippets.txt.bin;

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell #!/usr/bin/env nix-shell
#!nix-shell -i bash -p sane-open #!nix-shell -i bash -p bash -p sane-open
# use: # use:
# rofi-run-command <handler>.desktop [cmd [args ...]] # rofi-run-command <handler>.desktop [cmd [args ...]]

View File

@@ -1,10 +1,14 @@
#!/usr/bin/env nix-shell #!/usr/bin/env nix-shell
#!nix-shell -i bash -p gnused -p rofi -p wtype #!nix-shell -i bash -p bash -p gnused -p rofi -p wtype
# "bookmarking"/snippets inspired by Luke Smith: # "bookmarking"/snippets inspired by Luke Smith:
# - <https://www.youtube.com/watch?v=d_11QaTlf1I> # - <https://www.youtube.com/watch?v=d_11QaTlf1I>
snippet=$(cat ~/.config/rofi-snippets/public.txt ~/.config/rofi-snippets/private.txt | \ # rofi flags (see: `man rofi-dmenu`):
rofi -dmenu | \ # `-i`: case insensitive filtering
sed 's/ #.*$//') # `-sync -ellipsize-mode middle`: for lengthy entries, replace the *middle* with an ellipsis instead of the end
wtype "$snippet" # requires rofi 1.7.6, and `-sync`, wich must come *before* the `-dmenu` flag
cat ~/.config/rofi-snippets/public.txt ~/.config/rofi-snippets/private.txt | \
rofi -sync -ellipsize-mode middle -dmenu -i | \
sed -z -e 's/ *#.*$//' -e 's/\n$//' | \
wtype -

View File

@@ -5,7 +5,6 @@ https://nixos.org/manual/nix/stable/language/builtins.html
https://github.com/nixos/nixpkgs/pulls?q= https://github.com/nixos/nixpkgs/pulls?q=
https://nur.nix-community.org/ https://nur.nix-community.org/
https://repology.org/projects/?maintainer=colin@uninsane.org&inrepo=nix_unstable&outdated=1 https://repology.org/projects/?maintainer=colin@uninsane.org&inrepo=nix_unstable&outdated=1
https://lists.sr.ht/~mil/sxmo-devel
https://w.uninsane.org/viewer#search?books.name=wikipedia_en_all_maxi_2022-05&pattern= https://w.uninsane.org/viewer#search?books.name=wikipedia_en_all_maxi_2022-05&pattern=
https://jackett.uninsane.org/UI/Dashboard#search= https://jackett.uninsane.org/UI/Dashboard#search=
https://lemmy.uninsane.org https://lemmy.uninsane.org

View File

@@ -85,7 +85,7 @@ in
"playerctl" "playerctl"
"procps" "procps"
"sane-open" "sane-open"
"sway" # "sway" #< TODO: circular dependency :-(
"wireplumber" "wireplumber"
# optional integrations: # optional integrations:
"megapixels" "megapixels"
@@ -97,9 +97,7 @@ in
sandbox.whitelistAudio = true; sandbox.whitelistAudio = true;
sandbox.whitelistDbus = [ "user" ]; #< to launch applications sandbox.whitelistDbus = [ "user" ]; #< to launch applications
sandbox.extraRuntimePaths = [ "sway" ]; sandbox.extraRuntimePaths = [ "sway" ];
sandbox.extraConfig = [ sandbox.isolatePids = false; #< for toggling the keyboard
"--sanebox-keep-namespace" "pid"
];
}; };
# sane.programs.actkbd = { # sane.programs.actkbd = {
@@ -157,6 +155,7 @@ in
voldown_pressed.timeout = recurseHold "voldown" {}; voldown_pressed.timeout = recurseHold "voldown" {};
}); });
sane.programs.sway.sandbox.extraRuntimePaths = lib.mkIf cfg.enabled [ "bonsai" ];
sane.programs.sway.config.extra_lines = lib.mkIf cfg.enabled ( sane.programs.sway.config.extra_lines = lib.mkIf cfg.enabled (
'' ''
# bindsym --input-device=... : # bindsym --input-device=... :

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell #!/usr/bin/env nix-shell
#!nix-shell -i bash -p coreutils -p jq -p killall -p playerctl -p procps -p sane-open -p sway -p util-linux -p wireplumber #!nix-shell -i bash -p bash -p coreutils -p jq -p killall -p playerctl -p procps -p sane-open -p sway -p util-linux -p wireplumber
# vim: set filetype=bash : # vim: set filetype=bash :
# input map considerations # input map considerations
@@ -61,27 +61,62 @@ KEYBOARD="${KEYBOARD:-wvkbd-mobintl}"
action="$1" action="$1"
showHelp() {
echo "usage: sane-input-handler <action>"
echo ""
echo "where action is one of:"
echo "- power_tap_{1,2}"
echo "- power_hold"
echo "- power_tap_1_hold"
echo "- power_and_volup"
echo "- power_and_voldown"
echo "- power_then_volup"
echo "- power_then_voldown"
echo "- volup_tap_{1,2,3}"
echo "- volup_hold_{1,2,3}"
echo "- voldown_tap_{1,2,3}"
echo "- voldown_hold_{1,2,3}"
echo "- voldown_start"
}
log() { log() {
printf "sane-input-handler: %s\n" "$1" printf "sane-input-handler: %s\n" "$1"
} }
## HELPERS ## HELPERS
isTouchOn() { # swaySetOutput true|false
# turns the display on or off
swaySetOutput() {
swaymsg -- output '*' power "$1"
}
# swaySetTouch enabled|disabled
# turns touch input on or off
swaySetTouch() {
# XXX(2024/06/09): `type:touch` method is documented, but now silently fails
# swaymsg -- input type:touch events "$1"
local inputs=$(swaymsg -t get_inputs --raw | jq '. | map(select(.type == "touch")) | map(.identifier) | join(" ")' --raw-output)
for id in "${inputs[@]}"; do
swaymsg -- input "$id" events "$1"
done
}
# success if all touch inputs have their events enabled # success if all touch inputs have their events enabled
swayGetTouch() {
swaymsg -t get_inputs --raw \ swaymsg -t get_inputs --raw \
| jq --exit-status '. | map(select(.type == "touch")) | all(.libinput.send_events == "enabled")' \ | jq --exit-status '. | map(select(.type == "touch")) | all(.libinput.send_events == "enabled")' \
> /dev/null > /dev/null
} }
isScreenOn() {
# success if all outputs have power # success if all outputs have power
swayGetOutput() {
swaymsg -t get_outputs --raw \ swaymsg -t get_outputs --raw \
| jq --exit-status '. | all(.power)' \ | jq --exit-status '. | all(.power)' \
> /dev/null > /dev/null
} }
isAllOn() { isAllOn() {
isTouchOn && isScreenOn swayGetOutput && swayGetTouch
} }
isInhibited() { isInhibited() {
@@ -116,12 +151,12 @@ unmapped() {
} }
allOn() { allOn() {
swaymsg -- output '*' power true swaySetOutput true
swaymsg -- input type:touch events enabled swaySetTouch enabled
} }
allOff() { allOff() {
swaymsg -- output '*' power false swaySetOutput false
swaymsg -- input type:touch events disabled swaySetTouch disabled
} }
toggleKeyboard() { toggleKeyboard() {
@@ -242,6 +277,7 @@ dispatchInhibited() {
esac esac
} }
dispatchToplevel() {
_isAllOn="$(isAllOn && echo 1 || true)" _isAllOn="$(isAllOn && echo 1 || true)"
if [ -z "$_isAllOn" ]; then if [ -z "$_isAllOn" ]; then
@@ -256,5 +292,16 @@ else
fi fi
dispatchDefault dispatchDefault
}
case "$action" in
(--help)
showHelp
exit 0
;;
(*)
dispatchToplevel
handleWith unmapped handleWith unmapped
;;
esac

View File

@@ -4,13 +4,11 @@
sandbox.method = "bwrap"; sandbox.method = "bwrap";
sandbox.autodetectCliPaths = "existing"; # for when opening a file sandbox.autodetectCliPaths = "existing"; # for when opening a file
sandbox.whitelistDbus = [ "user" ]; sandbox.whitelistDbus = [ "user" ];
sandbox.extraConfig = [ sandbox.isolatePids = false; #< to toggle keyboard
"--sanebox-keep-namespace" "pid" # to toggle keyboard
];
sandbox.extraHomePaths = [ sandbox.extraHomePaths = [
".local/share/applications" ".local/share/applications"
]; ];
sandbox.extraRuntimePaths = [ "sway" ]; sandbox.extraRuntimePaths = [ "sway" ]; #< calls `swaymsg` to query rotation and see if there's room for a keyboard
suggestedPrograms = [ suggestedPrograms = [
"gdbus" "gdbus"
"xdg-utils" "xdg-utils"

View File

@@ -229,7 +229,6 @@ in
fwmark=${builtins.toString vpnCfg.fwmark} fwmark=${builtins.toString vpnCfg.fwmark}
priorityMain=${builtins.toString vpnCfg.priorityMain} priorityMain=${builtins.toString vpnCfg.priorityMain}
priorityFwMark=${builtins.toString vpnCfg.priorityFwMark} priorityFwMark=${builtins.toString vpnCfg.priorityFwMark}
bridgeDevice=${vpnCfg.bridgeDevice}
addrV4=${vpnCfg.addrV4} addrV4=${vpnCfg.addrV4}
name=${vpnCfg.name} name=${vpnCfg.name}
dns=(${lib.concatStringsSep " " vpnCfg.dns}) dns=(${lib.concatStringsSep " " vpnCfg.dns})
@@ -248,13 +247,7 @@ in
# extraHomePaths = [ ".config/sane-vpn" ]; # extraHomePaths = [ ".config/sane-vpn" ];
}; };
"sane-scripts.which".sandbox = { "sane-scripts.which".sandbox.method = "bwrap";
method = "bwrap";
extraHomePaths = [
# for SXMO
".config/sxmo/hooks"
];
};
"sane-scripts.wipe".sandbox = { "sane-scripts.wipe".sandbox = {
method = "bwrap"; method = "bwrap";

View File

@@ -0,0 +1,10 @@
{ ... }:
{
sane.programs.sane-sysinfo = {
sandbox.method = "bwrap";
sandbox.extraPaths = [
"/sys/class/power_supply"
"/sys/devices"
];
};
}

View File

@@ -1,15 +1,6 @@
# gtk apps search XDG_ICON_DIRS for icons (nixos specific)
# nixos ships the hi-color icon theme by default, which has *some* icons,
# but leaves a lot of standard ones unavailable.
#
# system-wide theme components live in:
# - /run/current-system/sw/share/color-schemes/${theme}
# - /run/current-system/sw/share/icons/${theme}
# - /run/current-system/sw/share/icons/${theme}/cursors (cursor-theme)
# - /run/current-system/sw/share/themes/${theme}/gtk-4.0
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
cfg = config.sane.gui.gtk; cfg = config.sane.programs.sane-theme.config;
unsortedThemes = { unsortedThemes = {
# crude assortment of themes in nixpkgs; some might not be gtk themes, some gtk themes might not be in this list # crude assortment of themes in nixpkgs; some might not be gtk themes, some gtk themes might not be in this list
inherit (pkgs) inherit (pkgs)
@@ -278,38 +269,62 @@ let
}; };
in in
{ {
options = with lib; { sane.programs.sane-theme = {
sane.gui.gtk.enable = mkOption { configOption = with lib; mkOption {
default = false; default = {};
type = types.bool; type = types.submodule {
description = "apply theme to gtk4 apps"; options = {
}; all = mkOption {
sane.gui.gtk.all = mkOption {
default = false; default = false;
type = types.bool; type = types.bool;
description = "install all known gtk themes (for testing)"; description = "install all known gtk themes (for testing)";
}; };
sane.gui.gtk.color-scheme = mkOption { color-scheme = mkOption {
default = "default"; default = "default";
type = types.str; type = types.str;
}; };
sane.gui.gtk.cursor-theme = mkOption { cursor-theme = mkOption {
default = "Adwaita"; default = "Adwaita";
type = types.str; type = types.str;
}; };
sane.gui.gtk.gtk-theme = mkOption { gtk-theme = mkOption {
default = "Adwaita"; default = "Adwaita";
type = types.str; type = types.str;
}; };
sane.gui.gtk.icon-theme = mkOption { icon-theme = mkOption {
default = "Adwaita"; default = "Adwaita";
type = types.str; type = types.str;
}; };
}; };
};
};
packageUnwrapped = pkgs.symlinkJoin {
name = "sane-theme";
paths = [
themes.color-scheme."${cfg.color-scheme}"
themes.cursor-theme."${cfg.cursor-theme}"
themes.gtk-theme."${cfg.gtk-theme}"
themes.icon-theme."${cfg.icon-theme}"
] ++ lib.optionals cfg.all (lib.attrValues unsortedThemes);
};
sandbox.enable = false; #< no binaries
suggestedPrograms = [
"sane-backgrounds"
];
};
config.sane.programs.dconf.config.site = lib.mkIf cfg.enable [ sane.programs.sane-backgrounds = {
sandbox.enable = false; #< no binaries
};
environment.pathsToLink = lib.mkIf config.sane.programs.sane-backgrounds.enabled [
"/share/backgrounds"
];
sane.programs.dconf.config.site = lib.mkIf config.sane.programs.sane-theme.enabled [
(pkgs.writeTextFile { (pkgs.writeTextFile {
name = "dconf-sway-settings"; name = "sane-theme";
destination = "/etc/dconf/db/site.d/10_gtk_settings"; destination = "/etc/dconf/db/site.d/10_gtk_settings";
text = '' text = ''
[org/gnome/desktop/interface] [org/gnome/desktop/interface]
@@ -320,13 +335,6 @@ in
''; '';
}) })
]; ];
# environment.systemPackages = lib.attrValues themes;
config.environment.systemPackages = lib.mkIf cfg.enable ([
themes.color-scheme."${cfg.color-scheme}"
themes.cursor-theme."${cfg.cursor-theme}"
themes.gtk-theme."${cfg.gtk-theme}"
themes.icon-theme."${cfg.icon-theme}"
] ++ lib.optionals cfg.all (lib.attrValues unsortedThemes));
# XXX(2024/02/05): set GSK_RENDERER=cairo to solve graphical edge-case on moby where some JPEGs would render as black! # XXX(2024/02/05): set GSK_RENDERER=cairo to solve graphical edge-case on moby where some JPEGs would render as black!
# - repro by loading komikku and viewing images. some fail (particularly mangadex onimai), some work. # - repro by loading komikku and viewing images. some fail (particularly mangadex onimai), some work.
@@ -338,4 +346,5 @@ in
# - upstream gtk recommends using mesa 24.0 (latest) specifically in response to the GSK renderers triggering new driver bugs, # - upstream gtk recommends using mesa 24.0 (latest) specifically in response to the GSK renderers triggering new driver bugs,
# so maybe i can update that before re-enabling GSK_RENDERER anywhere else. # so maybe i can update that before re-enabling GSK_RENDERER anywhere else.
# environment.variables.GSK_RENDERER = "cairo"; # environment.variables.GSK_RENDERER = "cairo";
} }

View File

@@ -0,0 +1,52 @@
{ config, lib, ... }:
let
cfg = config.sane.programs.seatd;
in
lib.mkMerge [
{
sane.programs.seatd = {
sandbox.method = "bwrap";
sandbox.capabilities = [
"sys_tty_config" "sys_admin"
"chown"
"dac_override" #< TODO: is there no way to get rid of this?
];
sandbox.extraPaths = [
"/dev" #< TODO: this can be removed if i have seatd restart on client error such that seatd can discover devices as they appear
# "/dev/dri"
# # "/dev/drm_dp_aux0"
# # "/dev/drm_dp_aux1"
# # "/dev/drm_dp_aux2"
# # "/dev/fb0"
# "/dev/input"
# # "/dev/uinput"
# "/dev/tty0"
# "/dev/tty1"
# "/proc"
"/run" #< TODO: confine this to some subdirectory
# "/sys"
];
};
}
(lib.mkIf cfg.enabled {
users.groups.seat = {};
# TODO: /run/seatd.sock location can be configured, but only via compile-time flag
systemd.services.seatd = {
description = "Seat management daemon";
documentation = [ "man:seatd(1)" ];
wantedBy = [ "multi-user.target" ];
restartIfChanged = false;
path = [ "/run/current-system/sw" ]; #< so `sanebox` works
serviceConfig = {
Type = "simple";
ExecStart = "${cfg.package}/bin/seatd -g seat";
Group = "seat";
# AmbientCapabilities = [ "CAP_SYS_TTY_CONFIG" "CAP_SYS_ADMIN" ];
};
};
})
]

View File

@@ -1,6 +1,5 @@
# simple RSS and Atom parser # simple RSS and Atom parser
# - <https://codemadness.org/sfeed-simple-feed-parser.html> # - <https://codemadness.org/sfeed-simple-feed-parser.html>
# - used by sxmo
# - man 5 sfeedrc # - man 5 sfeedrc
# #
# call `sfeed_update` to query each feed and populate entries in ~/.sfeed/feeds # call `sfeed_update` to query each feed and populate entries in ~/.sfeed/feeds

View File

@@ -0,0 +1,17 @@
{ config, lib, ... }:
let
cfg = config.sane.programs.shadow;
in
{
config = lib.mkMerge [
{
sane.programs.shadow = {
sandbox.enable = false; #< `login` can't be sandboxed because it launches a user shell
};
}
(lib.mkIf cfg.enabled {
services.getty.loginProgram = "${cfg.package}/bin/login";
security.pam.services.login.startSession = lib.mkForce false; #< disable systemd integration
})
];
}

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