Compare commits

...

699 Commits

Author SHA1 Message Date
c45898f903 WIP: wg-dev 2024-01-15 04:15:17 +00:00
0efec20904 hosts/common/net/vpn: remove unused "extraOptions" argument 2024-01-15 03:52:31 +00:00
2f04b563d1 nixpkgs: 2024-01-11 -> 2024-01-14
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/06797d4df4baaa51b229081083a88b92dac3ff7c' (2024-01-11)
  → 'github:nixos/nixpkgs/724e39ebb9b8eda97f17d423f66fbc5a991f4f8d' (2024-01-14)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/51f399ec47c082d678261883095bb8ad552e6500' (2024-01-11)
  → 'github:nixos/nixpkgs/6c08fe3ccf437d8b26bec010fd925ddd6bb0d0d5' (2024-01-14)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/c0b3a5af90fae3ba95645bbf85d2b64880addd76' (2024-01-10)
  → 'github:Mic92/sops-nix/70dd0d521f7849338e487a219c1a07c429a66d77' (2024-01-14)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/70bdadeb94ffc8806c0570eb5c2695ad29f0e421' (2024-01-03)
  → 'github:NixOS/nixpkgs/a1982c92d8980a0114372973cbdfe0a307f1bdea' (2024-01-12)
```
2024-01-15 01:32:07 +00:00
5b9c58dbc6 hosts/common: use servo-style dns on all machines
it'll be handy as i want to place individual applications inside VPNs/namespaces
2024-01-15 01:16:22 +00:00
a7964c4f0c hosts/common: net: split upnp config into own file 2024-01-15 01:12:09 +00:00
006a7e9f72 consolidate net-related stuff into hosts/common/net/ directory 2024-01-15 01:11:13 +00:00
3856710faf net: annotate the UPNP rule 2024-01-15 01:08:10 +00:00
6cbc0bedf3 ddns-he (HurricaneElectric): remove
it's unused for a year
2024-01-15 00:55:10 +00:00
fbc0c7615a ddns-afraid (afraid.org): remove
it's unused for a year
2024-01-15 00:54:41 +00:00
34bcdb5128 firefox: disable kinetic scrolling 2024-01-14 20:34:14 +00:00
a5c6e41622 feeds: subscribe to POD OF JAKE 2024-01-14 05:20:28 +00:00
02e03227d8 servo: try to integrate peerswap with clightning, but it fails 2024-01-14 04:33:12 +00:00
faa0a7c9ea peerswap: init at unstable-20240111 2024-01-14 02:55:32 +00:00
812a02bc6b feeds: add The Dollop podcast 2024-01-14 00:49:29 +00:00
27898ecdc8 feeds: unsubscribe from Louis Rossman
his channel is kinda just the same idea  played over and over
2024-01-14 00:36:52 +00:00
1c2324cca4 servo: clightning-sane: status command: show profits from fees 2024-01-13 16:43:49 +00:00
70f059eaac feeds: subscribe to Jack Stauber 2024-01-13 16:43:41 +00:00
bac72be730 servo: clightning-sane: status command: show in/out payment sums 2024-01-13 15:53:48 +00:00
99858c1384 servo: clightning-sane: centralize metric reporting, fix so we blacklist our own channels less frequently 2024-01-13 04:47:20 +00:00
103a300e77 servo: clightning-sane: implement an autobalance subcommand 2024-01-13 03:04:24 +00:00
6b5cdd7508 servo: clightning-sane: log before we give up 2024-01-13 01:10:52 +00:00
2f1e354400 servo: clightning-sane: drop caches after so many failures 2024-01-12 23:54:06 +00:00
585a87130c servo: clightning-sane: remove unused loop_once_with_retries method 2024-01-12 23:31:30 +00:00
0e68533776 servo: clightning-sane: introduce parallelism 2024-01-12 23:30:52 +00:00
882cc5bfd0 servo: clightning-sane: rename Balancer -> LoopRouter 2024-01-12 21:36:20 +00:00
91847a9a8e servo: clightning-sane: factor "loop" action into own subroutine 2024-01-12 21:28:20 +00:00
5c649ff216 servo: clightning-sane: include peer_id in status --full 2024-01-12 20:56:00 +00:00
abdd224211 servo: clightning-sane: increase CLTV 9->18 2024-01-12 20:55:32 +00:00
0c72c59190 servo: clightning-sane: handle closed channels in status listing 2024-01-12 20:28:57 +00:00
432170a69e servo: clightning-sane: rename ppm in/out to theirs/mine 2024-01-12 19:31:39 +00:00
805b37a9a5 servo: clightning-sane: add a --full option for more info 2024-01-12 19:24:50 +00:00
87a0bda011 servo: clightning-sane: perform rebalance operation in a loop 2024-01-12 19:17:07 +00:00
5d2c6e1978 servo: clightning-sane: mark channels which cant be rebalanced freely 2024-01-12 18:43:58 +00:00
abafbd811b servo: clightning-sane: minor bugfixes 2024-01-12 18:30:49 +00:00
aca50d9946 servo: clightning-sane: add a "status" subcommand 2024-01-12 17:42:44 +00:00
bd4f4dab81 servo: clightning-sane: factor out a subcommands interface 2024-01-12 15:42:12 +00:00
aebd11ea82 alacritty: port config: yaml to toml 2024-01-12 03:24:55 +00:00
fa6906fdf9 cross: fix appstream/eyed3 failures from nixpkgs update 2024-01-12 03:24:55 +00:00
cec21375a5 servo: disable mautrix-signal 2024-01-12 03:24:55 +00:00
0428f64afa nixpkgs: 2024-01-10 -> 2024-01-11
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/2f9e98ccf3283a34ce9301c7ee4ca18d219d829d' (2024-01-10)
  → 'github:nixos/nixpkgs/06797d4df4baaa51b229081083a88b92dac3ff7c' (2024-01-11)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/32afa5e024e45885dacadf1c8ad65e9ebc51a901' (2024-01-10)
  → 'github:nixos/nixpkgs/51f399ec47c082d678261883095bb8ad552e6500' (2024-01-11)
```
2024-01-12 03:24:55 +00:00
e0864edefc nixpkgs: 2024-01-10 -> 2024-01-10
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/0231e3ccf485b7b110f0e0e55be6a711cb0093fb' (2024-01-10)
  → 'github:nixos/nixpkgs/2f9e98ccf3283a34ce9301c7ee4ca18d219d829d' (2024-01-10)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/a962df01db9bff000df83733bf6d7ef60a855057' (2024-01-10)
  → 'github:nixos/nixpkgs/32afa5e024e45885dacadf1c8ad65e9ebc51a901' (2024-01-10)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/0ded57412079011f1210c2fcc10e112427d4c0e6' (2024-01-08)
  → 'github:Mic92/sops-nix/c0b3a5af90fae3ba95645bbf85d2b64880addd76' (2024-01-10)
```
2024-01-12 03:24:55 +00:00
7460fd283c nixpkgs: 2024-01-09 -> 2024-01-10
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/fcff3d7883a38ef71832899085ba365658c96867' (2024-01-09)
  → 'github:nixos/nixpkgs/0231e3ccf485b7b110f0e0e55be6a711cb0093fb' (2024-01-10)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/519c93eda20a7c361e6159d853bf33b1e6236141' (2024-01-09)
  → 'github:nixos/nixpkgs/a962df01db9bff000df83733bf6d7ef60a855057' (2024-01-10)
```
2024-01-12 03:24:55 +00:00
7a7dee1630 nixpkgs: 2023-12-29 -> 2024-01-09; sops-nix; uninsane-dot-org
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/f50aae4fb10dd51bd6ffcce0eb96d02b608a9595' (2023-12-29)
  → 'github:nixos/nixpkgs/fcff3d7883a38ef71832899085ba365658c96867' (2024-01-09)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/04df6aa7bad237aeeb69f603e1f4ec1a2c28a4da' (2023-12-29)
  → 'github:nixos/nixpkgs/519c93eda20a7c361e6159d853bf33b1e6236141' (2024-01-09)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/e523e89763ff45f0a6cf15bcb1092636b1da9ed3' (2023-12-24)
  → 'github:Mic92/sops-nix/0ded57412079011f1210c2fcc10e112427d4c0e6' (2024-01-08)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/7790e078f8979a9fcd543f9a47427eeaba38f268' (2023-12-23)
  → 'github:NixOS/nixpkgs/70bdadeb94ffc8806c0570eb5c2695ad29f0e421' (2024-01-03)
• Updated input 'uninsane-dot-org':
    'git+https://git.uninsane.org/colin/uninsane?ref=refs/heads/master&rev=b21e6899490f25fa450fb9e3efa0c8774bcee0d3' (2023-12-31)
  → 'git+https://git.uninsane.org/colin/uninsane?ref=refs/heads/master&rev=4a1fa488e64e6c87c6c951e3fafb2684692f64d3' (2024-01-01)
```
2024-01-12 03:24:55 +00:00
913403aac6 servo: clightning-sane: tidy 2024-01-12 01:25:56 +00:00
432a66bf5f servo: clightning: initialize a script for rebalancing with peers 2024-01-11 23:11:33 +00:00
e2a43ddfa0 servo: clightning: allow group members to run lightning-cli 2024-01-11 15:59:32 +00:00
b2ba204ca1 nixpatches: update hashes (?) 2024-01-11 15:58:44 +00:00
892b045342 pyln-client: init at 23.11.2 2024-01-11 00:38:08 +00:00
8644e6705a servo: decrease ZFS cache size 2024-01-11 00:20:52 +00:00
3f60206eef servo: clightning: tune config 2024-01-10 23:40:17 +00:00
568ead4bd7 servo: lightning: tune config 2024-01-10 21:01:36 +00:00
14241d54c9 flake: fix packages output to eval (even though its dumb and i just use hostPkgs.<machine>.<xyz>) 2024-01-10 11:48:20 +00:00
e4d75c5f38 servo: clightning: disable features which are incompatible with lnd 2024-01-10 11:18:54 +00:00
c42dda1bab servo: clightning: document more parts of the config 2024-01-09 16:19:48 +00:00
3295ae3b74 servo: clightning: update config 2024-01-09 16:13:08 +00:00
e63438bedf feeds: disable The Linux Experience 2024-01-09 00:45:18 +00:00
25422da9ba servo: tune clightning config 2024-01-09 00:42:37 +00:00
37583d8c9c clightning: tune fees, logging 2024-01-06 18:08:51 +00:00
62b3863722 servo: clightning: enable experimental features 2024-01-06 09:13:17 +00:00
b11f03bd18 servo: clightning: docs 2024-01-05 22:09:32 +00:00
63620fa058 servo: clightning: node personalization and docs 2024-01-04 21:55:13 +00:00
cecb114810 clightning: harden 2024-01-04 18:47:40 +00:00
4ce93f74c6 wob: add debug logging 2024-01-04 17:07:47 +00:00
09b806d7a7 go2tv: document youtube workarounds 2024-01-04 16:26:25 +00:00
2f31100c3f servo: ship go2tv 2024-01-04 16:25:50 +00:00
ca3f97ec51 docs: go2tv: elaborate seeking limitations 2024-01-04 16:25:49 +00:00
7378d6c5b2 bitcoind: host behind tor 2024-01-04 16:25:49 +00:00
276de5d662 tor: fix /var/lib/tor directory permissions 2024-01-04 16:25:49 +00:00
6f449cf35f clightning: document some places to find nodes for channels 2024-01-04 16:25:49 +00:00
daf046861c wob: implement as part of sway instead of exclusive to sxmo 2024-01-04 13:08:20 +00:00
43498c62f9 clightning: integrate with tor 2024-01-03 18:29:16 +00:00
22f5853741 firefox: remove unused functions 2024-01-03 14:59:59 +00:00
fe217f6667 firefox: disable ctrl+shift+c shortcut more broadly 2024-01-03 14:59:27 +00:00
41ae86f40f servo: enable clightning 2024-01-03 13:56:42 +00:00
6d52c8ecf8 servo: split tor/i2p into own files 2024-01-03 13:56:14 +00:00
75b649543a firefox: enable ctrl-shift-c-should-copy extension 2024-01-03 13:42:58 +00:00
1261a6f452 firefox-extensions.ctrl-shift-c-should-copy: init at unstable-2023-03-04 2024-01-03 13:33:32 +00:00
041855dbc7 zsh: fix broken <del> and <ctrl>+<arrow> keybindings 2024-01-03 13:07:29 +00:00
3e52956a3a servo: clightning: integrate, but do not enable 2024-01-02 18:32:34 +00:00
d8f4158bc6 servo: consolidate blockchains under cryptocurrencies directory 2024-01-02 18:16:58 +00:00
36638e80a3 bitcoin: add myself as an authenticated rpcuser 2024-01-02 18:11:46 +00:00
28d0a72c62 define (but dont activate) a clighting bitcoin service 2024-01-02 14:29:52 +00:00
6471524f4a programs: zecwallet-lite: move to own file 2024-01-01 15:17:51 +00:00
61b2b8f2cd nixpatches: cleanup 2024-01-01 14:46:37 +00:00
02aae4bb8b conky: start upstreaming it 2024-01-01 14:38:08 +00:00
3efecb9560 sxmo_hook_block_suspend: re-introduce exponential backoff 2024-01-01 13:03:26 +00:00
8d0707699c mpv/vlc: associate with flv video type 2024-01-01 11:48:18 +00:00
318774a2a0 sxmo_suspend: fix that "sxmo_jobs periodic_blink" would hang post-wakeup 2024-01-01 11:48:03 +00:00
b14e997a43 sxmo: remove sxmo_hook_screenoff.sh override
generally, i can get away with the defaults and patch my alternative into sxmo_suspend.sh more reliably/simply
2024-01-01 10:33:24 +00:00
b949438be5 sxmo_suspend.sh: stop, and resume, the sxmo LED blinking
then later i can remove the custom screenoff hook
2024-01-01 10:01:48 +00:00
6ee9e8e405 sxmo_hook_screenoff: decrease the blink frequency even more
if i was smarter i'd just disable the periodic blinking right before entering sleep
2024-01-01 07:24:08 +00:00
09ee8e6efc sxmo_hook_block_suspend: forward only to the next script, not all next scripts 2024-01-01 07:01:09 +00:00
49527edaa9 sxmo_suspend.sh: fix rtcwake to use sudo 2024-01-01 06:38:43 +00:00
92d193ffe3 sxmo_hook_block_suspend: fix recursion counter 2024-01-01 06:19:30 +00:00
4805510073 sxmo-utils: ship with gojq 2024-01-01 06:15:31 +00:00
6fe195e2dd sxmo: block suspend if go2tv is active 2024-01-01 04:56:39 +00:00
c54df8d9c4 hare-ev: 2023-10-31 -> 2023-12-04 2024-01-01 03:56:45 +00:00
6d8b6c61a2 feeds: sort 2024-01-01 03:56:25 +00:00
822653ec10 feeds: vitalik.ca -> vitalik.eth.limo 2024-01-01 03:48:06 +00:00
68502ca944 feeds: add webcurious.co.uk link aggregator 2024-01-01 03:46:52 +00:00
103d11a87c net: fix broken firewall/ipset setup 2023-12-31 14:25:36 +00:00
0028c41bdc uninsane-dot-org: update 2023-12-31 12:22:23 +00:00
a4fe002607 sway: always render KOReader titlebar 2023-12-30 11:57:33 +00:00
b54ab9391b sxmo-utils: add Notejot app 2023-12-30 11:41:36 +00:00
0c7612c83f sxmo-utils: 2023-12-17 -> 2023-12-28
this should fix spurious screenoff -> unlock transitions (thanks Aren!)
2023-12-30 11:31:36 +00:00
f9361af41c go2tv: remove firewall fix and allow SSDP at the iptables layer 2023-12-30 06:16:17 +00:00
3cd3ebed51 nixpkgs -> latest 2023-12-30 05:34:23 +00:00
4ad209020a disable chatty (doesnt cross compile) 2023-12-30 05:34:02 +00:00
556327740b nixpkgs: 2023-12-26 -> 2023-12-29
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/0db7618e46243d3710ff2b8040aca5f6e0102900' (2023-12-26)
  → 'github:nixos/nixpkgs/bd7fd36fe22e0de1162f1623f1736517c1506164' (2023-12-29)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/d956588517edbcde71781bd8ac3a9947a9fc55a6' (2023-12-26)
  → 'github:nixos/nixpkgs/f46c267fc63f01c75fa9f6d9fb8345e6a1ed0063' (2023-12-29)
```
2023-12-29 15:52:32 +00:00
b0ddb1b31c conky: use the same percent symbol even in battery_estimate 2023-12-28 17:43:34 +00:00
70ee98736a conky/battery_estimate: handle the static state better 2023-12-28 17:35:33 +00:00
5de06cef35 conky: fix text substitutions 2023-12-28 17:07:29 +00:00
4f3706622c conky/battery_estimate: render stylized 2023-12-28 03:05:27 +00:00
104e76de47 conky/battery_estimate: render h/m indicators as superscript 2023-12-28 01:53:43 +00:00
1df99978bb conky/battery_estimte: select icon based on battery percentage 2023-12-28 01:11:51 +00:00
3846322f12 conky/battery_estimate: support new-style Thinkpad batteries 2023-12-28 00:41:23 +00:00
623b2c6611 conky/battery_estimate: add debugging 2023-12-28 00:35:48 +00:00
cb4d73f959 nixpkgs: 2023-12-23 -> 2023-12-26
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/2125288b9266cde9e3333a6787525bc151918742' (2023-12-23)
  → 'github:nixos/nixpkgs/0db7618e46243d3710ff2b8040aca5f6e0102900' (2023-12-26)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/d8aba6fe4067abdd8b1a7f398f2b90f21c608530' (2023-12-23)
  → 'github:nixos/nixpkgs/d956588517edbcde71781bd8ac3a9947a9fc55a6' (2023-12-26)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/f7db64b88dabc95e4f7bee20455f418e7ab805d4' (2023-12-18)
  → 'github:Mic92/sops-nix/e523e89763ff45f0a6cf15bcb1092636b1da9ed3' (2023-12-24)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/a19a71d1ee93226fd71984359552affbc1cd3dc3' (2023-12-17)
  → 'github:NixOS/nixpkgs/7790e078f8979a9fcd543f9a47427eeaba38f268' (2023-12-23)
```
2023-12-27 00:34:48 +00:00
58febf51bd remove most useDHCP=false settings
networking.useDHCP was deprecated, and then later undeprecated: it's safe to keep it defaulted
2023-12-24 02:17:06 +00:00
b254379fb1 firefox-extensions: update to latest 2023-12-23 21:31:13 +00:00
835d933719 nixpkgs: 2023-12-22 -> 2023-12-23
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/21e572254ecbbb9d55be98841b279d21ee5754b6' (2023-12-22)
  → 'github:nixos/nixpkgs/2125288b9266cde9e3333a6787525bc151918742' (2023-12-23)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/66bda599f409f9834c6fd6abc602e452a5c16b61' (2023-12-22)
  → 'github:nixos/nixpkgs/d8aba6fe4067abdd8b1a7f398f2b90f21c608530' (2023-12-23)
```
2023-12-23 21:18:25 +00:00
31130d90bc nixpatches: fix broken hash 2023-12-23 12:44:17 +00:00
237c493252 slskd: fix Restart option 2023-12-23 10:23:17 +00:00
18e7acd9e7 slskd: restart even on non-failure exit 2023-12-23 05:39:22 +00:00
906026e333 nixpkgs: 2023-12-21 -> 2023-12-22
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/63fbe1a992e6030fbf444ac9d6b629ec76ab86ad' (2023-12-21)
  → 'github:nixos/nixpkgs/21e572254ecbbb9d55be98841b279d21ee5754b6' (2023-12-22)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/490828bce1b0cdfe328adc7f6280a519d7e68ed4' (2023-12-21)
  → 'github:nixos/nixpkgs/66bda599f409f9834c6fd6abc602e452a5c16b61' (2023-12-22)
```
2023-12-22 19:07:32 +00:00
9e24fba5ee document that loupe is an image viewer 2023-12-21 22:58:23 +00:00
12edd60969 nixpkgs: bump 2023-12-21
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/459873d8d6492b492ca7f9b03d5a50117099abfa' (2023-12-21)
  → 'github:nixos/nixpkgs/63fbe1a992e6030fbf444ac9d6b629ec76ab86ad' (2023-12-21)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/38bbf09b10659db891af01288bd99a5e8e8d7861' (2023-12-21)
  → 'github:nixos/nixpkgs/490828bce1b0cdfe328adc7f6280a519d7e68ed4' (2023-12-21)
```
2023-12-21 20:03:06 +00:00
0f429caaca nixpkgs: 2023-12-20 -> 2023-12-21
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/7749fa1e8c5e2f6a003fd4d3a2ed52924c4a7217' (2023-12-20)
  → 'github:nixos/nixpkgs/459873d8d6492b492ca7f9b03d5a50117099abfa' (2023-12-21)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/9ee63abe2cbeea5bf15f319a0a5aaf0919fe22e8' (2023-12-20)
  → 'github:nixos/nixpkgs/38bbf09b10659db891af01288bd99a5e8e8d7861' (2023-12-21)
```
2023-12-21 18:41:55 +00:00
940f1140a3 disable webkit for erlang 2023-12-21 05:22:45 +00:00
dbb6773634 audacity: disable first-run splashscreen 2023-12-21 04:08:05 +00:00
245a0544bc audacity: ship w/o the webkitgtk dependency 2023-12-21 03:10:38 +00:00
cbd65f0816 argyllcms: build without qemu 2023-12-21 01:44:36 +00:00
f8ea711f6a cross compilation: remove dead code 2023-12-21 00:20:42 +00:00
ace94cf4d6 cross: use newer jbig2dec fix; send dconf upstream 2023-12-20 22:32:07 +00:00
829fde4336 bonsai: grab from upstream PR 2023-12-20 09:24:41 +00:00
ba8774d6e5 hare-ev: remove (upstreamed) 2023-12-20 09:21:11 +00:00
7597853cda nixpkgs: 2023-12-19 -> 2023-12-20
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/7467ab39493e17abc28c7f66179feb0a69a3dbd4' (2023-12-19)
  → 'github:nixos/nixpkgs/7749fa1e8c5e2f6a003fd4d3a2ed52924c4a7217' (2023-12-20)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/63dd8e1d2e81aaecb7de9b70ca143a607b19a3b9' (2023-12-19)
  → 'github:nixos/nixpkgs/9ee63abe2cbeea5bf15f319a0a5aaf0919fe22e8' (2023-12-20)
```
2023-12-20 09:08:42 +00:00
21077c0e34 cross: document rustPlatform cross compilation woes 2023-12-20 08:00:40 +00:00
b6a45656af gui: add planify app 2023-12-19 22:31:14 +00:00
33d2f0895f signal-desktop-from-src: 6.40.0 -> 6.42.0 2023-12-19 20:53:33 +00:00
5cd92279b7 firefox-extensions: update to latest 2023-12-19 19:40:24 +00:00
4085f60018 firefox-extensions.bypass-paywalls-clean: 3.4.6.0 -> 3.4.7.0 2023-12-19 19:40:08 +00:00
3faee78717 docs: cross: update upstreaming status 2023-12-19 19:39:38 +00:00
e96e07ac21 lemoa: todo: fold 2023-12-19 19:39:11 +00:00
0c34aec8ec lemoa: 0.4.0 -> 0.5.0 2023-12-19 18:08:16 +00:00
9d04037bec hare-ev: remove unnecessary rec 2023-12-19 17:44:04 +00:00
6af44bfd86 delfin: add an updateScript 2023-12-19 17:43:07 +00:00
5ceefa4d6d nixpkgs: 2023-12-18 -> 2023-12-19; uninsane-dot-org -> 2023-12-18
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/ab47e6046f991dc98641ffbd9f881afcd304cfca' (2023-12-18)
  → 'github:nixos/nixpkgs/7467ab39493e17abc28c7f66179feb0a69a3dbd4' (2023-12-19)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/f61b7ce80fcc95be72c5c4fea19fba928072af8b' (2023-12-18)
  → 'github:nixos/nixpkgs/63dd8e1d2e81aaecb7de9b70ca143a607b19a3b9' (2023-12-19)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/21f2b8f123a1601fef3cf6bbbdf5171257290a77' (2023-12-17)
  → 'github:Mic92/sops-nix/f7db64b88dabc95e4f7bee20455f418e7ab805d4' (2023-12-18)
• Updated input 'uninsane-dot-org':
    'git+https://git.uninsane.org/colin/uninsane?ref=refs/heads/master&rev=ee722a13732b8d03bae56be8147333d144a02126' (2023-12-10)
  → 'git+https://git.uninsane.org/colin/uninsane?ref=refs/heads/master&rev=41354f754107376f5c9265eae89d07275f0305de' (2023-12-18)
• Removed input 'uninsane-dot-org/flake-utils'
• Removed input 'uninsane-dot-org/flake-utils/systems'
```
2023-12-19 16:44:22 +00:00
f618925190 gui: ship openscad 2023-12-19 08:04:20 +00:00
68ae723543 nixos-prebuild: disable 2023-12-19 01:58:59 +00:00
e4123759f5 nginx: only auto-index /share 2023-12-19 00:12:27 +00:00
5e727a83b3 slskd: disable debug logging 2023-12-18 18:09:58 +00:00
dc288d9aa7 sane_ssdp: reduce verbosity 2023-12-18 18:00:12 +00:00
8d49c423ca transmission: disable debug logging 2023-12-18 17:58:04 +00:00
c056564c9c nixpkgs: 2023-12-17 -> 2023-12-18
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/ec02adf37f19c5dcd891ebf9f175ebb1c4fba80a' (2023-12-17)
  → 'github:nixos/nixpkgs/ab47e6046f991dc98641ffbd9f881afcd304cfca' (2023-12-18)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/91a00709aebb3602f172a0bf47ba1ef013e34835' (2023-12-17)
  → 'github:nixos/nixpkgs/f61b7ce80fcc95be72c5c4fea19fba928072af8b' (2023-12-18)
```
2023-12-18 16:39:25 +00:00
efb2815fa5 uninsane.org: simplify the /share routing (and generalize it to other subdirectories) 2023-12-18 06:03:49 +00:00
577d149728 sxmo-utils: 2023-12-09 -> 2023-12-17 2023-12-18 00:05:14 +00:00
45c2bfaaeb nixpkgs: 2023-12-16 -> 2023-12-17
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/029c707186e2b00f9e98f590b9a019320ccc21d7' (2023-12-16)
  → 'github:nixos/nixpkgs/ec02adf37f19c5dcd891ebf9f175ebb1c4fba80a' (2023-12-17)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/ceb8e4efd95627c0a86f106ba2afcd207ad5c6b3' (2023-12-16)
  → 'github:nixos/nixpkgs/91a00709aebb3602f172a0bf47ba1ef013e34835' (2023-12-17)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/d806e546f96c88cd9f7d91c1c19ebc99ba6277d9' (2023-12-10)
  → 'github:Mic92/sops-nix/21f2b8f123a1601fef3cf6bbbdf5171257290a77' (2023-12-17)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/b8f33c044e51de6dde3ad80a9676945e0e4e3227' (2023-12-09)
  → 'github:NixOS/nixpkgs/a19a71d1ee93226fd71984359552affbc1cd3dc3' (2023-12-17)
```
2023-12-18 00:02:23 +00:00
16d4c9cdf2 nixpkgs: 2023-12-15 -> 2023-12-16
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/9ad53b7aaf2b9e9e0d7e36ff4f8a779bf9b0195f' (2023-12-15)
  → 'github:nixos/nixpkgs/029c707186e2b00f9e98f590b9a019320ccc21d7' (2023-12-16)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/8a205497ba6f6938b7b516c184b7cf326ab15548' (2023-12-15)
  → 'github:nixos/nixpkgs/ceb8e4efd95627c0a86f106ba2afcd207ad5c6b3' (2023-12-16)
```
2023-12-17 21:26:41 +00:00
1063a89541 powerbutton/lid-switch: tune the desired actions 2023-12-17 21:08:16 +00:00
fd0f709d50 git: remove a/ b/ prefixes from diffs 2023-12-17 20:48:31 +00:00
5edd10c332 move kiwix data to /var/lib/kiwix and persist 2023-12-16 03:05:15 +00:00
5c36ee79be kiwix: wikipedia snapshot: 2022-05 -> 2023-11 2023-12-16 01:54:34 +00:00
b2bf9d63a3 mpv: don't assume xdg-terminal-exec is on PATH 2023-12-16 00:43:43 +00:00
e297df011d xdg-terminal-exec: remove (it exists upstream now) 2023-12-16 00:41:51 +00:00
bcac00d766 mpv: uosc: add a "cast" option to the menu 2023-12-16 00:39:36 +00:00
c256d7ded5 koreader: implement copy-to-clipboard 2023-12-15 20:53:04 +00:00
7ba39ea831 koreader: document how to configure 2023-12-15 20:05:06 +00:00
28f90e4421 sxmo: lengthen voldown hold time before revealing terminal 2023-12-15 19:12:26 +00:00
5d66a1e6a5 hare-json: remove. it's been upstreamed as hareThirdParty.hare-json 2023-12-15 17:59:09 +00:00
1522eccfb3 nixpkgs: 2023-12-14 -> 2023-12-15
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/248d12a902bfc36134176f31beba87b1fe30a3c1' (2023-12-14)
  → 'github:nixos/nixpkgs/9ad53b7aaf2b9e9e0d7e36ff4f8a779bf9b0195f' (2023-12-15)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/fd7914c96f7c006047e0154dd239aa2396478094' (2023-12-14)
  → 'github:nixos/nixpkgs/8a205497ba6f6938b7b516c184b7cf326ab15548' (2023-12-15)
```
2023-12-15 17:40:44 +00:00
728604e036 gui hosts: ship delfin 2023-12-15 08:44:32 +00:00
58d4f0d512 delfin: fix cross build 2023-12-15 08:43:10 +00:00
1f7fc8700e delfin: fix icons 2023-12-15 08:30:20 +00:00
a933f8b512 delfin: persist server settings 2023-12-15 08:17:07 +00:00
83b83841d6 delfin: init at 0.2.1 2023-12-15 08:08:11 +00:00
ef8a8bc246 go2tv: document known-good format matrix 2023-12-15 03:22:03 +00:00
136ddda055 nautilus: enable the A/V pane 2023-12-15 02:57:25 +00:00
5fbf2166f1 moby: enable go2tv/catt 2023-12-15 02:33:18 +00:00
ba7bc3bd03 go2tv: docs: show that some mp4s work w/o transcoding 2023-12-15 02:32:44 +00:00
311412c5ee go2tv: configure firewall as needed 2023-12-15 00:50:58 +00:00
d18e94ea87 feeds: subscribe to linmob.net 2023-12-14 22:20:30 +00:00
6a548366cd sway: enable gvfs to support remote filesystems 2023-12-14 21:59:42 +00:00
54d2e875f6 koreader: disable image-based feeds; text only 2023-12-14 20:51:09 +00:00
c5cc0e90a3 wob: theme 2023-12-14 20:49:48 +00:00
50ce8da68c sxmo: remove sxmo-set-permissions job. upstream refactored it to not exist and they use doas now instead 2023-12-14 19:17:38 +00:00
3449bfc2a9 sxmo: bonsai: tune timings: powerhold: 1000ms -> 900ms; volhold: 400ms -> 600ms
this should improve: (1) awkwardly long power hold until window is killed, (2) accidentally seeking the media player when i meant to only adjust volume
2023-12-14 19:12:08 +00:00
18d301d9dd cross: dino: remove patch which has been upstreame into nixpkgs 2023-12-14 19:08:08 +00:00
357bf7f4ca nixpkgs: 2023-12-13 -> 2023-12-14
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/022a4231437548b719eb9e5b8bae1a7f6117fa93' (2023-12-13)
  → 'github:nixos/nixpkgs/1aca249f1846b6bb7a156b809c312de58945c85a' (2023-12-14)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/8556109c1f04574ad59dcb0c4882f44eb27ea581' (2023-12-13)
  → 'github:nixos/nixpkgs/8e23dec5ac5ebc36057e980d4e6a3eb6a44da74b' (2023-12-14)
```
2023-12-14 18:50:36 +00:00
f763448d6f go2tv: docs: firewall 2023-12-14 10:56:07 +00:00
deb828e98a programs: enable go2tv 2023-12-14 10:39:33 +00:00
cbca41accf permit moby to ssh into my devices 2023-12-14 10:35:36 +00:00
ac22e07388 sxmo: bring wob service in-house 2023-12-14 10:33:33 +00:00
cb0d9e077b programs: enable catt 2023-12-14 08:41:16 +00:00
58105e9b62 fix open-in-mpv extension 2023-12-14 07:26:50 +00:00
32fb79d43d dino: auto-start 2023-12-14 01:57:32 +00:00
f129afdae8 flare-signal: document linking/registration issue 2023-12-14 01:56:54 +00:00
29cde5e724 firefox: support Element and Nheko URIs 2023-12-13 23:14:04 +00:00
3467a5df48 feeds: subscribe Origin Stories 2023-12-13 22:31:58 +00:00
694dd59e27 feeds: subscribe bitsaboutmoney 2023-12-13 22:29:22 +00:00
540b3e4af2 firefox: auto-dispatch mpv:// URI handlers 2023-12-13 21:41:06 +00:00
e0211646b2 firefox: extraNativeMessagingHosts -> nativeMessagingHosts 2023-12-13 21:34:59 +00:00
94dcb0f08a firefox: ship open-in-mpv extension 2023-12-13 21:34:34 +00:00
0b38ed2f2a firefox: docs: clarify fxCast behavior 2023-12-13 20:58:45 +00:00
15622251ef firefox: define the fx_cast addon 2023-12-13 20:51:57 +00:00
4eb79a4a5c gui: ship pwvucontrol 2023-12-13 20:43:16 +00:00
9f54413d46 pwvucontrol: support cross compilation 2023-12-13 20:02:48 +00:00
f467898a04 sync TODO 2023-12-13 17:41:31 +00:00
413c8a4fef sponsorblock: re-disable the first-launch nag 2023-12-13 17:37:48 +00:00
d4440736dd nixpkgs: 2023-12-12 -> 2023-12-13
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/a3eee1a84ec0aadb7f567175d79574d63dcecff2' (2023-12-12)
  → 'github:nixos/nixpkgs/022a4231437548b719eb9e5b8bae1a7f6117fa93' (2023-12-13)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/47bca5bb0209496389f3a70d2e388c5531831d60' (2023-12-12)
  → 'github:nixos/nixpkgs/8556109c1f04574ad59dcb0c4882f44eb27ea581' (2023-12-13)
```
2023-12-13 16:27:18 +00:00
bb1ceaed12 gui: disable newsflash
it doesn't cross compile. also, gnome-feeds would be a better implementation if i can get the package updated
2023-12-13 16:27:18 +00:00
51a90136ea sxmo-utils: default preferSystemd to true
this probably removes some duplicate sxmo-utils packages from my install
2023-12-13 16:27:18 +00:00
e7cfa19897 sxmo-utils: use xdg-open in sxmo_open.sh 2023-12-13 16:27:18 +00:00
41411e005f flare-signal-nixified: document experience with 10.1-xx seies 2023-12-13 08:10:50 +00:00
c22119f69b flare-signal-nixified: enable primary device registration 2023-12-13 07:17:17 +00:00
354a4e523b flare-signal-nixified: 0.10.1-beta.4 -> 0.10.1-beta.6 2023-12-13 07:01:16 +00:00
b34b8a249c nixpatches: link but dont apply gnome-feeds update 2023-12-13 03:47:20 +00:00
508257da87 newsflash: enable podcasts/videos; document 2023-12-13 03:45:07 +00:00
fadcf7d7c1 mpv: youtube: associate with another URL variant 2023-12-13 03:44:57 +00:00
7f43360120 newsflash: enable 2023-12-13 03:06:08 +00:00
f9a8389f58 gui: switch from gthumb to loupe for image viewing 2023-12-13 02:29:43 +00:00
f77a18a655 cross: enable Loupe for cross compilation 2023-12-13 02:00:43 +00:00
7e4d6853f5 cross: glycin-loaders: simplify 2023-12-13 01:48:26 +00:00
5615c7cf6e cross: glycin-loader: fix compilation 2023-12-13 01:40:36 +00:00
54c51a5636 fractal-latest: remove old comments 2023-12-12 21:02:09 +00:00
1119726c64 docs: koreader: dictionary installation 2023-12-12 20:56:46 +00:00
101a2bc3af hare-ev: 2023-10-30 -> 2023-12-04 2023-12-12 20:45:46 +00:00
f4bfaf3581 firefox-extensions: update to latest 2023-12-12 20:44:56 +00:00
e8dfc1dc71 sxmo-utils: 2023-11-26 -> 2023-12-09 2023-12-12 20:44:27 +00:00
ef26b9085c nixpatches: remove merged numpy patch 2023-12-12 20:37:55 +00:00
85d9c11733 sxmo: add an option to disable wob 2023-12-12 19:00:43 +00:00
6d41f1f1db sxmo: re-enable audio
SXMO_NO_AUDIO disables too much. i just want to not launch the daemons, and customizing sxmo_hook_start is enough for that
2023-12-12 18:59:31 +00:00
f9434215db nixpkgs: 2023-12-11 -> 2023-12-12
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/43f7188eba3bc2eb73031bf8f9ad1a02224b6be1' (2023-12-12)
  → 'github:nixos/nixpkgs/a3eee1a84ec0aadb7f567175d79574d63dcecff2' (2023-12-12)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/a8dac2fa64af92360f126d2e20f47cd4ccf1c905' (2023-12-11)
  → 'github:nixos/nixpkgs/47bca5bb0209496389f3a70d2e388c5531831d60' (2023-12-12)
```
2023-12-12 18:40:06 +00:00
83d402eb77 nixos-prebuild: fix typo 2023-12-12 18:39:46 +00:00
cec48e0270 nixpkgs: 2023-12-11 -> 2023-12-12
```
• Updated input 'nixpkgs-next-unpatched':
    'github:nixos/nixpkgs/f81605387c494a302c16901ac6459e877c45f913' (2023-12-11)
  → 'github:nixos/nixpkgs/43f7188eba3bc2eb73031bf8f9ad1a02224b6be1' (2023-12-12)
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d' (2023-12-11)
  → 'github:nixos/nixpkgs/a59c7364955e5f32798d0314fbb6aae347ff064d' (2023-12-12)
```
2023-12-12 09:34:52 +00:00
322038ca21 flake.nix: expose the patched nixpkgs as an output, for debugging 2023-12-12 09:34:28 +00:00
6395e60f17 nixpatches: fix date check to be based on when upstream nixpkgs was updated, not this repo 2023-12-12 09:34:28 +00:00
7969eb12d6 cross: partially fix glycin-loaders 2023-12-12 09:34:28 +00:00
f942e2c5a9 nixpatches: revise numpy master merge date 2023-12-12 09:34:28 +00:00
089f676c4a gui: switch back to gthumb; loupe does not cross compile yet 2023-12-12 08:44:08 +00:00
d2012b4e40 notejot: fix store typo 2023-12-12 07:55:18 +00:00
a319017567 gui: switch from gthumb to loupe 2023-12-12 07:38:13 +00:00
a669c9c88b gui: add Loupe image viewer specialization 2023-12-12 07:36:21 +00:00
8391e500c9 gui: handheld: ship notejot 2023-12-12 07:31:00 +00:00
5f27c8fddf servo: nixos-prebuild: cleanup garbage better 2023-12-12 06:47:47 +00:00
a4ae41e627 servo: nixos-prebuild: dont ship jobs to other builders 2023-12-12 06:44:08 +00:00
a5126ae8fb cross: re-enable jbig2dec fix (turns out it is necessary) 2023-12-12 06:20:43 +00:00
f33776e0ed flake: check.nur: simplify nixpkgs path 2023-12-12 03:53:54 +00:00
189eccb01e nixpatches: improve patch conditionality 2023-12-12 03:22:25 +00:00
4336d68e6f flake: fix CLI argument quoting 2023-12-12 02:16:06 +00:00
4f45adb063 gui: disable slic3r 2023-12-12 02:16:06 +00:00
e6b16624c3 ntfy-waiter: fix port typo in service description 2023-12-12 02:15:01 +00:00
e87d2f545c sftpgo: fix systemd after/wants typo 2023-12-12 02:14:45 +00:00
69bc219efa ports: fix systemd RandomizedDelaySec typo 2023-12-12 02:14:27 +00:00
e4f1cfb53f servo: deploy a service which periodically rebuilds my nix config to populate the cache 2023-12-12 02:13:59 +00:00
f1e59061d7 flake: check.hostConfigs: build *-light first even for -next 2023-12-11 23:00:15 +00:00
cd312e41d4 flake: remove check.hostConfigs variants 2023-12-11 22:51:58 +00:00
1bd2d0dfc1 flake: remove separate nixpkgs-staging and staging-next 2023-12-11 22:33:38 +00:00
49235a4d83 flake: add check.hostConfigsNext 2023-12-11 22:23:14 +00:00
e7826e0648 flake: add host outputs for nixpkgs-staging and nixpkgs-staging-next 2023-12-11 22:15:35 +00:00
e7edb4739f flake.nix: fix for better caching on non-cross builds 2023-12-11 21:24:33 +00:00
4a622c558e signal-desktop-from-src: fix nodejs to 18.x 2023-12-11 21:07:42 +00:00
bfe69a4708 flake: fix patching process to assume less about nixpkgs internals 2023-12-11 21:07:17 +00:00
688b4edf13 mpv: handle shorthand youtu.be URLs too 2023-12-11 16:19:51 +00:00
7ca2e5f539 nixpkgs: 2023-12-10 -> 2023-12-11; uninsane-dot-org
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/64292b08dc5d1538d7ab88817a90b2713c34c8a0' (2023-12-10)
  → 'github:nixos/nixpkgs/e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d' (2023-12-11)
• Updated input 'uninsane-dot-org':
    'git+https://git.uninsane.org/colin/uninsane?ref=refs/heads/master&rev=8f7a3f3f7ce95f21131f94418c522062a8dc2055' (2023-12-09)
  → 'git+https://git.uninsane.org/colin/uninsane?ref=refs/heads/master&rev=ee722a13732b8d03bae56be8147333d144a02126' (2023-12-10)
```
2023-12-11 06:23:43 +00:00
4c5fb74c7d feeds: subscribe to kosmosghost 2023-12-11 04:55:47 +00:00
ad82bb2630 mimeo: fix infinite loop when dispatching non-specialized http/s URLs 2023-12-11 04:52:49 +00:00
008a6192d4 mpv: associate with https://youtube.com/... 2023-12-11 04:52:49 +00:00
f4d4c7a92a sxmo-utils: remove gojq and just use normal jq 2023-12-11 04:44:45 +00:00
0a41192eb1 sxmo-utils: remove gojq requirement 2023-12-11 03:27:58 +00:00
f044fcb584 gnome-frog: fix cross compilation 2023-12-11 03:27:46 +00:00
9e2c0a7112 megapixels: simplify zbar fix 2023-12-11 03:27:29 +00:00
d2e1441d1f sane-clone: grab package data from ~/nixos instead of nixpkgs
this way i can clone my own packages
2023-12-10 17:28:30 +00:00
abbd28a634 git: add an "amend" alias 2023-12-10 17:01:58 +00:00
b309402784 nixpkgs: update; sops-nix: 2023-12-04 -> 2023-12-10
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/852e0ea0e8e1bd174bf1af9706f6b855319a5f1d' (2023-12-10)
  → 'github:nixos/nixpkgs/64292b08dc5d1538d7ab88817a90b2713c34c8a0' (2023-12-10)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/e91ece6d2cf5a0ae729796b8f0dedceab5107c3d' (2023-12-04)
  → 'github:Mic92/sops-nix/d806e546f96c88cd9f7d91c1c19ebc99ba6277d9' (2023-12-10)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/dc01248a9c946953ad4d438b0a626f5c987a93e4' (2023-12-03)
  → 'github:NixOS/nixpkgs/b8f33c044e51de6dde3ad80a9676945e0e4e3227' (2023-12-09)
```
2023-12-10 16:50:24 +00:00
a7d3ac95aa nginx: uninsane.org: redirect common feed URIs to the canonical feed 2023-12-10 16:31:30 +00:00
255da2b976 docs: gtkcord4: explain how to disable notif sounds 2023-12-10 16:26:26 +00:00
8cdb4aa53d docs: feedbackd: show how to trigger a sound 2023-12-10 16:25:13 +00:00
4d5b462b2c swaync: add rules to help with debugging 2023-12-10 16:18:55 +00:00
f7a318c937 modules/users: fix services to specify PATH with correct precedence 2023-12-10 15:18:26 +00:00
eb5b9b083c mpv-uosc-latest: remove (no longer needed)
nixpkgs mpv-uosc was recently updated, seems to work well out-of-the-box
2023-12-10 02:32:33 +00:00
e0d9a59d10 nixpkgs: 2023-12-09 -> 2023-12-10
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/61b691834e5ce9590c44690e73392ee7e001d45a' (2023-12-09)
  → 'github:nixos/nixpkgs/852e0ea0e8e1bd174bf1af9706f6b855319a5f1d' (2023-12-10)
```
2023-12-10 02:13:59 +00:00
119ac4cf95 cross: start upstreaming wob patch 2023-12-09 20:20:10 +00:00
f53d0e16ff cross: start upstreaming dino patch 2023-12-09 20:11:36 +00:00
5321ccc980 uninsane-dot-org: mobile-linux-push-notifications: fix src-port -> dest-port typo 2023-12-09 18:28:28 +00:00
e8a6fa3506 uninsane-dot-org: mobile-linux-push-notifications: fix link typo 2023-12-09 18:22:58 +00:00
26e1cc2a7a uninsane-dot-org: revise linux-mobile-notifications for sxmo integration 2023-12-09 18:16:32 +00:00
cec4b4b78e sway: fix app_id for gtkcord4 2023-12-09 16:48:17 +00:00
7ce3cb79c9 switch from abaddon -> gtkcord4 as default discord client 2023-12-09 16:45:40 +00:00
4c553b1525 gtkcord4: fix to Default_keyring instead of login.keyring 2023-12-09 16:42:27 +00:00
84ec809fb5 gui: ship gnome.seahorse 2023-12-09 15:02:00 +00:00
f49e466ce8 flake: add a "hostSystems" target 2023-12-09 14:11:37 +00:00
402baa1011 uninsane-dot-org: 2023-12-03 -> 2023-12-09; nixpkgs 2023-12-09 14:01:51 +00:00
01de6f84cf feeds: subscribe to Louis Rossmann 2023-12-09 08:14:16 +00:00
e1e9047664 nixpkgs: 2023-12-08 -> 2023-12-09
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/c89d45747b4ba510caa6b2704b574484b6f93e96' (2023-12-08)
  → 'github:nixos/nixpkgs/d02151974acd5d2e1a47cee3245d97e130c3ecfa' (2023-12-09)
```
2023-12-09 05:51:01 +00:00
0be9831b0c cross: update upstreaming status 2023-12-08 22:49:18 +00:00
1db9d4d10b roles/build-machine: re-enable big-parallel 2023-12-08 20:20:55 +00:00
ccef9d1414 nixpkgs: update
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/f63903a90faf6cce169eb2bcc93fb45c457b1d31' (2023-12-08)
  → 'github:nixos/nixpkgs/c89d45747b4ba510caa6b2704b574484b6f93e96' (2023-12-08)
```
2023-12-08 20:14:44 +00:00
8b09599c5e sane-sync-music: update files if mtime differs
*presumably* most tagging software updates the mtime when tags change, but i didn't actually check
2023-12-08 15:07:12 +00:00
368099e95a cross: ostree: apply Mindavi's PR feedback 2023-12-08 15:00:29 +00:00
34342b7f48 sync.moby: reduce job count 2023-12-08 14:52:11 +00:00
fcc7ebf5c1 sync.desko: fix mountpoint typo 2023-12-08 12:24:00 +00:00
114bdb30e8 flake: sync-*: refactor 2023-12-08 10:25:01 +00:00
4caf61387e sane-sync-music: add --compress and --compat options 2023-12-08 10:24:48 +00:00
ab020327f4 nixpkgs: 2023-12-07 -> 2023-12-08
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/449c6fb06be60edd4233bb9fe748a0754df185b1' (2023-12-07)
  → 'github:nixos/nixpkgs/f63903a90faf6cce169eb2bcc93fb45c457b1d31' (2023-12-08)
```
2023-12-08 04:26:09 +00:00
bacad0f111 sane-sync-music: add a --force-copy flag 2023-12-07 19:00:51 +00:00
9619c6d2e1 sane-sync-music: refactor to facilitate future tweaks 2023-12-07 18:49:01 +00:00
07c7050335 docs: sane-sync-music: document a bug 2023-12-07 18:17:21 +00:00
24a6fba008 sane-tag-music: remove prefer-path flag to force 2023-12-07 18:08:41 +00:00
51c53b2103 sane-tag-music: allow manually specifying tags via CLI 2023-12-07 18:08:41 +00:00
4ae01aa353 sane-tag-music: auto-create id3 tags for MP3 files 2023-12-07 18:08:41 +00:00
0db1e3728a sway: dont ship custom gtk icons
the GNOME 45 update makes it so default adwaita icons are reliable on moby
2023-12-07 17:56:56 +00:00
83c7657951 sane-tag-music: better handle track names for compilation albums 2023-12-07 17:29:10 +00:00
e20386299f sane-tag-music: add a --force flag 2023-12-07 17:29:10 +00:00
d6e43effde sane-tag-music: better handle verbose track names 2023-12-07 17:29:10 +00:00
bbe8f4a852 sane-tag-music: support opus, aac (limited) 2023-12-07 17:29:10 +00:00
8c98e38053 sane-tag-music: better handling of "Various Artists" 2023-12-07 17:29:10 +00:00
96a36d4d6b sane-tag-music: support ogg files 2023-12-07 17:29:10 +00:00
366a9cea0d fractal: ship optimized build 2023-12-07 16:39:36 +00:00
e810774202 fractal,flare: note that release is incompatible with cross compilation 2023-12-07 16:39:36 +00:00
f2de781cbc nixpkgs: update
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/17411d69e415b5f4910f9a66f89dc6a1866cb410' (2023-12-07)
  → 'github:nixos/nixpkgs/449c6fb06be60edd4233bb9fe748a0754df185b1' (2023-12-07)
```
2023-12-07 16:39:36 +00:00
7f08ad01db sane-tag-music: handle more character encoding edgecases 2023-12-07 15:52:28 +00:00
2c66d8cad0 sane-tag-music: don't crash when file opening fails 2023-12-07 15:51:51 +00:00
fc4803f3fd sane-tag-music: fix bug that song would be extracted into a list of chars 2023-12-07 15:51:17 +00:00
5a6d1dd3c2 sane-tag-music: don't write empty tags 2023-12-07 13:55:45 +00:00
ba42ff7469 sane-tag-music: support mp3 2023-12-07 13:55:45 +00:00
a6cc698c69 signal-desktop-from-src: simplify build process 2023-12-07 13:49:07 +00:00
19b0a62fee flake: support cross deployments from non-binfmt machines 2023-12-07 13:49:07 +00:00
1a6ce11b07 disable binfmt emulation on my build machines 2023-12-07 13:49:07 +00:00
49d8578b83 signal-desktop-from-src: build without emulation 2023-12-07 13:49:07 +00:00
53c0cd570a update todos: moby: install games 2023-12-07 13:49:07 +00:00
4d84bdafed koreader: cross-compile without binfmt 2023-12-07 13:49:07 +00:00
059cd38e7b cross: comment out the firefox hacks
they're unused and broken anyway
2023-12-07 13:49:07 +00:00
8f89d11435 cross: fix wob compilation 2023-12-07 13:49:07 +00:00
243f78ff0e nixpkgs: 2023-12-06 -> 2023-12-07
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/2bea1bc0f98bb316e26d1a5a17df58fce54ca8c4' (2023-12-06)
  → 'github:nixos/nixpkgs/17411d69e415b5f4910f9a66f89dc6a1866cb410' (2023-12-07)

```
2023-12-07 13:49:07 +00:00
21be1b392e servo: switch external storage to zfs pool 2023-12-07 08:57:26 +00:00
8b71e6ac5a sane-stop-all-servo: update with newer services 2023-12-07 05:36:09 +00:00
f5f6298284 re-enable flare-signal 2023-12-06 19:27:47 +00:00
c8370bc290 cross: tried to get cinny to cross-compile, not quite there 2023-12-06 19:26:18 +00:00
abc0ac88d3 flare-signal-nixified: cross-compile without emulation 2023-12-06 19:25:09 +00:00
9da604c0af fractal-nixified: fix build 2023-12-06 19:22:45 +00:00
801da9d321 cross: add a cantBinfmt option to force a package to be built on a non-binfmt machine 2023-12-06 19:20:39 +00:00
ac3b0b873b transmission: increase speed limits 2023-12-06 18:03:08 +00:00
9beee146f2 feeds: sort Youtube feeds 2023-12-06 16:49:40 +00:00
2d06401f3c feeds: subscribe to Tom Scott 2023-12-06 16:19:37 +00:00
2db56f2499 feeds: subscribe to TheB1M 2023-12-06 16:18:03 +00:00
63ea6d7002 feeds: subscribe to Exurb1a 2023-12-06 16:16:29 +00:00
3e2523cc2c feeds: subscribe to Cold Fusion 2023-12-06 16:15:25 +00:00
ad3f5e305e feeds: subscribe to Vox
don't @ me
2023-12-06 16:13:08 +00:00
aa5b9e3db3 user services: wrap with user PATH
notably, this alllows Fractal to open links with the preferred browser
2023-12-06 16:09:07 +00:00
46123719e9 feeds: subscribe to Vihart 2023-12-06 16:09:07 +00:00
16bce990c6 feeds: subscribe to PolyMatter 2023-12-06 16:09:07 +00:00
d55e387187 feeds: subscribe to Vsauce 2023-12-06 16:09:06 +00:00
e75c3375dc feeds: subscribe to Channel5 News 2023-12-06 16:08:50 +00:00
b1c7cb367a feeds: subcsribe to hbomberguy 2023-12-06 15:47:39 +00:00
d63d660ec2 feeds: subscribe to ContraPoints 2023-12-06 15:45:43 +00:00
f24a0a84b5 gpodder: ship on all systems
it's more useful on desko/lappy now that i can ship Youtube feeds.
2023-12-06 15:36:41 +00:00
9704dcc997 feeds: add support for video; subscribe to videos in gpodder 2023-12-06 15:36:05 +00:00
80875d6312 feeds: subscribe to Technology Connections 2023-12-06 15:35:38 +00:00
79f4c9f98c flare-signal-nixified: support defaultCrateOverrides 2023-12-06 14:22:16 +00:00
e2735e151e cross: make buildInQemu more flexible to non-stdenv builders 2023-12-06 14:08:46 +00:00
afb4a88830 moby: enable dialect 2023-12-06 14:00:34 +00:00
84dc8cfd23 cross: build dialect so that it doesn't depend on build binaries at runtime 2023-12-06 13:56:39 +00:00
6ef52677ee nixpkgs: 2023-12-05 -> 2023-12-06
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/3532bd963c2a1417e7d5d9a13b90f3ab8e6b6538' (2023-12-05)
  → 'github:nixos/nixpkgs/2bea1bc0f98bb316e26d1a5a17df58fce54ca8c4' (2023-12-06)
```
2023-12-06 01:45:09 +00:00
73c0e9a742 cross: update error message for fractal 2023-12-05 17:02:33 +00:00
7ff259073e swaync: decrease mpris icon size 64 -> 48px 2023-12-05 17:01:57 +00:00
2bf10c60ee swaynotificationcenter: fix mpris icon height even when it fails to load an icon 2023-12-05 16:57:24 +00:00
72f4b43b54 sxmo: better input mappings 2023-12-05 15:12:08 +00:00
e1ced7a7fe sxmo_hook_inputhandler.sh: remove unused VOL_INCR_2 variable 2023-12-05 10:08:16 +00:00
f41b1cf3b5 sxmo: enable powertoggle -> volup/down for seeking even when screen is on
it's not currently mapped to anything else, so...
2023-12-05 10:04:01 +00:00
70693c2052 sxmo: simplify shortcuts
remove power -> volup DE menu map -- it's accessible via sysmenu now

replace power -> voldown terminal map with just voldown hold
2023-12-05 10:02:19 +00:00
f61d7d0f7d sxmo: decrease power-button timeout 2023-12-05 08:54:18 +00:00
3d7ea75bfc sxmo: simplify XDG_SESSION_TYPE fix 2023-12-05 08:50:19 +00:00
f350d7949c sxmo: fix missing XDG_SESSION_TYPE env var 2023-12-05 08:06:14 +00:00
10c21714ef tangram: build without emulation 2023-12-05 06:02:38 +00:00
2dbae69d50 komikku: build without emulation 2023-12-05 05:16:40 +00:00
4cc5eed884 feeds: subscribe to srslywrong.com 2023-12-05 04:25:25 +00:00
9967868e80 nixpkgs: update
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/d90955124ff3af2d469bf10000b09b9d7dfc5240' (2023-12-04)
  → 'github:nixos/nixpkgs/3532bd963c2a1417e7d5d9a13b90f3ab8e6b6538'
```
2023-12-05 02:04:40 +00:00
bb79752101 cross: gnome-online-accounts: disable unnecessary needsBinfmt
perhaps this was fixed in gnome 44 -> gnome 45
2023-12-04 17:50:12 +00:00
ebd24e5999 cross: evolution-data-server: build w/o binfmt/qemu 2023-12-04 17:50:12 +00:00
7a3fa88559 cross: gnome.mutter: build without binfmt/qemu 2023-12-04 17:50:12 +00:00
cff4fdc5f5 feeds: unsubscribe from Daniel Huberman 2023-12-04 12:36:10 +00:00
e7fc52ff20 cross: build neovim w/o binfmt/qemu 2023-12-04 11:26:28 +00:00
b061aff76e IOCTL_... errrors: track mesa 23.3.1 PR which SHOULD fix them? 2023-12-04 11:07:59 +00:00
b14214761b cross: get jbig2dec to build without binfmt/qemu 2023-12-04 11:07:53 +00:00
9bd684a971 cross: waybar: build without binfmt/qemu 2023-12-04 08:57:57 +00:00
89286be9e1 cross: tidy: remove explicit "final." 2023-12-04 07:42:11 +00:00
991a6a7552 cross: build libpanel w/o binfmt/qemu 2023-12-04 07:26:56 +00:00
04af5558b5 ibus: cross compile without binfmt/qemu 2023-12-04 06:59:00 +00:00
3ee487ca94 cross: fix flatpak to not require binfmt/qemu 2023-12-04 05:05:26 +00:00
20352ff170 calls: cross compile without binfmt/qemu 2023-12-04 04:24:53 +00:00
819894ccbf dino: compile without binfmt/qemu 2023-12-04 04:02:07 +00:00
aa46c4cb8f chatty: remove redundant evolution-data-server override: its done in overlays/preferences.nix 2023-12-04 02:09:52 +00:00
1c75977da7 firefox-extensions: update bypass-paywalls-clean, ublacklist, ublock-origin 2023-12-04 01:47:35 +00:00
c099483305 cross: mark as needsBinfmtOrQemu those packages which can build in either 2023-12-04 01:47:35 +00:00
959e200837 cross: remove upstreamed vulkan-tools fix 2023-12-04 00:38:54 +00:00
d9f0bdb089 nixpkgs, sops-nix, uninsane-dot-org -> 2023-12-04
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/0616776a5e4072e9455e3966d1fce58feefa7a58' (2023-12-03)
  → 'github:nixos/nixpkgs/d90955124ff3af2d469bf10000b09b9d7dfc5240' (2023-12-04)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/e19071f9958c8da4f4347d3d78790d97e98ba22f' (2023-12-02)
  → 'github:Mic92/sops-nix/8bca48cb9a12bbd8766f359ad00336924e91b7f7' (2023-12-03)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/dfb95385d21475da10b63da74ae96d89ab352431' (2023-11-25)
  → 'github:NixOS/nixpkgs/dc01248a9c946953ad4d438b0a626f5c987a93e4' (2023-12-03)
• Updated input 'uninsane-dot-org':
    'git+https://git.uninsane.org/colin/uninsane?ref=refs/heads/master&rev=8a4273489d945f21d7e0ca6aac952460c7d4c391' (2023-11-09)
  → 'git+https://git.uninsane.org/colin/uninsane?ref=refs/heads/master&rev=f865fdd262e249bb1b829900f99cbb67f21a0365' (2023-12-03)
```
2023-12-04 00:34:27 +00:00
b50d723158 servo: nginx: remove "root" in uninsane share path 2023-12-03 15:53:29 +00:00
14739af1b9 servo: nginx: dont follow symlinks in the /share directory 2023-12-03 15:51:01 +00:00
747511c6a8 waybar: link to a better playerctl integration 2023-12-03 15:19:55 +00:00
c96f9cd4de ibus: 1.5.29-rc1 -> 1.5.29
TODO: cleanup this patch and then send to nixpkgs :)
2023-12-03 14:41:56 +00:00
31da2f10c9 sane-wipe: support dino 2023-12-03 14:40:14 +00:00
9e51d7f150 sane-wipe-*: consolidate into one sane-wipe binary 2023-12-03 14:25:35 +00:00
b1b1f8d659 cross: vulkan-tools: link to upstream PR 2023-12-03 14:02:57 +00:00
0c0e7881b1 signal-desktop: document a known bug 2023-12-03 13:58:30 +00:00
6c2f07aab1 cross: disable gnome-2048 fix in light of vala fix being upstreamed (still in staging) 2023-12-03 13:46:01 +00:00
84d2b31c51 cross: fix vulkan-tools compilation 2023-12-03 13:29:44 +00:00
2f23d916f5 sxmo: disable xwayland 2023-12-03 13:03:57 +00:00
d413f4a782 gtkcord4: partially re-enable 2023-12-03 13:01:52 +00:00
c2080cfe1e sway: position Signal on the correct desktop even when run without Xwayland 2023-12-03 13:00:29 +00:00
c687d059c5 signal-desktop: support wayland even when running as a service 2023-12-03 13:00:29 +00:00
a131358c36 signal-desktop: support wayland 2023-12-03 13:00:29 +00:00
0ba012fd7c guis: ship vulkan-tools 2023-12-03 13:00:29 +00:00
b43a693a1e nginx: render directory listings for uninsane.org/share 2023-12-03 09:00:45 +00:00
6f4072efdd servo: enable bitcoind 2023-12-03 08:49:24 +00:00
908984c285 cross: mark mutter as needs binfmt 2023-12-03 02:10:34 +00:00
8772aaec65 zfs: dont ship on moby 2023-12-03 00:58:49 +00:00
f3d605bb63 cross: fix fractal-nixified dep which needs binfmt 2023-12-03 00:40:08 +00:00
6741e0b9e1 nixpkgs: -> tip; sops-nix: 2023-11-27 -> 2023-12-02
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/eb18da27b9cb7e2006574cd962f8a22baf2955f1' (2023-12-02)
  → 'github:nixos/nixpkgs/0616776a5e4072e9455e3966d1fce58feefa7a58' (2023-12-03)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/b1edbf5c0464b4cced90a3ba6f999e671f0af631' (2023-11-27)
  → 'github:Mic92/sops-nix/e19071f9958c8da4f4347d3d78790d97e98ba22f' (2023-12-02)
```
2023-12-03 00:22:07 +00:00
a9f932408c servo: add zfs dataset 2023-12-02 17:38:00 +00:00
a00e6984d9 nixpkgs: 2023-12-01 -> 2023-12-02
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/7c12c8615307e2677a5f769e27ddb0ab4e36a940' (2023-12-01)
  → 'github:nixos/nixpkgs/eb18da27b9cb7e2006574cd962f8a22baf2955f1' (2023-12-02)
```
2023-12-02 00:12:16 +00:00
b4738438b1 nixpkgs: 2023-11-30 -> 2023-12-01
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/8d0f0ca32319439fe9940b1de917dbbdcb8e6f3d' (2023-11-30)
  → 'github:nixos/nixpkgs/7c12c8615307e2677a5f769e27ddb0ab4e36a940' (2023-12-01)
```
2023-12-01 16:19:05 +00:00
416c2f2f39 feeds: remove Hard Fork 2023-12-01 15:35:15 +00:00
589f86010f fix that servo had too low of a inotify watch limit for wan.txt path unit to work 2023-12-01 13:18:05 +00:00
76a7c19996 waybar-sxmo-status: fix volume 2023-12-01 12:51:55 +00:00
3fa676e169 sxmo: waybar: include the volume sxmo status (i.e. microphone/headphones) 2023-12-01 08:45:31 +00:00
3193028c48 sxmo_hook_start: dont start the statusbar items 2023-12-01 07:56:43 +00:00
ba823e8283 sxmo: waybar: provide status more granularly 2023-12-01 07:43:20 +00:00
55f4ef9a4f firefox-extensions.metamask: 11.6.2 -> 11.6.3 2023-12-01 04:33:03 +00:00
200b0dcf7c sxmo: better integrate the status components into waybar
maybe i'll remove all the sxmo-specific logic eventually: it seems generalizable
2023-12-01 03:28:32 +00:00
181f9597c2 Merge branch 'dev' 2023-12-01 01:52:12 +00:00
e55c264c29 activationScripts: fix error messages which would occur on boot, for scripts which only want to run during upgrades 2023-12-01 01:51:37 +00:00
dfbae7e7b5 notify user when nixos deploy/activation completes 2023-12-01 01:29:37 +00:00
98fa50d0eb nixpkgs: 2023-11-29 -> 2023-11-30
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/6711380ae7874005d707d7d03830bd5eee40b43b' (2023-11-29)
  → 'github:nixos/nixpkgs/8d0f0ca32319439fe9940b1de917dbbdcb8e6f3d' (2023-11-30)
```
2023-11-30 23:53:17 +00:00
9503658dec sane-tag-music: handle tracks with soundcloud ID at end of title 2023-11-30 13:59:08 +00:00
3c9bf681b2 sane-tag-music: better handle compilation albums 2023-11-30 13:23:55 +00:00
c1b20675c1 sane-tag-music: handle more path schemas 2023-11-30 12:53:04 +00:00
5703caac19 remove unused scripts/ensure-perms script 2023-11-30 12:53:04 +00:00
7abf7459f9 signal-desktop-from-src: 6.38.0 -> 6.40.0 2023-11-30 09:58:25 +00:00
b14c6ecd5b firefox-extensions: update to latest 2023-11-30 09:47:09 +00:00
455127219d flake: rename check.host-configs -> check.hostConfigs 2023-11-30 01:40:50 +00:00
e235014bde cross: lift defaultCrateOverrides patches to toplevel 2023-11-30 01:40:02 +00:00
ed1bf899b6 fractal: annotate crates which require binfmt for cross compilation 2023-11-30 01:36:53 +00:00
36c7f77a98 nixpkgs: 2023-11-28 -> 2023-11-29
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/c9702bf40b036c0f1d3d5b0aaf3eee2bf920124c' (2023-11-28)
  → 'github:nixos/nixpkgs/6711380ae7874005d707d7d03830bd5eee40b43b' (2023-11-29)
```
2023-11-30 00:50:35 +00:00
996b4f8366 sane-tag-music: update tags even if file had no existing tags 2023-11-29 13:05:05 +00:00
39d94b34d7 sane-tag-music: better handle singles 2023-11-29 12:57:16 +00:00
6edc6841bf sane-tag-music: support directory/tree operations 2023-11-29 12:52:35 +00:00
b2806bd649 sxmo: ship codemadness-frontends 0.6 2023-11-29 12:31:36 +00:00
936118b8cb sane-tag-music: init 2023-11-29 12:29:58 +00:00
120f251590 sxmo-utils: enable sxmo_youtube.sh script 2023-11-29 10:16:00 +00:00
d9962e1b03 codemadness-frontends: fix cross compilation 2023-11-29 10:15:39 +00:00
1396eb2c58 codemadness-frontends: init at 0.8 2023-11-29 09:51:42 +00:00
12daa9830e pkgs/default.nix: fix sorting 2023-11-29 04:29:40 +00:00
3e5e1477b9 pipeline: init at 1.14.1
note that this doesn't cross compile, because of stupid fucking rust build.rs scripts

thanks, openssl-sys
2023-11-29 04:28:19 +00:00
c100f55f1c mpv: associate with opus mimetype 2023-11-29 01:14:15 +00:00
5a0c0dff41 nixpkgs: 2023-11-27 -> 2023-11-28, sops-nix -> 2023-11-27
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/927a9655a267b2b92ece7363efc4f74bf7b2612d' (2023-11-27)
  → 'github:nixos/nixpkgs/c9702bf40b036c0f1d3d5b0aaf3eee2bf920124c' (2023-11-28)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/4be58d802693d7def8622ff34d36714f8db40371' (2023-11-26)
  → 'github:Mic92/sops-nix/b1edbf5c0464b4cced90a3ba6f999e671f0af631' (2023-11-27)
```
2023-11-28 14:16:22 +00:00
8fc5e3611e slskd: fix that the nixos module unconditionall enables nginx 2023-11-28 14:08:08 +00:00
3c3fe16569 servo: enable Soulseek 2023-11-28 11:46:47 +00:00
8eb83bb283 sane-ssl-dump: remove
i never used it
2023-11-28 09:12:39 +00:00
e559f1b960 docs: comment nixpkgs.config options 2023-11-28 08:05:19 +00:00
24a485c213 ripgrep: send cross compilation patch upstream 2023-11-28 00:33:13 +00:00
413669d118 cross: avoid building samba
i was already trying to avoid it, just missed some spots
2023-11-28 00:33:13 +00:00
1729f29374 cross: fix ripgrep 2023-11-28 00:33:13 +00:00
e58833da3b nixpkgs: 2023-11-27 -> 2023-11-27
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/494d8bcc83c99f1c5668cfd5f042b11a0d753749' (2023-11-27)
  → 'github:nixos/nixpkgs/927a9655a267b2b92ece7363efc4f74bf7b2612d' (2023-11-27)
```
2023-11-28 00:33:13 +00:00
e5d4b57d9e overlays/cross: remove dead commented out code 2023-11-28 00:33:13 +00:00
1d61834a95 cross: remove upstreamed mpv patch 2023-11-28 00:33:13 +00:00
b74f55cf54 nixpkgs: 2023-11-26 -> 2023-11-27
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/013f0a99e56eeb1cfb44764fc0d419306b84bbe4' (2023-11-26)
  → 'github:nixos/nixpkgs/494d8bcc83c99f1c5668cfd5f042b11a0d753749' (2023-11-27)
```
2023-11-28 00:33:13 +00:00
eb07a416b4 nixcache: disable big-parallel for servo 2023-11-28 00:33:13 +00:00
ca277567f4 snippets.txt: remove double-spaces 2023-11-27 11:31:52 +00:00
68c2f8f333 fetchFromGitLab: passthru owner and repo 2023-11-27 10:26:44 +00:00
ae5dee394c sane-clone: simplify to not use jq 2023-11-27 10:22:45 +00:00
a94c460a95 sane-clone: note that fetchFromGitLab doesnt pass attrs through in quite the same way 2023-11-27 09:48:59 +00:00
78bf5caf00 cross: fix iotas
i don't know if it's actually runnable. it complains about aspell/gtkspellcheck not finding any dictionary, when i emulate it. but if this is a problem on non-emulated host, i expect it's not specific to cross compilation
2023-11-27 09:48:37 +00:00
c5dbda67ad bonsai: fix cross compilation 2023-11-27 09:19:13 +00:00
2260fbaec5 bonsai/hare-ev/hare-json: sync with nixpkgs PR 2023-11-27 09:19:13 +00:00
4d2fecec13 geary: add my other email account 2023-11-27 07:56:26 +00:00
101677688e trust-dns: note that --debug doesnt act as expected 2023-11-27 06:53:48 +00:00
ca8fefe0c6 sxmo: persist SMS messages 2023-11-27 06:46:57 +00:00
3e8d7ef8e3 sane-wipe-browser: also wipe Brave 2023-11-27 06:45:41 +00:00
71aed74e20 nixcache: disable supercap 2023-11-27 01:48:19 +00:00
712e2c2d12 monero: forward port 18080 2023-11-27 01:48:19 +00:00
892ba7d63e sxmo: disable sway-autoscaler
1: gnome-maps 45 scales way better. 2: the autoscaler seems to not be working anymore (app_id changed?)
2023-11-26 22:03:57 +00:00
96ca2a6585 sxmo-utils: 2023-11-07 -> 2023-11-26 2023-11-26 22:02:47 +00:00
3ebf6470c1 nixpkgs: 2023-11-26 -> 2023-11-26
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/c6c20c63b4c1f715f602ecc46e21521e7825c2fb' (2023-11-26)
  → 'github:nixos/nixpkgs/013f0a99e56eeb1cfb44764fc0d419306b84bbe4' (2023-11-26)
```
2023-11-26 21:58:03 +00:00
f8db994129 nixpkgs: 2023-11-25 -> 2023-11-26; sops-nix -> 2023-11-26
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/e6e261526ebe0762e1fb7a80cd320d09602ade5a' (2023-11-25)
  → 'github:nixos/nixpkgs/c6c20c63b4c1f715f602ecc46e21521e7825c2fb' (2023-11-26)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/49a87c6c827ccd21c225531e30745a9a6464775c' (2023-11-19)
  → 'github:Mic92/sops-nix/4be58d802693d7def8622ff34d36714f8db40371' (2023-11-26)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/decdf666c833a325cb4417041a90681499e06a41' (2023-11-18)
  → 'github:NixOS/nixpkgs/dfb95385d21475da10b63da74ae96d89ab352431' (2023-11-25)
```
2023-11-26 12:33:32 +00:00
dcb74234a6 wine: persist pb powerbomber 2023-11-26 12:18:08 +00:00
ac7c0709e8 monero: enable i2p/tor 2023-11-26 10:11:52 +00:00
7d8595233c servo: enable monero service 2023-11-26 10:11:52 +00:00
5452286493 games: ship hitori 2023-11-26 09:22:40 +00:00
5528b6d87d games: ship wine
launch games with `wine some-game.exe`
2023-11-26 09:20:48 +00:00
6ae3e61d1d sxmo: doc: dedupe_lisgd 2023-11-26 07:01:13 +00:00
a9093a6a69 snippets: fix comment formatting 2023-11-26 06:35:49 +00:00
3dcf7a1204 snippets: add link 2023-11-26 06:35:31 +00:00
c2c63d400f sxmo: bonsai: dont ship service file if sxmo isnt enabled 2023-11-26 02:31:59 +00:00
8f9c9efca1 feeds: econlib: update feed URL 2023-11-26 02:17:36 +00:00
1cb83032a1 feeds: postmarketOS: update feed url 2023-11-26 02:17:23 +00:00
eba9253efe firefox-extensions: bump 2023-11-26 02:16:55 +00:00
9bd0537854 flake: fix "update" for my newer overlay schema 2023-11-26 02:16:25 +00:00
9491190ce4 bonsai: 1.0.0 -> 1.0.2; hare-json/hare-ev deps also updated
nixpkgs has a new version of hare which supports these
2023-11-26 01:21:02 +00:00
9b70d8884d refactor: expose "pkgs.sane.*" even for pkgs which wouldnt be visible in the toplevel scope 2023-11-26 01:20:17 +00:00
9824094fdc nixpkgs: 2023-11-24 -> 2023-11-25
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/869da636fea368dccc4331355894778f64c4a9bb' (2023-11-24)
  → 'github:nixos/nixpkgs/e6e261526ebe0762e1fb7a80cd320d09602ade5a' (2023-11-25)
```
2023-11-25 10:41:25 +00:00
361be1e5d1 fractal-latest: 2023-09-14 -> 2023-11-24 2023-11-25 09:01:41 +00:00
1d38aa62de fractal: persist the new(est) state dir
hope it stops moving around soon lol
2023-11-25 08:57:50 +00:00
d8a4702f1e bonsai: disable auto-updater 2023-11-25 08:57:50 +00:00
75124f18c0 firefox-extensions: update 2023-11-25 08:57:50 +00:00
f54df71d2a fractal-nixified: unstable-2023-09-14 (350a65cb0) -> 5 (2023-11-24)
this gets me the libadwaita/gtk4 updates from gnome 45.
2023-11-25 08:57:50 +00:00
b40b29350a linux-megous: orange-pi-6.5-20230914-1327 -> orange-pi-6.6-20231103-1422 2023-11-25 08:57:42 +00:00
6a9b8b558a cross: mark tangram, gnome-online-accounts as needs binfmt 2023-11-25 06:27:20 +00:00
58f17eac2d cross: mark calls as needs binfmt 2023-11-25 05:55:17 +00:00
41709b6eac cross: mark fractal-nixified as needs binfmt 2023-11-25 05:54:06 +00:00
f9f247df39 cross: annotate which packages require binfmt 2023-11-25 05:05:05 +00:00
4c4a8a0897 neovim: port to wrapNeovimUnstable 2023-11-25 05:02:48 +00:00
10aea555dd neovim: simplify implementation 2023-11-25 04:46:24 +00:00
43f7f07d0e cross: mark argyllcms, jbig2dec as needsBinfmt 2023-11-25 00:13:49 +00:00
3bde4a70ca docs: nix store ping when user doesnt have perms 2023-11-24 22:38:58 +00:00
b9fefdab80 nixcache: fix so supercap can be used as a remote builder w/o any of the others 2023-11-24 22:21:08 +00:00
2ac2aa4e6c tuba: 0.4.1 -> 0.5.0 2023-11-24 21:57:29 +00:00
8f526cd2b5 tuba: remove workaround (fixed via gnome 45 update) 2023-11-24 21:41:07 +00:00
6382ac22cb zsh: new alias to aid cloning an OS package 2023-11-24 21:40:16 +00:00
e1845d37da zsh: order aliases alphabetically 2023-11-24 21:39:52 +00:00
9ccbfd8bf0 sane-clone: init
script to "git clone" a nix packages source code
2023-11-24 21:29:15 +00:00
37a95b97f6 nixpkgs: 2023-11-21 -> 2023-11-24
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/72edcc748a92377d0568c9536ece114dbabb948c' (2023-11-21)
  → 'github:nixos/nixpkgs/869da636fea368dccc4331355894778f64c4a9bb' (2023-11-24)
```
2023-11-24 09:17:21 +00:00
4e0845eb9c cross: koreader-from-src: mark as needsBinfmt 2023-11-24 09:17:17 +00:00
dc8b79b721 sync todo.md 2023-11-24 08:20:03 +00:00
dd0ab41396 refactor: move builders-user-substitutes to be near the other nix extraOptions 2023-11-24 08:13:37 +00:00
c3c3cff6ca enable supercap as remote builder 2023-11-24 08:06:17 +00:00
1f26b36fb8 hosts/modules/hostnames.nix -> hosts/common/hostnames.nix 2023-11-24 07:37:14 +00:00
e990d5a645 hosts: add supercap 2023-11-24 07:35:58 +00:00
121e86013e feeds: add Hard Fork podcast 2023-11-23 05:57:23 +00:00
e0a1dcd51f refactor: remove modules/data/keys.nix 2023-11-23 03:56:00 +00:00
758281f772 modules/feeds: remove unused parameter 2023-11-23 03:37:18 +00:00
fe19065a6a rename working -> .working 2023-11-23 03:29:04 +00:00
a9ba9b77ad enable servo as a remote builder 2023-11-23 02:21:01 +00:00
23f4b2e2e4 nixserve: dependency-inject the pubkey
this is in modules/ dir; shouldn't have that kind of data in it
2023-11-23 02:14:18 +00:00
2d65282643 nixremote: define the user as part of the nixserve module 2023-11-23 02:08:45 +00:00
0bd9125484 remote builder: simplify auth 2023-11-23 02:06:54 +00:00
175144663d desko: dont use ourself as remote substituter/builder 2023-11-23 02:02:19 +00:00
77a0a36bb8 enable remote-building for lappy/moby 2023-11-23 01:59:37 +00:00
f26b64c660 nixremote: fix up perms 2023-11-23 01:44:27 +00:00
3ff9c0ad0c add a "nixremote" user for remote bulding (experimental; builds arent actually enabled yet) 2023-11-23 01:27:28 +00:00
3eb6ce6ff6 cross: apply vala targetOffset fix 2023-11-22 22:11:27 +00:00
845b4b219d cross: update upstreaming status 2023-11-22 22:03:34 +00:00
ffe53086fb cross: update upstreaming notes 2023-11-22 10:22:11 +00:00
5c34c807c5 cross: remove unused networkmanager-fortisslvpn 2023-11-22 09:52:30 +00:00
de2a33580a cross: update upstreaming/blocker notes 2023-11-22 08:33:09 +00:00
08a875d862 cross: remove workaround for obex_data_server, which cross compiles cleanly now 2023-11-22 08:05:14 +00:00
7eeebd632d cross: libpanel: annotate with upstreaming status 2023-11-22 05:02:43 +00:00
a72e9b1a3e cross: remove fixes for packages i dont use 2023-11-22 05:01:34 +00:00
56808821da overlays/cross: disable the unused qt5 stuff; it's not clear it even still works 2023-11-22 03:53:27 +00:00
b53eca6323 cross: annotate xdg-desktop-portal upstreaming status 2023-11-22 03:52:36 +00:00
5a1edb51ef preferences: re-enable pipewire patch. it's still needed 2023-11-22 03:52:15 +00:00
b03328b54f chatty-latest: fix build
evolution-data-server no longer propagates libsecret: upstream nixpkgs applied this patch as well
2023-11-22 03:50:39 +00:00
4e2615f321 xdg-desktop-portal: fix cross compilation 2023-11-22 03:36:50 +00:00
1e14654d95 libpanel: fix cross compilation 2023-11-22 03:36:36 +00:00
0519db4d2c overlays/preferences: disable python stuff no longer needed by komikku 2023-11-22 02:21:23 +00:00
5b9e4df03b overlays/cross: remove upstreamed dead-code 2023-11-22 02:21:00 +00:00
2dbde57f46 overlays/disable-flakey-tests: remove unneeded libwacom patch 2023-11-22 01:42:33 +00:00
d51b7eb124 overlays/disable-flakey-tests: remove unneeded gupnp patch 2023-11-22 01:30:06 +00:00
bfcc071d94 overlays/disable-flakey-tests: remove unnecessary visidata patch 2023-11-22 01:26:38 +00:00
72e1ab6ad6 nixpatches: remove dead mepo patch (merged upstream) 2023-11-22 01:11:49 +00:00
d54efbaacf overlays/preferences: remove unneeded pipewire specialization 2023-11-22 00:54:05 +00:00
7d2f166d67 prefs: remove unnecessary electrum patch 2023-11-22 00:36:48 +00:00
aff3e1aee8 disable gtkcord4 2023-11-22 00:25:14 +00:00
9343447c03 nixpkgs: 2023-11-19 -> 2023-11-21
switch to `master` branch for the GNOME changes

```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/e4ad989506ec7d71f7302cc3067abd82730a4beb' (2023-11-19)
  → 'github:nixos/nixpkgs/72edcc748a92377d0568c9536ece114dbabb948c' (2023-11-21)
```
2023-11-22 00:00:52 +00:00
beb13b8f84 gnome 44 -> 45 2023-11-21 23:12:19 +00:00
70b273a0d2 sxmo: include WM menu in the system menu 2023-11-21 22:39:31 +00:00
fc2bf35588 sway-autoscaler: tune gnome-maps scale 2023-11-21 08:59:34 +00:00
05893ad661 moby: auto-start Signal 2023-11-21 08:28:15 +00:00
fdc9df6b91 sway-autoscaler: cleanup 2023-11-21 08:25:01 +00:00
c6d68e1450 sway: reposition displays 2023-11-21 08:18:35 +00:00
d294be9f35 sxmo: auto-scale the environment to accomodate non-mobile-friendly apps
this is hacky, but it hopefully makes gnome-maps usable, quickly.
an alternative fix would be to theme gnome-maps.
it's likely also that it becomes more mobile-friendly in the gnome 45
release.
2023-11-21 08:14:52 +00:00
98ea4d2dfe abaddon: depend on gnome-keyring 2023-11-21 06:05:52 +00:00
6a950b4e97 abaddon: integrate with swaync services buttons 2023-11-21 03:32:59 +00:00
70292e4f8e abaddon: dont show the "view members" pane, by default 2023-11-21 03:06:58 +00:00
67f8b82740 gitea: track upstream auth fix PR 2023-11-21 02:44:42 +00:00
e9eb139b80 gitea: fix database permissions 2023-11-21 02:27:00 +00:00
61d5b9f048 abaddon: disable platform override (upstream has merged support for aarch64) 2023-11-21 00:37:02 +00:00
c5c86c3964 abaddon: configure for autoconnect 2023-11-21 00:36:43 +00:00
0f233f3a22 gitea: fix database creation error (from latest nixpkgs update) 2023-11-20 10:48:27 +00:00
166bd70a1f nixpkgs: 2023-11-17 -> 2023-11-19; sops-nix -> 2023-11-19
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/c757e9bd77b16ca2e03c89bf8bc9ecb28e0c06ad' (2023-11-17)
  → 'github:nixos/nixpkgs/e4ad989506ec7d71f7302cc3067abd82730a4beb' (2023-11-19)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/0e3a94167dcd10a47b89141f35b2ff9e04b34c46' (2023-11-14)
  → 'github:Mic92/sops-nix/49a87c6c827ccd21c225531e30745a9a6464775c' (2023-11-19)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/9502d0245983bb233da8083b55d60d96fd3c29ff' (2023-11-12)
  → 'github:NixOS/nixpkgs/decdf666c833a325cb4417041a90681499e06a41' (2023-11-18)
```
2023-11-20 10:02:56 +00:00
776b4a6c02 doc: consider ideal input mapping a bit more 2023-11-20 09:21:44 +00:00
75dcc60be5 sxmo/bonsai: simplify bindings: remove power x 3 in favor of powerhold 2023-11-20 09:12:43 +00:00
53034a6ff4 bonsai: simplify the nix code for volume handling 2023-11-20 09:07:51 +00:00
1ea6df9e6c sxmo/bonsai: rework mappings so vol-up/vol-down (app menu/keyboard) trigger instantly w/o timeout 2023-11-20 08:44:10 +00:00
a98a14da3d sxmo: map power hold to just a single power press
less risky than accidentally killing a window (power x3)
2023-11-20 07:36:46 +00:00
629cb8776e sxmo: map volup_three/voldown_three to seek controls when screenoff 2023-11-20 07:35:23 +00:00
96a63d0e89 sxmo: friendly format with which to define bonsai map 2023-11-20 07:25:21 +00:00
c7b065eed9 sxmo_hook_inputhandler: set volume directly
now that i'm using SXMO_NO_AUDIO, i can't use sxmo_audio.sh
2023-11-20 06:57:51 +00:00
89b0b8884b sxmo: set SXMO_STATES=unlock screenoff 2023-11-20 06:53:59 +00:00
644983d27a bonsaid: configure via nix 2023-11-20 06:46:44 +00:00
04d3ea97f3 flake: add a hostConfigs output 2023-11-20 06:29:51 +00:00
11baf471a4 desko: open firewall for nix-serve 2023-11-20 04:58:13 +00:00
505c2d83f2 sxmo-utils: add missing upower dependency 2023-11-20 04:49:38 +00:00
f84ab9a4d1 sxmo: fix that sxmo_state_switch.sh was renamed upstream 2023-11-20 02:36:42 +00:00
0127b61901 sxmo: fix that upstream renamed sxmo_dameons.sh -> sxmo_jobs.sh 2023-11-20 02:31:55 +00:00
b7247f6082 sxmo.bonsaid: make it a proper nix module 2023-11-20 02:31:23 +00:00
9cc72c09dc sxmo: split bonsai out to own file 2023-11-20 01:55:15 +00:00
d763f3b912 nix.extraOptions: tune 2023-11-20 01:37:26 +00:00
f8899aada0 sane.programs.animatch: move to own file 2023-11-19 23:58:00 +00:00
2e983267d4 sxmo-utils: 2023-10-10 -> 2023-11-07 2023-11-19 23:55:41 +00:00
df0c63b300 sxmo-utils: obtain via fetchFromSourcehut 2023-11-19 23:53:37 +00:00
1db2031b76 sxmo-utils: rename from sxmo-utils-latest 2023-11-19 23:44:48 +00:00
2720ccc1fc sxmo-utils.stable: remove
i don't use this. upstream doesn't tag releases enough for it to be useful.
2023-11-19 23:40:56 +00:00
f2aea2c201 phog: 0.1.5 -> 0.1.6 2023-11-19 23:35:00 +00:00
6b9c5f518e koreader-from-src: 2023-10-18 -> 2023.10 (i.e. end-of-month commit) 2023-11-19 23:04:39 +00:00
6d6d2320bd cross: fix mutter build 2023-11-19 11:06:51 +00:00
a1298d6cda nixpkgs 2023-11-14 -> 2023-11-17
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/bf744fe90419885eefced41b3e5ae442d732712d' (2023-11-14)
  → 'github:nixos/nixpkgs/c757e9bd77b16ca2e03c89bf8bc9ecb28e0c06ad' (2023-11-17)
```
2023-11-19 10:57:50 +00:00
52b59bcde8 feeds: add Mic92 (nix dev) 2023-11-19 10:55:51 +00:00
256c85ba5c abaddon: refer to upstream PR for platforms fix 2023-11-19 03:24:46 +00:00
5e484719c2 swaync: sound alerts for abaddon (discord) 2023-11-19 03:14:22 +00:00
6b88379b01 abaddon: 0.1.12 -> 0.1.13
this resolves the warning on launch about the build id not being found
2023-11-19 03:13:44 +00:00
7b29624776 abaddon: force to workspace 1 2023-11-19 03:02:14 +00:00
18f8825cd5 flake: fix deploy so the -light and -test variants work 2023-11-19 02:53:38 +00:00
3d94d02960 flake: fix deploy script map 2023-11-19 02:41:00 +00:00
1f8886684f ship abaddon discord client 2023-11-19 02:37:51 +00:00
29f1da873b sane-weather: enable alternate NWS provider (metar API has changed) 2023-11-19 02:07:07 +00:00
97ec517a1e conky: battery_estimate: fix formatting 2023-11-19 01:51:15 +00:00
2fccaf684c conky: show battery on lappy, and not on desko 2023-11-19 01:50:14 +00:00
008063e645 flake: check target builds hosts in a specific order 2023-11-19 01:36:34 +00:00
867c949604 todo: removed x86GuiApps 2023-11-19 01:36:29 +00:00
7a1af6ee5c firefox: mark as *not* slow to build
this ensures it's always in the base desktop build. otherwise, i never build any browser for desko-light
2023-11-18 23:00:40 +00:00
0893c90c51 refactor how i decide which programs go on which machine (leverage "roles" like pc and handheld) 2023-11-18 22:56:53 +00:00
3c7ebb5385 hosts/modules/gui: refactor package sets 2023-11-18 22:20:38 +00:00
91c2f6fc95 implement sane.programs.slowToBuild and {moby,desko,lappy}-light targets
i'm not sure this is the exact right abstraction, but it's a starting point
2023-11-18 22:06:42 +00:00
ead08fbb5d disable nheko 2023-11-18 22:06:37 +00:00
3ad6a15f56 firefox: reduce scrollbar size :-( 2023-11-18 22:06:34 +00:00
12adb9f10a element-desktop: use electron-bin instead of from-source electron 2023-11-18 22:06:30 +00:00
7b2932b02b firefox-extensions: update to latest 2023-11-18 22:06:26 +00:00
57a47da12c swaync: audibly notify on gtkcord4 notification 2023-11-18 19:19:33 +00:00
84a51faa70 todo.md: document some nix-related bugs 2023-11-18 00:24:16 +00:00
ad495301c0 feeds: add Jeff Geerling 2023-11-18 00:23:58 +00:00
43bd745228 sway: fix broken brightness_down_cmd 2023-11-17 22:46:44 +00:00
fea056d9be todo.md: fix swaync mpris art 2023-11-17 09:36:07 +00:00
2f320db5e2 gtkcord4: add swaync icon and user service 2023-11-17 09:18:14 +00:00
130268491c ship gtkcord4 2023-11-17 08:27:19 +00:00
caf95675d6 packages: persist data for unofficial discord clients 2023-11-17 08:26:36 +00:00
b23281e9dc swaync: make the service buttons more compact 2023-11-17 04:06:26 +00:00
850354b7d7 integrate Signal into swaync and sway/autostart 2023-11-17 04:05:59 +00:00
5c7851e4d9 signal-desktop-from-src: fix SOURCE_EPOCH_DATE to prevent "build to old" runtime error 2023-11-17 03:22:27 +00:00
d85dbf1d33 animatch: correctly persist progress (?) 2023-11-17 01:24:04 +00:00
93ea668db3 install more desktop games 2023-11-17 00:13:34 +00:00
5f426b3efd ship vvvvvv game 2023-11-16 20:50:40 +00:00
4b6a18e4e7 programs: split games into own category; re-enable shattered-pixel-dungeon 2023-11-16 20:26:37 +00:00
35629a2a07 nixpkgs: 2023-11-12 -> 2023-11-14
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/e44462d6021bfe23dfb24b775cc7c390844f773d' (2023-11-12)
  → 'github:nixos/nixpkgs/bf744fe90419885eefced41b3e5ae442d732712d' (2023-11-14)
```
2023-11-16 20:17:30 +00:00
50651d1c03 animatch: provide via upstream 2023-11-16 20:17:20 +00:00
412667dd0e nixpatches: remove gnustep patch (invalid ref) 2023-11-16 20:12:53 +00:00
c46a5089a6 animatch: simplify build 2023-11-16 07:39:49 +00:00
1b3f902dc2 signal-desktop-from-src: use non-builtins fetchurl to fix purity (and NUR build) 2023-11-16 07:24:39 +00:00
bfcb4f92e8 add todo item: remove x86GuiApps 2023-11-16 00:38:06 +00:00
13dda2e533 programs: ship animatch 2023-11-16 00:36:31 +00:00
29c5811b68 animatch: init at 1.0.3 2023-11-16 00:32:02 +00:00
8111757357 firefox-extensions: update (bypass-paywalls-clean, ublacklist, ether-metamask) 2023-11-15 23:20:40 +00:00
93ff8f25a1 signal-desktop-from-src: 6.36.0 -> 6.38.0
apparently after pairing, both versions give the message that they're 'too old'
2023-11-15 23:12:55 +00:00
bb810ac75a signal-desktop: fix directory persistence 2023-11-15 23:07:25 +00:00
87b78d1c89 signal-desktop-from-src: remove unused package.json 2023-11-15 22:41:05 +00:00
bc56f78fd2 signal-desktop-from-src: clean up the package 2023-11-15 22:40:13 +00:00
41ac63f445 signal-desktop-from-src: remove lockfile from repo 2023-11-15 21:41:29 +00:00
b538044d9a nvme-cli: dont ship on moby 2023-11-15 20:41:41 +00:00
02882dd781 nixpkgs: 2023-10-29 -> 2023-11-12; sops-nix -> 2023-11-14; uninsane-dot-org
```
• Updated input 'nixpkgs-unpatched':
    'github:nixos/nixpkgs/0cbe9f69c234a7700596e943bfae7ef27a31b735' (2023-10-29)
  → 'github:nixos/nixpkgs/e44462d6021bfe23dfb24b775cc7c390844f773d' (2023-11-12)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/632c3161a6cc24142c8e3f5529f5d81042571165' (2023-10-29)
  → 'github:Mic92/sops-nix/0e3a94167dcd10a47b89141f35b2ff9e04b34c46' (2023-11-14)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/d87c5d8c41c9b3b39592563242f3a448b5cc4bc9' (2023-10-29)
  → 'github:NixOS/nixpkgs/9502d0245983bb233da8083b55d60d96fd3c29ff' (2023-11-12)
• Updated input 'uninsane-dot-org':
    'git+https://git.uninsane.org/colin/uninsane?ref=refs/heads/master&rev=2419750ca98fc04af42c91e50c49a29c68d465d2' (2023-10-30)
  → 'git+https://git.uninsane.org/colin/uninsane?ref=refs/heads/master&rev=8a4273489d945f21d7e0ca6aac952460c7d4c391' (2023-11-09)
• Updated input 'uninsane-dot-org/flake-utils':
    'github:numtide/flake-utils/dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7' (2023-06-25)
  → 'github:numtide/flake-utils/ff7b65b44d01cf9ba6a71320833626af21126384' (2023-09-12)
```
2023-11-15 07:16:20 +00:00
a24d5581f1 nixpatches: build latest zcash 2023-11-15 07:13:33 +00:00
3125acc95c nixpatches: assorted minor updates 2023-11-15 07:12:46 +00:00
d4c7cfcdf8 ship signal-desktop-from-src 2023-11-15 07:07:58 +00:00
6ff01649d6 signal-desktop-from-src: build with electron_27-bin 2023-11-15 07:07:44 +00:00
dfe724ff52 shattered-pixel-dungeon: persist save file 2023-11-15 05:53:14 +00:00
6c759c226a cross: docs: mention that libgnome-games-support has been merged 2023-11-15 05:52:46 +00:00
d22c2ea56a sxmo: re-enable xwayland
this fixes signal-desktop :)
2023-11-15 05:51:32 +00:00
319bfe205d signal-desktop-from-src: support cross compilation 2023-11-15 05:50:23 +00:00
c4367644dd sane-vpn: add usage/help 2023-11-14 23:29:34 +00:00
69464c2405 snippets: update dead links 2023-11-14 22:43:09 +00:00
1da78d093f ship gnome-2048 game 2023-11-14 03:36:15 +00:00
70ccbb3f59 signal-desktop-from-src: working build 2023-11-14 02:18:28 +00:00
214f24805e swaync: disable vpn::hn action 2023-11-14 01:31:30 +00:00
37f6c9c3bf swaync: improve service icons slightly more 2023-11-14 00:46:39 +00:00
c0ba6dc9f5 swaync: change GPS icon to an actual icon 2023-11-14 00:39:24 +00:00
92159f2a3d dino: simplify service description 2023-11-14 00:39:24 +00:00
3855fb5eb6 geary: integrate with swaync and auto-start 2023-11-14 00:39:24 +00:00
5b3a716819 todo.md: add more apps to install 2023-11-14 00:39:24 +00:00
48b6045ba3 gui: ship superTux, superTuxKart 2023-11-14 00:39:24 +00:00
fd965177ff gui: ship gnome-calendar 2023-11-14 00:39:24 +00:00
b34d332a32 gui: ship gnome-clocks 2023-11-14 00:39:24 +00:00
23db2bf1bf gui: ship gnome-calculator 2023-11-14 00:39:24 +00:00
5996e1f301 servo: fix sane.persist ext store 2023-11-13 05:27:14 +00:00
70a61386b8 add todo for biblioteca doc viewer 2023-11-13 00:14:21 +00:00
53df000ba6 zsh: increase history size 2023-11-12 22:16:33 +00:00
802294ec9c moby: disable dialect program 2023-11-11 02:07:36 +00:00
ed4e289209 moby: fix cross-compilation of dialect/wike 2023-11-10 23:05:12 +00:00
796977713d cross compilation: fix spot build 2023-11-10 22:12:00 +00:00
1f0f84f2f0 programs: add dialect, spot, wike, xq 2023-11-10 19:29:43 +00:00
4e328ae0a3 todo: fix fractal link opener 2023-11-10 18:52:03 +00:00
b572d6d27b new todo: RSS paywall bypass 2023-11-10 17:34:15 +00:00
cd79be5414 feeds: remove unused fields 2023-11-10 17:27:51 +00:00
28dbf10a30 todo.md: remove completed items 2023-11-10 16:25:51 +00:00
96cabc30bc move /etc/nix/source -> /etc/nixos 2023-11-09 17:29:41 +00:00
f5376f2dbb desko: update disk UUIDs 2023-11-09 16:10:11 +00:00
8b25bc96a4 rescue: enable root-on-tmpfs, and consolidate those definitions 2023-11-09 00:15:30 +00:00
6acd363f55 sane.persist.root-on-tmpfs -> sane.root-on-tmpfs 2023-11-09 00:15:04 +00:00
539ee010ab hosts: ship a copy of this repo in /etc/nix/source 2023-11-08 23:56:31 +00:00
5202c572fb firefox-extensions: update to latest 2023-11-08 23:44:27 +00:00
5630b6d8d7 swaync: fix build (github patch changed) 2023-11-08 21:56:46 +00:00
353 changed files with 19238 additions and 55394 deletions

3
.gitignore vendored
View File

@@ -1,5 +1,4 @@
/keep .working
result result
result-* result-*
/secrets/local.nix /secrets/local.nix
/working

View File

@@ -11,7 +11,7 @@ the only hard dependency for my exported pkgs/modules should be [nixpkgs][nixpkg
building <./hosts/> will require [sops][sops]. building <./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-latest`](./pkgs/additional/sxmo-utils/default.nix) - [`sxmo-utils`](./pkgs/additional/sxmo-utils/default.nix)
- [example SXMO deployment](./hosts/modules/gui/sxmo/default.nix) - [example SXMO deployment](./hosts/modules/gui/sxmo/default.nix)
- [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:

50
TODO.md
View File

@@ -1,10 +1,13 @@
## BUGS ## BUGS
- why i need to manually restart `wireguard-wg-ovpns` on servo periodically - nixpkgs date is incorrect (1970.01.01...)
- else DNS fails
- ringer (i.e. dino incoming call) doesn't prevent moby from sleeping - ringer (i.e. dino incoming call) doesn't prevent moby from sleeping
- `nix` operations from lappy hang when `desko` is unreachable
- could at least direct the cache to `http://desko-hn:5001`
## REFACTORING: ## REFACTORING:
- fold hosts/common/home/ssh.nix -> hosts/common/users/colin.nix
### sops/secrets ### sops/secrets
- attach secrets to the thing they're used by (sane.programs) - attach secrets to the thing they're used by (sane.programs)
- rework secrets to leverage `sane.fs` - rework secrets to leverage `sane.fs`
@@ -21,17 +24,13 @@
- fix lightdm-mobile-greeter for newer libhandy - fix lightdm-mobile-greeter for newer libhandy
- port zecwallet-lite to a from-source build - port zecwallet-lite to a from-source build
- REVIEW/integrate jellyfin dataDir config: <https://github.com/NixOS/nixpkgs/pull/233617> - REVIEW/integrate jellyfin dataDir config: <https://github.com/NixOS/nixpkgs/pull/233617>
- remove `libsForQt5.callPackage` broadly: <https://github.com/NixOS/nixpkgs/issues/180841>
#### upstreaming to non-nixpkgs repos #### upstreaming to non-nixpkgs repos
- gtk: build schemas even on cross compilation: <https://github.com/NixOS/nixpkgs/pull/247844> - gtk: build schemas even on cross compilation: <https://github.com/NixOS/nixpkgs/pull/247844>
- sxmo: add new app entries
## IMPROVEMENTS: ## IMPROVEMENTS:
### security/resilience ### security/resilience
- matrix/ntfy: automatically add the ntfy.uninsane.org push URL as part of synapse launch
- ntfy: use a more secure topic
- validate duplicity backups! - validate duplicity backups!
- encrypt more ~ dirs (~/archives, ~/records, ..?) - encrypt more ~ dirs (~/archives, ~/records, ..?)
- best to do this after i know for sure i have good backups - best to do this after i know for sure i have good backups
@@ -49,19 +48,36 @@
- 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?
### faster/better deployments
- remove audacity's dependency on webkitgtk (via wxwidgets)
### user experience ### user experience
#### moby
- fix cpuidle (gets better power consumption): <https://xnux.eu/log/077.html>
- 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: <https://linuxphoneapps.org/apps/ro.hume.cosmin.shoppinglist/> - shopping list (not in nixpkgs): <https://linuxphoneapps.org/apps/ro.hume.cosmin.shoppinglist/>
- offline Wikipedia - offline Wikipedia (or, add to `wike`)
- offline docs viewer (gtk): <https://github.com/workbenchdev/Biblioteca>
- some type of games manager/launcher
- 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)
- note-taking app: <https://linuxphoneapps.org/categories/note-taking/>
- OSK overlay specifically for mobile gaming
- i.e. mock joysticks, for use with SuperTux and SuperTuxKart
- install mobile-friendly games:
- Shattered Pixel Dungeon (nixpkgs `shattered-pixel-dungeon`; doesn't cross-compile b/c openjdk/libIDL) <https://github.com/ebolalex/shattered-pixel-dungeon>
- UnCiv (Civ V clone; nixpkgs `unciv`; doesn't cross-compile): <https://github.com/yairm210/UnCiv>
- Simon Tatham's Puzzle Collection (not in nixpkgs) <https://git.tartarus.org/?p=simon/puzzles.git>
- Shootin Stars (Godot; not in nixpkgs) <https://gitlab.com/greenbeast/shootin-stars>
- numberlink (generic name for Flow Free). not packaged in Nix
- Neverball (https://neverball.org/screenshots.php). nix: as `neverball`
#### moby
- fix cpuidle (gets better power consumption): <https://xnux.eu/log/077.html>
- SwayNC: - SwayNC:
- don't show MPRIS if no players detected - don't show MPRIS if no players detected
- this is a problem of playerctld, i guess - this is a problem of playerctld, i guess
- add option to change audio output - add option to change audio output
- fix colors (red alert) to match overall theme - fix colors (red alert) to match overall theme
- extend width to 100% of portrait mode
- moby: tune GPS - moby: tune GPS
- run only geoclue, and not gpsd, to save power? - run only geoclue, and not gpsd, to save power?
- tune QGPS setting in eg25-control, for less jitter? - tune QGPS setting in eg25-control, for less jitter?
@@ -70,17 +86,14 @@
- manually do smoothing, as some layer between mepo and geoclue/gpsd? - manually do smoothing, as some layer between mepo and geoclue/gpsd?
- moby: show battery state on ssh login - moby: show battery state on ssh login
- moby: improve gPodder launch time - moby: improve gPodder launch time
- sxmo: port to swaybar like i use on desktop
- users in #sxmo claim it's way better perf
- sxmo: fix youtube scripts (package youtube-cli)
- moby: theme GTK apps (i.e. non-adwaita styles) - moby: theme GTK apps (i.e. non-adwaita styles)
- combine multiple icon themes to get one which has the full icon set?
- get adwaita-icon-theme to ship everything even when cross-compiled?
- especially, make the menubar collapsible - especially, make the menubar collapsible
- 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/>
- phog: remove the gnome-shell runtime dependency to save hella closure size - phog: remove the gnome-shell runtime dependency to save hella closure size
#### non-moby #### non-moby
- RSS: integrate a paywall bypass
- 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)
- Helix: make copy-to-system clipboard be the default - Helix: make copy-to-system clipboard be the default
- firefox/librewolf: persist history - firefox/librewolf: persist history
@@ -101,13 +114,10 @@
- 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!
- get moby to build without binfmt emulation (i.e. make all emulation explicit) - fix desko so it doesn't dispatch so many build jobs to servo by default
- then i can distribute builds across servo + desko, and also allow servo to pull packages from desko w/o worrying about purity
## NEW FEATURES: ## NEW FEATURES:
- migrate MAME cabinet to nix - migrate MAME cabinet to nix
- boot it from PXE from servo? - boot it from PXE from servo?
- deploy to new server, and use it as a remote builder
- enable IPv6 - enable IPv6
- package lemonade lemmy app: <https://linuxphoneapps.org/apps/ml.mdwalters.lemonade/> - package lemonade lemmy app: <https://linuxphoneapps.org/apps/ml.mdwalters.lemonade/>

79
flake.lock generated
View File

@@ -1,23 +1,5 @@
{ {
"nodes": { "nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1687709756,
"narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"mobile-nixos": { "mobile-nixos": {
"flake": false, "flake": false,
"locked": { "locked": {
@@ -35,13 +17,29 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-next-unpatched": {
"locked": {
"lastModified": 1705233677,
"narHash": "sha256-eq3VE8QGJsunqqF/BlLslWE1gASp4Hlgp0c78coxat0=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "724e39ebb9b8eda97f17d423f66fbc5a991f4f8d",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "staging-next",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": { "nixpkgs-stable": {
"locked": { "locked": {
"lastModified": 1698544399, "lastModified": 1705033721,
"narHash": "sha256-vhRmPyEyoPkrXF2iykBsWHA05MIaOSmMRLMF7Hul6+s=", "narHash": "sha256-K5eJHmL1/kev6WuqyqqbS1cdNnSidIZ3jeqJ7GbrYnQ=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "d87c5d8c41c9b3b39592563242f3a448b5cc4bc9", "rev": "a1982c92d8980a0114372973cbdfe0a307f1bdea",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -53,16 +51,16 @@
}, },
"nixpkgs-unpatched": { "nixpkgs-unpatched": {
"locked": { "locked": {
"lastModified": 1698611440, "lastModified": 1705254014,
"narHash": "sha256-jPjHjrerhYDy3q9+s5EAsuhyhuknNfowY6yt6pjn9pc=", "narHash": "sha256-4RrVNEqxeji4vqDgzSl7JoCD6a0ag5LF9zXFndtqrpE=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "0cbe9f69c234a7700596e943bfae7ef27a31b735", "rev": "6c08fe3ccf437d8b26bec010fd925ddd6bb0d0d5",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "nixos",
"ref": "nixos-unstable", "ref": "master",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@@ -70,6 +68,7 @@
"root": { "root": {
"inputs": { "inputs": {
"mobile-nixos": "mobile-nixos", "mobile-nixos": "mobile-nixos",
"nixpkgs-next-unpatched": "nixpkgs-next-unpatched",
"nixpkgs-unpatched": "nixpkgs-unpatched", "nixpkgs-unpatched": "nixpkgs-unpatched",
"sops-nix": "sops-nix", "sops-nix": "sops-nix",
"uninsane-dot-org": "uninsane-dot-org" "uninsane-dot-org": "uninsane-dot-org"
@@ -83,11 +82,11 @@
"nixpkgs-stable": "nixpkgs-stable" "nixpkgs-stable": "nixpkgs-stable"
}, },
"locked": { "locked": {
"lastModified": 1698548647, "lastModified": 1705201153,
"narHash": "sha256-7c03OjBGqnwDW0FBaBc+NjfEBxMkza+dxZGJPyIzfFE=", "narHash": "sha256-y0/a4IMDZrc7lAkR7Gcm5R3W2iCBiARHnYZe6vkmiNE=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "632c3161a6cc24142c8e3f5529f5d81042571165", "rev": "70dd0d521f7849338e487a219c1a07c429a66d77",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -96,34 +95,18 @@
"type": "github" "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"
}
},
"uninsane-dot-org": { "uninsane-dot-org": {
"inputs": { "inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unpatched" "nixpkgs-unpatched"
] ]
}, },
"locked": { "locked": {
"lastModified": 1698634059, "lastModified": 1704082841,
"narHash": "sha256-+Oyv6vDyCtBzab/5cTG0nUrHD9gj7KgGfD4D1Rn4fCk=", "narHash": "sha256-4g3lePnUALb8B1m3rEDD6rrZAq2pTN4qaSnStbd676U=",
"ref": "refs/heads/master", "ref": "refs/heads/master",
"rev": "2419750ca98fc04af42c91e50c49a29c68d465d2", "rev": "4a1fa488e64e6c87c6c951e3fafb2684692f64d3",
"revCount": 210, "revCount": 234,
"type": "git", "type": "git",
"url": "https://git.uninsane.org/colin/uninsane" "url": "https://git.uninsane.org/colin/uninsane"
}, },

245
flake.nix
View File

@@ -29,22 +29,24 @@
# - daily: # - daily:
# - nixos-unstable cut from master after enough packages have been built in caches. # - nixos-unstable cut from master after enough packages have been built in caches.
# - every 6 hours: # - every 6 hours:
# - master auto-merged into staging. # - master auto-merged into staging and staging-next
# - staging-next auto-merged into staging. # - staging-next auto-merged into staging.
# - manually, approximately once per month: # - manually, approximately once per month:
# - staging-next is cut from staging. # - staging-next is cut from staging.
# - staging-next merged into master. # - staging-next merged into master.
# #
# which branch to source from? # which branch to source from?
# - for everyday development, prefer `nixos-unstable` branch, as it provides good caching. # - nixos-unstable: for everyday development; it provides good caching
# - if need to test bleeding updates (e.g. if submitting code into staging): # - master: temporarily if i'm otherwise cherry-picking lots of already-applied patches
# - use `staging-next` if it's been cut (i.e. if there's an active staging-next -> master PR) # - staging-next: if testing stuff that's been PR'd into staging, i.e. base library updates.
# - use `staging` if no staging-next branch has been cut. # - staging: maybe if no staging-next -> master PR has been cut yet?
# #
# <https://github.com/nixos/nixpkgs/tree/nixos-unstable> # <https://github.com/nixos/nixpkgs/tree/nixos-unstable>
nixpkgs-unpatched.url = "github:nixos/nixpkgs?ref=nixos-unstable"; # nixpkgs-unpatched.url = "github:nixos/nixpkgs?ref=nixos-unstable";
# nixpkgs-unpatched.url = "github:nixos/nixpkgs?ref=staging-next"; nixpkgs-unpatched.url = "github:nixos/nixpkgs?ref=master";
# nixpkgs-unpatched.url = "github:nixos/nixpkgs?ref=staging"; # 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";
mobile-nixos = { mobile-nixos = {
# <https://github.com/nixos/mobile-nixos> # <https://github.com/nixos/mobile-nixos>
@@ -73,6 +75,7 @@
outputs = { outputs = {
self, self,
nixpkgs-unpatched, nixpkgs-unpatched,
nixpkgs-next-unpatched ? nixpkgs-unpatched,
mobile-nixos, mobile-nixos,
sops-nix, sops-nix,
uninsane-dot-org, uninsane-dot-org,
@@ -91,9 +94,9 @@
# rather than apply our nixpkgs patches as a flake input, do that here instead. # 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 # 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. # repo as the main flake causes the main flake to have an unstable hash.
nixpkgs = (import ./nixpatches/flake.nix).outputs { patchNixpkgs = variant: nixpkgs: (import ./nixpatches/flake.nix).outputs {
self = nixpkgs; inherit variant nixpkgs;
nixpkgs = nixpkgs-unpatched; self = patchNixpkgs variant nixpkgs;
} // { } // {
# provide values that nixpkgs ordinarily sources from the flake.lock file, # provide values that nixpkgs ordinarily sources from the flake.lock file,
# inaccessible to it here because of the import-from-derivation. # inaccessible to it here because of the import-from-derivation.
@@ -109,21 +112,24 @@
inherit (self) shortRev; inherit (self) shortRev;
}; };
nixpkgsCompiledBy = system: nixpkgs.legacyPackages."${system}"; nixpkgs' = patchNixpkgs "master" nixpkgs-unpatched;
nixpkgsCompiledBy = system: nixpkgs'.legacyPackages."${system}";
evalHost = { name, local, target }: nixpkgs.lib.nixosSystem { evalHost = { name, local, target, light ? false, nixpkgs ? nixpkgs' }: nixpkgs.lib.nixosSystem {
system = target; system = target;
modules = [ modules = [
{ {
nixpkgs = (if (local != null) then { nixpkgs.buildPlatform.system = local;
buildPlatform = local;
} else {}) // {
# TODO: does the earlier `system` arg to nixosSystem make its way here?
hostPlatform.system = target;
};
# nixpkgs.buildPlatform = local; # set by instantiate.nix instead
# nixpkgs.config.replaceStdenv = { pkgs }: pkgs.ccacheStdenv; # nixpkgs.config.replaceStdenv = { pkgs }: pkgs.ccacheStdenv;
} }
(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 light {
sane.enableSlowPrograms = false;
})
(import ./hosts/instantiate.nix { hostName = name; }) (import ./hosts/instantiate.nix { hostName = name; })
self.nixosModules.default self.nixosModules.default
self.nixosModules.passthru self.nixosModules.passthru
@@ -136,39 +142,24 @@
]; ];
}; };
in { in {
nixosConfigurations = nixosConfigurations = let
let
hosts = { hosts = {
servo = { name = "servo"; local = "x86_64-linux"; target = "x86_64-linux"; }; servo = { name = "servo"; local = "x86_64-linux"; target = "x86_64-linux"; };
desko = { name = "desko"; 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"; light = true; };
lappy = { name = "lappy"; local = "x86_64-linux"; target = "x86_64-linux"; }; lappy = { name = "lappy"; local = "x86_64-linux"; target = "x86_64-linux"; };
lappy-light = { name = "lappy"; local = "x86_64-linux"; target = "x86_64-linux"; light = true; };
moby = { name = "moby"; local = "x86_64-linux"; target = "aarch64-linux"; }; moby = { name = "moby"; local = "x86_64-linux"; target = "aarch64-linux"; };
moby-light = { name = "moby"; local = "x86_64-linux"; target = "aarch64-linux"; light = true; };
rescue = { name = "rescue"; local = "x86_64-linux"; target = "x86_64-linux"; }; rescue = { name = "rescue"; local = "x86_64-linux"; target = "x86_64-linux"; };
}; };
# cross-compiled builds: instead of emulating the host, build using a cross-compiler. hostsNext = mapAttrs' (h: v: {
# - these are faster to *build* than the emulated variants (useful when tweaking packages), name = "${h}-next";
# - but fewer of their packages can be found in upstream caches. value = v // { nixpkgs = patchNixpkgs "staging-next" nixpkgs-next-unpatched; };
cross = mapAttrValues evalHost hosts; }) hosts;
emulated = mapAttrValues in mapAttrValues evalHost (
({name, local, target}: evalHost { hosts // hostsNext
inherit name target; );
local = null;
})
hosts;
prefixAttrs = prefix: attrs: mapAttrs'
(name: value: {
name = prefix + name;
inherit value;
})
attrs;
in
(prefixAttrs "cross-" cross) //
(prefixAttrs "emulated-" emulated) // {
# prefer native builds for these machines:
inherit (emulated) servo desko lappy rescue;
# prefer cross-compiled builds for these machines:
inherit (cross) moby;
};
# unofficial output # unofficial output
# this produces a EFI-bootable .img file (GPT with a /boot partition and a system (/ or /nix) partition). # this produces a EFI-bootable .img file (GPT with a /boot partition and a system (/ or /nix) partition).
@@ -187,9 +178,13 @@
imgs = mapAttrValues (host: host.config.system.build.img) self.nixosConfigurations; imgs = mapAttrValues (host: host.config.system.build.img) self.nixosConfigurations;
# unofficial output # 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; hostPkgs = mapAttrValues (host: host.config.system.build.pkgs) self.nixosConfigurations;
hostPrograms = mapAttrValues (host: mapAttrValues (p: p.package) host.config.sane.programs) self.nixosConfigurations; hostPrograms = mapAttrValues (host: mapAttrValues (p: p.package) host.config.sane.programs) self.nixosConfigurations;
patched.nixpkgs = nixpkgs';
overlays = { overlays = {
# N.B.: `nix flake check` requires every overlay to take `final: prev:` at defn site, # N.B.: `nix flake check` requires every overlay to take `final: prev:` at defn site,
# hence the weird redundancy. # hence the weird redundancy.
@@ -203,7 +198,7 @@
passthru = final: prev: passthru = final: prev:
let let
mobile = (import "${mobile-nixos}/overlay/overlay.nix"); mobile = (import "${mobile-nixos}/overlay/overlay.nix");
uninsane = uninsane-dot-org.overlay; uninsane = uninsane-dot-org.overlays.default;
in in
(mobile final prev) (mobile final prev)
// (uninsane final prev) // (uninsane final prev)
@@ -234,23 +229,27 @@
# extract only our own packages from the full set. # 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. # because of `nix flake check`, we flatten the package set and only surface x86_64-linux packages.
packages = mapAttrs packages = mapAttrs
(system: allPkgs: (system: passthruPkgs: passthruPkgs.lib.filterAttrs
allPkgs.lib.filterAttrs (name: pkg: (name: pkg:
# keep only packages which will pass `nix flake check`, i.e. keep only: # keep only packages which will pass `nix flake check`, i.e. keep only:
# - derivations (not package sets) # - derivations (not package sets)
# - packages that build for the given platform # - packages that build for the given platform
(! elem name [ "feeds" "pythonPackagesExtensions" ]) (! elem name [ "feeds" "pythonPackagesExtensions" ])
&& (allPkgs.lib.meta.availableOn allPkgs.stdenv.hostPlatform pkg) && (passthruPkgs.lib.meta.availableOn passthruPkgs.stdenv.hostPlatform pkg)
) )
( (
# expose sane packages and chosen inputs (uninsane.org) # expose sane packages and chosen inputs (uninsane.org)
(import ./pkgs { pkgs = allPkgs; }) // { (import ./pkgs { pkgs = passthruPkgs; }) // {
inherit (allPkgs) uninsane-dot-org; inherit (passthruPkgs) uninsane-dot-org;
} }
) )
) )
# self.legacyPackages; # self.legacyPackages;
{ inherit (self.legacyPackages) x86_64-linux; } {
x86_64-linux = (nixpkgsCompiledBy "x86_64-linux").appendOverlays [
self.overlays.passthru
];
}
; ;
apps."x86_64-linux" = apps."x86_64-linux" =
@@ -258,17 +257,27 @@
pkgs = self.legacyPackages."x86_64-linux"; pkgs = self.legacyPackages."x86_64-linux";
sanePkgs = import ./pkgs { inherit pkgs; }; sanePkgs = import ./pkgs { inherit pkgs; };
deployScript = host: addr: action: pkgs.writeShellScript "deploy-${host}" '' deployScript = host: addr: action: pkgs.writeShellScript "deploy-${host}" ''
nix build '.#nixosConfigurations.${host}.config.system.build.toplevel' --out-link ./result-${host} $@ nix build '.#nixosConfigurations.${host}.config.system.build.toplevel' --out-link ./result-${host} "$@"
sudo nix sign-paths -r -k /run/secrets/nix_serve_privkey $(readlink ./result-${host}) sudo nix sign-paths -r -k /run/secrets/nix_serve_privkey $(readlink ./result-${host})
# XXX: this triggers another config eval & (potentially) build. # XXX: this triggers another config eval & (potentially) build.
# if the config changed between these invocations, the above signatures might not apply to the deployed config. # if the config changed between these invocations, the above signatures might not apply to the deployed config.
# let the user handle that edge case by re-running this whole command # let the user handle that edge case by re-running this whole command.
nixos-rebuild --flake '.#${host}' ${action} --target-host colin@${addr} --use-remote-sudo $@ # N.B.: `--fast` option here is critical to cross-compiled deployments: without it the build machine will try to invoke the host machine's `nix` binary.
# TODO: solve this by replacing the nixos-build invocation with:
# - nix-copy-closure --to $host $result
# - on target: nix-env set -p /nix/var/nix/profiles/system $result
# - on target: $result/bin/switch-to-configuration
nixos-rebuild --flake '.#${host}' ${action} --target-host colin@${addr} --use-remote-sudo "$@" --fast
''; '';
deployApp = host: addr: action: {
type = "app";
program = ''${deployScript host addr action}'';
};
# pkg updating. # pkg updating.
# a cleaner alternative lives here: <https://discourse.nixos.org/t/how-can-i-run-the-updatescript-of-personal-packages/25274/2> # 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: { mkUpdater = attrPath: {
type = "app"; type = "app";
program = let program = let
@@ -293,7 +302,7 @@
} else {} } else {}
) )
(pkgs.lib.getAttrFromPath basePath sanePkgs); (pkgs.lib.getAttrFromPath basePath sanePkgs);
mkUpdaters = { ignore ? [] }@opts: basePath: mkUpdaters = { ignore ? [], flakePrefix ? [] }@opts: basePath:
let let
updaters = mkUpdatersNoAliases opts basePath; updaters = mkUpdatersNoAliases opts basePath;
invokeUpdater = name: pkg: invokeUpdater = name: pkg:
@@ -303,7 +312,7 @@
# in case `name` has a `.` in it, we have to quote it # in case `name` has a `.` in it, we have to quote it
escapedPath = builtins.map (p: ''"${p}"'') fullPath; escapedPath = builtins.map (p: ''"${p}"'') fullPath;
updatePath = builtins.concatStringsSep "." ([ "update" "pkgs" ] ++ escapedPath); updatePath = builtins.concatStringsSep "." (flakePrefix ++ escapedPath);
in pkgs.lib.optionalString doUpdateByDefault ( in pkgs.lib.optionalString doUpdateByDefault (
pkgs.lib.escapeShellArgs [ pkgs.lib.escapeShellArgs [
"nix" "run" ".#${updatePath}" "nix" "run" ".#${updatePath}"
@@ -311,8 +320,9 @@
); );
in { in {
type = "app"; type = "app";
# top-level app just invokes the updater of everything one layer below it
program = builtins.toString (pkgs.writeShellScript program = builtins.toString (pkgs.writeShellScript
(builtins.concatStringsSep "-" (["update"] ++ basePath)) (builtins.concatStringsSep "-" (flakePrefix ++ basePath))
(builtins.concatStringsSep (builtins.concatStringsSep
"\n" "\n"
(pkgs.lib.mapAttrsToList invokeUpdater updaters) (pkgs.lib.mapAttrsToList invokeUpdater updaters)
@@ -332,7 +342,7 @@
- `nix run '.#update.feeds'` - `nix run '.#update.feeds'`
- updates metadata for all feeds - updates metadata for all feeds
- `nix run '.#init-feed' <url>` - `nix run '.#init-feed' <url>`
- `nix run '.#deploy-{lappy,moby,moby-test,servo}' [nixos-rebuild args ...]` - `nix run '.#deploy.{desko,lappy,moby,servo}[-light][.test]' [nixos-rebuild args ...]`
- `nix run '.#check'` - `nix run '.#check'`
- make sure all systems build; NUR evaluates - make sure all systems build; NUR evaluates
@@ -346,48 +356,70 @@
nix flake show --option allow-import-from-derivation true nix flake show --option allow-import-from-derivation true
''); '');
}; };
update.pkgs = mkUpdaters { ignore = [ ["feeds"] ]; } []; # wrangle some names to get package updaters which refer back into the flake, but also conditionally ignore certain paths (e.g. sane.feeds).
update.feeds = mkUpdaters {} [ "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 = { init-feed = {
type = "app"; type = "app";
program = "${pkgs.feeds.init-feed}"; program = "${pkgs.feeds.init-feed}";
}; };
deploy-lappy = { deploy = {
type = "app"; lappy = deployApp "lappy" "lappy" "switch";
program = ''${deployScript "lappy" "lappy" "switch"}''; lappy-light = deployApp "lappy-light" "lappy" "switch";
}; moby = deployApp "moby" "moby" "switch";
deploy-moby-test = { moby-light = deployApp "moby-light" "moby" "switch";
type = "app"; moby-test = deployApp "moby" "moby" "test";
program = ''${deployScript "moby" "moby-hn" "test"}''; servo = deployApp "servo" "servo" "switch";
};
deploy-moby = {
type = "app";
program = ''${deployScript "moby" "moby-hn" "switch"}'';
};
deploy-servo = {
type = "app";
program = ''${deployScript "servo" "servo" "switch"}'';
}; };
sync-moby = { sync = {
# copy music from the current device to moby
# TODO: should i actually sync from /mnt/servo-media/Music instead of the local drive?
type = "app"; type = "app";
program = builtins.toString (pkgs.writeShellScript "sync-to-moby" '' program = builtins.toString (pkgs.writeShellScript "sync-all" ''
sudo mount /mnt/moby-home RC_lappy=$(nix run '.#sync.lappy' -- "$@")
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music ~/Music /mnt/moby-home/Music 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-lappy = { 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 # copy music from servo to lappy
# can run this from any device that has ssh access to lappy # can run this from any device that has ssh access to lappy and servo
type = "app"; type = "app";
program = builtins.toString (pkgs.writeShellScript "sync-to-lappy" '' program = builtins.toString (pkgs.writeShellScript "sync-to-lappy" ''
sudo mount /mnt/lappy-home sudo mount /mnt/lappy-home
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music /mnt/servo-media/Music /mnt/lappy-home/Music ${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
# 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 "$@"
''); '');
}; };
@@ -396,12 +428,12 @@
program = builtins.toString (pkgs.writeShellScript "check-all" '' program = builtins.toString (pkgs.writeShellScript "check-all" ''
nix run '.#check.nur' nix run '.#check.nur'
RC0=$? RC0=$?
nix run '.#check.host-configs' nix run '.#check.hostConfigs'
RC1=$? RC1=$?
nix run '.#check.rescue' nix run '.#check.rescue'
RC2=$? RC2=$?
echo "nur: $RC0" echo "nur: $RC0"
echo "host-configs: $RC1" echo "hostConfigs: $RC1"
echo "rescue: $RC2" echo "rescue: $RC2"
exit $(($RC0 | $RC1 | $RC2)) exit $(($RC0 | $RC1 | $RC2))
''); '');
@@ -418,32 +450,59 @@
--option restrict-eval true \ --option restrict-eval true \
--option allow-import-from-derivation true \ --option allow-import-from-derivation true \
--drv-path --show-trace \ --drv-path --show-trace \
-I nixpkgs=$(nix-instantiate --find-file nixpkgs) \ -I nixpkgs=${nixpkgs-unpatched} \
-I ../../ \ -I ../../ \
| tee # tee to prevent interactive mode | tee # tee to prevent interactive mode
''); '');
}; };
check.host-configs = { check.hostConfigs = {
type = "app"; type = "app";
program = let program = let
checkHost = host: '' checkHost = host: let
nix build -v '.#nixosConfigurations.${host}.config.system.build.toplevel' --out-link ./result-${host} -j2 $@ shellHost = pkgs.lib.replaceStrings [ "-" ] [ "_" ] host;
RC_${host}=$? in ''
nix build -v '.#nixosConfigurations.${host}.config.system.build.toplevel' --out-link ./result-${host} -j2 "$@"
RC_${shellHost}=$?
''; '';
in builtins.toString (pkgs.writeShellScript in builtins.toString (pkgs.writeShellScript
"check-host-configs" "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 "desko-light"}
${checkHost "moby-light"}
${checkHost "lappy-light"}
${checkHost "desko"} ${checkHost "desko"}
${checkHost "lappy"} ${checkHost "lappy"}
${checkHost "servo"} ${checkHost "servo"}
${checkHost "moby"} ${checkHost "moby"}
${checkHost "rescue"} ${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 "desko: $RC_desko"
echo "lappy: $RC_lappy" echo "lappy: $RC_lappy"
echo "servo: $RC_servo" echo "servo: $RC_servo"
echo "moby: $RC_moby" echo "moby: $RC_moby"
echo "rescue: $RC_rescue" 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)) exit $(($RC_desko | $RC_lappy | $RC_servo | $RC_moby | $RC_rescue))
'' ''
); );

View File

@@ -9,25 +9,34 @@
# services.distccd.enable = true; # services.distccd.enable = true;
# sane.programs.distcc.enableFor.user.guest = true; # sane.programs.distcc.enableFor.user.guest = true;
# TODO: remove emulation, but need to fix nixos-rebuild to moby for that.
# sane.roles.build-machine.emulation = true;
sops.secrets.colin-passwd.neededForUsers = true; sops.secrets.colin-passwd.neededForUsers = true;
sane.ports.openFirewall = true; # for e.g. nix-serve
sane.roles.build-machine.enable = true; sane.roles.build-machine.enable = true;
sane.roles.ac = true;
sane.roles.client = true; sane.roles.client = true;
sane.roles.dev-machine = true; sane.roles.dev-machine = 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.services.duplicity.enable = true; sane.services.duplicity.enable = true;
sane.services.nixserve.secretKeyFile = config.sops.secrets.nix_serve_privkey.path; sane.services.nixserve.secretKeyFile = config.sops.secrets.nix_serve_privkey.path;
sane.nixcache.substituters.desko = false;
sane.nixcache.remote-builders.desko = false;
sane.gui.sway.enable = true; sane.gui.sway.enable = 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;
sane.programs.guiApps.suggestedPrograms = [ "desktopGuiApps" ];
sane.programs.consoleUtils.suggestedPrograms = [ "consoleMediaUtils" "desktopConsoleUtils" ];
# sane.programs.devPkgs.enableFor.user.colin = true; # sane.programs.devPkgs.enableFor.user.colin = true;
sane.programs.signal-desktop.config.autostart = true;
sane.programs."gnome.geary".config.autostart = true;
boot.loader.efi.canTouchEfiVariables = false; boot.loader.efi.canTouchEfiVariables = false;
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ]; sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];

View File

@@ -1,14 +1,13 @@
{ ... }: { ... }:
{ {
sane.persist.root-on-tmpfs = true;
# increase /tmp space (defaults to 50% of RAM) for building large nix things. # increase /tmp space (defaults to 50% of RAM) for building large nix things.
# a cross-compiled kernel, particularly, will easily use 30+GB of tmp # a cross-compiled kernel, particularly, will easily use 30+GB of tmp
fileSystems."/tmp".options = [ "size=64G" ]; fileSystems."/tmp".options = [ "size=64G" ];
fileSystems."/nix" = { fileSystems."/nix" = {
# device = "/dev/disk/by-uuid/985a0a32-da52-4043-9df7-615adec2e4ff"; # device = "/dev/disk/by-uuid/0ab0770b-7734-4167-88d9-6e4e20bb2a56";
device = "/dev/disk/by-uuid/0ab0770b-7734-4167-88d9-6e4e20bb2a56"; device = "/dev/disk/by-uuid/845d85bf-761d-431b-a406-e6f20909154f";
fsType = "btrfs"; fsType = "btrfs";
options = [ options = [
"compress=zstd" "compress=zstd"
@@ -17,8 +16,8 @@
}; };
fileSystems."/boot" = { fileSystems."/boot" = {
# device = "/dev/disk/by-uuid/CAA7-E7D2"; # device = "/dev/disk/by-uuid/41B6-BAEF";
device = "/dev/disk/by-uuid/41B6-BAEF"; device = "/dev/disk/by-uuid/5049-9AFD";
fsType = "vfat"; fsType = "vfat";
}; };
} }

View File

@@ -7,6 +7,7 @@
sane.roles.client = true; sane.roles.client = true;
sane.roles.dev-machine = true; sane.roles.dev-machine = 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;
@@ -15,11 +16,7 @@
boot.loader.efi.canTouchEfiVariables = false; boot.loader.efi.canTouchEfiVariables = false;
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ]; sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
sane.programs.guiApps.suggestedPrograms = [ sane.programs.stepmania.enableFor.user.colin = true;
"desktopGuiApps"
"stepmania"
];
sane.programs.consoleUtils.suggestedPrograms = [ "consoleMediaUtils" "desktopConsoleUtils" ];
sops.secrets.colin-passwd.neededForUsers = true; sops.secrets.colin-passwd.neededForUsers = true;

View File

@@ -1,8 +1,6 @@
{ ... }: { ... }:
{ {
sane.persist.root-on-tmpfs = true;
fileSystems."/nix" = { fileSystems."/nix" = {
device = "/dev/disk/by-uuid/75230e56-2c69-4e41-b03e-68475f119980"; device = "/dev/disk/by-uuid/75230e56-2c69-4e41-b03e-68475f119980";
fsType = "btrfs"; fsType = "btrfs";

View File

@@ -22,7 +22,6 @@
# the device type informs (at least): # the device type informs (at least):
# - SXMO_WIFI_MODULE # - SXMO_WIFI_MODULE
# - SXMO_RTW_SCAN_INTERVAL # - SXMO_RTW_SCAN_INTERVAL
# - SXMO_SYS_FILES
# - SXMO_TOUCHSCREEN_ID # - SXMO_TOUCHSCREEN_ID
# - SXMO_MONITOR # - SXMO_MONITOR
# - SXMO_ALSA_CONTROL_NAME # - SXMO_ALSA_CONTROL_NAME
@@ -33,7 +32,7 @@
# and so it just wouldn't handle any button inputs (sxmo_hook_inputhandler.sh not on path) # and so it just wouldn't handle any button inputs (sxmo_hook_inputhandler.sh not on path)
SXMO_DEVICE_NAME = "three_button_touchscreen"; SXMO_DEVICE_NAME = "three_button_touchscreen";
}; };
package = (pkgs.sxmo-utils-latest.override { preferSystemd = true; }).overrideAttrs (base: { package = (pkgs.sxmo-utils.override { preferSystemd = true; }).overrideAttrs (base: {
postPatch = (base.postPatch or "") + '' postPatch = (base.postPatch or "") + ''
# after volume-button navigation mode, restore full keyboard functionality # after volume-button navigation mode, restore full keyboard functionality
cp ${./xkb_mobile_normal_buttons} ./configs/xkb/xkb_mobile_normal_buttons cp ${./xkb_mobile_normal_buttons} ./configs/xkb/xkb_mobile_normal_buttons

View File

@@ -20,6 +20,7 @@
]; ];
sane.roles.client = true; sane.roles.client = true;
sane.roles.handheld = true;
sane.zsh.showDeadlines = false; # unlikely to act on them when in shell sane.zsh.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;
@@ -32,15 +33,11 @@
sops.secrets.colin-passwd.neededForUsers = true; sops.secrets.colin-passwd.neededForUsers = true;
sane.gui.sxmo.enable = true; sane.gui.sxmo.enable = true;
sane.programs.guiApps.suggestedPrograms = [ "handheldGuiApps" ];
# sane.programs.consoleUtils.enableFor.user.colin = false; # sane.programs.consoleUtils.enableFor.user.colin = false;
# sane.programs.guiApps.enableFor.user.colin = false; # sane.programs.guiApps.enableFor.user.colin = false;
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.mercurial.enableFor.user.colin = false; # does not cross compile sane.programs.mercurial.enableFor.user.colin = false; # does not cross compile
sane.programs.sequoia.enableFor.user.colin = false; sane.programs.nvme-cli.enableFor.system = false; # does not cross compile (libhugetlbfs)
sane.programs.tuiApps.enableFor.user.colin = false; # visidata, others, don't compile well
# disabled for faster deploys
sane.programs.soundconverter.enableFor.user.colin = false;
# enabled for easier debugging # enabled for easier debugging
sane.programs.eg25-control.enableFor.user.colin = true; sane.programs.eg25-control.enableFor.user.colin = true;
@@ -48,6 +45,8 @@
# sane.programs.ntfy-sh.config.autostart = true; # sane.programs.ntfy-sh.config.autostart = true;
sane.programs.dino.config.autostart = true; sane.programs.dino.config.autostart = true;
sane.programs.signal-desktop.config.autostart = true;
# sane.programs."gnome.geary".config.autostart = true;
# sane.programs.calls.config.autostart = true; # sane.programs.calls.config.autostart = true;
sane.programs.mpv.config.vo = "wlshm"; #< see hosts/common/programs/mpv.nix for details sane.programs.mpv.config.vo = "wlshm"; #< see hosts/common/programs/mpv.nix for details
@@ -55,7 +54,6 @@
# HACK/TODO: make `programs.P.env.VAR` behave according to `mime.priority` # HACK/TODO: make `programs.P.env.VAR` behave according to `mime.priority`
sane.programs.firefox.env = lib.mkForce {}; sane.programs.firefox.env = lib.mkForce {};
sane.programs.epiphany.env.BROWSER = "epiphany"; sane.programs.epiphany.env.BROWSER = "epiphany";
sane.programs.firefox.enableFor.user.colin = false; # use epiphany instead
# note the .conf.d approach: using ~/.config/pipewire/pipewire.conf directly breaks all audio, # note the .conf.d approach: using ~/.config/pipewire/pipewire.conf directly breaks all audio,
# presumably because that deletes the defaults entirely whereas the .conf.d approach selectively overrides defaults # presumably because that deletes the defaults entirely whereas the .conf.d approach selectively overrides defaults

View File

@@ -1,7 +1,6 @@
{ ... }: { ... }:
{ {
sane.persist.root-on-tmpfs = true;
fileSystems."/nix" = { fileSystems."/nix" = {
device = "/dev/disk/by-uuid/1f1271f8-53ce-4081-8a29-60a4a6b5d6f9"; device = "/dev/disk/by-uuid/1f1271f8-53ce-4081-8a29-60a4a6b5d6f9";
fsType = "btrfs"; fsType = "btrfs";

View File

@@ -74,6 +74,7 @@ in
# without this some GUI apps fail: `DRM_IOCTL_MODE_CREATE_DUMB failed: Cannot allocate memory` # 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. # this is because they can't allocate enough video ram.
# see related nixpkgs issue: <https://github.com/NixOS/nixpkgs/issues/260222> # 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. # 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? # 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?

View File

@@ -1,7 +1,7 @@
{ ... }: { ... }:
{ {
fileSystems."/" = { fileSystems."/nix" = {
device = "/dev/disk/by-uuid/44445555-6666-7777-8888-999900001111"; device = "/dev/disk/by-uuid/44445555-6666-7777-8888-999900001111";
fsType = "ext4"; fsType = "ext4";
}; };

View File

@@ -14,12 +14,11 @@
signaldctl.enableFor.user.colin = true; signaldctl.enableFor.user.colin = true;
}; };
sane.roles.ac = true;
sane.roles.build-machine.enable = true; sane.roles.build-machine.enable = true;
sane.roles.build-machine.emulation = false;
sane.zsh.showDeadlines = false; # ~/knowledge doesn't always exist sane.zsh.showDeadlines = false; # ~/knowledge doesn't always exist
sane.programs.consoleUtils.suggestedPrograms = [ sane.programs.consoleUtils.suggestedPrograms = [
"desktopConsoleUtils" "consoleMediaUtils" # notably, for go2tv / casting
"pcConsoleUtils"
"sane-scripts.stop-all-servo" "sane-scripts.stop-all-servo"
]; ];
sane.services.dyn-dns.enable = true; sane.services.dyn-dns.enable = true;
@@ -30,6 +29,8 @@
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.nixcache.substituters.servo = false; sane.nixcache.substituters.servo = false;
sane.nixcache.substituters.desko = false; sane.nixcache.substituters.desko = false;
sane.nixcache.remote-builders.desko = 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
# automatically log in at the virtual consoles. # automatically log in at the virtual consoles.

View File

@@ -1,7 +1,57 @@
# zfs docs:
# - <https://nixos.wiki/wiki/ZFS>
# - <repo:nixos/nixpkgs:nixos/modules/tasks/filesystems/zfs.nix>
#
# zfs check health: `zpool status`
#
# zfs pool creation (requires `boot.supportedFilesystems = [ "zfs" ];`
# - 1. identify disk IDs: `ls -l /dev/disk/by-id`
# - 2. pool these disks: `zpool create -f -m legacy pool raidz ata-ST4000VN008-2DR166_WDH0VB45 ata-ST4000VN008-2DR166_WDH17616 ata-ST4000VN008-2DR166_WDH0VC8Q ata-ST4000VN008-2DR166_WDH17680`
# - legacy documented: <https://superuser.com/questions/790036/what-is-a-zfs-legacy-mount-point>
#
# import pools: `zpool import pool`
# show zfs datasets: `zfs list` (will be empty if haven't imported)
# show zfs properties (e.g. compression): `zfs get all pool`
# set zfs properties: `zfs set compression=on pool`
{ ... }: { ... }:
{ {
sane.persist.root-on-tmpfs = true; # hostId: not used for anything except zfs guardrail?
# [hex(ord(x)) for x in 'serv']
networking.hostId = "73657276";
boot.supportedFilesystems = [ "zfs" ];
# boot.zfs.enabled = true;
boot.zfs.forceImportRoot = false;
# scrub all zfs pools weekly:
services.zfs.autoScrub.enable = true;
boot.extraModprobeConfig = ''
# ZFS likes to use half the ram for its own cache and let the kernel push everything else to swap.
# so, reduce its cache size
# see: <https://askubuntu.com/a/1290387>
# see: <https://serverfault.com/a/1119083>
# see: <https://openzfs.github.io/openzfs-docs/Performance%20and%20Tuning/Module%20Parameters.html#zfs-arc-max>
# for all tunables, see: `man 4 zfs`
# to update these parameters without rebooting:
# - `echo '4294967296' | sane-sudo-redirect /sys/module/zfs/parameters/zfs_arc_max`
options zfs zfs_arc_max=4294967296
'';
# to be able to mount the pool like this, make sure to tell zfs to NOT manage it itself.
# otherwise local-fs.target will FAIL and you will be dropped into a rescue shell.
# - `zfs set mountpoint=legacy pool`
# if done correctly, the pool can be mounted before this `fileSystems` entry is created:
# - `sudo mount -t zfs pool /mnt/persist/pool`
fileSystems."/mnt/pool" = {
device = "pool";
fsType = "zfs";
};
# services.zfs.zed = ... # TODO: zfs can send me emails when disks fail
sane.programs.sysadminUtils.suggestedPrograms = [ "zfs" ];
sane.persist.stores."ext" = {
origin = "/mnt/pool/persist";
storeDescription = "external HDD storage";
};
# increase /tmp space (defaults to 50% of RAM) for building large nix things. # increase /tmp space (defaults to 50% of RAM) for building large nix things.
# even the stock `nixpkgs.linux` consumes > 16 GB of tmp # even the stock `nixpkgs.linux` consumes > 16 GB of tmp
fileSystems."/tmp".options = [ "size=32G" ]; fileSystems."/tmp".options = [ "size=32G" ];
@@ -21,7 +71,7 @@
}; };
# slow, external storage (for archiving, etc) # slow, external storage (for archiving, etc)
fileSystems."/mnt/persist/ext" = { fileSystems."/mnt/usb-hdd" = {
device = "/dev/disk/by-uuid/aa272cff-0fcc-498e-a4cb-0d95fb60631b"; device = "/dev/disk/by-uuid/aa272cff-0fcc-498e-a4cb-0d95fb60631b";
fsType = "btrfs"; fsType = "btrfs";
options = [ options = [
@@ -29,12 +79,7 @@
"defaults" "defaults"
]; ];
}; };
sane.fs."/mnt/usb-hdd".mount = {};
sane.persist.stores."ext" = {
origin = "/mnt/persist/ext/persist";
storeDescription = "external HDD storage";
};
sane.fs."/mnt/persist/ext".mount = {};
sane.persist.sys.byStore.plaintext = [ sane.persist.sys.byStore.plaintext = [
# TODO: this is overly broad; only need media and share directories to be persisted # TODO: this is overly broad; only need media and share directories to be persisted
@@ -69,7 +114,7 @@
the contents should be a subset of what's in ../media/datasets. the contents should be a subset of what's in ../media/datasets.
''; '';
# make sure large media is stored to the HDD # make sure large media is stored to the HDD
sane.persist.sys.ext = [ sane.persist.sys.byStore.ext = [
{ {
user = "colin"; user = "colin";
group = "users"; group = "users";

View File

@@ -27,9 +27,7 @@ in
# view refused packets with: `sudo journalctl -k` # view refused packets with: `sudo journalctl -k`
# networking.firewall.logRefusedPackets = true; # networking.firewall.logRefusedPackets = true;
# The global useDHCP flag is deprecated, therefore explicitly set to false here. # these useDHCP lines are legacy from the auto-generated config. might be safe to remove now?
# Per-interface useDHCP will be mandatory in the future, so this generated config
# replicates the default behaviour.
networking.useDHCP = false; networking.useDHCP = false;
networking.interfaces.eth0.useDHCP = true; networking.interfaces.eth0.useDHCP = true;
# XXX colin: probably don't need this. wlan0 won't be populated unless i touch a value in networking.interfaces.wlan0 # XXX colin: probably don't need this. wlan0 won't be populated unless i touch a value in networking.interfaces.wlan0
@@ -44,41 +42,6 @@ in
# "9.9.9.9" # "9.9.9.9"
# ]; # ];
# use systemd's stub resolver.
# /etc/resolv.conf isn't sophisticated enough to use different servers per net namespace (or link).
# instead, running the stub resolver on a known address in the root ns lets us rewrite packets
# in the ovnps namespace to use the provider's DNS resolvers.
# a weakness is we can only query 1 NS at a time (unless we were to clone the packets?)
# there also seems to be some cache somewhere that's shared between the two namespaces.
# i think this is a libc thing. might need to leverage proper cgroups to _really_ kill it.
# - getent ahostsv4 www.google.com
# - try fix: <https://serverfault.com/questions/765989/connect-to-3rd-party-vpn-server-but-dont-use-it-as-the-default-route/766290#766290>
services.resolved.enable = true;
# without DNSSEC:
# - dig matrix.org => works
# - curl https://matrix.org => works
# with default DNSSEC:
# - dig matrix.org => works
# - curl https://matrix.org => fails
# i don't know why. this might somehow be interfering with the DNS run on this device (trust-dns)
services.resolved.dnssec = "false";
networking.nameservers = [
# use systemd-resolved resolver
# full resolver (which understands /etc/hosts) lives on 127.0.0.53
# stub resolver (just forwards upstream) lives on 127.0.0.54
"127.0.0.53"
];
# nscd -- the Name Service Caching Daemon -- caches DNS query responses
# in a way that's unaware of my VPN routing, so routes are frequently poor against
# services which advertise different IPs based on geolocation.
# nscd claims to be usable without a cache, but in practice i can't get it to not cache!
# nsncd is the Name Service NON-Caching Daemon. it's a drop-in that doesn't cache;
# this is OK on the host -- because systemd-resolved caches. it's probably sub-optimal
# in the netns and we query upstream DNS more often than needed. hm.
# TODO: run a separate recursive resolver in each namespace.
services.nscd.enableNsncd = true;
# services.resolved.extraConfig = '' # services.resolved.extraConfig = ''
# # docs: `man resolved.conf` # # docs: `man resolved.conf`
# # DNS servers to use via the `wg-ovpns` interface. # # DNS servers to use via the `wg-ovpns` interface.

View File

@@ -0,0 +1,84 @@
# as of 2023/12/02: complete blockchain is 530 GiB (on-disk size may be larger)
#
# ports:
# - 8333: for node-to-node communications
# - 8332: rpc (client-to-node)
#
# rpc setup:
# - generate a password
# - use: <https://github.com/bitcoin/bitcoin/blob/master/share/rpcauth/rpcauth.py>
# (rpcauth.py is not included in the `'.#bitcoin'` package result)
# - `wget https://raw.githubusercontent.com/bitcoin/bitcoin/master/share/rpcauth/rpcauth.py`
# - `python ./rpcauth.py colin`
# - copy the hash here. it's SHA-256, so safe to be public.
# - add "rpcuser=colin" and "rpcpassword=<output>" to secrets/servo/bitcoin.conf (i.e. ~/.bitcoin/bitcoin.conf)
# - bitcoin.conf docs: <https://github.com/bitcoin/bitcoin/blob/master/doc/bitcoin-conf.md>
# - validate with `bitcoin-cli -netinfo`
{ config, lib, pkgs, sane-lib, ... }:
let
# wrapper to run bitcoind with the tor onion address as externalip (computed at runtime)
_bitcoindWithExternalIp = with pkgs; writeShellScriptBin "bitcoind" ''
externalip="$(cat /var/lib/tor/onion/bitcoind/hostname)"
exec ${bitcoind}/bin/bitcoind "-externalip=$externalip" "$@"
'';
# the package i provide to services.bitcoind ends up on system PATH, and used by other tools like clightning.
# therefore, even though services.bitcoind only needs `bitcoind` binary, provide all the other bitcoin-related binaries (notably `bitcoin-cli`) as well:
bitcoindWithExternalIp = with pkgs; symlinkJoin {
name = "bitcoind-with-external-ip";
paths = [ _bitcoindWithExternalIp bitcoind ];
};
in
{
sane.persist.sys.byStore.ext = [
# /var/lib/monero/lmdb is what consumes most of the space
{ user = "bitcoind-mainnet"; group = "bitcoind-mainnet"; path = "/var/lib/bitcoind-mainnet"; }
];
# sane.ports.ports."8333" = {
# # this allows other nodes and clients to download blocks from me.
# protocol = [ "tcp" ];
# visibleTo.wan = true;
# description = "colin-bitcoin";
# };
services.tor.relay.onionServices.bitcoind = {
version = 3;
map = [{
# by default tor will route public tor port P to 127.0.0.1:P.
# so if this port is the same as clightning would natively use, then no further config is needed here.
# see: <https://2019.www.torproject.org/docs/tor-manual.html.en#HiddenServicePort>
port = 8333;
# target.port; target.addr; #< set if tor port != clightning port
}];
# allow "tor" group (i.e. bitcoind-mainnet) to read /var/lib/tor/onion/bitcoind/hostname
settings.HiddenServiceDirGroupReadable = true;
};
services.bitcoind.mainnet = {
enable = true;
package = bitcoindWithExternalIp;
rpc.users.colin = {
# see docs at top of file for how to generate this
passwordHMAC = "30002c05d82daa210550e17a182db3f3$6071444151281e1aa8a2729f75e3e2d224e9d7cac3974810dab60e7c28ffaae4";
};
extraConfig = ''
# don't load the wallet, and disable wallet RPC calls
disablewallet=1
# proxy all outbound traffic through Tor
proxy=127.0.0.1:9050
'';
};
users.users.bitcoind-mainnet.extraGroups = [ "tor" ];
systemd.services.bitcoind-mainnet.serviceConfig.RestartSec = "30s"; #< default is 0
sane.users.colin.fs.".bitcoin/bitcoin.conf" = sane-lib.fs.wantedSymlinkTo config.sops.secrets."bitcoin.conf".path;
sops.secrets."bitcoin.conf" = {
mode = "0600";
owner = "colin";
group = "users";
};
sane.programs.bitcoind.enableFor.user.colin = true; # for debugging/administration: `bitcoin-cli`
}

View File

@@ -0,0 +1,766 @@
#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p "python3.withPackages (ps: [ ps.pyln-client ])"
# pyln-client docs: <https://github.com/ElementsProject/lightning/tree/master/contrib/pyln-client>
# terminology:
# - "scid": "Short Channel ID", e.g. 123456x7890x0
# from this id, we can locate the actual channel, its peers, and its parameters
import argparse
import logging
import math
import sys
import time
from concurrent.futures import ThreadPoolExecutor
from dataclasses import dataclass
from enum import Enum
from pyln.client import LightningRpc, Millisatoshi, RpcError
logger = logging.getLogger(__name__)
RPC_FILE = "/var/lib/clightning/bitcoin/lightning-rpc"
# CLTV (HLTC delta) of the final hop
# set this too low and you might get inadvertent channel closures (?)
CLTV = 18
# for every sequentally failed transaction, delay this much before trying again.
# note that the initial route building process can involve 10-20 "transient" failures, as it discovers dead channels.
TX_FAIL_BACKOFF = 0.8
MAX_SEQUENTIAL_JOB_FAILURES = 200
class LoopError(Enum):
""" error when trying to loop sats, or when unable to calculate a route for the loop """
TRANSIENT = "TRANSIENT" # try again, we'll maybe find a different route
NO_ROUTE = "NO_ROUTE"
class RouteError(Enum):
""" error when calculated a route """
HAS_BASE_FEE = "HAS_BASE_FEE"
NO_ROUTE = "NO_ROUTE"
class Metrics:
looped_msat: int = 0
sendpay_fail: int = 0
sendpay_succeed: int = 0
own_bad_channel: int = 0
no_route: int = 0
in_ch_unsatisfiable: int = 0
def __repr__(self) -> str:
return f"looped:{self.looped_msat}, tx:{self.sendpay_succeed}, tx_fail:{self.sendpay_fail}, own_bad_ch:{self.own_bad_channel}, no_route:{self.no_route}, in_ch_restricted:{self.in_ch_unsatisfiable}"
@dataclass
class TxBounds:
max_msat: int
min_msat: int = 0
def __repr__(self) -> str:
return f"TxBounds({self.min_msat} <= msat <= {self.max_msat})"
def is_satisfiable(self) -> bool:
return self.min_msat <= self.max_msat
def raise_max_to_be_satisfiable(self) -> "Self":
if self.max_msat < self.min_msat:
logger.debug(f"raising max_msat to be consistent: {self.max_msat} -> {self.min_msat}")
return TxBounds(self.min_msat, self.min_msat)
return TxBounds(min_msat=self.min_msat, max_msat=self.max_msat)
def intersect(self, other: "TxBounds") -> "Self":
return TxBounds(
min_msat=max(self.min_msat, other.min_msat),
max_msat=min(self.max_msat, other.max_msat),
)
def restrict_to_htlc(self, ch: "LocalChannel", why: str = "") -> "Self":
"""
apply min/max HTLC size restrictions of the given channel.
"""
if ch:
why = why or ch.directed_scid_to_me
if why: why = f"{why}: "
new_min, new_max = self.min_msat, self.max_msat
if ch.htlc_minimum_to_me > self.min_msat:
new_min = ch.htlc_minimum_to_me
logger.debug(f"{why}raising min_msat due to HTLC requirements: {self.min_msat} -> {new_min}")
if ch.htlc_maximum_to_me < self.max_msat:
new_max = ch.htlc_maximum_to_me
logger.debug(f"{why}lowering max_msat due to HTLC requirements: {self.max_msat} -> {new_max}")
return TxBounds(min_msat=new_min, max_msat=new_max)
def restrict_to_zero_fees(self, ch: "LocalChannel"=None, base: int=0, ppm: int=0, why:str = "") -> "Self":
"""
restrict tx size such that PPM fees are zero.
if the channel has a base fee, then `max_msat` is forced to 0.
"""
if ch:
why = why or ch.directed_scid_to_me
self = self.restrict_to_zero_fees(base=ch.to_me["base_fee_millisatoshi"], ppm=ch.to_me["fee_per_millionth"], why=why)
if why: why = f"{why}: "
new_max = self.max_msat
ppm_max = math.ceil(1000000 / ppm) - 1 if ppm != 0 else new_max
if ppm_max < new_max:
logger.debug(f"{why}decreasing max_msat due to fee ppm: {new_max} -> {ppm_max}")
new_max = ppm_max
if base != 0:
logger.debug(f"{why}free route impossible: channel has base fees")
new_max = 0
return TxBounds(min_msat=self.min_msat, max_msat=new_max)
class LocalChannel:
def __init__(self, channels: list, rpc: "RpcHelper"):
assert 0 < len(channels) <= 2, f"unexpected: channel count: {channels}"
out = None
in_ = None
for c in channels:
if c["source"] == rpc.self_id:
assert out is None, f"unexpected: multiple channels from self: {channels}"
out = c
if c["destination"] == rpc.self_id:
assert in_ is None, f"unexpected: multiple channels to self: {channels}"
in_ = c
# assert out is not None, f"no channel from self: {channels}"
# assert in_ is not None, f"no channel to self: {channels}"
if out and in_:
assert out["destination"] == in_["source"], f"channel peers are asymmetric?! {channels}"
assert out["short_channel_id"] == in_["short_channel_id"], f"channel ids differ?! {channels}"
self.from_me = out
self.to_me = in_
self.remote_node = rpc.node(self.remote_peer)
self.peer_ch = rpc.peerchannel(self.scid, self.remote_peer)
self.forwards_from_me = rpc.rpc.listforwards(out_channel=self.scid, status="settled")["forwards"]
def __repr__(self) -> str:
return self.to_str(with_scid=True, with_bal_ratio=True, with_cost=False, with_ppm_theirs=False)
def to_str(
self,
with_peer_id:bool = False,
with_scid:bool = False,
with_bal_msat:bool = False,
with_bal_ratio:bool = False,
with_cost:bool = False,
with_ppm_theirs:bool = False,
with_ppm_mine:bool = False,
with_profits:bool = True,
with_payments:bool = False,
) -> str:
base_flag = "*" if not self.online or self.base_fee_to_me != 0 else ""
alias = f"({self.remote_alias}){base_flag}"
peerid = f" {self.remote_peer}" if with_peer_id else ""
scid = f" scid:{self.scid:>13}" if with_scid else ""
bal = f" S:{int(self.sendable):11}/R:{int(self.receivable):11}" if with_bal_msat else ""
ratio = f" MINE:{(100*self.send_ratio):>8.4f}%" if with_bal_ratio else ""
payments = f" OUT:{int(self.out_fulfilled_msat):>11}/IN:{int(self.in_fulfilled_msat):>11}" if with_payments else ""
profits = f" P$:{int(self.fees_lifetime_mine):>8}" if with_profits else ""
cost = f" COST:{self.opportunity_cost_lent:>8}" if with_cost else ""
ppm_theirs = self.ppm_to_me if self.to_me else "N/A"
ppm_theirs = f" PPM_THEIRS:{ppm_theirs:>6}" if with_ppm_theirs else ""
ppm_mine = self.ppm_from_me if self.from_me else "N/A"
ppm_mine = f" PPM_MINE:{ppm_mine:>6}" if with_ppm_mine else ""
return f"channel{alias:30}{peerid}{scid}{bal}{ratio}{payments}{profits}{cost}{ppm_theirs}{ppm_mine}"
@property
def online(self) -> bool:
return self.from_me and self.to_me
@property
def remote_peer(self) -> str:
if self.from_me:
return self.from_me["destination"]
else:
return self.to_me["source"]
@property
def remote_alias(self) -> str:
return self.remote_node["alias"]
@property
def scid(self) -> str:
if self.from_me:
return self.from_me["short_channel_id"]
else:
return self.to_me["short_channel_id"]
@property
def htlc_minimum_to_me(self) -> Millisatoshi:
return self.to_me["htlc_minimum_msat"]
@property
def htlc_minimum_from_me(self) -> Millisatoshi:
return self.from_me["htlc_minimum_msat"]
@property
def htlc_minimum(self) -> Millisatoshi:
return max(self.htlc_minimum_to_me, self.htlc_minimum_from_me)
@property
def htlc_maximum_to_me(self) -> Millisatoshi:
return self.to_me["htlc_maximum_msat"]
@property
def htlc_maximum_from_me(self) -> Millisatoshi:
return self.from_me["htlc_maximum_msat"]
@property
def htlc_maximum(self) -> Millisatoshi:
return min(self.htlc_maximum_to_me, self.htlc_maximum_from_me)
@property
def direction_to_me(self) -> int:
return self.to_me["direction"]
@property
def direction_from_me(self) -> int:
return self.from_me["direction"]
@property
def directed_scid_to_me(self) -> str:
return f"{self.scid}/{self.direction_to_me}"
@property
def directed_scid_from_me(self) -> str:
return f"{self.scid}/{self.direction_from_me}"
@property
def delay_them(self) -> str:
return self.to_me["delay"]
@property
def delay_me(self) -> str:
return self.from_me["delay"]
@property
def ppm_to_me(self) -> int:
return self.to_me["fee_per_millionth"]
@property
def ppm_from_me(self) -> int:
return self.from_me["fee_per_millionth"]
# return self.peer_ch["fee_proportional_millionths"]
@property
def base_fee_to_me(self) -> int:
return self.to_me["base_fee_millisatoshi"]
@property
def receivable(self) -> int:
return self.peer_ch["receivable_msat"]
@property
def sendable(self) -> int:
return self.peer_ch["spendable_msat"]
@property
def in_fulfilled_msat(self) -> Millisatoshi:
return self.peer_ch["in_fulfilled_msat"]
@property
def out_fulfilled_msat(self) -> Millisatoshi:
return self.peer_ch["out_fulfilled_msat"]
@property
def fees_lifetime_mine(self) -> Millisatoshi:
return sum(fwd["fee_msat"] for fwd in self.forwards_from_me)
@property
def send_ratio(self) -> float:
cap = self.receivable + self.sendable
return self.sendable / cap
@property
def opportunity_cost_lent(self) -> int:
""" how much msat did we gain by pushing their channel to its current balance? """
return int(self.receivable * self.ppm_from_me / 1000000)
class RpcHelper:
def __init__(self, rpc: LightningRpc):
self.rpc = rpc
self.self_id = rpc.getinfo()["id"]
def localchannel(self, scid: str) -> LocalChannel:
listchan = self.rpc.listchannels(scid)
# this assertion would probably indicate a typo in the scid
assert listchan and listchan.get("channels", []) != [], f"bad listchannels for {scid}: {listchan}"
return LocalChannel(listchan["channels"], self)
def node(self, id: str) -> dict:
nodes = self.rpc.listnodes(id)["nodes"]
assert len(nodes) == 1, f"unexpected: multiple nodes for {id}: {nodes}"
return nodes[0]
def peerchannel(self, scid: str, peer_id: str) -> dict:
peerchannels = self.rpc.listpeerchannels(peer_id)["channels"]
channels = [c for c in peerchannels if c["short_channel_id"] == scid]
assert len(channels) == 1, f"expected exactly 1 channel, got: {channels}"
return channels[0]
def try_getroute(self, *args, **kwargs) -> dict | None:
""" wrapper for getroute which returns None instead of error if no route exists """
try:
route = self.rpc.getroute(*args, **kwargs)
except RpcError as e:
logger.debug(f"rpc failed: {e}")
return None
else:
route = route["route"]
if route == []: return None
return route
class LoopRouter:
def __init__(self, rpc: RpcHelper, metrics: Metrics = None):
self.rpc = rpc
self.metrics = metrics or Metrics()
self.bad_channels = [] # list of directed scid
self.nonzero_base_channels = [] # list of directed scid
def drop_caches(self) -> None:
logger.info("LoopRouter.drop_caches()")
self.bad_channels = []
def _get_directed_scid(self, scid: str, direction: int) -> dict:
channels = self.rpc.rpc.listchannels(scid)["channels"]
channels = [c for c in channels if c["direction"] == direction]
assert len(channels) == 1, f"expected exactly 1 channel: {channels}"
return channels[0]
def loop_once(self, out_scid: str, in_scid: str, bounds: TxBounds) -> LoopError|int:
out_ch = self.rpc.localchannel(out_scid)
in_ch = self.rpc.localchannel(in_scid)
if out_ch.directed_scid_from_me in self.bad_channels or in_ch.directed_scid_to_me in self.bad_channels:
logger.info(f"loop {out_scid} -> {in_scid} failed in our own channel")
self.metrics.own_bad_channel += 1
return LoopError.TRANSIENT
# bounds = bounds.restrict_to_htlc(out_ch) # htlc bounds seem to be enforced only in the outward direction
bounds = bounds.restrict_to_htlc(in_ch)
bounds = bounds.restrict_to_zero_fees(in_ch)
if not bounds.is_satisfiable():
self.metrics.in_ch_unsatisfiable += 1
return LoopError.NO_ROUTE
logger.debug(f"route with bounds {bounds}")
route = self.route(out_ch, in_ch, bounds)
logger.debug(f"route: {route}")
if route == RouteError.NO_ROUTE:
self.metrics.no_route += 1
return LoopError.NO_ROUTE
elif route == RouteError.HAS_BASE_FEE:
# try again with a different route
return LoopError.TRANSIENT
amount_msat = route[0]["amount_msat"]
invoice_id = f"loop-{time.time():.6f}".replace(".", "_")
invoice_desc = f"bal {out_scid}:{in_scid}"
invoice = self.rpc.rpc.invoice("any", invoice_id, invoice_desc)
logger.debug(f"invoice: {invoice}")
payment = self.rpc.rpc.sendpay(route, invoice["payment_hash"], invoice_id, amount_msat, invoice["bolt11"], invoice["payment_secret"])
logger.debug(f"sent: {payment}")
try:
wait = self.rpc.rpc.waitsendpay(invoice["payment_hash"])
logger.debug(f"result: {wait}")
except RpcError as e:
self.metrics.sendpay_fail += 1
err_data = e.error["data"]
err_scid, err_dir = err_data["erring_channel"], err_data["erring_direction"]
err_directed_scid = f"{err_scid}/{err_dir}"
logger.debug(f"ch failed, adding to excludes: {err_directed_scid}; {e.error}")
self.bad_channels.append(err_directed_scid)
return LoopError.TRANSIENT
else:
self.metrics.sendpay_succeed += 1
self.metrics.looped_msat += int(amount_msat)
return int(amount_msat)
def route(self, out_ch: LocalChannel, in_ch: LocalChannel, bounds: TxBounds) -> list[dict] | RouteError:
exclude = [
# ensure the payment doesn't cross either channel in reverse.
# note that this doesn't preclude it from taking additional trips through self, with other peers.
# out_ch.directed_scid_to_me,
# in_ch.directed_scid_from_me,
# alternatively, never route through self. this avoids a class of logic error, like what to do with fees i charge "myself".
self.rpc.self_id
] + self.bad_channels + self.nonzero_base_channels
out_peer = out_ch.remote_peer
in_peer = in_ch.remote_peer
route_or_bounds = bounds
while isinstance(route_or_bounds, TxBounds):
old_bounds = route_or_bounds
route_or_bounds = self._find_partial_route(out_peer, in_peer, old_bounds, exclude=exclude)
if route_or_bounds == old_bounds:
return RouteError.NO_ROUTE
if isinstance(route_or_bounds, RouteError):
return route_or_bounds
route = self._add_route_endpoints(route_or_bounds, out_ch, in_ch)
return route
def _find_partial_route(self, out_peer: str, in_peer: str, bounds: TxBounds, exclude: list[str]=[]) -> list[dict] | RouteError | TxBounds:
route = self.rpc.try_getroute(in_peer, amount_msat=bounds.max_msat, riskfactor=0, fromid=out_peer, exclude=exclude, cltv=CLTV)
if route is None:
logger.debug(f"no route for {bounds.max_msat}msat {out_peer} -> {in_peer}")
return RouteError.NO_ROUTE
send_msat = route[0]["amount_msat"]
if send_msat != Millisatoshi(bounds.max_msat):
logger.debug(f"found route with non-zero fee: {send_msat} -> {bounds.max_msat}. {route}")
error = None
for hop in route:
hop_scid = hop["channel"]
hop_dir = hop["direction"]
directed_scid = f"{hop_scid}/{hop_dir}"
ch = self._get_directed_scid(hop_scid, hop_dir)
if ch["base_fee_millisatoshi"] != 0:
self.nonzero_base_channels.append(directed_scid)
error = RouteError.HAS_BASE_FEE
bounds = bounds.restrict_to_zero_fees(ppm=ch["fee_per_millionth"], why=directed_scid)
return bounds.raise_max_to_be_satisfiable() if error is None else error
return route
def _add_route_endpoints(self, route, out_ch: LocalChannel, in_ch: LocalChannel):
inbound_hop = dict(
id=self.rpc.self_id,
channel=in_ch.scid,
direction=in_ch.direction_to_me,
amount_msat=route[-1]["amount_msat"],
delay=route[-1]["delay"],
style="tlv",
)
route = self._add_route_delay(route, in_ch.delay_them) + [ inbound_hop ]
outbound_hop = dict(
id=out_ch.remote_peer,
channel=out_ch.scid,
direction=out_ch.direction_from_me,
amount_msat=route[0]["amount_msat"],
delay=route[0]["delay"] + out_ch.delay_them,
style="tlv",
)
route = [ outbound_hop ] + route
return route
def _add_route_delay(self, route: list[dict], delay: int) -> list[dict]:
return [ dict(hop, delay=hop["delay"] + delay) for hop in route ]
@dataclass
class LoopJob:
out: str # scid
in_: str # scid
amount: int
@dataclass
class LoopJobIdle:
sec: int = 10
class LoopJobDone(Enum):
COMPLETED = "COMPLETED"
ABORTED = "ABORTED"
class AbstractLoopRunner:
def __init__(self, looper: LoopRouter, bounds: TxBounds, parallelism: int):
self.looper = looper
self.bounds = bounds
self.parallelism = parallelism
self.bounds_map = {} # map (out:str, in_:str) -> TxBounds. it's a cache so we don't have to try 10 routes every time.
def pop_job(self) -> LoopJob | LoopJobIdle | LoopJobDone:
raise NotImplemented # abstract method
def finished_job(self, job: LoopJob, progress: int|LoopError) -> None:
raise NotImplemented # abstract method
def run_to_completion(self, exit_on_any_completed:bool = False) -> None:
self.exiting = False
self.exit_on_any_completed = exit_on_any_completed
if self.parallelism == 1:
# run inline to aid debugging
self._worker_thread()
else:
with ThreadPoolExecutor(max_workers=self.parallelism) as executor:
_ = list(executor.map(lambda _i: self._try_invoke(self._worker_thread), range(self.parallelism)))
def drop_caches(self) -> None:
logger.info("AbstractLoopRunner.drop_caches()")
self.looper.drop_caches()
self.bounds_map = {}
def _try_invoke(self, f, *args) -> None:
"""
try to invoke `f` with the provided `args`, and log if it fails.
this overcomes the issue that background tasks which fail via Exception otherwise do so silently.
"""
try:
f(*args)
except Exception as e:
logger.error(f"task failed: {e}")
def _worker_thread(self) -> None:
while not self.exiting:
job = self.pop_job()
logger.debug(f"popped job: {job}")
if isinstance(job, LoopJobDone):
return self._worker_finished(job)
if isinstance(job, LoopJobIdle):
logger.debug(f"idling for {job.sec}")
time.sleep(job.sec)
continue
result = self._execute_job(job)
logger.debug(f"finishing job {job} with {result}")
self.finished_job(job, result)
def _execute_job(self, job: LoopJob) -> LoopError|int:
bounds = self.bounds_map.get((job.out, job.in_), self.bounds)
bounds = bounds.intersect(TxBounds(max_msat=job.amount))
if not bounds.is_satisfiable():
logger.debug(f"TxBounds for job are unsatisfiable; skipping: {bounds} {job}")
return LoopError.NO_ROUTE
amt_looped = self.looper.loop_once(job.out, job.in_, bounds)
if amt_looped in (0, LoopError.NO_ROUTE, LoopError.TRANSIENT):
return amt_looped
logger.info(f"looped {amt_looped} from {job.out} -> {job.in_}")
bounds = bounds.intersect(TxBounds(max_msat=amt_looped))
self.bounds_map[(job.out, job.in_)] = bounds
return amt_looped
def _worker_finished(self, job: LoopJobDone) -> None:
if job == LoopJobDone.COMPLETED and self.exit_on_any_completed:
logger.debug(f"worker completed -> exiting pool")
self.exiting = True
class LoopPairState:
# TODO: use this in MultiLoopBalancer, or stop shoving state in here and put it on LoopBalancer instead.
def __init__(self, out: str, in_: str, amount: int):
self.out = out
self.in_ = in_
self.amount_target = amount
self.amount_looped = 0
self.amount_outstanding = 0
self.tx_fail_count = 0
self.route_fail_count = 0
self.last_job_start_time = None
self.failed_tx_throttler = 0 # increase by one every time we fail, decreases more gradually, when we succeed
class LoopBalancer(AbstractLoopRunner):
def __init__(self, out: str, in_: str, amount: int, looper: LoopRouter, bounds: TxBounds, parallelism: int=1):
super().__init__(looper, bounds, parallelism)
self.state = LoopPairState(out, in_, amount)
def pop_job(self) -> LoopJob | LoopJobIdle | LoopJobDone:
if self.state.tx_fail_count + 10*self.state.route_fail_count >= MAX_SEQUENTIAL_JOB_FAILURES:
logger.info(f"giving up ({self.state.out} -> {self.state.in_}): {self.state.tx_fail_count} tx failures, {self.state.route_fail_count} route failures")
return LoopJobDone.ABORTED
if self.state.tx_fail_count + self.state.route_fail_count > 0:
# N.B.: last_job_start_time is guaranteed to have been set by now
idle_until = self.state.last_job_start_time + TX_FAIL_BACKOFF*self.state.failed_tx_throttler
idle_for = idle_until - time.time()
if self.state.amount_outstanding != 0 or idle_for > 0:
# when we hit transient failures, restrict to just one job in flight at a time.
# this is aimed for the initial route building, where multiple jobs in flight is just useless,
# but it's not a bad idea for network blips, etc, either.
logger.info(f"throttling ({self.state.out} -> {self.state.in_}) for {idle_for:.0f}: {self.state.tx_fail_count} tx failures, {self.state.route_fail_count} route failures")
return LoopJobIdle(idle_for) if idle_for > 0 else LoopJobIdle()
amount_avail = self.state.amount_target - self.state.amount_looped - self.state.amount_outstanding
if amount_avail < self.bounds.min_msat:
if self.state.amount_outstanding == 0: return LoopJobDone.COMPLETED
return LoopJobIdle() # sending out another job would risk over-transferring
amount_this_job = min(amount_avail, self.bounds.max_msat)
self.state.amount_outstanding += amount_this_job
self.state.last_job_start_time = time.time()
return LoopJob(out=self.state.out, in_=self.state.in_, amount=amount_this_job)
def finished_job(self, job: LoopJob, progress: int) -> None:
self.state.amount_outstanding -= job.amount
if progress == LoopError.NO_ROUTE:
self.state.route_fail_count += 1
self.state.failed_tx_throttler += 10
elif progress == LoopError.TRANSIENT:
self.state.tx_fail_count += 1
self.state.failed_tx_throttler += 1
else:
self.state.amount_looped += progress
self.state.tx_fail_count = 0
self.state.route_fail_count = 0
self.state.failed_tx_throttler = max(0, self.state.failed_tx_throttler - 0.2)
logger.info(f"loop progressed ({job.out} -> {job.in_}) {progress}: {self.state.amount_looped} of {self.state.amount_target}")
class MultiLoopBalancer(AbstractLoopRunner):
"""
multiplexes jobs between multiple LoopBalancers.
note that the child LoopBalancers don't actually execute the jobs -- just produce them.
"""
def __init__(self, looper: LoopRouter, bounds: TxBounds, parallelism: int=1):
super().__init__(looper, bounds, parallelism)
self.loops = []
# job_index: increments on every job so we can grab jobs evenly from each LoopBalancer.
# in that event that producers are idling, it can actually increment more than once,
# so don't take this too literally
self.job_index = 0
def add_loop(self, out: LocalChannel, in_: LocalChannel, amount: int) -> None:
"""
start looping sats from out -> in_
"""
assert not any(l.state.out == out.scid and l.state.in_ == in_.scid for l in self.loops), f"tried to add duplicate loops from {out} -> {in_}"
logger.info(f"looping from ({out}) to ({in_})")
self.loops.append(LoopBalancer(out.scid, in_.scid, amount, self.looper, self.bounds, self.parallelism))
def pop_job(self) -> LoopJob | LoopJobIdle | LoopJobDone:
# N.B.: this can be called in parallel, so try to be consistent enough to not crash
idle_job = None
abort_job = None
for i, _ in enumerate(self.loops):
loop = self.loops[(self.job_index + i) % len(self.loops)]
self.job_index += 1
job = loop.pop_job()
if isinstance(job, LoopJob):
return job
if isinstance(job, LoopJobIdle):
idle_job = LoopJobIdle(min(job.sec, idle_job.sec)) if idle_job is not None else job
if job == LoopJobDone.ABORTED:
abort_job = job
# either there's a task to idle, or we have to terminate.
# if terminating, terminate ABORTED if any job aborted, else COMPLETED
if idle_job is not None: return idle_job
if abort_job is not None: return abort_job
return LoopJobDone.COMPLETED
def finished_job(self, job: LoopJob, progress: int) -> None:
# this assumes (enforced externally) that we have only one loop for a given out/in_ pair
for l in self.loops:
if l.state.out == job.out and l.state.in_ == job.in_:
l.finished_job(job, progress)
logger.info(f"total: {self.looper.metrics}")
def balance_loop(rpc: RpcHelper, out: str, in_: str, amount_msat: int, min_msat: int, max_msat: int, parallelism: int):
looper = LoopRouter(rpc)
bounds = TxBounds(min_msat=min_msat, max_msat=max_msat)
balancer = LoopBalancer(out, in_, amount_msat, looper, bounds, parallelism)
balancer.run_to_completion()
def autobalance_once(rpc: RpcHelper, metrics: Metrics, bounds: TxBounds, parallelism: int) -> bool:
"""
autobalances all channels.
returns True if channels are balanced (or as balanced as can be); False if in need of further balancing
"""
looper = LoopRouter(rpc, metrics)
balancer = MultiLoopBalancer(looper, bounds, parallelism)
channels = []
for peerch in rpc.rpc.listpeerchannels()["channels"]:
try:
channels.append(rpc.localchannel(peerch["short_channel_id"]))
except:
logger.info(f"NO CHANNELS for {peerch['peer_id']}")
channels = [ch for ch in channels if ch.online and ch.base_fee_to_me == 0]
give_to = [ ch for ch in channels if ch.send_ratio > 0.95 ]
take_from = [ ch for ch in channels if ch.send_ratio < 0.20 ]
if give_to == [] and take_from == []:
return True
for to in give_to:
for from_ in take_from:
balancer.add_loop(to, from_, 10000000)
balancer.run_to_completion(exit_on_any_completed=True)
return False
def autobalance(rpc: RpcHelper, min_msat: int, max_msat: int, parallelism: int):
bounds = TxBounds(min_msat=min_msat, max_msat=max_msat)
metrics = Metrics()
while not autobalance_once(rpc, metrics, bounds, parallelism):
pass
def show_status(rpc: RpcHelper, full: bool=False):
"""
show a table of channel balances between peers.
"""
for peerch in rpc.rpc.listpeerchannels()["channels"]:
try:
ch = rpc.localchannel(peerch["short_channel_id"])
except:
print(f"{peerch['peer_id']} scid:{peerch['short_channel_id']} state:{peerch['state']} NO CHANNELS")
else:
print(ch.to_str(with_scid=True, with_bal_ratio=True, with_payments=True, with_cost=full, with_ppm_theirs=True, with_ppm_mine=True, with_peer_id=full))
def main():
logging.basicConfig()
logger.setLevel(logging.INFO)
parser = argparse.ArgumentParser(description="rebalance lightning channel balances")
parser.add_argument("--verbose", action="store_true", help="more logging")
parser.add_argument("--min-msat", default="999", help="min transaction size")
parser.add_argument("--max-msat", default="1000000", help="max transaction size")
parser.add_argument("--jobs", default="1", help="how many HTLCs to keep in-flight at once")
subparsers = parser.add_subparsers(help="action")
status_parser = subparsers.add_parser("status")
status_parser.set_defaults(action="status")
status_parser.add_argument("--full", action="store_true", help="more info per channel")
loop_parser = subparsers.add_parser("loop")
loop_parser.set_defaults(action="loop")
loop_parser.add_argument("out", help="peer id to send tx through")
loop_parser.add_argument("in_", help="peer id to receive tx through")
loop_parser.add_argument("amount", help="total amount of msat to loop")
autobal_parser = subparsers.add_parser("autobalance")
autobal_parser.set_defaults(action="autobalance")
args = parser.parse_args()
if args.verbose:
logger.setLevel(logging.DEBUG)
rpc = RpcHelper(LightningRpc(RPC_FILE))
if args.action == "status":
show_status(rpc, full=args.full)
if args.action == "loop":
balance_loop(rpc, out=args.out, in_=args.in_, amount_msat=int(args.amount), min_msat=int(args.min_msat), max_msat=int(args.max_msat), parallelism=int(args.jobs))
if args.action == "autobalance":
autobalance(rpc, min_msat=int(args.min_msat), max_msat=int(args.max_msat), parallelism=int(args.jobs))
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,135 @@
# clightning is an implementation of Bitcoin's Lightning Network.
# as such, this assumes that `services.bitcoin` is enabled.
# docs:
# - tor clightning config: <https://docs.corelightning.org/docs/tor>
# - `lightning-cli` and subcommands: <https://docs.corelightning.org/reference/lightning-cli>
# - `man lightningd-config`
#
# management/setup/use:
# - guide: <https://github.com/ElementsProject/lightning>
#
# debugging:
# - `lightning-cli getlog debug`
# - `lightning-cli listpays` -> show payments this node sent
# - `lightning-cli listinvoices` -> show payments this node received
#
# first, acquire peers:
# - `lightning-cli connect id@host`
# where `id` is the node's pubkey, and `host` is perhaps an ip:port tuple, or a hash.onion:port tuple.
# for testing, choose any node listed on <https://1ml.com>
# - `lightning-cli listpeers`
# should show the new peer, with `connected: true`
#
# then, fund the clightning wallet
# - `lightning-cli newaddr`
#
# then, open channels
# - `lightning-cli connect ...`
# - `lightning-cli fundchannel <node_id> <amount_in_satoshis>`
#
# who to federate with?
# - a lot of the larger nodes allow hands-free channel creation
# - either inbound or outbound, sometimes paid
# - find nodes on:
# - <https://terminal.lightning.engineering/>
# - <https://1ml.com>
# - tor nodes: <https://1ml.com/node?order=capacity&iponionservice=true>
# - <https://lightningnetwork.plus>
# - <https://mempool.space/lightning>
# - <https://amboss.space>
# - a few tor-capable nodes which allow channel creation:
# - <https://c-otto.de/>
# - <https://cyberdyne.sh/>
# - <https://yalls.org/about/>
# - <https://coincept.com/>
# - more resources: <https://www.lopp.net/lightning-information.html>
# - node routability: https://hashxp.org/lightning/node/<id>
# - especially, acquire inbound liquidity via lightningnetwork.plus's swap feature
# - most of the opportunities are gated behind a minimum connection or capacity requirement
#
# tune payment parameters
# - `lightning-cli setchannel <id> [feebase] [feeppm] [htlcmin] [htlcmax] [enforcedelay] [ignorefeelimits]`
# - e.g. `lightning-cli setchannel all 0 10`
# - it's suggested that feebase=0 simplifies routing.
#
# teardown:
# - `lightning-cli withdraw <bc1... dest addr> <amount in satoshis> [feerate]`
#
# sanity:
# - `lightning-cli listfunds`
#
# to receive a payment (do as `clightning` user):
# - `lightning-cli invoice <amount in millisatoshi> <label> <description>`
# - specify amount as `any` if undetermined
# - then give the resulting bolt11 URI to the payer
# to send a payment:
# - `lightning-cli pay <bolt11 URI>`
# - or `lightning-cli pay <bolt11 URI> [amount_msat] [label] [riskfactor] [maxfeepercent] ...`
# - amount_msat must be "null" if the bolt11 URI specifies a value
# - riskfactor defaults to 10
# - maxfeepercent defaults to 0.5
# - label is a human-friendly label for my records
{ config, pkgs, ... }:
{
sane.persist.sys.byStore.ext = [
{ user = "clightning"; group = "clightning"; mode = "0710"; path = "/var/lib/clightning"; }
];
# `lightning-cli` finds its RPC file via `~/.lightning/bitcoin/lightning-rpc`, to message the daemon
sane.user.fs.".lightning".symlink.target = "/var/lib/clightning";
# see bitcoin.nix for how to generate this
services.bitcoind.mainnet.rpc.users.clightning.passwordHMAC =
"befcb82d9821049164db5217beb85439$2c31ac7db3124612e43893ae13b9527dbe464ab2d992e814602e7cb07dc28985";
sane.services.clightning.enable = true;
sane.services.clightning.proxy = "127.0.0.1:9050"; # proxy outgoing traffic through tor
# sane.services.clightning.publicAddress = "statictor:127.0.0.1:9051";
sane.services.clightning.getPublicAddressCmd = "cat /var/lib/tor/onion/clightning/hostname";
services.tor.relay.onionServices.clightning = {
version = 3;
map = [{
# by default tor will route public tor port P to 127.0.0.1:P.
# so if this port is the same as clightning would natively use, then no further config is needed here.
# see: <https://2019.www.torproject.org/docs/tor-manual.html.en#HiddenServicePort>
port = 9735;
# target.port; target.addr; #< set if tor port != clightning port
}];
# allow "tor" group (i.e. clightning) to read /var/lib/tor/onion/clightning/hostname
settings.HiddenServiceDirGroupReadable = true;
};
# must be in "tor" group to read /var/lib/tor/onion/*/hostname
users.users.clightning.extraGroups = [ "tor" ];
systemd.services.clightning.after = [ "tor.service" ];
# lightning-config contains fields from here:
# - <https://docs.corelightning.org/docs/configuration>
# secret config includes:
# - bitcoin-rpcpassword
# - alias=nodename
# - rgb=rrggbb
# - fee-base=<millisatoshi>
# - fee-per-satoshi=<ppm>
# - feature configs (i.e. experimental-xyz options)
sane.services.clightning.extraConfig = ''
log-level=debug:lightningd
# peerswap:
# - config example: <https://github.com/fort-nix/nix-bitcoin/pull/462/files#diff-b357d832705b8ce8df1f41934d613f79adb77c4cd5cd9e9eb12a163fca3e16c6>
# XXX: peerswap crashes clightning on launch. stacktrace is useless.
# plugin=${pkgs.peerswap}/bin/peerswap
# peerswap-db-path=/var/lib/clightning/peerswap/swaps
# peerswap-policy-path=...
'';
sane.services.clightning.extraConfigFiles = [ config.sops.secrets."lightning-config".path ];
sops.secrets."lightning-config" = {
mode = "0640";
owner = "clightning";
group = "clightning";
};
sane.programs.clightning.enableFor.user.colin = true; # for debugging/admin: `lightning-cli`
}

View File

@@ -0,0 +1,10 @@
{ ... }:
{
imports = [
./bitcoin.nix
./clightning.nix
./i2p.nix
./monero.nix
./tor.nix
];
}

View File

@@ -0,0 +1,4 @@
{ ... }:
{
services.i2p.enable = true;
}

View File

@@ -0,0 +1,31 @@
# as of 2023/11/26: complete downloaded blockchain should be 200GiB on disk, give or take.
{ ... }:
{
sane.persist.sys.byStore.ext = [
# /var/lib/monero/lmdb is what consumes most of the space
{ user = "monero"; group = "monero"; path = "/var/lib/monero"; }
];
services.monero.enable = true;
services.monero.limits.upload = 5000; # in kB/s
services.monero.extraConfig = ''
# see: monero doc/ANONYMITY_NETWORKS.md
#
# "If any anonymity network is enabled, transactions being broadcast that lack a valid 'context'
# (i.e. the transaction did not come from a P2P connection) will only be sent to peers on anonymity networks."
#
# i think this means that setting tx-proxy here ensures any transactions sent locally to my node (via RPC)
# will be sent over an anonymity network.
tx-proxy=i2p,127.0.0.1:9000
tx-proxy=tor,127.0.0.1:9050
'';
# monero ports: <https://monero.stackexchange.com/questions/604/what-ports-does-monero-use-rpc-p2p-etc>
# - 18080 = "P2P" monero node <-> monero node connections
# - 18081 = "RPC" monero client -> monero node connections
sane.ports.ports."18080" = {
protocol = [ "tcp" ];
visibleTo.wan = true;
description = "colin-monero-p2p";
};
}

View File

@@ -0,0 +1,25 @@
# tor settings: <https://2019.www.torproject.org/docs/tor-manual.html.en>
{ lib, ... }:
{
# tor hidden service hostnames aren't deterministic, so persist.
# might be able to get away with just persisting /var/lib/tor/onion, not sure.
sane.persist.sys.byStore.plaintext = [
{ user = "tor"; group = "tor"; mode = "0710"; path = "/var/lib/tor"; }
];
# tor: `tor.enable` doesn't start a relay, exit node, proxy, etc. it's minimal.
# tor.client.enable configures a torsocks proxy, accessible *only* to localhost.
# at 127.0.0.1:9050
services.tor.enable = true;
services.tor.client.enable = true;
# in order for services to read /var/lib/tor/onion/*/hostname, they must be able to traverse /var/lib/tor,
# and /var/lib/tor must have g+x.
# DataDirectoryGroupReadable causes tor to use g+rx, technically more than we need, but all the files are 600 so it's fine.
services.tor.settings.DataDirectoryGroupReadable = true;
# StateDirectoryMode defaults to 0700, and thereby prevents the onion hostnames from being group readable
systemd.services.tor.serviceConfig.StateDirectoryMode = lib.mkForce "0710";
users.users.tor.homeMode = "0710"; # home mode defaults to 0700, causing readability problems, enforced by nixos "users" activation script
services.tor.settings.SafeLogging = false; # show actual .onion names in the syslog, else debugging is impossible
}

View File

@@ -1,27 +0,0 @@
{ config, lib, pkgs, ... }:
# using manual ddns now
lib.mkIf false
{
systemd.services.ddns-afraid = {
description = "update dynamic DNS entries for freedns.afraid.org";
serviceConfig = {
EnvironmentFile = config.sops.secrets."ddns_afraid.env".path;
# TODO: ProtectSystem = "strict";
# TODO: ProtectHome = "full";
# TODO: PrivateTmp = true;
};
script = let
curl = "${pkgs.curl}/bin/curl -4";
in ''
${curl} "https://freedns.afraid.org/dynamic/update.php?$AFRAID_KEY"
'';
};
systemd.timers.ddns-afraid = {
wantedBy = [ "multi-user.target" ];
timerConfig = {
OnStartupSec = "2min";
OnUnitActiveSec = "10min";
};
};
}

View File

@@ -1,30 +0,0 @@
{ config, lib, pkgs, ... }:
# we use manual DDNS now
lib.mkIf false
{
systemd.services.ddns-he = {
description = "update dynamic DNS entries for HurricaneElectric";
serviceConfig = {
EnvironmentFile = config.sops.secrets."ddns_he.env".path;
# TODO: ProtectSystem = "strict";
# TODO: ProtectHome = "full";
# TODO: PrivateTmp = true;
};
# HE DDNS API is documented: https://dns.he.net/docs.html
script = let
crl = "${pkgs.curl}/bin/curl -4";
in ''
${crl} "https://he.uninsane.org:$HE_PASSPHRASE@dyn.dns.he.net/nic/update?hostname=he.uninsane.org"
${crl} "https://native.uninsane.org:$HE_PASSPHRASE@dyn.dns.he.net/nic/update?hostname=native.uninsane.org"
${crl} "https://uninsane.org:$HE_PASSPHRASE@dyn.dns.he.net/nic/update?hostname=uninsane.org"
'';
};
systemd.timers.ddns-he = {
wantedBy = [ "multi-user.target" ];
timerConfig = {
OnStartupSec = "2min";
OnUnitActiveSec = "10min";
};
};
}

View File

@@ -3,8 +3,7 @@
imports = [ imports = [
./calibre.nix ./calibre.nix
./coturn.nix ./coturn.nix
./ddns-afraid.nix ./cryptocurrencies
./ddns-he.nix
./email ./email
./ejabberd.nix ./ejabberd.nix
./freshrss.nix ./freshrss.nix
@@ -20,12 +19,14 @@
./matrix ./matrix
./navidrome.nix ./navidrome.nix
./nginx.nix ./nginx.nix
./nixos-prebuild.nix
./nixserve.nix ./nixserve.nix
./ntfy ./ntfy
./pict-rs.nix ./pict-rs.nix
./pleroma.nix ./pleroma.nix
./postgres.nix ./postgres.nix
./prosody ./prosody
./slskd.nix
./transmission.nix ./transmission.nix
./trust-dns.nix ./trust-dns.nix
./wikipedia.nix ./wikipedia.nix

View File

@@ -29,7 +29,7 @@
# - `sudo btrfs qgroup limit 20G /mnt/persist/ext/persist/var/export/playground` # - `sudo btrfs qgroup limit 20G /mnt/persist/ext/persist/var/export/playground`
# to query the quota/status: # to query the quota/status:
# - `sudo btrfs qgroup show -re /var/export/playground` # - `sudo btrfs qgroup show -re /var/export/playground`
sane.persist.sys.ext = [ sane.persist.sys.byStore.ext = [
{ user = "root"; group = "export"; mode = "0775"; path = "/var/export/playground"; } { user = "root"; group = "export"; mode = "0775"; path = "/var/export/playground"; }
]; ];

View File

@@ -172,13 +172,15 @@ in
users.users.sftpgo.extraGroups = [ "export" ]; users.users.sftpgo.extraGroups = [ "export" ];
systemd.services.sftpgo.serviceConfig = { systemd.services.sftpgo = {
ReadOnlyPaths = [ "/var/export" ];
ReadWritePaths = [ "/var/export/playground" ];
after = [ "network-online.target" ]; after = [ "network-online.target" ];
wants = [ "network-online.target" ]; wants = [ "network-online.target" ];
serviceConfig = {
ReadOnlyPaths = [ "/var/export" ];
ReadWritePaths = [ "/var/export/playground" ];
Restart = "always"; Restart = "always";
RestartSec = "20s"; RestartSec = "20s";
}; };
};
} }

View File

@@ -13,6 +13,10 @@
services.gitea.appName = "Perfectly Sane Git"; services.gitea.appName = "Perfectly Sane Git";
# services.gitea.disableRegistration = true; # services.gitea.disableRegistration = true;
services.gitea.database.createDatabase = false; #< silence warning which wants db user and name to be equal
# TODO: remove this after merge: <https://github.com/NixOS/nixpkgs/pull/268849>
services.gitea.database.socket = "/run/postgresql"; #< would have been set if createDatabase = true
# gitea doesn't create the git user # gitea doesn't create the git user
users.users.git = { users.users.git = {
description = "Gitea Service"; description = "Gitea Service";

View File

@@ -1,9 +1,19 @@
# how to update wikipedia snapshot:
# - browse for later snapshots:
# - <https://mirror.accum.se/mirror/wikimedia.org/other/kiwix/zim/wikipedia>
# - DL directly, or via rsync (resumable):
# - `rsync --progress --append-verify rsync://mirror.accum.se/mirror/wikimedia.org/other/kiwix/zim/wikipedia/wikipedia_en_all_maxi_2022-05.zim .`
{ ... }: { ... }:
{ {
sane.persist.sys.byStore.ext = [
{ user = "colin"; group = "users"; path = "/var/lib/kiwix"; }
];
sane.services.kiwix-serve = { sane.services.kiwix-serve = {
enable = true; enable = true;
port = 8013; port = 8013;
zimPaths = [ "/var/lib/uninsane/www-archive/wikipedia_en_all_maxi_2022-05.zim" ]; zimPaths = [ "/var/lib/kiwix/wikipedia_en_all_maxi_2023-11.zim" ];
}; };
services.nginx.virtualHosts."w.uninsane.org" = { services.nginx.virtualHosts."w.uninsane.org" = {

View File

@@ -1,6 +1,8 @@
# config options: # config options:
# - <https://github.com/mautrix/signal/blob/master/mautrix_signal/example-config.yaml> # - <https://github.com/mautrix/signal/blob/master/mautrix_signal/example-config.yaml>
{ config, pkgs, ... }: { config, lib, pkgs, ... }:
lib.mkIf false # disabled 2024/01/11: i don't use it, and pkgs.mautrix-signal had some API changes
{ {
sane.persist.sys.byStore.plaintext = [ sane.persist.sys.byStore.plaintext = [
{ user = "mautrix-signal"; group = "mautrix-signal"; path = "/var/lib/mautrix-signal"; } { user = "mautrix-signal"; group = "mautrix-signal"; path = "/var/lib/mautrix-signal"; }

View File

@@ -54,8 +54,10 @@ in
services.nginx.recommendedOptimisation = true; services.nginx.recommendedOptimisation = true;
# web blog/personal site # web blog/personal site
# alternative way to link stuff into the share:
# sane.fs."/var/lib/uninsane/share/Ubunchu".mount.bind = "/var/lib/uninsane/media/Books/Visual/HiroshiSeo/Ubunchu";
# sane.fs."/var/lib/uninsane/media/Books/Visual/HiroshiSeo/Ubunchu".dir = {};
services.nginx.virtualHosts."uninsane.org" = publog { services.nginx.virtualHosts."uninsane.org" = publog {
root = "${pkgs.uninsane-dot-org}/share/uninsane-dot-org";
# a lot of places hardcode https://uninsane.org, # a lot of places hardcode https://uninsane.org,
# and then when we mix http + non-https, we get CORS violations # and then when we mix http + non-https, we get CORS violations
# and things don't look right. so force SSL. # and things don't look right. so force SSL.
@@ -65,9 +67,28 @@ in
# for OCSP stapling # for OCSP stapling
sslTrustedCertificate = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; sslTrustedCertificate = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
# uninsane.org/share/foo => /var/lib/uninsane/root/share/foo. locations."/" = {
# yes, nginx does not strip the prefix when evaluating against the root. root = "${pkgs.uninsane-dot-org}/share/uninsane-dot-org";
locations."/share".root = "/var/lib/uninsane/root"; tryFiles = "$uri $uri/ @fallback";
};
# unversioned files
locations."@fallback" = {
root = "/var/www/sites/uninsane.org";
};
# uninsane.org/share/foo => /var/www/sites/uninsane.org/share/foo.
# special-cased to enable directory listings
locations."/share" = {
root = "/var/www/sites/uninsane.org";
extraConfig = ''
# autoindex => render directory listings
autoindex on;
# don't follow any symlinks when serving files
# otherwise it allows a directory escape
disable_symlinks on;
'';
};
# allow matrix users to discover that @user:uninsane.org is reachable via matrix.uninsane.org # allow matrix users to discover that @user:uninsane.org is reachable via matrix.uninsane.org
locations."= /.well-known/matrix/server".extraConfig = locations."= /.well-known/matrix/server".extraConfig =
@@ -108,6 +129,19 @@ in
# proxyPass = "http://127.0.0.1:4000"; # proxyPass = "http://127.0.0.1:4000";
# extraConfig = pleromaExtraConfig; # extraConfig = pleromaExtraConfig;
# }; # };
# redirect common feed URIs to the canonical feed
locations."= /atom".extraConfig = "return 301 /atom.xml;";
locations."= /feed".extraConfig = "return 301 /atom.xml;";
locations."= /feed.xml".extraConfig = "return 301 /atom.xml;";
locations."= /rss".extraConfig = "return 301 /atom.xml;";
locations."= /rss.xml".extraConfig = "return 301 /atom.xml;";
locations."= /blog/atom".extraConfig = "return 301 /atom.xml;";
locations."= /blog/atom.xml".extraConfig = "return 301 /atom.xml;";
locations."= /blog/feed".extraConfig = "return 301 /atom.xml;";
locations."= /blog/feed.xml".extraConfig = "return 301 /atom.xml;";
locations."= /blog/rss".extraConfig = "return 301 /atom.xml;";
locations."= /blog/rss.xml".extraConfig = "return 301 /atom.xml;";
}; };
@@ -135,7 +169,6 @@ in
security.acme.defaults.email = "admin.acme@uninsane.org"; security.acme.defaults.email = "admin.acme@uninsane.org";
sane.persist.sys.byStore.plaintext = [ sane.persist.sys.byStore.plaintext = [
# TODO: mode?
{ user = "acme"; group = "acme"; path = "/var/lib/acme"; } { user = "acme"; group = "acme"; path = "/var/lib/acme"; }
{ user = "colin"; group = "users"; path = "/var/www/sites"; } { user = "colin"; group = "users"; path = "/var/www/sites"; }
]; ];

View File

@@ -0,0 +1,26 @@
{ lib, pkgs, ... }:
lib.optionalAttrs false # disabled until i can be sure it's not gonna OOM my server in the middle of the night
{
systemd.services.nixos-prebuild = {
description = "build a nixos image with all updated deps";
path = with pkgs; [ coreutils git nix ];
script = ''
working=$(mktemp -d /tmp/nixos-prebuild.XXXXXX)
pushd "$working"
git clone https://git.uninsane.org/colin/nix-files.git \
&& cd nix-files \
&& nix flake update \
|| true
RC=$(nix run "$working/nix-files#check" -- -j1 --cores 5 --builders "")
popd
rm -rf "$working"
exit "$RC"
'';
};
systemd.timers.nixos-prebuild = {
wantedBy = [ "multi-user.target" ];
timerConfig.OnCalendar = "11,23:00:00";
};
}

View File

@@ -64,7 +64,7 @@ in
protocol = [ "tcp" ]; protocol = [ "tcp" ];
visibleTo.lan = true; visibleTo.lan = true;
visibleTo.wan = true; visibleTo.wan = true;
description = "colin-notification-waiter-${builtins.toString (port+1)}-of-${builtins.toString numPorts}"; description = "colin-notification-waiter-${builtins.toString (port - portLow + 1)}-of-${builtins.toString numPorts}";
}; };
})); }));
systemd.services = lib.mkMerge (builtins.map mkService portRange); systemd.services = lib.mkMerge (builtins.map mkService portRange);

View File

@@ -0,0 +1,74 @@
# Soulseek daemon (p2p file sharing with an emphasis on Music)
# docs: <https://github.com/slskd/slskd/blob/master/docs/config.md>
#
# config precedence (higher precedence overrules lower precedence):
# - Default Values < Environment Variables < YAML Configuraiton File < Command Line Arguments
{ config, lib, ... }:
{
sane.persist.sys.byStore.plaintext = [
{ user = "slskd"; group = "slskd"; path = "/var/lib/slskd"; }
];
sops.secrets."slskd_env" = {
owner = config.users.users.slskd.name;
mode = "0400";
};
users.users.slskd.extraGroups = [ "media" ];
sane.ports.ports."50000" = {
protocol = [ "tcp" ];
# not visible to WAN: i run this in a separate netns
visibleTo.ovpn = true;
description = "colin-soulseek";
};
sane.dns.zones."uninsane.org".inet.CNAME."soulseek" = "native";
services.nginx.virtualHosts."soulseek.uninsane.org" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://10.0.1.6:5001";
proxyWebsockets = true;
};
};
services.slskd.enable = true;
# env file, for auth (SLSKD_SLSK_PASSWORD, SLSKD_SLSK_USERNAME)
services.slskd.environmentFile = config.sops.secrets.slskd_env.path;
services.slskd.settings = {
soulseek.diagnostic_level = "Debug"; # one of "None"|"Warning"|"Info"|"Debug"
shares.directories = [
# folders to share
# syntax: <https://github.com/slskd/slskd/blob/master/docs/config.md#directories>
# [Alias]/path/on/disk
# NOTE: Music library is quick to scan; videos take a solid 10min to scan.
# TODO: re-enable the other libraries
# "[Audioooks]/var/lib/uninsane/media/Books/Audiobooks"
# "[Books]/var/lib/uninsane/media/Books/Books"
# "[Manga]/var/lib/uninsane/media/Books/Visual"
# "[games]/var/lib/uninsane/media/games"
"[Music]/var/lib/uninsane/media/Music"
# "[Film]/var/lib/uninsane/media/Videos/Film"
# "[Shows]/var/lib/uninsane/media/Videos/Shows"
];
# directories.downloads = "..." # TODO
# directories.incomplete = "..." # TODO
# what unit is this? kbps??
global.upload.speed_limit = 32000;
web.logging = true;
# debug = true;
flags.no_logo = true; # don't show logo at start
# flags.volatile = true; # store searches and active transfers in RAM (completed transfers still go to disk). rec for btrfs/zfs
};
systemd.services.slskd = {
serviceConfig = {
# run this behind the OVPN static VPN
NetworkNamespacePath = "/run/netns/ovpns";
Restart = lib.mkForce "always"; # exits "success" when it fails to connect to soulseek server
RestartSec = "60s";
Group = "media";
};
};
}

View File

@@ -16,7 +16,7 @@
# transmission will by default not allow the world to read its files. # transmission will by default not allow the world to read its files.
services.transmission.downloadDirPermissions = "775"; services.transmission.downloadDirPermissions = "775";
services.transmission.extraFlags = [ services.transmission.extraFlags = [
"--log-level=debug" # "--log-level=debug"
]; ];
services.transmission.settings = { services.transmission.settings = {
@@ -39,9 +39,9 @@
encryption = 2; encryption = 2;
# units in kBps # units in kBps
speed-limit-down = 3000; speed-limit-down = 12000;
speed-limit-down-enabled = true; speed-limit-down-enabled = true;
speed-limit-up = 600; speed-limit-up = 800;
speed-limit-up-enabled = true; speed-limit-up-enabled = true;
# see: https://git.zknt.org/mirror/transmission/commit/cfce6e2e3a9b9d31a9dafedd0bdc8bf2cdb6e876?lang=bg-BG # see: https://git.zknt.org/mirror/transmission/commit/cfce6e2e3a9b9d31a9dafedd0bdc8bf2cdb6e876?lang=bg-BG
@@ -91,5 +91,10 @@
}; };
sane.dns.zones."uninsane.org".inet.CNAME."bt" = "native"; sane.dns.zones."uninsane.org".inet.CNAME."bt" = "native";
sane.ports.ports."51413" = {
protocol = [ "tcp" "udp" ];
visibleTo.ovpn = true;
description = "colin-bittorrent";
};
} }

View File

@@ -11,6 +11,8 @@ in lib.mkMerge [
# don't bind to IPv6 until i explicitly test that stack # don't bind to IPv6 until i explicitly test that stack
services.trust-dns.settings.listen_addrs_ipv6 = []; services.trust-dns.settings.listen_addrs_ipv6 = [];
services.trust-dns.quiet = true; services.trust-dns.quiet = true;
# FIXME(2023/11/26): services.trust-dns.debug doesn't log requests: use RUST_LOG=debug env for that.
# - see: <https://github.com/hickory-dns/hickory-dns/issues/2082>
# services.trust-dns.debug = true; # services.trust-dns.debug = true;
sane.ports.ports."53" = { sane.ports.ports."53" = {

View File

@@ -8,38 +8,58 @@
./hosts.nix ./hosts.nix
./ids.nix ./ids.nix
./machine-id.nix ./machine-id.nix
./net.nix ./net
./nix-path ./nix-path
./persist.nix ./persist.nix
./programs ./programs
./secrets.nix ./secrets.nix
./ssh.nix ./ssh.nix
./users ./users
./vpn.nix
]; ];
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;
sane.root-on-tmpfs = lib.mkDefault true;
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.config.allowUnfree = true; # NIXPKGS_ALLOW_UNFREE=1
nixpkgs.config.allowBroken = true; # NIXPKGS_ALLOW_BROKEN 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
# allow `nix flake ...` command
# TODO: is this still required?
nix.extraOptions = '' nix.extraOptions = ''
# see: `man nix.conf`
# useful when a remote builder has a faster internet connection than me
builders-use-substitutes = true # default: false
# maximum seconds to wait when connecting to binary substituter
connect-timeout = 3 # default: 0
# download-attempts = 5 # default: 5
# allow `nix flake ...` command
experimental-features = nix-command flakes experimental-features = nix-command flakes
# whether to build from source when binary substitution fails
fallback = true # default: false
# whether to keep building dependencies if any other one fails
keep-going = true # default: false
# whether to keep build-only dependencies of GC roots (e.g. C compiler) when doing GC
keep-outputs = true # default: false
# how many lines to show from failed build
log-lines = 30 # default: 10
# narinfo-cache-negative-ttl = 3600 # default: 3600
# whether to use ~/.local/state/nix/profile instead of ~/.nix-profile, etc
use-xdg-base-directories = true # default: false
# whether to warn if repository has uncommited changes
warn-dirty = false # default: true
''; '';
# hardlinks identical files in the nix store to save 25-35% disk space. # hardlinks identical files in the nix store to save 25-35% disk space.
# unclear _when_ this occurs. it's not a service. # unclear _when_ this occurs. it's not a service.
# does the daemon continually scan the nix store? # does the daemon continually scan the nix store?
# does the builder use some content-addressed db to efficiently dedupe? # does the builder use some content-addressed db to efficiently dedupe?
nix.settings.auto-optimise-store = true; nix.settings.auto-optimise-store = true;
# TODO: see if i can remove this?
nix.settings.trusted-users = [ "root" ];
services.journald.extraConfig = '' services.journald.extraConfig = ''
# docs: `man journald.conf` # docs: `man journald.conf`
@@ -72,7 +92,21 @@
text = '' text = ''
# show which packages changed versions or are new/removed in this upgrade # show which packages changed versions or are new/removed in this upgrade
# source: <https://github.com/luishfonseca/dotfiles/blob/32c10e775d9ec7cc55e44592a060c1c9aadf113e/modules/upgrade-diff.nix> # source: <https://github.com/luishfonseca/dotfiles/blob/32c10e775d9ec7cc55e44592a060c1c9aadf113e/modules/upgrade-diff.nix>
# modified to not error on boot (when /run/current-system doesn't exist)
if [ -d /run/current-system ]; then
${pkgs.nvd}/bin/nvd --nix-bin-dir=${pkgs.nix}/bin diff /run/current-system "$systemConfig" ${pkgs.nvd}/bin/nvd --nix-bin-dir=${pkgs.nix}/bin diff /run/current-system "$systemConfig"
fi
'';
};
system.activationScripts.notifyActive = {
text = ''
# send a notification to any sway users logged in, that the system has been activated/upgraded.
# this probably doesn't work if more than one sway session exists on the system.
_notifyActiveSwaySock="$(echo /run/user/*/sway-ipc.*.sock)"
if [ -e "$_notifyActiveSwaySock" ]; then
SWAYSOCK="$_notifyActiveSwaySock" ${pkgs.sway}/bin/swaymsg -- exec \
"${pkgs.libnotify}/bin/notify-send 'nixos activated' 'version: $(cat $systemConfig/nixos-version)'"
fi
''; '';
}; };

View File

@@ -50,6 +50,8 @@ let
else else
"infrequent" "infrequent"
)); ));
} // lib.optionalAttrs (lib.hasPrefix "https://www.youtube.com/" raw.url) {
format = "video";
} // lib.optionalAttrs (raw.is_podcast or false) { } // lib.optionalAttrs (raw.is_podcast or false) {
format = "podcast"; format = "podcast";
} // lib.optionalAttrs (raw.title or "" != "") { } // lib.optionalAttrs (raw.title or "" != "") {
@@ -60,6 +62,7 @@ let
(fromDb "acquiredlpbonussecretsecret.libsyn.com" // tech) # ACQ2 - more "Acquired" episodes (fromDb "acquiredlpbonussecretsecret.libsyn.com" // tech) # ACQ2 - more "Acquired" episodes
(fromDb "allinchamathjason.libsyn.com" // pol) (fromDb "allinchamathjason.libsyn.com" // pol)
(fromDb "anchor.fm/s/34c7232c/podcast/rss" // tech) # Civboot -- https://anchor.fm/civboot (fromDb "anchor.fm/s/34c7232c/podcast/rss" // tech) # Civboot -- https://anchor.fm/civboot
(fromDb "anchor.fm/s/2da69154/podcast/rss" // tech) # POD OF JAKE -- https://podofjake.com/
(fromDb "cast.postmarketos.org" // tech) (fromDb "cast.postmarketos.org" // tech)
(fromDb "congressionaldish.libsyn.com" // pol) # Jennifer Briney (fromDb "congressionaldish.libsyn.com" // pol) # Jennifer Briney
(fromDb "craphound.com" // pol) # Cory Doctorow -- both podcast & text entries (fromDb "craphound.com" // pol) # Cory Doctorow -- both podcast & text entries
@@ -71,19 +74,22 @@ let
(fromDb "feeds.feedburner.com/radiolab" // pol) # Radiolab -- also available here, but ONLY OVER HTTP: <http://feeds.wnyc.org/radiolab> (fromDb "feeds.feedburner.com/radiolab" // pol) # Radiolab -- also available here, but ONLY OVER HTTP: <http://feeds.wnyc.org/radiolab>
(fromDb "feeds.libsyn.com/421877" // rat) # Less Wrong Curated (fromDb "feeds.libsyn.com/421877" // rat) # Less Wrong Curated
(fromDb "feeds.megaphone.fm/behindthebastards" // pol) # also Maggie Killjoy (fromDb "feeds.megaphone.fm/behindthebastards" // pol) # also Maggie Killjoy
(fromDb "feeds.megaphone.fm/hubermanlab" // uncat) # Daniel Huberman on sleep # (fromDb "feeds.megaphone.fm/hubermanlab" // uncat) # Daniel Huberman on sleep
(fromDb "feeds.megaphone.fm/recodedecode" // tech) # The Verge - Decoder (fromDb "feeds.megaphone.fm/recodedecode" // tech) # The Verge - Decoder
(fromDb "feeds.simplecast.com/54nAGcIl" // pol) # The Daily (fromDb "feeds.simplecast.com/54nAGcIl" // pol) # The Daily
(fromDb "feeds.simplecast.com/82FI35Px" // pol) # Ezra Klein Show (fromDb "feeds.simplecast.com/82FI35Px" // pol) # Ezra Klein Show
(fromDb "feeds.simplecast.com/wgl4xEgL" // rat) # Econ Talk (fromDb "feeds.simplecast.com/wgl4xEgL" // rat) # Econ Talk
(fromDb "feeds.simplecast.com/xKJ93w_w" // uncat) # Atlas Obscura (fromDb "feeds.simplecast.com/xKJ93w_w" // uncat) # Atlas Obscura
# (fromDb "feeds.simplecast.com/l2i9YnTd" // tech // pol) # Hard Fork (NYtimes tech)
(fromDb "feeds.transistor.fm/acquired" // tech) (fromDb "feeds.transistor.fm/acquired" // tech)
(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 "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/the-dollop-with-dave-anthony-and-gareth-reynolds") # The Dollop history/comedy
(fromDb "originstories.libsyn.com" // uncat)
(fromDb "podcast.posttv.com/itunes/post-reports.xml" // pol) (fromDb "podcast.posttv.com/itunes/post-reports.xml" // pol)
(fromDb "podcast.thelinuxexp.com" // tech) # (fromDb "podcast.thelinuxexp.com" // tech) # low-brow linux/foss PR announcements
(fromDb "politicalorphanage.libsyn.com" // pol) (fromDb "politicalorphanage.libsyn.com" // pol)
(fromDb "reverseengineering.libsyn.com/rss" // tech) # UnNamed Reverse Engineering Podcast (fromDb "reverseengineering.libsyn.com/rss" // tech) # UnNamed Reverse Engineering Podcast
(fromDb "rss.acast.com/deconstructed") # The Intercept - Deconstructed (fromDb "rss.acast.com/deconstructed") # The Intercept - Deconstructed
@@ -92,6 +98,7 @@ let
(fromDb "rss.art19.com/60-minutes" // pol) (fromDb "rss.art19.com/60-minutes" // pol)
(fromDb "rss.art19.com/the-portal" // rat) # Eric Weinstein (fromDb "rss.art19.com/the-portal" // rat) # Eric Weinstein
(fromDb "seattlenice.buzzsprout.com" // pol) (fromDb "seattlenice.buzzsprout.com" // pol)
(fromDb "srslywrong.com" // pol)
(fromDb "sharkbytes.transistor.fm" // tech) # Wireshark Podcast o_0 (fromDb "sharkbytes.transistor.fm" // tech) # Wireshark Podcast o_0
(fromDb "sscpodcast.libsyn.com" // rat) # Astral Codex Ten (fromDb "sscpodcast.libsyn.com" // rat) # Astral Codex Ten
(fromDb "talesfromthebridge.buzzsprout.com" // tech) # Sci-Fi? has Peter Watts; author of No Moods, Ads or Cutesy Fucking Icons (rifters.com) (fromDb "talesfromthebridge.buzzsprout.com" // tech) # Sci-Fi? has Peter Watts; author of No Moods, Ads or Cutesy Fucking Icons (rifters.com)
@@ -110,135 +117,118 @@ let
]; ];
texts = [ texts = [
# AGGREGATORS (> 1 post/day) (fromDb "amosbbatto.wordpress.com" // tech)
(fromDb "lwn.net" // tech) (fromDb "applieddivinitystudies.com" // rat)
# (fromDb "lesswrong.com" // rat) (fromDb "artemis.sh" // tech)
(fromDb "ascii.textfiles.com" // tech) # Jason Scott
(fromDb "austinvernon.site" // tech)
(fromDb "balajis.com" // pol) # Balaji
(fromDb "ben-evans.com/benedictevans" // pol)
(fromDb "bitbashing.io" // tech)
(fromDb "bitsaboutmoney.com" // uncat)
(fromDb "blog.danieljanus.pl" // tech)
(fromDb "blog.dshr.org" // pol) # David Rosenthal
(fromDb "blog.jmp.chat" // tech)
(fromDb "blog.rust-lang.org" // tech)
(fromDb "blog.thalheim.io" // tech) # Mic92
(fromDb "bunniestudios.com" // tech) # Bunnie Juang
(fromDb "capitolhillseattle.com" // pol)
# (fromDb "drewdevault.com" // tech)
# (fromDb "econlib.org" // pol) # (fromDb "econlib.org" // pol)
(fromDb "edwardsnowden.substack.com" // pol // text)
# AGGREGATORS (< 1 post/day) (fromDb "fasterthanli.me" // tech)
(fromDb "gwern.net" // rat)
(fromDb "harihareswara.net" // tech // pol) # rec by Cory Doctorow
(fromDb "ianthehenry.com" // tech)
(fromDb "idiomdrottning.org" // uncat)
(fromDb "interconnected.org/home/feed" // rat) # Matt Webb -- engineering-ish, but dreamy
(fromDb "jeffgeerling.com" // tech)
(fromDb "jefftk.com" // tech)
(fromDb "kosmosghost.github.io/index.xml" // tech)
# (fromDb "lesswrong.com" // rat)
(fromDb "linmob.net" // tech)
(fromDb "lwn.net" // tech)
(fromDb "lynalden.com" // pol)
(fromDb "mako.cc/copyrighteous" // tech // pol) # rec by Cory Doctorow
(fromDb "mg.lol" // tech)
(fromDb "mindingourway.com" // rat)
(fromDb "morningbrew.com/feed" // pol)
(fromDb "overcomingbias.com" // rat) # Robin Hanson
(fromDb "palladiummag.com" // uncat) (fromDb "palladiummag.com" // uncat)
(fromDb "philosopher.coach" // rat) # Peter Saint-Andre -- side project of stpeter.im
(fromDb "pomeroyb.com" // tech)
(fromDb "preposterousuniverse.com" // rat) # Sean Carroll
(fromDb "profectusmag.com" // uncat) (fromDb "profectusmag.com" // uncat)
(fromDb "project-insanity.org" // tech) # shared blog by a few NixOS devs, notably onny
(fromDb "putanumonit.com" // rat) # mostly dating topics. not advice, or humor, but looking through a social lens
(fromDb "richardcarrier.info" // rat)
(fromDb "rifters.com/crawl" // uncat) # No Moods, Ads or Cutesy Fucking Icons
(fromDb "righto.com" // tech) # Ken Shirriff
(fromDb "rootsofprogress.org" // rat) # Jason Crawford
(fromDb "sagacioussuricata.com" // tech) # ian (Sanctuary)
(fromDb "semiaccurate.com" // tech) (fromDb "semiaccurate.com" // tech)
(mkText "https://linuxphoneapps.org/blog/atom.xml" // tech // infrequent) (fromDb "sideways-view.com" // rat) # Paul Christiano
(fromDb "tuxphones.com" // tech) (fromDb "slimemoldtimemold.com" // rat)
(fromDb "spectrum.ieee.org" // tech) (fromDb "spectrum.ieee.org" // tech)
(fromDb "stpeter.im/atom.xml" // pol)
# (fromDb "theregister.com" // tech) # (fromDb "theregister.com" // tech)
(fromDb "thisweek.gnome.org" // tech) (fromDb "thisweek.gnome.org" // tech)
# more nixos stuff here, but unclear how to subscribe: <https://nixos.org/blog/categories.html> (fromDb "tuxphones.com" // tech)
(mkText "https://nixos.org/blog/announcements-rss.xml" // tech // infrequent)
(mkText "https://nixos.org/blog/stories-rss.xml" // tech // weekly)
## n.b.: quality RSS list here: <https://forum.merveilles.town/thread/57/share-your-rss-feeds%21-6/>
(mkText "https://forum.merveilles.town/rss.xml" // pol // infrequent)
## No Moods, Ads or Cutesy Fucking Icons
(fromDb "rifters.com/crawl" // uncat)
# DEVELOPERS
(fromDb "blog.jmp.chat" // tech)
(fromDb "uninsane.org" // tech) (fromDb "uninsane.org" // tech)
(fromDb "ascii.textfiles.com" // tech) # Jason Scott (fromDb "unintendedconsequenc.es" // rat)
# (fromDb "vitalik.ca" // tech) # moved to vitalik.eth.limo
(fromDb "vitalik.eth.limo" // tech) # Vitalik Buterin
(fromDb "webcurious.co.uk" // uncat)
(fromDb "xn--gckvb8fzb.com" // tech) (fromDb "xn--gckvb8fzb.com" // tech)
(fromDb "amosbbatto.wordpress.com" // tech) (mkSubstack "astralcodexten" // rat // daily) # Scott Alexander
(fromDb "fasterthanli.me" // tech)
(fromDb "mg.lol" // tech)
# (fromDb "drewdevault.com" // tech)
## Ken Shirriff
(fromDb "righto.com" // tech)
## shared blog by a few NixOS devs, notably onny
(fromDb "project-insanity.org" // tech)
## Vitalik Buterin
(fromDb "vitalik.ca" // tech)
## ian (Sanctuary)
(fromDb "sagacioussuricata.com" // tech)
(fromDb "artemis.sh" // tech)
## Bunnie Juang
(fromDb "bunniestudios.com" // tech)
(fromDb "blog.danieljanus.pl" // tech)
(fromDb "ianthehenry.com" // tech)
(fromDb "bitbashing.io" // tech)
(fromDb "idiomdrottning.org" // uncat)
(mkText "http://boginjr.com/feed" // tech // infrequent)
(mkText "https://anish.lakhwara.com/home.html" // tech // weekly)
(fromDb "jefftk.com" // tech)
(fromDb "pomeroyb.com" // tech)
(fromDb "harihareswara.net" // tech // pol) # rec by Cory Doctorow
(fromDb "mako.cc/copyrighteous" // tech // pol) # rec by Cory Doctorow
# (mkText "https://til.simonwillison.net/tils/feed.atom" // tech // weekly)
# TECH PROJECTS
(fromDb "blog.rust-lang.org" // tech)
# (TECH; POL) COMMENTATORS
## Matt Webb -- engineering-ish, but dreamy
(fromDb "interconnected.org/home/feed" // rat)
(fromDb "edwardsnowden.substack.com" // pol // text)
## Julia Evans
(mkText "https://jvns.ca/atom.xml" // tech // weekly)
(mkText "http://benjaminrosshoffman.com/feed" // pol // weekly)
## Ben Thompson
(mkText "https://www.stratechery.com/rss" // pol // weekly)
## Balaji
(fromDb "balajis.com" // pol)
(fromDb "ben-evans.com/benedictevans" // pol)
(fromDb "lynalden.com" // pol)
(fromDb "austinvernon.site" // tech)
(mkSubstack "oversharing" // pol // daily)
(mkSubstack "byrnehobart" // pol // infrequent) (mkSubstack "byrnehobart" // pol // infrequent)
# (mkSubstack "doomberg" // tech // weekly) # articles are all pay-walled # (mkSubstack "doomberg" // tech // weekly) # articles are all pay-walled
## David Rosenthal
(fromDb "blog.dshr.org" // pol)
## Matt Levine
(mkText "https://www.bloomberg.com/opinion/authors/ARbTQlRLRjE/matthew-s-levine.rss" // pol // weekly)
(fromDb "stpeter.im/atom.xml" // pol)
## Peter Saint-Andre -- side project of stpeter.im
(fromDb "philosopher.coach" // rat)
(fromDb "morningbrew.com/feed" // pol)
# RATIONALITY/PHILOSOPHY/ETC
(mkSubstack "samkriss" // humor // infrequent)
(fromDb "unintendedconsequenc.es" // rat)
(fromDb "applieddivinitystudies.com" // rat)
(fromDb "slimemoldtimemold.com" // rat)
(fromDb "richardcarrier.info" // rat)
(fromDb "gwern.net" // rat)
## Jason Crawford
(fromDb "rootsofprogress.org" // rat)
## Robin Hanson
(fromDb "overcomingbias.com" // rat)
## Scott Alexander
(mkSubstack "astralcodexten" // rat // daily)
## Paul Christiano
(fromDb "sideways-view.com" // rat)
## Sean Carroll
(fromDb "preposterousuniverse.com" // rat)
(mkSubstack "eliqian" // rat // weekly) (mkSubstack "eliqian" // rat // weekly)
(mkSubstack "oversharing" // pol // daily)
(mkSubstack "samkriss" // humor // infrequent)
(mkText "http://benjaminrosshoffman.com/feed" // pol // weekly)
(mkText "http://boginjr.com/feed" // tech // infrequent)
(mkText "https://acoup.blog/feed" // rat // weekly) (mkText "https://acoup.blog/feed" // rat // weekly)
(fromDb "mindingourway.com" // rat) (mkText "https://anish.lakhwara.com/home.html" // tech // weekly)
(mkText "https://forum.merveilles.town/rss.xml" // pol // infrequent) #quality RSS list here: <https://forum.merveilles.town/thread/57/share-your-rss-feeds%21-6/>
## mostly dating topics. not advice, or humor, but looking through a social lens
(fromDb "putanumonit.com" // rat)
# LOCAL
(fromDb "capitolhillseattle.com" // pol)
# CODE
# (mkText "https://github.com/Kaiteki-Fedi/Kaiteki/commits/master.atom" // tech // infrequent) # (mkText "https://github.com/Kaiteki-Fedi/Kaiteki/commits/master.atom" // tech // infrequent)
(mkText "https://jvns.ca/atom.xml" // tech // weekly) # Julia Evans
(mkText "https://linuxphoneapps.org/blog/atom.xml" // tech // infrequent)
(mkText "https://nixos.org/blog/announcements-rss.xml" // tech // infrequent) # more nixos stuff here, but unclear how to subscribe: <https://nixos.org/blog/categories.html>
(mkText "https://nixos.org/blog/stories-rss.xml" // tech // weekly)
# (mkText "https://til.simonwillison.net/tils/feed.atom" // tech // weekly)
(mkText "https://www.bloomberg.com/opinion/authors/ARbTQlRLRjE/matthew-s-levine.rss" // pol // weekly) # Matt Levine
(mkText "https://www.stratechery.com/rss" // pol // weekly) # Ben Thompson
];
videos = [
(fromDb "youtube.com/@Channel5YouTube" // pol)
(fromDb "youtube.com/@ColdFusion")
(fromDb "youtube.com/@ContraPoints" // pol)
(fromDb "youtube.com/@Exurb1a")
(fromDb "youtube.com/@hbomberguy")
(fromDb "youtube.com/@JackStauber")
(fromDb "youtube.com/@PolyMatter")
# (fromDb "youtube.com/@rossmanngroup" // pol // tech) # Louis Rossmann
(fromDb "youtube.com/@TechnologyConnections" // tech)
(fromDb "youtube.com/@TheB1M")
(fromDb "youtube.com/@TomScottGo")
(fromDb "youtube.com/@Vihart")
(fromDb "youtube.com/@Vox")
(fromDb "youtube.com/@Vsauce")
]; ];
images = [ images = [
(fromDb "smbc-comics.com" // img // humor)
(fromDb "xkcd.com" // img // humor)
(fromDb "turnoff.us" // img // humor)
(fromDb "pbfcomics.com" // img // humor)
# (mkImg "http://dilbert.com/feed" // humor // daily)
(fromDb "poorlydrawnlines.com/feed" // img // humor)
# ART
(fromDb "miniature-calendar.com" // img // art // daily) (fromDb "miniature-calendar.com" // img // art // daily)
(fromDb "pbfcomics.com" // img // humor)
(fromDb "poorlydrawnlines.com/feed" // img // humor)
(fromDb "smbc-comics.com" // img // humor)
(fromDb "turnoff.us" // img // humor)
(fromDb "xkcd.com" // img // humor)
]; ];
in in
{ {
sane.feeds = texts ++ images ++ podcasts; sane.feeds = texts ++ images ++ podcasts ++ videos;
assertions = builtins.map assertions = builtins.map
(p: { (p: {

View File

@@ -1,4 +1,4 @@
{ lib, pkgs, ... }: { config, lib, pkgs, ... }:
{ {
imports = [ imports = [
@@ -12,8 +12,9 @@
copy_bin_and_libs ${pkgs.util-linux}/bin/{cfdisk,lsblk,lscpu} 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.gptfdisk}/bin/{cgdisk,gdisk}
copy_bin_and_libs ${pkgs.smartmontools}/bin/smartctl copy_bin_and_libs ${pkgs.smartmontools}/bin/smartctl
copy_bin_and_libs ${pkgs.nvme-cli}/bin/nvme
copy_bin_and_libs ${pkgs.e2fsprogs}/bin/resize2fs 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.kernelParams = [
"boot.shell_on_fail" "boot.shell_on_fail"
@@ -39,6 +40,12 @@
# non-free firmware # non-free firmware
hardware.enableRedistributableFirmware = true; 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 # powertop will default to putting USB devices -- including HID -- to sleep after TWO SECONDS
powerManagement.powertop.enable = false; powerManagement.powertop.enable = false;
# linux CPU governor: <https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt> # linux CPU governor: <https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt>
@@ -57,10 +64,19 @@
powerManagement.cpuFreqGovernor = "ondemand"; powerManagement.cpuFreqGovernor = "ondemand";
services.logind.extraConfig = '' services.logind.extraConfig = ''
# dont shutdown when power button is short-pressed # see: `man logind.conf`
HandlePowerKey=ignore # 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.
HandlePowerKey=lock
HandlePowerKeyLongPress=poweroff
HandleLidSwitch=lock
''; '';
# some packages build only if binfmt *isn't* present
nix.settings.system-features = lib.mkIf (config.boot.binfmt.emulatedSystems == []) [
"no-binfmt"
];
# services.snapper.configs = { # services.snapper.configs = {
# root = { # root = {
# subvolume = "/"; # subvolume = "/";

View File

@@ -1,19 +1,32 @@
{ config, lib, ...}: { config, lib, ...}:
let let
# ProgramConfig -> { "<mime-type>" = { priority, desktop }; }
weightedMimes = prog: builtins.mapAttrs (_key: desktop: { priority = prog.mime.priority; desktop = desktop; }) prog.mime.associations;
# [ { "<mime-type>" = { priority, desktop } ]; } ] -> { "<mime-type>" = [ { priority, desktop } ... ]; }
mergeMimes = mimes: lib.foldAttrs (item: acc: [item] ++ acc) [] mimes;
# [ { priority, desktop } ... ] -> Self
sortOneMimeType = associations: builtins.sort (l: r: assert l.priority != r.priority; l.priority < r.priority) associations;
sortMimes = mimes: builtins.mapAttrs (_k: sortOneMimeType) mimes;
removePriorities = mimes: builtins.mapAttrs (_k: associations: builtins.map (a: a.desktop) associations) mimes;
# [ ProgramConfig ] # [ ProgramConfig ]
enabledPrograms = builtins.filter (p: p.enabled) (builtins.attrValues config.sane.programs); enabledPrograms = builtins.filter
(p: p.enabled)
(builtins.attrValues config.sane.programs);
# [ { "<mime-type>" = { prority, desktop } ] # [ { "<mime-type>" = { prority, desktop } ]
enabledWeightedMimes = builtins.map weightedMimes enabledPrograms; enabledWeightedMimes = builtins.map weightedMimes enabledPrograms;
# ProgramConfig -> { "<mime-type>" = { priority, desktop }; }
weightedMimes = prog: builtins.mapAttrs
(_key: desktop: {
priority = prog.mime.priority; desktop = desktop;
})
prog.mime.associations;
# [ { "<mime-type>" = { priority, desktop } ]; } ] -> { "<mime-type>" = [ { priority, desktop } ... ]; }
mergeMimes = mimes: lib.foldAttrs (item: acc: [item] ++ acc) [] mimes;
# [ { priority, desktop } ... ] -> Self
sortOneMimeType = associations: builtins.sort
(l: r: assert l.priority != r.priority; l.priority < r.priority)
associations;
sortMimes = mimes: builtins.mapAttrs (_k: sortOneMimeType) mimes;
removePriorities = mimes: builtins.mapAttrs
(_k: associations: builtins.map (a: a.desktop) associations)
mimes;
in in
{ {
# the xdg mime type for a file can be found with: # the xdg mime type for a file can be found with:
@@ -25,4 +38,6 @@ in
# there's also options to *remove* [non-default] associations from specific apps # there's also options to *remove* [non-default] associations from specific apps
xdg.mime.enable = true; xdg.mime.enable = true;
xdg.mime.defaultApplications = removePriorities (sortMimes (mergeMimes enabledWeightedMimes)); xdg.mime.defaultApplications = removePriorities (sortMimes (mergeMimes enabledWeightedMimes));
} }

View File

@@ -19,7 +19,7 @@
}; };
sane.hosts.by-name."moby" = { sane.hosts.by-name."moby" = {
ssh.authorized = lib.mkDefault false; # moby's too easy to hijack: don't let it ssh places # ssh.authorized = lib.mkDefault false; # moby's too easy to hijack: don't let it ssh places
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrR+gePnl0nV/vy7I5BzrGeyVL+9eOuXHU1yNE3uCwU"; ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrR+gePnl0nV/vy7I5BzrGeyVL+9eOuXHU1yNE3uCwU";
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO1N/IT3nQYUD+dBlU1sTEEVMxfOyMkrrDeyHcYgnJvw"; ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO1N/IT3nQYUD+dBlU1sTEEVMxfOyMkrrDeyHcYgnJvw";
wg-home.pubkey = "I7XIR1hm8bIzAtcAvbhWOwIAabGkuEvbWH/3kyIB1yA="; wg-home.pubkey = "I7XIR1hm8bIzAtcAvbhWOwIAabGkuEvbWH/3kyIB1yA=";
@@ -36,4 +36,10 @@
wg-home.endpoint = "uninsane.org:51820"; wg-home.endpoint = "uninsane.org:51820";
lan-ip = "10.78.79.51"; lan-ip = "10.78.79.51";
}; };
sane.hosts.by-name."supercap" = {
ssh.authorized = false;
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHf/mqqkX45EWAcquV04MC3SUljTApdclH1gjI19F+PA";
lan-ip = "10.78.79.232";
};
} }

View File

@@ -49,6 +49,14 @@
sane.ids.media.gid = 2414; sane.ids.media.gid = 2414;
sane.ids.ntfy-sh.uid = 2415; sane.ids.ntfy-sh.uid = 2415;
sane.ids.ntfy-sh.gid = 2415; sane.ids.ntfy-sh.gid = 2415;
sane.ids.monero.uid = 2416;
sane.ids.monero.gid = 2416;
sane.ids.slskd.uid = 2417;
sane.ids.slskd.gid = 2417;
sane.ids.bitcoind-mainnet.uid = 2418;
sane.ids.bitcoind-mainnet.gid = 2418;
sane.ids.clightning.uid = 2419;
sane.ids.clightning.gid = 2419;
sane.ids.colin.uid = 1000; sane.ids.colin.uid = 1000;
sane.ids.guest.uid = 1100; sane.ids.guest.uid = 1100;
@@ -63,6 +71,8 @@
sane.ids.systemd-oom.uid = 2005; sane.ids.systemd-oom.uid = 2005;
sane.ids.systemd-oom.gid = 2005; sane.ids.systemd-oom.gid = 2005;
sane.ids.wireshark.gid = 2006; sane.ids.wireshark.gid = 2006;
sane.ids.nixremote.uid = 2007;
sane.ids.nixremote.gid = 2007;
# 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

View File

@@ -1,6 +1,12 @@
{ lib, ... }: { lib, ... }:
{ {
imports = [
./dns.nix
./hostnames.nix
./upnp.nix
./vpn.nix
];
# the default backend is "wpa_supplicant". # the default backend is "wpa_supplicant".
# wpa_supplicant reliably picks weak APs to connect to. # wpa_supplicant reliably picks weak APs to connect to.
# see: <https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/474> # see: <https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/474>
@@ -35,10 +41,6 @@
# e.g. openconnect drags in webkitgtk (for SSO)! # e.g. openconnect drags in webkitgtk (for SSO)!
networking.networkmanager.plugins = lib.mkForce []; networking.networkmanager.plugins = lib.mkForce [];
networking.firewall.allowedUDPPorts = [
1900 # to received UPnP advertisements. required by sane-ip-check-upnp
];
# keyfile.path = where networkmanager should look for connection credentials # keyfile.path = where networkmanager should look for connection credentials
networking.networkmanager.extraConfig = '' networking.networkmanager.extraConfig = ''
[keyfile] [keyfile]

37
hosts/common/net/dns.nix Normal file
View File

@@ -0,0 +1,37 @@
{ ... }:
{
# use systemd's stub resolver.
# /etc/resolv.conf isn't sophisticated enough to use different servers per net namespace (or link).
# instead, running the stub resolver on a known address in the root ns lets us rewrite packets
# in the ovnps namespace to use the provider's DNS resolvers.
# a weakness is we can only query 1 NS at a time (unless we were to clone the packets?)
# there also seems to be some cache somewhere that's shared between the two namespaces.
# i think this is a libc thing. might need to leverage proper cgroups to _really_ kill it.
# - getent ahostsv4 www.google.com
# - try fix: <https://serverfault.com/questions/765989/connect-to-3rd-party-vpn-server-but-dont-use-it-as-the-default-route/766290#766290>
services.resolved.enable = true;
# without DNSSEC:
# - dig matrix.org => works
# - curl https://matrix.org => works
# with default DNSSEC:
# - dig matrix.org => works
# - curl https://matrix.org => fails
# i don't know why. this might somehow be interfering with the DNS run on this device (trust-dns)
services.resolved.dnssec = "false";
networking.nameservers = [
# use systemd-resolved resolver
# full resolver (which understands /etc/hosts) lives on 127.0.0.53
# stub resolver (just forwards upstream) lives on 127.0.0.54
"127.0.0.53"
];
# nscd -- the Name Service Caching Daemon -- caches DNS query responses
# in a way that's unaware of my VPN routing, so routes are frequently poor against
# services which advertise different IPs based on geolocation.
# nscd claims to be usable without a cache, but in practice i can't get it to not cache!
# nsncd is the Name Service NON-Caching Daemon. it's a drop-in that doesn't cache;
# this is OK on the host -- because systemd-resolved caches. it's probably sub-optimal
# in the netns and we query upstream DNS more often than needed. hm.
# TODO: run a separate recursive resolver in each namespace.
services.nscd.enableNsncd = true;
}

View File

@@ -0,0 +1,15 @@
{ config, lib, ... }:
{
# give each host a shortname that all the other hosts know, to allow easy comms.
networking.hosts = lib.mkMerge (builtins.map
(host: let
cfg = config.sane.hosts.by-name."${host}";
in {
"${cfg.lan-ip}" = [ host ];
} // lib.optionalAttrs (cfg.wg-home.ip != null) {
"${cfg.wg-home.ip}" = [ "${host}-hn" ];
})
(builtins.attrNames config.sane.hosts.by-name)
);
}

20
hosts/common/net/upnp.nix Normal file
View File

@@ -0,0 +1,20 @@
{ pkgs, ... }:
{
networking.firewall.allowedUDPPorts = [
# to receive UPnP advertisements. required by sane-ip-check.
# N.B. sane-ip-check isn't query/response based. it needs to receive on port 1900 -- not receive responses FROM port 1900.
1900
];
networking.firewall.extraCommands = with pkgs; ''
# after an outgoing SSDP query to the multicast address, open FW for incoming responses.
# necessary for anything DLNA, especially go2tv
# source: <https://serverfault.com/a/911286>
# context: <https://github.com/alexballas/go2tv/issues/72>
# ipset -! means "don't fail if set already exists"
${ipset}/bin/ipset create -! upnp hash:ip,port timeout 10
${iptables}/bin/iptables -A OUTPUT -d 239.255.255.250/32 -p udp -m udp --dport 1900 -j SET --add-set upnp src,src --exist
${iptables}/bin/iptables -A INPUT -p udp -m set --match-set upnp dst,dst -j ACCEPT
'';
}

View File

@@ -8,21 +8,41 @@
# - copy the Address, PublicKey, Endpoint from OVPN's config # - copy the Address, PublicKey, Endpoint from OVPN's config
# N.B.: maximum interface name in Linux is 15 characters. # N.B.: maximum interface name in Linux is 15 characters.
let let
def-wg-vpn = name: { endpoint, publicKey, address, dns, privateKeyFile, extraOptions ? {} }: { def-wg-vpn = name: { endpoint, publicKey, address, dns, privateKeyFile }: {
networking.wg-quick.interfaces."${name}" = { # networking.wg-quick.interfaces."${name}" = {
inherit address privateKeyFile dns; # inherit address privateKeyFile dns;
peers = [ # peers = [
{ # {
allowedIPs = [ # allowedIPs = [
# "0.0.0.0/0"
# "::/0"
# ];
# inherit endpoint publicKey;
# }
# ];
# # to start: `systemctl start wg-quick-${name}`
# autostart = false;
# };
systemd.network.netdevs."${name}" = {
# see: `man 5 systemd.netdev`
wireguardConfig = {
PrivateKeyFile = privateKeyFile;
};
wireguardPeers = [{
AllowedIPs = [
"0.0.0.0/0" "0.0.0.0/0"
"::/0" "::/0"
]; ];
inherit endpoint publicKey; Endpoint = endpoint;
} PublicKey = publicKey;
]; }];
# to start: `systemctl start wg-quick-${name}` };
autostart = false; systemd.network.networks."${name}" = {
} // extraOptions; # see: `man 5 systemd.network`
matchConfig.Name = name;
networkConfig.Address = address;
networkConfig.DNS = dns;
};
}; };
def-ovpn = name: { endpoint, publicKey, address }: def-wg-vpn "ovpnd-${name}" { def-ovpn = name: { endpoint, publicKey, address }: def-wg-vpn "ovpnd-${name}" {
inherit endpoint publicKey address; inherit endpoint publicKey address;

View File

@@ -1,4 +1,4 @@
{ pkgs, ... }: { pkgs, sane-lib, ... }:
{ {
# allow `nix-shell` (and probably nix-index?) to locate our patched and custom packages # allow `nix-shell` (and probably nix-index?) to locate our patched and custom packages
@@ -10,4 +10,7 @@
# to avoid switching so much during development # to avoid switching so much during development
"nixpkgs-overlays=/home/colin/dev/nixos/hosts/common/nix-path/overlay" "nixpkgs-overlays=/home/colin/dev/nixos/hosts/common/nix-path/overlay"
]; ];
# ensure new deployments have a source of this repo with which they can bootstrap.
environment.etc."nixos".source = ../../..;
} }

View File

@@ -0,0 +1,99 @@
# discord gtk3 client
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.abaddon;
in
{
sane.programs.abaddon = {
configOption = with lib; mkOption {
default = {};
type = types.submodule {
options.autostart = mkOption {
type = types.bool;
default = false;
};
};
};
package = pkgs.abaddon.overrideAttrs (upstream: {
patches = (upstream.patches or []) ++ [
(pkgs.fetchpatch {
url = "https://git.uninsane.org/colin/abaddon/commit/eb551f188d34679f75adcbc83cb8d5beb4d19fd6.patch";
name = ''"view members" default to false'';
hash = "sha256-9BX8iO86CU1lNrKS1G2BjDR+3IlV9bmhRNTsLrxChwQ=";
})
];
});
suggestedPrograms = [ "gnome-keyring" ];
fs.".config/abaddon/abaddon.ini".symlink.text = ''
# see abaddon README.md for options.
# at time of writing:
# | Setting | Type | Default | Description |
# |[discord]------|---------|---------|--------------------------------------------------------------------------------------------------|
# | `gateway` | string | | override url for Discord gateway. must be json format and use zlib stream compression |
# | `api_base` | string | | override base url for Discord API |
# | `memory_db` | boolean | false | if true, Discord data will be kept in memory as opposed to on disk |
# | `token` | string | | Discord token used to login, this can be set from the menu |
# | `prefetch` | boolean | false | if true, new messages will cause the avatar and image attachments to be automatically downloaded |
# | `autoconnect` | boolean | false | autoconnect to discord |
# |[http]--------|--------|---------|---------------------------------------------------------------------------------------------|
# | `user_agent` | string | | sets the user-agent to use in HTTP requests to the Discord API (not including media/images) |
# | `concurrent` | int | 20 | how many images can be concurrently retrieved |
# |[gui}------------------------|---------|---------|----------------------------------------------------------------------------------------------------------------------------|
# | `member_list_discriminator` | boolean | true | show user discriminators in the member list |
# | `stock_emojis` | boolean | true | allow abaddon to substitute unicode emojis with images from emojis.bin, must be false to allow GTK to render emojis itself |
# | `custom_emojis` | boolean | true | download and use custom Discord emojis |
# | `css` | string | | path to the main CSS file |
# | `animations` | boolean | true | use animated images where available (e.g. server icons, emojis, avatars). false means static images will be used |
# | `animated_guild_hover_only` | boolean | true | only animate guild icons when the guild is being hovered over |
# | `owner_crown` | boolean | true | show a crown next to the owner |
# | `unreads` | boolean | true | show unread indicators and mention badges |
# | `save_state` | boolean | true | save the state of the gui (active channels, tabs, expanded channels) |
# | `alt_menu` | boolean | false | keep the menu hidden unless revealed with alt key |
# | `hide_to_tray` | boolean | false | hide abaddon to the system tray on window close |
# | `show_deleted_indicator` | boolean | true | show \[deleted\] indicator next to deleted messages instead of actually deleting the message |
# | `font_scale` | double | | scale font rendering. 1 is unchanged |
# |[style]------------------|--------|-----------------------------------------------------|
# | `linkcolor` | string | color to use for links in messages |
# | `expandercolor` | string | color to use for the expander in the channel list |
# | `nsfwchannelcolor` | string | color to use for NSFW channels in the channel list |
# | `channelcolor` | string | color to use for SFW channels in the channel list |
# | `mentionbadgecolor` | string | background color for mention badges |
# | `mentionbadgetextcolor` | string | color to use for number displayed on mention badges |
# | `unreadcolor` | string | color to use for the unread indicator |
# |[notifications]|---------|--------------------------|-------------------------------------------------------------------------------|
# | `enabled` | boolean | true (if not on Windows) | Enable desktop notifications |
# | `playsound` | boolean | true | Enable notification sounds. Requires ENABLE_NOTIFICATION_SOUNDS=TRUE in CMake |
# |[voice]--|--------|------------------------------------|------------------------------------------------------------|
# | `vad` | string | rnnoise if enabled, gate otherwise | Method used for voice activity detection. Changeable in UI |
# |[windows]|---------|---------|-------------------------|
# | `hideconsole` | boolean | true | Hide console on startup |
# N.B.: abaddon writes this file itself (and even when i don't change anything internally).
# it prefers no spaces around the equal sign.
[discord]
autoconnect=true
[notifications]
# playsound: i manage sounds via swaync
playsound=false
'';
persist.byStore.private = [
".cache/abaddon"
];
services.abaddon = {
description = "unofficial Discord chat client";
wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/abaddon";
Type = "simple";
Restart = "always";
RestartSec = "20s";
};
};
};
}

View File

@@ -7,18 +7,34 @@
{ {
sane.programs.alacritty = { sane.programs.alacritty = {
env.TERMINAL = lib.mkDefault "alacritty"; env.TERMINAL = lib.mkDefault "alacritty";
# note: alacritty will switch to .toml config in 13.0 release fs.".config/alacritty/alacritty.toml".symlink.text = ''
# - run `alacritty migrate` to convert the yaml to toml [font]
fs.".config/alacritty/alacritty.yml".symlink.text = '' size = 14
font:
size: 14
key_bindings: [[keyboard.bindings]]
- { key: N, mods: Control, action: CreateNewWindow } mods = "Control"
- { key: PageUp, mods: Control, action: ScrollPageUp } key = "N"
- { key: PageDown, mods: Control, action: ScrollPageDown } action = "CreateNewWindow"
- { key: PageUp, mods: Control|Shift, action: ScrollPageUp }
- { key: PageDown, mods: Control|Shift, action: ScrollPageDown } [[keyboard.bindings]]
mods = "Control"
key = "PageUp"
action = "ScrollPageUp"
[[keyboard.bindings]]
mods = "Control"
key = "PageDown"
action = "ScrollPageDown"
[[keyboard.bindings]]
mods = "Control|Shift"
key = "PageUp"
action = "ScrollPageUp"
[[keyboard.bindings]]
mods = "Control|Shift"
key = "PageDown"
action = "ScrollPageDown"
''; '';
}; };
} }

View File

@@ -0,0 +1,10 @@
{ ... }:
{
sane.programs.animatch = {
persist.byStore.plaintext = [
# game progress
".config/Holy Pangolin/Animatch"
".local/share/Holy Pangolin/Animatch" # i think this one might be wrong
];
};
}

View File

@@ -20,6 +20,7 @@ in
"sane-scripts.bt-show" "sane-scripts.bt-show"
]; ];
"sane-scripts.dev" = declPackageSet [ "sane-scripts.dev" = declPackageSet [
"sane-scripts.clone"
"sane-scripts.dev-cargo-loop" "sane-scripts.dev-cargo-loop"
"sane-scripts.git-init" "sane-scripts.git-init"
]; ];
@@ -41,14 +42,12 @@ in
"sane-scripts.secrets-unlock" "sane-scripts.secrets-unlock"
"sane-scripts.secrets-update-keys" "sane-scripts.secrets-update-keys"
"sane-scripts.shutdown" "sane-scripts.shutdown"
"sane-scripts.ssl-dump"
"sane-scripts.sudo-redirect" "sane-scripts.sudo-redirect"
"sane-scripts.sync-from-servo" "sane-scripts.sync-from-servo"
"sane-scripts.tag-music"
"sane-scripts.vpn" "sane-scripts.vpn"
"sane-scripts.which" "sane-scripts.which"
"sane-scripts.wipe-browser" "sane-scripts.wipe"
"sane-scripts.wipe-flare"
"sane-scripts.wipe-fractal"
]; ];
"sane-scripts.sys-utils" = declPackageSet [ "sane-scripts.sys-utils" = declPackageSet [
"sane-scripts.ip-port-forward" "sane-scripts.ip-port-forward"
@@ -109,6 +108,8 @@ in
"util-linux" # lsblk, lscpu, etc "util-linux" # lsblk, lscpu, etc
"wget" "wget"
"wirelesstools" # iwlist "wirelesstools" # iwlist
"xq" # jq for XML
# "zfs" # doesn't cross-compile (requires samba)
]; ];
sysadminExtraUtils = declPackageSet [ sysadminExtraUtils = declPackageSet [
"backblaze-b2" "backblaze-b2"
@@ -143,6 +144,7 @@ in
"lshw" "lshw"
# "memtester" # "memtester"
"mercurial" # hg "mercurial" # hg
"mimeo" # like xdg-open
"neovim" # needed as a user package, for swap persistence "neovim" # needed as a user package, for swap persistence
# "nettools" # "nettools"
# "networkmanager" # "networkmanager"
@@ -172,7 +174,7 @@ in
"zsh" "zsh"
]; ];
desktopConsoleUtils = declPackageSet [ pcConsoleUtils = declPackageSet [
"gh" # MS GitHub cli "gh" # MS GitHub cli
"nix-index" "nix-index"
"nixpkgs-review" "nixpkgs-review"
@@ -181,17 +183,19 @@ in
]; ];
consoleMediaUtils = declPackageSet [ consoleMediaUtils = declPackageSet [
"catt" # cast videos to chromecast
"ffmpeg" "ffmpeg"
"go2tv" # cast videos to UPNP/DLNA device (i.e. tv).
"imagemagick" "imagemagick"
"sox" "sox"
"yt-dlp" "yt-dlp"
]; ];
tuiApps = declPackageSet [ pcTuiApps = declPackageSet [
"aerc" # email client "aerc" # email client
"msmtp" # sendmail "msmtp" # sendmail
"offlineimap" # email mailbox sync "offlineimap" # email mailbox sync
"sfeed" # RSS fetcher # "sfeed" # RSS fetcher
"visidata" # TUI spreadsheet viewer/editor "visidata" # TUI spreadsheet viewer/editor
"w3m" # web browser "w3m" # web browser
]; ];
@@ -218,9 +222,14 @@ in
cargo.persist.byStore.plaintext = [ ".cargo" ]; cargo.persist.byStore.plaintext = [ ".cargo" ];
# auth token, preferences
delfin.persist.byStore.private = [ ".config/delfin" ];
# creds, but also 200 MB of node modules, etc # creds, but also 200 MB of node modules, etc
discord.persist.byStore.private = [ ".config/discord" ]; discord.persist.byStore.private = [ ".config/discord" ];
endless-sky.persist.byStore.plaintext = [ ".local/share/endless-sky" ];
# `emote` will show a first-run dialog based on what's in this directory. # `emote` will show a first-run dialog based on what's in this directory.
# mostly, it just keeps a LRU of previously-used emotes to optimize display order. # mostly, it just keeps a LRU of previously-used emotes to optimize display order.
# TODO: package [smile](https://github.com/mijorus/smile) for probably a better mobile experience. # TODO: package [smile](https://github.com/mijorus/smile) for probably a better mobile experience.
@@ -237,6 +246,8 @@ in
# TODO: we can populate gh's stuff statically; it even lets us use the same oauth across machines # TODO: we can populate gh's stuff statically; it even lets us use the same oauth across machines
gh.persist.byStore.private = [ ".config/gh" ]; gh.persist.byStore.private = [ ".config/gh" ];
gnome-2048.persist.byStore.plaintext = [ ".local/share/gnome-2048/scores" ];
"gnome.gnome-maps".persist.byStore.plaintext = [ ".cache/shumate" ]; "gnome.gnome-maps".persist.byStore.plaintext = [ ".cache/shumate" ];
"gnome.gnome-maps".persist.byStore.private = [ ".local/share/maps-places.json" ]; "gnome.gnome-maps".persist.byStore.private = [ ".local/share/maps-places.json" ];
@@ -253,22 +264,24 @@ in
requests requests
]); ]);
# creds, media shattered-pixel-dungeon.persist.byStore.plaintext = [ ".local/share/.shatteredpixel/shattered-pixel-dungeon" ];
signal-desktop.persist.byStore.private = [ ".config/Signal" ];
# printer/filament settings # printer/filament settings
slic3r.persist.byStore.plaintext = [ ".Slic3r" ]; slic3r.persist.byStore.plaintext = [ ".Slic3r" ];
space-cadet-pinball.persist.byStore.plaintext = [ ".local/share/SpaceCadetPinball" ];
superTux.persist.byStore.plaintext = [ ".local/share/supertux2" ];
tdesktop.persist.byStore.private = [ ".local/share/TelegramDesktop" ]; tdesktop.persist.byStore.private = [ ".local/share/TelegramDesktop" ];
tokodon.persist.byStore.private = [ ".cache/KDE/tokodon" ]; tokodon.persist.byStore.private = [ ".cache/KDE/tokodon" ];
vvvvvv.persist.byStore.plaintext = [ ".local/share/VVVVVV" ];
whalebird.persist.byStore.private = [ ".config/Whalebird" ]; whalebird.persist.byStore.private = [ ".config/Whalebird" ];
yarn.persist.byStore.plaintext = [ ".cache/yarn" ]; yarn.persist.byStore.plaintext = [ ".cache/yarn" ];
# zcash coins. safe to delete, just slow to regenerate (10-60 minutes)
zecwallet-lite.persist.byStore.private = [ ".zcash" ];
}; };
programs.feedbackd = lib.mkIf config.sane.programs.feedbackd.enabled { programs.feedbackd = lib.mkIf config.sane.programs.feedbackd.enabled {

View File

@@ -0,0 +1,22 @@
{ pkgs, ... }:
{
sane.programs.audacity = {
package = pkgs.audacity.override {
# wxGTK32 uses webkitgtk-4.0.
# audacity doesn't actually need webkit though, so diable to reduce closure
wxGTK32 = pkgs.wxGTK32.override {
withWebKit = false;
};
};
# disable first-run splash screen
fs.".config/audacity/audacity.cfg".file.text = ''
PrefsVersion=1.1.1r1
[GUI]
ShowSplashScreen=0
[Version]
Major=3
Minor=4
'';
};
}

View File

@@ -0,0 +1,29 @@
# use like:
# - catt -d lgtv_chrome cast ./path/to.mp4
#
# support matrix:
# - webm: audio only
# - mp4: audio + video
{ config, lib, ... }:
let
cfg = config.sane.programs.catt;
in
{
sane.programs.catt = {
fs.".config/catt/catt.cfg".symlink.text = ''
[options]
device = lgtv_chrome
[aliases]
lgtv_chrome = 10.78.79.106
'';
};
# necessary to cast local files
networking.firewall.allowedTCPPortRanges = lib.mkIf cfg.enabled [
{
from = 45000;
to = 47000;
}
];
}

View File

@@ -1,40 +1,8 @@
{ pkgs, ... }: { pkgs, ... }:
let
chattyNoOauth = pkgs.chatty.override {
# the OAuth feature (presumably used for web-based logins) pulls a full webkitgtk.
# especially when using the gtk3 version of evolution-data-server, it's an ancient webkitgtk_4_1.
# disable OAuth for a faster build & smaller closure
evolution-data-server = pkgs.evolution-data-server.override {
enableOAuth2 = false;
gnome-online-accounts = pkgs.gnome-online-accounts.override {
# disables the upstream "goabackend" feature -- presumably "Gnome Online Accounts Backend"
# frees us from webkit_4_1, in turn.
enableBackend = false;
gvfs = pkgs.gvfs.override {
# saves 20 minutes of build time, for unused feature
samba = null;
};
};
};
};
chatty-latest = pkgs.chatty-latest.override {
evolution-data-server-gtk4 = pkgs.evolution-data-server-gtk4.override {
gnome-online-accounts = pkgs.gnome-online-accounts.override {
# disables the upstream "goabackend" feature -- presumably "Gnome Online Accounts Backend"
# frees us from webkit_4_1, in turn.
enableBackend = false;
gvfs = pkgs.gvfs.override {
# saves 20 minutes of build time and cross issues, for unused feature
samba = null;
};
};
};
};
in
{ {
sane.programs.chatty = { sane.programs.chatty = {
# package = chattyNoOauth; # package = chattyNoOauth;
package = chatty-latest; package = pkgs.chatty-latest;
suggestedPrograms = [ "gnome-keyring" ]; suggestedPrograms = [ "gnome-keyring" ];
persist.byStore.private = [ persist.byStore.private = [
".local/share/chatty" # matrix avatars and files ".local/share/chatty" # matrix avatars and files

View File

@@ -1,32 +1,184 @@
#!/bin/sh
#!/usr/bin/env nix-shell #!/usr/bin/env nix-shell
#!nix-shell -i bash #!nix-shell -i bash
full=$(cat /sys/class/power_supply/axp20x-battery/charge_full_design) usage() {
rate=$(cat /sys/class/power_supply/axp20x-battery/current_now) echo "usage: battery_estimate [options...]"
perc=$(cat /sys/class/power_supply/axp20x-battery/capacity) echo
perc_left=$((100 - $perc)) echo "pretty-prints a battery estimate (icon to indicate state, and a duration estimate)"
# these icons come from sxmo; they only render in nerdfonts echo
bat_dis="󱊢" echo "options:"
bat_chg="󱊥" 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"
}
fmt_minutes() { # these icons come from sxmo; they only render in nerdfonts
# args: <battery symbol> <text if ludicrous estimate> <estimated minutes to full/empty> icon_bat_chg=("󰢟" "󱊤" "󱊥" "󰂅")
if [[ $3 -gt 1440 ]]; then icon_bat_dis=("󰂎" "󱊡" "󱊢" "󱊣")
printf "%s %s" "$1" "$2" # more than 1d suffix_icon="" # thin space
else suffix_percent="%"
hr=$(($3 / 60)) # suffix_icon=" "
hr_in_min=$(($hr * 60))
min=$(($3 - $hr_in_min)) # render time like: 2ʰ08ᵐ
printf "%s %dh%02dm" "$1" "$hr" "$min" # 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 fi
} }
if [[ $rate -lt 0 ]]; then render_icon() {
# discharging # args:
fmt_minutes "$bat_dis" '∞' "$(($full * 60 * $perc / (-100 * $rate)))" # 1: "chg" or "dis"
elif [[ $rate -gt 0 ]]; then # 2: current battery percentage
# charging level=$(($2 / 25))
fmt_minutes "$bat_chg" '100%' "$(($full * 60 * $perc_left / (100 * $rate)))" level=$(($level > 3 ? 3 : $level))
else level=$(($level < 0 ? 0 : $level))
echo "$bat_dis $perc%" 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 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

@@ -3,6 +3,11 @@
-- - can also use #rrggbb syntax -- - can also use #rrggbb syntax
-- example configs: <https://forum.manjaro.org/t/conky-showcase-2022/97123> -- example configs: <https://forum.manjaro.org/t/conky-showcase-2022/97123>
-- example configs: <https://www.reddit.com/r/Conkyporn/> -- example configs: <https://www.reddit.com/r/Conkyporn/>
--
-- exec options:
-- `exec <cmd>` => executes the command, synchronously, renders its output as text
-- `texeci <interval_sec> <cmd>` => executes the command periodically, async (to not block render), renders as text
-- `pexec <cmd>` => executes the command, synchronously, parses its output
conky.config = { conky.config = {
out_to_wayland = true, out_to_wayland = true,
@@ -35,16 +40,43 @@ conky.config = {
color2 = '404040', color2 = '404040',
} }
-- texeci <interval_sec> <cmd>: run the command periodically, _in a separate thread_ so as not to block rendering vars = {
-- kBps = 'K/s',
kBps = 'ᴷᐟˢ',
-- percent = '%',
-- percent = '﹪',
percent = '٪',
-- percent = '⁒',
-- percent = '',
icon_suffix = nil,
hour_suffix = nil,
minute_suffix = '${font sans-serif:size=14}${color2}⧗',
}
bat_args = ""
if vars.icon_suffix ~= nil then
bat_args = bat_args .. " --icon-suffix '" .. vars.icon_suffix .. "'"
end
if vars.hour_suffix ~= nil then
bat_args = bat_args .. " --hour-suffix '" .. vars.hour_suffix .. "'"
end
if vars.minute_suffix ~= nil then
bat_args = bat_args .. " --minute-suffix '" .. vars.minute_suffix .. "'"
end
if vars.percent ~= nil then
bat_args = bat_args .. " --percent-suffix '" .. vars.percent .. "'"
end
-- N.B.: `[[ <text> ]]` is Lua's multiline string literal
conky.text = [[ conky.text = [[
${color1}${shadecolor 707070}${font sans-serif:size=50:style=Bold}${alignc}${exec date +"%H:%M"}${font} ${color1}${shadecolor 707070}${font sans-serif:size=50:style=Bold}${alignc}${exec date +"%H:%M"}${font}
${color2}${shadecolor a4d7d0}${font sans-serif:size=20}${alignc}${exec date +"%a %d %b"}${font} ${color2}${shadecolor a4d7d0}${font sans-serif:size=20}${alignc}${exec date +"%a %d %b"}${font}
${color1}${shadecolor}${font sans-serif:size=22:style=Bold}${alignc}${exec @bat@ }${font} ${color1}${shadecolor}${font sans-serif:size=22:style=Bold}${alignc}${execp @bat@ ]] .. bat_args .. [[ }${font}
${color1}${shadecolor}${font sans-serif:size=20:style=Bold}${alignc}${texeci 600 @weather@ }${font} ${color1}${shadecolor}${font sans-serif:size=20:style=Bold}${alignc}${texeci 600 @weather@ }${font}
${color2}${shadecolor a4d7d0}${font sans-serif:size=16}${alignc}⇅ ${downspeedf wlan0}K/s${font} ${color2}${shadecolor a4d7d0}${font sans-serif:size=16}${alignc}⇅ ${downspeedf wlan0}]] .. vars.kBps .. [[${font}
${font sans-serif:size=16}${alignc}☵ $memperc%  $cpu%${font} ${font sans-serif:size=16}${alignc}☵ $memperc]] .. vars.percent .. [[  $cpu]] .. vars.percent .. [[${font}
]] ]]

View File

@@ -2,16 +2,21 @@
{ {
imports = [ imports = [
./abaddon.nix
./aerc.nix ./aerc.nix
./alacritty.nix ./alacritty.nix
./animatch.nix
./assorted.nix ./assorted.nix
./audacity.nix
./bemenu.nix ./bemenu.nix
./brave.nix ./brave.nix
./calls.nix ./calls.nix
./cantata.nix ./cantata.nix
./catt.nix
./chatty.nix ./chatty.nix
./conky ./conky
./cozy.nix ./cozy.nix
./dialect.nix
./dino.nix ./dino.nix
./element-desktop.nix ./element-desktop.nix
./epiphany.nix ./epiphany.nix
@@ -29,8 +34,10 @@
./gnome-feeds.nix ./gnome-feeds.nix
./gnome-keyring.nix ./gnome-keyring.nix
./gnome-weather.nix ./gnome-weather.nix
./go2tv.nix
./gpodder.nix ./gpodder.nix
./gthumb.nix ./gthumb.nix
./gtkcord4.nix
./helix.nix ./helix.nix
./imagemagick.nix ./imagemagick.nix
./jellyfin-media-player.nix ./jellyfin-media-player.nix
@@ -38,36 +45,49 @@
./koreader ./koreader
./libreoffice.nix ./libreoffice.nix
./lemoa.nix ./lemoa.nix
./loupe.nix
./mako.nix ./mako.nix
./megapixels.nix
./mepo.nix ./mepo.nix
./mimeo
./mopidy.nix ./mopidy.nix
./mpv.nix ./mpv.nix
./msmtp.nix ./msmtp.nix
./nautilus.nix
./neovim.nix ./neovim.nix
./newsflash.nix ./newsflash.nix
./nheko.nix ./nheko.nix
./nix-index.nix ./nix-index.nix
./notejot.nix
./ntfy-sh.nix ./ntfy-sh.nix
./obsidian.nix ./obsidian.nix
./offlineimap.nix ./offlineimap.nix
./open-in-mpv.nix
./planify.nix
./playerctl.nix ./playerctl.nix
./rhythmbox.nix ./rhythmbox.nix
./ripgrep.nix ./ripgrep.nix
./sfeed.nix ./sfeed.nix
./signal-desktop.nix
./splatmoji.nix ./splatmoji.nix
./spot.nix
./spotify.nix ./spotify.nix
./steam.nix ./steam.nix
./stepmania.nix ./stepmania.nix
./sublime-music.nix ./sublime-music.nix
./supertuxkart.nix
./sway-autoscaler
./swaynotificationcenter.nix ./swaynotificationcenter.nix
./tangram.nix ./tangram.nix
./tor-browser-bundle-bin.nix ./tor-browser-bundle-bin.nix
./tuba.nix ./tuba.nix
./vlc.nix ./vlc.nix
./wike.nix
./wine.nix
./wireshark.nix ./wireshark.nix
./wob.nix
./xarchiver.nix ./xarchiver.nix
./zeal.nix ./zeal.nix
./zecwallet-lite.nix
./zsh ./zsh
]; ];

View File

@@ -0,0 +1,13 @@
{ pkgs, ... }:
{
sane.programs.dialect = {
package = pkgs.dialect.overrideAttrs (upstream: {
# TODO: send upstream
# TODO: figure out how to get audio working
# TODO: move to runtimeDependencies?
buildInputs = upstream.buildInputs ++ [
pkgs.glib-networking # for TLS
];
});
};
}

View File

@@ -40,7 +40,7 @@ in
type = types.submodule { type = types.submodule {
options.autostart = mkOption { options.autostart = mkOption {
type = types.bool; type = types.bool;
default = false; default = true;
}; };
}; };
}; };
@@ -48,7 +48,7 @@ in
persist.byStore.private = [ ".local/share/dino" ]; persist.byStore.private = [ ".local/share/dino" ];
services.dino = { services.dino = {
description = "auto-start and maintain dino XMPP connection"; description = "dino XMPP client";
wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ]; wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ];
serviceConfig = { serviceConfig = {
ExecStart = "${cfg.package}/bin/dino"; ExecStart = "${cfg.package}/bin/dino";

View File

@@ -4,9 +4,14 @@
# - <https://github.com/vector-im/element-desktop/issues/1029#issuecomment-1632688224> # - <https://github.com/vector-im/element-desktop/issues/1029#issuecomment-1632688224>
# - `rm -rf ~/.config/Element/GPUCache` # - `rm -rf ~/.config/Element/GPUCache`
# - <https://github.com/NixOS/nixpkgs/issues/244486> # - <https://github.com/NixOS/nixpkgs/issues/244486>
{ ... }: { pkgs, ... }:
{ {
sane.programs.element-desktop = { sane.programs.element-desktop = {
package = pkgs.element-desktop.override {
# use pre-build electron because otherwise it takes 4 hrs to build from source.
electron = pkgs.electron-bin;
};
# creds/session keys, etc # creds/session keys, etc
persist.byStore.private = [ ".config/Element" ]; persist.byStore.private = [ ".config/Element" ];

View File

@@ -1,3 +1,6 @@
# test with e.g.
# - `fbcli --event proxied-message-new-instant`
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
cfg = config.sane.programs.feedbackd; cfg = config.sane.programs.feedbackd;

View File

@@ -13,7 +13,14 @@ let
mobile-prefs = lib.optionals false pkgs.librewolf-pmos-mobile.extraPrefsFiles; mobile-prefs = lib.optionals false pkgs.librewolf-pmos-mobile.extraPrefsFiles;
# allow easy switching between firefox and librewolf with `defaultSettings`, below # allow easy switching between firefox and librewolf with `defaultSettings`, below
librewolfSettings = { librewolfSettings = {
browser = pkgs.librewolf-unwrapped; browser = pkgs.librewolf-unwrapped.overrideAttrs (upstream: {
# TEMP(2023/11/21): fix eval bug in wrapFirefox
# see: <https://github.com/NixOS/nixpkgs/pull/244591>
passthru = upstream.passthru // {
requireSigning = false;
allowAddonSideload = true;
};
});
extraPrefsFiles = pkgs.librewolf-unwrapped.extraPrefsFiles ++ mobile-prefs; extraPrefsFiles = pkgs.librewolf-unwrapped.extraPrefsFiles ++ mobile-prefs;
libName = "librewolf"; libName = "librewolf";
dotDir = ".librewolf"; dotDir = ".librewolf";
@@ -31,25 +38,16 @@ let
# defaultSettings = firefoxSettings; # defaultSettings = firefoxSettings;
defaultSettings = librewolfSettings; defaultSettings = librewolfSettings;
addon = name: extid: hash: pkgs.fetchFirefoxAddon { package = (pkgs.wrapFirefox cfg.browser.browser {
inherit name hash;
url = "https://addons.mozilla.org/firefox/downloads/latest/${name}/latest.xpi";
# extid can be found by unar'ing the above xpi, and copying browser_specific_settings.gecko.id field
fixedExtid = extid;
};
localAddon = pkg: pkgs.fetchFirefoxAddon {
inherit (pkg) name;
src = "${pkg}/share/mozilla/extensions/\\{ec8030f7-c20a-464f-9b0e-13a3a9e97384\\}/${pkg.extid}.xpi";
fixedExtid = pkg.extid;
};
package = pkgs.wrapFirefox cfg.browser.browser {
# inherit the default librewolf.cfg # inherit the default librewolf.cfg
# it can be further customized via ~/.librewolf/librewolf.overrides.cfg # it can be further customized via ~/.librewolf/librewolf.overrides.cfg
inherit (cfg.browser) extraPrefsFiles libName; inherit (cfg.browser) extraPrefsFiles libName;
extraNativeMessagingHosts = optional cfg.addons.browserpass-extension.enable pkgs.browserpass; nativeMessagingHosts = lib.optionals cfg.addons.browserpass-extension.enable [
# extraNativeMessagingHosts = [ pkgs.gopass-native-messaging-host ]; pkgs.browserpass
] ++ lib.optionals cfg.addons.fxCast.enable [
pkgs.fx-cast-bridge
];
nixExtensions = concatMap (ext: optional ext.enable ext.package) (attrValues cfg.addons); nixExtensions = concatMap (ext: optional ext.enable ext.package) (attrValues cfg.addons);
@@ -106,7 +104,17 @@ let
# NewTabPage = true; # NewTabPage = true;
}; };
# extraPrefs = ... # extraPrefs = ...
}; }).overrideAttrs (base: {
# de-associate `ctrl+shift+c` from activating the devtools.
# based on <https://stackoverflow.com/a/54260938>
buildCommand = (base.buildCommand or "") + ''
mkdir omni
${pkgs.buildPackages.unzip}/bin/unzip $out/lib/${cfg.browser.libName}/browser/omni.ja -d omni
rm $out/lib/${cfg.browser.libName}/browser/omni.ja
${pkgs.buildPackages.gnused}/bin/sed -i s'/devtools-commandkey-inspector = C/devtools-commandkey-inspector = VK_F12/' omni/localization/en-US/devtools/startup/key-shortcuts.ftl
pushd omni; ${pkgs.buildPackages.zip}/bin/zip $out/lib/${cfg.browser.libName}/browser/omni.ja -r ./*; popd
'';
});
addonOpts = types.submodule { addonOpts = types.submodule {
options = { options = {
@@ -150,6 +158,16 @@ in
default = {}; default = {};
}; };
sane.programs.firefox.config.addons = { sane.programs.firefox.config.addons = {
fxCast = {
# add a menu to cast to chromecast devices, but it doesn't seem to work very well.
# right click (or shift+rc) a video, then select "cast".
# - asciinema.org: icon appears, but glitches when clicked.
# - youtube.com: no icon appears, even when site is whitelisted.
# future: maybe better to have browser open all videos in mpv, and then use mpv for casting.
# see e.g. `ff2mpv`, `open-in-mpv` (both are packaged in nixpkgs)
package = pkgs.firefox-extensions.fx_cast;
enable = lib.mkDefault false;
};
browserpass-extension = { browserpass-extension = {
package = pkgs.firefox-extensions.browserpass-extension; package = pkgs.firefox-extensions.browserpass-extension;
enable = lib.mkDefault true; enable = lib.mkDefault true;
@@ -158,6 +176,10 @@ in
package = pkgs.firefox-extensions.bypass-paywalls-clean; package = pkgs.firefox-extensions.bypass-paywalls-clean;
enable = lib.mkDefault true; enable = lib.mkDefault true;
}; };
ctrl-shift-c-should-copy = {
package = pkgs.firefox-extensions.ctrl-shift-c-should-copy;
enable = lib.mkDefault false; # prefer patching firefox source code, so it works in more places
};
ether-metamask = { ether-metamask = {
package = pkgs.firefox-extensions.ether-metamask; package = pkgs.firefox-extensions.ether-metamask;
enable = lib.mkDefault false; # until i can disable the first-run notification enable = lib.mkDefault false; # until i can disable the first-run notification
@@ -166,6 +188,10 @@ in
package = pkgs.firefox-extensions.i2p-in-private-browsing; package = pkgs.firefox-extensions.i2p-in-private-browsing;
enable = lib.mkDefault config.services.i2p.enable; enable = lib.mkDefault config.services.i2p.enable;
}; };
open-in-mpv = {
package = pkgs.firefox-extensions.open-in-mpv;
enable = lib.mkDefault config.sane.programs.open-in-mpv.enabled;
};
sidebery = { sidebery = {
package = pkgs.firefox-extensions.sidebery; package = pkgs.firefox-extensions.sidebery;
enable = lib.mkDefault true; enable = lib.mkDefault true;
@@ -188,6 +214,10 @@ in
sane.programs.firefox = { sane.programs.firefox = {
inherit package; inherit package;
suggestedPrograms = [
"open-in-mpv"
];
mime.associations = let mime.associations = let
inherit (cfg.browser) desktop; inherit (cfg.browser) desktop;
in { in {
@@ -229,8 +259,21 @@ in
// scrollbar configuration, see: <https://artemis.sh/2023/10/12/scrollbars.html> // scrollbar configuration, see: <https://artemis.sh/2023/10/12/scrollbars.html>
// style=4 gives rectangular scrollbars // style=4 gives rectangular scrollbars
// could also enable "always show scrollbars" in about:preferences -- not sure what the actual pref name for that is // could also enable "always show scrollbars" in about:preferences -- not sure what the actual pref name for that is
defaultPref("widget.non-native-theme.scrollbar.size.override", 50); // note that too-large scrollbars (like 50px wide) tend to obscure content (and make buttons unclickable)
defaultPref("widget.non-native-theme.scrollbar.size.override", 20);
defaultPref("widget.non-native-theme.scrollbar.style", 4); defaultPref("widget.non-native-theme.scrollbar.style", 4);
// disable inertial/kinetic/momentum scrolling because it just gets in the way on touchpads
// source: <https://kparal.wordpress.com/2019/10/31/disabling-kinetic-scrolling-in-firefox/>
defaultPref("apz.gtk.kinetic_scroll.enabled", false);
// auto-dispatch mpv:// URIs to xdg-open without prompting.
// can do this with other protocols too (e.g. matrix?). see about:config for common handlers.
defaultPref("network.protocol-handler.external.mpv", true);
// element:// for Element matrix client
defaultPref("network.protocol-handler.external.element", true);
// matrix: for Nheko matrix client
defaultPref("network.protocol-handler.external.matrix", true);
''; '';
fs."${cfg.browser.dotDir}/default".dir = {}; fs."${cfg.browser.dotDir}/default".dir = {};
# instruct Firefox to put the profile in a predictable directory (so we can do things like persist just it). # instruct Firefox to put the profile in a predictable directory (so we can do things like persist just it).

View File

@@ -1,15 +1,18 @@
# Flare is a 3rd-party GTK4 Signal app. # Flare is a 3rd-party GTK4 Signal app.
# UI is effectively a clone of Fractal. # UI is effectively a clone of Fractal.
# #
# compatibility: ### compatibility:
# - desko: works fine. pairs, and exchanges contact list (but not message history) with the paired device. exchanges future messages fine. # - desko: works fine. pairs, and exchanges contact list (but not message history) with the paired device. exchanges future messages fine.
# - moby (cross compiled flare-signal-nixified): nope. it pairs, but can only *receive* messages and never *send* them. # - moby (cross compiled flare-signal-nixified): nope. it pairs, but can only *receive* messages and never *send* them.
# - even `rsync`ing the data and keyrings from desko -> moby, still fails in that same manner. # - even `rsync`ing the data and keyrings from desko -> moby, still fails in that same manner.
# - console shows error messages. quite possibly an endianness mismatch somewhere # - console shows error messages. quite possibly an endianness mismatch somewhere
# - moby (partially-emulated flare-signal): works! pairs and can send/receive messages, same as desko. # - moby (partially-emulated flare-signal): works! pairs and can send/receive messages, same as desko.
# #
# error signatures (to reset, run `sane-wipe-fractal`): ### debugging:
# - upon sending a message, the other side receives it, but Signal desktop gets "A message from Colin could not be delivered" and the local CLI shows: # - `RUST_LOG=flare=trace flare`
#
### error signatures (to reset, run `sane-wipe flare`):
#### upon sending a message, the other side receives it, but Signal desktop gets "A message from Colin could not be delivered" and the local CLI shows:
# ``` # ```
# ERROR libsignal_service::websocket] SignalWebSocket: Websocket error: SignalWebSocket: end of application request stream; socket closing # ERROR libsignal_service::websocket] SignalWebSocket: Websocket error: SignalWebSocket: end of application request stream; socket closing
# ERROR presage::manager] Error opening envelope: ProtobufDecodeError(DecodeError { description: "invalid tag value: 0", stack: [("Content", "data_message")] }), message will be skipped! # ERROR presage::manager] Error opening envelope: ProtobufDecodeError(DecodeError { description: "invalid tag value: 0", stack: [("Content", "data_message")] }), message will be skipped!
@@ -18,7 +21,8 @@
# - this occurs on moby, desko, `flare-signal` and `flare-signal-nixified` # - this occurs on moby, desko, `flare-signal` and `flare-signal-nixified`
# - the Websocket error seems to be unrelated, occurs during normal/good operation # - the Websocket error seems to be unrelated, occurs during normal/good operation
# - related issues: <https://github.com/whisperfish/presage/issues/152> # - related issues: <https://github.com/whisperfish/presage/issues/152>
# error when sending from Flare to other Flare device: #
#### error when sending from Flare to other Flare device:
# - ``` # - ```
# ERROR libsignal_protocol::session_cipher] Message from <UUID>.3 failed to decrypt; sender ratchet public key <key> message counter 1 # ERROR libsignal_protocol::session_cipher] Message from <UUID>.3 failed to decrypt; sender ratchet public key <key> message counter 1
# No current session # No current session
@@ -26,6 +30,32 @@
# ``` # ```
# - but signal iOS will still read it. # - but signal iOS will still read it.
# #
#### HTTP 405 when linking flare to iOS signal:
# [DEBUG libsignal_service_hyper::push_service] HTTP request PUT https://chat.signal.org/v1/devices/{uuid}.{timestamp?}:{b64-string}
# [TRACE libsignal_service_hyper::push_service] Unhandled response 405 with body: {"code":405,"message":"HTTP 405 Method Not Allowed"}
# [ERROR flare::gui::error_dialog] ErrorDialog displaying error: Something unexpected happened with the signal backend. Please retry later.
# [TRACE flare::gui::error_dialog] ErrorDialog full error: Presage(
# ProvisioningError(
# ServiceError(
# UnhandledResponseCode {
# http_code: 405,
# },
# ),
# ),
# )
# flare matrix suggests the signal endpoint has changed:
# - "/v1/device/link instead of confirming via /v1/devices/{I'd}"
# - this endpoint is declared in libsignal-service-rs (used both by flare and presage)
# - libsignal-service/src/provisioning/manager.rs
# - libsignal-service issues a put_json to that URL (i.e. HTTP PUT)
# - libsignal-service is "based on" the official rust signal API <https://github.com/signalapp/libsignal>
# - did these guys recently change it?
# - no, but Signal-Desktop did. see ccb5eb0dd2 from 2023/08/29
# - that's a fairly involved change.
# - signalcli is reporting this same error: <https://github.com/AsamK/signal-cli/issues/1399>
# - Mixin Messenger / libsignal_protocol_dart doesn't seem to be reporting any issue
# - <https://github.com/MixinNetwork/flutter-app>
#
# well, seems to have unpredictable errors particularly when being used on multiple devices. # well, seems to have unpredictable errors particularly when being used on multiple devices.
# desktop _seems_ more reliable than on mobile, but not confident. # desktop _seems_ more reliable than on mobile, but not confident.

View File

@@ -23,7 +23,7 @@ let
in in
{ {
sane.programs.fractal = { sane.programs.fractal = {
package = pkgs.fractal-nixified; package = pkgs.fractal-nixified.optimized;
# package = pkgs.fractal-latest; # package = pkgs.fractal-latest;
# package = pkgs.fractal-next; # package = pkgs.fractal-next;
@@ -41,6 +41,7 @@ in
# XXX by default fractal stores its state in ~/.local/share/<build-profile>/<UUID>. # XXX by default fractal stores its state in ~/.local/share/<build-profile>/<UUID>.
".local/share/hack" # for debug-like builds ".local/share/hack" # for debug-like builds
".local/share/stable" # for normal releases ".local/share/stable" # for normal releases
".local/share/fractal" # for version 5+, i think?
]; ];
suggestedPrograms = [ "gnome-keyring" ]; suggestedPrograms = [ "gnome-keyring" ];

View File

@@ -3,9 +3,23 @@
# - it uses webkitgtk_4_1, which is expensive to build. # - it uses webkitgtk_4_1, which is expensive to build.
# could be upgraded to webkitgtk latest if upgraded to gtk4 # could be upgraded to webkitgtk latest if upgraded to gtk4
# <https://gitlab.gnome.org/GNOME/geary/-/issues/1212> # <https://gitlab.gnome.org/GNOME/geary/-/issues/1212>
{ ... }: { config, lib, ... }:
let
cfg = config.sane.programs."gnome.geary";
in
{ {
sane.programs."gnome.geary" = { sane.programs."gnome.geary" = {
configOption = with lib; mkOption {
default = {};
type = types.submodule {
options.autostart = mkOption {
type = types.bool;
default = false;
};
};
};
slowToBuild = true; # uses webkitgtk 4.1
persist.byStore.private = [ persist.byStore.private = [
# attachments, and email -- contained in a sqlite db # attachments, and email -- contained in a sqlite db
".local/share/geary" ".local/share/geary"
@@ -51,5 +65,18 @@
transport_security=transport transport_security=transport
credentials=use-incoming credentials=use-incoming
''; '';
secrets.".config/geary/account_02/geary.ini" = ../../../secrets/common/geary_account_02.ini.bin;
services.geary = {
description = "Geary email client";
wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/geary";
Type = "simple";
Restart = "always";
RestartSec = "20s";
}; };
};
};
} }

View File

@@ -13,6 +13,7 @@ in
user.name = "Colin"; user.name = "Colin";
user.email = "colin@uninsane.org"; user.email = "colin@uninsane.org";
alias.amend = "commit --amend --no-edit";
alias.br = "branch"; alias.br = "branch";
alias.co = "checkout"; alias.co = "checkout";
alias.cp = "cherry-pick"; alias.cp = "cherry-pick";
@@ -23,6 +24,7 @@ in
alias.st = "status"; alias.st = "status";
alias.stat = "status"; alias.stat = "status";
diff.noprefix = true; #< don't show a/ or b/ prefixes in diffs
# difftastic docs: # difftastic docs:
# - <https://difftastic.wilfred.me.uk/git.html> # - <https://difftastic.wilfred.me.uk/git.html>
diff.tool = "difftastic"; diff.tool = "difftastic";

View File

@@ -0,0 +1,38 @@
# TROUBLESHOOTING:
# - turn the tv off and on again (no, really...)
#
# SANITY CHECKS:
# - `go2tv -u 'https://uninsane.org/share/AmenBreak.mp4'`
# - LGTV: works, but not seekable
# - `go2tv -u 'https://youtu.be/p3G5IXn0K7A'`
# - LGTV: FAILS ("this file cannot be recognized")
# - no fix via transcoding, altering the URI, etc.
# - workable if you use an invidious frontend, but you lose seeking.
# - e.g. `go2tv -u 'https://inv.us.projectsegfau.lt/latest_version?id=qBzjHU_zEwM&itag=18'`
# - e.g. `go2tv -tc -u 'https://yt.artemislena.eu/latest_version?id=qBzjHU_zEwM&itag=22'`
# - sometimes transcoding is needed, sometimes not...
# - `go2tv -v /mnt/servo-media/Videos/Shows/bebop/session1.mkv`
# - LGTV: works
# - `go2tv -tc -v /mnt/servo-media/Videos/Shows/bebop/session1.mkv`
# - LGTV: works
#
# WHEN TO TRANSCODE:
# - mkv container + mpeg-2 video + AC-3/48k stereo audio:
# - LGTV: no transcoding needed
# - mkv container + H.264 video + AAC/48k 5.1 audio:
# - LGTV: no transcoding needed
# - mp4 container + H.264 video + MP3/48k stereo audio:
# - LGTV: no transcoding needed
# - mp4 container + H.264 video + AAC/44k1 stereo audio:
# - LGTV: no transcoding needed
# - mkv container + H.265 video + E-AC-3/48k stereo audio:
# - LGTV: no transcoding needed
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.go2tv;
in
{
# for serving local files
# see: go2tv/soapcalls/utils/iptools.go
networking.firewall.allowedTCPPorts = lib.mkIf cfg.enabled [ 3500 ];
}

View File

@@ -5,7 +5,7 @@
let let
feeds = sane-lib.feeds; feeds = sane-lib.feeds;
all-feeds = config.sane.feeds; all-feeds = config.sane.feeds;
wanted-feeds = feeds.filterByFormat ["podcast"] all-feeds; wanted-feeds = feeds.filterByFormat [ "podcast" "video" ] all-feeds;
in { in {
sane.programs.gpodder = { sane.programs.gpodder = {
package = pkgs.gpodder-adaptive-configured.overrideAttrs (base: { package = pkgs.gpodder-adaptive-configured.overrideAttrs (base: {

View File

@@ -3,6 +3,7 @@
sane.programs.gthumb = { sane.programs.gthumb = {
# compile without webservices to avoid the expensive webkitgtk dependency # compile without webservices to avoid the expensive webkitgtk dependency
package = pkgs.gthumb.override { withWebservices = false; }; package = pkgs.gthumb.override { withWebservices = false; };
mime.priority = 200; # gthumb is kinda bloated image/gallery viewer
mime.associations = { mime.associations = {
"image/gif" = "org.gnome.gThumb.desktop"; "image/gif" = "org.gnome.gThumb.desktop";
"image/heif" = "org.gnome.gThumb.desktop"; # apple codec "image/heif" = "org.gnome.gThumb.desktop"; # apple codec

View File

@@ -0,0 +1,51 @@
# FIRST-TIME SETUP:
# - disable notification sounds: hamburger menu in bottom-left -> preferences
# - notification sounds can be handled by swaync
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.gtkcord4;
in
{
sane.programs.gtkcord4 = {
configOption = with lib; mkOption {
default = {};
type = types.submodule {
options.autostart = mkOption {
type = types.bool;
default = true;
};
};
};
package = pkgs.gtkcord4.overrideAttrs (upstream: {
postConfigure = (upstream.postConfigure or "") + ''
# gtkcord4 uses go-keyring to interface with the org.freedesktop.secrets provider (i.e. gnome-keyring).
# go-keyring hardcodes `login.keyring` as the keyring to store secrets in, instead of reading `~/.local/share/keyring/default`.
# `login.keyring` seems to be a special keyring preconfigured (by gnome-keyring) to encrypt everything to the user's password.
# that's redundant with my fs-level encryption and makes the keyring less inspectable,
# so patch gtkcord4 to use Default_keyring instead.
# see:
# - <https://github.com/diamondburned/gtkcord4/issues/139>
# - <https://github.com/zalando/go-keyring/issues/46>
substituteInPlace vendor/github.com/zalando/go-keyring/secret_service/secret_service.go \
--replace '"login"' '"Default_keyring"'
'';
});
persist.byStore.private = [
".cache/gtkcord4"
".config/gtkcord4" # empty?
];
services.gtkcord4 = {
description = "unofficial Discord chat client";
wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/gtkcord4";
Type = "simple";
Restart = "always";
RestartSec = "20s";
};
};
};
}

View File

@@ -0,0 +1,40 @@
local logger = require("logger")
logger.info("applying colin patch colin-impl-clipboard")
-- source: <https://github.com/ncopa/lua-shell/blob/master/shell.lua>
local function shescape(arg)
if arg:match("[^A-Za-z0-9_/:=-]") then
arg = "'"..arg:gsub("'", "'\\''").."'"
end
return arg
end
-- 2023/12/15: the default setClipboardText doesn't do anything
-- frontend/device/sdl/device.lua calls frontend/device/input.lua is noop
local input = require("ffi/input")
input.setClipboardText = function(text)
logger.info("input.setClipboardText")
local cmd = "wl-copy " .. shescape(text)
logger.info("invoke: " .. cmd)
os.execute(cmd)
end
-- 2023/12/15: the default ReaderLink "Copy" option (when clicking a URL) doesn't do anything
-- patch so it calls `setClipboardText`
local ReaderLink = require("apps/reader/modules/readerlink")
local UIManager = require("ui/uimanager")
local _ = require("gettext")
local orig_ReaderLink_init = ReaderLink.init;
ReaderLink.init = function(self)
orig_ReaderLink_init(self)
self._external_link_buttons["10_copy"] = function(this, link_url)
return {
text = _("Copy"),
callback = function()
UIManager:close(this.external_link_dialog)
input.setClipboardText(link_url)
end,
}
end
end

View File

@@ -1,9 +1,21 @@
# docs:
# - <https://koreader.rocks/user_guide/>
# - <https://github.com/koreader/koreader/wiki>
#
# post-installation setup:
# - download dictionaries:
# - search icon > settings > dictionary settings > download dictionaries
# - these are stored in `~/.config/koreader/data/dict`
# - configure defaults:
# - edit keys in ~/.config/koreader/settings.reader.lua
# - default font size: `["copt_font_size"] = 28,`
# - home dir: `["home_dir"] = "/home/colin/Books",`
{ config, lib, pkgs, sane-lib, ... }: { config, lib, pkgs, sane-lib, ... }:
let let
feeds = sane-lib.feeds; feeds = sane-lib.feeds;
allFeeds = config.sane.feeds; allFeeds = config.sane.feeds;
wantedFeeds = feeds.filterByFormat [ "image" "text" ] allFeeds; wantedFeeds = feeds.filterByFormat [ "text" ] allFeeds;
koreaderRssEntries = builtins.map (feed: koreaderRssEntries = builtins.map (feed:
# format: # format:
# { "<rss/atom url>", limit = <int>, download_full_article=<bool>, include_images=<bool>, enable_filter=<bool>, filter_element = "<css selector>"}, # { "<rss/atom url>", limit = <int>, download_full_article=<bool>, include_images=<bool>, enable_filter=<bool>, filter_element = "<css selector>"},
@@ -14,7 +26,7 @@ let
# enable_filter = true => only render content that matches the filter_element css selector. # enable_filter = true => only render content that matches the filter_element css selector.
let fields = [ let fields = [
(lib.escapeShellArg feed.url) (lib.escapeShellArg feed.url)
"limit = 5" "limit = 20"
"download_full_article = true" "download_full_article = true"
"include_images = true" "include_images = true"
"enable_filter = false" "enable_filter = false"
@@ -26,9 +38,13 @@ in {
package = pkgs.koreader-from-src; package = pkgs.koreader-from-src;
# koreader applies these lua "patches" at boot: # koreader applies these lua "patches" at boot:
# - <https://github.com/koreader/koreader/wiki/User-patches> # - <https://github.com/koreader/koreader/wiki/User-patches>
# - 2023/10/29: koreader code hasn't changed, but somehow FTP browser seems usable even without the isConnected patch now. # the naming is IMPORTANT. these must start with a `2-` in order to be invoked during the right initialization phase
#
# 2023/10/29: koreader code hasn't changed, but somehow FTP browser seems usable even without the isConnected patch now.
# fs.".config/koreader/patches/2-colin-NetworkManager-isConnected.lua".symlink.target = "${./2-colin-NetworkManager-isConnected.lua}"; # fs.".config/koreader/patches/2-colin-NetworkManager-isConnected.lua".symlink.target = "${./2-colin-NetworkManager-isConnected.lua}";
fs.".config/koreader/patches/2-02-colin-impl-clipboard-ops.lua".symlink.target = "${./2-02-colin-impl-clipboard-ops.lua}";
# koreader news plugin, enabled by default. file format described here: # koreader news plugin, enabled by default. file format described here:
# - <repo:koreader/koreader:plugins/newsdownloader.koplugin/feed_config.lua> # - <repo:koreader/koreader:plugins/newsdownloader.koplugin/feed_config.lua>
fs.".config/koreader/news/feed_config.lua".symlink.text = '' fs.".config/koreader/news/feed_config.lua".symlink.text = ''

View File

@@ -6,6 +6,8 @@
# package = pkgs.libreoffice-still; # package = pkgs.libreoffice-still;
package = pkgs.libreoffice-fresh; package = pkgs.libreoffice-fresh;
slowToBuild = true;
# disable first-run stuff # disable first-run stuff
fs.".config/libreoffice/4/user/registrymodifications.xcu".symlink.text = '' fs.".config/libreoffice/4/user/registrymodifications.xcu".symlink.text = ''
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>

View File

@@ -0,0 +1,14 @@
{ pkgs, ... }:
{
sane.programs.loupe = {
mime.associations = {
"image/gif" = "org.gnome.Loupe.desktop";
"image/heif" = "org.gnome.Loupe.desktop"; # apple codec
"image/png" = "org.gnome.Loupe.desktop";
"image/jpeg" = "org.gnome.Loupe.desktop";
"image/svg+xml" = "org.gnome.Loupe.desktop";
"image/webp" = "org.gnome.Loupe.desktop";
};
};
}

View File

@@ -1,11 +0,0 @@
{ pkgs, ... }:
{
sane.programs.megapixels.package = pkgs.megapixels.override {
# megapixels uses zbar to read barcodes.
# zbar by default ships zbarcam-gtk and zbarcam-qt, neither of which megapixels needs.
# but the latter takes a dep on qt, which bloats the closure and the build, so disable this feature.
zbar = pkgs.zbar.override {
enableVideo = false;
};
};
}

View File

@@ -0,0 +1,78 @@
# mimeo is an exec dispatcher like xdg-open, but why allows mapping different URL regexes to different handlers.
# my setup sets mimeo as the default http/https handler,
# and from there it dispatches specialized rules, falling back to the original http/https handler if no URL specialization exists
{ config, lib, pkgs, ... }:
let
mimeo-open-desktop = pkgs.static-nix-shell.mkPython3Bin {
pname = "mimeo-open-desktop";
src = ./.;
pkgs = [ "mimeo" ];
};
# [ProgramConfig]
enabledPrograms = builtins.filter
(p: p.enabled)
(builtins.attrValues config.sane.programs);
# [ProgramConfig]
sortedPrograms = builtins.sort
(l: r: l.priority or 1000 < r.priority or 1000)
enabledPrograms;
fmtAssoc = regex: desktop: ''
${mimeo-open-desktop}/bin/mimeo-open-desktop ${desktop} %U
${regex}
'';
assocs = builtins.map
(program: lib.mapAttrsToList fmtAssoc program.mime.urlAssociations)
sortedPrograms;
assocs' = lib.flatten assocs;
fmtFallbackAssoc = mimeType: desktop: if mimeType == "x-scheme-handler/http" then ''
${mimeo-open-desktop}/bin/mimeo-open-desktop ${desktop} %U
^http://.*
'' else if mimeType == "x-scheme-handler/https" then ''
${mimeo-open-desktop}/bin/mimeo-open-desktop ${desktop} %U
^https://.*
'' else "";
fmtFallbackAssoc' = mimeType: desktop:
lib.optionalString (desktop != "mimeo.desktop") (fmtFallbackAssoc mimeType desktop);
fallbackAssocs = builtins.map
(program: lib.mapAttrsToList fmtFallbackAssoc' program.mime.associations)
sortedPrograms;
fallbackAssocs' = lib.flatten fallbackAssocs;
in
{
sane.programs.mimeo = {
package = pkgs.mimeo.overridePythonAttrs (upstream: {
nativeBuildInputs = (upstream.nativeBuildInputs or []) ++ [
pkgs.copyDesktopItems
];
desktopItems = [
(pkgs.makeDesktopItem {
name = "mimeo";
desktopName = "Mimeo";
exec = "mimeo %U";
comment = "Open files by MIME-type or file name using regular expressions.";
})
];
# upstream mimeo doesn't run preInstall/postInstall hooks, but we need that for the .desktop file
installPhase = ''
runHook preInstall
${upstream.installPhase}
runHook postInstall
'';
passthru = (upstream.passthru or {}) // {
inherit mimeo-open-desktop;
};
});
fs.".config/mimeo/associations.txt".symlink.text = lib.concatStringsSep "\n" (assocs' ++ fallbackAssocs');
mime.priority = 20;
mime.associations."x-scheme-handler/http" = "mimeo.desktop";
mime.associations."x-scheme-handler/https" = "mimeo.desktop";
};
}

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p "python3.withPackages (ps: [ ])" -p mimeo
# TODO: migrate nixpkgs mimeo to be `buildPythonPackage` to make it importable here.
# see <doc/languages-frameworks/python.section.md>
import subprocess
import sys
desktop = sys.argv[1]
opener_args = sys.argv[2:]
desktop_fields=subprocess.check_output([
"mimeo",
"--desk2field",
"Exec",
desktop
]).decode('utf-8')
# print(f"fields: {desktop_fields!r}")
desktop_exec = '\n'.join(desktop_fields.split('\n')[1:])
# print(f"exec: {desktop_exec!r}")
# TODO: this is obviously not correct if any of the args included spaces
desktop_argv = [f.strip() for f in desktop_exec.split(' ') if f.strip()]
# print(f"desktop_argv: {desktop_argv!r}")
# fields explained: <https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s07.html>
# - %U = all URLs
# - %U = just the first URL
substituted_argv = []
for arg in desktop_argv:
if arg == '%U':
substituted_argv += opener_args
elif arg == '%u':
substituted_argv += opener_args[:1]
else:
substituted_argv += [arg]
# print(f"argv: {substituted_argv}")
print(subprocess.check_output(substituted_argv).decode())

View File

@@ -23,16 +23,19 @@ in
package = pkgs.wrapMpv pkgs.mpv-unwrapped { package = pkgs.wrapMpv pkgs.mpv-unwrapped {
scripts = with pkgs.mpvScripts; [ scripts = with pkgs.mpvScripts; [
mpris mpris
# uosc uosc
pkgs.mpv-uosc-latest # pkgs.mpv-uosc-latest
]; ];
extraMakeWrapperArgs = lib.optionals (cfg.config.vo != null) [ extraMakeWrapperArgs = lib.optionals (cfg.config.vo != null) [
# 2023/08/29: fixes an error where mpv on moby launches with the message # 2023/08/29: fixes an error where mpv on moby launches with the message
# "DRM_IOCTL_MODE_CREATE_DUMB failed: Cannot allocate memory" # "DRM_IOCTL_MODE_CREATE_DUMB failed: Cannot allocate memory"
# audio still works, and controls, screenshotting, etc -- just not the actual rendering # audio still works, and controls, screenshotting, etc -- just not the actual rendering
#
# this is likely a regression for mpv 0.36.0. # this is likely a regression for mpv 0.36.0.
# the actual error message *appears* to come from the mesa library, but it's tough to trace. # the actual error message *appears* to come from the mesa library, but it's tough to trace.
# #
# TODO(2023/12/03): remove once mesa 23.3.1 lands: <https://github.com/NixOS/nixpkgs/pull/265740>
#
# backend compatibility (2023/10/22): # backend compatibility (2023/10/22):
# run with `--vo=help` to see a list of all output options. # run with `--vo=help` to see a list of all output options.
# non-exhaustive (W=works, F=fails, A=audio-only, U=audio+ui only (no video)) # non-exhaustive (W=works, F=fails, A=audio-only, U=audio+ui only (no video))
@@ -54,13 +57,46 @@ in
]; ];
}; };
persist.byStore.plaintext = [ ".local/state/mpv/watch_later" ]; persist.byStore.plaintext = [ ".local/state/mpv/watch_later" ];
fs.".config/mpv/input.conf".symlink.text = '' fs.".config/mpv/input.conf".symlink.text = let
execInTerm = "${pkgs.xdg-terminal-exec}/bin/xdg-terminal-exec";
in ''
# docs:
# - <https://mpv.io/manual/master/#list-of-input-commands>
# - script-binding: <https://mpv.io/manual/master/#command-interface-script-binding>
# - 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 sxmo.
# 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
VOLUME_DOWN ignore VOLUME_DOWN ignore
# uosc menu
# text after the shebang is parsed by uosc to construct the menu and names
menu script-binding uosc/menu
s script-binding uosc/subtitles #! Subtitles
a script-binding uosc/audio #! Audio tracks
q script-binding uosc/stream-quality #! Stream quality
p script-binding uosc/items #! Playlist
c script-binding uosc/chapters #! Chapters
> script-binding uosc/next #! Navigation > Next
< script-binding uosc/prev #! Navigation > Prev
o script-binding uosc/open-file #! Navigation > Open file
# set video-aspect-override "-1" #! Utils > Aspect ratio > Default
# set video-aspect-override "16:9" #! Utils > Aspect ratio > 16:9
# set video-aspect-override "4:3" #! Utils > Aspect ratio > 4:3
# set video-aspect-override "2.35:1" #! Utils > Aspect ratio > 2.35:1
# script-binding uosc/audio-device #! Utils > Audio devices
# script-binding uosc/editions #! Utils > Editions
ctrl+s async screenshot #! Utils > Screenshot
alt+i script-binding uosc/keybinds #! Utils > Key bindings
O script-binding uosc/show-in-directory #! Utils > Show in directory
# script-binding uosc/open-config-directory #! Utils > Open config directory
# set pause yes; run ${execInTerm} go2tv -v "''${stream-open-filename}" #! Cast
# set pause yes; run ${execInTerm} go2tv -u "''${stream-open-filename}" #! Cast (...) > Stream
# set pause yes; run go2tv #! Cast (...) > GUI
# TODO: unify "Cast" and "Cast (stream)" options above.
''; '';
fs.".config/mpv/mpv.conf".symlink.text = '' fs.".config/mpv/mpv.conf".symlink.text = ''
save-position-on-quit=yes save-position-on-quit=yes
@@ -91,6 +127,7 @@ in
in '' in ''
# docs: # docs:
# - <https://github.com/tomasklaen/uosc> # - <https://github.com/tomasklaen/uosc>
# - <https://github.com/tomasklaen/uosc/blob/main/src/uosc.conf>
# - <https://superuser.com/questions/1775550/add-new-buttons-to-mpv-uosc-ui> # - <https://superuser.com/questions/1775550/add-new-buttons-to-mpv-uosc-ui>
timeline_style=bar timeline_style=bar
timeline_persistency=paused,audio timeline_persistency=paused,audio
@@ -107,8 +144,7 @@ in
text_border=6.0 text_border=6.0
font_bold=yes font_bold=yes
background_text=ff8080 color=foreground=ff8080,background_text=ff8080
foreground=ff8080
ui_scale=1.0 ui_scale=1.0
''; '';
@@ -117,11 +153,16 @@ in
mime.priority = 50; # default = 100; 50 in order to take precedence over vlc. mime.priority = 50; # default = 100; 50 in order to take precedence over vlc.
mime.associations."audio/flac" = "mpv.desktop"; mime.associations."audio/flac" = "mpv.desktop";
mime.associations."audio/mpeg" = "mpv.desktop"; mime.associations."audio/mpeg" = "mpv.desktop";
mime.associations."audio/x-opus+ogg" = "mpv.desktop";
mime.associations."audio/x-vorbis+ogg" = "mpv.desktop"; mime.associations."audio/x-vorbis+ogg" = "mpv.desktop";
mime.associations."video/mp4" = "mpv.desktop"; mime.associations."video/mp4" = "mpv.desktop";
mime.associations."video/quicktime" = "mpv.desktop"; mime.associations."video/quicktime" = "mpv.desktop";
mime.associations."video/webm" = "mpv.desktop"; mime.associations."video/webm" = "mpv.desktop";
mime.associations."video/x-flv" = "mpv.desktop";
mime.associations."video/x-matroska" = "mpv.desktop"; mime.associations."video/x-matroska" = "mpv.desktop";
mime.urlAssociations."^https?://(www.)?youtube.com/watch\?.*v=" = "mpv.desktop";
mime.urlAssociations."^https?://(www.)?youtube.com/v/" = "mpv.desktop";
mime.urlAssociations."^https?://(www.)?youtu.be/.+" = "mpv.desktop";
}; };
} }

View File

@@ -0,0 +1,12 @@
{ pkgs, ... }:
{
sane.programs."gnome.nautilus" = {
package = pkgs.gnome.nautilus.overrideAttrs (orig: {
# enable the "Audio and Video Properties" pane. see: <https://nixos.wiki/wiki/Nautilus>
buildInputs = orig.buildInputs ++ (with pkgs.gst_all_1; [
gst-plugins-good
gst-plugins-bad
]);
});
};
}

View File

@@ -85,27 +85,13 @@ let
plugin-config-lua = concatMapStrings (p: optionalString (p.type or "" == "lua") p.config) plugins; plugin-config-lua = concatMapStrings (p: optionalString (p.type or "" == "lua") p.config) plugins;
in in
{ {
# private because there could be sensitive things in the swap
sane.programs.neovim = { sane.programs.neovim = {
persist.byStore.private = [ ".cache/vim-swap" ]; # package = config.programs.neovim.finalPackage;
env.EDITOR = "vim"; package = pkgs.wrapNeovimUnstable pkgs.neovim-unwrapped (pkgs.neovimUtils.makeNeovimConfig {
# git claims it should use EDITOR, but it doesn't! withRuby = false; #< doesn't cross-compile w/o binfmt
env.GIT_EDITOR = "vim";
mime.priority = 200; # default=100 => yield to other, more specialized applications
mime.associations."application/schema+json" = "nvim.desktop";
mime.associations."plain/text" = "nvim.desktop";
mime.associations."text/markdown" = "nvim.desktop";
};
programs.neovim = mkIf config.sane.programs.neovim.enabled {
# neovim: https://github.com/neovim/neovim
enable = true;
viAlias = true; viAlias = true;
vimAlias = true; vimAlias = true;
configure = { plugins = plugin-packages;
packages.plugins = {
start = plugin-packages;
};
customRC = '' customRC = ''
" let the terminal handle mouse events, that way i get OS-level ctrl+shift+c/etc " let the terminal handle mouse events, that way i get OS-level ctrl+shift+c/etc
" this used to be default, until <https://github.com/neovim/neovim/pull/19290> " this used to be default, until <https://github.com/neovim/neovim/pull/19290>
@@ -147,6 +133,16 @@ in
${plugin-config-lua} ${plugin-config-lua}
EOF EOF
''; '';
}; });
# private because there could be sensitive things in the swap
persist.byStore.private = [ ".cache/vim-swap" ];
env.EDITOR = "vim";
# git claims it should use EDITOR, but it doesn't!
env.GIT_EDITOR = "vim";
mime.priority = 200; # default=100 => yield to other, more specialized applications
mime.associations."application/schema+json" = "nvim.desktop";
mime.associations."plain/text" = "nvim.desktop";
mime.associations."text/markdown" = "nvim.desktop";
}; };
} }

View File

@@ -1,12 +1,19 @@
# news-flash RSS viewer # news-flash RSS viewer
# - feeds have to be manually imported:
# - Local RSS -> Import OPML -> ~/.config/newsflashFeeds.opml
# - clicking article-embedded links doesn't work because of xdg portal stuff
# - need to either run unsandboxed, or install a org.freedesktop.portal.OpenURI handler
{ config, sane-lib, ... }: { config, sane-lib, ... }:
let let
feeds = sane-lib.feeds; feeds = sane-lib.feeds;
all-feeds = config.sane.feeds; all-feeds = config.sane.feeds;
wanted-feeds = feeds.filterByFormat ["text" "image"] all-feeds; # text/image: newsflash renders these natively
# podcast/video: newsflash dispatches these to xdg-open
wanted-feeds = feeds.filterByFormat [ "text" "image" "podcast" "video" ] all-feeds;
in { in {
sane.programs.newsflash = { sane.programs.newsflash = {
slowToBuild = true; # mainly for desktop: webkitgtk-6.0
persist.byStore.plaintext = [ ".local/share/news-flash" ]; persist.byStore.plaintext = [ ".local/share/news-flash" ];
fs.".config/newsflashFeeds.opml".symlink.text = fs.".config/newsflashFeeds.opml".symlink.text =
feeds.feedsToOpml wanted-feeds feeds.feedsToOpml wanted-feeds

View File

@@ -0,0 +1,8 @@
{ ... }:
{
sane.programs.notejot = {
persist.byStore.private = [
".local/share/io.github.lainsce.Notejot"
];
};
}

View File

@@ -0,0 +1,18 @@
{ ... }:
{
sane.programs.open-in-mpv = {
# taken from <https://github.com/Baldomo/open-in-mpv>
fs.".config/open-in-mpv/config.yml".symlink.text = ''
players:
mpv:
name: mpv
executable: mpv
fullscreen: "--fs"
pip: "--ontop --no-border --autofit=384x216 --geometry=98\\%:98\\%"
enqueue: ""
new_window: ""
needs_ipc: true
flag_overrides: {}
'';
};
}

View File

@@ -0,0 +1,11 @@
{ ... }:
{
sane.programs.planify = {
persist.byStore.private = [
# TODO items as a sqlite database
".local/share/io.github.alainm23.planify"
];
slowToBuild = true; # webkitgtk-6.0; slow for desktop
};
}

View File

@@ -0,0 +1,44 @@
# TODO(bug): signal-desktop is known to hang on exit.
# particularly, it may fail to start (because e.g. there's no wayland session yet),
# and it will try to exit -- after which the service would restart -- but it hangs w/ no GUI instead.
# characterized by these log messages:
#
# Dec 03 13:46:23 moby signal-desktop[4097]: [4097:1203/134623.906367:ERROR:ozone_platform_x11.cc(240)] Missing X server or $DISPLAY
# Dec 03 13:46:23 moby signal-desktop[4097]: [4097:1203/134623.909667:ERROR:env.cc(255)] The platform failed to initialize. Exiting.
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.signal-desktop;
in
{
sane.programs.signal-desktop = {
configOption = with lib; mkOption {
default = {};
type = types.submodule {
options.autostart = mkOption {
type = types.bool;
default = false;
};
};
};
package = pkgs.signal-desktop-from-src;
# creds, media
persist.byStore.private = [
".config/Signal"
];
services.signal-desktop = {
description = "Signal Messenger";
wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/signal-desktop";
Type = "simple";
Restart = "always";
RestartSec = "20s";
};
# for some reason the --ozone-platform-hint=auto flag fails when signal-desktop is launched from a service
environment.NIXOS_OZONE_WL = "1";
};
};
}

View File

@@ -0,0 +1,11 @@
{ ... }:
{
sane.programs.spot = {
secrets.".cache/spot/librespot/credentials/credentials.json" = ../../../secrets/common/spot_credentials.json.bin;
persist.byStore.plaintext = [
".cache/spot/img" # album art
".cache/spot/librespot/audio" # audio/track cache
".cache/spot/net" # album metadata
];
};
}

View File

@@ -0,0 +1,10 @@
{ ... }:
{
sane.programs.superTuxKart = {
persist.byStore.plaintext = [
".cache/supertuxkart"
".config/supertuxkart"
".local/share/supertuxkart"
];
};
}

View File

@@ -0,0 +1,44 @@
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.sway-autoscaler;
in
{
sane.programs.sway-autoscaler = {
configOption = with lib; mkOption {
default = {};
type = types.submodule {
options.autostart = mkOption {
type = types.bool;
default = false;
};
options.defaultScale = mkOption {
type = types.number;
default = 1;
};
options.interval = mkOption {
type = types.number;
default = 5;
};
};
};
package = pkgs.static-nix-shell.mkBash {
pname = "sway-autoscaler";
pkgs = [ "jq" "sway" "util-linux" ];
src = ./.;
};
services.sway-autoscaler = {
description = "adjust global desktop scale to match the activate application";
wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/sway-autoscaler --loop-sec ${builtins.toString cfg.config.interval}";
Type = "simple";
Restart = "always";
RestartSec = "10s";
};
environment.SWAY_DEFAULT_SCALE = builtins.toString cfg.config.defaultScale;
};
};
}

View File

@@ -0,0 +1,87 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p jq -p sway -p util-linux
help() {
echo "queries the focused window and apply an appropriate display-wide scale."
echo "this should be considered a temporary workaround until more apps support small displays."
echo ""
echo "args:"
echo " -v | --verbose"
echo " --loop-sec N: re-compute the scale every N seconds. else, run once and exit."
echo ""
echo "environment variables:"
echo " SWAY_DEFAULT_SCALE=N: scale to apply when no known window is selected."
# TODO: could use map-style environment variables to allow external per-app config
# - SWAY_SCALE_org.gnome.Maps=1 ; ...
}
options=$(getopt -l h,loop-sec:,verbose -o h,v -- "" "${@}")
eval "set -- ${options}"
verbose=false
loop=false
loop_sec=
while true; do
case "$1" in
(-h|--help)
shift
help
exit
;;
(--loop-sec)
shift
loop=true
loop_sec="$1"
shift
;;
(-v|--verbose)
shift
verbose=true
;;
(--)
shift
if [ $# -eq 1 ]; then
break
fi
;;
(*)
echo "invalid arguments: '$1'"
echo ""
help
exit 1
;;
esac
done
autoscale() {
focused=$(swaymsg -t get_tree | jq --raw-output '.. | select(.type?) | select(.focused==true) | .app_id')
$verbose && echo "focused: '$focused'"
scale=${SWAY_DEFAULT_SCALE:-1}
case "$focused" in
(org.gnome.Maps)
# scale=1.6: 3 turns visible at once in landscape
# scale=1.25: max scale at which no text/menuitems are cutoff in vertical mode
# 5 turns visible at once in landscape
# scale=1.2: max of 6 turns visible at once in landscape
# scale=1.1: max of 7 turns visible at once in landscape
# scale=1: max of 8 turns visible at once in landscape
#
# as scale is increased past 1.1, vertical mode becomes substantially less usable
# as scale is decreased past 1.3, the whole desktop UI becomes less usable (keyboard, workspaces)
scale=1.2
;;
esac
$verbose && echo "scaling to $scale"
swaymsg -q -- output '*' scale "$scale"
}
if $loop; then
while true; do
autoscale
sleep "$loop_sec"
done
else
autoscale
fi

View File

@@ -17,6 +17,9 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
cfg = config.sane.programs.swaynotificationcenter; cfg = config.sane.programs.swaynotificationcenter;
mprisIconSize = 48;
fbcli-wrapper = pkgs.writeShellApplication { fbcli-wrapper = pkgs.writeShellApplication {
name = "swaync-fbcli"; name = "swaync-fbcli";
runtimeInputs = [ runtimeInputs = [
@@ -116,8 +119,15 @@ in
package = pkgs.rmDbusServices (pkgs.swaynotificationcenter.overrideAttrs (upstream: { package = pkgs.rmDbusServices (pkgs.swaynotificationcenter.overrideAttrs (upstream: {
# allow toggle buttons: # allow toggle buttons:
patches = (upstream.patches or []) ++ [ patches = (upstream.patches or []) ++ [
# (pkgs.fetchpatch {
# url = "https://github.com/ErikReider/SwayNotificationCenter/pull/304.patch";
# name = "Add toggle button";
# hash = "sha256-bove2EXc5FZ5nN1X1FYOn3czCgHG03ibIAupJNoctiM=";
# })
(pkgs.fetchpatch { (pkgs.fetchpatch {
url = "https://github.com/ErikReider/SwayNotificationCenter/pull/304.patch"; # import of <https://github.com/ErikReider/SwayNotificationCenter/pull/304>
# as of 2023/11/08 the upstream patch has merge conflicts AND runtime issues (see wip-swaync-update nixos branch)
url = "https://git.uninsane.org/colin/SwayNotificationCenter/commit/d9a0d938b88cbee65cfaef887af77a5a23d5fe89.patch";
name = "Add toggle button"; name = "Add toggle button";
hash = "sha256-bove2EXc5FZ5nN1X1FYOn3czCgHG03ibIAupJNoctiM="; hash = "sha256-bove2EXc5FZ5nN1X1FYOn3czCgHG03ibIAupJNoctiM=";
}) })
@@ -127,6 +137,12 @@ in
hash = "sha256-Y8fiZbAP9yGOVU3rOkZKO8TnPPlrGpINWYGaqeeNzF0="; hash = "sha256-Y8fiZbAP9yGOVU3rOkZKO8TnPPlrGpINWYGaqeeNzF0=";
}) })
]; ];
postPatch = (upstream.postPatch or "") + ''
# XXX: this might actually be changing the DPI, not the scaling...
# in that case, it might be possible to do this in CSS
substituteInPlace src/controlCenter/widgets/mpris/mpris_player.ui \
--replace '96' '${builtins.toString mprisIconSize}'
'';
})); }));
suggestedPrograms = [ "feedbackd" ]; suggestedPrograms = [ "feedbackd" ];
fs.".config/swaync/style.css".symlink.text = '' fs.".config/swaync/style.css".symlink.text = ''
@@ -145,11 +161,14 @@ in
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
} }
button { .widget-buttons-grid>flowbox>flowboxchild>button.toggle {
/* text color for inactive buttons, and "Clear All" button.*/ /* text color for inactive buttons, and "Clear All" button.*/
color: rgb(172, 172, 172); color: rgb(172, 172, 172);
/* padding defaults to 16px; tighten, so i can squish it all onto one row */
padding-left: 0px;
padding-right: 0px;
} }
button.active { .widget-buttons-grid>flowbox>flowboxchild>button.toggle.active {
color: rgb(255, 255, 255); color: rgb(255, 255, 255);
background-color: rgb(0, 110, 190); background-color: rgb(0, 110, 190);
} }
@@ -208,12 +227,39 @@ in
# - SWAYNC_REPLACES_ID # - SWAYNC_REPLACES_ID
# - SWAYNC_ID # - SWAYNC_ID
# - SWAYNC_SUMMARY # - SWAYNC_SUMMARY
incoming-im = {
# rules to use for testing. trigger with:
# - `notify-send test test:message` (etc)
# should also be possible to trigger via any messaging app
fbcli-test-im = {
body = "test:message";
exec = "${fbcli} --event proxied-message-new-instant";
};
fbcli-test-call = {
body = "test:call";
exec = "${fbcli} --event phone-incoming-call -t 20";
};
fbcli-test-call-stop = {
body = "test:call-stop";
exec = "${fbcli-stop} --event phone-incoming-call -t 20";
};
fbcli-test-timer = {
body = "test:timer";
exec = "${fbcli} --event timeout-completed";
};
incoming-im-known-app-name = {
# trigger notification sound on behalf of these IM clients. # trigger notification sound on behalf of these IM clients.
app-name = "(Chats|Dino|discord|Element|Fractal)"; app-name = "(Chats|Dino|discord|Element|Fractal|gtkcord4)";
body = "^(?!Incoming call).*$"; #< don't match Dino Incoming calls body = "^(?!Incoming call).*$"; #< don't match Dino Incoming calls
exec = "${fbcli} --event proxied-message-new-instant"; exec = "${fbcli} --event proxied-message-new-instant";
}; };
incoming-im-known-desktop-entry = {
# trigger notification sound on behalf of these IM clients.
# these clients don't have an app-name (listed as "<unknown>"), but do have a desktop-entry
desktop-entry = "com.github.uowuo.abaddon";
exec = "${fbcli} --event proxied-message-new-instant";
};
incoming-call = { incoming-call = {
app-name = "Dino"; app-name = "Dino";
body = "^Incoming call$"; body = "^Incoming call$";
@@ -318,22 +364,22 @@ in
lib.optionals config.sane.programs.eg25-control.enabled [ lib.optionals config.sane.programs.eg25-control.enabled [
{ {
type = "toggle"; type = "toggle";
label = "gps"; label = ""; # GPS services; other icons: gps, ⌖, 🛰, 🌎, 
command = "/run/wrappers/bin/sudo ${systemctl-toggle}/bin/systemctl-toggle eg25-control-gps"; command = "/run/wrappers/bin/sudo ${systemctl-toggle}/bin/systemctl-toggle eg25-control-gps";
active = "${pkgs.systemd}/bin/systemctl is-active eg25-control-gps.service"; active = "${pkgs.systemd}/bin/systemctl is-active eg25-control-gps.service";
} }
{ {
type = "toggle"; type = "toggle";
label = "5g"; label = "󰺐"; # icons: 5g, 📡, 📱, ᯤ, ⚡, , 🌐, 📶, 🗼, 󰀂, , 󰺐, 󰩯
# modem and NetworkManager auto-establishes a connection when powered. # modem and NetworkManager auto-establishes a connection when powered.
# though some things like `wg-home` VPN tunnel will remain routed over the old interface. # though some things like `wg-home` VPN tunnel will remain routed over the old interface.
command = "/run/wrappers/bin/sudo ${systemctl-toggle}/bin/systemctl-toggle eg25-control-powered"; command = "/run/wrappers/bin/sudo ${systemctl-toggle}/bin/systemctl-toggle eg25-control-powered";
active = "${pkgs.systemd}/bin/systemctl is-active eg25-control-powered.service"; active = "${pkgs.systemd}/bin/systemctl is-active eg25-control-powered.service";
} }
] ++ [ ] ++ lib.optionals false [
{ {
type = "toggle"; type = "toggle";
label = "vpn::hn"; label = "vpn::hn"; # route all traffic through servo; useful to debug moby's networking
command = "/run/wrappers/bin/sudo ${systemctl-toggle}/bin/systemctl-toggle wg-quick-vpn-servo"; command = "/run/wrappers/bin/sudo ${systemctl-toggle}/bin/systemctl-toggle wg-quick-vpn-servo";
active = "${pkgs.systemd}/bin/systemctl is-active wg-quick-vpn-servo.service"; active = "${pkgs.systemd}/bin/systemctl is-active wg-quick-vpn-servo.service";
} }
@@ -344,6 +390,35 @@ in
command = "${systemctl-toggle}/bin/systemctl-toggle --user gnome-calls"; command = "${systemctl-toggle}/bin/systemctl-toggle --user gnome-calls";
active = "${pkgs.systemd}/bin/systemctl is-active --user gnome-calls"; active = "${pkgs.systemd}/bin/systemctl is-active --user gnome-calls";
} }
] ++ lib.optionals config.sane.programs."gnome.geary".enabled [
{
type = "toggle";
label = "󰇮"; # email (Geary); other icons: ✉, [E], 📧, 󰇮
command = "${systemctl-toggle}/bin/systemctl-toggle --user geary";
active = "${pkgs.systemd}/bin/systemctl is-active --user geary";
}
# ] ++ lib.optionals config.sane.programs.abaddon.enabled [
# # XXX: disabled in favor of gtkcord4: abaddon has troubles auto-connecting at start
# {
# type = "toggle";
# label = "󰊴"; # Discord chat client; icons: 󰊴, 🎮
# command = "${systemctl-toggle}/bin/systemctl-toggle --user abaddon";
# active = "${pkgs.systemd}/bin/systemctl is-active --user abaddon";
# }
] ++ lib.optionals config.sane.programs.gtkcord4.enabled [
{
type = "toggle";
label = "󰊴"; # Discord chat client; icons: 󰊴, 🎮
command = "${systemctl-toggle}/bin/systemctl-toggle --user gtkcord4";
active = "${pkgs.systemd}/bin/systemctl is-active --user gtkcord4";
}
] ++ lib.optionals config.sane.programs.signal-desktop.enabled [
{
type = "toggle";
label = "💬"; # Signal messenger; other icons: 󰍦
command = "${systemctl-toggle}/bin/systemctl-toggle --user signal-desktop";
active = "${pkgs.systemd}/bin/systemctl is-active --user signal-desktop";
}
] ++ lib.optionals config.sane.programs.dino.enabled [ ] ++ lib.optionals config.sane.programs.dino.enabled [
{ {
type = "toggle"; type = "toggle";
@@ -369,7 +444,7 @@ in
clear-all-button = true; clear-all-button = true;
}; };
mpris = { mpris = {
image-size = 64; image-size = mprisIconSize;
image-radius = 8; image-radius = 8;
}; };
title = { title = {

View File

@@ -27,6 +27,8 @@ in
'' + (upstream.preFixup or ""); '' + (upstream.preFixup or "");
}); });
slowToBuild = true; # only true for cross-compiled tangram
persist.byStore.private = [ persist.byStore.private = [
".cache/Tangram" ".cache/Tangram"
".local/share/Tangram" ".local/share/Tangram"

View File

@@ -1,26 +1,6 @@
{ pkgs, ... }: { ... }:
{ {
sane.programs.tuba = { sane.programs.tuba = {
package = pkgs.tuba.overrideAttrs (upstream: {
postInstall = (upstream.postInstall or "") + ''
# ship a `tuba` alias to the actual tuba binary, since i can never remember its name
ln -s $out/bin/dev.geopjr.Tuba $out/bin/tuba
'';
preFixup = (upstream.preFixup or "") + ''
# 2023/09/24: fix so i can upload media when creating a post.
# see: <https://github.com/GeopJr/Tuba/issues/414#issuecomment-1732695845>
gappsWrapperArgs+=(
--prefix GDK_DEBUG , no-portals
)
'';
# alternative to disabling portals is to remove the filters on FileDialogs.
# done like so (but would want to apply to the other dialogs too)
# postPatch = (upstream.postPatch or "") + ''
# substituteInPlace src/Dialogs/ProfileEdit.vala \
# --replace "default_filter = filter" ""
# '';
});
suggestedPrograms = [ "gnome-keyring" ]; suggestedPrograms = [ "gnome-keyring" ];
}; };
} }

View File

@@ -32,6 +32,7 @@ in
mime.associations."video/mp4" = "vlc.desktop"; mime.associations."video/mp4" = "vlc.desktop";
mime.associations."video/quicktime" = "vlc.desktop"; mime.associations."video/quicktime" = "vlc.desktop";
mime.associations."video/webm" = "vlc.desktop"; mime.associations."video/webm" = "vlc.desktop";
mime.associations."video/x-flv" = "vlc.desktop";
mime.associations."video/x-matroska" = "vlc.desktop"; mime.associations."video/x-matroska" = "vlc.desktop";
}; };
} }

View File

@@ -0,0 +1,18 @@
{ ... }:
{
sane.programs.wike = {
# wike probably meant to put everything here in a subdir, but didn't.
persist.byStore.cryptClearOnBoot = [
".cache/webkitgtk"
".local/share/webkitgtk"
];
persist.byStore.private = [
".local/share/historic.json" # history
# .local/share/cookies (probably not necessary to persist?)
# .local/share/booklists.json (empty; not sure if wike's)
# .local/share/bookmarks.json (empty; not sure if wike's)
# .local/share/languages.json (not sure if wike's)
];
};
}

View File

@@ -0,0 +1,11 @@
{ ... }:
{
sane.programs.wine = {
# no need for the cryptographic nature, just needs to not use loads of / tmpfs.
persist.byStore.cryptClearOnBoot = [ ".wine" ];
persist.byStore.plaintext = [
# Power Bomberman: <https://www.bombermanboard.com/viewtopic.php?t=1925>
".wine/drive_c/users/colin/AppData/pb"
];
};
}

View File

@@ -1,4 +1,6 @@
{ config, ... }: { config, ... }:
{ {
sane.programs.wireshark.slowToBuild = true;
programs.wireshark.enable = config.sane.programs.wireshark.enabled; programs.wireshark.enable = config.sane.programs.wireshark.enabled;
} }

View File

@@ -0,0 +1,143 @@
# docs:
# - <https://github.com/francma/wob/blob/master/wob.ini.5.scd>
# - `wob -vv` to see config defaults
#
# the wob services defined here are largely based on those from SXMO.
#
# this should arguably be just a (user) service. nothing actually needs `wob` on the PATH.
#
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.wob;
in
{
sane.programs.wob = {
configOption = with lib; mkOption {
default = {};
type = types.submodule {
options.autostart = mkOption {
type = types.bool;
default = true;
};
options.sock = mkOption {
type = types.str;
default = "sxmo.wobsock";
};
};
};
fs.".config/wob/wob.ini".symlink.text = ''
timeout = 900
anchor = top right
orientation = vertical
# margin top right bottom left
# note that wob is "aware" of the sway bar, so margin 0 never overlaps it.
# however it's not aware of sway's window title
margin = 54 3 54 3
height = 164
width = 30
border_offset = 0
border_size = 2
bar_padding = 0
# very light teal, derived from conky background
bar_color = e1f0efDC
background_color = 000000B4
border_color = 000000C8
overflow_bar_color = FF4040DC
overflow_background_color = FFFFFFC8
overflow_border_color = FF4040DC
'';
services.wob = {
description = "Wayland Overlay Bar (renders volume/backlight levels)";
wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ];
serviceConfig = {
# ExecStart = "${cfg.package}/bin/wob";
Type = "simple";
Restart = "always";
RestartSec = "20s";
};
path = [ cfg.package ];
script = ''
wobsock="$XDG_RUNTIME_DIR/${cfg.config.sock}"
rm -f "$wobsock" || true
mkfifo "$wobsock" && wob <> "$wobsock"
# TODO: cleanup should be done in a systemd OnFailure, or OnExit, or whatever
rm -f "$wobsock"
'';
};
services.wob-pulse = {
description = "notify wob when pulseaudio volume changes";
wantedBy = [ "wob.service" ];
serviceConfig = {
Type = "simple";
Restart = "always";
RestartSec = "20s";
};
path = with pkgs; [
# coreutils
gnugrep
gnused
pulseaudio
];
# environment.WOB_VERBOSE = "1";
script = ''
debug() {
printf "$@" >&2
printf "\n" >&2
}
verbose() {
if [ "$WOB_VERBOSE" = "1" ]; then
debug "$@"
fi
}
volismuted() {
pactl get-sink-mute @DEFAULT_SINK@ | grep -q "Mute: yes"
}
volget() {
if volismuted; then
verbose "muted"
printf "0"
else
pactl get-sink-volume @DEFAULT_SINK@ | head -n1 | cut -d'/' -f2 | sed 's/ //g' | sed 's/\%//'
fi
}
notify_volume_change() {
verbose "notify_volume_change"
vol=$(volget)
verbose "got volume: %d -> %d" "$lastvol" "$vol"
if [ "$vol" != "$lastvol" ]; then
debug "notify wob: %d -> %d" "$lastvol" "$vol"
printf "%s\n" "$vol" > "$XDG_RUNTIME_DIR/${cfg.config.sock}"
fi
lastvol="$vol"
}
pactl subscribe | while read -r line; do
verbose "pactl says: %s" "$line"
case "$line" in
"Event 'change' on sink "*)
notify_volume_change
;;
"Event 'change' on source "*)
# microphone volume changed. ignore.
;;
esac
done
'';
};
};
}

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