Compare commits
411 Commits
wip/koread
...
dev-export
Author | SHA1 | Date | |
---|---|---|---|
15e09573d5 | |||
d6479ca148 | |||
cf9558f166 | |||
68bce9c8b7 | |||
913201b9cd | |||
3f748164e4 | |||
ded5d94d69 | |||
815a8b52b6 | |||
639a4cfe50 | |||
b2af4e8983 | |||
ff39fc5d95 | |||
9fea007d4f | |||
f44a094d1d | |||
ec6f90eb44 | |||
bbe583637f | |||
29eab151a1 | |||
a7c5daf8a5 | |||
a23dea03a9 | |||
45e5f3ecca | |||
8bcba8802f | |||
3e2e0ccc1c | |||
c14d88f1ea | |||
e72e847147 | |||
073879e523 | |||
bf302f70f1 | |||
a045eaa181 | |||
b83b2ce0cc | |||
377aec7e07 | |||
9d50a6669a | |||
bded6c9562 | |||
5520c74921 | |||
589c005bc4 | |||
d64a213ec2 | |||
18c940962e | |||
e01b1f35fc | |||
60030860e5 | |||
90894087e5 | |||
bdcccbd894 | |||
b64cf408fb | |||
eaca5b9889 | |||
1c265b2073 | |||
fa98ba86bc | |||
53aee9e651 | |||
d4a305f5bb | |||
fd39efe31f | |||
3b2f4b6f72 | |||
9a16942b16 | |||
fe47d68fd3 | |||
deaee833cf | |||
8d03881109 | |||
e476adfdf5 | |||
4201aa7466 | |||
a85d594c89 | |||
7b98cd3d50 | |||
d256a0b647 | |||
c87ba7f670 | |||
e4e5df80f1 | |||
02f409451d | |||
9f2c7b90ce | |||
559c551752 | |||
304482cc9b | |||
ad9db91812 | |||
1c7997e1ef | |||
deefcaae9a | |||
562008f3c0 | |||
2584d62b28 | |||
dc64193a62 | |||
a7f8089ed8 | |||
e8e63167d2 | |||
c056191de1 | |||
f2a597f698 | |||
7b637f976b | |||
39a378c517 | |||
0f9dfb9f8a | |||
ab7f2fb1ec | |||
a892c364c6 | |||
a5c829fa96 | |||
e844cf5970 | |||
999c6fd880 | |||
2aa4bdd5a6 | |||
05801f298f | |||
0fd1ec861b | |||
37d0473b7f | |||
aaca46c485 | |||
30a6a1c1c2 | |||
2c39ac3015 | |||
cc6a0dd8b3 | |||
fbf62f0531 | |||
c96b951895 | |||
34294341d7 | |||
cdc8885e60 | |||
41416cd184 | |||
3c32246d9a | |||
6862d084ac | |||
6eb3626203 | |||
5f808eab5c | |||
fe15c0b097 | |||
e4fbe9d03c | |||
de09d54c64 | |||
5bf117fc05 | |||
f734797628 | |||
236470dc33 | |||
555627dad5 | |||
49c5ddd9f3 | |||
a43ccaac64 | |||
91c02aec9a | |||
681d3d5520 | |||
f945dc42fa | |||
cc6f33b928 | |||
2f83e73139 | |||
53ccb96234 | |||
a0d6139e50 | |||
90abadf7c4 | |||
7f1e959ece | |||
794df4d762 | |||
d6b262a28e | |||
0cc518e523 | |||
8780dff794 | |||
0f881006e7 | |||
5d349ce042 | |||
940711878b | |||
75048efcf3 | |||
8cc5199d9b | |||
3f60bacd38 | |||
8fb705dde4 | |||
79777cd4ae | |||
fabd1e3b64 | |||
bcb6beef05 | |||
34336e4ade | |||
a518e56cf1 | |||
6cc7655180 | |||
0a15aad6d7 | |||
1d8bee2856 | |||
6894d5828b | |||
35bc222552 | |||
16b5b6840f | |||
1a7837d740 | |||
607bfbe452 | |||
c2b85bd6b8 | |||
c3bc0ec645 | |||
89b5e8145d | |||
0edab7ed64 | |||
c8a3814f6a | |||
9ddac508e2 | |||
3245f8f94c | |||
8be1f43c23 | |||
e29e26605b | |||
7bd6c0c14d | |||
d7c912386f | |||
e7e86cae95 | |||
b083ce87be | |||
17b90fc697 | |||
4fc59fa2ac | |||
e87cda2e55 | |||
2c4d30b5ec | |||
d0af645af8 | |||
a1f79dc18a | |||
ff65a697a9 | |||
ef881b1392 | |||
debea8fa5b | |||
8a9acbaeea | |||
8869ec7bca | |||
dc0268736a | |||
6f9c2a846e | |||
3cb00840de | |||
6a2603a4ea | |||
69efecb2ef | |||
056e6d358e | |||
793baf0e0f | |||
721899258a | |||
4f9d84cd82 | |||
a462180d3c | |||
58f2d87959 | |||
a50b8e6373 | |||
4ec947d549 | |||
6751a74063 | |||
6118a18200 | |||
d223d4be06 | |||
ab7ec9bd74 | |||
7b70b5ec86 | |||
db99043753 | |||
8f87e49606 | |||
5557107259 | |||
1b5c870798 | |||
a5162651b7 | |||
b9868512d6 | |||
8432d9c9ed | |||
5d4f94f218 | |||
7e9d5d99c7 | |||
487e64b09b | |||
5e350b810f | |||
5fb3a6be81 | |||
dbec4b8f32 | |||
f8b559bef1 | |||
7d9d0ce8b5 | |||
7857f123a4 | |||
e3ba156fe1 | |||
c824751682 | |||
e5520437a5 | |||
c6211fe48f | |||
54d6c9008d | |||
05e5edcce3 | |||
3249baccfa | |||
274682cf85 | |||
31a700f6a7 | |||
91a6fc32ef | |||
135b87a091 | |||
6b9484f611 | |||
7a612b701d | |||
c69fb690f1 | |||
1ef73dd69d | |||
54afa1aec5 | |||
72c3c939e2 | |||
67d8e89556 | |||
07408813db | |||
436760a592 | |||
5c758df032 | |||
d12a41bfa9 | |||
8ec22b6320 | |||
95d04467a8 | |||
dd53de96fe | |||
8089334ea9 | |||
5bbb3678ed | |||
4e7ffe3140 | |||
d2842484fd | |||
a8932b5a72 | |||
a283d1ee21 | |||
d41d802d83 | |||
8a0efb3e40 | |||
b013123669 | |||
264657d623 | |||
8ad4ee4341 | |||
664b21e5f1 | |||
163a7af328 | |||
4adeae6d85 | |||
9168803008 | |||
3f9c0d1b60 | |||
cc35317b54 | |||
006070d08f | |||
19f6a98d31 | |||
301abbe155 | |||
dab3a2d0a9 | |||
3a00e93dc3 | |||
4c4b0ce920 | |||
b9259ff8b9 | |||
e2ed37196f | |||
b343d5d83a | |||
9bbff0d7a7 | |||
014fb5a633 | |||
76d8921bdf | |||
b7f23a032c | |||
68be1ba2a1 | |||
5a6bb475c4 | |||
132e15cb9f | |||
07c0878d11 | |||
b993479ada | |||
8dc568d52e | |||
44ee7cd3db | |||
2773cd8406 | |||
9bb26e0199 | |||
8d772074ba | |||
18c6ad0663 | |||
24a91acd0a | |||
bec5241326 | |||
2b5365d774 | |||
e377a9f05b | |||
2f53e94cc9 | |||
75770cd34b | |||
a4860c3963 | |||
4b072ecbe5 | |||
3423f103fc | |||
c3bb776149 | |||
d31aac4d19 | |||
378e72ceb7 | |||
d86be97ced | |||
44388b132a | |||
cd6b112d33 | |||
8eb6be863a | |||
3b5ff938ce | |||
2685c91dd9 | |||
169354bd33 | |||
cc1889d2dd | |||
22ffcb1b55 | |||
76abbac6f6 | |||
12e15b6456 | |||
8c2a4a31bf | |||
1fcfa04447 | |||
f3af31c727 | |||
21e22096b1 | |||
c9383da414 | |||
b82bb13f4f | |||
346a68884b | |||
eb04129959 | |||
2e93f58795 | |||
26b77221da | |||
6877507ae0 | |||
8757f86c57 | |||
633997f452 | |||
ff9163b365 | |||
edd86e3981 | |||
c9b60788b5 | |||
66dad1e519 | |||
687ceba474 | |||
6e85f26964 | |||
40dc8d698e | |||
350f7e32f8 | |||
3a5b72a258 | |||
b40ac95b5c | |||
c1a8d1aa18 | |||
03d7806adf | |||
9d06bfb544 | |||
bf5ac3cb76 | |||
85e63caeb0 | |||
dcf97b70e1 | |||
44059b34c7 | |||
561802ec41 | |||
b464e60a77 | |||
b73b4b0439 | |||
991685d149 | |||
4d7111feef | |||
bd8cec311e | |||
fd174a0475 | |||
3e83a1956c | |||
57f272c9ba | |||
186c09594d | |||
c74ba4e733 | |||
8a126d0a64 | |||
2e04a512b3 | |||
b4c83987f9 | |||
cc09832187 | |||
33b41482e2 | |||
6e523e7162 | |||
995c586fd9 | |||
3aa5852cf2 | |||
8efad09cf4 | |||
a7b71979f9 | |||
1082ab22bf | |||
5b2598bcaa | |||
1ba877b325 | |||
7ab5cfa698 | |||
8a367b718d | |||
4e37f2c651 | |||
2cf714c999 | |||
6f835db8f3 | |||
206dd84477 | |||
381a111944 | |||
3138482ed9 | |||
1796d3c259 | |||
b565a719fb | |||
f7ac46fd30 | |||
61cf801983 | |||
ae9a81919f | |||
9ca8c74ed7 | |||
fd58896c0c | |||
d2a46e88f6 | |||
5cd05d8762 | |||
a35f3e238d | |||
039d685e3c | |||
da42b3ddd7 | |||
51eaf83be8 | |||
d8a6a1df41 | |||
36176abdf3 | |||
085c38ea47 | |||
9adaece9d6 | |||
df8e572a8f | |||
d39b698066 | |||
83c483395c | |||
2e08321016 | |||
abf80d765c | |||
8c0b215832 | |||
28c9bd3cac | |||
e1e40332f7 | |||
28ef8141f7 | |||
ad6b0ea75e | |||
f59da7ad0f | |||
183457444c | |||
28a91723b8 | |||
9b53a28920 | |||
49e33d7238 | |||
6572557b5b | |||
e18fb2ce4e | |||
027e7cb074 | |||
13ae0b798c | |||
d8675b544a | |||
5bf5d82d30 | |||
0c92f3695a | |||
558258c367 | |||
7f13c482e5 | |||
7b21ede5c4 | |||
219bb02cb8 | |||
2df59f7c7d | |||
11a7370a76 | |||
44e3b01e7c | |||
c7f0e5c8b5 | |||
7ce33340f9 | |||
8f77b1db94 | |||
f4cac0c158 | |||
04106e660e | |||
6ed550b813 | |||
1cfd0fab6a | |||
5a31a0b415 | |||
eb82268eee | |||
86964f6fde | |||
3121a6a7e9 | |||
c353f06832 | |||
b6a878757c | |||
c862b559e7 | |||
64c8dabaf2 | |||
512b5d78d4 | |||
0479a43f2d | |||
307e93de3b |
22
TODO.md
22
TODO.md
@@ -1,7 +1,10 @@
|
||||
## BUGS
|
||||
- mpv UI is sometimes blank for audio/podcasts?
|
||||
- i think it's when the audio file has no thumbnail?
|
||||
- why i need to manually restart `wireguard-wg-ovpns` on servo periodically
|
||||
- else DNS fails
|
||||
- fix epiphany URL bar input on moby
|
||||
- sxmo: wvkbd: missing font for icons on the 3rd page
|
||||
|
||||
## REFACTORING:
|
||||
|
||||
@@ -23,6 +26,10 @@
|
||||
- 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
|
||||
- gtk: build schemas even on cross compilation: <https://github.com/NixOS/nixpkgs/pull/247844>
|
||||
- sxmo: add new app entries
|
||||
|
||||
|
||||
## IMPROVEMENTS:
|
||||
### security/resilience
|
||||
@@ -44,6 +51,13 @@
|
||||
- integrate `nix check` into Gitea actions?
|
||||
|
||||
### user experience
|
||||
- moby: sxmo: fix youtube scripts (package youtube-cli)
|
||||
- moby: tune GPS
|
||||
- run only geoclue, and not gpsd, to save power?
|
||||
- tune QGPS setting in eg25-control, for less jitter?
|
||||
- direct mepo to prefer gpsd, with fallback to geoclue, for better accuracy?
|
||||
- configure geoclue to do some smoothing?
|
||||
- manually do smoothing, as some layer between mepo and geoclue/gpsd?
|
||||
- neovim: set up language server (lsp; rnix-lsp; nvim-lspconfig)
|
||||
- Helix: make copy-to-system clipboard be the default
|
||||
- firefox/librewolf: persist history
|
||||
@@ -62,6 +76,12 @@
|
||||
- email: fix so that local mail doesn't go to junk
|
||||
- git sendmail flow adds the DKIM signatures, but gets delivered locally w/o having the sig checked, so goes into Junk
|
||||
- could change junk filter from "no DKIM success" to explicit "DKIM failed"
|
||||
- sxmo: don't put all deps on PATH
|
||||
- maybe: use resholve to hard-code them
|
||||
- this is the most "correct", but least patchable
|
||||
- maybe: express each invocation as a function in sxmo_common.sh
|
||||
- this will require some patching to handle `exec <foo>` style
|
||||
- maybe: save original PATH and reset it before invoking user files
|
||||
|
||||
### perf
|
||||
- add `pkgs.impure-cached.<foo>` package set to build things with ccache enabled
|
||||
@@ -78,4 +98,6 @@
|
||||
## NEW FEATURES:
|
||||
- migrate MAME cabinet to nix
|
||||
- boot it from PXE from servo?
|
||||
- deploy to new server, and use it as a remote builder
|
||||
- enable IPv6
|
||||
- package lemonade lemmy app: <https://linuxphoneapps.org/apps/ml.mdwalters.lemonade/>
|
||||
|
32
flake.lock
generated
32
flake.lock
generated
@@ -21,11 +21,11 @@
|
||||
"mobile-nixos": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1683422260,
|
||||
"narHash": "sha256-79zaClbubRkBNlJ04OSADILuLQHH48N5fu296hEWYlw=",
|
||||
"lastModified": 1690059310,
|
||||
"narHash": "sha256-4zcoDp8wwZVfGSzXltC5x+eH4kDWC/eJpyQNgr7shAA=",
|
||||
"owner": "nixos",
|
||||
"repo": "mobile-nixos",
|
||||
"rev": "ba4638836e94a8f16d1d1f9e8c0530b86078029c",
|
||||
"rev": "56fc9f9619f305f0865354975a98d22410eed127",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -69,11 +69,11 @@
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1689473667,
|
||||
"narHash": "sha256-41ePf1ylHMTogSPAiufqvBbBos+gtB6zjQlYFSEKFMM=",
|
||||
"lastModified": 1693097136,
|
||||
"narHash": "sha256-fBZSMdBaoZ0INFbyZ5s0DOF7zDNcLsLxgkwdDh3l9Pc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "13231eccfa1da771afa5c0807fdd73e05a1ec4e6",
|
||||
"rev": "9117c4e9dc117a6cd0319cca40f2349ed333669d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -85,11 +85,11 @@
|
||||
},
|
||||
"nixpkgs-unpatched": {
|
||||
"locked": {
|
||||
"lastModified": 1689534811,
|
||||
"narHash": "sha256-jnSUdzD/414d94plCyNlvTJJtiTogTep6t7ZgIKIHiE=",
|
||||
"lastModified": 1693377291,
|
||||
"narHash": "sha256-vYGY9bnqEeIncNarDZYhm6KdLKgXMS+HA2mTRaWEc80=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "6cee3b5893090b0f5f0a06b4cf42ca4e60e5d222",
|
||||
"rev": "e7f38be3775bab9659575f192ece011c033655f0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -116,11 +116,11 @@
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1689534977,
|
||||
"narHash": "sha256-EB4hasmjKgetTR0My2bS5AwELZFIQ4zANLqHKi7aVXg=",
|
||||
"lastModified": 1693404499,
|
||||
"narHash": "sha256-cx/7yvM/AP+o/3wPJmA9W9F+WHemJk5t+Xcr+Qwkqhg=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "bd695cc4d0a5e1bead703cc1bec5fa3094820a81",
|
||||
"rev": "d9c5dc41c4b1f74c77f0dbffd0f3a4ebde447b7a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -152,11 +152,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1688265812,
|
||||
"narHash": "sha256-Wkx56Pw7V5+5Gn6B3olDGP+o1qIp8BPFL0MWC2wbKVg=",
|
||||
"lastModified": 1691106178,
|
||||
"narHash": "sha256-3mZ9gTvMpbZA9ea9ovoQpn2wKuQY0QZ7MDdEjArYdAQ=",
|
||||
"ref": "refs/heads/master",
|
||||
"rev": "1542323cfb46a8950c17a3afa5f7cd2e62dd9672",
|
||||
"revCount": 202,
|
||||
"rev": "f4d91aa201b6e49af690f250d4786bd1d8b4dcfd",
|
||||
"revCount": 205,
|
||||
"type": "git",
|
||||
"url": "https://git.uninsane.org/colin/uninsane"
|
||||
},
|
||||
|
73
flake.nix
73
flake.nix
@@ -94,7 +94,17 @@
|
||||
evalHost = { name, local, target }: nixpkgs.lib.nixosSystem {
|
||||
system = target;
|
||||
modules = [
|
||||
(import ./hosts/instantiate.nix { localSystem = local; hostName = name; })
|
||||
{
|
||||
nixpkgs = (if (local != null) then {
|
||||
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;
|
||||
}
|
||||
(import ./hosts/instantiate.nix { hostName = name; })
|
||||
self.nixosModules.default
|
||||
self.nixosModules.passthru
|
||||
{
|
||||
@@ -103,12 +113,6 @@
|
||||
self.overlays.sane-all
|
||||
];
|
||||
}
|
||||
({ lib, ... }: {
|
||||
# TODO: does the earlier `system` arg to nixosSystem make its way here?
|
||||
nixpkgs.hostPlatform.system = target;
|
||||
# nixpkgs.buildPlatform = local; # set by instantiate.nix instead
|
||||
# nixpkgs.config.replaceStdenv = { pkgs }: pkgs.ccacheStdenv;
|
||||
})
|
||||
];
|
||||
};
|
||||
in {
|
||||
@@ -174,6 +178,7 @@
|
||||
disable-flakey-tests = final: prev: import ./overlays/disable-flakey-tests.nix final prev;
|
||||
pkgs = final: prev: import ./overlays/pkgs.nix final prev;
|
||||
pins = final: prev: import ./overlays/pins.nix final prev;
|
||||
preferences = final: prev: import ./overlays/preferences.nix final prev;
|
||||
optimizations = final: prev: import ./overlays/optimizations.nix final prev;
|
||||
passthru = final: prev:
|
||||
let
|
||||
@@ -239,46 +244,78 @@
|
||||
apps."x86_64-linux" =
|
||||
let
|
||||
pkgs = self.legacyPackages."x86_64-linux";
|
||||
deployScript = host: 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} $@
|
||||
sudo nix sign-paths -r -k /run/secrets/nix_serve_privkey $(readlink ./result-${host})
|
||||
|
||||
# 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.
|
||||
# let the user handle that edge case by re-running this whole command
|
||||
nixos-rebuild --flake '.#${host}' ${action} --target-host colin@${host} --use-remote-sudo $@
|
||||
nixos-rebuild --flake '.#${host}' ${action} --target-host colin@${addr} --use-remote-sudo $@
|
||||
'';
|
||||
in {
|
||||
help = {
|
||||
type = "app";
|
||||
program = let
|
||||
helpMsg = builtins.toFile "nixos-config-help-message" ''
|
||||
commands:
|
||||
- `nix run '.#help'`
|
||||
- show this message
|
||||
- `nix run '.#update-feeds'`
|
||||
- updates metadata for all feeds
|
||||
- `nix run '.#init-feed' <url>`
|
||||
- `nix run '.#deploy-{lappy,moby,moby-test,servo}' [nixos-rebuild args ...]`
|
||||
- `nix run '.#check-nur'`
|
||||
'';
|
||||
in builtins.toString (pkgs.writeShellScript "nixos-config-help" ''
|
||||
cat ${helpMsg}
|
||||
'');
|
||||
};
|
||||
update-feeds = {
|
||||
type = "app";
|
||||
program = "${pkgs.feeds.updateScript}";
|
||||
};
|
||||
|
||||
init-feed = {
|
||||
# use like `nix run '.#init-feed' uninsane.org`
|
||||
type = "app";
|
||||
program = "${pkgs.feeds.initFeedScript}";
|
||||
};
|
||||
|
||||
deploy-lappy = {
|
||||
# `nix run '.#deploy-lappy'`
|
||||
type = "app";
|
||||
program = ''${deployScript "lappy" "switch"}'';
|
||||
program = ''${deployScript "lappy" "lappy" "switch"}'';
|
||||
};
|
||||
deploy-moby-test = {
|
||||
# `nix run '.#deploy-moby-test'`
|
||||
type = "app";
|
||||
program = ''${deployScript "moby" "test"}'';
|
||||
program = ''${deployScript "moby" "moby-hn" "test"}'';
|
||||
};
|
||||
deploy-moby = {
|
||||
# `nix run '.#deploy-moby'`
|
||||
type = "app";
|
||||
program = ''${deployScript "moby" "switch"}'';
|
||||
program = ''${deployScript "moby" "moby-hn" "switch"}'';
|
||||
};
|
||||
deploy-servo = {
|
||||
# `nix run '.#deploy-servo'`
|
||||
type = "app";
|
||||
program = ''${deployScript "servo" "switch"}'';
|
||||
program = ''${deployScript "servo" "servo" "switch"}'';
|
||||
};
|
||||
|
||||
sync-moby = {
|
||||
# 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";
|
||||
program = builtins.toString (pkgs.writeShellScript "sync-to-moby" ''
|
||||
sudo mount /mnt/moby-home
|
||||
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music ~/Music /mnt/moby-home/Music
|
||||
'');
|
||||
};
|
||||
|
||||
sync-lappy = {
|
||||
# copy music from servo to lappy
|
||||
# can run this from any device that has ssh access to lappy
|
||||
type = "app";
|
||||
program = builtins.toString (pkgs.writeShellScript "sync-to-lappy" ''
|
||||
sudo mount /mnt/lappy-home
|
||||
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music /mnt/servo-media/Music /mnt/lappy-home/Music
|
||||
'');
|
||||
};
|
||||
|
||||
check-nur = {
|
||||
|
@@ -25,7 +25,7 @@
|
||||
sane.programs.steam.enableFor.user.colin = true;
|
||||
|
||||
sane.programs.guiApps.suggestedPrograms = [ "desktopGuiApps" ];
|
||||
sane.programs.consoleUtils.suggestedPrograms = [ "consoleMediaUtils" ];
|
||||
sane.programs.consoleUtils.suggestedPrograms = [ "consoleMediaUtils" "desktopConsoleUtils" ];
|
||||
# sane.programs.devPkgs.enableFor.user.colin = true;
|
||||
|
||||
boot.loader.efi.canTouchEfiVariables = false;
|
||||
|
@@ -19,7 +19,7 @@
|
||||
"desktopGuiApps"
|
||||
"stepmania"
|
||||
];
|
||||
sane.programs.consoleUtils.suggestedPrograms = [ "consoleMediaUtils" ];
|
||||
sane.programs.consoleUtils.suggestedPrograms = [ "consoleMediaUtils" "desktopConsoleUtils" ];
|
||||
|
||||
sops.secrets.colin-passwd.neededForUsers = true;
|
||||
|
||||
|
@@ -28,7 +28,7 @@
|
||||
# see <repo:mil/sxmo-utils:scripts/deviceprofiles>
|
||||
# SXMO_DEVICE_NAME = "pine64,pinephone-1.2";
|
||||
};
|
||||
package = pkgs.sxmo-utils.overrideAttrs (base: {
|
||||
package = pkgs.sxmo-utils-latest.overrideAttrs (base: {
|
||||
postPatch = (base.postPatch or "") + ''
|
||||
# after volume-button navigation mode, restore full keyboard functionality
|
||||
cp ${./xkb_mobile_normal_buttons} ./configs/xkb/xkb_mobile_normal_buttons
|
||||
|
@@ -12,8 +12,9 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
imports = [
|
||||
./firmware.nix
|
||||
./bootloader.nix
|
||||
./fs.nix
|
||||
./gps.nix
|
||||
./kernel.nix
|
||||
./polyfill.nix
|
||||
];
|
||||
@@ -43,6 +44,7 @@
|
||||
sane.programs.tuiApps.enableFor.user.colin = false; # visidata, others, don't compile well
|
||||
# disabled for faster deploys
|
||||
sane.programs.soundconverter.enableFor.user.colin = false;
|
||||
sane.programs.eg25-control.enableFor.user.colin = true;
|
||||
|
||||
# sane.programs.firefox.mime.priority = 300; # prefer other browsers when possible
|
||||
# HACK/TODO: make `programs.P.env.VAR` behave according to `mime.priority`
|
||||
@@ -111,6 +113,15 @@
|
||||
services.pipewire.environment.ALSA_CONFIG_UCM2 = ucm-env;
|
||||
services.pipewire-pulse.environment.ALSA_CONFIG_UCM2 = ucm-env;
|
||||
services.wireplumber.environment.ALSA_CONFIG_UCM2 = ucm-env;
|
||||
|
||||
|
||||
# TODO: move elsewhere...
|
||||
services.ModemManager.serviceConfig = {
|
||||
# N.B.: the extra "" in ExecStart serves to force upstream ExecStart to be ignored
|
||||
ExecStart = [ "" "${pkgs.modemmanager}/bin/ModemManager --debug" ];
|
||||
# --debug sets DEBUG level logging: so reset
|
||||
ExecStartPost = [ "${pkgs.modemmanager}/bin/mmcli --set-logging=INFO" ];
|
||||
};
|
||||
};
|
||||
|
||||
services.udev.extraRules = let
|
||||
@@ -126,37 +137,4 @@
|
||||
'';
|
||||
|
||||
hardware.opengl.driSupport = true;
|
||||
|
||||
services.xserver.displayManager.job.preStart = let
|
||||
dmesg = "${pkgs.util-linux}/bin/dmesg";
|
||||
grep = "${pkgs.gnugrep}/bin/grep";
|
||||
modprobe = "${pkgs.kmod}/bin/modprobe";
|
||||
in ''
|
||||
# common boot failure:
|
||||
# blank screen (no backlight even), with the following log:
|
||||
# ```syslog
|
||||
# sun8i-dw-hdmi 1ee0000.hdmi: Couldn't get the HDMI PHY
|
||||
# ...
|
||||
# sun4i-drm display-engine: Couldn't bind all pipelines components
|
||||
# ...
|
||||
# sun8i-dw-hdmi: probe of 1ee0000.hdmi failed with error -17
|
||||
# ```
|
||||
#
|
||||
# in particular, that `probe ... failed` occurs *only* on failed boots
|
||||
# (the other messages might sometimes occur even on successful runs?)
|
||||
#
|
||||
# reloading the sun8i hdmi driver usually gets the screen on, showing boot text.
|
||||
# then restarting display-manager.service gets us to the login.
|
||||
#
|
||||
# NB: the above log is default level. though less specific, there's a `err` level message that also signals this:
|
||||
# sun4i-drm display-engine: failed to bind 1ee0000.hdmi (ops sun8i_dw_hdmi_ops [sun8i_drm_hdmi]): -17
|
||||
|
||||
if (${dmesg} --kernel --level err --color=never --notime | ${grep} -q 'sun4i-drm display-engine: failed to bind 1ee0000.hdmi')
|
||||
then
|
||||
echo "reprobing sun8i_drm_hdmi"
|
||||
# if a command here fails it errors the whole service, so prefer to log instead
|
||||
${modprobe} -r sun8i_drm_hdmi || echo "failed to unload sun8i_drm_hdmi"
|
||||
${modprobe} sun8i_drm_hdmi || echo "failed to load sub8i_drm_hdmi"
|
||||
fi
|
||||
'';
|
||||
}
|
||||
|
42
hosts/by-name/moby/gps.nix
Normal file
42
hosts/by-name/moby/gps.nix
Normal file
@@ -0,0 +1,42 @@
|
||||
# pinephone GPS happens in EG25 modem
|
||||
# serial control interface to modem is /dev/ttyUSB2
|
||||
# after enabling GPS, readout is /dev/ttyUSB1
|
||||
#
|
||||
# minimal process to enable modem and GPS:
|
||||
# - `echo 1 > /sys/class/modem-power/modem-power/device/powered`
|
||||
# - `screen /dev/ttyUSB2 115200`
|
||||
# - `AT+QGPSCFG="nmeasrc",1`
|
||||
# - `AT+QGPS=1`
|
||||
#
|
||||
# now, something like `gpsd` can directly read from /dev/ttyUSB1.
|
||||
#
|
||||
# initial GPS fix can take 15+ minutes.
|
||||
# meanwhile, services like eg25-manager can speed this up by uploading assisted GPS data to the modem.
|
||||
#
|
||||
# geoclue somehow fits in here as a geospatial provider that leverages GPS and also other sources like radio towers
|
||||
|
||||
{ lib, ... }:
|
||||
{
|
||||
# test gpsd with `gpspipe -w -n 10 2> /dev/null | grep -m 1 TPV | jq '.lat, .lon' | tr '\n' ' '`
|
||||
# ^ should return <lat> <long>
|
||||
services.gpsd.enable = true;
|
||||
services.gpsd.devices = [ "/dev/ttyUSB1" ];
|
||||
|
||||
# test geoclue2 by building `geoclue2-with-demo-agent`
|
||||
# and running "${geoclue2-with-demo-agent}/libexec/geoclue-2/demos/where-am-i"
|
||||
services.geoclue2.enable = true;
|
||||
services.geoclue2.appConfig.where-am-i = {
|
||||
# this is the default "agent", shipped by geoclue package: allow it to use location
|
||||
isAllowed = true;
|
||||
isSystem = false;
|
||||
# XXX: setting users != [] might be causing `where-am-i` to time out
|
||||
# users = [
|
||||
# # restrict to only one set of users. empty array (default) means "allow any user to access geolocation".
|
||||
# (builtins.toString config.users.users.colin.uid)
|
||||
# ];
|
||||
};
|
||||
systemd.services.geoclue.after = lib.mkForce []; #< defaults to network-online, but not all my sources require network
|
||||
|
||||
|
||||
sane.services.eg25-control.enable = true;
|
||||
}
|
@@ -1,71 +1,56 @@
|
||||
{ lib, pkgs, ... }:
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
# use the last commit on the 5.18 branch (5.18.14)
|
||||
# manjaro's changes between kernel patch versions tend to be minimal if any.
|
||||
manjaroBase = "https://gitlab.manjaro.org/manjaro-arm/packages/core/linux/-/raw/25bd828cd47b1c6e09fcbcf394a649b89d2876dd";
|
||||
manjaroPatch = name: sha256: {
|
||||
inherit name;
|
||||
patch = pkgs.fetchpatch {
|
||||
inherit name;
|
||||
url = "${manjaroBase}/${name}?inline=false";
|
||||
inherit sha256;
|
||||
};
|
||||
};
|
||||
dmesg = "${pkgs.util-linux}/bin/dmesg";
|
||||
grep = "${pkgs.gnugrep}/bin/grep";
|
||||
modprobe = "${pkgs.kmod}/bin/modprobe";
|
||||
ensureHWReady = ''
|
||||
# common boot failure:
|
||||
# blank screen (no backlight even), with the following log:
|
||||
# ```syslog
|
||||
# sun8i-dw-hdmi 1ee0000.hdmi: Couldn't get the HDMI PHY
|
||||
# ...
|
||||
# sun4i-drm display-engine: Couldn't bind all pipelines components
|
||||
# ...
|
||||
# sun8i-dw-hdmi: probe of 1ee0000.hdmi failed with error -17
|
||||
# ```
|
||||
#
|
||||
# in particular, that `probe ... failed` occurs *only* on failed boots
|
||||
# (the other messages might sometimes occur even on successful runs?)
|
||||
#
|
||||
# reloading the sun8i hdmi driver usually gets the screen on, showing boot text.
|
||||
# then restarting display-manager.service gets us to the login.
|
||||
#
|
||||
# NB: the above log is default level. though less specific, there's a `err` level message that also signals this:
|
||||
# sun4i-drm display-engine: failed to bind 1ee0000.hdmi (ops sun8i_dw_hdmi_ops [sun8i_drm_hdmi]): -17
|
||||
# NB: this is the most common, but not the only, failure mode for `display-manager`.
|
||||
# another error seems characterized by these dmesg logs, in which reprobing sun8i_drm_hdmi does not fix:
|
||||
# ```syslog
|
||||
# sun6i-mipi-dsi 1ca0000.dsi: Couldn't get the MIPI D-PHY
|
||||
# sun4i-drm display-engine: Couldn't bind all pipelines components
|
||||
# sun6i-mipi-dsi 1ca0000.dsi: Couldn't register our component
|
||||
# ```
|
||||
|
||||
# the idea for patching off Manjaro's kernel comes from jakewaksbaum:
|
||||
# - https://git.sr.ht/~jakewaksbaum/pi/tree/af20aae5653545d6e67a459b59ee3e1ca8a680b0/item/kernel/default.nix
|
||||
# - he later abandoned this, i think because he's using the Pinephone Pro which received mainline support.
|
||||
manjaroPatches = [
|
||||
(manjaroPatch
|
||||
"1001-arm64-dts-allwinner-add-hdmi-sound-to-pine-devices.patch"
|
||||
"sha256-DApd791A+AxB28Ven/MVAyuyVphdo8KQDx8O7oxVPnc="
|
||||
)
|
||||
# these patches below are critical to enable wifi (RTL8723CS)
|
||||
# - the alternative is a wholly forked kernel by megi/megous:
|
||||
# - https://xnux.eu/howtos/build-pinephone-kernel.html#toc-how-to-build-megi-s-pinehpone-kernel
|
||||
# - i don't know if these patches are based on megi's or original
|
||||
(manjaroPatch
|
||||
"2001-Bluetooth-Add-new-quirk-for-broken-local-ext-features.patch"
|
||||
"sha256-CExhJuUWivegxPdnzKINEsKrMFx/m/1kOZFmlZ2SEOc="
|
||||
)
|
||||
(manjaroPatch
|
||||
"2002-Bluetooth-btrtl-add-support-for-the-RTL8723CS.patch"
|
||||
"sha256-dDdvOphTcP/Aog93HyH+L9m55laTgtjndPSE4/rnzUA="
|
||||
)
|
||||
(manjaroPatch
|
||||
"2004-arm64-dts-allwinner-enable-bluetooth-pinetab-pinepho.patch"
|
||||
"sha256-o43P3WzXyHK1PF+Kdter4asuyGAEKO6wf5ixcco2kCQ="
|
||||
)
|
||||
# XXX: this one has a Makefile, which hardcodes /sbin/depmod:
|
||||
# - drivers/staging/rtl8723cs/Makefile
|
||||
# - not sure if this is problematic?
|
||||
(manjaroPatch
|
||||
"2005-staging-add-rtl8723cs-driver.patch"
|
||||
"sha256-6ywm3dQQ5JYl60CLKarxlSUukwi4QzqctCj3tVgzFbo="
|
||||
)
|
||||
];
|
||||
if (${dmesg} --kernel --level err --color=never --notime | ${grep} -q 'sun4i-drm display-engine: failed to bind 1ee0000.hdmi')
|
||||
then
|
||||
echo "reprobing sun8i_drm_hdmi"
|
||||
# if a command here fails it errors the whole service, so prefer to log instead
|
||||
${modprobe} -r sun8i_drm_hdmi || echo "failed to unload sun8i_drm_hdmi"
|
||||
${modprobe} sun8i_drm_hdmi || echo "failed to load sub8i_drm_hdmi"
|
||||
fi
|
||||
'';
|
||||
in
|
||||
{
|
||||
# use Megi's kernel:
|
||||
# even with the Manjaro patches, stock 5.18 has a few issues on Pinephone:
|
||||
# - no battery charging
|
||||
# - phone rotation sensor is off by 90 degrees
|
||||
# - ambient light sensor causes screen brightness to be shakey
|
||||
# - phosh greeter may not appear after wake from sleep
|
||||
boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux-megous;
|
||||
# boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux-manjaro;
|
||||
# boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux_latest;
|
||||
|
||||
# alternatively, use nixos' kernel and add the stuff we want:
|
||||
# # cross-compilation optimization:
|
||||
# boot.kernelPackages =
|
||||
# let p = (import nixpkgs { localSystem = "x86_64-linux"; });
|
||||
# in p.pkgsCross.aarch64-multiplatform.linuxPackages_5_18;
|
||||
# # non-cross:
|
||||
# # boot.kernelPackages = pkgs.linuxPackages_5_18;
|
||||
|
||||
# alternatively, apply patches directly to stock nixos kernel:
|
||||
# boot.kernelPatches = manjaroPatches ++ [
|
||||
# (patchDefconfig kernelConfig)
|
||||
# ];
|
||||
|
||||
# configure nixos to build a compressed kernel image, since it doesn't usually do that for aarch64 target.
|
||||
# without this i run out of /boot space in < 10 generations
|
||||
nixpkgs.hostPlatform.linux-kernel = {
|
||||
# defaults:
|
||||
name = "aarch64-multiplatform";
|
||||
@@ -80,4 +65,7 @@ in
|
||||
target = "Image.gz"; # <-- compress the kernel image
|
||||
# target = "zImage"; # <-- confuses other parts of nixos :-(
|
||||
};
|
||||
|
||||
services.xserver.displayManager.job.preStart = ensureHWReady;
|
||||
systemd.services.greetd.preStart = ensureHWReady;
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 110 KiB |
1608
hosts/by-name/moby/nixos-bg-02.svg
Normal file
1608
hosts/by-name/moby/nixos-bg-02.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 118 KiB |
@@ -4,11 +4,17 @@
|
||||
#
|
||||
# NixOS backgrounds:
|
||||
# - <https://github.com/NixOS/nixos-artwork>
|
||||
# - <https://github.com/NixOS/nixos-artwork/issues/50> (colorful; unmerged)
|
||||
# - <https://github.com/NixOS/nixos-artwork/pull/60/files> (desktop-oriented; clean; unmerged)
|
||||
# - <https://itsfoss.com/content/images/2023/04/nixos-tutorials.png>
|
||||
|
||||
{ pkgs, sane-lib, ... }:
|
||||
{ lib, pkgs, sane-lib, ... }:
|
||||
let
|
||||
bg-01 = ./nixos-bg-01.png;
|
||||
# TODO: generate this from the .svg
|
||||
# bg = ./nixos-bg-02.png;
|
||||
bg = pkgs.runCommand "nixos-bg.png" { nativeBuildInputs = [ pkgs.inkscape ]; } ''
|
||||
inkscape ${./nixos-bg-02.svg} -o $out
|
||||
'';
|
||||
in
|
||||
{
|
||||
sane.programs.firefox.config = {
|
||||
@@ -23,6 +29,7 @@ in
|
||||
};
|
||||
|
||||
sane.gui.sxmo = {
|
||||
nogesture = true;
|
||||
settings = {
|
||||
### hardware: touch screen
|
||||
SXMO_LISGD_INPUT_DEVICE = "/dev/input/by-path/platform-1c2ac00.i2c-event";
|
||||
@@ -30,6 +37,90 @@ in
|
||||
|
||||
|
||||
### preferences
|
||||
# notable bemenu options:
|
||||
# - see `bemenu --help` for all
|
||||
# -P, --prefix text to show before highlighted item.
|
||||
# --scrollbar display scrollbar. (none (default), always, autohide)
|
||||
# -H, --line-height defines the height to make each menu line (0 = default height). (wx)
|
||||
# -M, --margin defines the empty space on either side of the menu. (wx)
|
||||
# -W, --width-factor defines the relative width factor of the menu (from 0 to 1). (wx)
|
||||
# -B, --border defines the width of the border in pixels around the menu. (wx)
|
||||
# -R --border-radius defines the radius of the border around the menu (0 = no curved borders).
|
||||
# --ch defines the height of the cursor (0 = scales with line height). (wx)
|
||||
# --cw defines the width of the cursor. (wx)
|
||||
# --hp defines the horizontal padding for the entries in single line mode. (wx)
|
||||
# --fn defines the font to be used ('name [size]'). (wx)
|
||||
# --tb defines the title background color. (wx)
|
||||
# --tf defines the title foreground color. (wx)
|
||||
# --fb defines the filter background color. (wx)
|
||||
# --ff defines the filter foreground color. (wx)
|
||||
# --nb defines the normal background color. (wx)
|
||||
# --nf defines the normal foreground color. (wx)
|
||||
# --hb defines the highlighted background color. (wx)
|
||||
# --hf defines the highlighted foreground color. (wx)
|
||||
# --fbb defines the feedback background color. (wx)
|
||||
# --fbf defines the feedback foreground color. (wx)
|
||||
# --sb defines the selected background color. (wx)
|
||||
# --sf defines the selected foreground color. (wx)
|
||||
# --ab defines the alternating background color. (wx)
|
||||
# --af defines the alternating foreground color. (wx)
|
||||
# --scb defines the scrollbar background color. (wx)
|
||||
# --scf defines the scrollbar foreground color. (wx)
|
||||
# --bdr defines the border color. (wx)
|
||||
#
|
||||
# colors are specified as `#RRGGBB`
|
||||
# defaults:
|
||||
# --ab "#222222"
|
||||
# --af "#bbbbbb"
|
||||
# --bdr "#005577"
|
||||
# --border 3
|
||||
# --cb "#222222"
|
||||
# --center
|
||||
# --cf "#bbbbbb"
|
||||
# --fb "#222222"
|
||||
# --fbb "#eeeeee"
|
||||
# --fbf "#222222"
|
||||
# --ff "#bbbbbb"
|
||||
# --fixed-height
|
||||
# --fn 'Sxmo 14'
|
||||
# --hb "#005577"
|
||||
# --hf "#eeeeee"
|
||||
# --line-height 20
|
||||
# --list 16
|
||||
# --margin 40
|
||||
# --nb "#222222"
|
||||
# --nf "#bbbbbb"
|
||||
# --no-overlap
|
||||
# --no-spacing
|
||||
# --sb "#323232"
|
||||
# --scb "#005577"
|
||||
# --scf "#eeeeee"
|
||||
# --scrollbar autohide
|
||||
# --tb "#005577"
|
||||
# --tf "#eeeeee"
|
||||
# --wrap
|
||||
BEMENU_OPTS = let
|
||||
bg = "#1d1721"; # slight purple
|
||||
fg0 = "#d8d8d8"; # inactive text (light grey)
|
||||
fg1 = "#ffffff"; # active text (white)
|
||||
accent0 = "#1f5e54"; # darker but saturated teal
|
||||
accent1 = "#418379"; # teal (matches nixos-bg)
|
||||
accent2 = "#5b938a"; # brighter but muted teal
|
||||
in lib.concatStringsSep " " [
|
||||
"--wrap --scrollbar autohide --fixed-height"
|
||||
"--center --margin 45"
|
||||
"--no-spacing"
|
||||
# XXX: font size doesn't seem to take effect (would prefer larger)
|
||||
"--fn 'Sxmo 14' --line-height 22 --border 3"
|
||||
"--bdr '${accent0}'" # border
|
||||
"--scf '${accent2}' --scb '${accent0}'" # scrollbar
|
||||
"--tb '${accent0}' --tf '${fg0}'" # title
|
||||
"--fb '${accent0}' --ff '${fg1}'" # filter (i.e. text that's been entered)
|
||||
"--hb '${accent1}' --hf '${fg1}'" # selected item
|
||||
"--nb '${bg}' --nf '${fg0}'" # normal lines (even)
|
||||
"--ab '${bg}' --af '${fg0}'" # alternated lines (odd)
|
||||
"--cf '${accent0}' --cb '${accent0}'" # cursor (not very useful)
|
||||
];
|
||||
DEFAULT_COUNTRY = "US";
|
||||
|
||||
# BEMENU lines (wayland DMENU):
|
||||
@@ -43,7 +134,7 @@ in
|
||||
# - close is 16th entry
|
||||
SXMO_BEMENU_LANDSCAPE_LINES = "11"; # default 8
|
||||
SXMO_BEMENU_PORTRAIT_LINES = "16"; # default 16
|
||||
SXMO_BG_IMG = "${bg-01}";
|
||||
SXMO_BG_IMG = "${bg}";
|
||||
SXMO_LOCK_IDLE_TIME = "15"; # how long between screenoff -> lock -> back to screenoff (default: 8)
|
||||
# gravity: how far to tilt the device before the screen rotates
|
||||
# for a given setting, normal <-> invert requires more movement then left <-> right
|
||||
@@ -76,11 +167,8 @@ in
|
||||
WVKBD_LANDSCAPE_LAYERS = "landscape,special,emoji";
|
||||
WVKBD_LAYERS = "full,special,emoji";
|
||||
};
|
||||
package = pkgs.sxmo-utils.overrideAttrs (base: {
|
||||
package = pkgs.sxmo-utils-latest.overrideAttrs (base: {
|
||||
postPatch = (base.postPatch or "") + ''
|
||||
# don't enable gestures at launch
|
||||
# sed -i '/superctl start sxmo_hook_lisgd/d' ./configs/default_hooks/sxmo_hook_start.sh
|
||||
|
||||
cat <<EOF >> ./configs/default_hooks/sxmo_hook_start.sh
|
||||
# rotate UI based on physical display angle by default
|
||||
sxmo_daemons.sh start autorotate sxmo_autorotate.sh
|
||||
|
@@ -18,6 +18,10 @@
|
||||
sane.roles.build-machine.enable = true;
|
||||
sane.roles.build-machine.emulation = false;
|
||||
sane.zsh.showDeadlines = false; # ~/knowledge doesn't always exist
|
||||
sane.programs.consoleUtils.suggestedPrograms = [
|
||||
"desktopConsoleUtils"
|
||||
"sane-scripts.stop-all-servo"
|
||||
];
|
||||
sane.services.dyn-dns.enable = true;
|
||||
sane.services.wg-home.enable = true;
|
||||
sane.services.wg-home.enableWan = true;
|
||||
|
@@ -2,6 +2,9 @@
|
||||
|
||||
{
|
||||
sane.persist.root-on-tmpfs = true;
|
||||
# increase /tmp space (defaults to 50% of RAM) for building large nix things.
|
||||
# even the stock `nixpkgs.linux` consumes > 16 GB of tmp
|
||||
fileSystems."/tmp".options = [ "size=32G" ];
|
||||
|
||||
fileSystems."/nix" = {
|
||||
device = "/dev/disk/by-uuid/cc81cca0-3cc7-4d82-a00c-6243af3e7776";
|
||||
|
@@ -7,7 +7,7 @@
|
||||
./email
|
||||
./ejabberd.nix
|
||||
./freshrss.nix
|
||||
./ftp
|
||||
./export
|
||||
./gitea.nix
|
||||
./goaccess.nix
|
||||
./ipfs.nix
|
||||
@@ -18,7 +18,6 @@
|
||||
./lemmy.nix
|
||||
./matrix
|
||||
./navidrome.nix
|
||||
./nfs.nix
|
||||
./nixserve.nix
|
||||
./nginx.nix
|
||||
./pict-rs.nix
|
||||
|
@@ -17,73 +17,86 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
# XXX: avatar support works in MUCs but not DMs
|
||||
# lib.mkIf false
|
||||
let
|
||||
# TODO: this range could be larger, but right now that's costly because each element is its own UPnP forward
|
||||
# TURN port range (inclusive)
|
||||
turnPortLow = 49152;
|
||||
turnPortHigh = 49167;
|
||||
turnPortRange = lib.range turnPortLow turnPortHigh;
|
||||
in
|
||||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "ejabberd"; group = "ejabberd"; path = "/var/lib/ejabberd"; }
|
||||
];
|
||||
sane.ports.ports."3478" = {
|
||||
sane.ports.ports = lib.mkMerge ([
|
||||
{
|
||||
"3478" = {
|
||||
protocol = [ "tcp" "udp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-stun-turn";
|
||||
};
|
||||
sane.ports.ports."5222" = {
|
||||
"5222" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-client-to-server";
|
||||
};
|
||||
sane.ports.ports."5223" = {
|
||||
"5223" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpps-client-to-server"; # XMPP over TLS
|
||||
};
|
||||
sane.ports.ports."5269" = {
|
||||
"5269" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-server-to-server";
|
||||
};
|
||||
sane.ports.ports."5270" = {
|
||||
"5270" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpps-server-to-server"; # XMPP over TLS
|
||||
};
|
||||
sane.ports.ports."5280" = {
|
||||
"5280" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-bosh";
|
||||
};
|
||||
sane.ports.ports."5281" = {
|
||||
"5281" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-bosh-https";
|
||||
};
|
||||
sane.ports.ports."5349" = {
|
||||
"5349" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-stun-turn-over-tls";
|
||||
};
|
||||
sane.ports.ports."5443" = {
|
||||
"5443" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-web-services"; # file uploads, websockets, admin
|
||||
};
|
||||
|
||||
# TODO: forward these TURN ports!
|
||||
networking.firewall.allowedTCPPortRanges = [{
|
||||
from = 49152; # TURN
|
||||
to = 49408;
|
||||
}];
|
||||
networking.firewall.allowedUDPPortRanges = [{
|
||||
from = 49152; # TURN
|
||||
to = 49408;
|
||||
}];
|
||||
}
|
||||
] ++ (builtins.map
|
||||
(port: {
|
||||
"${builtins.toString port}" = let
|
||||
count = port - turnPortLow + 1;
|
||||
numPorts = turnPortHigh - turnPortLow + 1;
|
||||
in {
|
||||
protocol = [ "tcp" "udp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-turn-${builtins.toString count}-of-${builtins.toString numPorts}";
|
||||
};
|
||||
})
|
||||
turnPortRange
|
||||
));
|
||||
|
||||
# provide access to certs
|
||||
# TODO: this should just be `acme`. then we also add nginx to the `acme` group.
|
||||
@@ -272,8 +285,8 @@
|
||||
module: ejabberd_stun
|
||||
transport: tcp
|
||||
use_turn: true
|
||||
turn_min_port: 49152
|
||||
turn_max_port: 65535
|
||||
turn_min_port: ${builtins.toString turnPortLow}
|
||||
turn_max_port: ${builtins.toString turnPortHigh}
|
||||
turn_ipv4_address: %ANATIVE%
|
||||
-
|
||||
# STUN+TURN UDP
|
||||
@@ -281,8 +294,8 @@
|
||||
module: ejabberd_stun
|
||||
transport: udp
|
||||
use_turn: true
|
||||
turn_min_port: 49152
|
||||
turn_max_port: 65535
|
||||
turn_min_port: ${builtins.toString turnPortLow}
|
||||
turn_max_port: ${builtins.toString turnPortHigh}
|
||||
turn_ipv4_address: %ANATIVE%
|
||||
-
|
||||
# STUN+TURN TLS over TCP
|
||||
@@ -292,8 +305,8 @@
|
||||
tls: true
|
||||
certfile: /var/lib/acme/uninsane.org/full.pem
|
||||
use_turn: true
|
||||
turn_min_port: 49152
|
||||
turn_max_port: 65535
|
||||
turn_min_port: ${builtins.toString turnPortLow}
|
||||
turn_max_port: ${builtins.toString turnPortHigh}
|
||||
turn_ipv4_address: %ANATIVE%
|
||||
|
||||
# TODO: enable mod_fail2ban
|
||||
|
42
hosts/by-name/servo/services/export/default.nix
Normal file
42
hosts/by-name/servo/services/export/default.nix
Normal file
@@ -0,0 +1,42 @@
|
||||
{ config, ... }:
|
||||
{
|
||||
imports = [
|
||||
./nfs.nix
|
||||
./sftpgo.nix
|
||||
];
|
||||
|
||||
|
||||
fileSystems."/var/export/media" = {
|
||||
# everything in here could be considered publicly readable (based on the viewer's legal jurisdiction)
|
||||
device = "/var/lib/uninsane/media";
|
||||
options = [ "rbind" ];
|
||||
};
|
||||
fileSystems."/var/export/playground" = {
|
||||
device = config.fileSystems."/mnt/persist/ext".device;
|
||||
fsType = "btrfs";
|
||||
options = [
|
||||
"subvol=export-playground"
|
||||
"compress=zstd"
|
||||
"defaults"
|
||||
];
|
||||
};
|
||||
|
||||
sane.fs."/var/export/README.md" = {
|
||||
wantedBy = [ "nfs.service" "sftpgo.service" ];
|
||||
file.text = ''
|
||||
- media/ read-only: Videos, Music, Books, etc
|
||||
- playground/ read-write: use it to share files with other users of this server
|
||||
'';
|
||||
};
|
||||
|
||||
# sane.fs."/var/lib/sftpgo/export/playground/README.md" = {
|
||||
# wantedBy = [ "nfs.service" "sftpgo.service" ];
|
||||
# file.text = ''
|
||||
# this directory is intentionally read+write by anyone.
|
||||
# there are no rules, except a server-level quota:
|
||||
# - share files
|
||||
# - write poetry
|
||||
# - be a friendly troll
|
||||
# '';
|
||||
# };
|
||||
}
|
@@ -56,12 +56,6 @@
|
||||
#
|
||||
# 10.0.0.0/8 to export (readonly) both to LAN (unencrypted) and wg vpn (encrypted)
|
||||
services.nfs.server.exports = ''
|
||||
/var/nfs/export 10.78.79.0/22(ro,crossmnt,fsid=0,subtree_check) 10.0.10.0/24(rw,no_root_squash,crossmnt,fsid=0,subtree_check)
|
||||
/var/export 10.78.79.0/22(ro,crossmnt,fsid=0,subtree_check) 10.0.10.0/24(rw,no_root_squash,crossmnt,fsid=0,subtree_check)
|
||||
'';
|
||||
|
||||
fileSystems."/var/nfs/export/media" = {
|
||||
# everything in here could be considered publicly readable (based on the viewer's legal jurisdiction)
|
||||
device = "/var/lib/uninsane/media";
|
||||
options = [ "rbind" ];
|
||||
};
|
||||
}
|
193
hosts/by-name/servo/services/export/sftpgo.nix
Normal file
193
hosts/by-name/servo/services/export/sftpgo.nix
Normal file
@@ -0,0 +1,193 @@
|
||||
# docs:
|
||||
# - <https://github.com/drakkan/sftpgo>
|
||||
# - config options: <https://github.com/drakkan/sftpgo/blob/main/docs/full-configuration.md>
|
||||
# - config defaults: <https://github.com/drakkan/sftpgo/blob/main/sftpgo.json>
|
||||
# - nixos options: <repo:nixos/nixpkgs:nixos/modules/services/web-apps/sftpgo.nix>
|
||||
# - nixos example: <repo:nixos/nixpkgs:nixos/tests/sftpgo.nix>
|
||||
#
|
||||
# sftpgo is a FTP server that also supports WebDAV, SFTP, and web clients.
|
||||
#
|
||||
# TODO: change umask so sftpgo-created files default to 644.
|
||||
# - it does indeed appear that the 600 is not something sftpgo is explicitly doing.
|
||||
#
|
||||
# TODO: enforce a "quota" by placing /playground on a btrfs subvolume
|
||||
# - sane.persist API could expose a `subvolume` option to make this feel natural
|
||||
|
||||
|
||||
{ config, lib, pkgs, sane-lib, ... }:
|
||||
let
|
||||
# user permissions:
|
||||
# - see <repo:drakkan/sftpgo:internal/dataprovider/user.go>
|
||||
# - "*" = grant all permissions
|
||||
# - read-only perms:
|
||||
# - "list" = list files and directories
|
||||
# - "download"
|
||||
# - rw perms:
|
||||
# - "upload"
|
||||
# - "overwrite" = allow uploads to replace existing files
|
||||
# - "delete" = delete files and directories
|
||||
# - "delete_files"
|
||||
# - "delete_dirs"
|
||||
# - "rename" = rename files and directories
|
||||
# - "rename_files"
|
||||
# - "rename_dirs"
|
||||
# - "create_dirs"
|
||||
# - "create_symlinks"
|
||||
# - "chmod"
|
||||
# - "chown"
|
||||
# - "chtimes" = change atime/mtime (access and modification times)
|
||||
#
|
||||
# home_dir:
|
||||
# - it seems (empirically) that a user can't cd above their home directory.
|
||||
# though i don't have a reference for that in the docs.
|
||||
authResponseSuccess = {
|
||||
status = 1;
|
||||
username = "anonymous";
|
||||
expiration_date = 0;
|
||||
home_dir = "/var/export";
|
||||
# uid/gid 0 means to inherit sftpgo uid.
|
||||
# - i.e. users can't read files which Linux user `sftpgo` can't read
|
||||
# - uploaded files belong to Linux user `sftpgo`
|
||||
# other uid/gid values aren't possible for localfs backend, unless i let sftpgo use `sudo`.
|
||||
uid = 0;
|
||||
gid = 0;
|
||||
# uid = 65534;
|
||||
# gid = 65534;
|
||||
max_sessions = 0;
|
||||
# quota_*: 0 means to not use SFTP's quota system
|
||||
quota_size = 0;
|
||||
quota_files = 0;
|
||||
permissions = {
|
||||
"/" = [ "list" "download" ];
|
||||
"/playground" = [
|
||||
# read-only:
|
||||
"list"
|
||||
"download"
|
||||
# write:
|
||||
"upload"
|
||||
"overwrite"
|
||||
"delete"
|
||||
"rename"
|
||||
"create_dirs"
|
||||
"create_symlinks"
|
||||
# intentionally omitted:
|
||||
# "chmod"
|
||||
# "chown"
|
||||
# "chtimes"
|
||||
];
|
||||
};
|
||||
upload_bandwidth = 0;
|
||||
download_bandwidth = 0;
|
||||
filters = {
|
||||
allowed_ip = [];
|
||||
denied_ip = [];
|
||||
};
|
||||
public_keys = [];
|
||||
# other fields:
|
||||
# ? groups
|
||||
# ? virtual_folders
|
||||
};
|
||||
authResponseFail = {
|
||||
username = "";
|
||||
};
|
||||
authSuccessJson = pkgs.writeText "sftp-auth-success.json" (builtins.toJSON authResponseSuccess);
|
||||
authFailJson = pkgs.writeText "sftp-auth-fail.json" (builtins.toJSON authResponseFail);
|
||||
unwrappedAuthProgram = pkgs.static-nix-shell.mkBash {
|
||||
pname = "sftpgo_external_auth_hook";
|
||||
src = ./.;
|
||||
pkgs = [ "coreutils" ];
|
||||
};
|
||||
authProgram = pkgs.writeShellScript "sftpgo-auth-hook" ''
|
||||
${unwrappedAuthProgram}/bin/sftpgo_external_auth_hook ${authFailJson} ${authSuccessJson}
|
||||
'';
|
||||
in
|
||||
{
|
||||
# Client initiates a FTP "control connection" on port 21.
|
||||
# - this handles the client -> server commands, and the server -> client status, but not the actual data
|
||||
# - file data, directory listings, etc need to be transferred on an ephemeral "data port".
|
||||
# - 50000-50100 is a common port range for this.
|
||||
sane.ports.ports = {
|
||||
"21" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "colin-FTP server";
|
||||
};
|
||||
} // (sane-lib.mapToAttrs
|
||||
(port: {
|
||||
name = builtins.toString port;
|
||||
value = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "colin-FTP server data port range";
|
||||
};
|
||||
})
|
||||
(lib.range 50000 50100)
|
||||
);
|
||||
|
||||
services.sftpgo = {
|
||||
enable = true;
|
||||
settings = {
|
||||
ftpd = {
|
||||
bindings = [
|
||||
{
|
||||
# binding this means any wireguard client can connect
|
||||
address = "10.0.10.5";
|
||||
port = 21;
|
||||
debug = true;
|
||||
}
|
||||
{
|
||||
# binding this means any LAN client can connect
|
||||
address = "10.78.79.51";
|
||||
port = 21;
|
||||
debug = true;
|
||||
}
|
||||
];
|
||||
|
||||
# active mode is susceptible to "bounce attacks", without much benefit over passive mode
|
||||
disable_active_mode = true;
|
||||
hash_support = true;
|
||||
passive_port_range = {
|
||||
start = 50000;
|
||||
end = 50100;
|
||||
};
|
||||
|
||||
banner = ''
|
||||
Welcome, friends, to Colin's read-only FTP server! Also available via NFS on the same host.
|
||||
Username: "anonymous"
|
||||
Password: "anonymous"
|
||||
CONFIGURE YOUR CLIENT FOR "PASSIVE" mode, e.g. `ftp --passive uninsane.org`
|
||||
Please let me know if anything's broken or not as it should be. Otherwise, browse and DL freely :)
|
||||
'';
|
||||
|
||||
};
|
||||
data_provider = {
|
||||
driver = "memory";
|
||||
external_auth_hook = "${authProgram}";
|
||||
# track_quota:
|
||||
# - 0: disable quota tracking
|
||||
# - 1: quota is updated on every upload/delete, even if user has no quota restriction
|
||||
# - 2: quota is updated on every upload/delete, but only if user/folder has a quota restriction (default, i think)
|
||||
# track_quota = 2;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# fileSystems."/var/lib/sftpgo/export/media" = {
|
||||
# # everything in here could be considered publicly readable (based on the viewer's legal jurisdiction)
|
||||
# device = "/var/lib/uninsane/media";
|
||||
# options = [ "rbind" ];
|
||||
# };
|
||||
# sane.persist.sys.plaintext = [
|
||||
# { user = "sftpgo"; group = "sftpgo"; path = "/var/lib/sftpgo/export/playground"; }
|
||||
# ];
|
||||
# sane.fs."/var/lib/sftpgo/export/playground/README.md" = {
|
||||
# wantedBy = [ "sftpgo.service" ];
|
||||
# file.text = ''
|
||||
# this directory is intentionally read+write by anyone.
|
||||
# there are no rules, except a server-level quota:
|
||||
# - share files
|
||||
# - write poetry
|
||||
# - be a friendly troll
|
||||
# '';
|
||||
# };
|
||||
}
|
23
hosts/by-name/servo/services/export/sftpgo_external_auth_hook
Executable file
23
hosts/by-name/servo/services/export/sftpgo_external_auth_hook
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p coreutils
|
||||
# vim: set filetype=bash :
|
||||
#
|
||||
# available environment variables:
|
||||
# - SFTPGO_AUTHD_USERNAME
|
||||
# - SFTPGO_AUTHD_USER
|
||||
# - SFTPGO_AUTHD_IP
|
||||
# - SFTPGO_AUTHD_PROTOCOL = { "DAV", "FTP", "HTTP", "SSH" }
|
||||
# - SFTPGO_AUTHD_PASSWORD
|
||||
# - SFTPGO_AUTHD_PUBLIC_KEY
|
||||
# - SFTPGO_AUTHD_KEYBOARD_INTERACTIVE
|
||||
# - SFTPGO_AUTHD_TLS_CERT
|
||||
#
|
||||
#
|
||||
# call with <script_name> /path/to/fail/response.json /path/to/success/response.json
|
||||
|
||||
|
||||
if [ "$SFTPGO_AUTHD_USERNAME" = "anonymous" ]; then
|
||||
cat "$2"
|
||||
else
|
||||
cat "$1"
|
||||
fi
|
@@ -1,70 +0,0 @@
|
||||
# docs:
|
||||
# - <https://github.com/drakkan/sftpgo>
|
||||
# - config options: <https://github.com/drakkan/sftpgo/blob/main/docs/full-configuration.md>
|
||||
# - config defaults: <https://github.com/drakkan/sftpgo/blob/main/sftpgo.json>
|
||||
# - nixos options: <repo:nixos/nixpkgs:nixos/modules/services/web-apps/sftpgo.nix>
|
||||
#
|
||||
# sftpgo is a FTP server that also supports WebDAV, SFTP, and web clients.
|
||||
|
||||
|
||||
{ lib, pkgs, sane-lib, ... }:
|
||||
let
|
||||
authProgram = pkgs.static-nix-shell.mkBash {
|
||||
pname = "sftpgo_external_auth_hook";
|
||||
src = ./.;
|
||||
};
|
||||
in
|
||||
{
|
||||
# Client initiates a FTP "control connection" on port 21.
|
||||
# - this handles the client -> server commands, and the server -> client status, but not the actual data
|
||||
# - file data, directory listings, etc need to be transferred on an ephemeral "data port".
|
||||
# - 50000-50100 is a common port range for this.
|
||||
sane.ports.ports = {
|
||||
"21" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "colin-FTP server";
|
||||
};
|
||||
} // (sane-lib.mapToAttrs
|
||||
(port: {
|
||||
name = builtins.toString port;
|
||||
value = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "colin-FTP server data port range";
|
||||
};
|
||||
})
|
||||
(lib.range 50000 50100)
|
||||
);
|
||||
|
||||
services.sftpgo = {
|
||||
enable = true;
|
||||
settings = {
|
||||
ftpd = {
|
||||
bindings = [{
|
||||
address = "10.0.10.5";
|
||||
port = 21;
|
||||
debug = true;
|
||||
}];
|
||||
|
||||
# active mode is susceptible to "bounce attacks", without much benefit over passive mode
|
||||
disable_active_mode = true;
|
||||
hash_support = true;
|
||||
passive_port_range = {
|
||||
start = 50000;
|
||||
end = 50100;
|
||||
};
|
||||
|
||||
banner = ''
|
||||
Welcome, friends, to Colin's read-only FTP server! Also available via NFS on the same host.
|
||||
Please let me know if anything's broken or not as it should be. Otherwise, browse and DL freely :)
|
||||
'';
|
||||
|
||||
};
|
||||
data_provider = {
|
||||
driver = "memory";
|
||||
external_auth_hook = "${authProgram}/bin/sftpgo_external_auth_hook";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@@ -1,55 +0,0 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash
|
||||
# vim: set filetype=bash :
|
||||
#
|
||||
# available environment variables:
|
||||
# - SFTPGO_AUTHD_USERNAME
|
||||
# - SFTPGO_AUTHD_USER
|
||||
# - SFTPGO_AUTHD_IP
|
||||
# - SFTPGO_AUTHD_PROTOCOL = { "DAV", "FTP", "HTTP", "SSH" }
|
||||
# - SFTPGO_AUTHD_PASSWORD
|
||||
# - SFTPGO_AUTHD_PUBLIC_KEY
|
||||
# - SFTPGO_AUTHD_KEYBOARD_INTERACTIVE
|
||||
# - SFTPGO_AUTHD_TLS_CERT
|
||||
#
|
||||
# user permissions:
|
||||
# - see <repo:drakkan/sftpgo:internal/dataprovider/user.go>
|
||||
# - "*" = grant all permissions
|
||||
# - read-only perms:
|
||||
# - "list" = list files and directories
|
||||
# - "download"
|
||||
# - rw perms:
|
||||
# - "upload"
|
||||
# - "overwrite" = allow uploads to replace existing files
|
||||
# - "delete" = delete files and directories
|
||||
# - "delete_files"
|
||||
# - "delete_dirs"
|
||||
# - "rename" = rename files and directories
|
||||
# - "rename_files"
|
||||
# - "rename_dirs"
|
||||
# - "create_dirs"
|
||||
# - "create_symlinks"
|
||||
# - "chmod"
|
||||
# - "chown"
|
||||
# - "chtimes" = change atime/mtime (access and modification times)
|
||||
#
|
||||
# home_dir:
|
||||
# - it seems (empirically) that a user can't cd above their home directory.
|
||||
# though i don't have a reference for that in the docs.
|
||||
# TODO: don't reuse /var/nfs/export here. formalize this some other way.
|
||||
|
||||
|
||||
if [ "$SFTPGO_AUTHD_USERNAME" = "anonymous" ]; then
|
||||
echo '{'
|
||||
echo ' "status":1,'
|
||||
echo ' "username":"anonymous","expiration_date":0,'
|
||||
echo ' "home_dir":"/var/nfs/export","uid":65534,"gid":65534,"max_sessions":0,"quota_size":0,"quota_files":100000,'
|
||||
echo ' "permissions":{'
|
||||
echo ' "/":["list", "download"]'
|
||||
echo ' },'
|
||||
echo ' "upload_bandwidth":0,"download_bandwidth":0,'
|
||||
echo ' "filters":{"allowed_ip":[],"denied_ip":[]},"public_keys":[]'
|
||||
echo '}'
|
||||
else
|
||||
echo '{"username":""}'
|
||||
fi
|
@@ -3,13 +3,23 @@
|
||||
# - <repo:LemmyNet/lemmy:docker/nginx.conf>
|
||||
# - <repo:LemmyNet/lemmy-ansible:templates/nginx.conf>
|
||||
|
||||
{ config, lib, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
inherit (builtins) toString;
|
||||
inherit (lib) mkForce;
|
||||
uiPort = 1234; # default ui port is 1234
|
||||
backendPort = 8536; # default backend port is 8536
|
||||
# - i guess the "backend" port is used for federation?
|
||||
#^ i guess the "backend" port is used for federation?
|
||||
pict-rs = pkgs.pict-rs.overrideAttrs (upstream: {
|
||||
# as of v 0.4.2, all non-GIF video is forcibly transcoded.
|
||||
# that breaks lemmy, because of the request latency.
|
||||
# and it eats up hella CPU.
|
||||
# pict-rs is iffy around video altogether: mp4 seems the best supported.
|
||||
postPatch = (upstream.postPatch or "") + ''
|
||||
substituteInPlace src/validate.rs \
|
||||
--replace 'if transcode_options.needs_reencode() {' 'if false {'
|
||||
'';
|
||||
});
|
||||
in {
|
||||
services.lemmy = {
|
||||
enable = true;
|
||||
@@ -56,4 +66,20 @@ in {
|
||||
};
|
||||
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."lemmy" = "native";
|
||||
|
||||
#v DO NOT REMOVE: defaults to 0.3, instead of latest, so always need to explicitly set this.
|
||||
services.pict-rs.package = pict-rs;
|
||||
|
||||
# pict-rs configuration is applied in this order:
|
||||
# - via toml
|
||||
# - via env vars (overrides everything above)
|
||||
# - via CLI flags (overrides everything above)
|
||||
# some of the CLI flags have defaults, making it the only actual way to configure certain things even when docs claim otherwise.
|
||||
# CLI args: <https://git.asonix.dog/asonix/pict-rs#user-content-running>
|
||||
systemd.services.pict-rs.serviceConfig.ExecStart = lib.mkForce (lib.concatStringsSep " " [
|
||||
"${lib.getBin pict-rs}/bin/pict-rs run"
|
||||
"--media-max-frame-count" (builtins.toString (30*60*60))
|
||||
"--media-process-timeout 120"
|
||||
"--media-enable-full-video true" # allow audio
|
||||
]);
|
||||
}
|
||||
|
@@ -63,6 +63,7 @@ in
|
||||
database: "pleroma",
|
||||
hostname: "localhost",
|
||||
pool_size: 10,
|
||||
prepare: :named,
|
||||
parameters: [
|
||||
plan_cache_mode: "force_custom_plan"
|
||||
]
|
||||
|
@@ -1,12 +1,39 @@
|
||||
{ ... }:
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
GiB = n: MiB 1024*n;
|
||||
MiB = n: KiB 1024*n;
|
||||
KiB = n: 1024*n;
|
||||
in
|
||||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
# TODO: mode?
|
||||
{ user = "postgres"; group = "postgres"; path = "/var/lib/postgresql"; }
|
||||
];
|
||||
services.postgresql.enable = true;
|
||||
# services.postgresql.dataDir = "/opt/postgresql/13";
|
||||
|
||||
# HOW TO UPDATE:
|
||||
# postgres version updates are manual and require intervention.
|
||||
# - `sane-stop-all-servo`
|
||||
# - `systemctl start postgresql`
|
||||
# - as `sudo su postgres`:
|
||||
# - `cd /var/log/postgresql`
|
||||
# - `pg_dumpall > state.sql`
|
||||
# - `echo placeholder > <new_version>` # to prevent state from being created earlier than we want
|
||||
# - then, atomically:
|
||||
# - update the `services.postgresql.package` here
|
||||
# - `dataDir` is atomically updated to match package; don't touch
|
||||
# - `nixos-rebuild --flake . switch ; sane-stop-all-servo`
|
||||
# - `sudo rm -rf /var/lib/postgresql/<new_version>`
|
||||
# - `systemctl start postgresql`
|
||||
# - as `sudo su postgres`:
|
||||
# - `cd /var/lib/postgreql`
|
||||
# - `psql -f state.sql`
|
||||
# - restart dependent services (maybe test one at a time)
|
||||
|
||||
services.postgresql.package = pkgs.postgresql_15;
|
||||
|
||||
|
||||
# XXX colin: for a proper deploy, we'd want to include something for Pleroma here too.
|
||||
# services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" ''
|
||||
# CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD '<password goes here>';
|
||||
@@ -17,10 +44,33 @@
|
||||
# LC_CTYPE = "C";
|
||||
# '';
|
||||
|
||||
# TODO: perf tuning
|
||||
# perf tuning
|
||||
# - for recommended values see: <https://pgtune.leopard.in.ua/>
|
||||
# - for official docs (sparse), see: <https://www.postgresql.org/docs/11/config-setting.html#CONFIG-SETTING-CONFIGURATION-FILE>
|
||||
# services.postgresql.settings = { ... }
|
||||
services.postgresql.settings = {
|
||||
# DB Version: 15
|
||||
# OS Type: linux
|
||||
# DB Type: web
|
||||
# Total Memory (RAM): 32 GB
|
||||
# CPUs num: 12
|
||||
# Data Storage: ssd
|
||||
max_connections = 200;
|
||||
shared_buffers = "8GB";
|
||||
effective_cache_size = "24GB";
|
||||
maintenance_work_mem = "2GB";
|
||||
checkpoint_completion_target = 0.9;
|
||||
wal_buffers = "16MB";
|
||||
default_statistics_target = 100;
|
||||
random_page_cost = 1.1;
|
||||
effective_io_concurrency = 200;
|
||||
work_mem = "10485kB";
|
||||
min_wal_size = "1GB";
|
||||
max_wal_size = "4GB";
|
||||
max_worker_processes = 12;
|
||||
max_parallel_workers_per_gather = 4;
|
||||
max_parallel_workers = 12;
|
||||
max_parallel_maintenance_workers = 4;
|
||||
};
|
||||
|
||||
# daily backups to /var/backup
|
||||
services.postgresqlBackup.enable = true;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
# where to find good stuff?
|
||||
# - podcasts w/ a community: <https://lemmyverse.net/communities?query=podcast>
|
||||
# - podcast rec thread: <https://lemmy.ml/post/1565858>
|
||||
#
|
||||
# candidates:
|
||||
@@ -67,7 +68,12 @@ let
|
||||
(fromDb "craphound.com" // pol)
|
||||
## Maggie Killjoy -- referenced by Cory Doctorow
|
||||
(fromDb "omny.fm/shows/cool-people-who-did-cool-stuff" // pol)
|
||||
## also Maggie Killjoy
|
||||
(fromDb "feeds.megaphone.fm/behindthebastards" // pol)
|
||||
## Jennifer Briney
|
||||
(fromDb "congressionaldish.libsyn.com" // pol)
|
||||
(fromDb "werenotwrong.fireside.fm" // pol)
|
||||
(fromDb "usefulidiots.substack.com" // pol)
|
||||
# (mkPod "https://podcasts.la.utexas.edu/this-is-democracy/feed/podcast/" // pol // weekly)
|
||||
## Civboot -- https://anchor.fm/civboot
|
||||
(fromDb "anchor.fm/s/34c7232c/podcast/rss" // tech)
|
||||
@@ -119,6 +125,16 @@ let
|
||||
## The Witch Trials of J.K. Rowling
|
||||
## - <https://www.thefp.com/witchtrials>
|
||||
(mkPod "https://feeds.megaphone.fm/RUNMED9919162779" // pol // infrequent)
|
||||
## Atlas Obscura
|
||||
(fromDb "feeds.simplecast.com/xKJ93w_w" // uncat)
|
||||
## Ezra Klein Show
|
||||
(fromDb "feeds.simplecast.com/82FI35Px" // pol)
|
||||
## Wireshark Podcast o_0
|
||||
(fromDb "sharkbytes.transistor.fm" // tech)
|
||||
## 3/4 German; 1/4 eps are English
|
||||
(fromDb "omegataupodcast.net" // tech)
|
||||
## Lateral with Tom Scott
|
||||
(mkPod "https://audioboom.com/channels/5097784.rss" // tech)
|
||||
];
|
||||
|
||||
texts = [
|
||||
@@ -220,6 +236,7 @@ let
|
||||
(fromDb "preposterousuniverse.com" // rat)
|
||||
(mkSubstack "eliqian" // rat // weekly)
|
||||
(mkText "https://acoup.blog/feed" // rat // weekly)
|
||||
(fromDb "mindingourway.com" // rat)
|
||||
|
||||
## mostly dating topics. not advice, or humor, but looking through a social lens
|
||||
(fromDb "putanumonit.com" // rat)
|
||||
|
@@ -1,9 +1,10 @@
|
||||
# docs
|
||||
# - x-systemd options: <https://www.freedesktop.org/software/systemd/man/systemd.mount.html>
|
||||
|
||||
{ pkgs, sane-lib, ... }:
|
||||
{ lib, pkgs, sane-lib, ... }:
|
||||
|
||||
let fsOpts = rec {
|
||||
let
|
||||
fsOpts = rec {
|
||||
common = [
|
||||
"_netdev"
|
||||
"noatime"
|
||||
@@ -55,7 +56,17 @@ let fsOpts = rec {
|
||||
"nofail" # don't fail remote-fs.target when this mount fails (not an option for sshfs else would be common)
|
||||
];
|
||||
};
|
||||
remoteHome = host: {
|
||||
fileSystems."/mnt/${host}-home" = {
|
||||
device = "colin@${host}:/home/colin";
|
||||
fsType = "fuse.sshfs";
|
||||
options = fsOpts.sshColin ++ fsOpts.noauto;
|
||||
noCheck = true;
|
||||
};
|
||||
sane.fs."/mnt/${host}-home" = sane-lib.fs.wantedDir;
|
||||
};
|
||||
in
|
||||
lib.mkMerge [
|
||||
{
|
||||
# some services which use private directories error if the parent (/var/lib/private) isn't 700.
|
||||
sane.fs."/var/lib/private".dir.acl.mode = "0700";
|
||||
@@ -108,21 +119,6 @@ in
|
||||
# };
|
||||
sane.fs."/mnt/servo-media" = sane-lib.fs.wantedSymlinkTo "/mnt/servo-nfs/media";
|
||||
|
||||
fileSystems."/mnt/desko-home" = {
|
||||
device = "colin@desko:/home/colin";
|
||||
fsType = "fuse.sshfs";
|
||||
options = fsOpts.sshColin ++ fsOpts.noauto;
|
||||
noCheck = true;
|
||||
};
|
||||
sane.fs."/mnt/desko-home" = sane-lib.fs.wantedDir;
|
||||
fileSystems."/mnt/desko-root" = {
|
||||
device = "colin@desko:/";
|
||||
fsType = "fuse.sshfs";
|
||||
options = fsOpts.sshRoot ++ fsOpts.noauto;
|
||||
noCheck = true;
|
||||
};
|
||||
sane.fs."/mnt/desko-root" = sane-lib.fs.wantedDir;
|
||||
|
||||
environment.pathsToLink = [
|
||||
# needed to achieve superuser access for user-mounted filesystems (see optionsRoot above)
|
||||
# we can only link whole directories here, even though we're only interested in pkgs.openssh
|
||||
@@ -134,3 +130,8 @@ in
|
||||
];
|
||||
}
|
||||
|
||||
(remoteHome "desko")
|
||||
(remoteHome "lappy")
|
||||
(remoteHome "moby")
|
||||
]
|
||||
|
||||
|
@@ -23,7 +23,6 @@
|
||||
|
||||
# non-free firmware
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
services.fwupd.enable = true;
|
||||
|
||||
# powertop will default to putting USB devices -- including HID -- to sleep after TWO SECONDS
|
||||
powerManagement.powertop.enable = false;
|
||||
|
24
hosts/common/programs/alacritty.nix
Normal file
24
hosts/common/programs/alacritty.nix
Normal file
@@ -0,0 +1,24 @@
|
||||
# alacritty terminal emulator
|
||||
# - config options: <https://github.com/alacritty/alacritty/blob/master/extra/man/alacritty.5.scd>
|
||||
# - `man 5 alacritty`
|
||||
# - defaults: <https://github.com/alacritty/alacritty/releases> -> alacritty.yml
|
||||
# - irc: #alacritty on libera.chat
|
||||
{ lib, ... }:
|
||||
{
|
||||
sane.programs.alacritty = {
|
||||
env.TERMINAL = lib.mkDefault "alacritty";
|
||||
# note: alacritty will switch to .toml config in 13.0 release
|
||||
# - run `alacritty migrate` to convert the yaml to toml
|
||||
fs.".config/alacritty/alacritty.yml".symlink.text = ''
|
||||
font:
|
||||
size: 14
|
||||
|
||||
key_bindings:
|
||||
- { key: N, mods: Control, action: CreateNewWindow }
|
||||
- { key: PageUp, mods: Control, action: ScrollPageUp }
|
||||
- { key: PageDown, mods: Control, action: ScrollPageDown }
|
||||
- { key: PageUp, mods: Control|Shift, action: ScrollPageUp }
|
||||
- { key: PageDown, mods: Control|Shift, action: ScrollPageDown }
|
||||
'';
|
||||
};
|
||||
}
|
@@ -1,11 +1,61 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
declPackageSet = pkgs: {
|
||||
package = null;
|
||||
suggestedPrograms = pkgs;
|
||||
};
|
||||
in
|
||||
{
|
||||
sane.programs = {
|
||||
# PACKAGE SETS
|
||||
sysadminUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = [
|
||||
"sane-scripts.backup" = declPackageSet [
|
||||
"sane-scripts.backup-ls"
|
||||
"sane-scripts.backup-restore"
|
||||
];
|
||||
"sane-scripts.bittorrent" = declPackageSet [
|
||||
"sane-scripts.bt-add"
|
||||
"sane-scripts.bt-rm"
|
||||
"sane-scripts.bt-search"
|
||||
"sane-scripts.bt-show"
|
||||
];
|
||||
"sane-scripts.dev" = declPackageSet [
|
||||
"sane-scripts.dev-cargo-loop"
|
||||
"sane-scripts.git-init"
|
||||
];
|
||||
"sane-scripts.cli" = declPackageSet [
|
||||
"sane-scripts.deadlines"
|
||||
"sane-scripts.find-dotfiles"
|
||||
"sane-scripts.ip-check"
|
||||
"sane-scripts.ip-reconnect"
|
||||
"sane-scripts.private-change-passwd"
|
||||
"sane-scripts.private-do"
|
||||
"sane-scripts.private-init"
|
||||
"sane-scripts.private-lock"
|
||||
"sane-scripts.private-unlock"
|
||||
"sane-scripts.rcp"
|
||||
"sane-scripts.reboot"
|
||||
"sane-scripts.reclaim-boot-space"
|
||||
"sane-scripts.reclaim-disk-space"
|
||||
"sane-scripts.secrets-dump"
|
||||
"sane-scripts.secrets-unlock"
|
||||
"sane-scripts.secrets-update-keys"
|
||||
"sane-scripts.shutdown"
|
||||
"sane-scripts.ssl-dump"
|
||||
"sane-scripts.sudo-redirect"
|
||||
"sane-scripts.sync-from-servo"
|
||||
"sane-scripts.vpn-down"
|
||||
"sane-scripts.vpn-up"
|
||||
"sane-scripts.which"
|
||||
"sane-scripts.wipe-browser"
|
||||
];
|
||||
"sane-scripts.sys-utils" = declPackageSet [
|
||||
"sane-scripts.ip-port-forward"
|
||||
"sane-scripts.sync-music"
|
||||
];
|
||||
|
||||
|
||||
sysadminUtils = declPackageSet [
|
||||
"btrfs-progs"
|
||||
"cacert.unbundled" # some services require unbundled /etc/ssl/certs
|
||||
"cryptsetup"
|
||||
@@ -14,6 +64,7 @@
|
||||
"fatresize"
|
||||
"fd"
|
||||
"file"
|
||||
# "fwupd"
|
||||
"gawk"
|
||||
"git"
|
||||
"gptfdisk"
|
||||
@@ -50,39 +101,33 @@
|
||||
"wget"
|
||||
"wirelesstools" # iwlist
|
||||
];
|
||||
};
|
||||
sysadminExtraUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = [
|
||||
sysadminExtraUtils = declPackageSet [
|
||||
"backblaze-b2"
|
||||
"duplicity"
|
||||
"sane-scripts.backup"
|
||||
"sqlite" # to debug sqlite3 databases
|
||||
];
|
||||
};
|
||||
|
||||
# TODO: split these into smaller groups.
|
||||
# - moby doesn't want a lot of these.
|
||||
# - categories like
|
||||
# - dev?
|
||||
# - debugging?
|
||||
consoleUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = [
|
||||
consoleUtils = declPackageSet [
|
||||
"alsaUtils" # for aplay, speaker-test
|
||||
# "cdrtools"
|
||||
"clinfo"
|
||||
"dmidecode"
|
||||
"dtrx" # `unar` alternative, "Do The Right eXtraction"
|
||||
"efivar"
|
||||
# "flashrom"
|
||||
"fwupd"
|
||||
"gh" # MS GitHub cli
|
||||
"git" # needed as a user package, for config.
|
||||
# "gnupg"
|
||||
# "gocryptfs"
|
||||
# "gopass"
|
||||
# "gopass-jsonapi"
|
||||
"helix" # text editor
|
||||
"kitty" # TODO: move to GUI, but `ssh servo` from kitty sets `TERM=xterm-kitty` in the remove and breaks things
|
||||
# "kitty" # XXX needs to be in consolueUtils because `ssh servo` from kitty sets `TERM=xterm-kitty` in the remote and breaks things
|
||||
"libsecret" # for managing user keyrings. TODO: what needs this? lift into the consumer
|
||||
"lm_sensors" # for sensors-detect. TODO: what needs this? lift into the consumer
|
||||
"lshw"
|
||||
@@ -90,8 +135,6 @@
|
||||
"neovim" # needed as a user package, for swap persistence
|
||||
# "nettools"
|
||||
# "networkmanager"
|
||||
"nix-index"
|
||||
"nixpkgs-review"
|
||||
# "nixos-generators"
|
||||
"nmon"
|
||||
# "node2nix"
|
||||
@@ -102,74 +145,65 @@
|
||||
# "python3Packages.eyeD3" # music tagging
|
||||
"ripgrep" # needed as a user package so that its user-level config file can be installed
|
||||
"rsync"
|
||||
"sane-scripts"
|
||||
"sequoia"
|
||||
"sane-scripts.bittorrent"
|
||||
"sane-scripts.cli"
|
||||
"snapper"
|
||||
"sops"
|
||||
"speedtest-cli"
|
||||
# "ssh-to-age"
|
||||
"sudo"
|
||||
# "tageditor" # music tagging
|
||||
"unar"
|
||||
# "unar"
|
||||
"wireguard-tools"
|
||||
"xdg-terminal-exec"
|
||||
"xdg-utils" # for xdg-open
|
||||
# "yarn"
|
||||
"zsh"
|
||||
];
|
||||
};
|
||||
|
||||
consoleMediaUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = [
|
||||
desktopConsoleUtils = declPackageSet [
|
||||
"gh" # MS GitHub cli
|
||||
"nix-index"
|
||||
"nixpkgs-review"
|
||||
"sane-scripts.dev"
|
||||
"sequoia"
|
||||
];
|
||||
|
||||
consoleMediaUtils = declPackageSet [
|
||||
"ffmpeg"
|
||||
"imagemagick"
|
||||
"sox"
|
||||
"yt-dlp"
|
||||
];
|
||||
};
|
||||
|
||||
tuiApps = {
|
||||
package = null;
|
||||
suggestedPrograms = [
|
||||
tuiApps = declPackageSet [
|
||||
"aerc" # email client
|
||||
"msmtp" # sendmail
|
||||
"offlineimap" # email mailox sync
|
||||
"offlineimap" # email mailbox sync
|
||||
"sfeed" # RSS fetcher
|
||||
"visidata" # TUI spreadsheet viewer/editor
|
||||
"w3m" # web browser
|
||||
];
|
||||
};
|
||||
|
||||
iphoneUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = [
|
||||
iphoneUtils = declPackageSet [
|
||||
"ifuse"
|
||||
"ipfs"
|
||||
"libimobiledevice"
|
||||
"sane-scripts.sync-from-iphone"
|
||||
];
|
||||
};
|
||||
|
||||
devPkgs = {
|
||||
package = null;
|
||||
suggestedPrograms = [
|
||||
devPkgs = declPackageSet [
|
||||
"clang"
|
||||
"nodejs"
|
||||
"tree-sitter"
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
# INDIVIDUAL PACKAGE DEFINITIONS
|
||||
|
||||
dino.persist.private = [ ".local/share/dino" ];
|
||||
|
||||
# creds, but also 200 MB of node modules, etc
|
||||
discord.persist.private = [ ".config/discord" ];
|
||||
|
||||
# creds/session keys, etc
|
||||
element-desktop.persist.private = [ ".config/Element" ];
|
||||
|
||||
# `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.
|
||||
# TODO: package [smile](https://github.com/mijorus/smile) for probably a better mobile experience.
|
||||
@@ -177,12 +211,6 @@
|
||||
|
||||
fluffychat-moby.persist.plaintext = [ ".local/share/chat.fluffy.fluffychat" ];
|
||||
|
||||
# XXX by default fractal stores its state in ~/.local/share/<UUID>.
|
||||
# after logging in, manually change ~/.local/share/keyrings/... to point it to some predictable subdir.
|
||||
# then reboot (so that libsecret daemon re-loads the keyring...?)
|
||||
fractal-latest.persist.private = [ ".local/share/fractal" ];
|
||||
fractal-next.persist.private = [ ".local/share/fractal" ];
|
||||
|
||||
# MS GitHub stores auth token in .config
|
||||
# TODO: we can populate gh's stuff statically; it even lets us use the same oauth across machines
|
||||
gh.persist.private = [ ".config/gh" ];
|
||||
@@ -193,13 +221,6 @@
|
||||
|
||||
mumble.persist.private = [ ".local/share/Mumble" ];
|
||||
|
||||
# not strictly necessary, but allows caching articles; offline use, etc.
|
||||
nheko.persist.private = [
|
||||
".config/nheko" # config file (including client token)
|
||||
".cache/nheko" # media cache
|
||||
".local/share/nheko" # per-account state database
|
||||
];
|
||||
|
||||
# settings (electron app)
|
||||
obsidian.persist.plaintext = [ ".config/obsidian" ];
|
||||
|
||||
|
36
hosts/common/programs/cantata.nix
Normal file
36
hosts/common/programs/cantata.nix
Normal file
@@ -0,0 +1,36 @@
|
||||
# cantata is a mpd frontend.
|
||||
# before launching it, run `mopidy` in some tab
|
||||
# TODO: auto-launch mopidy when cantata launches?
|
||||
{ ... }:
|
||||
{
|
||||
sane.programs.cantata = {
|
||||
persist.plaintext = [
|
||||
".cache/cantata" # album art
|
||||
".local/share/cantata/library" # library index (?)
|
||||
];
|
||||
fs.".config/cantata/cantata.conf".symlink.text = ''
|
||||
[General]
|
||||
fetchCovers=true
|
||||
storeCoversInMpdDir=false
|
||||
version=2.5.0
|
||||
|
||||
[Connection]
|
||||
allowLocalStreaming=true
|
||||
applyReplayGain=true
|
||||
autoUpdate=false
|
||||
dir=~/Music
|
||||
host=localhost
|
||||
partition=
|
||||
passwd=
|
||||
port=6600
|
||||
replayGain=off
|
||||
streamUrl=
|
||||
|
||||
[LibraryPage]
|
||||
artist\gridZoom=100
|
||||
artist\searchActive=false
|
||||
artist\viewMode=detailedtree
|
||||
'';
|
||||
suggestedPrograms = [ "mopidy" ];
|
||||
};
|
||||
}
|
46
hosts/common/programs/chatty.nix
Normal file
46
hosts/common/programs/chatty.nix
Normal file
@@ -0,0 +1,46 @@
|
||||
{ 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, for unused feature
|
||||
samba = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
sane.programs.chatty = {
|
||||
# package = chattyNoOauth;
|
||||
package = chatty-latest;
|
||||
suggestedPrograms = [ "gnome-keyring" ];
|
||||
persist.private = [
|
||||
".local/share/chatty" # matrix avatars and files
|
||||
# not just XMPP; without this Chatty will regenerate its device-id every boot.
|
||||
# .purple/ contains XMPP *and* Matrix auth, logs, avatar cache, and a bit more
|
||||
".purple"
|
||||
];
|
||||
};
|
||||
}
|
@@ -3,14 +3,24 @@
|
||||
{
|
||||
imports = [
|
||||
./aerc.nix
|
||||
./alacritty.nix
|
||||
./assorted.nix
|
||||
./cantata.nix
|
||||
./chatty.nix
|
||||
./cozy.nix
|
||||
./dino.nix
|
||||
./element-desktop.nix
|
||||
./epiphany.nix
|
||||
./evince.nix
|
||||
./firefox.nix
|
||||
./fontconfig.nix
|
||||
./fractal.nix
|
||||
./fwupd.nix
|
||||
./g4music.nix
|
||||
./git.nix
|
||||
./gnome-feeds.nix
|
||||
./gnome-keyring.nix
|
||||
./gnome-weather.nix
|
||||
./gpodder.nix
|
||||
./gthumb.nix
|
||||
./helix.nix
|
||||
@@ -21,22 +31,28 @@
|
||||
./koreader
|
||||
./libreoffice.nix
|
||||
./lemoa.nix
|
||||
./megapixels.nix
|
||||
./mepo.nix
|
||||
./mopidy.nix
|
||||
./mpv.nix
|
||||
./msmtp.nix
|
||||
./neovim.nix
|
||||
./newsflash.nix
|
||||
./nheko.nix
|
||||
./nix-index.nix
|
||||
./obsidian.nix
|
||||
./offlineimap.nix
|
||||
./rhythmbox.nix
|
||||
./ripgrep.nix
|
||||
./sfeed.nix
|
||||
./splatmoji.nix
|
||||
./steam.nix
|
||||
./sublime-music.nix
|
||||
./tangram.nix
|
||||
./tuba.nix
|
||||
./vlc.nix
|
||||
./wireshark.nix
|
||||
./xarchiver.nix
|
||||
./zeal.nix
|
||||
./zsh
|
||||
];
|
||||
|
15
hosts/common/programs/dino.nix
Normal file
15
hosts/common/programs/dino.nix
Normal file
@@ -0,0 +1,15 @@
|
||||
# usage:
|
||||
# - start a DM with a rando via
|
||||
# - '+' -> 'start conversation'
|
||||
# - add a user to your roster via
|
||||
# - '+' -> 'start conversation' -> '+' (opens the "add contact" dialog)
|
||||
# - this triggers a popup on the remote side asking them for confirmation
|
||||
# - after the remote's confirmation there will be a local popup for you to allow them to add you to their roster
|
||||
# - to make a call:
|
||||
# - ensure the other party is in your roster
|
||||
# - open a DM with the party
|
||||
# - click the phone icon at top (only visible if other party is in your roster)
|
||||
{ ... }:
|
||||
{
|
||||
sane.programs.dino.persist.private = [ ".local/share/dino" ];
|
||||
}
|
9
hosts/common/programs/element-desktop.nix
Normal file
9
hosts/common/programs/element-desktop.nix
Normal file
@@ -0,0 +1,9 @@
|
||||
{ ... }:
|
||||
{
|
||||
sane.programs.element-desktop = {
|
||||
# creds/session keys, etc
|
||||
persist.private = [ ".config/Element" ];
|
||||
|
||||
suggestedPrograms = [ "gnome-keyring" ];
|
||||
};
|
||||
}
|
@@ -8,7 +8,8 @@
|
||||
serif = [ "DejaVu Serif" ];
|
||||
sansSerif = [ "DejaVu Sans" ];
|
||||
};
|
||||
enableDefaultFonts = true;
|
||||
fonts = with pkgs; [ font-awesome noto-fonts-emoji hack-font ];
|
||||
#vvv enables dejavu_fonts, freefont_ttf, gyre-fonts, liberation_ttf, unifont, noto-fonts-emoji
|
||||
enableDefaultPackages = true;
|
||||
packages = with pkgs; [ font-awesome noto-fonts-emoji hack-font ];
|
||||
};
|
||||
}
|
||||
|
12
hosts/common/programs/fractal.nix
Normal file
12
hosts/common/programs/fractal.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
sane.programs.fractal = {
|
||||
# package = pkgs.fractal-latest;
|
||||
package = pkgs.fractal-next;
|
||||
|
||||
# XXX by default fractal stores its state in ~/.local/share/stable/<UUID>.
|
||||
persist.private = [ ".local/share/stable" ];
|
||||
|
||||
suggestedPrograms = [ "gnome-keyring" ];
|
||||
};
|
||||
}
|
7
hosts/common/programs/fwupd.nix
Normal file
7
hosts/common/programs/fwupd.nix
Normal file
@@ -0,0 +1,7 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
services.fwupd = lib.mkIf config.sane.programs.fwupd.enabled {
|
||||
# enables the dbus service, which i think the frontend speaks to.
|
||||
enable = true;
|
||||
};
|
||||
}
|
16
hosts/common/programs/g4music.nix
Normal file
16
hosts/common/programs/g4music.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
# N.B.: requires first-run setup on moby:
|
||||
# - UI will render transparent
|
||||
# - click the hamburger (top-right: immediately left from close button)
|
||||
# > Preferences
|
||||
# > Background-blur mode: change from "Always" to "Never"
|
||||
#
|
||||
# the background blur is probably some dconf setting somewhere.
|
||||
{ ... }:
|
||||
{
|
||||
sane.programs.g4music = {
|
||||
persist.plaintext = [
|
||||
# index?
|
||||
".cache/com.github.neithern.g4music"
|
||||
];
|
||||
};
|
||||
}
|
10
hosts/common/programs/gnome-keyring.nix
Normal file
10
hosts/common/programs/gnome-keyring.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
sane.programs.gnome-keyring = {
|
||||
package = pkgs.gnome.gnome-keyring;
|
||||
};
|
||||
# adds gnome-keyring as a xdg-data-portal (xdg.portal)
|
||||
services.gnome.gnome-keyring = lib.mkIf config.sane.programs.gnome-keyring.enabled {
|
||||
enable = true;
|
||||
};
|
||||
}
|
10
hosts/common/programs/gnome-weather.nix
Normal file
10
hosts/common/programs/gnome-weather.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
# preferences are saved via dconf; see `dconf dump /`
|
||||
# cache dir is just for weather data (or maybe a http cache)
|
||||
{ ... }:
|
||||
{
|
||||
sane.programs.gnome-weather = {
|
||||
persist.plaintext = [
|
||||
".cache/libgweather"
|
||||
];
|
||||
};
|
||||
}
|
@@ -4,10 +4,12 @@
|
||||
# compile without webservices to avoid the expensive webkitgtk dependency
|
||||
package = pkgs.gthumb.override { withWebservices = false; };
|
||||
mime.associations = {
|
||||
"image/gif" = "org.gnome.gThumb.desktop";
|
||||
"image/heif" = "org.gnome.gThumb.desktop"; # apple codec
|
||||
"image/png" = "org.gnome.gThumb.desktop";
|
||||
"image/jpeg" = "org.gnome.gThumb.desktop";
|
||||
"image/svg+xml" = "org.gnome.gThumb.desktop";
|
||||
"image/webp" = "org.gnome.gThumb.desktop";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@@ -3,7 +3,9 @@
|
||||
{
|
||||
sane.programs.jellyfin-media-player = {
|
||||
# package = pkgs.jellyfin-media-player;
|
||||
package = pkgs.jellyfin-media-player-qt6;
|
||||
# qt6 version is slightly buggy, but also most qtwebengine apps (e.g. zeal) are on qt5
|
||||
# so using qt6 would force yet *another* qtwebengine compile.
|
||||
# package = pkgs.jellyfin-media-player-qt6;
|
||||
|
||||
# jellyfin stores things in a bunch of directories: this one persists auth info.
|
||||
# it *might* be possible to populate this externally (it's Qt stuff), but likely to
|
||||
|
@@ -1,4 +1,4 @@
|
||||
{ config, lib, sane-lib, ... }:
|
||||
{ config, lib, pkgs, sane-lib, ... }:
|
||||
|
||||
let
|
||||
feeds = sane-lib.feeds;
|
||||
@@ -10,11 +10,12 @@ let
|
||||
# limit = 0 => download and keep *all* articles
|
||||
# download_full_article = true => populate feed by downloading the webpage -- not just what's encoded in the RSS <article> tags
|
||||
# - use this for articles where the RSS only encodes content previews
|
||||
# - in practice, most articles don't work with download_full_article = false
|
||||
# enable_filter = true => only render content that matches the filter_element css selector.
|
||||
let fields = [
|
||||
(lib.escapeShellArg feed.url)
|
||||
"limit = 5"
|
||||
"download_full_article = false"
|
||||
"download_full_article = true"
|
||||
"include_images = true"
|
||||
"enable_filter = false"
|
||||
"filter_element = \"\""
|
||||
@@ -22,6 +23,7 @@ let
|
||||
) wantedFeeds;
|
||||
in {
|
||||
sane.programs.koreader = {
|
||||
package = pkgs.koreader-from-src;
|
||||
# koreader applies these lua "patches" at boot:
|
||||
# - <https://github.com/koreader/koreader/wiki/User-patches>
|
||||
# - TODO: upstream this patch to koreader
|
||||
|
@@ -1,8 +1,13 @@
|
||||
{ ... }:
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
# libreoffice: disable first-run stuff
|
||||
sane.programs.libreoffice-fresh.fs.".config/libreoffice/4/user/registrymodifications.xcu".symlink.text = ''
|
||||
sane.programs.libreoffice = {
|
||||
# package = pkgs.libreoffice-bin;
|
||||
# package = pkgs.libreoffice-still;
|
||||
package = pkgs.libreoffice-fresh;
|
||||
|
||||
# disable first-run stuff
|
||||
fs.".config/libreoffice/4/user/registrymodifications.xcu".symlink.text = ''
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<oor:items xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<item oor:path="/org.openoffice.Office.Common/Misc"><prop oor:name="FirstRun" oor:op="fuse"><value>false</value></prop></item>
|
||||
@@ -11,4 +16,5 @@
|
||||
'';
|
||||
# <item oor:path="/org.openoffice.Setup/Product"><prop oor:name="LastTimeDonateShown" oor:op="fuse"><value>1667693880</value></prop></item>
|
||||
# <item oor:path="/org.openoffice.Setup/Product"><prop oor:name="LastTimeGetInvolvedShown" oor:op="fuse"><value>1667693880</value></prop></item>
|
||||
};
|
||||
}
|
||||
|
11
hosts/common/programs/megapixels.nix
Normal file
11
hosts/common/programs/megapixels.nix
Normal file
@@ -0,0 +1,11 @@
|
||||
{ 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;
|
||||
};
|
||||
};
|
||||
}
|
@@ -9,12 +9,18 @@
|
||||
persist.private = [
|
||||
{ type = "file"; path = ".cache/mepo/savestate"; }
|
||||
];
|
||||
|
||||
# give mepo access to gpsd for location data, if that's enabled.
|
||||
# same with geoclue2.
|
||||
suggestedPrograms = lib.optional config.services.gpsd.enable "gpsd"
|
||||
++ lib.optional config.services.geoclue2.enable "geoclue2-with-demo-agent"
|
||||
;
|
||||
};
|
||||
|
||||
programs.mepo = lib.mkIf config.sane.programs.mepo.enabled {
|
||||
# enable location services (via geoclue)
|
||||
enable = true;
|
||||
# more precise, via gpsd ("may require additional config")
|
||||
# programs.mepo.gpsd.enable = true
|
||||
};
|
||||
# programs.mepo = lib.mkIf config.sane.programs.mepo.enabled {
|
||||
# # enable location services (via geoclue)
|
||||
# enable = true;
|
||||
# # more precise, via gpsd ("may require additional config")
|
||||
# # programs.mepo.gpsd.enable = true
|
||||
# };
|
||||
}
|
||||
|
56
hosts/common/programs/mopidy.nix
Normal file
56
hosts/common/programs/mopidy.nix
Normal file
@@ -0,0 +1,56 @@
|
||||
# chat: <https://mopidy.zulipchat.com/>
|
||||
# config docs: <https://docs.mopidy.com/en/latest/config/>
|
||||
# web client: <http://localhost:6680>
|
||||
# mpd: hosted on `localhost:6600`, no password`
|
||||
#
|
||||
# dump config:
|
||||
# - `mopidy config`
|
||||
# update local file index with
|
||||
# - `mopidy local scan`
|
||||
#
|
||||
# if running as service, those commands are `mopidy --config ... <command>`
|
||||
# and config path is found by `systemctl cat mopidy`
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
# TODO: upstream this as `mopidy.withExtensions`
|
||||
# this is borrowed from the nixos mopidy service
|
||||
mopidyWithExtensions = extensions: with pkgs; buildEnv {
|
||||
name = "mopidy-with-extensions-${mopidy.version}";
|
||||
|
||||
paths = lib.closePropagation extensions;
|
||||
pathsToLink = [ "/${mopidyPackages.python.sitePackages}" ];
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
postBuild = ''
|
||||
makeWrapper ${mopidy}/bin/mopidy $out/bin/mopidy \
|
||||
--prefix PYTHONPATH : $out/${mopidyPackages.python.sitePackages}
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
sane.programs.mopidy = {
|
||||
package = mopidyWithExtensions (with pkgs; [
|
||||
mopidy-iris # web client: <https://github.com/jaedb/Iris>
|
||||
mopidy-jellyfin
|
||||
mopidy-local
|
||||
mopidy-mpd
|
||||
mopidy-mpris
|
||||
mopidy-spotify
|
||||
# TODO: mopidy-podcast, mopidy-youtube
|
||||
|
||||
# alternate web clients:
|
||||
# mopidy-moped: <https://github.com/martijnboland/moped>
|
||||
# mopidy-muse: <https://github.com/cristianpb/muse>
|
||||
]);
|
||||
persist.plaintext = [
|
||||
".local/share/mopidy/local" # thumbs, library db
|
||||
];
|
||||
persist.private = [
|
||||
".local/share/mopidy/http" # cookie
|
||||
];
|
||||
secrets.".config/mopidy/mopidy.conf" = ../../../secrets/common/mopidy.conf.bin;
|
||||
# other folders:
|
||||
# - .cache/mopidy
|
||||
# - .config/mopidy
|
||||
};
|
||||
}
|
@@ -1,13 +1,109 @@
|
||||
{ ... }:
|
||||
# mpv docs:
|
||||
# - <https://mpv.io/manual/master>
|
||||
# - <https://github.com/mpv-player/mpv/wiki>
|
||||
# curated mpv mods/scripts/users:
|
||||
# - <https://github.com/stax76/awesome-mpv>
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
sane.programs.mpv = {
|
||||
package = pkgs.wrapMpv pkgs.mpv-unwrapped {
|
||||
youtubeSupport = false; #< XXX(2023/08/03): doesn't cross compile until next staging -> master merge
|
||||
scripts = with pkgs.mpvScripts; [
|
||||
mpris
|
||||
# uosc
|
||||
pkgs.mpv-uosc-latest
|
||||
];
|
||||
extraMakeWrapperArgs = [
|
||||
# 2023/08/29: fixes an error where mpv on moby launches with the message
|
||||
# "DRM_IOCTL_MODE_CREATE_DUMB failed: Cannot allocate memory"
|
||||
# audio still works, and controls, screenshotting, etc -- just not the actual rendering
|
||||
# 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.
|
||||
# run with `--vo=help` to see a list of all output options.
|
||||
# non-exhaustive (F=fails, W=works)
|
||||
# ? libmpv render API for libmpv
|
||||
# ? gpu Shader-based GPU Renderer
|
||||
# ? gpu-next Video output based on libplacebo
|
||||
# ? vdpau VDPAU with X11
|
||||
# ? wlshm Wayland SHM video output (software scaling)
|
||||
# ? xv X11/Xv
|
||||
# W sdl SDL 2.0 Renderer
|
||||
# F dmabuf-wayland Wayland dmabuf video output
|
||||
# ? vaapi VA API with X11
|
||||
# ? x11 X11 (software scaling)
|
||||
# ? null Null video output
|
||||
# ? caca libcaca
|
||||
# F drm Direct Rendering Manager (software scaling)
|
||||
"--add-flags" "--vo=sdl"
|
||||
];
|
||||
};
|
||||
persist.plaintext = [ ".config/mpv/watch_later" ];
|
||||
# format is <key>=%<length>%<value>
|
||||
fs.".config/mpv/mpv.conf".symlink.text = ''
|
||||
save-position-on-quit=%3%yes
|
||||
keep-open=%3%yes
|
||||
fs.".config/mpv/input.conf".symlink.text = ''
|
||||
# let volume keys be interpreted by the system.
|
||||
# this is important for sxmo.
|
||||
VOLUME_UP ignore
|
||||
VOLUME_DOWN ignore
|
||||
'';
|
||||
fs.".config/mpv/mpv.conf".symlink.text = ''
|
||||
save-position-on-quit=yes
|
||||
keep-open=yes
|
||||
|
||||
# force GUI, even for tracks w/o album art
|
||||
# see: <https://www.reddit.com/r/mpv/comments/rvrrpt/oscosdgui_and_arch_linux/>
|
||||
player-operation-mode=pseudo-gui
|
||||
|
||||
# use uosc instead (for On Screen Controls)
|
||||
osc=no
|
||||
# uosc provides its own seeking/volume indicators, so you also don't need this
|
||||
osd-bar=no
|
||||
# uosc will draw its own window controls if you disable window border
|
||||
border=no
|
||||
'';
|
||||
fs.".config/mpv/script-opts/osc.conf".symlink.text = ''
|
||||
# make the on-screen controls *always* visible
|
||||
# unfortunately, this applies to full-screen as well
|
||||
# - docs: <https://mpv.io/manual/master/#on-screen-controller-visibility>
|
||||
# if uosc is installed, this file is unused
|
||||
visibility=always
|
||||
'';
|
||||
fs.".config/mpv/script-opts/uosc.conf".symlink.text = let
|
||||
play_pause_btn = "cycle:play_arrow:pause:no=pause/yes=play_arrow";
|
||||
rev_btn = "command:replay_10:seek -10";
|
||||
fwd_btn = "command:forward_30:seek 30";
|
||||
in ''
|
||||
# docs:
|
||||
# - <https://github.com/tomasklaen/uosc>
|
||||
# - <https://superuser.com/questions/1775550/add-new-buttons-to-mpv-uosc-ui>
|
||||
timeline_style=bar
|
||||
timeline_persistency=paused,audio
|
||||
controls_persistency=paused,audio
|
||||
volume_persistency=audio
|
||||
volume_opacity=0.75
|
||||
|
||||
# speed_persistency=paused,audio
|
||||
# vvv want a close button?
|
||||
top_bar=always
|
||||
top_bar_persistency=paused
|
||||
|
||||
controls=menu,<video>subtitles,<has_many_audio>audio,<has_many_video>video,<has_many_edition>editions,<stream>stream-quality,space,${rev_btn},${play_pause_btn},${fwd_btn},space,speed:1.0,gap,<video>fullscreen
|
||||
|
||||
text_border=6.0
|
||||
font_bold=yes
|
||||
background_text=ff8080
|
||||
foreground=ff8080
|
||||
|
||||
ui_scale=1.0
|
||||
'';
|
||||
|
||||
mime.priority = 200; # default = 100; 200 means to yield to other apps
|
||||
mime.associations."audio/flac" = "mpv.desktop";
|
||||
mime.associations."audio/mpeg" = "mpv.desktop";
|
||||
mime.associations."audio/x-vorbis+ogg" = "mpv.desktop";
|
||||
mime.associations."video/mp4" = "mpv.desktop";
|
||||
mime.associations."video/quicktime" = "mpv.desktop";
|
||||
mime.associations."video/webm" = "mpv.desktop";
|
||||
mime.associations."video/x-matroska" = "mpv.desktop";
|
||||
};
|
||||
}
|
||||
|
||||
|
9
hosts/common/programs/nheko.nix
Normal file
9
hosts/common/programs/nheko.nix
Normal file
@@ -0,0 +1,9 @@
|
||||
{ ... }:
|
||||
{
|
||||
# not strictly necessary, but allows caching articles; offline use, etc.
|
||||
sane.programs.nheko.persist.private = [
|
||||
".config/nheko" # config file (including client token)
|
||||
".cache/nheko" # media cache
|
||||
".local/share/nheko" # per-account state database
|
||||
];
|
||||
}
|
11
hosts/common/programs/rhythmbox.nix
Normal file
11
hosts/common/programs/rhythmbox.nix
Normal file
@@ -0,0 +1,11 @@
|
||||
{ ... }:
|
||||
{
|
||||
sane.programs.rhythmbox = {
|
||||
persist.plaintext = [
|
||||
# playlists; index
|
||||
".local/share/rhythmbox"
|
||||
# album art
|
||||
".cache/rhythmbox"
|
||||
];
|
||||
};
|
||||
}
|
4
hosts/common/programs/tuba.nix
Normal file
4
hosts/common/programs/tuba.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{ ... }:
|
||||
{
|
||||
sane.programs.tuba.suggestedPrograms = [ "gnome-keyring" ];
|
||||
}
|
7
hosts/common/programs/xarchiver.nix
Normal file
7
hosts/common/programs/xarchiver.nix
Normal file
@@ -0,0 +1,7 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
sane.programs.xarchiver.package = pkgs.xarchiver.override {
|
||||
# unar doesn't cross compile well, so disable support for it
|
||||
unar = null;
|
||||
};
|
||||
}
|
@@ -13,6 +13,7 @@ let
|
||||
};
|
||||
in {
|
||||
sane.programs.zeal = {
|
||||
# package = pkgs.zeal-qt6; #< TODO: upgrade system to qt6 versions of everything (i.e. jellyfin-media-player, nheko)
|
||||
package = pkgs.zeal-qt5;
|
||||
persist.plaintext = [
|
||||
".cache/Zeal"
|
||||
|
@@ -7,6 +7,7 @@
|
||||
# - $ZDOTDIR/.zprofile
|
||||
# - if interactive:
|
||||
# - /etc/zshrc
|
||||
# -> /etc/zinputrc
|
||||
# - $ZDOTDIR/.zshrc
|
||||
# - if login (again):
|
||||
# - /etc/zlogin
|
||||
@@ -79,6 +80,18 @@ in
|
||||
hash -d tmp="/home/colin/tmp"
|
||||
hash -d uninsane="/home/colin/dev/uninsane"
|
||||
hash -d Videos="/home/colin/Videos"
|
||||
|
||||
# emulate bash keybindings
|
||||
bindkey -e
|
||||
|
||||
# or manually recreate what i care about...
|
||||
# key[Left]=''${terminfo[kcub1]}
|
||||
# key[Right]=''${terminfo[kcuf1]}
|
||||
# bindkey '^R' history-incremental-search-backward
|
||||
# bindkey '^A' beginning-of-line
|
||||
# bindkey '^E' end-of-line
|
||||
# bindkey "^''${key[Left]}" backward-word
|
||||
# bindkey "^''${key[Right]}" forward-word
|
||||
'';
|
||||
};
|
||||
})
|
||||
|
@@ -83,7 +83,7 @@
|
||||
fs."Books/servo".symlink.target = "/mnt/servo-media/Books";
|
||||
fs."Videos/servo".symlink.target = "/mnt/servo-media/Videos";
|
||||
fs."Videos/servo-incomplete".symlink.target = "/mnt/servo-media/incomplete";
|
||||
fs."Music/servo".symlink.target = "/mnt/servo-media/Music";
|
||||
# fs."Music/servo".symlink.target = "/mnt/servo-media/Music";
|
||||
fs."Pictures/servo-macros".symlink.target = "/mnt/servo-media/Pictures/macros";
|
||||
|
||||
# used by password managers, e.g. unix `pass`
|
||||
|
@@ -1,10 +1,10 @@
|
||||
# trampoline from flake.nix into the specific host definition, while doing a tiny bit of common setup
|
||||
|
||||
# args from flake-level `import`
|
||||
{ hostName, localSystem }:
|
||||
{ hostName }:
|
||||
|
||||
# module args
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
@@ -14,5 +14,4 @@
|
||||
];
|
||||
|
||||
networking.hostName = hostName;
|
||||
nixpkgs.buildPlatform = lib.mkIf (localSystem != null) localSystem;
|
||||
}
|
||||
|
@@ -10,37 +10,42 @@
|
||||
|
||||
sane.programs.guiApps = {
|
||||
package = null;
|
||||
suggestedPrograms = [
|
||||
"firefox"
|
||||
suggestedPrograms = lib.optionals (pkgs.system == "x86_64-linux") [
|
||||
"x86GuiApps"
|
||||
] ++ [
|
||||
# package sets
|
||||
"tuiApps"
|
||||
] ++ lib.optional (pkgs.system == "x86_64-linux") "x86GuiApps"
|
||||
++ [
|
||||
] ++ [
|
||||
"alacritty" # terminal emulator
|
||||
# "celluloid" # mpv frontend
|
||||
"chatty" # matrix/xmpp/irc client
|
||||
"cozy" # audiobook player
|
||||
# "emote"
|
||||
"epiphany" # gnome's web browser
|
||||
"evince" # works on phosh
|
||||
"firefox"
|
||||
# "foliate" # e-book reader
|
||||
# "fractal" # matrix client
|
||||
"g4music" # local music player
|
||||
# "gnome.cheese"
|
||||
# "gnome-feeds" # RSS reader (with claimed mobile support)
|
||||
"gnome.file-roller"
|
||||
# "gnome.file-roller"
|
||||
# "gnome.gnome-maps" # works on phosh
|
||||
"gnome.nautilus"
|
||||
# "gnome-podcasts"
|
||||
# "gnome.gnome-system-monitor"
|
||||
# "gnome.gnome-terminal" # works on phosh
|
||||
# "gnome.gnome-weather"
|
||||
"gnome.gnome-weather"
|
||||
"gpodder"
|
||||
"gthumb"
|
||||
"komikku"
|
||||
"koreader"
|
||||
"lemoa" # lemmy app
|
||||
# "lollypop"
|
||||
"mate.engrampa" # archive manager
|
||||
"mepo" # maps viewer
|
||||
# "mpv"
|
||||
"mpv"
|
||||
# "networkmanagerapplet"
|
||||
# "newsflash"
|
||||
"nheko"
|
||||
"pavucontrol"
|
||||
# "picard" # music tagging
|
||||
# "libsForQt5.plasmatube" # Youtube player
|
||||
@@ -50,7 +55,6 @@
|
||||
# "tdesktop" # broken on phosh
|
||||
# "tokodon"
|
||||
"tuba" # mastodon/pleroma client (stores pw in keyring)
|
||||
"vlc"
|
||||
# "whalebird" # pleroma client (Electron). input is broken on phosh.
|
||||
"xterm" # broken on phosh
|
||||
];
|
||||
@@ -62,28 +66,34 @@
|
||||
"audacity"
|
||||
"blanket" # ambient noise generator
|
||||
"brave" # for the integrated wallet -- as a backup
|
||||
"chromium"
|
||||
"dino"
|
||||
"cantata" # music player (mpd frontend)
|
||||
# "chromium" # chromium takes hours to build. brave is chromium-based, distributed in binary form, so prefer it.
|
||||
"dino" # XMPP client
|
||||
"electrum"
|
||||
"element-desktop"
|
||||
# "font-manager" #< depends on webkitgtk4_0 (expensive to build)
|
||||
"gajim" # XMPP client
|
||||
# "gajim" # XMPP client
|
||||
"gimp" # broken on phosh
|
||||
"gnome.dconf-editor"
|
||||
# "gnome.file-roller"
|
||||
"gnome.gnome-disk-utility"
|
||||
"gnome.nautilus" # file browser
|
||||
# "gnome.totem" # video player, supposedly supports UPnP
|
||||
"handbrake"
|
||||
"hase"
|
||||
"inkscape"
|
||||
"jellyfin-media-player"
|
||||
# "jellyfin-media-player"
|
||||
"kdenlive"
|
||||
"kid3" # audio tagging
|
||||
"krita"
|
||||
"libreoffice-fresh"
|
||||
"libreoffice" # TODO: replace with an office suite that uses saner packaging?
|
||||
"mumble"
|
||||
"nheko"
|
||||
"obsidian"
|
||||
"rhythmbox" # local music player
|
||||
"slic3r"
|
||||
"steam"
|
||||
"vlc"
|
||||
"wireshark" # could maybe ship the cli as sysadmin pkg
|
||||
];
|
||||
};
|
||||
@@ -92,6 +102,8 @@
|
||||
package = null;
|
||||
suggestedPrograms = [
|
||||
"megapixels" # camera app
|
||||
"portfolio-filemanager"
|
||||
"xarchiver"
|
||||
];
|
||||
};
|
||||
|
||||
|
@@ -5,11 +5,15 @@ https://nixos.org/manual/nix/stable/language/builtins.html
|
||||
https://github.com/nixos/nixpkgs/pulls?q=
|
||||
https://nur.nix-community.org/
|
||||
https://nix-community.github.io/home-manager/options.html
|
||||
https://lists.sr.ht/~mil/sxmo-devel
|
||||
https://w.uninsane.org/viewer#search?books.name=wikipedia_en_all_maxi_2022-05&pattern=
|
||||
https://jackett.uninsane.org/UI/Dashboard#search=
|
||||
https://lemmy.uninsane.org
|
||||
https://fed.uninsane.org
|
||||
https://jelly.uninsane.org
|
||||
https://bt.uninsane.org
|
||||
https://sci-hub.se
|
||||
https://archive.is
|
||||
https://news.ycombinator.com
|
||||
http://10.78.79.1 # Router/Firewall
|
||||
http://10.78.79.1 # router/firewall
|
||||
https://jochen-hoenicke.de/queue # johoe's mempool (bitcoin/ethereum)
|
||||
|
@@ -97,9 +97,6 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
# some programs (e.g. fractal) **require** a "Secret Service Provider"
|
||||
services.gnome.gnome-keyring.enable = true;
|
||||
|
||||
# unlike other DEs, sway configures no audio stack
|
||||
# administer with pw-cli, pw-mon, pw-top commands
|
||||
services.pipewire = {
|
||||
@@ -133,9 +130,38 @@ in
|
||||
};
|
||||
|
||||
programs.sway = {
|
||||
# provides xdg-desktop-portal-wlr, which exposes on dbus:
|
||||
# - org.freedesktop.impl.portal.ScreenCast
|
||||
# - org.freedesktop.impl.portal.Screenshot
|
||||
enable = true;
|
||||
extraPackages = []; # nixos adds swaylock, swayidle, foot, dmenu by default
|
||||
# "wrapGAppsHook wrapper to execute sway with required environment variables for GTK applications."
|
||||
wrapperFeatures.gtk = true;
|
||||
};
|
||||
# provide portals for:
|
||||
# - org.freedesktop.impl.portal.Access
|
||||
# - org.freedesktop.impl.portal.Account
|
||||
# - org.freedesktop.impl.portal.DynamicLauncher
|
||||
# - org.freedesktop.impl.portal.Email
|
||||
# - org.freedesktop.impl.portal.FileChooser
|
||||
# - org.freedesktop.impl.portal.Inhibit
|
||||
# - org.freedesktop.impl.portal.Notification
|
||||
# - org.freedesktop.impl.portal.Print
|
||||
# and conditionally (i.e. unless buildPortalsInGnome = false) for:
|
||||
# - org.freedesktop.impl.portal.AppChooser (@appchooser_iface@)
|
||||
# - org.freedesktop.impl.portal.Background (@background_iface@)
|
||||
# - org.freedesktop.impl.portal.Lockdown (@lockdown_iface@)
|
||||
# - org.freedesktop.impl.portal.RemoteDesktop (@remotedesktop_iface@)
|
||||
# - org.freedesktop.impl.portal.ScreenCast (@screencast_iface@)
|
||||
# - org.freedesktop.impl.portal.Screenshot (@screenshot_iface@)
|
||||
# - org.freedesktop.impl.portal.Settings (@settings_iface@)
|
||||
# - org.freedesktop.impl.portal.Wallpaper (@wallpaper_iface@)
|
||||
xdg.portal.extraPortals = [
|
||||
(pkgs.xdg-desktop-portal-gtk.override {
|
||||
buildPortalsInGnome = false;
|
||||
})
|
||||
];
|
||||
|
||||
sane.user.fs.".config/sway/config".symlink.text =
|
||||
import ./sway-config.nix { inherit pkgs; };
|
||||
|
||||
|
@@ -3,9 +3,8 @@ let
|
||||
fuzzel = "${pkgs.fuzzel}/bin/fuzzel";
|
||||
sed = "${pkgs.gnused}/bin/sed";
|
||||
wtype = "${pkgs.wtype}/bin/wtype";
|
||||
kitty = "${pkgs.kitty}/bin/kitty";
|
||||
launcher-cmd = fuzzel;
|
||||
terminal-cmd = kitty;
|
||||
terminal-cmd = "${pkgs.xdg-terminal-exec}/bin/xdg-terminal-exec";
|
||||
lock-cmd = "${pkgs.swaylock}/bin/swaylock --indicator-idle-visible --indicator-radius 100 --indicator-thickness 30";
|
||||
vol-up-cmd = "${pkgs.pulsemixer}/bin/pulsemixer --change-volume +5";
|
||||
vol-down-cmd = "${pkgs.pulsemixer}/bin/pulsemixer --change-volume -5";
|
||||
@@ -170,4 +169,13 @@ in ''
|
||||
pos 1920,0
|
||||
res 1920x1080
|
||||
}
|
||||
|
||||
# XXX: needed for xdg-desktop-portal-* to work.
|
||||
# this is how we expose these env vars to user dbus services:
|
||||
# - DISPLAY
|
||||
# - WAYLAND_DISPLAY
|
||||
# - SWAYSOCK
|
||||
# - XDG_CURRENT_DESKTOP
|
||||
# for more, see: <repo:nixos/nixpkgs:nixos/modules/programs/wayland/sway.nix>
|
||||
include /etc/sway/config.d/*
|
||||
''
|
||||
|
@@ -1,5 +1,3 @@
|
||||
-- configversion: 737cb1de0389cee32a04785691a446a2
|
||||
|
||||
-- docs: <https://conky.cc/variables>
|
||||
-- color names are X11 colors: <https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart>
|
||||
-- - can also use #rrggbb syntax
|
||||
@@ -13,11 +11,12 @@ conky.config = {
|
||||
alignment = 'middle_middle',
|
||||
own_window_type = 'desktop',
|
||||
-- own_window_argb_value: opacity of the background (0-255)
|
||||
own_window_argb_value = 92,
|
||||
own_window_colour = '#beebe5', -- beebe5 matches nixos flake bg color
|
||||
own_window_argb_value = 0,
|
||||
-- own_window_argb_value = 92,
|
||||
-- own_window_colour = '#beebe5', -- beebe5 matches nixos flake bg color
|
||||
|
||||
-- "border" pads the entire conky window
|
||||
-- this can be used to control the extend of the own_window background
|
||||
-- this can be used to control the extent of the own_window background
|
||||
border_inner_margin = 8,
|
||||
-- optionally, actually draw borders
|
||||
-- draw_borders = true,
|
||||
@@ -36,12 +35,14 @@ conky.config = {
|
||||
color2 = '404040',
|
||||
}
|
||||
|
||||
-- texeci <interval_sec> <cmd>: run the command periodically, _in a separate thread_ so as not to block rendering
|
||||
conky.text = [[
|
||||
${color1}${shadecolor 707070}${font Sxmo:size=50:style=Bold}${alignc}${exec date +"%H:%M"}${font}
|
||||
${color2}${shadecolor a4d7d0}${font Sxmo:size=20}${alignc}${exec date +"%a %d %b"}${font}
|
||||
|
||||
|
||||
${color1}${shadecolor}${font Sxmo:size=22:style=Bold}${alignc}${exec @bat@ }${font}
|
||||
${color1}${shadecolor}${font Sxmo:size=20:style=Bold}${alignc}${texeci 600 @weather@ }${font}
|
||||
|
||||
|
||||
${color2}${shadecolor a4d7d0}${font Sxmo:size=16}${alignc}⇅ ${downspeedf wlan0}K/s${font}
|
||||
|
@@ -37,7 +37,7 @@
|
||||
# - live in ~/.local/state/sxmo.log
|
||||
# - ~/.local/state/superd.log
|
||||
# - ~/.local/state/superd/logs/<daemon>.log
|
||||
# - `journalctl --user --boot` (lightm redirects the sxmo session stdout => systemd)
|
||||
# - `journalctl --user --boot` (lightdm redirects the sxmo session stdout => systemd)
|
||||
#
|
||||
# - default components:
|
||||
# - DE: sway (if wayland), dwm (if X)
|
||||
@@ -57,6 +57,12 @@ let
|
||||
knownTerminals = {
|
||||
vte = "vte-2.91";
|
||||
};
|
||||
|
||||
systemd-cat = "${pkgs.systemd}/bin/systemd-cat";
|
||||
runWithLogger = identifier: cmd: pkgs.writeShellScript identifier ''
|
||||
echo "launching ${identifier}..." | ${systemd-cat} --identifier=${identifier}
|
||||
${cmd} 2>&1 | ${systemd-cat} --identifier=${identifier}
|
||||
'';
|
||||
in
|
||||
{
|
||||
options = with lib; {
|
||||
@@ -65,17 +71,31 @@ in
|
||||
type = types.bool;
|
||||
};
|
||||
sane.gui.sxmo.greeter = mkOption {
|
||||
type = types.enum [ "lightdm-mobile" "sway" ];
|
||||
default = "lightdm-mobile";
|
||||
type = types.enum [
|
||||
"greetd-phog"
|
||||
"greetd-sway-phog"
|
||||
"greetd-sxmo"
|
||||
"lightdm-mobile"
|
||||
"sway-gtkgreet"
|
||||
];
|
||||
# default = "lightdm-mobile";
|
||||
default = "greetd-sway-phog";
|
||||
description = ''
|
||||
which greeter to use.
|
||||
"greetd-phog" => phosh-based greeter. keypad (0-9) with option to open an on-screen keyboard.
|
||||
"greetd-sway-phog" => phog, but uses sway as the compositor instead of phoc.
|
||||
requires a patched phog, since sway doesn't provide the Wayland global "zphoc_layer_shell_effects_v1".
|
||||
"greetd-sxmo" => launch sxmo directly from greetd, no auth.
|
||||
this means no keychain unlocked or encrypted home mounted.
|
||||
"lightdm-mobile" => keypad style greeter. can only enter digits 0-9 as password.
|
||||
"sway" => layered sway greeter. behaves as if you booted to swaylock.
|
||||
"sway-gtkgreet" => layered sway greeter. behaves as if you booted to swaylock.
|
||||
this isn't practically usable on mobile because of keyboard input.
|
||||
also, it takes literally 6 minutes to appear
|
||||
'';
|
||||
};
|
||||
sane.gui.sxmo.package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.sxmo-utils;
|
||||
default = pkgs.sxmo-utils-latest;
|
||||
description = ''
|
||||
sxmo base scripts and hooks collection.
|
||||
consider overriding the outputs under /share/sxmo/default_hooks
|
||||
@@ -116,6 +136,7 @@ in
|
||||
};
|
||||
in {
|
||||
SXMO_BAR_SHOW_BAT_PER = mkSettingsOpt "1" "show battery percentage in statusbar";
|
||||
SXMO_DISABLE_CONFIGVERSION_CHECK = mkSettingsOpt "1" "allow omitting the configversion line from user-provided sxmo dotfiles";
|
||||
SXMO_UNLOCK_IDLE_TIME = mkSettingsOpt "300" "how many seconds of inactivity before locking the screen"; # lock -> screenoff happens 8s later, not configurable
|
||||
};
|
||||
};
|
||||
@@ -126,6 +147,11 @@ in
|
||||
default = false;
|
||||
description = "inhibit lock-on-idle and screenoff-on-idle";
|
||||
};
|
||||
sane.gui.sxmo.nogesture = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "don't start lisgd gesture daemon by default";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
@@ -170,11 +196,10 @@ in
|
||||
hardware.bluetooth.enable = true;
|
||||
services.blueman.enable = true;
|
||||
|
||||
# TODO: nerdfonts is 4GB. it accepts an option to ship only some fonts: probably want to use that.
|
||||
fonts.fonts = [ pkgs.nerdfonts ];
|
||||
hardware.opengl.enable = true;
|
||||
|
||||
# some programs (e.g. fractal/nheko) **require** a "Secret Service Provider"
|
||||
services.gnome.gnome-keyring.enable = true;
|
||||
# TODO: nerdfonts is 4GB. it accepts an option to ship only some fonts: probably want to use that.
|
||||
fonts.packages = [ pkgs.nerdfonts ];
|
||||
|
||||
# lightdm-mobile-greeter: "The name org.a11y.Bus was not provided by any .service files"
|
||||
services.gnome.at-spi2-core.enable = true;
|
||||
@@ -202,7 +227,10 @@ in
|
||||
# TODO: only need the share/sxmo directly linked
|
||||
"${cfg.package}/share"
|
||||
];
|
||||
};
|
||||
} // (lib.filterAttrs # certain settings are read before the `profile` is sourced
|
||||
(k: v: k == "SXMO_DISABLE_CONFIGVERSION_CHECK")
|
||||
cfg.settings
|
||||
);
|
||||
|
||||
systemd.services."sxmo-set-permissions" = {
|
||||
description = "configure specific /sys and /dev nodes to be writable by sxmo scripts";
|
||||
@@ -213,19 +241,41 @@ in
|
||||
wantedBy = [ "display-manager.service" ];
|
||||
};
|
||||
|
||||
# if superd fails to start a service within 100ms, it'll try to start again
|
||||
# the fallout of this is that during intense lag (e.g. OOM or swapping) it can
|
||||
# start the service many times.
|
||||
# see <repo:craftyguy/superd:internal/cmd/cmd.go>
|
||||
# TODO: better fix may be to patch `sxmo_hook_lisgdstart.sh` and force it to behave as a singleton
|
||||
systemd.services."dedupe-sxmo-lisgd" = {
|
||||
description = "kill duplicate lisgd processes started by superd";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
script = ''
|
||||
if [ "$(${pkgs.procps}/bin/pgrep -c lisgd)" -gt 1 ]; then
|
||||
echo 'killing duplicated lisgd daemons'
|
||||
${pkgs.psmisc}/bin/killall lisgd # let superd restart it
|
||||
fi
|
||||
'';
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
systemd.timers."dedupe-sxmo-lisgd" = {
|
||||
wantedBy = [ "dedupe-sxmo-lisgd.service" ];
|
||||
timerConfig = {
|
||||
OnUnitActiveSec = "2min";
|
||||
};
|
||||
};
|
||||
|
||||
sane.user.fs.".cache/sxmo/sxmo.noidle" = lib.mkIf cfg.noidle {
|
||||
symlink.text = "";
|
||||
};
|
||||
sane.user.fs.".cache/sxmo/sxmo.nogesture" = lib.mkIf cfg.nogesture {
|
||||
symlink.text = "";
|
||||
};
|
||||
sane.user.fs.".config/sxmo/profile".symlink.text = let
|
||||
mkKeyValue = key: value: ''export ${key}="${value}"'';
|
||||
userConfig = lib.generators.toKeyValue { inherit mkKeyValue; } cfg.settings;
|
||||
in ''
|
||||
# configversion: 4284f96d91e9550ff8f3b25823e402ad
|
||||
# ^ upstream adds new options every now and then, expects user config file
|
||||
# to include the md5sum of the template it's based on.
|
||||
# see `setup_config_version.sh`
|
||||
${userConfig}
|
||||
'';
|
||||
in
|
||||
lib.generators.toKeyValue { inherit mkKeyValue; } cfg.settings;
|
||||
|
||||
sane.user.fs.".config/sxmo/sway".symlink.target = pkgs.substituteAll {
|
||||
src = ./sway-config;
|
||||
@@ -238,8 +288,8 @@ in
|
||||
in
|
||||
(pkgs.formats.json {}).generate "waybar-config.json" waybar-config;
|
||||
|
||||
# sane.user.fs.".config/waybar/style.css".symlink.text =
|
||||
# builtins.readFile ./waybar-style.css;
|
||||
sane.user.fs.".config/waybar/style.css".symlink.text =
|
||||
builtins.readFile ./waybar-style.css;
|
||||
|
||||
sane.user.fs.".config/sxmo/conky.conf".symlink.target = let
|
||||
battery_estimate = pkgs.static-nix-shell.mkBash {
|
||||
@@ -249,6 +299,7 @@ in
|
||||
in pkgs.substituteAll {
|
||||
src = ./conky-config;
|
||||
bat = "${battery_estimate}/bin/battery_estimate";
|
||||
weather = "timeout 20 ${pkgs.sane-weather}/bin/sane-weather";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -283,16 +334,14 @@ in
|
||||
};
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.greeter == "sway") {
|
||||
(lib.mkIf (cfg.greeter == "sway-gtkgreet") {
|
||||
services.greetd = {
|
||||
enable = true;
|
||||
# borrowed from gui/sway
|
||||
settings.default_session.command =
|
||||
let
|
||||
# start sway and have it construct the gtkgreeter
|
||||
sway-as-greeter = pkgs.writeShellScriptBin "sway-as-greeter" ''
|
||||
${pkgs.sway}/bin/sway --debug --config ${sway-config-into-gtkgreet} > /var/log/sway/sway-as-greeter.log 2>&1
|
||||
'';
|
||||
sway-as-greeter = runWithLogger "sway-as-greeter" "${pkgs.sway}/bin/sway --debug --config ${sway-config-into-gtkgreet}";
|
||||
# (config file for the above)
|
||||
sway-config-into-gtkgreet = pkgs.writeText "greetd-sway-config" ''
|
||||
exec "${gtkgreet-launcher}"
|
||||
@@ -303,12 +352,60 @@ in
|
||||
# so that command must exist on the specific user's path who is logging in. it doesn't need to exist system-wide.
|
||||
${pkgs.greetd.gtkgreet}/bin/gtkgreet --layer-shell --command sxmo_winit.sh
|
||||
'';
|
||||
in "${sway-as-greeter}/bin/sway-as-greeter";
|
||||
in "${sway-as-greeter}";
|
||||
};
|
||||
})
|
||||
|
||||
sane.fs."/var/log/sway" = {
|
||||
dir.acl.mode = "0777";
|
||||
wantedBeforeBy = [ "greetd.service" "display-manager.service" ];
|
||||
(lib.mkIf (cfg.greeter == "greetd-sway-phog") {
|
||||
services.greetd = {
|
||||
enable = true;
|
||||
# borrowed from gui/sway
|
||||
settings.default_session.command =
|
||||
let
|
||||
# start sway and have it construct the greeter
|
||||
sway-as-greeter = runWithLogger "sway-as-greeter" "${pkgs.sway}/bin/sway --debug --config ${sway-config-into-phog}";
|
||||
# (config file for the above)
|
||||
sway-config-into-phog = pkgs.writeText "greetd-sway-config" ''
|
||||
exec "${pkgs.phog}/libexec/phog"
|
||||
'';
|
||||
in "${sway-as-greeter}";
|
||||
};
|
||||
# phog locates sxmo_winit.sh via <env>/share/wayland-sessions
|
||||
environment.pathsToLink = [ "/share/wayland-sessions" ];
|
||||
|
||||
# persisting fontconfig & mesa_shader_cache improves start time from like 6 minutes to 1 minute
|
||||
# TODO: this should apply to any greetd implementation
|
||||
users.users.greeter.home = "/var/lib/greeter";
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "greeter"; group = "greeter"; path = "/var/lib/greeter/.cache/fontconfig"; }
|
||||
{ user = "greeter"; group = "greeter"; path = "/var/lib/greeter/.cache/mesa_shader_cache"; }
|
||||
];
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.greeter == "greetd-phog") {
|
||||
services.greetd = {
|
||||
enable = true;
|
||||
|
||||
# launch directly: but stdout/stderr gets dropped
|
||||
# settings.default_session.command = "${pkgs.phog}/bin/phog";
|
||||
|
||||
# wrapper to launch phog and redirect logs to system journal.
|
||||
settings.default_session.command = let
|
||||
launch-phog = runWithLogger "phog" "${pkgs.phog}/bin/phog";
|
||||
in "${launch-phog}";
|
||||
};
|
||||
environment.pathsToLink = [ "/share/wayland-sessions" ];
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.greeter == "greetd-sxmo") {
|
||||
services.greetd = {
|
||||
enable = true;
|
||||
settings.default_session = {
|
||||
command = let
|
||||
launch-sxmo = runWithLogger "sxmo" "${cfg.package}/bin/sxmo_winit.sh";
|
||||
in "${launch-sxmo}";
|
||||
user = "colin";
|
||||
};
|
||||
};
|
||||
})
|
||||
|
||||
@@ -322,16 +419,6 @@ in
|
||||
# '';
|
||||
# }];
|
||||
# services.xserver.enable = true;
|
||||
|
||||
# services.greetd = {
|
||||
# enable = true;
|
||||
# settings = {
|
||||
# default_session = {
|
||||
# command = "${cfg.package}/bin/sxmo_winit.sh";
|
||||
# user = "colin";
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
]))
|
||||
];
|
||||
}
|
||||
|
@@ -1,10 +1,8 @@
|
||||
# Default config for sway
|
||||
# configversion: 5eff902ecca36b4e75567322335cc81c
|
||||
#
|
||||
# Copy this to ~/.config/sway/config and edit it to your liking.
|
||||
#
|
||||
# Read `man 5 sway` for a complete reference.
|
||||
|
||||
# TODO: use stock sxmo config & override via /etc/sway/config.d/*
|
||||
# especially, this will let me avoid issues around `configversion`
|
||||
|
||||
### Variables
|
||||
#
|
||||
# Mod4 = Logo key
|
||||
@@ -39,18 +37,41 @@ mode "menu" {
|
||||
bindsym --input-device=1:1:1c21800.lradc XF86AudioMute exec nothing # just a placeholder for "menu" mode
|
||||
}
|
||||
|
||||
hide_edge_borders smart
|
||||
default_border pixel 1
|
||||
titlebar_border_thickness 1
|
||||
# XX YY distance from edge of window title to edge of text
|
||||
# the YY distance here determines the heigh of the overall title
|
||||
titlebar_padding 12 1
|
||||
title_align center
|
||||
|
||||
# tabbed windows by default
|
||||
workspace_layout tabbed
|
||||
|
||||
### tab colors (#border #background #text [#indicator #childBorder])
|
||||
# focused & unfocused are the main interest
|
||||
# urgent is used when an inactive window wants attention (e.g. terminal rings a bell)
|
||||
# colors are synchronized with waybar and mpv
|
||||
client.focused #1f5e54 #418379 #ffffff
|
||||
client.focused_inactive #1f5e54 #5f676a #ffffff
|
||||
client.unfocused #1f5e54 #1f554c #b4b4b4
|
||||
client.urgent #ff8080 #ff8080 #ffffff
|
||||
|
||||
### Key bindings
|
||||
#
|
||||
# Basics:
|
||||
#
|
||||
input * xkb_options compose:ralt
|
||||
|
||||
# Start a terminal
|
||||
bindsym $mod+Return exec $term
|
||||
|
||||
# Launch appmenu
|
||||
bindsym $mod+p exec sxmo_appmenu.sh
|
||||
bindsym $mod+Shift+p exec sxmo_appmenu.sh sys
|
||||
|
||||
# Launch scripts menu
|
||||
bindsym $mod+i exec sxmo_appmenu.sh scripts
|
||||
# Wm menu switcher
|
||||
bindsym $mod+i exec sxmo_wmmenu.sh windowswitcher
|
||||
|
||||
# Kill focused window
|
||||
bindsym $mod+Shift+q kill
|
||||
@@ -142,7 +163,7 @@ mode "menu" {
|
||||
bindsym $mod+e layout toggle split
|
||||
|
||||
# Make the current focus fullscreen
|
||||
# bindsym $mod+f fullscreen
|
||||
bindsym $mod+f fullscreen
|
||||
|
||||
# Toggle the current focus between tiling and floating mode
|
||||
bindsym $mod+Shift+space floating toggle
|
||||
@@ -152,6 +173,12 @@ mode "menu" {
|
||||
|
||||
# Move focus to the parent container
|
||||
bindsym $mod+a focus parent
|
||||
|
||||
# Manual locker
|
||||
bindsym $mod+g exec sxmo_hook_locker.sh
|
||||
|
||||
# Shutdown
|
||||
bindsym $mod+t exec sxmo_appmenu.sh power
|
||||
#
|
||||
# Scratchpad:
|
||||
#
|
||||
@@ -172,16 +199,16 @@ mode "resize" {
|
||||
# right will grow the containers width
|
||||
# up will shrink the containers height
|
||||
# down will grow the containers height
|
||||
bindsym $left resize shrink width 10px
|
||||
bindsym $down resize grow height 10px
|
||||
bindsym $up resize shrink height 10px
|
||||
bindsym $right resize grow width 10px
|
||||
bindsym $left resize shrink width 30px
|
||||
bindsym $down resize grow height 30px
|
||||
bindsym $up resize shrink height 30px
|
||||
bindsym $right resize grow width 30px
|
||||
|
||||
# Ditto, with arrow keys
|
||||
bindsym Left resize shrink width 10px
|
||||
bindsym Down resize grow height 10px
|
||||
bindsym Up resize shrink height 10px
|
||||
bindsym Right resize grow width 10px
|
||||
bindsym Left resize shrink width 30px
|
||||
bindsym Down resize grow height 30px
|
||||
bindsym Up resize shrink height 30px
|
||||
bindsym Right resize grow width 30px
|
||||
|
||||
# Return to default mode
|
||||
bindsym Return mode "default"
|
||||
@@ -207,16 +234,30 @@ bar {
|
||||
statusline #ffffff
|
||||
background #323232
|
||||
inactive_workspace #32323200 #32323200 #5c5c5c
|
||||
font "Sxmo"
|
||||
font "Sxmo 10"
|
||||
}
|
||||
}
|
||||
|
||||
for_window [app_id="pinentry-.*"] floating true
|
||||
for_window [app_id="foot" title=".*sxmo/modem/.*/draft.txt.*"] resize set height 25
|
||||
for_window [title="megapixels"] inhibit_idle open
|
||||
|
||||
default_border pixel 3
|
||||
titlebar_border_thickness 3
|
||||
hide_edge_borders smart
|
||||
# Need playerctl installed and running
|
||||
bindsym XF86AudioPlay exec playerctl play-pause
|
||||
bindsym XF86AudioStop exec playerctl stop
|
||||
bindsym XF86AudioNext exec playerctl next
|
||||
bindsym XF86AudioPrev exec playerctl previous
|
||||
|
||||
bindsym XF86MonBrightnessUp exec sxmo_brightness.sh up
|
||||
bindsym XF86MonBrightnessDown exec sxmo_brightness.sh down
|
||||
|
||||
bindsym Print exec sxmo_screenshot.sh
|
||||
|
||||
bindsym button2 kill
|
||||
|
||||
bindswitch lid:on exec sxmo_wm.sh dpms on
|
||||
bindswitch lid:off exec sxmo_wm.sh dpms off
|
||||
|
||||
|
||||
include /etc/sway/config.d/*
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
[
|
||||
{ # TOP BAR
|
||||
layer = "top";
|
||||
height = 32;
|
||||
height = 26;
|
||||
|
||||
modules-left = [ "sway/workspaces" ];
|
||||
modules-center = [ ];
|
||||
|
64
hosts/modules/gui/sxmo/waybar-style.css
Normal file
64
hosts/modules/gui/sxmo/waybar-style.css
Normal file
@@ -0,0 +1,64 @@
|
||||
/* style docs: https://github.com/Alexays/Waybar/wiki/Styling */
|
||||
/* defaults: https://github.com/Alexays/Waybar/blob/master/resources/style.css */
|
||||
|
||||
window#waybar {
|
||||
background-color: #418379;
|
||||
border-bottom: 0px solid #1f5e54;
|
||||
color: #ffffff;
|
||||
transition-property: background-color;
|
||||
transition-duration: .2s;
|
||||
}
|
||||
|
||||
.modules-right {
|
||||
/* workspace buttons (LHS) get padding between it and the screen edge */
|
||||
/* replicate that same padding for whatever's on the RHS (i.e. the clock) */
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#workspaces button {
|
||||
padding: 0 5px;
|
||||
background-color: #418379;
|
||||
color: #ffffff;
|
||||
/* Use box-shadow instead of border so the text isn't offset */
|
||||
box-shadow: inset 0 0px #1f5e54;
|
||||
/* Avoid rounded borders under each workspace name */
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
#workspaces button:hover {
|
||||
/* i don't want hover effects, so reset this styling to be the same as default button */
|
||||
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
||||
background: inherit;
|
||||
box-shadow: inherit;
|
||||
text-shadow: inherit;
|
||||
}
|
||||
|
||||
#workspaces button.focused {
|
||||
background-color: #63a89c;
|
||||
box-shadow: inset 0 0px #2c8274;
|
||||
}
|
||||
|
||||
#workspaces button.urgent {
|
||||
background-color: #e64291;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
to {
|
||||
background-color: #ffffff;
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
|
||||
#tray {
|
||||
background-color: #418379;
|
||||
}
|
||||
|
||||
#tray > .passive {
|
||||
-gtk-icon-effect: dim;
|
||||
}
|
||||
|
||||
#tray > .needs-attention {
|
||||
-gtk-icon-effect: highlight;
|
||||
background-color: #e64291;
|
||||
}
|
@@ -24,8 +24,7 @@ in
|
||||
(mkIf cfg {
|
||||
sane.programs.docsets.enableFor.system = true;
|
||||
sane.programs.ldd-aarch64.enableFor.user.colin = true;
|
||||
# TODO: migrate this to `sane.user.programs.zeal.enable = true`
|
||||
sane.programs.zeal.enableFor.user.colin = true;
|
||||
# sane.programs.zeal.enableFor.user.colin = true;
|
||||
})
|
||||
];
|
||||
}
|
||||
|
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 3520653,
|
||||
"content_type": "application/xml; charset=utf-8",
|
||||
"description": "There\u2019s a reason the History Channel has produced hundreds of documentaries about Hitler but only a few about Dwight D. Eisenhower. Bad guys (and gals) are eternally fascinating. Behind the Bastards dives in past the Cliffs Notes of the worst humans in history and exposes the bizarre realities of their lives. Listeners will learn about the young adult novels that helped Hitler form his monstrous ideology, the founder of Blackwater\u2019s insane quest to build his own Air Force, the bizarre lives of the sons and daughters of dictators and Saddam Hussein\u2019s side career as a trashy romance novelist.",
|
||||
"favicon": "",
|
||||
"favicon_data_uri": "",
|
||||
"hubs": [],
|
||||
"is_podcast": true,
|
||||
"is_push": false,
|
||||
"item_count": 689,
|
||||
"last_updated": "2023-08-15T04:00:00+00:00",
|
||||
"score": 8,
|
||||
"self_url": "https://www.omnycontent.com/d/playlist/e73c998e-6e60-432f-8610-ae210140c5b1/e5f91208-cc7e-4726-a312-ae280140ad11/d64f756d-6d5e-4fae-b24f-ae280140ad36/podcast.rss",
|
||||
"site_name": "",
|
||||
"site_url": "",
|
||||
"title": "Behind the Bastards",
|
||||
"url": "https://omnycontent.com/d/playlist/e73c998e-6e60-432f-8610-ae210140c5b1/E5F91208-CC7E-4726-A312-AE280140AD11/D64F756D-6D5E-4FAE-B24F-AE280140AD36/podcast.rss",
|
||||
"velocity": 0.35,
|
||||
"version": "rss20"
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 3673943,
|
||||
"content_type": "application/xml; charset=utf-8",
|
||||
"description": "*** Named a best podcast of 2021 by Time, Vulture, Esquire and The Atlantic. ***\nEach Tuesday and Friday, Ezra Klein invites you into a conversation on something that matters. How do we address climate change if the political system fails to act? Has the logic of markets infiltrated too many aspects of our lives? What is the future of the Republican Party? What do psychedelics teach us about consciousness? What does sci-fi understand about our present that we miss? Can our food system be just to humans and animals alike?\n\nListen to this podcast in New York Times Audio, our new iOS app for news subscribers. Download now at nytimes.com/audioapp",
|
||||
"favicon": "",
|
||||
"favicon_data_uri": "",
|
||||
"hubs": [
|
||||
"https://simplecast.superfeedr.com/"
|
||||
],
|
||||
"is_podcast": true,
|
||||
"is_push": true,
|
||||
"item_count": 255,
|
||||
"last_updated": "2023-07-25T09:00:00+00:00",
|
||||
"score": 24,
|
||||
"self_url": "https://feeds.simplecast.com/82FI35Px",
|
||||
"site_name": "",
|
||||
"site_url": "",
|
||||
"title": "The Ezra Klein Show",
|
||||
"url": "https://feeds.simplecast.com/82FI35Px",
|
||||
"velocity": 0.275,
|
||||
"version": "rss20"
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 1410917,
|
||||
"content_type": "application/xml; charset=utf-8",
|
||||
"description": "An audio guide to the world\u2019s strange, incredible, and wondrous places. Co-founder Dylan Thuras and a neighborhood of Atlas Obscura reporters explore a new wonder every day, Monday through Thursday. In under 15 minutes, they\u2019ll take you to an incredible place, and along the way, you\u2019ll meet some fascinating people and hear their stories. Our theme and end credit music is composed by Sam Tyndall.",
|
||||
"favicon": "",
|
||||
"favicon_data_uri": "",
|
||||
"hubs": [
|
||||
"https://simplecast.superfeedr.com/"
|
||||
],
|
||||
"is_podcast": true,
|
||||
"is_push": true,
|
||||
"item_count": 571,
|
||||
"last_updated": "2023-07-27T04:05:00+00:00",
|
||||
"score": 24,
|
||||
"self_url": "https://feeds.simplecast.com/xKJ93w_w",
|
||||
"site_name": "",
|
||||
"site_url": "",
|
||||
"title": "The Atlas Obscura Podcast",
|
||||
"url": "https://feeds.simplecast.com/xKJ93w_w",
|
||||
"velocity": 0.647,
|
||||
"version": "rss20"
|
||||
}
|
21
modules/data/feeds/sources/mindingourway.com/default.json
Normal file
21
modules/data/feeds/sources/mindingourway.com/default.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 133561,
|
||||
"content_type": "text/xml; charset=utf-8",
|
||||
"description": "to the heavens",
|
||||
"favicon": "https://mindingourway.com/favicon.png",
|
||||
"favicon_data_uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAAAnAAAAJwEqCZFPAAAE2klEQVR42u2dSasUVxxHW4zGiFmbrxHliU8NKMaF+AWcn34IcQIFA4pK4rAJZKcrNyKIOOCnUBwS5wnUlaIicbaXVYfC/7td1dXV3nPh7N6rvsNp+NH3f2/1et95m5iYmAJfAjYW6dkUwKYANgWwjcuCzwS3QCTAv6D0PGdYAWwKYFMAW2cF2AS4wDfBf4B/v6GIM6wANgWwKYCtMwv+A2CI++YPPdMQxlCoAAqgAAqgAArQTQE2Ay4gQ97MAEOhAiiAAiiAAijAeIS+aLMnqcDDUKgACqAACqAACtBZAaIiz9ugJMw0nm8oVAAFUAAFUAAF6MaCpxZ5lkJcA5+fWmBiKFQABVAABVAABWhGABZwtLoAAwhoKFQABVAABVCAsRCg38lFRTrQn1kgqcizhf5FBSidDoX9PkwWUQAFUAAFUICsBfgADoGfirTQwS2AE8wQ1uoEdz0Ucr36HAYfiyiAAiiAAihA1gJ8BFGBxW9FhjChUQFGo5s9DfR/pEWk/WcsBgyh7E/pC68ACqAACqAAWQvAdgXwAZ/AUTC3SAObPd883NkBAVIFTj2oMgcwpEdf4Gug1BRAARRAARQgXwEqPpCHL7eD/wE/8AH4HfD5dwCft65Ir+ON/a0YD8fL+VgB7gE+7x3geiUdjFEABVAABVCAfAWYxgB/Bamh8TIYq9A3hFB4AUSh7jpot6BHARRAARRAAbIVoGLAs8E+8B5EL23aW6Q35q0/hl0gGj8FOAhKPwx1YYAKoAAKoAAKkKcAQ5gAhsYjIGmzqYXx/QgOABbdRuPfXaSX4TdAARRAARRAAcZTgIofQqLNnnMgCo08iLGsSAvjY2PBRRTqLoLv6zJqBVAABVAABchZgFpFnn0WgNTNplqhsSLU7QdRqOPBDB7cGGoRqQIogAIogAIoQIsLnlrkubbIAM9vukh1ObgLUoswS5dcTWN8tYpIFUABFEABFEABRihAdEHCE9DoACpC41UQhcYo1PGHmfJFi/X7z4sxn4Juh0IFUAAFUAAFyEaAAX7IIPfBHjC/yAD9mwRvQdQ/bkatKjJAf34BewFDatS/0W4WKYACKIACKEDOAkQvTHgEUgVhKDsLVoM/QBTq2J/U0PgXWAPY39SiUC7wYzDaUKgACqAACqAA2QhQsRkTvSBhPZgBVoIzIHXCIk4BvlCBh1v/AXU/n+PheDkfnK+RXkatAAqgAAqgAFkLMAXYgc+AFxqwAGMe4AL8DeouAEPceUBBUi+0iDgJKODPgPPFy6E538MNhQqgAAqgAAqQjQAVoY8vjWo6FD0D0f+fACyqfAXq9vc1WAtShX0BKGjd/tYLhQqgAAqgAAqQswDRy5tvAG7OHAPR5cepMASlhjZurjwEqQUjUSirG1qPA853s4dLFUABFEABFCAbAeoe7qwowoxeXhwN+EvLNL2AqZdBR3/PBV4K6m0WKYACKIACKEDOAmwFfAB/CPoTNB3yJO0LwyLV6KBJORQqgAIogAIoQM4CRJcijTqkRbwBl8BOsAQsArz0iS925ObQuAlUCoUKoAAKoAAKkLUAo+7QS8AXSOwAXMCkixmHcFCGP4SxvxwPxzvS+VcABVAABVAABajBc3AabAO82HG8XorU/CVbCwHni/PJ+VYABVAABVAABRiEr4mwVmPpPyoAAAAAAElFTkSuQmCC",
|
||||
"hubs": [],
|
||||
"is_podcast": false,
|
||||
"is_push": false,
|
||||
"item_count": 15,
|
||||
"last_updated": "2019-12-21T19:28:00+00:00",
|
||||
"score": 16,
|
||||
"self_url": "https://mindingourway.com/rss/",
|
||||
"site_name": "Minding our way",
|
||||
"site_url": "https://mindingourway.com",
|
||||
"title": "Minding our way",
|
||||
"url": "https://mindingourway.com/rss/",
|
||||
"velocity": 0.01,
|
||||
"version": "rss20"
|
||||
}
|
21
modules/data/feeds/sources/omegataupodcast.net/default.json
Normal file
21
modules/data/feeds/sources/omegataupodcast.net/default.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 805006,
|
||||
"content_type": "application/rss+xml; charset=utf-8",
|
||||
"description": "Wissenschaft und Technik im Kopfhoerer / Science and Engineering in your Headphones",
|
||||
"favicon": "http://omegataupodcast.net/omegatau_fav.png",
|
||||
"favicon_data_uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsTAAALEwEAmpwYAAACC2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjE8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlBob3RvbWV0cmljSW50ZXJwcmV0YXRpb24+MjwvdGlmZjpQaG90b21ldHJpY0ludGVycHJldGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KD0UqkwAAB2BJREFUWAmdV1tvVFUU/ubMmQud0k6vUzrTUsq1twSMmKI+idBIJJFECPAACS9NTLzwYkzwof/BoC8QE30xITHSSIgQVEyEUsDUVkRgqC200HtnmPvd9e1hD6cNmOpuTvc+a6+9Lt9ea501tmPHjhXwH4dpmpiamsKePXvQ29urThcKBdhsNqRSKfT19WF8fBzl5eXIZrOKblVBXj6GYcCMRqPWvZIwLihQP1Ymp9OJJ0+eKOFWul7TiFgsBrvdrnieKbQhny/A6XDA5XYrGeKMqayhIu0FaXzP5/PI5XKKroVog2gEPXjeoGLK4JwXT52yRiaFnKBBmeUuD1ZXVWFmdhYGBXNwQx8KhUJ4/PgxpqenEQ6HkUgkkE6nlTfJZFLRL1y4gOehR1lzc3O4desWJh89wq3hYeSEFqnyYcTmxl1HOUYNF/I0LpeH7dChQ2JDAQ6BhbBR6IYNG9Dc3Iza2lp1j/RWI0WvGhsbkclkUFFRgS1btlBnCT0iNjIyogxWCBFZ4U390o9CLAyBDXaHC8OOOlz+MwiTyik8Eomgrq4OBw4cQCAQQFlZmaITcj2IksvlwubNmzWpNGs+Grh169YSXS0EfvxwAkj8KIFVB5S14nb4FXzz+z2YPECIGxoacPDgQdTU1Kh7pzLCrq+IgkjjO73XiDwvDsjHUZDZEOfSiSRs6RQcCaEZcu/2ekQliDEVgknL4/E4enp6FOQ0hkN7pGetiDNpmq6Yl/3TvMKkdvhuFMQICTdFKcRRyGaAcBomoec9NjU1qRzWwukpD2pP6RX3iBhpKxmS7aJQYkDOpau3wXRWSww4YXdXoMzux47dEvj0eP369WCgEXIqoXIq4vudO3cwMTGhgpMBxthgkdm+fbtCjLxWNHjm9OnTWFhYUPGSkfcKrxfhRBOiERamnFxxAe4KJ1o8Lpj0sr6+XjlEYRwUSGXnz5/HuXPnlCLSNP3UqVPo7OzEyZMnVcASHQ07ZQwNDWFwcFBly/z8PDo6OpCX85NT07gZnESDtxId6/w4c+ZnmPSI6aSV0wCm5NjYGC5fvqwOc08HFo1obW3FwMAALl26hKNHj5ZQ00YykDdu3IjKykr1VFdXIytIzEjet3jc8NdXoVz0dnYGiga4pSxSCQXoMStViilHxSyt1j2WYaasLkTcszrALOHVrlq1Ss38HsSkgN2fmGHaIZnJKoQTKQlCMtFjqwCuqcTqtdUAwr3cKG04Z/JqfvJyHQpFpfJJbDnkvcgEQ+gGvWTAWQcNYGqSbjXMykOhL9pbzheNxZFKZ+AwjSVnGHGSUaYKIKswrgmjDiyrwJWuKYMOhMIROJxSVe2G+jAtcVUsEB1FiLRg7RmzQK/13kpnrTyZTCH49xRsRhEt0vnHoaNNVcKVCl4pH51KC+ShyDyyTFFbsaCtckveC+LsB5RzYkzpc7xcOBk49Lx8/9/eGbx/BSeQSWfhcrAnyKsClErJV1HSMSNZQTSowSTUfNGDa3pAS3UW6L2VzDw/vxDG9GIMgUafKJdT8kzNzOL2H9eViGTbS6ivqynqYbBRkdVTrlma/48BPMOo95a7lRNj98bx7jtv4dMTn5TaM5dcRX//9/j6qy9hMp9ZKJiOetAAVsjlhul9PVuN1jQioM4JwS6RD4SkqfGgvb1Ns6j515orajZYsZanHAWvXr16ydUsOS0vvKYXIcQ+oKi8eEo7x+vmx4gjK9WQw2AbxqJDpdZYYD2nAtKYz1TIh3x8Zxn2eDxKiPUcy7rf34gH92eV52RobgoovuLZYiNL1DkMNpksu9bBzTVr1qC7uxtj8lGiMvYN+mGz6vP5sGnTptIxCqfBNHL3rp1Cn8J3315U+907upfw8SX+tPFRPSEFtre3K++0IGbB3r171VdtcnJSNaxUQDj5IWJf6JXvPK9Pf0t4lqOnZzfOnu3H3XtB7HpzJ1rXrVNI6n3KmZ6eEc5y2Pbt21fw+/04cuSIgpZwkpEzvWE2EBHeHwdpOkWJXltbWyle9DmtSB2Qf1omf5QYUhUXFxfxxq63izr48ykYDKouh/dH6/hQCGcGKQ3gu6ZRsb7DmRl6UmxY9Tkq5FrP+lwuV7z3gYFrGLp5RRCsgL2rq6uPHrHtamlpQVVVtSh6JpDCtSAtVNOIBtOYGUPjqUgXNrFBzhW7Y/KTl8E7OjqK3vc+gm9Nk/BKtki71Mc7ZCASCfYHjG4K5H1zjw+N1Gtei14TiRs3bmJOWq/GRr/iozLrQ8PYK167NogPj3+MB5OzqK/1Ii3xYzt8+DCbVnUwGo1JMxlCTW2dtF3r0BTww1vlRZkYZYoR/KgQBQpjZkwL/MHgKC7+dAXjwWG8/8FxvP7aq/AHGuVMsZBFohE8fDiBq1ev4YvPP0NTaxfWBnyIxhOwi6G2/fv3F5LSGsXjKdU0RGIJzMzJb8OHIbmHuIDnRlmtBxVl8vNMIMxIIVmIJJGRDgfyq89d48XmtT4F72/Xh4W2NKWF8HRUY9vLbYKqU1IwqbohbvwDi4As2ZCohrEAAAAASUVORK5CYII=",
|
||||
"hubs": [],
|
||||
"is_podcast": true,
|
||||
"is_push": false,
|
||||
"item_count": 100,
|
||||
"last_updated": "2023-06-16T09:08:08+00:00",
|
||||
"score": 10,
|
||||
"self_url": "https://omegataupodcast.net/feed/mp3/",
|
||||
"site_name": "omega tau science & engineering podcast",
|
||||
"site_url": "https://omegataupodcast.net",
|
||||
"title": "omega tau science & engineering podcast",
|
||||
"url": "https://omegataupodcast.net/feed/mp3/",
|
||||
"velocity": 0.062,
|
||||
"version": "rss20"
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 26554,
|
||||
"content_type": "application/rss+xml; charset=utf-8",
|
||||
"description": "Welcome to the SharkBytes Podcast. We will discuss all things Wireshark, as well as topics from the world of Packet Analysis and SharkFest, our packet analysis and developer conference. We'll be hanging out with interesting people from diverse backgrounds in the industry and we'll also learn why the truth is always in the packets. Support this podcast: <a href=\"https://podcasters.spotify.com/pod/show/sharkbytes/support\" rel=\"payment\">https://podcasters.spotify.com/pod/show/sharkbytes/support</a>",
|
||||
"favicon": "",
|
||||
"favicon_data_uri": "",
|
||||
"hubs": [
|
||||
"https://pubsubhubbub.appspot.com/"
|
||||
],
|
||||
"is_podcast": true,
|
||||
"is_push": true,
|
||||
"item_count": 8,
|
||||
"last_updated": "2023-06-29T15:00:00+00:00",
|
||||
"score": 2,
|
||||
"self_url": "https://anchor.fm/s/d4b7d750/podcast/rss",
|
||||
"site_name": "",
|
||||
"site_url": "",
|
||||
"title": "SharkBytes Podcast",
|
||||
"url": "https://anchor.fm/s/d4b7d750/podcast/rss",
|
||||
"velocity": 0.025,
|
||||
"version": "rss20"
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 87719,
|
||||
"content_type": "application/xml; charset=utf-8",
|
||||
"description": "Useful Idiots is an informative and irreverent politics podcast.",
|
||||
"favicon": "",
|
||||
"favicon_data_uri": "",
|
||||
"hubs": [],
|
||||
"is_podcast": true,
|
||||
"is_push": false,
|
||||
"item_count": 20,
|
||||
"last_updated": "2023-08-15T14:54:32+00:00",
|
||||
"score": 14,
|
||||
"self_url": "https://usefulidiots.substack.com/feed",
|
||||
"site_name": "Useful Idiots | Substack",
|
||||
"site_url": "https://usefulidiots.substack.com",
|
||||
"title": "Useful Idiots",
|
||||
"url": "https://usefulidiots.substack.com/feed",
|
||||
"velocity": 0.655,
|
||||
"version": "rss20"
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 232527,
|
||||
"content_type": "application/xml; charset=utf-8",
|
||||
"description": "Not wrong political opinions.",
|
||||
"favicon": "",
|
||||
"favicon_data_uri": "",
|
||||
"hubs": [],
|
||||
"is_podcast": true,
|
||||
"is_push": false,
|
||||
"item_count": 67,
|
||||
"last_updated": "2023-08-09T21:26:55+00:00",
|
||||
"score": -10,
|
||||
"self_url": "https://feeds.acast.com/public/shows/6490a2ce7ded6b001126fa5b",
|
||||
"site_name": "",
|
||||
"site_url": "",
|
||||
"title": "We're Not Wrong",
|
||||
"url": "https://feeds.acast.com/public/shows/6490a2ce7ded6b001126fa5b",
|
||||
"velocity": 0.145,
|
||||
"version": "rss20"
|
||||
}
|
@@ -9,6 +9,10 @@ let
|
||||
pname = "ensure-dir";
|
||||
src = ./.;
|
||||
};
|
||||
ensure-file = pkgs.static-nix-shell.mkBash {
|
||||
pname = "ensure-file";
|
||||
src = ./.;
|
||||
};
|
||||
ensure-symlink = pkgs.static-nix-shell.mkBash {
|
||||
pname = "ensure-symlink";
|
||||
src = ./.;
|
||||
@@ -33,6 +37,10 @@ let
|
||||
type = types.nullOr dirEntry;
|
||||
default = null;
|
||||
};
|
||||
file = mkOption {
|
||||
type = types.nullOr (fileEntryFor name);
|
||||
default = null;
|
||||
};
|
||||
symlink = mkOption {
|
||||
type = types.nullOr (symlinkEntryFor name);
|
||||
default = null;
|
||||
@@ -81,6 +89,8 @@ let
|
||||
default-acl
|
||||
(lib.mkIf (config.dir != null)
|
||||
(sane-lib.filterNonNull config.dir.acl))
|
||||
(lib.mkIf (config.file != null)
|
||||
(sane-lib.filterNonNull config.file.acl))
|
||||
(lib.mkIf (config.symlink != null)
|
||||
(sane-lib.filterNonNull config.symlink.acl))
|
||||
];
|
||||
@@ -88,6 +98,7 @@ let
|
||||
# actually generate the item
|
||||
generated.command = lib.mkMerge [
|
||||
(lib.mkIf (config.dir != null) [ "${ensure-dir}/bin/ensure-dir" name ])
|
||||
(lib.mkIf (config.file != null) [ "${ensure-file}/bin/ensure-file" name config.file.copyFrom ])
|
||||
(lib.mkIf (config.symlink != null) [ "${ensure-symlink}/bin/ensure-symlink" name config.symlink.target ])
|
||||
];
|
||||
|
||||
@@ -124,6 +135,26 @@ let
|
||||
# takes no special options
|
||||
dirEntry = types.submodule propagatedGenerateMod;
|
||||
|
||||
fileEntryFor = path: types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
inherit (propagatedGenerateMod.options) acl;
|
||||
text = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
description = "create a file with this text, overwriting anything that was there before.";
|
||||
};
|
||||
copyFrom = mkOption {
|
||||
type = types.coercedTo types.package toString types.str;
|
||||
description = "populate the file based on the content at this provided path";
|
||||
};
|
||||
};
|
||||
config = {
|
||||
copyFrom = lib.mkIf (config.text != null) (
|
||||
pkgs.writeText (path-lib.leaf path) config.text
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
symlinkEntryFor = path: types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
inherit (propagatedGenerateMod.options) acl;
|
||||
|
16
modules/fs/ensure-file
Executable file
16
modules/fs/ensure-file
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash
|
||||
|
||||
set -e
|
||||
|
||||
cpto="$1"
|
||||
cpfrom="$2"
|
||||
|
||||
# -f flag in case the destination perms were set to 000
|
||||
# --no-dereference in case the destination already exists as a symlink
|
||||
# however, "no-dereference" has the edge case of copying `cpfrom` to `cpto`
|
||||
# when `cpto` already exists as a symlink to `cpfom`:
|
||||
# "cp: <cpto> and <cpfrom> are the same file"
|
||||
# use `--remove-destination` for that
|
||||
cp --no-dereference -f "$cpfrom" "$cpto" \
|
||||
|| cp --no-dereference --remove-destination "$cpfrom" "$cpto"
|
@@ -46,13 +46,15 @@ let
|
||||
upnpServiceForPort = port: portCfg:
|
||||
lib.mkIf portCfg.visibleTo.wan {
|
||||
"upnp-forward-${port}" = {
|
||||
description = "forward port ${port} from upstream gateway to this host";
|
||||
serviceConfig.Type = "oneshot";
|
||||
description = "forward port ${port} (${portCfg.description}) from upstream gateway to this host";
|
||||
restartTriggers = [(builtins.toJSON portCfg)];
|
||||
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "upnp-forwards.target" ];
|
||||
script =
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
TimeoutSec = "6min";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "3min";
|
||||
ExecStart =
|
||||
let
|
||||
portFwd = "${pkgs.sane-scripts.ip-port-forward}/bin/sane-ip-port-forward";
|
||||
forwards = lib.flatten [
|
||||
@@ -64,6 +66,10 @@ let
|
||||
${lib.escapeShellArgs forwards}
|
||||
'';
|
||||
};
|
||||
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "upnp-forwards.target" ];
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
@@ -120,9 +126,9 @@ in
|
||||
systemd.timers.upnp-forwards = {
|
||||
wantedBy = [ "network.target" ];
|
||||
timerConfig = {
|
||||
OnStartupSec = "1min";
|
||||
OnStartupSec = "75s";
|
||||
OnCalendar = cfg.upnpRenewInterval;
|
||||
RandomizeDelaySec = "2min";
|
||||
RandomizeDelaySec = "30s";
|
||||
Unit = "upnp-forwards.target";
|
||||
};
|
||||
};
|
||||
|
@@ -231,8 +231,10 @@ in
|
||||
(lib.mapAttrs' (pkgName: _pkg: { name = "cacert.${pkgName}"; value = {}; }) pkgs.cacert)
|
||||
(lib.mapAttrs' (pkgName: _pkg: { name = "gnome.${pkgName}"; value = {}; }) pkgs.gnome)
|
||||
(lib.mapAttrs' (pkgName: _pkg: { name = "libsForQt5.${pkgName}"; value = {}; }) pkgs.libsForQt5)
|
||||
(lib.mapAttrs' (pkgName: _pkg: { name = "mate.${pkgName}"; value = {}; }) pkgs.mate)
|
||||
(lib.mapAttrs' (pkgName: _pkg: { name = "plasma5Packages.${pkgName}"; value = {}; }) pkgs.plasma5Packages)
|
||||
(lib.mapAttrs' (pkgName: _pkg: { name = "python3Packages.${pkgName}"; value = {}; }) pkgs.python3Packages)
|
||||
(lib.mapAttrs' (pkgName: _pkg: { name = "sane-scripts.${pkgName}"; value = {}; }) pkgs.sane-scripts)
|
||||
(lib.mapAttrs' (pkgName: _pkg: { name = "sway-contrib.${pkgName}"; value = {}; }) pkgs.sway-contrib)
|
||||
];
|
||||
}
|
||||
|
@@ -2,6 +2,8 @@
|
||||
{
|
||||
imports = [
|
||||
./dyn-dns.nix
|
||||
./eg25-control.nix
|
||||
./eg25-manager.nix
|
||||
./kiwix-serve.nix
|
||||
./mautrix-signal.nix
|
||||
./nixserve.nix
|
||||
|
27
modules/services/eg25-control.nix
Normal file
27
modules/services/eg25-control.nix
Normal file
@@ -0,0 +1,27 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.sane.services.eg25-control;
|
||||
in
|
||||
{
|
||||
options.sane.services.eg25-control = with lib; {
|
||||
enable = mkEnableOption "Quectel EG25 modem configuration scripts. alternative to eg25-manager";
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.eg25-control;
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.eg25-control = {
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${cfg.package}/bin/eg25-control --power-on --enable-gps --dump-debug-info --verbose";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "60s";
|
||||
};
|
||||
after = [ "ModemManager.service" ];
|
||||
wants = [ "ModemManager.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
};
|
||||
}
|
69
modules/services/eg25-manager.nix
Normal file
69
modules/services/eg25-manager.nix
Normal file
@@ -0,0 +1,69 @@
|
||||
# eg25-manager: <https://gitlab.com/mobian1/eg25-manager>
|
||||
# - used by sxmo, in <configs/default_hooks/sxmo_hook_restart_modem_daemons.sh>
|
||||
# - requires modemmanager (ModemManager.service)
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.sane.services.eg25-manager;
|
||||
eg25-config-toml = pkgs.writeText "eg25-manager-config.toml" ''
|
||||
# config here is applied *on top of* the per-device configs shipped by eg25-manager.
|
||||
# these values take precedence, but there's no need to redefine things if we don't want them changed
|
||||
[at]
|
||||
uart = "/dev/ttyUSB2"
|
||||
'';
|
||||
in
|
||||
{
|
||||
options.sane.services.eg25-manager = with lib; {
|
||||
enable = mkEnableOption "Quectel EG25 modem manager service";
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.eg25-manager;
|
||||
};
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
# eg25-manager package ships udev rules *and* a systemd service.
|
||||
# for that reason, i think it needs to be on the system path for the systemd service to be enabled.
|
||||
services.udev.packages = [ cfg.package ];
|
||||
|
||||
# but actually, let's define our own systemd service so that we can control config
|
||||
systemd.services.eg25-manager = {
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${cfg.package}/bin/eg25-manager --config ${eg25-config-toml}";
|
||||
ExecStartPre = pkgs.writeShellScript "unload-modem-power" ''
|
||||
# see issue: <https://gitlab.com/mobian1/eg25-manager/-/issues/38>
|
||||
${pkgs.kmod}/bin/modprobe -r modem_power && echo "WARNING: kernel configured with CONFIG_MODEM_POWER=y, may be incompatible with eg25-manager" || true
|
||||
'';
|
||||
|
||||
Restart = "on-failure";
|
||||
RestartSec = "60s"; # can make this more frequent once stable?
|
||||
|
||||
# sandboxing (taken from the service file shipped by eg25-manager):
|
||||
# TODO: this is too strict and breaks access to e.g. /dev/ttyUSB2!
|
||||
# ProtectControlGroups = true;
|
||||
# ProtectHome = true;
|
||||
# ProtectSystem = "strict";
|
||||
# RestrictSUIDSGID = true;
|
||||
# PrivateTmp = true;
|
||||
# MemoryDenyWriteExecute = true;
|
||||
# PrivateMounts = true;
|
||||
# NoNewPrivileges = true;
|
||||
# CapabilityBoundingSet = [ "" ];
|
||||
# LockPersonality = true;
|
||||
};
|
||||
before = [ "ModemManager.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
# systemd.packages = [ pkgs.eg25-manager ];
|
||||
# systemd.services.eg25-manager.wantedBy = [ "multi-user.target" ];
|
||||
# systemd.services.prepare-eg25-manager = {
|
||||
# description = "unload megi's modem_power module to provide gpio access to eg25-manager";
|
||||
# serviceConfig.Type = "oneshot";
|
||||
# wantedBy = [ "eg25-manager.service" ];
|
||||
# before = [ "eg25-manager.service" ];
|
||||
# script = ''
|
||||
# ${pkgs.kmod}/bin/modprobe -r modem_power && echo "WARNING: kernel configured with CONFIG_MODEM_POWER=y, may be incompatible with eg25-manager" || true
|
||||
# '';
|
||||
# };
|
||||
};
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
|
||||
index d188ecdda55..69174ba7dc7 100644
|
||||
--- a/pkgs/top-level/all-packages.nix
|
||||
+++ b/pkgs/top-level/all-packages.nix
|
||||
@@ -26607,7 +26607,8 @@ with pkgs;
|
||||
|
||||
tinyalsa = callPackage ../os-specific/linux/tinyalsa { };
|
||||
|
||||
- inherit (callPackage ../os-specific/linux/alsa-project { })
|
||||
+ alsa-project = callPackage ../os-specific/linux/alsa-project { };
|
||||
+ inherit (alsa-project)
|
||||
alsa-firmware
|
||||
alsa-lib
|
||||
alsa-oss
|
@@ -15,9 +15,15 @@
|
||||
patchedFlakeFor = system: import "${patchedPkgsFor system}/flake.nix";
|
||||
patchedFlakeOutputsFor = system:
|
||||
(patchedFlakeFor system).outputs { inherit self; };
|
||||
|
||||
extractBuildPlatform = nixosSystemArgs:
|
||||
let
|
||||
firstMod = builtins.head nixosSystemArgs.modules;
|
||||
in
|
||||
firstMod.nixpkgs.buildPlatform or nixosSystemArgs.system;
|
||||
in
|
||||
{
|
||||
lib.nixosSystem = args: (patchedFlakeOutputsFor args.system).lib.nixosSystem args;
|
||||
lib.nixosSystem = args: (patchedFlakeOutputsFor (extractBuildPlatform args)).lib.nixosSystem args;
|
||||
|
||||
legacyPackages = builtins.mapAttrs
|
||||
(system: _:
|
||||
|
@@ -19,6 +19,26 @@ let
|
||||
// (if title != null then { name = title; } else {})
|
||||
);
|
||||
in [
|
||||
# (fetchpatch' {
|
||||
# # disabled, at least until the PR is updated to use `pkg-config` instead of `pkgconfig`.
|
||||
# # the latter is an alias, which breaks nix-index
|
||||
# title = "phog: init at 0.1.3";
|
||||
# prUrl = "https://github.com/NixOS/nixpkgs/pull/251249";
|
||||
# hash = "sha256-e38Z7sO7xDQHzE9UOfbptc6vJuONE5eP9JFp2Nzx53E=";
|
||||
# })
|
||||
|
||||
(fetchpatch' {
|
||||
title = "nixos/update-users-groups: fix cross compilation";
|
||||
prUrl = "https://github.com/NixOS/nixpkgs/pull/251850";
|
||||
hash = "sha256-uqx9sJ1zkwys9Ur35iXY3gZKVb52wlnBGkhBB5sc6WQ=";
|
||||
})
|
||||
|
||||
# (fetchpatch' {
|
||||
# # TODO: check back in on this around 2023-10-01
|
||||
# title = "libkiwix: 12.0.0 -> 12.1.0";
|
||||
# prUrl = "https://github.com/NixOS/nixpkgs/pull/246700";
|
||||
# hash = "sha256-LyTkWNgG1mynCdckKm3Hj9ifzLemyrhJ9BFVaPppwgw=";
|
||||
# })
|
||||
|
||||
# (fetchpatch' {
|
||||
# # XXX: doesn't cleanly apply; fetch `firefox-pmos-mobile` branch from my git instead
|
||||
@@ -58,15 +78,15 @@ in [
|
||||
# hash = "sha256-oQEM3EZfAOmfZzDu9faCqyOFZsdHYGn1mVBgkxt68Zg=";
|
||||
# })
|
||||
(fetchpatch' {
|
||||
saneCommit = "c3becd7cdf144d85d12e2e76663e9549a0536efd";
|
||||
title = "firefox-pmos-mobile: init at 4.0.2";
|
||||
saneCommit = "c3becd7cdf144d85d12e2e76663e9549a0536efd";
|
||||
hash = "sha256-NRh2INUMA2K7q8zioqKA7xwoqg7v6sxpuJRpTG5IP1Q=";
|
||||
})
|
||||
|
||||
# splatmoji: init at 1.2.0
|
||||
(fetchpatch' {
|
||||
saneCommit = "75149039b6eaf57d8a92164e90aab20eb5d89196";
|
||||
title = "splatmoji: init at 1.2.0";
|
||||
prUrl = "https://github.com/NixOS/nixpkgs/pull/211874";
|
||||
saneCommit = "75149039b6eaf57d8a92164e90aab20eb5d89196";
|
||||
hash = "sha256-jDXYLlXaEBKMrZ2dgxc6ucrcX/5dtqoIIKw+Ay19vlc=";
|
||||
})
|
||||
|
||||
@@ -77,7 +97,7 @@ in [
|
||||
# hash = "sha256-eTwEbVULYjmOW7zUFcTUqvBZqUFjHTKFhvmU2m3XQeo=";
|
||||
# })
|
||||
|
||||
./2022-12-19-i2p-aarch64.patch
|
||||
# ./2022-12-19-i2p-aarch64.patch
|
||||
|
||||
# fix for CMA memory leak in mesa: <https://gitlab.freedesktop.org/mesa/mesa/-/issues/8198>
|
||||
# fixed in mesa 22.3.6: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21330/diffs>
|
||||
@@ -87,18 +107,15 @@ in [
|
||||
# upgrade to 22.3.6 instead
|
||||
# ./2023-02-28-mesa-22.3.6.patch
|
||||
|
||||
# fix qt6.qtbase and qt6.qtModule to cross-compile.
|
||||
# unfortunately there's some tangle that makes that difficult to do via the normal `override` facilities
|
||||
./2023-03-03-qtbase-cross-compile.patch
|
||||
|
||||
# let ccache cross-compile
|
||||
# TODO: why doesn't this apply?
|
||||
# ./2023-03-04-ccache-cross-fix.patch
|
||||
|
||||
# 2023-04-11: bambu-studio: init at 01.06.02.04
|
||||
(fetchpatch' {
|
||||
title = "bambu-studio: init at 01.06.02.04";
|
||||
prUrl = "https://github.com/NixOS/nixpkgs/pull/206495";
|
||||
hash = "sha256-XG4hvHXmP/wgiKuNRCAfttaGLrg/6mAOr+YvAVmycKQ=";
|
||||
hash = "sha256-Z+IOzd+bnxjg6neF1YcrRDTzz9GhJfbbj0Wa8yTXsa4=";
|
||||
})
|
||||
|
||||
# (fetchpatch' {
|
||||
@@ -140,44 +157,76 @@ in [
|
||||
# hash = "sha256-MNG8C0OgdPnFQ8SF2loiEhXJuP2z4n9pkXr8Zh4X7QU=";
|
||||
# })
|
||||
|
||||
# 2023-08-06: conky wayland + cross compilation patches.
|
||||
# nix path-info shows clean
|
||||
# branch is wip-conky-cross2 on servo
|
||||
# factoring out those feature abstractions was possibly overkill.
|
||||
# the manual wayland-scanner patching is unfortunate, but within
|
||||
# acceptable norms of the existing package.
|
||||
(fetchpatch' {
|
||||
title = "conky: support wayland";
|
||||
# saneCommit = "82978099c3a0d5fb4925351da1b0e2598503dc6c";
|
||||
# hash = "sha256-lnDGEDhmeOIXfFnizEIVUiUzI7nMvpoCERbdjhR+Bto=";
|
||||
saneCommit = "3ad928e20b498444e3a106b182e09317cea9a11f";
|
||||
hash = "sha256-lvIASvQWVFbjHsQwO2EhEBUTSq1UkHvriaZZ2iS0ulU=";
|
||||
title = "conky: factor out an abstraction for feature flags";
|
||||
saneCommit = "3ddf13038d6df90ad0db36a41d55e4077818a3e9";
|
||||
hash = "sha256-CjLzndFEH1Ng9CqKX8gxCJ6n/wFv5U/sHnQE0FMYILc=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "conky: simplify the features even more";
|
||||
saneCommit = "1c4aa404743f1ae7d5b95f18a96c4057ca251a96";
|
||||
hash = "sha256-0zhiw9siIkFgFW4sow+X88NBEa3ggCe1t1HJ5xFH4ac=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "conky: support cross compilation";
|
||||
saneCommit = "01e607e11c7e5bbbfe6ad132fb72394ec29dab0a";
|
||||
hash = "sha256-Bm/XFLvE7gEyLPlBWNSAcU3qwwqKLIRdpoe0/1aHUho=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "conky: add wayland support";
|
||||
saneCommit = "84c51f67e02ebc7f118fd3171bd10f1978d4f1e6";
|
||||
hash = "sha256-gRYbkzCe3q1R7X/FeOcz/haURQkeAfmED1/ZQlCCdWE=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "conky: remove no-op sed patch";
|
||||
saneCommit = "e8b19984a2858ca24b7e8f5acd20be8b7dfe1af0";
|
||||
hash = "sha256-K3mG1kcyB7sQZ7ZRCdlinNsV6mCcl3eIUI2ldSmcbJE=";
|
||||
})
|
||||
|
||||
# (fetchpatch' {
|
||||
# title = "hare-json: init at unstable-2023-01-31";
|
||||
# saneCommit = "260f9c6ac4e3564acbceb46aa4b65fbb652f8e23";
|
||||
# hash = "sha256-bjLKANo0+zaxugJlEk1ObPqRHWOKptD7dXB+/xzsYqA=";
|
||||
# title = "gtk3: compile schemas even when cross compiling";
|
||||
# saneCommit = "5ee69670071f583bdffe2718dc46763fa1698f92";
|
||||
# hash = "sha256-ZX3lY63qUW2XuwCoxffbLYoFxckDImKy+S8mqlYJcvk=";
|
||||
# })
|
||||
# (fetchpatch' {
|
||||
# title = "gtk4: compile schemas even when cross compiling";
|
||||
# saneCommit = "7a1c5e3a5d1ff82c8afa659c7f903d5309d5de6a";
|
||||
# hash = "sha256-Tz8NBcIqGE9rCqbOrixgbvApYDEAHWCg4lZbklL/xXc=";
|
||||
# })
|
||||
(fetchpatch' {
|
||||
title = "gtk{3,4}: compile schemas even when cross compiling";
|
||||
prUrl = "https://github.com/NixOS/nixpkgs/pull/247844";
|
||||
hash = "sha256-1CsjLgMvX0Lx500UDzal5HZi78hb7zBcb+AlNPF6NvA=";
|
||||
})
|
||||
|
||||
# (fetchpatch' {
|
||||
# title = "hare-json: init at unstable-2023-02-25";
|
||||
# saneCommit = "6c88c2b087755e8f60c9f61c6361dec2f7a38155";
|
||||
# hash = "sha256-9TTlhwLDZESaFC02k4+YER+NvoNVPz9wFYV79+Dmuxs=";
|
||||
# })
|
||||
# (fetchpatch' {
|
||||
# title = "hare-ev: init at unstable-2022-12-29";
|
||||
# saneCommit = "4058200a407c86c5d963bc49b608aa1a881cbbf2";
|
||||
# hash = "sha256-wm1aavbCfxBhcOXh4EhFO4u0LrA9tNr0mSczHUK8mQU=";
|
||||
# saneCommit = "1761049e9b8620091f29bf864ecbbf204b0c56b4";
|
||||
# hash = "sha256-H2ekBJx/iRX8E4uVmdEyaAZVhqeM25QbwvQ9Ki7fMQ0=";
|
||||
# })
|
||||
# (fetchpatch' {
|
||||
# title = "bonsai: init at 1.0.0";
|
||||
# saneCommit = "65d37294d939384e8db400ea82d25ce8b4ad6897";
|
||||
# hash = "sha256-2easgOtJfzvVcz/3nt3lo1GKLLotrM4CkBRyTgIAhHU=";
|
||||
# saneCommit = "507252828934c73c7cffe255dae237c041676c27";
|
||||
# hash = "sha256-HwycOd3v4IifdQqQmMP6w14g0E/T9RAjAw41AsUZQoc=";
|
||||
# })
|
||||
(fetchpatch' {
|
||||
# includes hare-json and hare-ev as pre-reqs
|
||||
title = "bonsai: init at 1.0.0";
|
||||
prUrl = "https://github.com/NixOS/nixpkgs/pull/233892";
|
||||
hash = "sha256-HqtDgisbR0xOUY4AxhzEv+2JJMPyQMawKo6nbd9pxhE=";
|
||||
hash = "sha256-HaTr7GBCfK1I2e7K4k2dUGZ6hZf4PwtEFobLaSz262M=";
|
||||
})
|
||||
|
||||
# make alsa-project members overridable
|
||||
./2023-05-31-toplevel-alsa.patch
|
||||
|
||||
# qt6 qtwebengine: specify `python` as buildPackages
|
||||
./2023-06-02-qt6-qtwebengine-cross.patch
|
||||
|
||||
# Jellyfin: don't build via `libsForQt5.callPackage`
|
||||
./2023-06-06-jellyfin-no-libsForQt5-callPackage.patch
|
||||
|
||||
# pin to a pre-0.17.3 release
|
||||
# removing this and using stock 0.17.3 (also 0.17.4) causes:
|
||||
# INFO lemmy_server::code_migrations: No Local Site found, creating it.
|
||||
@@ -189,24 +238,18 @@ in [
|
||||
# related: <https://github.com/NixOS/nixpkgs/issues/236890#issuecomment-1585030861>
|
||||
# ./2023-06-10-lemmy-downgrade.patch
|
||||
|
||||
# (fetchpatch' {
|
||||
# title = "gpodder: wrap with missing `xdg-utils` path";
|
||||
# saneCommit = "10d0ac11bc083cbcf0d6340950079b3888095abf";
|
||||
# hash = "sha256-cu8L30ZiUJnWFGRR/SK917TC7TalzpGkurGkUAAxl54=";
|
||||
# })
|
||||
|
||||
(fetchpatch' {
|
||||
title = "koreader: 2023.04 -> 2023.05.1";
|
||||
saneCommit = "a5c471bd263abe93e291239e0078ac4255a94262";
|
||||
hash = "sha256-38sND/UNRj5WAYYKpzdrRBIOK4UAT14RzbIv49KmNNw=";
|
||||
})
|
||||
|
||||
(fetchpatch' {
|
||||
# TODO: send this upstream!
|
||||
title = "mepo: 1.1 -> 1.1.2";
|
||||
saneCommit = "eee68d7146a6cd985481cdd8bca52ffb204de423";
|
||||
hash = "sha256-uNerTwyFzivTU+o9bEKmNMFceOmy2AKONfKJWI5qkzo=";
|
||||
})
|
||||
# (fetchpatch' {
|
||||
# title = "mepo: 1.1 -> 1.1.2";
|
||||
# prUrl = "https://github.com/NixOS/nixpkgs/pull/247866";
|
||||
# saneCommit = "eee68d7146a6cd985481cdd8bca52ffb204de423";
|
||||
# hash = "sha256-uNerTwyFzivTU+o9bEKmNMFceOmy2AKONfKJWI5qkzo=";
|
||||
# })
|
||||
|
||||
(fetchpatch' {
|
||||
title = "gthumb: make the webservices feature be optional";
|
||||
@@ -221,6 +264,107 @@ in [
|
||||
hash = "sha256-rD0es4uUbaLMrI9ZB2HzPmRLyu/ixNBLAFyDJtFHNko=";
|
||||
})
|
||||
|
||||
# (fetchpatch' {
|
||||
# title = "perlPackages.FileBaseDir: 0.08 -> 0.09";
|
||||
# saneCommit = "acc990b04bbe8c99587eadccc65f100c326ec204";
|
||||
# hash = "sha256-8s789GGARJH1i088OGBjGGnL2l5m8Q+iBPS213QsS6A=";
|
||||
# })
|
||||
# (fetchpatch' {
|
||||
# title = "perlPackages.TestFile: 1.443 -> 1.993";
|
||||
# saneCommit = "6cf080fb51d034f9c2ddd60cef7dee7d041afd3e";
|
||||
# hash = "sha256-fAZpduh3JZeFixJ4yX0wkh/GRp0gYKsTT+XkNdpK7CU=";
|
||||
# })
|
||||
(fetchpatch' {
|
||||
# TODO: split this apart for easier reviewing:
|
||||
# - perlPackages.TestFile 1.443 -> 1.993
|
||||
# - perlPackages.FileBaseDir 0.08 -> 0.09
|
||||
title = "xdg-utils: enable cross compilation";
|
||||
prUrl = "https://github.com/NixOS/nixpkgs/pull/246954";
|
||||
saneCommit = "b7aa5e0c1ec06723cf1594de192703a65be21497";
|
||||
hash = "sha256-5iYzyjVlye7mhwhlZOHucVod/aPT3OrXolC9jAnB544=";
|
||||
})
|
||||
# (fetchpatch' {
|
||||
# # N.B.: duplicates outstanding, merged PR: <https://github.com/NixOS/nixpkgs/pull/246362>
|
||||
# # - also a stale, approved PR: <https://github.com/NixOS/nixpkgs/pull/245761>
|
||||
# title = "libgudev: support cross compilation";
|
||||
# saneCommit = "4dc30718fe01e9dbed4ffc2ff375148da218e86b";
|
||||
# hash = "sha256-Nb2LphSyv8Dayqfwqfua0eKtNzsnaf7PC/KYUhIvnT8=";
|
||||
# })
|
||||
(fetchpatch' {
|
||||
title = "blueman: support cross compilation";
|
||||
saneCommit = "e070195bdf213dffb0164574397b6a7417f81c9e";
|
||||
hash = "sha256-6JnIJCVBbV4tmFinX7Qv2wO2AThrgxrnyb9T4Ov6p5w=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "tracker-miners: support cross compilation";
|
||||
saneCommit = "24b062309ea8baa2d8303c0610c9ec7b8c399e8b";
|
||||
hash = "sha256-Jj+1z2DeCEY+DqI1J4vYjYJwDDMRcA93CqpZSXzG0wE=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "clapper: support cross compilation";
|
||||
saneCommit = "8a171b49aca406f8220f016e56964b3fae53a3df";
|
||||
hash = "sha256-R11IYatGhSXxZnJxJid519Oc9Kh56D9NT2/cxf2CLuM=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "gcr_4: support cross compilation";
|
||||
saneCommit = "a8c3d69236fa67382a8c18cc1ef0f34610fd3275";
|
||||
hash = "sha256-UnLqkkpXxBKaqlsoD1jUIigZkxgLtNpjmMHOx10HpfE=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "networkmanager-openvpn: support cross compilation";
|
||||
saneCommit = "6f53c267fbeb2ff543f075032a7e73af2d4bcb9e";
|
||||
hash = "sha256-gq9AyKH7/k2ZVSZ3jpPJPt3uAM+CllXQnaiC1tE1r/8=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "WIP: networkmanager-sstp: support cross compilation";
|
||||
saneCommit = "6de63fe320406ec9a509db721c52b3894a93bda2";
|
||||
hash = "sha256-EY3bQuv/80JbpquUJhc89CcYAgN9A9KkpsSitw/684I=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "WIP: networkmanager-l2tp: support cross compilation";
|
||||
saneCommit = "7a4191c570b0e5a1ab257222c26a4a2ecb945037";
|
||||
hash = "sha256-FiPJhHGqZ8MFwLY+1t6HgbK6ndomFSYUKvApvrikRHE=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "gtkspell2: support cross compilation";
|
||||
saneCommit = "56348833b4411e9fe2016c24c7fc4af1e3c1d28a";
|
||||
hash = "sha256-0RMxouOBw7SUmQDLB2qGey714DaM0AOvZlZ5nB+Lkc4=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "libgnt: 2.14.1 -> 2.14.3";
|
||||
prUrl = "https://github.com/NixOS/nixpkgs/pull/246937";
|
||||
saneCommit = "ecd423195d72036a209912868ad02742cb4b6fcd";
|
||||
# hash = "sha256-u4V/UHNtd2c3+FppuJ5LeLNSV8ZaLe8cqj8HmcW2a/0=";
|
||||
hash = "sha256-cGhJSby0K+e1hKPdPZjLFRKvwjGaTbq/kb6Fxj2v8g8=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
# TODO: send for review once thie libgnt patch above is merged
|
||||
title = "pidgin: support cross compilation";
|
||||
saneCommit = "caacbcc54e217f5ee9281422777a7f712765f71a";
|
||||
hash = "sha256-PDCp4GOm6hWcRob4kz7qXZfxAF6YbYrESx9idoS3e/s=";
|
||||
})
|
||||
|
||||
# (fetchpatch' {
|
||||
# # doesn't cleanly apply. TODO: see if this cross compiles now, thanks to <https://github.com/NixOS/nixpkgs/pull/234615>
|
||||
# title = "nixos/dconf: support cross compilation";
|
||||
# prUrl = "https://github.com/NixOS/nixpkgs/pull/249093";
|
||||
# saneCommit = "08f7cdebc58eeaa62cb349dab57db3be7a0c073d";
|
||||
# hash = "sha256-gqHUGeTQnr0f99gqEdd+VANLkWO+joLxz5I0RSarznE=";
|
||||
# })
|
||||
|
||||
(fetchpatch' {
|
||||
title = "playerctl: support cross compilation";
|
||||
prUrl = "https://github.com/NixOS/nixpkgs/pull/249512";
|
||||
saneCommit = "67df31a8984ab3067af5b65446d2808b0aedadc6";
|
||||
hash = "sha256-qY0bjMoFneC5VJ467TeiuOycLYNaVO7Xo/0fCauDZAM=";
|
||||
})
|
||||
(fetchpatch' {
|
||||
title = "libgweather: enable introspection on cross builds";
|
||||
prUrl = "https://github.com/NixOS/nixpkgs/pull/251956";
|
||||
saneCommit = "7a2d0a90cc558ea71dfc78356e61b0675b995634";
|
||||
hash = "sha256-tjO19dXVUrD+V+YpD7z3iWSgNyOirG70HuQ+c+0fZYA=";
|
||||
})
|
||||
|
||||
# (fetchpatch' {
|
||||
# # N.B.: compiles, but runtime error on launch suggestive of some module not being shipped
|
||||
# title = "matrix-appservice-irc: 0.38.0 -> 1.0.0";
|
||||
@@ -234,4 +378,14 @@ in [
|
||||
./02-rpi4-uboot.patch
|
||||
|
||||
# ./07-duplicity-rich-url.patch
|
||||
|
||||
# fix qt6.qtbase and qt6.qtModule to cross-compile.
|
||||
# unfortunately there's some tangle that makes that difficult to do via the normal `override` facilities
|
||||
# ./2023-03-03-qtbase-cross-compile.patch
|
||||
|
||||
# qt6 qtwebengine: specify `python` as buildPackages
|
||||
# ./2023-06-02-qt6-qtwebengine-cross.patch
|
||||
|
||||
# Jellyfin: don't build via `libsForQt5.callPackage`
|
||||
# ./2023-06-06-jellyfin-no-libsForQt5-callPackage.patch
|
||||
]
|
||||
|
@@ -5,6 +5,7 @@
|
||||
final: prev:
|
||||
let
|
||||
pkgs = import ./pkgs.nix;
|
||||
preferences = import ./preferences.nix;
|
||||
disable-flakey-tests = import ./disable-flakey-tests.nix;
|
||||
optimizations = import ./optimizations.nix;
|
||||
cross = import ./cross.nix;
|
||||
@@ -18,6 +19,7 @@ let
|
||||
in
|
||||
renderOverlays [
|
||||
pkgs
|
||||
preferences
|
||||
disable-flakey-tests
|
||||
(ifCross optimizations)
|
||||
(ifCross cross)
|
||||
|
2067
overlays/cross.nix
2067
overlays/cross.nix
File diff suppressed because it is too large
Load Diff
@@ -4,200 +4,87 @@
|
||||
# - they assume a particular architecture (e.g. x86) whereas i compile on multiple archs.
|
||||
# - they assume too much about their environment and fail under qemu.
|
||||
#
|
||||
(next: prev: {
|
||||
ell = prev.ell.overrideAttrs (_upstream: {
|
||||
# 2023/02/11
|
||||
# fixes "TEST FAILED in get_random_return_callback at unit/test-dbus-message-fds.c:278: !l_dbus_message_get_error(message, ((void *)0), ((void *)0))"
|
||||
# 2023/04/06
|
||||
# fixes "test-cipher: unit/test-cipher.c:102: test_aes_ctr: Assertion `!r' failed."
|
||||
# unclear *why* this test fails.
|
||||
(next: prev:
|
||||
let
|
||||
dontCheck = p: p.overrideAttrs (_: {
|
||||
doCheck = false;
|
||||
doInstallCheck = false;
|
||||
});
|
||||
aarch64Only = f: p: p.overrideAttrs (upstream:
|
||||
next.lib.optionalAttrs
|
||||
(p.stdenv.targetPlatform.system == "aarch64-linux")
|
||||
(f upstream)
|
||||
);
|
||||
emulatedOnly = f: p: p.overrideAttrs (upstream:
|
||||
next.lib.optionalAttrs
|
||||
(p.stdenv.targetPlatform.system == "aarch64-linux" && p.stdenv.buildPlatform.system == "aarch64-linux")
|
||||
(f upstream)
|
||||
);
|
||||
dontCheckAarch64 = aarch64Only (_: {
|
||||
# only `dontCheck` if the package is being built for aarch64
|
||||
doCheck = false;
|
||||
doInstallCheck = false;
|
||||
});
|
||||
dontCheckEmulated = emulatedOnly (_: {
|
||||
doCheck = false;
|
||||
});
|
||||
# fish = prev.fish.overrideAttrs (_upstream: {
|
||||
# # 2023/02/28
|
||||
# # The following tests FAILED:
|
||||
# # 177 - sigint.fish (Failed)
|
||||
# # 241 - torn_escapes.py (Failed)
|
||||
# doCheck = false;
|
||||
# });
|
||||
# gjs = prev.gjs.overrideAttrs (_upstream: {
|
||||
# # 2023/01/30: one test times out. probably flakey test that only got built because i patched mesa.
|
||||
# doCheck = false;
|
||||
# });
|
||||
# gssdp = prev.gssdp.overrideAttrs (_upstream: {
|
||||
# # 2023/02/11
|
||||
# # fixes "ERROR:../tests/test-regression.c:429:test_ggo_7: assertion failed (error == NULL): Failed to set multicast interfaceProtocol not available (gssdp-error, 1)"
|
||||
# doCheck = false;
|
||||
# });
|
||||
# gupnp = prev.gupnp.overrideAttrs (_upstream: {
|
||||
# # 2023/02/22
|
||||
# # fixes "Bail out! ERROR:../tests/test-bugs.c:205:test_bgo_696762: assertion failed (error == NULL): Failed to set multicast interfaceProtocol not available (gssdp-erro>"
|
||||
# doCheck = false;
|
||||
# });
|
||||
# json-glib = prev.json-glib.overrideAttrs (_upstream: {
|
||||
# # 2023/02/11
|
||||
# # fixes: "15/15 json-glib:docs / doc-check TIMEOUT 30.52s killed by signal 15 SIGTERM"
|
||||
# doCheck = false;
|
||||
# });
|
||||
# lapack-reference = prev.lapack-reference.overrideAttrs (_upstream: {
|
||||
# # 2023/02/11: test timeouts
|
||||
# # > The following tests FAILED:
|
||||
# # > 93 - LAPACK-xlintstz_ztest_in (Timeout)
|
||||
# # > 98 - LAPACK-xeigtstz_svd_in (Timeout)
|
||||
# # > 99 - LAPACK-xeigtstz_zec_in (Timeout)
|
||||
# doCheck = false;
|
||||
# });
|
||||
# libadwaita = prev.libadwaita.overrideAttrs (_upstream: {
|
||||
# # 2023/01/30: one test times out. probably flakey test that only got built because i patched mesa.
|
||||
# doCheck = false;
|
||||
# });
|
||||
# libsecret = prev.libsecret.overrideAttrs (_upstream: {
|
||||
# # 2023/01/30: one test times out. probably flakey test that only got built because i patched mesa.
|
||||
# doCheck = false;
|
||||
# });
|
||||
# libuv = prev.libuv.overrideAttrs (_upstream: {
|
||||
# # 2023/02/11
|
||||
# # 2 tests fail:
|
||||
# # - not ok 261 - tcp_bind6_error_addrinuse
|
||||
# # - not ok 267 - tcp_bind_error_addrinuse_listen
|
||||
# doCheck = false;
|
||||
# });
|
||||
libwacom = prev.libwacom.overrideAttrs (_upstream: {
|
||||
# 2023/03/30
|
||||
# "libwacom:all / pytest TIMEOUT"
|
||||
in {
|
||||
# 2023/07/27
|
||||
# 4 tests fail when building `host-pkgs.moby.emulated.elfutils`
|
||||
# it might be enough to only disable checks when targeting aarch64, which could reduce rebuilds?
|
||||
elfutils = dontCheckAarch64 prev.elfutils;
|
||||
|
||||
# 2023/07/31
|
||||
# tests just hang after mini-record-2
|
||||
# only for binfmt-emulated aarch64 -> aarch64 build
|
||||
gnutls = dontCheckEmulated prev.gnutls;
|
||||
|
||||
# 2023/07/31
|
||||
# tests fail (not timeout), but only when cross compiling, and not on servo (so, due to binfmt?)
|
||||
gupnp = dontCheck prev.gupnp;
|
||||
|
||||
# hangs during checkPhase (or maybe it just takes 20-30 minutes)
|
||||
# libqmi = dontCheckEmulated prev.libqmi;
|
||||
|
||||
# 2023/07/28
|
||||
# "7/7 libwacom:all / pytest TIMEOUT 30.36s killed by signal 15 SIGTERM"
|
||||
# N.B.: it passes on x86_64, but only if it's not CPU starved (i.e. nix build with -j1 if it fails)
|
||||
libwacom = aarch64Only (_: {
|
||||
doCheck = false;
|
||||
mesonFlags = [ "-Dtests=disabled" ];
|
||||
});
|
||||
|
||||
# llvmPackages_12 =
|
||||
# let
|
||||
# tools = prev.llvmPackages_12.tools.extend (self: super: {
|
||||
# libllvm = super.libllvm.overrideAttrs (upstream: {
|
||||
# # 2023/02/21: fix: "FAIL: LLVM-Unit :: ExecutionEngine/MCJIT/./MCJITTests/MCJITTest.return_global (2857 of 42084)"
|
||||
# # - nix log /nix/store/6vydavlxh1gvs0vmrkcx9qp67g3h7kcz-llvm-12.0.1.drv
|
||||
# # - wanted by sequoia, rav1e, rustc-1.66.1 (is this right?)
|
||||
# doCheck = false;
|
||||
# # upstream sets this with `rec`; TODO: have upstream refer to the final overrideAttrs version of the derivation instead of using rec.
|
||||
# cmakeFlags = next.lib.remove "-DLLVM_BUILD_TESTS=ON" upstream.cmakeFlags;
|
||||
# });
|
||||
# });
|
||||
# in
|
||||
# # see <nixpkgs:pkgs/development/compilers/llvm/12/default.nix>
|
||||
# # - we copy their strategy / attrset mutilation
|
||||
# prev.llvmPackages_12 // { inherit tools; } // tools;
|
||||
|
||||
# llvmPackages_14 =
|
||||
# let
|
||||
# tools = prev.llvmPackages_14.tools.extend (self: super: {
|
||||
# libllvm = super.libllvm.overrideAttrs (upstream: {
|
||||
# # 2023/02/21: fix: "FAIL: LLVM-Unit :: ExecutionEngine/MCJIT/./MCJITTests/MCJITMultipleModuleTest.two_module_global_variables_case (43769 of 46988)"
|
||||
# # - nix log /nix/store/ib2yw6sajnhlmibxkrn7lj7chllbr85h-llvm-14.0.6.drv
|
||||
# # - wanted by clang-11-12-LLVMgold-path, compiler-rt-libc-12.0.1, clang-wrapper-12.0.1 (is this right?)
|
||||
# doCheck = false;
|
||||
# # upstream sets this with `rec`; TODO: have upstream refer to the final overrideAttrs version of the derivation instead of using rec.
|
||||
# cmakeFlags = next.lib.remove "-DLLVM_BUILD_TESTS=ON" upstream.cmakeFlags;
|
||||
# });
|
||||
# });
|
||||
# in
|
||||
# # see <nixpkgs:pkgs/development/compilers/llvm/14/default.nix>
|
||||
# # - we copy their strategy / attrset mutilation
|
||||
# prev.llvmPackages_14 // { inherit tools; } // tools;
|
||||
|
||||
# llvmPackages_15 =
|
||||
# let
|
||||
# tools = prev.llvmPackages_15.tools.extend (self: super: {
|
||||
# libllvm = super.libllvm.override {
|
||||
# # 2023/02/21: fix: "FAIL: LLVM-Unit :: ExecutionEngine/MCJIT/./MCJITTests/..."
|
||||
# # llvm15 passes doCheck as a call arg, so we don't need to set cmakeFlags explicitly as in previous versions
|
||||
# doCheck = false;
|
||||
# };
|
||||
# });
|
||||
# in
|
||||
# prev.llvmPackages_15 // { inherit tools; } // tools;
|
||||
|
||||
# modemmanager = prev.modemmanager.overrideAttrs (_upstream: {
|
||||
# # 2023/02/25
|
||||
# # "ERROR:test-modem-helpers.c:257:test_cmgl_response: assertion failed: (list != NULL)"
|
||||
# doCheck = false;
|
||||
# doInstallCheck = false; # tests are run during install check??
|
||||
# });
|
||||
}) prev.libwacom;
|
||||
|
||||
pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
|
||||
(py-next: py-prev: {
|
||||
# ipython = py-prev.ipython.overridePythonAttrs (upstream: {
|
||||
# # > FAILED IPython/core/tests/test_debugger.py::test_xmode_skip - pexpect.exceptions.TIMEOUT: Timeout exceeded.
|
||||
# # > FAILED IPython/core/tests/test_debugger.py::test_decorator_skip - pexpect.exceptions.TIMEOUT: Timeout exceeded.
|
||||
# # > FAILED IPython/core/tests/test_debugger.py::test_decorator_skip_disabled - pexpect.exceptions.TIMEOUT: Timeout exceeded.
|
||||
# # > FAILED IPython/core/tests/test_debugger.py::test_decorator_skip_with_breakpoint - pexpect.exceptions.TIMEOUT: Timeout exceeded.
|
||||
# # > FAILED IPython/core/tests/test_debugger.py::test_where_erase_value - pexpect.exceptions.TIMEOUT: Timeout exceeded.
|
||||
# # > FAILED IPython/terminal/tests/test_debug_magic.py::test_debug_magic_passes_through_generators - pexpect.exceptions.TIMEOUT: Timeout exceeded.
|
||||
# # > FAILED IPython/terminal/tests/test_embed.py::test_nest_embed - pexpect.exceptions.TIMEOUT: Timeout exceeded.
|
||||
# disabledTestPaths = upstream.disabledTestPaths or [] ++ [
|
||||
# "IPython/core/tests/test_debugger.py"
|
||||
# "IPython/terminal/tests/test_debug_magic.py"
|
||||
# "IPython/terminal/tests/test_embed.py"
|
||||
# ];
|
||||
# });
|
||||
pyarrow = py-prev.pyarrow.overridePythonAttrs (upstream: {
|
||||
# 2023/04/02
|
||||
# disabledTests = upstream.disabledTests ++ [ "test_generic_options" ];
|
||||
disabledTestPaths = upstream.disabledTestPaths or [] ++ [
|
||||
disabledTestPaths = (upstream.disabledTestPaths or []) ++ [
|
||||
"pyarrow/tests/test_flight.py"
|
||||
];
|
||||
});
|
||||
# pytest-xdist = py-prev.pytest-xdist.overridePythonAttrs (upstream: {
|
||||
# # 2023/02/19
|
||||
# # 4 tests fail:
|
||||
# # - FAILED: testing/test_remote.py::TestWorkInteractor::* - execnet.gateway_base.TimeoutError: no item after 10.0 seconds
|
||||
# # doCheck = false;
|
||||
# disabledTestPaths = upstream.disabledTestPaths or [] ++ [
|
||||
# "testing/test_remote.py"
|
||||
# ];
|
||||
# # disabledTests = upstream.disabledTests or [] ++ [
|
||||
# # "test_basic_collect_and_runtests"
|
||||
# # "test_remote_collect_fail"
|
||||
# # "test_remote_collect_skip"
|
||||
# # "test_runtests_all"
|
||||
# # ];
|
||||
# });
|
||||
# twisted = py-prev.twisted.overridePythonAttrs (upstream: {
|
||||
# # 2023/02/25
|
||||
# # ```
|
||||
# # [ERROR]
|
||||
# # Traceback (most recent call last):
|
||||
# # File "/nix/store/dcnsxrn8rsfk1dghah7md5glbbnfysq3-python3.10-twisted-22.10.0/lib/python3.10/site-packages/twisted/test/test_udp.py", line 645, in test_interface
|
||||
# # self.assertEqual(self.client.transport.getOutgoingInterface(), "0.0.0.0")
|
||||
# # File "/nix/store/dcnsxrn8rsfk1dghah7md5glbbnfysq3-python3.10-twisted-22.10.0/lib/python3.10/site-packages/twisted/internet/udp.py", line 449, in getOutgoingInterface
|
||||
# # i = self.socket.getsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF)
|
||||
# # builtins.OSError: [Errno 92] Protocol not available
|
||||
# #
|
||||
# # twisted.test.test_udp.MulticastTests.test_interface
|
||||
# # ```
|
||||
# postPatch = upstream.postPatch + ''
|
||||
# echo 'MulticastTests.test_interface.skip = "Protocol not available"'>> src/twisted/test/test_udp.py
|
||||
# '';
|
||||
# });
|
||||
|
||||
# 2023/08/09: unclear why it fails; probably can remove after next nixpkgs update
|
||||
pillow = py-prev.pillow.overridePythonAttrs (_upstream: {
|
||||
format = "setuptools";
|
||||
});
|
||||
|
||||
seaborn = py-prev.seaborn.overridePythonAttrs (upstream: {
|
||||
# 2023/08/09
|
||||
disabledTestPaths = (upstream.disabledTestPaths or []) ++ [
|
||||
"tests/test_categorical.py"
|
||||
"tests/test_core.py"
|
||||
];
|
||||
});
|
||||
})
|
||||
];
|
||||
|
||||
# strp = prev.srtp.overrideAttrs (_upstream: {
|
||||
# # 2023/02/11
|
||||
# # roc_driver test times out after 30s
|
||||
# doCheck = false;
|
||||
# });
|
||||
tracker = prev.tracker.overrideAttrs (_upstream: {
|
||||
# 2023/02/22
|
||||
# "27/37 tracker:core / service TIMEOUT 60.37s killed by signal 15 SIGTERM"
|
||||
doCheck = false;
|
||||
});
|
||||
# udisks2 = prev.udisks2.overrideAttrs (_upstream: {
|
||||
# # 2023/02/25
|
||||
# # "udisks-test:ERROR:test.c:61:on_completed_expect_failure: assertion failed (message == expected_message): ("Command-line `./udisks-test-helper 4' was signaled with signal SIGSEGV (11):\nstdout: `OK, deliberately causing a segfault\n'\nstderr: `qemu: uncaught target signal 11 (Segmentation fault) - core dumped\n'" == "Command-line `./udisks-test-helper 4' was signaled with signal SIGSEGV (11): OK, deliberately causing a segfault\n")"
|
||||
# doCheck = false;
|
||||
# });
|
||||
# upower = prev.upower.overrideAttrs (_upstream: {
|
||||
# # 2023/02/25
|
||||
# # "Tests.test_battery_state_guessing TIMEOUT 60.80s killed by signal 15 SIGTERM"
|
||||
# doCheck = false;
|
||||
# });
|
||||
tracker = dontCheck prev.tracker;
|
||||
|
||||
# 2023/07/31
|
||||
# fails a test (didn't see which one)
|
||||
# only for binfmt-emulated aarch64 -> aarch64 build
|
||||
umockdev = dontCheckEmulated prev.umockdev;
|
||||
})
|
||||
|
47
overlays/preferences.nix
Normal file
47
overlays/preferences.nix
Normal file
@@ -0,0 +1,47 @@
|
||||
# personal preferences
|
||||
# prefer to encode these in `sane.programs`
|
||||
# resort to this method for e.g. system dependencies, or things which are referenced from too many places.
|
||||
(self: super: with self; {
|
||||
gnome = super.gnome.overrideScope' (gself: gsuper: with gself; {
|
||||
evolution-data-server = gsuper.evolution-data-server.override {
|
||||
# OAuth depends on webkitgtk_4_1: old, forces an annoying recompilation
|
||||
enableOAuth2 = false;
|
||||
gnome-online-accounts = gnome-online-accounts.override {
|
||||
# avoid webkitgtk_4_1 build
|
||||
enableBackend = false;
|
||||
};
|
||||
};
|
||||
# gnome-shell = gsuper.gnome-shell.override {
|
||||
# evolution-data-server-gtk4 = evolution-data-server-gtk4.override {
|
||||
# # avoid webkitgtk_6_0 build. lol.
|
||||
# withGtk4 = false;
|
||||
# };
|
||||
# };
|
||||
});
|
||||
|
||||
phog = super.phog.override {
|
||||
# disable squeekboard because it takes 20 minutes to compile when emulated
|
||||
squeekboard = null;
|
||||
};
|
||||
|
||||
pipewire = super.pipewire.override {
|
||||
# avoid a dep on python3.10-PyQt5, which has mixed qt5 versions.
|
||||
# this means we lose firewire support (oh well..?)
|
||||
ffadoSupport = false;
|
||||
};
|
||||
|
||||
pythonPackagesExtensions = super.pythonPackagesExtensions ++ [
|
||||
(pySelf: pySuper: {
|
||||
keyring = (pySuper.keyring.override {
|
||||
# jaraco-classes doesn't cross compile, but it looks like `keyring`
|
||||
# has some _temporary_ fallback logic for when jaraco-classes isn't
|
||||
# installed (i.e. may break in future).
|
||||
jaraco-classes = null;
|
||||
}).overrideAttrs (upstream: {
|
||||
postPatch = (upstream.postPatch or "") + ''
|
||||
sed -i /jaraco.classes/d setup.cfg
|
||||
'';
|
||||
});
|
||||
})
|
||||
];
|
||||
})
|
@@ -18,6 +18,21 @@ stdenv.mkDerivation rec {
|
||||
hash = "sha256-jOtFUpl2/Aa7f8JMZf6g63ayFOi+Ci+i7Ac63k63znc=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace Makefile \
|
||||
--replace 'hare build' 'hare build $(HARE_TARGET_FLAGS)'
|
||||
'';
|
||||
|
||||
env.HARE_TARGET_FLAGS =
|
||||
if stdenv.hostPlatform.isAarch64 then
|
||||
"-t aarch64"
|
||||
else if stdenv.hostPlatform.isRiscV64 then
|
||||
"-t riscv64"
|
||||
else if stdenv.hostPlatform.isx86_64 then
|
||||
"-t x86_64"
|
||||
else
|
||||
"";
|
||||
|
||||
nativeBuildInputs = [
|
||||
hare
|
||||
hare-ev
|
||||
@@ -31,7 +46,7 @@ stdenv.mkDerivation rec {
|
||||
# export ARFLAGS="-csr"
|
||||
'';
|
||||
|
||||
installFlags = [ "PREFIX=" "DESTDIR=$(out)" ];
|
||||
installFlags = [ "PREFIX=$(out)" ];
|
||||
|
||||
passthru.updateScript = gitUpdater {
|
||||
rev-prefix = "v";
|
||||
|
87
pkgs/additional/chatty-latest/default.nix
Normal file
87
pkgs/additional/chatty-latest/default.nix
Normal file
@@ -0,0 +1,87 @@
|
||||
{ chatty
|
||||
, fetchFromGitLab
|
||||
, appstream-glib
|
||||
, desktop-file-utils
|
||||
, itstool
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
, python3
|
||||
# , wrapGAppsHook
|
||||
# , evolution-data-server
|
||||
, feedbackd
|
||||
, glibmm
|
||||
, gnome-desktop
|
||||
, gspell
|
||||
# , gtk3
|
||||
, json-glib
|
||||
, libgcrypt
|
||||
, libhandy
|
||||
, libphonenumber
|
||||
, modemmanager
|
||||
, olm
|
||||
, pidgin
|
||||
, protobuf
|
||||
, sqlite
|
||||
# NEW
|
||||
, evolution-data-server-gtk4
|
||||
, glib-networking
|
||||
, gtk4
|
||||
, libadwaita
|
||||
, wrapGAppsHook4
|
||||
}:
|
||||
chatty.overrideAttrs (upstream: {
|
||||
pname = "chatty-latest";
|
||||
version = "unstable-2023-08-01";
|
||||
src = fetchFromGitLab {
|
||||
domain = "source.puri.sm";
|
||||
owner = "Librem5";
|
||||
repo = "chatty";
|
||||
rev = "ca556b7df539b37e08ed2c73e2beb2b6cc7b91f3";
|
||||
hash = "sha256-Tzdai2VU9wh/HW52uB+9uzpQymZmTqwiGqB6N20IvxE=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
postPatch = (upstream.postPatch or "") + ''
|
||||
substituteInPlace build-aux/meson/postinstall.py \
|
||||
--replace 'gtk-update-icon-cache' 'gtk4-update-icon-cache'
|
||||
'';
|
||||
|
||||
nativeBuildInputs = [
|
||||
appstream-glib
|
||||
desktop-file-utils
|
||||
itstool
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
python3
|
||||
#wrapGAppsHook
|
||||
|
||||
# NEW
|
||||
wrapGAppsHook4
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
# evolution-data-server
|
||||
feedbackd
|
||||
glib-networking # for TLS
|
||||
glibmm
|
||||
gnome-desktop
|
||||
gspell
|
||||
# gtk3
|
||||
json-glib
|
||||
libgcrypt
|
||||
libhandy
|
||||
libphonenumber
|
||||
modemmanager
|
||||
olm
|
||||
pidgin
|
||||
protobuf
|
||||
sqlite
|
||||
|
||||
# NEW
|
||||
libadwaita
|
||||
gtk4
|
||||
evolution-data-server-gtk4
|
||||
];
|
||||
})
|
6
pkgs/additional/eg25-control/default.nix
Normal file
6
pkgs/additional/eg25-control/default.nix
Normal file
@@ -0,0 +1,6 @@
|
||||
{ static-nix-shell }:
|
||||
static-nix-shell.mkPython3Bin {
|
||||
pname = "eg25-control";
|
||||
src = ./.;
|
||||
pkgs = [ "curl" "modemmanager" ];
|
||||
}
|
429
pkgs/additional/eg25-control/eg25-control
Executable file
429
pkgs/additional/eg25-control/eg25-control
Executable file
@@ -0,0 +1,429 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i python3 -p "python3.withPackages (ps: [ ])" -p curl -p modemmanager
|
||||
|
||||
# this script should run after ModemManager.service is started.
|
||||
# typical invocation is `eg25_gps_init.py --enable-power --enable-gps`.
|
||||
# after running, the user may `cat /dev/ttyUSB1` to view NMEA-encoded GPS information.
|
||||
# the script attempts to be idempotent, such that it may be run multiple times per boot.
|
||||
#
|
||||
# this script downloads assisted GPS (AGPS) data via the system's default gateway (i.e. WiFi)
|
||||
# and shares that with the modem. this quickens the process of acquiring a GPS fix.
|
||||
#
|
||||
# the script may also configure other parts of the modem as `eg25-manager` does.
|
||||
# these options are less tested: see `--help` for more.
|
||||
#
|
||||
# PREREQUISITES/DEPENDENCIES:
|
||||
# this script expects to run on megi's kernel, with `CONFIG_MODEM_POWER=y`.
|
||||
# ModemManager must be launched with the `--debug` flag, so that `mmcli --command=...` works.
|
||||
#
|
||||
# ModemManager, and by extension this script, REQUIRES A SIM CARD IN YOUR PHONE.
|
||||
# the sim doesn't need to be "activated". you can buy a $1 SIM and never purchase
|
||||
# service and that works; it's just needed for ModemManager to boot the modem.
|
||||
# this isn't a fundamental requirement; if one did everything via serial instead of
|
||||
# ModemManager the SIM would not be necessary for GPS.
|
||||
#
|
||||
# EXPECTATIONS/TIPS:
|
||||
# - with the right environment, you may get a GPS fix in < 30s.
|
||||
# - the fix is likely to have a *lot* of jitter, like 10+ meters.
|
||||
# - indoors, you shouldn't expect to *ever* get a cold-start GPS fix.
|
||||
# - maybe you'll track 1 satellite if lucky: enough to receive GPS time but not for a GPS fix.
|
||||
# - get a fix outdoors, then walk indoors: GPS is smart enough to maintain a spotty fix.
|
||||
# - outdoors in suburbia, a fix might take 10-20 minutes.
|
||||
# - i have better luck *placing my phone on the roof of my car* than holding it in the air with my hand.
|
||||
# - maybe a big metal plate opposite the sky acts as a dish/antenna?
|
||||
# - in Seattle, i track several GLONASS and GPS sats: about an even split.
|
||||
# - the GPS sats have better SNR.
|
||||
# - modem seems to not show any BeiDou or Galileo sats even if i enable them.
|
||||
#
|
||||
# eg25 modem/GPS docs:
|
||||
# [GNSS-AP-Note]: https://wiki.pine64.org/images/0/09/Quectel_EC2x%26EG9x%26EG2x-G%26EM05_Series_GNSS_Application_Note_V1.3.pdf
|
||||
#
|
||||
# most acronyms are defined inline, particularly near variable/class declarations.
|
||||
# glossary, for those which aren't:
|
||||
#
|
||||
# Global Navigation Satellite Systems (GNSS):
|
||||
# - GPS (US)
|
||||
# - GLONASS (RU)
|
||||
# - Galileo (EU)
|
||||
# - BeiDou (CN)
|
||||
# ^ these are all global systems, usable outside the country that owns them
|
||||
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import logging
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
POWER_ENDPOINT = "/sys/class/modem-power/modem-power/device/powered"
|
||||
# GNSS-AP-Note 1.4:
|
||||
# also at xtrapath5 and xtrapath6 subdomains.
|
||||
# the AGPS data here is an almanac good for 7 days.
|
||||
AGPS_DATA_URI_BASE = "https://xtrapath4.izatcloud.net"
|
||||
|
||||
class AgpsDataVariant:
|
||||
# GNSS-AP-Note 1.4:
|
||||
gps_glonass = "xtra2.bin"
|
||||
gps_glonass_beidou = "xtra3grc.bin"
|
||||
# N.B.: not supported by all Quectel modems
|
||||
# on stock Pinephone, ModemManager gives "LOC service: general failure"
|
||||
gps_glonass_beidou_galileo = "xtra3grcej.bin"
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def destructive(fn: callable = None, return_ = None):
|
||||
""" decorate `fn` so that it becomes a no-op when --dry-run is active """
|
||||
def wrapped(self, *args, **kwargs):
|
||||
if self.dry_run:
|
||||
fmt_args = ", ".join(
|
||||
[repr(a) for a in args] +
|
||||
[f"{k}={v}" for k,v in kwargs.items()]
|
||||
)
|
||||
logger.info(f"[dry run] {fn.__name__}({fmt_args})")
|
||||
return return_
|
||||
else:
|
||||
return fn(self, *args, **kwargs)
|
||||
if fn:
|
||||
return wrapped
|
||||
else:
|
||||
return lambda fn: destructive(fn, return_=return_)
|
||||
|
||||
def log_scope(at_enter: str, at_exit: str):
|
||||
""" decorate a function so that it logs at start and end """
|
||||
def decorator(fn: callable):
|
||||
def wrapped(*args, **kwargs):
|
||||
logger.info(at_enter)
|
||||
ret = fn(*args, **kwargs)
|
||||
logger.info(at_exit)
|
||||
return ret
|
||||
return wrapped
|
||||
return decorator
|
||||
|
||||
class Executor:
|
||||
def __init__(self, dry_run: bool = False):
|
||||
self.dry_run = dry_run
|
||||
|
||||
@destructive
|
||||
def write_file(self, path: str, data: bytes) -> None:
|
||||
logger.debug(f"echo {data!r} > {path}")
|
||||
with open(path, 'wb') as f:
|
||||
f.write(data)
|
||||
|
||||
@destructive(return_=b'')
|
||||
def exec(self, cmd: list[str], check: bool = True) -> bytes:
|
||||
logger.debug(" ".join(cmd))
|
||||
res = subprocess.run(cmd, capture_output=True)
|
||||
logger.debug(res.stdout)
|
||||
if res.stderr:
|
||||
logger.warning(res.stderr)
|
||||
if check:
|
||||
res.check_returncode()
|
||||
return res.stdout
|
||||
|
||||
class GNSSConfig:
|
||||
# GNSS-AP-Note 2.2.7
|
||||
# Supported GNSS constellations. GPS is always ON
|
||||
# 0 GLONASS OFF/BeiDou OFF/Galileo OFF
|
||||
# 1 GLONASS ON/BeiDou ON/Galileo ON
|
||||
# 2 GLONASS ON/BeiDou ON/Galileo OFF
|
||||
# 3 GLONASS ON/BeiDou OFF/Galileo ON
|
||||
# 4 GLONASS ON/BeiDou OFF/Galileo OFF
|
||||
# 5 GLONASS OFF/BeiDou ON/Galileo ON
|
||||
# 6 GLONASS OFF/BeiDou OFF/Galileo ON
|
||||
# 7 GLONASS OFF/BeiDou ON/Galileo OFF
|
||||
gps = "0"
|
||||
gps_glonass_beidou_galileo = "1"
|
||||
gps_glonass_beidou = "2"
|
||||
gps_glonass_galilego = "3"
|
||||
gps_glonass = "4"
|
||||
gps_beidou_galileo = "5"
|
||||
gps_galileo = "6"
|
||||
gps_beidou = "7"
|
||||
|
||||
class ODPControl:
|
||||
# GNSS-AP-Note 2.2.8
|
||||
# 0 Disable ODP
|
||||
# 1 Low power mode
|
||||
# 2 Ready mode
|
||||
#
|
||||
# ODP = "On-Demand Positioning"
|
||||
# Low power mode:
|
||||
# - low-frequency background GNSS tracking session
|
||||
# - adjusts interval between 10m (when signal is good) - 60m (when signal is bad)
|
||||
# Ready mode:
|
||||
# - 1 Hz positioning
|
||||
# - keeps GNSS ready so that when application demands position it's immediately ready
|
||||
# - automatically stops positioning after 60s??
|
||||
disable = "0"
|
||||
lower_power_mode = "1"
|
||||
ready_mode = "2"
|
||||
|
||||
class DPOEnable:
|
||||
# GNSS-AP-Note 2.2.9
|
||||
# 0 Disable DPO
|
||||
# 1 Enable the DPO with dynamic duty cycle
|
||||
#
|
||||
# DPO = "Dynamic Power Optimization"
|
||||
# automatically shuts off radio under certain conditions
|
||||
# more info: <https://sixfab.com/wp-content/uploads/2018/09/Quectel_UC20_GNSS_AT_Commands_Manual_V1.1.pdf> 1.4.1
|
||||
disable = "0"
|
||||
enable = "1"
|
||||
|
||||
class GPSNMEAType:
|
||||
# GNSS-AP-Note 2.2.3
|
||||
# Output type of GPS NMEA sentences in ORed.
|
||||
disable = 0
|
||||
gpgga = 1
|
||||
gprmc = 2
|
||||
gpgsv = 4
|
||||
gpgsa = 8
|
||||
gpvtg = 16
|
||||
all = 31
|
||||
|
||||
class GlonassNmeaType:
|
||||
# GNSS-AP-Note 2.2.4
|
||||
# Configure output type of GLONASS NMEA sentences in ORed
|
||||
disable = 0
|
||||
glgsv = 1
|
||||
gngsa = 2
|
||||
gngns = 4
|
||||
all = 7
|
||||
|
||||
class GalileoNmeaType:
|
||||
# GNSS-AP-Note 2.2.5
|
||||
disable = 0
|
||||
gagsv = 1
|
||||
all = 1
|
||||
|
||||
class BeiDouNmeaType:
|
||||
# GNSS-AP-Note 2.2.6
|
||||
disable = 0
|
||||
pqgsa = 1
|
||||
pqgsv = 2
|
||||
all = 3
|
||||
|
||||
class AutoGps:
|
||||
# GNSS-AP-Note 2.2.12
|
||||
# Enable/disable GNSS to run automatically after the module is powered on.
|
||||
disable = "0"
|
||||
enable = "1"
|
||||
|
||||
class Sequencer:
|
||||
AGPS_DATA_URI_BASE = AGPS_DATA_URI_BASE
|
||||
def __init__(self, executor: Executor, modem: str, power_endpoint: str):
|
||||
self.executor = executor
|
||||
self.modem = modem
|
||||
self.power_endpoint = power_endpoint
|
||||
|
||||
def _mmcli(self, args: list[str], check: bool = True) -> str:
|
||||
return self.executor.exec(
|
||||
["mmcli", "--modem", self.modem] + args,
|
||||
check=check
|
||||
).decode('utf-8')
|
||||
|
||||
def _try_mmcli(self, args: list[str]) -> str:
|
||||
try:
|
||||
return self._mmcli(args)
|
||||
except subprocess.CalledProcessError:
|
||||
return None
|
||||
|
||||
def _at_cmd(self, cmd: str, check: bool = True) -> str:
|
||||
# this returns the mmcli output, which looks like:
|
||||
# response: 'blah'
|
||||
# i.e., quoted, and with a `response: ` prefix
|
||||
return self._mmcli([f"--command=+{cmd}"], check=check)
|
||||
|
||||
def _at_structured_cmd(self, cmd: str, subcmd: str | None = None, value: str | None = None, check: bool = True) -> str:
|
||||
if not subcmd and not value:
|
||||
return self._at_cmd(cmd, check=check)
|
||||
elif not subcmd and value:
|
||||
return self._at_cmd(f"{cmd}={value}", check=check)
|
||||
elif subcmd and not value:
|
||||
return self._at_cmd(f"{cmd}=\"{subcmd}\"", check=check)
|
||||
else:
|
||||
return self._at_cmd(f"{cmd}=\"{subcmd}\",{value}", check=check)
|
||||
|
||||
def _at_gnssconfig(self, cfg: GNSSConfig) -> str:
|
||||
return self._at_structured_cmd("QGPSCFG", "gnssconfig", cfg)
|
||||
|
||||
def _at_odpcontrol(self, control: ODPControl) -> str:
|
||||
return self._at_structured_cmd("QGPSCFG", "odpcontrol", control)
|
||||
|
||||
def _at_dpoenable(self, enable: DPOEnable) -> str:
|
||||
return self._at_structured_cmd("QGPSCFG", "dpoenable", enable)
|
||||
|
||||
def _at_gpsnmeatype(self, ty: GPSNMEAType) -> str:
|
||||
return self._at_structured_cmd("QGPSCFG", "gpsnmeatype", str(ty))
|
||||
|
||||
def _at_glonassnmeatype(self, ty: GlonassNmeaType) -> str:
|
||||
return self._at_structured_cmd("QGPSCFG", "glonassnmeatype", str(ty))
|
||||
|
||||
def _at_galileonmeatype(self, ty: GalileoNmeaType) -> str:
|
||||
return self._at_structured_cmd("QGPSCFG", "galileonmeatype", str(ty))
|
||||
|
||||
def _at_beidounmeatype(self, ty: BeiDouNmeaType) -> str:
|
||||
self._at_structured_cmd("QGPSCFG", "beidounmeatype", str(ty))
|
||||
|
||||
def _at_autogps(self, enable: AutoGps) -> str:
|
||||
return self._at_structured_cmd("QGPSCFG", "autogps", enable)
|
||||
|
||||
def _get_assistance_data(self, variant: AgpsDataVariant) -> str | None:
|
||||
try:
|
||||
self.executor.exec(["curl", f"{self.AGPS_DATA_URI_BASE}/{variant}", "-o", variant])
|
||||
return variant
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.warning(f"AGPS data download failed: {e}")
|
||||
return None # TODO: could be smarter: return cached AGPS data?
|
||||
|
||||
@log_scope("powering modem...", "modem powered")
|
||||
def power_on(self) -> None:
|
||||
self.executor.write_file(self.power_endpoint, b'1')
|
||||
while self._try_mmcli([]) is None:
|
||||
logger.info("modem hasn't appeared: sleeping for 1s")
|
||||
time.sleep(1) # wait for modem to appear
|
||||
|
||||
def at_check(self) -> None:
|
||||
""" sanity check that the modem is listening for AT commands and responding reasonably """
|
||||
hw = self._at_cmd("QGMR")
|
||||
assert 'EG25GGBR07A08M2G' in hw or self.executor.dry_run, hw
|
||||
|
||||
def dump_debug_info(self) -> None:
|
||||
logger.debug('checking if AGPS is enabled (1) or not (0)')
|
||||
self._at_structured_cmd('QGPSXTRA?')
|
||||
# see if the GPS assistance data is still within valid range
|
||||
logger.debug('QGPSXTRADATA: <valid_duration_minutes>,<start_time_of_agps_data>')
|
||||
self._at_structured_cmd('QGPSXTRADATA?')
|
||||
logger.debug('checking what time the modem last synchronized with the network')
|
||||
self._at_structured_cmd('QLTS')
|
||||
logger.debug('checking what time the modem thinks it is (extrapolated from sync)')
|
||||
self._at_structured_cmd('QLTS', value=1)
|
||||
logger.debug('checking what time the modem thinks it is (from RTC)')
|
||||
self._at_structured_cmd('CCLK?')
|
||||
logger.debug('checking if nmea GPS source is enabled')
|
||||
self._at_structured_cmd('QGPSCFG', 'nmeasrc')
|
||||
logger.debug('checking if GPS is enabled (1) or not (0)')
|
||||
self._at_structured_cmd('QGPS?')
|
||||
logger.debug('checking if GPS has a fix. Error 516 if not')
|
||||
self._at_structured_cmd('QGPSLOC', value='0', check=False)
|
||||
logger.debug('dumping AGPS positioning mode bitfield')
|
||||
self._at_structured_cmd('QGPSCFG', 'agpsposmode')
|
||||
|
||||
@log_scope("configuring audio...", "audio configured")
|
||||
def enable_audio(self) -> None:
|
||||
# cribbed from eg25-manager; i don't understand these
|
||||
# QDAI call shouldn't be necessary if using Megi's FW:
|
||||
# - <https://xnux.eu/devices/feature/modem-pp.html>
|
||||
self._at_structured_cmd("QDAI", value="1,1,0,1,0,0,1,1")
|
||||
# RI signaling using physical RI pin
|
||||
self._at_structured_cmd("QCFG", "risignaltype", "\"physical\"")
|
||||
# Enable VoLTE support
|
||||
self._at_structured_cmd("QCFG", "ims", "1")
|
||||
# Enable APREADY for PP 1.2
|
||||
self._at_structured_cmd("QCFG", "apready", "1,0,500")
|
||||
|
||||
@log_scope("configuring urc...", "urc configured")
|
||||
def enable_urc(self) -> None:
|
||||
# cribbed from eg25-manager; i don't even know what URC is
|
||||
# URC configuration for PP 1.2 (APREADY pin connected):
|
||||
# * RING URC: normal pulse length
|
||||
# * Incoming SMS URC: default pulse length
|
||||
# * Other URC: default length
|
||||
# * Report URCs on all ports (serial and USB) for FOSS firmware
|
||||
# * Reporting of URCs without any delay
|
||||
# * Configure URC pin to UART Ring Indicator
|
||||
self._at_structured_cmd("QCFG", "urc/ri/ring", "\"pulse\",120,1000,5000,\"off\",1")
|
||||
self._at_structured_cmd("QCFG", "urc/ri/smsincoming", "\"pulse\",120,1")
|
||||
self._at_structured_cmd("QCFG", "urc/ri/other", "\"off\",1,1")
|
||||
self._at_structured_cmd("QCFG", "urc/delay", "0")
|
||||
self._at_structured_cmd("QCFG", "urc/cache", "0")
|
||||
self._at_structured_cmd("QCFG", "urc/ri/pin", "uart_ri")
|
||||
self._at_structured_cmd("QURCCFG", "urcport", "\"all\"")
|
||||
|
||||
@log_scope("configuring gps...", "gps configured")
|
||||
def enable_gps(self) -> None:
|
||||
# set modem to use UTC time instead of local time.
|
||||
# modemmanager sends CTZU=3 during init and that causes `AT+CCLK?` to return a timestamp that's off by 600+ days
|
||||
# see: <https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/360>
|
||||
self._at_structured_cmd("CTZU", value="1")
|
||||
|
||||
# disable GNSS, because it's only configurable while offline
|
||||
self._at_structured_cmd("QGPSEND", check=False)
|
||||
# self._at_structured_cmd("QGPS", value="0")
|
||||
|
||||
# XXX: ModemManager plugin sets QGPSXTRA=1
|
||||
# self._at_structured_cmd("QGPSXTRA", value="1")
|
||||
|
||||
# now = datetime.datetime.now().strftime('%Y/%m/%d,%H:%M:%S') # UTC
|
||||
# self._at_structured_cmd("QGPSXTRATIME", value=f"0,\"{now}\"")
|
||||
locdata = self._get_assistance_data(AgpsDataVariant.gps_glonass_beidou)
|
||||
if locdata:
|
||||
self._mmcli([f"--location-inject-assistance-data={locdata}"])
|
||||
|
||||
self._at_gnssconfig(GNSSConfig.gps_glonass_beidou_galileo)
|
||||
self._at_odpcontrol(ODPControl.disable)
|
||||
self._at_dpoenable(DPOEnable.disable) # N.B.: eg25-manager uses `DPOEnable.enable`
|
||||
self._at_gpsnmeatype(GPSNMEAType.all)
|
||||
self._at_glonassnmeatype(GlonassNmeaType.all)
|
||||
self._at_galileonmeatype(GalileoNmeaType.all)
|
||||
self._at_beidounmeatype(BeiDouNmeaType.all)
|
||||
self._at_autogps(AutoGps.disable) #< don't start GPS on modem boot
|
||||
# configure so GPS output is readable via /dev/ttyUSB1
|
||||
# self._mmcli(["--location-enable-gps-unmanaged"])
|
||||
# TODO: tune/document these QGPS values; a smarter setting here might reduce jitter?
|
||||
self._at_structured_cmd("QGPS", value="1,255,1000,0,1")
|
||||
|
||||
@log_scope("configuring powersave...", "powersave configured")
|
||||
def enable_powersave(self) -> None:
|
||||
# Allow sleeping for power saving
|
||||
self._at_structured_cmd("QSCLK", value="1")
|
||||
# Disable fast poweroff for stability
|
||||
self._at_structured_cmd("QCFG", "fast/poweroff", "0")
|
||||
# Configure sleep and wake up pin levels to active low
|
||||
self._at_structured_cmd("QCFG", "sleepind/level", "0")
|
||||
self._at_structured_cmd("QCFG", "wakeupin/level", "0,0")
|
||||
# Do not enter RAMDUMP mode, auto-reset instead
|
||||
self._at_structured_cmd("QCFG", "ApRstLevel", "1")
|
||||
self._at_structured_cmd("QCFG", "ModemRstLevel", "1")
|
||||
|
||||
|
||||
def main():
|
||||
logging.basicConfig()
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
parser = argparse.ArgumentParser(description="initialize the eg25 Pinephone modem for GPS tracking")
|
||||
parser.add_argument('--modem', default='any', help='name of modem to configure (see mmcli --list-modems)')
|
||||
parser.add_argument('--power-endpoint', default='/sys/class/modem-power/modem-power/device/powered', help='sysfs endpoint that can turn the modem on/off')
|
||||
|
||||
parser.add_argument("--dry-run", action='store_true', help="print commands instead of executing them")
|
||||
parser.add_argument("--verbose", action='store_true', help="log each command before executing")
|
||||
|
||||
parser.add_argument('--power-on', action='store_true', help="enable power to the modem")
|
||||
parser.add_argument('--enable-audio', action='store_true', help="configure audio for calling (?)")
|
||||
parser.add_argument('--enable-urc', action='store_true', help="enable support for Unsolicited Return Codes (?)")
|
||||
parser.add_argument('--enable-gps', action='store_true', help="enable the GPS and acquire tracking until asked to stop")
|
||||
parser.add_argument('--enable-powersave', action='store_true', help="configure modem to sleep when possible")
|
||||
parser.add_argument('--dump-debug-info', action='store_true', help="don't initialize anything, just dump debugging data")
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.verbose or args.dump_debug_info:
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
|
||||
executor = Executor(args.dry_run)
|
||||
sequencer = Sequencer(executor, modem=args.modem, power_endpoint=args.power_endpoint)
|
||||
|
||||
if args.power_on:
|
||||
sequencer.power_on()
|
||||
if args.enable_audio:
|
||||
sequencer.enable_audio()
|
||||
if args.enable_urc:
|
||||
sequencer.enable_urc()
|
||||
if args.enable_gps:
|
||||
sequencer.enable_gps()
|
||||
if args.enable_powersave:
|
||||
sequencer.enable_powersave()
|
||||
if args.dump_debug_info:
|
||||
sequencer.dump_debug_info()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
77
pkgs/additional/eg25-manager/default.nix
Normal file
77
pkgs/additional/eg25-manager/default.nix
Normal file
@@ -0,0 +1,77 @@
|
||||
# package based on:
|
||||
# - <https://github.com/NixOS/mobile-nixos/pull/573>
|
||||
|
||||
{ lib
|
||||
, stdenv
|
||||
, callPackage
|
||||
, fetchFromGitLab
|
||||
, gnugrep
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
, scdoc
|
||||
, curl
|
||||
, glib
|
||||
, libgudev
|
||||
, libusb1
|
||||
# if true, build with MMGLIB. if false, eg25-manager won't speak to modemmanager and will be usable standalone
|
||||
, withModemManager ? true, modemmanager
|
||||
}:
|
||||
|
||||
let
|
||||
# eg25-manager needs to be made compatible with libgpiod 2.0 API. see:
|
||||
# - <https://github.com/NixOS/mobile-nixos/pull/573#issuecomment-1666739462>
|
||||
# - <https://gitlab.com/mobian1/eg25-manager/-/issues/45>
|
||||
# nixpkgs libgpiod was bumped 2023-07-29:
|
||||
# - <https://github.com/NixOS/nixpkgs/pull/246018>
|
||||
libgpiod1 = callPackage ./libgpiod1.nix { };
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "eg25-manager";
|
||||
version = "0.4.6";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
owner = "mobian1";
|
||||
repo = "eg25-manager";
|
||||
rev = version;
|
||||
hash = "sha256-2JsdwK1ZOr7ljNHyuUMzVCpl+HV0C5sA5LAOkmELqag=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace 'udev/80-modem-eg25.rules' \
|
||||
--replace '/bin/grep' '${gnugrep}/bin/grep'
|
||||
'';
|
||||
|
||||
depsBuildBuild = [
|
||||
pkg-config
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
glib # Contains gdbus-codegen program
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
scdoc
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
curl
|
||||
glib
|
||||
libgpiod1
|
||||
libgudev
|
||||
libusb1
|
||||
] ++ lib.optionals withModemManager [
|
||||
modemmanager
|
||||
];
|
||||
|
||||
passthru = {
|
||||
inherit libgpiod1;
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
description = "Manager daemon for the Quectel EG25 mobile broadband modem";
|
||||
homepage = "https://gitlab.com/mobian1/eg25-manager";
|
||||
license = licenses.gpl3Plus;
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
}
|
39
pkgs/additional/eg25-manager/libgpiod1.nix
Normal file
39
pkgs/additional/eg25-manager/libgpiod1.nix
Normal file
@@ -0,0 +1,39 @@
|
||||
{ lib, stdenv, fetchurl, autoreconfHook, autoconf-archive, pkg-config, kmod
|
||||
, enable-tools ? true
|
||||
, enablePython ? false, python3, ncurses }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "libgpiod";
|
||||
version = "1.6.4";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/snapshot/libgpiod-${version}.tar.gz";
|
||||
hash = "sha256-gp1KwmjfB4U2CdZ8/H9HbpqnNssqaKYwvpno+tGXvgo=";
|
||||
};
|
||||
|
||||
buildInputs = [ kmod ] ++ lib.optionals enablePython [ python3 ncurses ];
|
||||
nativeBuildInputs = [
|
||||
autoconf-archive
|
||||
pkg-config
|
||||
autoreconfHook
|
||||
];
|
||||
|
||||
configureFlags = [
|
||||
"--enable-tools=${if enable-tools then "yes" else "no"}"
|
||||
"--enable-bindings-cxx"
|
||||
"--prefix=${placeholder "out"}"
|
||||
] ++ lib.optional enablePython "--enable-bindings-python";
|
||||
|
||||
meta = with lib; {
|
||||
description = "C library and tools for interacting with the linux GPIO character device";
|
||||
longDescription = ''
|
||||
Since linux 4.8 the GPIO sysfs interface is deprecated. User space should use
|
||||
the character device instead. This library encapsulates the ioctl calls and
|
||||
data structures behind a straightforward API.
|
||||
'';
|
||||
homepage = "https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/about/";
|
||||
license = licenses.lgpl2;
|
||||
maintainers = [ maintainers.expipiplus1 ];
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
{ stdenv
|
||||
, fetchFromGitHub
|
||||
, fetchFromGitea
|
||||
, gnused
|
||||
, mkYarnModules
|
||||
, nodejs
|
||||
, zip
|
||||
}:
|
||||
|
||||
@@ -25,7 +25,8 @@ let
|
||||
# sha256 = "sha256-dSRZ2ToEOPhzHNvlG8qdewa7689gT8cNB7nXkN3/Avo=";
|
||||
# };
|
||||
browserpass-extension-yarn-modules = mkYarnModules {
|
||||
inherit pname version;
|
||||
inherit version;
|
||||
pname = "${pname}-modules";
|
||||
packageJSON = ./package.json;
|
||||
yarnLock = ./yarn.lock;
|
||||
# yarnNix is auto-generated. to update: leave unset, then query the package deps and copy it out of the store.
|
||||
@@ -37,9 +38,20 @@ let
|
||||
in stdenv.mkDerivation {
|
||||
inherit pname version src;
|
||||
|
||||
nativeBuildInputs = [ nodejs zip ];
|
||||
|
||||
postPatch = ''
|
||||
# dependencies are built separately: skip the yarn install
|
||||
${gnused}/bin/sed -i /yarn\ install/d src/Makefile
|
||||
# prettier, lessc, browserify are made available here via the modules,
|
||||
# which are for the host (even the devDependencies are compiled for the host).
|
||||
# but we can just run those via the build node.
|
||||
#
|
||||
# alternative would be to patchShebangs in the node_modules dir.
|
||||
substituteInPlace src/Makefile \
|
||||
--replace "yarn install" "true" \
|
||||
--replace ' $(PRETTIER)' ' node $(PRETTIER)' \
|
||||
--replace ' $(LESSC)' ' node $(LESSC)' \
|
||||
--replace ' $(BROWSERIFY)' ' node $(BROWSERIFY)'
|
||||
'';
|
||||
|
||||
preBuild = ''
|
||||
@@ -48,11 +60,12 @@ in stdenv.mkDerivation {
|
||||
|
||||
installPhase = ''
|
||||
pushd firefox
|
||||
${zip}/bin/zip -r $out ./*
|
||||
zip -r $out ./*
|
||||
popd
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
yarn-modules = browserpass-extension-yarn-modules;
|
||||
extid = "browserpass@maximbaz.com";
|
||||
};
|
||||
}
|
||||
|
@@ -20,8 +20,10 @@ stdenv.mkDerivation rec {
|
||||
./0003-disable-metrics.patch
|
||||
];
|
||||
|
||||
nativeBuildInputs = [ zip ];
|
||||
|
||||
installPhase = ''
|
||||
${zip}/bin/zip -r $out ./*
|
||||
zip -r $out ./*
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
|
@@ -29,7 +29,7 @@ let
|
||||
};
|
||||
in (stdenv.mkDerivation ({
|
||||
# heavily borrows from <repo:nixos/nixpkgs:pkgs/build-support/fetchfirefoxaddon/default.nix>
|
||||
inherit (addon) name;
|
||||
name = "${addon.name}-wrapped";
|
||||
unpackPhase = ''
|
||||
echo "patching firefox addon $name into $out/${extid}.xpi"
|
||||
|
||||
@@ -64,7 +64,7 @@ let
|
||||
'';
|
||||
} // args')).overrideAttrs (final: upstream: {
|
||||
passthru = (upstream.passthru or {}) // {
|
||||
withAttrs = attrs: wrapAddon final.finalPackage attrs;
|
||||
withAttrs = attrs: wrapAddon addon (args // attrs);
|
||||
withPostPatch = postPatch: final.passthru.withAttrs { inherit postPatch; };
|
||||
# given an addon, repackage it without some `perm`ission
|
||||
withoutPermission = perm: final.passthru.withPostPatch ''
|
||||
@@ -92,9 +92,9 @@ in lib.makeScope newScope (self: with self; {
|
||||
ether-metamask = fetchAddon "ether-metamask" "webextension@metamask.io" "sha256-UI83wUUc33OlQYX+olgujeppoo2D2PAUJ+Wma5mH2O0=";
|
||||
i2p-in-private-browsing = fetchAddon "i2p-in-private-browsing" "i2ppb@eyedeekay.github.io" "sha256-dJcJ3jxeAeAkRvhODeIVrCflvX+S4E0wT/PyYzQBQWs=";
|
||||
sidebery = fetchAddon "sidebery" "{3c078156-979c-498b-8990-85f7987dd929}" "sha256-YONfK/rIjlsrTgRHIt3km07Q7KnpIW89Z9r92ZSCc6w=";
|
||||
sponsorblock = fetchAddon "sponsorblock" "sponsorBlocker@ajay.app" "sha256-b/OTFmhSEUZ/CYrYCE4rHVMQmY+Y78k8jSGMoR8vsZA=";
|
||||
sponsorblock = fetchAddon "sponsorblock" "sponsorBlocker@ajay.app" "sha256-kIVx/Yl2IZ0/0RqLMf4+HJojoDA7oOUYwZfFvMt/2XE=";
|
||||
ublacklist = fetchAddon "ublacklist" "@ublacklist" "sha256-NZ2FmgJiYnH7j2Lkn0wOembxaEphmUuUk0Ytmb0rNWo=";
|
||||
ublock-origin = fetchAddon "ublock-origin" "uBlock0@raymondhill.net" "sha256-EGGAA+cLUow/F5luNzFG055rFfd3rEyh8hTaL/23pbM=";
|
||||
ublock-origin = fetchAddon "ublock-origin" "uBlock0@raymondhill.net" "sha256-i3NGi8IzoR3SiVIZRmOBeD0ZEjhX3Qtv0WoBgg/KSDQ=";
|
||||
|
||||
# TODO: build bypass-paywalls from source? it's mysteriously disappeared from the Mozilla store.
|
||||
# bypass-paywalls-clean = fetchAddon "bypass-paywalls-clean" "{d133e097-46d9-4ecc-9903-fa6a722a6e0e}" "sha256-oUwdqdAwV3DezaTtOMx7A/s4lzIws+t2f08mwk+324k=";
|
||||
@@ -113,7 +113,8 @@ in lib.makeScope newScope (self: with self; {
|
||||
# XXX: i tried to build sponsorblock from source and patch this *before* it gets webpack'd,
|
||||
# but web shit is absolutely cursed and building from source requires a fucking PhD
|
||||
# (if you have one, feel free to share your nix package)
|
||||
${gnused}/bin/sed -i 's/default\.config\.userID)/default.config.userID && false)/' js/background.js
|
||||
substituteInPlace js/background.js \
|
||||
--replace 'default.config.userId)' 'default.config.userID && false)'
|
||||
'';
|
||||
|
||||
ublacklist = wrapAddon unwrapped.ublacklist {};
|
||||
|
5684
pkgs/additional/fractal-latest/Cargo.lock
generated
Normal file
5684
pkgs/additional/fractal-latest/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user