Compare commits
195 Commits
staging/li
...
wip/sxmo-a
Author | SHA1 | Date | |
---|---|---|---|
50fa70ca56 | |||
86855b0c40 | |||
931838fb0d | |||
ec3a7067b6 | |||
8cb236b0a9 | |||
5f47372f6a | |||
afe27fd9cb | |||
e8265807a9 | |||
85ecaf64e9 | |||
33b33a9237 | |||
fecd2fa7d3 | |||
74ec65c8a9 | |||
21a060d856 | |||
6249f7553c | |||
96c976a3b0 | |||
d48d3a979f | |||
ab8ee51321 | |||
74891fb2f0 | |||
f62bd83eb8 | |||
c977665214 | |||
b3a605c76b | |||
2cbd44b2b3 | |||
689c63a905 | |||
ed2480f48c | |||
7aad3a62ba | |||
1583b213f1 | |||
db851d960c | |||
fb7cb091e3 | |||
048dbc5809 | |||
bb1a2c9dcb | |||
86c8fe1466 | |||
95f6fd7082 | |||
5fb52ba38e | |||
4f8d0023ef | |||
280c4aa2e8 | |||
fd270dd0b8 | |||
8e17e2beb2 | |||
d68704474d | |||
0fa5b5bf52 | |||
9caa2a0a17 | |||
023e28fb03 | |||
bed33fae60 | |||
3b958ba356 | |||
adb6ff4c66 | |||
931c76c2e7 | |||
d95042ab65 | |||
0605094461 | |||
4eb6c1fd7d | |||
c553e74cd6 | |||
4eb6f59b01 | |||
9f55a8288d | |||
feb299eb22 | |||
b21c79a0b4 | |||
c819bc2d95 | |||
21006e52dc | |||
5562d60cbb | |||
17041384e9 | |||
9eb36441e1 | |||
0d0a9fce6a | |||
847e618dee | |||
c4e345e2e7 | |||
c75719e751 | |||
7a57cf5327 | |||
b81642ccc9 | |||
57ca3e67b3 | |||
bcca6b6096 | |||
79772d4e3d | |||
339c0a47ab | |||
b1be78529b | |||
cce53b968b | |||
1d55b98cd1 | |||
e9d45c3b31 | |||
32dde42ee2 | |||
b60986cfb8 | |||
60ef232bc0 | |||
7f7bc33be5 | |||
f52f56a34c | |||
425de71583 | |||
0bd87077c1 | |||
601bf567eb | |||
4f74078423 | |||
f170351de7 | |||
bee9dab513 | |||
16c3d4289e | |||
21e0c0d00f | |||
fdf85156bc | |||
79a7daca12 | |||
3996e1be08 | |||
8b1dbd42da | |||
a2c7edf340 | |||
9b365d1771 | |||
8cf3402be4 | |||
a92fa489cb | |||
837f20e892 | |||
3d56117d65 | |||
1724ac60e5 | |||
bf168c7f0f | |||
37cafcf610 | |||
27d2f756d2 | |||
3ab33956e4 | |||
0b71712208 | |||
f31619d9e9 | |||
61838a589f | |||
c10c887650 | |||
6df61525a1 | |||
e5ce7c02ef | |||
88e5efd1f3 | |||
e9200ffcdf | |||
ab78a36354 | |||
c92f216a5b | |||
eacd3c88d1 | |||
487fbf2236 | |||
97f93e8ec0 | |||
e1eac4ae46 | |||
44d0b4efd4 | |||
9ab85167c3 | |||
9730659f32 | |||
b45981e870 | |||
95c9b5d6a2 | |||
05f10f0115 | |||
86b15d381f | |||
ecaab07bce | |||
4fd4efa22f | |||
527585e7eb | |||
481110fefb | |||
c44f69a01f | |||
adbc2a76c3 | |||
34ed201aff | |||
4d63b81b05 | |||
e1a18cdae1 | |||
2a1d87650b | |||
4a18dfeef3 | |||
ff1aece1ed | |||
05cf5e376a | |||
855a66499f | |||
b9cc581736 | |||
0a8eee8af0 | |||
a40fc7e112 | |||
6bbb5669a6 | |||
c8d5411462 | |||
af4cfc29b1 | |||
9942025a2f | |||
04f7287781 | |||
14ae501433 | |||
46edc56a32 | |||
7907623887 | |||
c542e120ef | |||
7fcff0b6a2 | |||
32671201a4 | |||
4d2268b5f1 | |||
e5fe7c093a | |||
162f3a291c | |||
31740befbf | |||
0c610c8f1c | |||
e9dc22c1f2 | |||
75e6393680 | |||
9ca6857f4d | |||
8c30b87a94 | |||
6ffd6693cb | |||
e11fe929f4 | |||
3dcd5629a7 | |||
4cf4c38da3 | |||
e0e3c36d1b | |||
108c1d9d60 | |||
c6e16ebc13 | |||
aa60838551 | |||
d6bde02dfe | |||
d07bb03936 | |||
1ab2f42ff4 | |||
e0d20cb62a | |||
f8944c8379 | |||
ca38bb4aec | |||
287817056f | |||
5cc7ced859 | |||
4dc5378b3e | |||
fe7e440997 | |||
e4262cb0bc | |||
35c9f2bf60 | |||
13794e9eaa | |||
a33950da62 | |||
37995e23c2 | |||
66156829d9 | |||
3c40fa6982 | |||
c1ddddddc0 | |||
aae118b476 | |||
7e402ce974 | |||
5b80308074 | |||
e5c94b410f | |||
209c18cb38 | |||
616a2dd19f | |||
5b0f898c62 | |||
a541e866a1 | |||
d3eb0bee26 | |||
2ca0f6ea62 | |||
66be38bfbf |
17
TODO.md
17
TODO.md
@@ -1,3 +1,7 @@
|
||||
## BUGS
|
||||
- why i need to manually restart `wireguard-wg-ovpns` on servo periodically
|
||||
- else DNS fails
|
||||
|
||||
## REFACTORING:
|
||||
### sops/secrets
|
||||
- attach secrets to the thing they're used by (sane.programs)
|
||||
@@ -9,10 +13,16 @@
|
||||
- will make it easier to test new services?
|
||||
|
||||
### upstreaming
|
||||
- split out a trust-dns module
|
||||
- see: <https://github.com/NixOS/nixpkgs/pull/205866#issuecomment-1575753054>
|
||||
- bump nodejs version in lemmy-ui
|
||||
- add updateScripts to all my packages in nixpkgs
|
||||
- fix lightdm-mobile-greeter for newer libhandy
|
||||
- port zecwallet-lite to a from-source build
|
||||
- fix or abandon Whalebird
|
||||
- FIX failed CI on bonsai PR: <https://github.com/NixOS/nixpkgs/pull/233892>
|
||||
- REVIEW/integrate jellyfin dataDir config: <https://github.com/NixOS/nixpkgs/pull/233617>
|
||||
- remove `libsForQt5.callPackage` broadly: <https://github.com/NixOS/nixpkgs/issues/180841>
|
||||
|
||||
|
||||
## IMPROVEMENTS:
|
||||
@@ -33,6 +43,8 @@
|
||||
- allows (maybe) to cache media for offline use
|
||||
- "newer" jellyfin client
|
||||
- not packaged for nix
|
||||
- moby/sxmo: display numerical vol percentage in topbar
|
||||
- moby/sxmo: include librewolf, jellyfin in `apps` menu
|
||||
- find a nice desktop ActivityPub client
|
||||
- package Nix/NixOS docs for Zeal
|
||||
- install [doc-browser](https://github.com/qwfy/doc-browser)
|
||||
@@ -42,10 +54,7 @@
|
||||
- have xdg-open parse `<repo:...> URIs (or adjust them so that it _can_ parse)
|
||||
- `sane.programs`: auto-populate defaults with everything from `pkgs`
|
||||
- zsh: disable "command not found" corrections
|
||||
- sxmo: allow rotation to the upside-down position
|
||||
- see: <repo:mil/sxmo-utils:scripts/core/sxmo_autorotate.sh>
|
||||
- all orientations *except* upside down are supported
|
||||
- sxmo: launch with auto-rotation enabled
|
||||
- sane-bt-search: show details like 5.1 vs stereo, h264 vs h265
|
||||
|
||||
### perf
|
||||
- why does nixos-rebuild switch take 5 minutes when net is flakey?
|
||||
|
28
flake.lock
generated
28
flake.lock
generated
@@ -66,27 +66,27 @@
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1684025543,
|
||||
"narHash": "sha256-hGe7S+i5je+8E/b2mOXVI9nmr038Dw+bV8e1P8xHSe0=",
|
||||
"lastModified": 1687031877,
|
||||
"narHash": "sha256-yMFcVeI+kZ6KD2QBrFPNsvBrLq2Gt//D0baHByMrjFY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "c6d2f3dc0d3efd4285eebe4f8a36a47ba438138e",
|
||||
"rev": "e2e2059d19668dab1744301b8b0e821e3aae9c99",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "release-22.11",
|
||||
"ref": "release-23.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unpatched": {
|
||||
"locked": {
|
||||
"lastModified": 1684385584,
|
||||
"narHash": "sha256-O7y0gK8OLIDqz+LaHJJyeu09IGiXlZIS3+JgEzGmmJA=",
|
||||
"lastModified": 1686960236,
|
||||
"narHash": "sha256-AYCC9rXNLpUWzD9hm+askOfpliLEC9kwAo7ITJc4HIw=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "48a0fb7aab511df92a17cf239c37f2bd2ec9ae3a",
|
||||
"rev": "04af42f3b31dba0ef742d254456dc4c14eedac86",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -113,11 +113,11 @@
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1684032930,
|
||||
"narHash": "sha256-ueeSYDii2e5bkKrsSdP12JhkW9sqgYrUghLC8aDfYGQ=",
|
||||
"lastModified": 1687058111,
|
||||
"narHash": "sha256-xDSn/APfAdJinHV4reTfplX5XnLsJSGdVwHpmdgP9Mo=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "a376127bb5277cd2c337a9458744f370aaf2e08d",
|
||||
"rev": "1634d2da53f079e7f5924efa7a96511cd9596f81",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -134,11 +134,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1684528780,
|
||||
"narHash": "sha256-QdYxjcTCCLPv++1v9tJBL98nn/AFx0fmzlgzcLK6KRE=",
|
||||
"lastModified": 1686876043,
|
||||
"narHash": "sha256-71SNPU2aeeJx29JSeW4JCJb8HXAuZRvL7sbh+c3wgkk=",
|
||||
"ref": "refs/heads/master",
|
||||
"rev": "f3747a1dad3d34880613821faf26357ba432d3d7",
|
||||
"revCount": 194,
|
||||
"rev": "0e0aa12aca143639f158b3a5c0c00349fcc2166c",
|
||||
"revCount": 199,
|
||||
"type": "git",
|
||||
"url": "https://git.uninsane.org/colin/uninsane"
|
||||
},
|
||||
|
@@ -252,7 +252,7 @@
|
||||
deployScript = action: pkgs.writeShellScript "deploy-moby" ''
|
||||
nixos-rebuild --flake '.#moby' build $@
|
||||
sudo nix sign-paths -r -k /run/secrets/nix_serve_privkey $(readlink ./result)
|
||||
nixos-rebuild --flake '.#moby' ${action} --target-host colin@moby-hn --use-remote-sudo $@
|
||||
nixos-rebuild --flake '.#moby' ${action} --target-host colin@moby --use-remote-sudo $@
|
||||
'';
|
||||
in {
|
||||
update-feeds = {
|
||||
|
@@ -19,6 +19,7 @@
|
||||
sane.programs.iphoneUtils.enableFor.user.colin = true;
|
||||
|
||||
sane.programs.guiApps.suggestedPrograms = [ "desktopGuiApps" ];
|
||||
sane.programs.consoleUtils.suggestedPrograms = [ "consoleMediaUtils" ];
|
||||
|
||||
boot.loader.efi.canTouchEfiVariables = false;
|
||||
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
||||
|
@@ -19,6 +19,7 @@
|
||||
"desktopGuiApps"
|
||||
"stepmania"
|
||||
];
|
||||
sane.programs.consoleUtils.suggestedPrograms = [ "consoleMediaUtils" ];
|
||||
|
||||
sops.secrets.colin-passwd.neededForUsers = true;
|
||||
|
||||
|
@@ -33,11 +33,16 @@
|
||||
".config/pulse" # persist pulseaudio volume
|
||||
];
|
||||
|
||||
sane.gui.phosh.enable = true;
|
||||
sane.gui.sxmo.enable = true;
|
||||
# sane.programs.consoleUtils.enableFor.user.colin = false;
|
||||
# sane.programs.guiApps.enableFor.user.colin = false;
|
||||
sane.programs.sequoia.enableFor.user.colin = false;
|
||||
sane.programs.tuiApps.enableFor.user.colin = false; # visidata, others, don't compile well
|
||||
# disabled for faster deploys (gthumb depends on webkitgtk, particularly)
|
||||
sane.programs.soundconverter.enableFor.user.colin = false;
|
||||
sane.programs.gthumb.enableFor.user.colin = false;
|
||||
sane.programs.jellyfin-media-player.enableFor.user.colin = false;
|
||||
# sane.programs.mpv.enableFor.user.colin = true;
|
||||
|
||||
boot.loader.efi.canTouchEfiVariables = false;
|
||||
# /boot space is at a premium. default was 20.
|
||||
@@ -77,14 +82,30 @@
|
||||
# enable rotation sensor
|
||||
hardware.sensor.iio.enable = true;
|
||||
|
||||
# from https://gitlab.manjaro.org/manjaro-arm/packages/community/phosh/alsa-ucm-pinephone
|
||||
# mobile-nixos does this same thing, with *slightly different settings*.
|
||||
# i trust manjaro more because the guy maintaining that is actively trying to upstream into alsa-ucm-conf.
|
||||
# an alternative may be to build a custom alsa with the PinePhone config patch applied:
|
||||
# - <https://github.com/alsa-project/alsa-ucm-conf/pull/134>
|
||||
# that would make this be not device-specific
|
||||
environment.variables.ALSA_CONFIG_UCM2 = "${./ucm2}";
|
||||
systemd.services.pulseaudio.environment.ALSA_CONFIG_UCM2 = "${./ucm2}";
|
||||
# inject specialized alsa configs via the environment.
|
||||
# specifically, this gets the pinephone headphones & internal earpiece working.
|
||||
# see pkgs/patched/alsa-ucm-conf for more info.
|
||||
environment.variables.ALSA_CONFIG_UCM2 = "/run/current-system/sw/share/alsa/ucm2";
|
||||
environment.pathsToLink = [ "/share/alsa/ucm2" ];
|
||||
environment.systemPackages = [ pkgs.alsa-ucm-conf-sane ];
|
||||
systemd =
|
||||
let ucm-env = config.environment.variables.ALSA_CONFIG_UCM2;
|
||||
in {
|
||||
# cribbed from <repo:nixos/mobile-nixos:modules/quirks/audio.nix>
|
||||
|
||||
# pulseaudio
|
||||
user.services.pulseaudio.environment.ALSA_CONFIG_UCM2 = ucm-env;
|
||||
services.pulseaudio.environment.ALSA_CONFIG_UCM2 = ucm-env;
|
||||
|
||||
# pipewire
|
||||
user.services.pipewire.environment.ALSA_CONFIG_UCM2 = ucm-env;
|
||||
user.services.pipewire-pulse.environment.ALSA_CONFIG_UCM2 = ucm-env;
|
||||
user.services.wireplumber.environment.ALSA_CONFIG_UCM2 = ucm-env;
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
hardware.opengl.driSupport = true;
|
||||
}
|
||||
|
@@ -5,19 +5,13 @@
|
||||
# touch screen
|
||||
SXMO_LISGD_INPUT_DEVICE = "/dev/input/by-path/platform-1c2ac00.i2c-event";
|
||||
# vol and power are detected correctly by upstream
|
||||
|
||||
# preferences
|
||||
# N.B. some deviceprofiles explicitly set SXMO_SWAY_SCALE, overwriting what we put here.
|
||||
SXMO_SWAY_SCALE = "1.5";
|
||||
SXMO_ROTATION_GRAVITY = "12800";
|
||||
DEFAULT_COUNTRY = "US";
|
||||
BROWSWER = "librewolf";
|
||||
};
|
||||
};
|
||||
# TODO: only populate this if sxmo is enabled?
|
||||
sane.user.fs.".config/sxmo/profile" = sane-lib.fs.wantedText ''
|
||||
# sourced by sxmo_init.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
export SXMO_SWAY_SCALE=1.5
|
||||
export SXMO_ROTATION_GRAVITY=12800
|
||||
|
||||
export DEFAULT_COUNTRY=US
|
||||
export BROWSER=librewolf
|
||||
|
||||
export SXMO_BG_IMG="$(xdg_data_path sxmo/background.jpg)"
|
||||
'';
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
sane.zsh.showDeadlines = false; # ~/knowledge doesn't always exist
|
||||
sane.services.dyn-dns.enable = true;
|
||||
sane.services.wg-home.enable = true;
|
||||
sane.services.wg-home.enableWan = true;
|
||||
sane.services.wg-home.ip = config.sane.hosts.by-name."servo".wg-home.ip;
|
||||
# sane.services.duplicity.enable = true; # TODO: re-enable after HW upgrade
|
||||
|
||||
|
@@ -3,6 +3,12 @@
|
||||
{
|
||||
networking.domain = "uninsane.org";
|
||||
|
||||
sane.ports.openFirewall = true;
|
||||
sane.ports.openUpnp = true;
|
||||
|
||||
# view refused packets with: `sudo journalctl -k`
|
||||
# networking.firewall.logRefusedPackets = true;
|
||||
|
||||
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
|
||||
# Per-interface useDHCP will be mandatory in the future, so this generated config
|
||||
# replicates the default behaviour.
|
||||
@@ -11,9 +17,6 @@
|
||||
# XXX colin: probably don't need this. wlan0 won't be populated unless i touch a value in networking.interfaces.wlan0
|
||||
networking.wireless.enable = false;
|
||||
|
||||
# networking.firewall.enable = false;
|
||||
networking.firewall.enable = true;
|
||||
|
||||
# this is needed to forward packets from the VPN to the host
|
||||
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
|
||||
|
||||
@@ -153,9 +156,9 @@
|
||||
|
||||
# we also bridge DNS traffic
|
||||
${in-ns} ${iptables} -A PREROUTING -t nat -p udp --dport 53 -m iprange --dst-range ${vpn-ip} \
|
||||
-j DNAT --to-destination ${veth-host-ip}:53
|
||||
-j DNAT --to-destination ${veth-host-ip}
|
||||
${in-ns} ${iptables} -A PREROUTING -t nat -p tcp --dport 53 -m iprange --dst-range ${vpn-ip} \
|
||||
-j DNAT --to-destination ${veth-host-ip}:53
|
||||
-j DNAT --to-destination ${veth-host-ip}
|
||||
|
||||
# in order to access DNS in this netns, we need to route it to the VPN's nameservers
|
||||
# - alternatively, we could fix DNS servers like 1.1.1.1.
|
||||
|
@@ -30,5 +30,5 @@ lib.mkIf false
|
||||
proxyPass = "http://${ip}:${builtins.toString port}";
|
||||
};
|
||||
};
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."calibre" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."calibre" = "native";
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@
|
||||
./email
|
||||
./ejabberd.nix
|
||||
./freshrss.nix
|
||||
./ftp
|
||||
./gitea.nix
|
||||
./goaccess.nix
|
||||
./ipfs.nix
|
||||
@@ -17,6 +18,7 @@
|
||||
./lemmy.nix
|
||||
./matrix
|
||||
./navidrome.nix
|
||||
./nfs.nix
|
||||
./nixserve.nix
|
||||
./nginx.nix
|
||||
./pict-rs.nix
|
||||
|
@@ -22,20 +22,60 @@
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "ejabberd"; group = "ejabberd"; directory = "/var/lib/ejabberd"; }
|
||||
];
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
3478 # STUN/TURN
|
||||
5222 # XMPP client -> server
|
||||
5223 # XMPPS client -> server (XMPP over TLS)
|
||||
5269 # XMPP server -> server
|
||||
5270 # XMPPS server -> server (XMPP over TLS)
|
||||
5280 # bosh
|
||||
5281 # bosh (https) ??
|
||||
5349 # STUN/TURN (TLS)
|
||||
5443 # web services (file uploads, websockets, admin)
|
||||
];
|
||||
networking.firewall.allowedUDPPorts = [
|
||||
3478 # STUN/TURN
|
||||
];
|
||||
sane.ports.ports."3478" = {
|
||||
protocol = [ "tcp" "udp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-stun-turn";
|
||||
};
|
||||
sane.ports.ports."5222" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-client-to-server";
|
||||
};
|
||||
sane.ports.ports."5223" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpps-client-to-server"; # XMPP over TLS
|
||||
};
|
||||
sane.ports.ports."5269" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-server-to-server";
|
||||
};
|
||||
sane.ports.ports."5270" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpps-server-to-server"; # XMPP over TLS
|
||||
};
|
||||
sane.ports.ports."5280" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-bosh";
|
||||
};
|
||||
sane.ports.ports."5281" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-bosh-https";
|
||||
};
|
||||
sane.ports.ports."5349" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-stun-turn-over-tls";
|
||||
};
|
||||
sane.ports.ports."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;
|
||||
@@ -75,9 +115,9 @@
|
||||
useACMEHost = "uninsane.org";
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet = {
|
||||
sane.dns.zones."uninsane.org".inet = {
|
||||
# XXX: SRV records have to point to something with a A/AAAA record; no CNAMEs
|
||||
A."xmpp" = "%NATIVE%";
|
||||
A."xmpp" = "%ANATIVE%";
|
||||
CNAME."muc.xmpp" = "xmpp";
|
||||
CNAME."pubsub.xmpp" = "xmpp";
|
||||
CNAME."upload.xmpp" = "xmpp";
|
||||
@@ -234,7 +274,7 @@
|
||||
use_turn: true
|
||||
turn_min_port: 49152
|
||||
turn_max_port: 65535
|
||||
turn_ipv4_address: %NATIVE%
|
||||
turn_ipv4_address: %ANATIVE%
|
||||
-
|
||||
# STUN+TURN UDP
|
||||
port: 3478
|
||||
@@ -243,7 +283,7 @@
|
||||
use_turn: true
|
||||
turn_min_port: 49152
|
||||
turn_max_port: 65535
|
||||
turn_ipv4_address: %NATIVE%
|
||||
turn_ipv4_address: %ANATIVE%
|
||||
-
|
||||
# STUN+TURN TLS over TCP
|
||||
port: 5349
|
||||
@@ -254,7 +294,7 @@
|
||||
use_turn: true
|
||||
turn_min_port: 49152
|
||||
turn_max_port: 65535
|
||||
turn_ipv4_address: %NATIVE%
|
||||
turn_ipv4_address: %ANATIVE%
|
||||
|
||||
# TODO: enable mod_fail2ban
|
||||
# TODO(low): look into mod_http_fileserver for serving macros?
|
||||
@@ -387,7 +427,7 @@
|
||||
# config is 444 (not 644), so we want to write out-of-place and then atomically move
|
||||
# TODO: factor this out into `sane-woop` helper?
|
||||
rm -f /var/lib/ejabberd/ejabberd.yaml.new
|
||||
${sed} "s/%NATIVE%/$ip/" ${config-in} > /var/lib/ejabberd/ejabberd.yaml.new
|
||||
${sed} "s/%ANATIVE%/$ip/" ${config-in} > /var/lib/ejabberd/ejabberd.yaml.new
|
||||
mv /var/lib/ejabberd/ejabberd.yaml{.new,}
|
||||
'';
|
||||
|
||||
|
@@ -6,18 +6,25 @@
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
# exposed over non-vpn imap.uninsane.org
|
||||
143 # IMAP
|
||||
993 # IMAPS
|
||||
];
|
||||
sane.ports.ports."143" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-imap-imap.uninsane.org";
|
||||
};
|
||||
sane.ports.ports."993" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-imaps-imap.uninsane.org";
|
||||
};
|
||||
|
||||
# exists only to manage certs for dovecot
|
||||
services.nginx.virtualHosts."imap.uninsane.org" = {
|
||||
enableACME = true;
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet = {
|
||||
sane.dns.zones."uninsane.org".inet = {
|
||||
CNAME."imap" = "native";
|
||||
};
|
||||
|
||||
|
@@ -28,12 +28,21 @@ in
|
||||
# "/var/lib/dovecot"
|
||||
];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
# exposed over vpn mx.uninsane.org
|
||||
25 # SMTP
|
||||
465 # SMTPS
|
||||
587 # SMTPS/submission
|
||||
];
|
||||
sane.ports.ports."25" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.ovpn = true;
|
||||
description = "colin-smtp-mx.uninsane.org";
|
||||
};
|
||||
sane.ports.ports."465" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.ovpn = true;
|
||||
description = "colin-smtps-mx.uninsane.org";
|
||||
};
|
||||
sane.ports.ports."587" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.ovpn = true;
|
||||
description = "colin-smtps-submission-mx.uninsane.org";
|
||||
};
|
||||
|
||||
# exists only to manage certs for Postfix
|
||||
services.nginx.virtualHosts."mx.uninsane.org" = {
|
||||
@@ -41,7 +50,7 @@ in
|
||||
};
|
||||
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet = {
|
||||
sane.dns.zones."uninsane.org".inet = {
|
||||
MX."@" = "10 mx.uninsane.org.";
|
||||
# XXX: RFC's specify that the MX record CANNOT BE A CNAME
|
||||
A."mx" = "185.157.162.178";
|
||||
|
@@ -59,5 +59,5 @@
|
||||
# the routing is handled by services.freshrss.virtualHost
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."rss" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."rss" = "native";
|
||||
}
|
||||
|
70
hosts/by-name/servo/services/ftp/default.nix
Normal file
70
hosts/by-name/servo/services/ftp/default.nix
Normal file
@@ -0,0 +1,70 @@
|
||||
# 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";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
55
hosts/by-name/servo/services/ftp/sftpgo_external_auth_hook
Executable file
55
hosts/by-name/servo/services/ftp/sftpgo_external_auth_hook
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/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
|
@@ -98,5 +98,12 @@
|
||||
};
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."git" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."git" = "native";
|
||||
|
||||
sane.ports.ports."22" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-git@git.uninsane.org";
|
||||
};
|
||||
}
|
||||
|
@@ -64,5 +64,5 @@
|
||||
};
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."sink" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."sink" = "native";
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@ lib.mkIf false # i don't actively use ipfs anymore
|
||||
};
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."ipfs" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."ipfs" = "native";
|
||||
|
||||
# services.ipfs.enable = true;
|
||||
services.kubo.localDiscovery = true;
|
||||
|
@@ -24,9 +24,10 @@
|
||||
locations."/" = {
|
||||
# proxyPass = "http://ovpns.uninsane.org:9117";
|
||||
proxyPass = "http://10.0.1.6:9117";
|
||||
recommendedProxySettings = true;
|
||||
};
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."jackett" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."jackett" = "native";
|
||||
}
|
||||
|
||||
|
@@ -16,17 +16,30 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
{
|
||||
# identical to:
|
||||
# services.jellyfin.openFirewall = true;
|
||||
networking.firewall.allowedUDPPorts = [
|
||||
# https://jellyfin.org/docs/general/networking/index.html
|
||||
1900 # UPnP service discovery
|
||||
7359 # Jellyfin-specific (?) client discovery
|
||||
];
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
8096 # HTTP (for the LAN)
|
||||
8920 # HTTPS (for the LAN)
|
||||
];
|
||||
# https://jellyfin.org/docs/general/networking/index.html
|
||||
sane.ports.ports."1900" = {
|
||||
protocol = [ "udp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "colin-upnp-for-jellyfin";
|
||||
};
|
||||
sane.ports.ports."7359" = {
|
||||
protocol = [ "udp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "colin-jellyfin-specific-client-discovery";
|
||||
# ^ not sure if this is necessary: copied this port from nixos jellyfin.openFirewall
|
||||
};
|
||||
# not sure if 8096/8920 get used either:
|
||||
sane.ports.ports."8096" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "colin-jellyfin-http-lan";
|
||||
};
|
||||
sane.ports.ports."8920" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "colin-jellyfin-https-lan";
|
||||
};
|
||||
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "jellyfin"; group = "jellyfin"; mode = "0700"; directory = "/var/lib/jellyfin"; }
|
||||
];
|
||||
@@ -108,7 +121,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."jelly" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."jelly" = "native";
|
||||
|
||||
services.jellyfin.enable = true;
|
||||
}
|
||||
|
@@ -13,5 +13,5 @@
|
||||
locations."/".proxyPass = "http://127.0.0.1:8013";
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."w" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."w" = "native";
|
||||
}
|
||||
|
@@ -18,5 +18,5 @@ in
|
||||
proxyPass = "http://127.0.0.1:${builtins.toString port}";
|
||||
};
|
||||
};
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."komga" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."komga" = "native";
|
||||
}
|
||||
|
@@ -14,8 +14,8 @@ in {
|
||||
services.lemmy = {
|
||||
enable = true;
|
||||
settings.hostname = "lemmy.uninsane.org";
|
||||
settings.federation.enabled = true;
|
||||
# federation.debug forces outbound federation queries to be run synchronously
|
||||
# N.B.: this option might not be read for 0.17.0+? <https://github.com/LemmyNet/lemmy/blob/c32585b03429f0f76d1e4ff738786321a0a9df98/RELEASES.md#upgrade-instructions>
|
||||
# settings.federation.debug = true;
|
||||
settings.port = backendPort;
|
||||
ui.port = uiPort;
|
||||
@@ -32,6 +32,7 @@ in {
|
||||
systemd.services.lemmy.environment = {
|
||||
RUST_BACKTRACE = "full";
|
||||
# RUST_LOG = "debug";
|
||||
# RUST_LOG = "trace";
|
||||
# upstream defaults LEMMY_DATABASE_URL = "postgres:///lemmy?host=/run/postgresql";
|
||||
# - Postgres complains that we didn't specify a user
|
||||
# lemmy formats the url as:
|
||||
@@ -54,5 +55,5 @@ in {
|
||||
enableACME = true;
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."lemmy" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."lemmy" = "native";
|
||||
}
|
||||
|
@@ -132,7 +132,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet = {
|
||||
sane.dns.zones."uninsane.org".inet = {
|
||||
CNAME."matrix" = "native";
|
||||
CNAME."web.matrix" = "native";
|
||||
};
|
||||
|
@@ -1,4 +1,9 @@
|
||||
{ lib, ... }:
|
||||
|
||||
# XXX mx-discord-puppet uses nodejs_14 which is EOL
|
||||
# - mx-discord-puppet is abandoned upstream _and_ in nixpkgs
|
||||
# - recommended to use mautrix-discord: <https://github.com/NixOS/nixpkgs/pull/200462>
|
||||
lib.mkIf false
|
||||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "matrix-synapse"; group = "matrix-synapse"; directory = "/var/lib/mx-puppet-discord"; }
|
||||
|
@@ -108,6 +108,12 @@ in
|
||||
{ user = "matrix-appservice-irc"; group = "matrix-appservice-irc"; directory = "/var/lib/matrix-appservice-irc"; }
|
||||
];
|
||||
|
||||
# XXX: matrix-appservice-irc PreStart tries to chgrp the registration.yml to matrix-synapse,
|
||||
# which requires matrix-appservice-irc to be of that group
|
||||
users.users.matrix-appservice-irc.extraGroups = [ "matrix-synapse" ];
|
||||
# weird race conditions around registration.yml mean we want matrix-synapse to be of matrix-appservice-irc group too.
|
||||
users.users.matrix-synapse.extraGroups = [ "matrix-appservice-irc" ];
|
||||
|
||||
services.matrix-synapse.settings.app_service_config_files = [
|
||||
"/var/lib/matrix-appservice-irc/registration.yml" # auto-created by irc appservice
|
||||
];
|
||||
@@ -153,4 +159,10 @@ in
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.matrix-appservice-irc.serviceConfig = {
|
||||
# XXX 2023/06/20: nixos specifies this + @aio and @memlock as forbidden
|
||||
# the service actively uses at least one of these, and both of them are fairly innocuous
|
||||
SystemCallFilter = lib.mkForce "~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @setuid @swap";
|
||||
};
|
||||
}
|
||||
|
@@ -36,5 +36,5 @@
|
||||
locations."/".proxyPass = "http://127.0.0.1:4533";
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."music" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."music" = "native";
|
||||
}
|
||||
|
67
hosts/by-name/servo/services/nfs.nix
Normal file
67
hosts/by-name/servo/services/nfs.nix
Normal file
@@ -0,0 +1,67 @@
|
||||
# docs:
|
||||
# - <https://nixos.wiki/wiki/NFS>
|
||||
# - <https://wiki.gentoo.org/wiki/Nfs-utils>
|
||||
|
||||
{ ... }:
|
||||
{
|
||||
services.nfs.server.enable = true;
|
||||
|
||||
# see which ports NFS uses with:
|
||||
# - `rpcinfo -p`
|
||||
sane.ports.ports."111" = {
|
||||
protocol = [ "tcp" "udp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "NFS server portmapper";
|
||||
};
|
||||
sane.ports.ports."2049" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "NFS server";
|
||||
};
|
||||
sane.ports.ports."4000" = {
|
||||
protocol = [ "udp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "NFS server status daemon";
|
||||
};
|
||||
sane.ports.ports."4001" = {
|
||||
protocol = [ "tcp" "udp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "NFS server lock daemon";
|
||||
};
|
||||
sane.ports.ports."4002" = {
|
||||
protocol = [ "tcp" "udp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "NFS server mount daemon";
|
||||
};
|
||||
|
||||
# NFS4 allows these to float, but NFS3 mandates specific ports, so fix them for backwards compat.
|
||||
services.nfs.server.lockdPort = 4001;
|
||||
services.nfs.server.mountdPort = 4002;
|
||||
services.nfs.server.statdPort = 4000;
|
||||
|
||||
# format:
|
||||
# fspoint visibility(options)
|
||||
# options:
|
||||
# - see: <https://wiki.gentoo.org/wiki/Nfs-utils#Exports>
|
||||
# - see [man 5 exports](https://linux.die.net/man/5/exports)
|
||||
# - insecure: require clients use src port > 1024
|
||||
# - rw, ro (default)
|
||||
# - async, sync (default)
|
||||
# - no_subtree_check (default), subtree_check: verify not just that files requested by the client live
|
||||
# in the expected fs, but also that they live under whatever subdirectory of that fs is exported.
|
||||
# - no_root_squash, root_squash (default): map requests from uid 0 to user `nobody`.
|
||||
# - crossmnt: reveal filesystems that are mounted under this endpoint
|
||||
# - fsid: must be zero for the root export
|
||||
# - mountpoint[=/path]: only export the directory if it's a mountpoint. used to avoid exporting failed mounts.
|
||||
#
|
||||
# 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)
|
||||
'';
|
||||
|
||||
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" ];
|
||||
};
|
||||
}
|
@@ -13,7 +13,19 @@ let
|
||||
in
|
||||
{
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
sane.ports.ports."80" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
visibleTo.ovpn = true; # so that letsencrypt can procure a cert for the mx record
|
||||
description = "colin-http-uninsane.org";
|
||||
};
|
||||
sane.ports.ports."443" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-https-uninsane.org";
|
||||
};
|
||||
|
||||
services.nginx.enable = true;
|
||||
services.nginx.appendConfig = ''
|
||||
|
@@ -14,7 +14,7 @@
|
||||
'';
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."nixcache" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."nixcache" = "native";
|
||||
|
||||
sane.services.nixserve.enable = true;
|
||||
sane.services.nixserve.secretKeyFile = config.sops.secrets.nix_serve_privkey.path;
|
||||
|
@@ -182,7 +182,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."fed" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."fed" = "native";
|
||||
|
||||
sops.secrets."pleroma_secrets" = {
|
||||
owner = config.users.users.pleroma.name;
|
||||
|
@@ -12,12 +12,29 @@ lib.mkIf false
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "prosody"; group = "prosody"; directory = "/var/lib/prosody"; }
|
||||
];
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
5222 # XMPP client -> server
|
||||
5269 # XMPP server -> server
|
||||
5280 # bosh
|
||||
5281 # Prosody HTTPS port (necessary?)
|
||||
];
|
||||
sane.ports.ports."5222" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-client-to-server";
|
||||
};
|
||||
sane.ports.ports."5269" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-server-to-server";
|
||||
};
|
||||
sane.ports.ports."5280" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-bosh";
|
||||
};
|
||||
sane.ports.ports."5281" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-xmpp-prosody-https"; # necessary?
|
||||
};
|
||||
|
||||
# provide access to certs
|
||||
users.users.prosody.extraGroups = [ "nginx" ];
|
||||
|
@@ -75,6 +75,6 @@
|
||||
};
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."bt" = "native";
|
||||
sane.dns.zones."uninsane.org".inet.CNAME."bt" = "native";
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
{ config, pkgs, ... }:
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
sane.services.trust-dns.enable = true;
|
||||
@@ -11,7 +11,7 @@
|
||||
];
|
||||
sane.services.trust-dns.quiet = true;
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".TTL = 900;
|
||||
sane.dns.zones."uninsane.org".TTL = 900;
|
||||
|
||||
# SOA record structure: <https://en.wikipedia.org/wiki/SOA_record#Structure>
|
||||
# SOA MNAME RNAME (... rest)
|
||||
@@ -21,7 +21,7 @@
|
||||
# Refresh = how frequently secondary NS should query master
|
||||
# Retry = how long secondary NS should wait until re-querying master after a failure (must be < Refresh)
|
||||
# Expire = how long secondary NS should continue to reply to queries after master fails (> Refresh + Retry)
|
||||
sane.services.trust-dns.zones."uninsane.org".inet = {
|
||||
sane.dns.zones."uninsane.org".inet = {
|
||||
SOA."@" = ''
|
||||
ns1.uninsane.org. admin-dns.uninsane.org. (
|
||||
2022122101 ; Serial
|
||||
@@ -30,17 +30,20 @@
|
||||
7d ; Expire
|
||||
5m) ; Negative response TTL
|
||||
'';
|
||||
TXT."rev" = "2022122101";
|
||||
TXT."rev" = "2023052901";
|
||||
|
||||
CNAME."native" = "%CNAMENATIVE%";
|
||||
A."@" = "%ANATIVE%";
|
||||
A."wan" = "%AWAN%";
|
||||
A."servo.lan" = config.sane.hosts.by-name."servo".lan-ip;
|
||||
|
||||
# XXX NS records must also not be CNAME
|
||||
# it's best that we keep this identical, or a superset of, what org. lists as our NS.
|
||||
# so, org. can specify ns2/ns3 as being to the VPN, with no mention of ns1. we provide ns1 here.
|
||||
A."ns1" = "%NATIVE%";
|
||||
A."ns1" = "%ANATIVE%";
|
||||
A."ns2" = "185.157.162.178";
|
||||
A."ns3" = "185.157.162.178";
|
||||
A."ovpns" = "185.157.162.178";
|
||||
A."native" = "%NATIVE%";
|
||||
A."@" = "%NATIVE%";
|
||||
NS."@" = [
|
||||
"ns1.uninsane.org."
|
||||
"ns2.uninsane.org."
|
||||
@@ -48,20 +51,70 @@
|
||||
];
|
||||
};
|
||||
|
||||
sane.services.trust-dns.zones."uninsane.org".file =
|
||||
"/var/lib/trust-dns/uninsane.org.zone";
|
||||
# we need trust-dns to load our zone by relative path instead of /nix/store path
|
||||
# because we generate it at runtime.
|
||||
sane.services.trust-dns.zones."uninsane.org".file = lib.mkForce "uninsane.org.zone";
|
||||
sane.services.trust-dns.zonedir = null;
|
||||
|
||||
systemd.services.trust-dns.preStart = let
|
||||
sed = "${pkgs.gnused}/bin/sed";
|
||||
zone-dir = "/var/lib/trust-dns";
|
||||
zone-out = "${zone-dir}/uninsane.org.zone";
|
||||
zone-template = pkgs.writeText "uninsane.org.zone.in" config.sane.services.trust-dns.generatedZones."uninsane.org";
|
||||
in ''
|
||||
# make WAN records available to trust-dns
|
||||
mkdir -p ${zone-dir}
|
||||
ip=$(cat '${config.sane.services.dyn-dns.ipPath}')
|
||||
${sed} s/%NATIVE%/$ip/ ${zone-template} > ${zone-out}
|
||||
'';
|
||||
sane.services.trust-dns.package =
|
||||
let
|
||||
sed = "${pkgs.gnused}/bin/sed";
|
||||
zone-dir = "/var/lib/trust-dns";
|
||||
zone-wan = "${zone-dir}/wan/uninsane.org.zone";
|
||||
zone-lan = "${zone-dir}/lan/uninsane.org.zone";
|
||||
zone-template = pkgs.writeText "uninsane.org.zone.in" config.sane.services.trust-dns.zones."uninsane.org".text;
|
||||
in pkgs.writeShellScriptBin "named" ''
|
||||
# compute wan/lan values
|
||||
mkdir -p ${zone-dir}/{ovpn,wan,lan}
|
||||
wan=$(cat '${config.sane.services.dyn-dns.ipPath}')
|
||||
lan=${config.sane.hosts.by-name."servo".lan-ip}
|
||||
|
||||
# create specializations that resolve native.uninsane.org to different CNAMEs
|
||||
${sed} s/%AWAN%/$wan/ ${zone-template} \
|
||||
| ${sed} s/%CNAMENATIVE%/wan/ \
|
||||
| ${sed} s/%ANATIVE%/$wan/ \
|
||||
> ${zone-wan}
|
||||
${sed} s/%AWAN%/$wan/ ${zone-template} \
|
||||
| ${sed} s/%CNAMENATIVE%/servo.lan/ \
|
||||
| ${sed} s/%ANATIVE%/$lan/ \
|
||||
> ${zone-lan}
|
||||
|
||||
# launch the different interfaces, separately
|
||||
${pkgs.trust-dns}/bin/named --port 53 --zonedir ${zone-dir}/wan/ $@ &
|
||||
WANPID=$!
|
||||
${pkgs.trust-dns}/bin/named --port 1053 --zonedir ${zone-dir}/lan/ $@ &
|
||||
LANPID=$!
|
||||
|
||||
# wait until any of the processes exits, then kill them all and exit error
|
||||
while kill -0 $WANPID $LANPID ; do
|
||||
sleep 5
|
||||
done
|
||||
kill $WANPID $LANPID
|
||||
exit 1
|
||||
'';
|
||||
|
||||
sane.services.dyn-dns.restartOnChange = [ "trust-dns.service" ];
|
||||
|
||||
networking.nat.enable = true;
|
||||
networking.nat.extraCommands = ''
|
||||
# redirect incoming DNS requests from LAN addresses
|
||||
# to the LAN-specialized DNS service
|
||||
# N.B.: use the `nixos-*` chains instead of e.g. PREROUTING
|
||||
# because they get cleanly reset across activations or `systemctl restart firewall`
|
||||
# instead of accumulating cruft
|
||||
iptables -t nat -A nixos-nat-pre -p udp --dport 53 \
|
||||
-m iprange --src-range 10.78.76.0-10.78.79.255 \
|
||||
-j DNAT --to-destination :1053
|
||||
iptables -t nat -A nixos-nat-pre -p tcp --dport 53 \
|
||||
-m iprange --src-range 10.78.76.0-10.78.79.255 \
|
||||
-j DNAT --to-destination :1053
|
||||
'';
|
||||
|
||||
sane.ports.ports."1053" = {
|
||||
# because the NAT above redirects in nixos-nat-pre, LAN requests behave as though they arrived on the external interface at the redirected port.
|
||||
# TODO: try nixos-nat-post instead?
|
||||
protocol = [ "udp" "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
description = "colin-redirected-dns-for-lan-namespace";
|
||||
};
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@
|
||||
./ids.nix
|
||||
./machine-id.nix
|
||||
./net.nix
|
||||
./nix-path
|
||||
./persist.nix
|
||||
./programs
|
||||
./secrets.nix
|
||||
@@ -36,11 +37,6 @@
|
||||
nix.extraOptions = ''
|
||||
experimental-features = nix-command flakes
|
||||
'';
|
||||
# allow `nix-shell` (and probably nix-index?) to locate our patched and custom packages
|
||||
nix.nixPath = [
|
||||
"nixpkgs=${pkgs.path}"
|
||||
"nixpkgs-overlays=${../..}/overlays"
|
||||
];
|
||||
# hardlinks identical files in the nix store to save 25-35% disk space.
|
||||
# unclear _when_ this occurs. it's not a service.
|
||||
# does the daemon continually scan the nix store?
|
||||
|
@@ -76,15 +76,17 @@ let
|
||||
## Multidisciplinary Association for Psychedelic Studies
|
||||
(fromDb "mapspodcast.libsyn.com" // uncat)
|
||||
(fromDb "allinchamathjason.libsyn.com" // pol)
|
||||
(fromDb "acquired.libsyn.com" // tech)
|
||||
(fromDb "feeds.transistor.fm/acquired" // tech)
|
||||
## ACQ2 - more "Acquired" episodes
|
||||
(fromDb "acquiredlpbonussecretsecret.libsyn.com" // tech)
|
||||
# The Intercept - Deconstructed; also available: <rss.acast.com/deconstructed>
|
||||
(fromDb "rss.prod.firstlook.media/deconstructed/podcast.rss" // pol)
|
||||
# The Intercept - Deconstructed
|
||||
(fromDb "rss.acast.com/deconstructed")
|
||||
# (fromDb "rss.prod.firstlook.media/deconstructed/podcast.rss" // pol) #< possible URL rot
|
||||
## The Daily
|
||||
(mkPod "https://feeds.simplecast.com/54nAGcIl" // pol // daily)
|
||||
# The Intercept - Intercepted; also available: <https://rss.acast.com/intercepted-with-jeremy-scahill>
|
||||
(fromDb "rss.prod.firstlook.media/intercepted/podcast.rss" // pol)
|
||||
# The Intercept - Intercepted
|
||||
(fromDb "rss.acast.com/intercepted-with-jeremy-scahill")
|
||||
# (fromDb "rss.prod.firstlook.media/intercepted/podcast.rss" // pol) #< possible URL rot
|
||||
(fromDb "podcast.posttv.com/itunes/post-reports.xml" // pol)
|
||||
## Eric Weinstein
|
||||
(fromDb "rss.art19.com/the-portal" // rat)
|
||||
|
@@ -1,72 +1,131 @@
|
||||
{ pkgs, ... }:
|
||||
# docs
|
||||
# - x-systemd options: <https://www.freedesktop.org/software/systemd/man/systemd.mount.html>
|
||||
|
||||
let sshOpts = rec {
|
||||
fsType = "fuse.sshfs";
|
||||
optionsBase = [
|
||||
"x-systemd.automount"
|
||||
{ pkgs, sane-lib, ... }:
|
||||
|
||||
let fsOpts = rec {
|
||||
common = [
|
||||
"_netdev"
|
||||
"noatime"
|
||||
"x-systemd.requires=network-online.target"
|
||||
"x-systemd.after=network-online.target"
|
||||
"x-systemd.mount-timeout=10s" # how long to wait for mount **and** how long to wait for unmount
|
||||
];
|
||||
auto = [ "x-systemd.automount" ];
|
||||
noauto = [ "noauto" ]; # don't mount as part of remote-fs.target
|
||||
wg = [
|
||||
"x-systemd.requires=wireguard-wg-home.service"
|
||||
"x-systemd.after=wireguard-wg-home.service"
|
||||
];
|
||||
|
||||
ssh = common ++ [
|
||||
"user"
|
||||
"identityfile=/home/colin/.ssh/id_ed25519"
|
||||
"allow_other"
|
||||
"default_permissions"
|
||||
];
|
||||
optionsColin = optionsBase ++ [
|
||||
sshColin = ssh ++ [
|
||||
"transform_symlinks"
|
||||
"idmap=user"
|
||||
"uid=1000"
|
||||
"gid=100"
|
||||
];
|
||||
|
||||
optionsRoot = optionsBase ++ [
|
||||
sshRoot = ssh ++ [
|
||||
# we don't transform_symlinks because that breaks the validity of remote /nix stores
|
||||
"sftp_server=/run/wrappers/bin/sudo\\040/run/current-system/sw/libexec/sftp-server"
|
||||
];
|
||||
# in the event of hunt NFS mounts, consider:
|
||||
# - <https://unix.stackexchange.com/questions/31979/stop-broken-nfs-mounts-from-locking-a-directory>
|
||||
|
||||
# NFS options: <https://linux.die.net/man/5/nfs>
|
||||
# actimeo=n = how long (in seconds) to cache file/dir attributes (default: 3-60s)
|
||||
# bg = retry failed mounts in the background
|
||||
# retry=n = for how many minutes `mount` will retry NFS mount operation
|
||||
# soft = on "major timeout", report I/O error to userspace
|
||||
# retrans=n = how many times to retry a NFS request before giving userspace a "server not responding" error (default: 3)
|
||||
# timeo=n = number of *deciseconds* to wait for a response before retrying it (default: 600)
|
||||
# note: client uses a linear backup, so the second request will have double this timeout, then triple, etc.
|
||||
nfs = common ++ [
|
||||
# "actimeo=10"
|
||||
"bg"
|
||||
"retrans=4"
|
||||
"retry=0"
|
||||
"soft"
|
||||
"timeo=15"
|
||||
"nofail" # don't fail remote-fs.target when this mount fails (not an option for sshfs else would be common)
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
# fileSystems."/mnt/servo-nfs" = {
|
||||
# device = "servo-hn:/";
|
||||
# noCheck = true;
|
||||
# fsType = "nfs";
|
||||
# options = fsOpts.nfs ++ fsOpts.auto ++ fsOpts.wg;
|
||||
# };
|
||||
fileSystems."/mnt/servo-nfs/media" = {
|
||||
device = "servo-hn:/media";
|
||||
noCheck = true;
|
||||
fsType = "nfs";
|
||||
options = fsOpts.nfs ++ fsOpts.auto ++ fsOpts.wg;
|
||||
};
|
||||
# fileSystems."/mnt/servo-media-nfs" = {
|
||||
# device = "servo-hn:/media";
|
||||
# noCheck = true;
|
||||
# fsType = "nfs";
|
||||
# options = fsOpts.common ++ fsOpts.auto;
|
||||
# };
|
||||
sane.fs."/mnt/servo-media" = sane-lib.fs.wantedSymlinkTo "/mnt/servo-nfs/media";
|
||||
|
||||
fileSystems."/mnt/servo-media-wan" = {
|
||||
device = "colin@uninsane.org:/var/lib/uninsane/media";
|
||||
fsType = "fuse.sshfs";
|
||||
options = fsOpts.sshColin ++ fsOpts.noauto;
|
||||
noCheck = true;
|
||||
};
|
||||
sane.fs."/mnt/servo-media-wan" = sane-lib.fs.wantedDir;
|
||||
fileSystems."/mnt/servo-media-lan" = {
|
||||
device = "colin@servo:/var/lib/uninsane/media";
|
||||
fsType = "fuse.sshfs";
|
||||
options = fsOpts.sshColin ++ fsOpts.noauto;
|
||||
noCheck = true;
|
||||
};
|
||||
sane.fs."/mnt/servo-media-lan" = sane-lib.fs.wantedDir;
|
||||
fileSystems."/mnt/servo-root-wan" = {
|
||||
device = "colin@uninsane.org:/";
|
||||
fsType = "fuse.sshfs";
|
||||
options = fsOpts.sshRoot ++ fsOpts.noauto;
|
||||
noCheck = true;
|
||||
};
|
||||
sane.fs."/mnt/servo-root-wan" = sane-lib.fs.wantedDir;
|
||||
fileSystems."/mnt/servo-root-lan" = {
|
||||
device = "colin@servo:/";
|
||||
fsType = "fuse.sshfs";
|
||||
options = fsOpts.sshRoot ++ fsOpts.noauto;
|
||||
noCheck = true;
|
||||
};
|
||||
sane.fs."/mnt/servo-root-lan" = sane-lib.fs.wantedDir;
|
||||
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
|
||||
"/libexec"
|
||||
];
|
||||
|
||||
fileSystems."/mnt/servo-media-wan" = {
|
||||
device = "colin@uninsane.org:/var/lib/uninsane/media";
|
||||
inherit (sshOpts) fsType;
|
||||
options = sshOpts.optionsColin;
|
||||
noCheck = true;
|
||||
};
|
||||
fileSystems."/mnt/servo-media-lan" = {
|
||||
device = "colin@servo:/var/lib/uninsane/media";
|
||||
inherit (sshOpts) fsType;
|
||||
options = sshOpts.optionsColin;
|
||||
noCheck = true;
|
||||
};
|
||||
fileSystems."/mnt/servo-root-wan" = {
|
||||
device = "colin@uninsane.org:/";
|
||||
inherit (sshOpts) fsType;
|
||||
options = sshOpts.optionsRoot;
|
||||
noCheck = true;
|
||||
};
|
||||
fileSystems."/mnt/servo-root-lan" = {
|
||||
device = "colin@servo:/";
|
||||
inherit (sshOpts) fsType;
|
||||
options = sshOpts.optionsRoot;
|
||||
noCheck = true;
|
||||
};
|
||||
fileSystems."/mnt/desko-home" = {
|
||||
device = "colin@desko:/home/colin";
|
||||
inherit (sshOpts) fsType;
|
||||
options = sshOpts.optionsColin;
|
||||
noCheck = true;
|
||||
};
|
||||
fileSystems."/mnt/desko-root" = {
|
||||
device = "colin@desko:/";
|
||||
inherit (sshOpts) fsType;
|
||||
options = sshOpts.optionsRoot;
|
||||
noCheck = true;
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
pkgs.sshfs-fuse
|
||||
];
|
||||
|
@@ -40,6 +40,8 @@
|
||||
sane.ids.lemmy.gid = 2408;
|
||||
sane.ids.pict-rs.uid = 2409;
|
||||
sane.ids.pict-rs.gid = 2409;
|
||||
sane.ids.sftpgo.uid = 2410;
|
||||
sane.ids.sftpgo.gid = 2410;
|
||||
|
||||
sane.ids.colin.uid = 1000;
|
||||
sane.ids.guest.uid = 1100;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{ lib, ... }:
|
||||
|
||||
{
|
||||
# the default backend is "wpa_supplicant".
|
||||
@@ -20,4 +20,8 @@
|
||||
General.RoamThreshold = "-52"; # default -70
|
||||
General.RoamThreshold5G = "-52"; # default -76
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [
|
||||
1900 # to received UPnP advertisements. required by sane-ip-check-upnp
|
||||
];
|
||||
}
|
||||
|
13
hosts/common/nix-path/default.nix
Normal file
13
hosts/common/nix-path/default.nix
Normal file
@@ -0,0 +1,13 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
# allow `nix-shell` (and probably nix-index?) to locate our patched and custom packages
|
||||
nix.nixPath = [
|
||||
"nixpkgs=${pkgs.path}"
|
||||
# note the import starts at repo root: this allows `./overlay/default.nix` to access the stuff at the root
|
||||
# "nixpkgs-overlays=${../../..}/hosts/common/nix-path/overlay"
|
||||
# as long as my system itself doesn't rely on NIXPKGS at runtime, we can point the overlays to git
|
||||
# to avoid switching so much during development
|
||||
"nixpkgs-overlays=/home/colin/dev/nixos/hosts/common/nix-path/overlay"
|
||||
];
|
||||
}
|
4
hosts/common/nix-path/overlay/default.nix
Normal file
4
hosts/common/nix-path/overlay/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
# XXX: NIX_PATH=...:nixpkgs-overlays=... will import every overlay in the directory
|
||||
# so we prefer to give it a directory with just this *one* overlay, otherwise it imports conflicting overlays
|
||||
# and gets stuck in a loop until it OOMs
|
||||
import ../../../../overlays/all.nix
|
385
hosts/common/programs/assorted.nix
Normal file
385
hosts/common/programs/assorted.nix
Normal file
@@ -0,0 +1,385 @@
|
||||
{ lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (builtins) attrNames;
|
||||
|
||||
flattenedPkgs = pkgs // (with pkgs; {
|
||||
# XXX can't `inherit` a nested attr, so we move them to the toplevel
|
||||
"cacert.unbundled" = pkgs.cacert.unbundled;
|
||||
"gnome.cheese" = gnome.cheese;
|
||||
"gnome.dconf-editor" = gnome.dconf-editor;
|
||||
"gnome.file-roller" = gnome.file-roller;
|
||||
"gnome.gnome-disk-utility" = gnome.gnome-disk-utility;
|
||||
"gnome.gnome-maps" = gnome.gnome-maps;
|
||||
"gnome.nautilus" = gnome.nautilus;
|
||||
"gnome.gnome-system-monitor" = gnome.gnome-system-monitor;
|
||||
"gnome.gnome-terminal" = gnome.gnome-terminal;
|
||||
"gnome.gnome-weather" = gnome.gnome-weather;
|
||||
"gnome.totem" = gnome.totem;
|
||||
"libsForQt5.plasmatube" = libsForQt5.plasmatube;
|
||||
});
|
||||
|
||||
sysadminPkgs = {
|
||||
inherit (flattenedPkgs)
|
||||
btrfs-progs
|
||||
"cacert.unbundled" # some services require unbundled /etc/ssl/certs
|
||||
cryptsetup
|
||||
dig
|
||||
efibootmgr
|
||||
fatresize
|
||||
fd
|
||||
file
|
||||
gawk
|
||||
git
|
||||
gptfdisk
|
||||
hdparm
|
||||
htop
|
||||
iftop
|
||||
inetutils # for telnet
|
||||
iotop
|
||||
iptables
|
||||
jq
|
||||
killall
|
||||
lsof
|
||||
miniupnpc
|
||||
nano
|
||||
netcat
|
||||
nethogs
|
||||
nmap
|
||||
openssl
|
||||
parted
|
||||
pciutils
|
||||
powertop
|
||||
pstree
|
||||
ripgrep
|
||||
screen
|
||||
smartmontools
|
||||
socat
|
||||
strace
|
||||
subversion
|
||||
tcpdump
|
||||
tree
|
||||
usbutils
|
||||
wget
|
||||
wirelesstools # iwlist
|
||||
;
|
||||
};
|
||||
sysadminExtraPkgs = {
|
||||
# application-specific packages
|
||||
inherit (pkgs)
|
||||
backblaze-b2
|
||||
duplicity
|
||||
sqlite # to debug sqlite3 databases
|
||||
;
|
||||
};
|
||||
|
||||
iphonePkgs = {
|
||||
inherit (pkgs)
|
||||
ifuse
|
||||
ipfs
|
||||
libimobiledevice
|
||||
;
|
||||
};
|
||||
|
||||
tuiPkgs = {
|
||||
inherit (pkgs)
|
||||
aerc # email client
|
||||
offlineimap # email mailox sync
|
||||
sfeed # RSS fetcher
|
||||
visidata # TUI spreadsheet viewer/editor
|
||||
w3m
|
||||
;
|
||||
};
|
||||
|
||||
consoleMediaPkgs = {
|
||||
inherit (pkgs)
|
||||
ffmpeg
|
||||
imagemagick
|
||||
sox
|
||||
yt-dlp
|
||||
;
|
||||
};
|
||||
# TODO: split these into smaller groups.
|
||||
# - moby doesn't want a lot of these.
|
||||
# - categories like
|
||||
# - dev?
|
||||
# - debugging?
|
||||
consolePkgs = {
|
||||
inherit (pkgs)
|
||||
alsaUtils # for aplay, speaker-test
|
||||
cdrtools
|
||||
clinfo
|
||||
dmidecode
|
||||
efivar
|
||||
flashrom
|
||||
fwupd
|
||||
gh # MS GitHub cli
|
||||
git # needed as a user package, for config.
|
||||
gnupg
|
||||
gocryptfs
|
||||
gopass # TODO: shouldn't be needed here
|
||||
gopass-jsonapi
|
||||
kitty # TODO: move to GUI, but `ssh servo` from kitty sets `TERM=xterm-kitty` in the remove and breaks things
|
||||
libsecret # for managing user keyrings
|
||||
lm_sensors # for sensors-detect
|
||||
lshw
|
||||
# memtester
|
||||
neovim
|
||||
# nettools
|
||||
# networkmanager
|
||||
nixpkgs-review
|
||||
# nixos-generators
|
||||
nmon
|
||||
# node2nix
|
||||
# oathToolkit # for oathtool
|
||||
# ponymix
|
||||
pulsemixer
|
||||
python3
|
||||
ripgrep # needed as a user package so that its user-level config file can be installed
|
||||
rsync
|
||||
# python3Packages.eyeD3 # music tagging
|
||||
sane-scripts
|
||||
sequoia
|
||||
snapper
|
||||
sops
|
||||
speedtest-cli
|
||||
# ssh-to-age
|
||||
sudo
|
||||
# tageditor # music tagging
|
||||
unar
|
||||
wireguard-tools
|
||||
xdg-utils # for xdg-open
|
||||
# yarn
|
||||
zsh
|
||||
;
|
||||
};
|
||||
|
||||
guiPkgs = {
|
||||
inherit (flattenedPkgs)
|
||||
# celluloid # mpv frontend
|
||||
cozy # audiobook player
|
||||
# emote
|
||||
evince # works on phosh
|
||||
|
||||
# { pkg = fluffychat-moby; persist.plaintext = [ ".local/share/chat.fluffy.fluffychat" ]; } # TODO: ship normal fluffychat on non-moby?
|
||||
|
||||
# foliate # e-book reader
|
||||
|
||||
# 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...?)
|
||||
# { pkg = fractal-latest; persist.private = [ ".local/share/fractal" ]; }
|
||||
# { pkg = fractal-next; persist.private = [ ".local/share/fractal" ]; }
|
||||
|
||||
# "gnome.cheese"
|
||||
# gnome-feeds # RSS reader (with claimed mobile support)
|
||||
"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"
|
||||
gpodder
|
||||
gthumb
|
||||
jellyfin-media-player
|
||||
komikku
|
||||
koreader
|
||||
# lollypop
|
||||
# mpv
|
||||
# networkmanagerapplet
|
||||
# newsflash
|
||||
nheko
|
||||
pavucontrol
|
||||
# picard # music tagging
|
||||
# "libsForQt5.plasmatube" # Youtube player
|
||||
soundconverter
|
||||
# sublime-music
|
||||
# tdesktop # broken on phosh
|
||||
# tokodon
|
||||
vlc
|
||||
# pleroma client (Electron). input is broken on phosh. TODO(2023/02/02): fix electron19 input (insecure)
|
||||
# whalebird
|
||||
xterm # broken on phosh
|
||||
;
|
||||
};
|
||||
desktopGuiPkgs = {
|
||||
inherit (flattenedPkgs)
|
||||
audacity
|
||||
brave # for the integrated wallet -- as a backup
|
||||
chromium
|
||||
dino
|
||||
electrum
|
||||
element-desktop
|
||||
font-manager
|
||||
gajim # XMPP client
|
||||
gimp # broken on phosh
|
||||
"gnome.dconf-editor"
|
||||
"gnome.gnome-disk-utility"
|
||||
# "gnome.totem" # video player, supposedly supports UPnP
|
||||
handbrake
|
||||
hase
|
||||
inkscape
|
||||
kdenlive
|
||||
kid3 # audio tagging
|
||||
krita
|
||||
libreoffice-fresh
|
||||
mumble
|
||||
obsidian
|
||||
slic3r
|
||||
steam
|
||||
wireshark # could maybe ship the cli as sysadmin pkg
|
||||
;
|
||||
};
|
||||
x86GuiPkgs = {
|
||||
inherit (pkgs)
|
||||
discord
|
||||
|
||||
# kaiteki # Pleroma client
|
||||
# gnome.zenity # for kaiteki (it will use qarma, kdialog, or zenity)
|
||||
# gpt2tc # XXX: unreliable mirror
|
||||
|
||||
# logseq # Personal Knowledge Management
|
||||
losslesscut-bin
|
||||
makemkv
|
||||
monero-gui
|
||||
signal-desktop
|
||||
spotify
|
||||
tor-browser-bundle-bin
|
||||
zecwallet-lite
|
||||
;
|
||||
};
|
||||
|
||||
# packages not part of any package set; not enabled by default
|
||||
otherPkgs = {
|
||||
inherit (pkgs)
|
||||
lemmy-server
|
||||
mx-sanebot
|
||||
stepmania
|
||||
;
|
||||
};
|
||||
|
||||
# define -- but don't enable -- the packages in some attrset.
|
||||
declarePkgs = pkgsAsAttrs: lib.mapAttrs (_n: p: {
|
||||
# no need to actually define the package here: it's defaulted
|
||||
# package = mkDefault p;
|
||||
}) pkgsAsAttrs;
|
||||
in
|
||||
{
|
||||
sane.programs = lib.mkMerge [
|
||||
(declarePkgs consoleMediaPkgs)
|
||||
(declarePkgs consolePkgs)
|
||||
(declarePkgs desktopGuiPkgs)
|
||||
(declarePkgs guiPkgs)
|
||||
(declarePkgs iphonePkgs)
|
||||
(declarePkgs sysadminPkgs)
|
||||
(declarePkgs sysadminExtraPkgs)
|
||||
(declarePkgs tuiPkgs)
|
||||
(declarePkgs x86GuiPkgs)
|
||||
(declarePkgs otherPkgs)
|
||||
{
|
||||
# link the various package sets into their own meta packages
|
||||
consoleMediaUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames consoleMediaPkgs;
|
||||
};
|
||||
consoleUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames consolePkgs;
|
||||
};
|
||||
desktopGuiApps = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames desktopGuiPkgs;
|
||||
};
|
||||
guiApps = {
|
||||
package = null;
|
||||
suggestedPrograms = (attrNames guiPkgs)
|
||||
++ [ "web-browser" ]
|
||||
++ [ "tuiApps" ]
|
||||
++ lib.optional (pkgs.system == "x86_64-linux") "x86GuiApps";
|
||||
};
|
||||
iphoneUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames iphonePkgs;
|
||||
};
|
||||
sysadminUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames sysadminPkgs;
|
||||
};
|
||||
sysadminExtraUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames sysadminExtraPkgs;
|
||||
};
|
||||
tuiApps = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames tuiPkgs;
|
||||
};
|
||||
x86GuiApps = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames x86GuiPkgs;
|
||||
};
|
||||
}
|
||||
{
|
||||
# nontrivial 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.
|
||||
emote.persist.plaintext = [ ".local/share/Emote" ];
|
||||
|
||||
# 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" ];
|
||||
|
||||
# actual monero blockchain (not wallet/etc; safe to delete, just slow to regenerate)
|
||||
# XXX: is it really safe to persist this? it doesn't have info that could de-anonymize if captured?
|
||||
monero-gui.persist.plaintext = [ ".bitmonero" ];
|
||||
|
||||
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" ];
|
||||
|
||||
# creds, media
|
||||
signal-desktop.persist.private = [ ".config/Signal" ];
|
||||
|
||||
# printer/filament settings
|
||||
slic3r.persist.plaintext = [ ".Slic3r" ];
|
||||
|
||||
# creds, widevine .so download. TODO: could easily manage these statically.
|
||||
spotify.persist.plaintext = [ ".config/spotify" ];
|
||||
|
||||
tdesktop.persist.private = [ ".local/share/TelegramDesktop" ];
|
||||
|
||||
tokodon.persist.private = [ ".cache/KDE/tokodon" ];
|
||||
|
||||
# hardenedMalloc solves a crash at startup
|
||||
# TODO 2023/02/02: is this safe to remove yet?
|
||||
tor-browser-bundle-bin.package = pkgs.tor-browser-bundle-bin.override {
|
||||
useHardenedMalloc = false;
|
||||
};
|
||||
|
||||
whalebird.persist.private = [ ".config/Whalebird" ];
|
||||
|
||||
yarn.persist.plaintext = [ ".cache/yarn" ];
|
||||
|
||||
# zcash coins. safe to delete, just slow to regenerate (10-60 minutes)
|
||||
zecwallet-lite.persist.private = [ ".zcash" ];
|
||||
}
|
||||
];
|
||||
}
|
11
hosts/common/programs/cozy.nix
Normal file
11
hosts/common/programs/cozy.nix
Normal file
@@ -0,0 +1,11 @@
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
sane.programs.cozy = {
|
||||
# cozy uses a sqlite db for its config and exposes no CLI options other than --help and --debug
|
||||
persist.plaintext = [
|
||||
".local/share/cozy" # sqlite db (config & index?)
|
||||
".cache/cozy" # offline cache
|
||||
];
|
||||
};
|
||||
}
|
@@ -1,274 +1,27 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (builtins) attrNames concatLists;
|
||||
inherit (lib) mapAttrs mapAttrsToList mkDefault mkIf mkMerge optional;
|
||||
|
||||
flattenedPkgs = pkgs // (with pkgs; {
|
||||
# XXX can't `inherit` a nested attr, so we move them to the toplevel
|
||||
"cacert.unbundled" = pkgs.cacert.unbundled;
|
||||
"gnome.cheese" = gnome.cheese;
|
||||
"gnome.dconf-editor" = gnome.dconf-editor;
|
||||
"gnome.file-roller" = gnome.file-roller;
|
||||
"gnome.gnome-disk-utility" = gnome.gnome-disk-utility;
|
||||
"gnome.gnome-maps" = gnome.gnome-maps;
|
||||
"gnome.nautilus" = gnome.nautilus;
|
||||
"gnome.gnome-system-monitor" = gnome.gnome-system-monitor;
|
||||
"gnome.gnome-terminal" = gnome.gnome-terminal;
|
||||
"gnome.gnome-weather" = gnome.gnome-weather;
|
||||
"gnome.totem" = gnome.totem;
|
||||
"libsForQt5.plasmatube" = libsForQt5.plasmatube;
|
||||
});
|
||||
|
||||
sysadminPkgs = {
|
||||
inherit (flattenedPkgs)
|
||||
btrfs-progs
|
||||
"cacert.unbundled" # some services require unbundled /etc/ssl/certs
|
||||
cryptsetup
|
||||
dig
|
||||
efibootmgr
|
||||
fatresize
|
||||
fd
|
||||
file
|
||||
gawk
|
||||
git
|
||||
gptfdisk
|
||||
hdparm
|
||||
htop
|
||||
iftop
|
||||
inetutils # for telnet
|
||||
iotop
|
||||
iptables
|
||||
jq
|
||||
killall
|
||||
lsof
|
||||
nano
|
||||
netcat
|
||||
nethogs
|
||||
nmap
|
||||
openssl
|
||||
parted
|
||||
pciutils
|
||||
powertop
|
||||
pstree
|
||||
ripgrep
|
||||
screen
|
||||
smartmontools
|
||||
socat
|
||||
strace
|
||||
subversion
|
||||
tcpdump
|
||||
tree
|
||||
usbutils
|
||||
wget
|
||||
;
|
||||
};
|
||||
sysadminExtraPkgs = {
|
||||
# application-specific packages
|
||||
inherit (pkgs)
|
||||
backblaze-b2
|
||||
duplicity
|
||||
sqlite # to debug sqlite3 databases
|
||||
;
|
||||
};
|
||||
|
||||
iphonePkgs = {
|
||||
inherit (pkgs)
|
||||
ifuse
|
||||
ipfs
|
||||
libimobiledevice
|
||||
;
|
||||
};
|
||||
|
||||
tuiPkgs = {
|
||||
inherit (pkgs)
|
||||
aerc # email client
|
||||
offlineimap # email mailox sync
|
||||
visidata # TUI spreadsheet viewer/editor
|
||||
w3m
|
||||
;
|
||||
};
|
||||
|
||||
# TODO: split these into smaller groups.
|
||||
# - transcoders (ffmpeg, imagemagick) only wanted on desko/lappy ("powerutils"?)
|
||||
consolePkgs = {
|
||||
inherit (pkgs)
|
||||
cdrtools
|
||||
dmidecode
|
||||
efivar
|
||||
flashrom
|
||||
fwupd
|
||||
gh # MS GitHub cli
|
||||
git # needed as a user package, for config.
|
||||
gnupg
|
||||
gocryptfs
|
||||
gopass # TODO: shouldn't be needed here
|
||||
gopass-jsonapi
|
||||
imagemagick
|
||||
kitty # TODO: move to GUI, but `ssh servo` from kitty sets `TERM=xterm-kitty` in the remove and breaks things
|
||||
libsecret # for managing user keyrings
|
||||
lm_sensors # for sensors-detect
|
||||
lshw
|
||||
ffmpeg
|
||||
memtester
|
||||
neovim
|
||||
# nettools
|
||||
# networkmanager
|
||||
nixpkgs-review
|
||||
# nixos-generators
|
||||
nmon
|
||||
# node2nix
|
||||
# oathToolkit # for oathtool
|
||||
# ponymix
|
||||
pulsemixer
|
||||
python3
|
||||
ripgrep # needed as a user package, for config.
|
||||
rsync
|
||||
# python3Packages.eyeD3 # music tagging
|
||||
sane-scripts
|
||||
sequoia
|
||||
snapper
|
||||
sops
|
||||
sox
|
||||
speedtest-cli
|
||||
# ssh-to-age
|
||||
sudo
|
||||
# tageditor # music tagging
|
||||
unar
|
||||
wireguard-tools
|
||||
xdg-utils # for xdg-open
|
||||
# yarn
|
||||
# youtube-dl
|
||||
yt-dlp
|
||||
zsh
|
||||
;
|
||||
};
|
||||
|
||||
guiPkgs = {
|
||||
inherit (flattenedPkgs)
|
||||
# celluloid # mpv frontend
|
||||
clinfo
|
||||
emote
|
||||
evince # works on phosh
|
||||
|
||||
# { pkg = fluffychat-moby; persist.plaintext = [ ".local/share/chat.fluffy.fluffychat" ]; } # TODO: ship normal fluffychat on non-moby?
|
||||
|
||||
# foliate # e-book reader
|
||||
|
||||
# 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...?)
|
||||
# { pkg = fractal-latest; persist.private = [ ".local/share/fractal" ]; }
|
||||
# { pkg = fractal-next; persist.private = [ ".local/share/fractal" ]; }
|
||||
|
||||
# "gnome.cheese"
|
||||
"gnome.dconf-editor"
|
||||
# gnome-feeds # RSS reader (with claimed mobile support)
|
||||
"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"
|
||||
gpodder
|
||||
gthumb
|
||||
jellyfin-media-player
|
||||
# lollypop
|
||||
# mpv
|
||||
networkmanagerapplet
|
||||
# newsflash
|
||||
nheko
|
||||
pavucontrol
|
||||
# picard # music tagging
|
||||
playerctl
|
||||
# "libsForQt5.plasmatube" # Youtube player
|
||||
soundconverter
|
||||
sublime-music
|
||||
# tdesktop # broken on phosh
|
||||
# tokodon
|
||||
vlc
|
||||
# pleroma client (Electron). input is broken on phosh. TODO(2023/02/02): fix electron19 input (insecure)
|
||||
# whalebird
|
||||
xterm # broken on phosh
|
||||
;
|
||||
};
|
||||
desktopGuiPkgs = {
|
||||
inherit (flattenedPkgs)
|
||||
audacity
|
||||
brave # for the integrated wallet -- as a backup
|
||||
chromium
|
||||
dino
|
||||
electrum
|
||||
element-desktop
|
||||
font-manager
|
||||
gajim # XMPP client
|
||||
gimp # broken on phosh
|
||||
"gnome.gnome-disk-utility"
|
||||
# "gnome.totem" # video player, supposedly supports UPnP
|
||||
handbrake
|
||||
hase
|
||||
inkscape
|
||||
kdenlive
|
||||
kid3 # audio tagging
|
||||
krita
|
||||
libreoffice-fresh
|
||||
mumble
|
||||
obsidian
|
||||
slic3r
|
||||
steam
|
||||
wireshark # could maybe ship the cli as sysadmin pkg
|
||||
;
|
||||
};
|
||||
x86GuiPkgs = {
|
||||
inherit (pkgs)
|
||||
discord
|
||||
|
||||
# kaiteki # Pleroma client
|
||||
# gnome.zenity # for kaiteki (it will use qarma, kdialog, or zenity)
|
||||
# gpt2tc # XXX: unreliable mirror
|
||||
|
||||
# logseq # Personal Knowledge Management
|
||||
losslesscut-bin
|
||||
makemkv
|
||||
monero-gui
|
||||
signal-desktop
|
||||
spotify
|
||||
tor-browser-bundle-bin
|
||||
zecwallet-lite
|
||||
;
|
||||
};
|
||||
|
||||
# packages not part of any package set; not enabled by default
|
||||
otherPkgs = {
|
||||
inherit (pkgs)
|
||||
lemmy-server
|
||||
mx-sanebot
|
||||
stepmania
|
||||
;
|
||||
};
|
||||
|
||||
# define -- but don't enable -- the packages in some attrset.
|
||||
declarePkgs = pkgsAsAttrs: mapAttrs (_n: p: {
|
||||
# no need to actually define the package here: it's defaulted
|
||||
# package = mkDefault p;
|
||||
}) pkgsAsAttrs;
|
||||
in
|
||||
{
|
||||
|
||||
imports = [
|
||||
./aerc.nix
|
||||
./assorted.nix
|
||||
./cozy.nix
|
||||
./git.nix
|
||||
./gnome-feeds.nix
|
||||
./gpodder.nix
|
||||
./imagemagick.nix
|
||||
./jellyfin-media-player.nix
|
||||
./kitty
|
||||
./komikku.nix
|
||||
./koreader
|
||||
./libreoffice.nix
|
||||
./mpv.nix
|
||||
./neovim.nix
|
||||
./newsflash.nix
|
||||
./offlineimap.nix
|
||||
./ripgrep.nix
|
||||
./sfeed.nix
|
||||
./splatmoji.nix
|
||||
./steam.nix
|
||||
./sublime-music.nix
|
||||
./vlc.nix
|
||||
./web-browser.nix
|
||||
@@ -278,146 +31,8 @@ in
|
||||
];
|
||||
|
||||
config = {
|
||||
sane.programs = mkMerge [
|
||||
(declarePkgs consolePkgs)
|
||||
(declarePkgs desktopGuiPkgs)
|
||||
(declarePkgs guiPkgs)
|
||||
(declarePkgs iphonePkgs)
|
||||
(declarePkgs sysadminPkgs)
|
||||
(declarePkgs sysadminExtraPkgs)
|
||||
(declarePkgs tuiPkgs)
|
||||
(declarePkgs x86GuiPkgs)
|
||||
(declarePkgs otherPkgs)
|
||||
{
|
||||
# link the various package sets into their own meta packages
|
||||
consoleUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames consolePkgs;
|
||||
};
|
||||
desktopGuiApps = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames desktopGuiPkgs;
|
||||
};
|
||||
guiApps = {
|
||||
package = null;
|
||||
suggestedPrograms = (attrNames guiPkgs)
|
||||
++ [ "web-browser" ]
|
||||
++ [ "tuiApps" ]
|
||||
++ optional (pkgs.system == "x86_64-linux") "x86GuiApps";
|
||||
};
|
||||
iphoneUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames iphonePkgs;
|
||||
};
|
||||
sysadminUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames sysadminPkgs;
|
||||
};
|
||||
sysadminExtraUtils = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames sysadminExtraPkgs;
|
||||
};
|
||||
tuiApps = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames tuiPkgs;
|
||||
};
|
||||
x86GuiApps = {
|
||||
package = null;
|
||||
suggestedPrograms = attrNames x86GuiPkgs;
|
||||
};
|
||||
}
|
||||
{
|
||||
# nontrivial 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.
|
||||
emote.persist.plaintext = [ ".local/share/Emote" ];
|
||||
|
||||
# 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" ];
|
||||
|
||||
ghostscript = {}; # used by imagemagick
|
||||
|
||||
imagemagick = {
|
||||
package = pkgs.imagemagick.override {
|
||||
ghostscriptSupport = true;
|
||||
};
|
||||
suggestedPrograms = [ "ghostscript" ];
|
||||
};
|
||||
|
||||
# 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
|
||||
# be fragile and take an hour+ to figure out.
|
||||
jellyfin-media-player.persist.plaintext = [ ".local/share/Jellyfin Media Player" ];
|
||||
|
||||
# actual monero blockchain (not wallet/etc; safe to delete, just slow to regenerate)
|
||||
# XXX: is it really safe to persist this? it doesn't have info that could de-anonymize if captured?
|
||||
monero-gui.persist.plaintext = [ ".bitmonero" ];
|
||||
|
||||
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" ];
|
||||
|
||||
# creds, media
|
||||
signal-desktop.persist.private = [ ".config/Signal" ];
|
||||
|
||||
# printer/filament settings
|
||||
slic3r.persist.plaintext = [ ".Slic3r" ];
|
||||
|
||||
# creds, widevine .so download. TODO: could easily manage these statically.
|
||||
spotify.persist.plaintext = [ ".config/spotify" ];
|
||||
|
||||
steam.persist.plaintext = [
|
||||
".steam"
|
||||
".local/share/Steam"
|
||||
];
|
||||
|
||||
tdesktop.persist.private = [ ".local/share/TelegramDesktop" ];
|
||||
|
||||
tokodon.persist.private = [ ".cache/KDE/tokodon" ];
|
||||
|
||||
# hardenedMalloc solves a crash at startup
|
||||
# TODO 2023/02/02: is this safe to remove yet?
|
||||
tor-browser-bundle-bin.package = pkgs.tor-browser-bundle-bin.override {
|
||||
useHardenedMalloc = false;
|
||||
};
|
||||
|
||||
whalebird.persist.private = [ ".config/Whalebird" ];
|
||||
|
||||
yarn.persist.plaintext = [ ".cache/yarn" ];
|
||||
|
||||
# zcash coins. safe to delete, just slow to regenerate (10-60 minutes)
|
||||
zecwallet-lite.persist.private = [ ".zcash" ];
|
||||
}
|
||||
];
|
||||
|
||||
# XXX: this might not be necessary. try removing this and cacert.unbundled (servo)?
|
||||
environment.etc."ssl/certs".source = "${pkgs.cacert.unbundled}/etc/ssl/certs/*";
|
||||
|
||||
# steam requires system-level config for e.g. firewall or controller support
|
||||
programs.steam = mkIf config.sane.programs.steam.enabled {
|
||||
enable = true;
|
||||
# not sure if needed: stole this whole snippet from the wiki
|
||||
remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
|
||||
dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@@ -7,7 +7,8 @@ let
|
||||
wanted-feeds = feeds.filterByFormat ["podcast"] all-feeds;
|
||||
in {
|
||||
sane.programs.gpodder = {
|
||||
package = pkgs.gpodder-configured;
|
||||
package = pkgs.gpodder-adaptive-configured;
|
||||
# package = pkgs.gpodder-configured;
|
||||
fs.".config/gpodderFeeds.opml".symlink.text = feeds.feedsToOpml wanted-feeds;
|
||||
|
||||
# XXX: we preserve the whole thing because if we only preserve gPodder/Downloads
|
||||
|
10
hosts/common/programs/imagemagick.nix
Normal file
10
hosts/common/programs/imagemagick.nix
Normal file
@@ -0,0 +1,10 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
sane.programs.imagemagick = {
|
||||
package = pkgs.imagemagick.override {
|
||||
ghostscriptSupport = true;
|
||||
};
|
||||
suggestedPrograms = [ "ghostscript" ];
|
||||
};
|
||||
sane.programs.ghostscript = {};
|
||||
}
|
13
hosts/common/programs/jellyfin-media-player.nix
Normal file
13
hosts/common/programs/jellyfin-media-player.nix
Normal file
@@ -0,0 +1,13 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
sane.programs.jellyfin-media-player = {
|
||||
# package = pkgs.jellyfin-media-player;
|
||||
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
|
||||
# be fragile and take an hour+ to figure out.
|
||||
persist.plaintext = [ ".local/share/Jellyfin Media Player" ];
|
||||
};
|
||||
}
|
8
hosts/common/programs/komikku.nix
Normal file
8
hosts/common/programs/komikku.nix
Normal file
@@ -0,0 +1,8 @@
|
||||
{ ... }:
|
||||
{
|
||||
sane.programs.komikku = {
|
||||
secrets.".local/share/komikku/keyrings/plaintext.keyring" = ../../../secrets/common/komikku_accounts.json.bin;
|
||||
# downloads end up here, and without the toplevel database komikku doesn't know they exist.
|
||||
persist.plaintext = [ ".local/share/komikku" ];
|
||||
};
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
-- as of 2023.05.1, koreader FTP browser always fails to load.
|
||||
-- it's convinced that it's offline, and asks to connect to wifi.
|
||||
-- this seems to be because of the following in <frontend/device/sdl/device.lua>:
|
||||
--
|
||||
-- function Device:initNetworkManager(NetworkMgr)
|
||||
-- function NetworkMgr:isWifiOn() return true end
|
||||
-- function NetworkMgr:isConnected()
|
||||
-- -- Pull the default gateway first, so we don't even try to ping anything if there isn't one...
|
||||
-- local default_gw = Device:getDefaultRoute()
|
||||
-- if not default_gw then
|
||||
-- return false
|
||||
-- end
|
||||
-- return 0 == os.execute("ping -c1 -w2 " .. default_gw .. " > /dev/null")
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- specifically, `os.execute` is not *expected* to return 0. it returns `true` on success:
|
||||
-- <https://www.lua.org/manual/5.3/manual.html#pdf-os.execute>
|
||||
-- this apparently changed from 5.1 -> 5.2
|
||||
--
|
||||
-- XXX: this same bug likely applies to `isCommand` and `runCommand` in <frontend/device/sdl/device.lua>
|
||||
-- - that would manifest as wikipedia links failing to open in external application (xdg-open)
|
||||
|
||||
local logger = require("logger")
|
||||
logger.info("applying colin patch")
|
||||
|
||||
local Device = require("device")
|
||||
logger.info("Device:" .. tostring(Device))
|
||||
|
||||
local orig_initNetworkManager = Device.initNetworkManager
|
||||
Device.initNetworkManager = function(self, NetworkMgr)
|
||||
logger.info("Device:initNetworkManager")
|
||||
orig_initNetworkManager(self, NetworkMgr)
|
||||
function NetworkMgr:isConnected()
|
||||
logger.info("mocked `NetworkMgr:isConnected` to return true")
|
||||
return true
|
||||
-- unpatch to show that the boolean form works
|
||||
-- local rc = os.execute("ping -c1 -w2 10.78.79.1 > /dev/null")
|
||||
-- logger.info("ping rc: " .. tostring(rc))
|
||||
-- return rc
|
||||
end
|
||||
end
|
46
hosts/common/programs/koreader/default.nix
Normal file
46
hosts/common/programs/koreader/default.nix
Normal file
@@ -0,0 +1,46 @@
|
||||
{ config, lib, sane-lib, ... }:
|
||||
|
||||
let
|
||||
feeds = sane-lib.feeds;
|
||||
allFeeds = config.sane.feeds;
|
||||
wantedFeeds = feeds.filterByFormat [ "image" "text" ] allFeeds;
|
||||
koreaderRssEntries = builtins.map (feed:
|
||||
# format:
|
||||
# { "<rss/atom url>", limit = <int>, download_full_article=<bool>, include_images=<bool>, enable_filter=<bool>, filter_element = "<css selector>"},
|
||||
# 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
|
||||
# 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"
|
||||
"include_images = true"
|
||||
"enable_filter = false"
|
||||
"filter_element = \"\""
|
||||
]; in "{ ${lib.concatStringsSep ", " fields } }"
|
||||
) wantedFeeds;
|
||||
in {
|
||||
sane.programs.koreader = {
|
||||
# koreader applies these lua "patches" at boot:
|
||||
# - <https://github.com/koreader/koreader/wiki/User-patches>
|
||||
# - TODO: upstream this patch to koreader
|
||||
# fs.".config/koreader/patches".symlink.target = "${./.}";
|
||||
fs.".config/koreader/patches/2-colin-NetworkManager-isConnected.lua".symlink.target = "${./2-colin-NetworkManager-isConnected.lua}";
|
||||
|
||||
# koreader news plugin, enabled by default. file format described here:
|
||||
# - <repo:koreader/koreader:plugins/newsdownloader.koplugin/feed_config.lua>
|
||||
fs.".config/koreader/news/feed_config.lua".symlink.text = ''
|
||||
return {--do NOT change this line
|
||||
${lib.concatStringsSep ",\n " koreaderRssEntries}
|
||||
}--do NOT change this line
|
||||
'';
|
||||
|
||||
# koreader on aarch64 errors if there's no fonts directory (sandboxing thing, i guess)
|
||||
fs.".local/share/fonts".dir = {};
|
||||
|
||||
# history, cache, dictionaries...
|
||||
# could be more explicit if i symlinked the history.lua file to somewhere it can persist better.
|
||||
persist.plaintext = [ ".config/koreader" ];
|
||||
};
|
||||
}
|
28
hosts/common/programs/sfeed.nix
Normal file
28
hosts/common/programs/sfeed.nix
Normal file
@@ -0,0 +1,28 @@
|
||||
# simple RSS and Atom parser
|
||||
# - <https://codemadness.org/sfeed-simple-feed-parser.html>
|
||||
# - used by sxmo
|
||||
# - man 5 sfeedrc
|
||||
#
|
||||
# call `sfeed_update` to query each feed and populate entries in ~/.sfeed/feeds
|
||||
{ lib, config, sane-lib, ... }:
|
||||
let
|
||||
feeds = sane-lib.feeds;
|
||||
allFeeds = config.sane.feeds;
|
||||
wantedFeeds = feeds.filterByFormat ["text"] allFeeds;
|
||||
sfeedEntries = builtins.map (feed:
|
||||
# format:
|
||||
# feed <name> <feedurl> [basesiteurl] [encoding]
|
||||
lib.escapeShellArgs [ "feed" (if feed.title != null then feed.title else feed.url) feed.url ]
|
||||
) wantedFeeds;
|
||||
in {
|
||||
sane.programs.sfeed = {
|
||||
fs.".sfeed/sfeedrc".symlink.text = ''
|
||||
feeds() {
|
||||
${lib.concatStringsSep "\n " sfeedEntries}
|
||||
}
|
||||
'';
|
||||
|
||||
# this is where the parsed feed items go
|
||||
persist.plaintext = [ ".sfeed/feeds" ];
|
||||
};
|
||||
}
|
16
hosts/common/programs/steam.nix
Normal file
16
hosts/common/programs/steam.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
{ config, lib, ...}:
|
||||
{
|
||||
sane.programs.steam = {
|
||||
persist.plaintext = [
|
||||
".steam"
|
||||
".local/share/Steam"
|
||||
];
|
||||
};
|
||||
# steam requires system-level config for e.g. firewall or controller support
|
||||
programs.steam = lib.mkIf config.sane.programs.steam.enabled {
|
||||
enable = true;
|
||||
# not sure if needed: stole this whole snippet from the wiki
|
||||
remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
|
||||
dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
|
||||
};
|
||||
}
|
@@ -56,10 +56,26 @@ let
|
||||
nixExtensions = concatMap (ext: optional ext.enable ext.package) (attrValues cfg.addons);
|
||||
|
||||
extraPolicies = {
|
||||
FirefoxHome = {
|
||||
Search = true;
|
||||
Pocket = false;
|
||||
Snippets = false;
|
||||
TopSites = false;
|
||||
Highlights = false;
|
||||
};
|
||||
NoDefaultBookmarks = true;
|
||||
OfferToSaveLogins = false;
|
||||
OfferToSaveLoginsDefault = false;
|
||||
PasswordManagerEnabled = false;
|
||||
SearchEngines = {
|
||||
Default = "DuckDuckGo";
|
||||
};
|
||||
UserMessaging = {
|
||||
ExtensionRecommendations = false;
|
||||
SkipOnboarding = true;
|
||||
};
|
||||
|
||||
# these were taken from Librewolf
|
||||
AppUpdateURL = "https://localhost";
|
||||
DisableAppUpdate = true;
|
||||
OverrideFirstRunPage = "";
|
||||
@@ -88,6 +104,7 @@ let
|
||||
# };
|
||||
# NewTabPage = true;
|
||||
};
|
||||
# extraPrefs = ...
|
||||
};
|
||||
|
||||
addonOpts = types.submodule {
|
||||
|
@@ -138,7 +138,7 @@ in
|
||||
}
|
||||
''
|
||||
+ lib.optionalString cfg.showDeadlines ''
|
||||
${pkgs.sane-scripts}/bin/sane-deadlines
|
||||
${pkgs.sane-scripts.deadlines}/bin/sane-deadlines
|
||||
''
|
||||
+ ''
|
||||
# auto-cd into any of these dirs by typing them and pressing 'enter':
|
||||
|
@@ -63,6 +63,7 @@ in
|
||||
"jackett_apikey".owner = config.users.users.colin.name;
|
||||
"mx-sanebot-env".owner = config.users.users.colin.name;
|
||||
"snippets".owner = config.users.users.colin.name;
|
||||
"transmission_passwd".owner = config.users.users.colin.name;
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{ config, lib, sane-data, sane-lib, ... }:
|
||||
|
||||
let
|
||||
inherit (builtins) head map mapAttrs tail;
|
||||
inherit (builtins) attrValues head map mapAttrs tail;
|
||||
inherit (lib) concatStringsSep mkMerge reverseList;
|
||||
in
|
||||
{
|
||||
@@ -18,11 +18,21 @@ in
|
||||
|
||||
# [{ path :: [String], value :: String }] for the keys we want to install
|
||||
globalKeys = sane-lib.flattenAttrs sane-data.keys;
|
||||
|
||||
keysForHost = hostCfg: sane-lib.mapToAttrs
|
||||
(name: {
|
||||
inherit name;
|
||||
value = {
|
||||
colin = hostCfg.ssh.user_pubkey;
|
||||
root = hostCfg.ssh.host_pubkey;
|
||||
};
|
||||
})
|
||||
hostCfg.names
|
||||
;
|
||||
domainKeys = sane-lib.flattenAttrs (
|
||||
mapAttrs (host: cfg: {
|
||||
colin = cfg.ssh.user_pubkey;
|
||||
root = cfg.ssh.host_pubkey;
|
||||
}) config.sane.hosts.by-name
|
||||
sane-lib.joinAttrsets (
|
||||
map keysForHost (builtins.attrValues config.sane.hosts.by-name)
|
||||
)
|
||||
);
|
||||
in mkMerge (map
|
||||
({ path, value }: {
|
||||
@@ -30,4 +40,15 @@ in
|
||||
})
|
||||
(globalKeys ++ domainKeys)
|
||||
);
|
||||
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings.PermitRootLogin = "no";
|
||||
settings.PasswordAuthentication = false;
|
||||
};
|
||||
sane.ports.ports."22" = {
|
||||
protocol = [ "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
description = lib.mkDefault "colin-ssh";
|
||||
};
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@ in
|
||||
"input" # for /dev/input/<xyz>: sxmo
|
||||
"networkmanager"
|
||||
"nixbuild"
|
||||
"transmission" # servo, to admin /var/lib/uninsane/media
|
||||
"video" # phosh/mobile. XXX colin: unsure if necessary
|
||||
"wheel"
|
||||
"wireshark"
|
||||
@@ -129,11 +130,5 @@ in
|
||||
enable = true;
|
||||
wheelNeedsPassword = false;
|
||||
};
|
||||
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings.PermitRootLogin = "no";
|
||||
settings.PasswordAuthentication = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@@ -90,7 +90,7 @@ in
|
||||
};
|
||||
sane.gui.sxmo.terminal = mkOption {
|
||||
# type = types.nullOr (types.enum [ "foot" "st" "vte" ]);
|
||||
type = types.nullOr types.string;
|
||||
type = types.nullOr types.str;
|
||||
default = "foot";
|
||||
description = ''
|
||||
name of terminal to use for sxmo_terminal.sh.
|
||||
@@ -99,7 +99,7 @@ in
|
||||
};
|
||||
sane.gui.sxmo.keyboard = mkOption {
|
||||
# type = types.nullOr (types.enum ["wvkbd"])
|
||||
type = types.nullOr types.string;
|
||||
type = types.nullOr types.str;
|
||||
default = "wvkbd";
|
||||
description = ''
|
||||
name of on-screen-keyboard to use for sxmo_keyboard.sh.
|
||||
@@ -108,12 +108,29 @@ in
|
||||
'';
|
||||
};
|
||||
sane.gui.sxmo.settings = mkOption {
|
||||
type = types.attrsOf types.string;
|
||||
default = {};
|
||||
description = ''
|
||||
environment variables used to configure sxmo.
|
||||
e.g. SXMO_UNLOCK_IDLE_TIME or SXMO_VOLUME_BUTTON.
|
||||
'';
|
||||
type = types.submodule {
|
||||
freeformType = types.attrsOf types.str;
|
||||
options =
|
||||
let
|
||||
mkSettingsOpt = default: description: mkOption {
|
||||
inherit default description;
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
in {
|
||||
SXMO_BAR_SHOW_BAT_PER = mkSettingsOpt "1" "show battery percentage in statusbar";
|
||||
SXMO_UNLOCK_IDLE_TIME = mkSettingsOpt "300" "how many seconds of inactivity before locking the screen"; # lock -> screenoff happens 8s later, not configurable
|
||||
};
|
||||
};
|
||||
default = {};
|
||||
};
|
||||
sane.gui.sxmo.noidle = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "inhibit lock-on-idle and screenoff-on-idle";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -123,18 +140,25 @@ in
|
||||
package = null;
|
||||
suggestedPrograms = [
|
||||
"guiApps"
|
||||
"sfeed" # want this here so that the user's ~/.sfeed/sfeedrc gets created
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
{
|
||||
# TODO: lift to option declaration
|
||||
sane.gui.sxmo.settings.TERMCMD = lib.mkIf (cfg.terminal != null)
|
||||
(lib.mkDefault (if cfg.terminal == "vte" then "vte-2.91" else cfg.terminal));
|
||||
sane.gui.sxmo.settings.KEYBOARD = lib.mkIf (cfg.keyboard != null)
|
||||
(lib.mkDefault (if cfg.keyboard == "wvkbd" then "wvkbd-mobintl" else cfg.keyboard));
|
||||
}
|
||||
|
||||
(lib.mkIf cfg.enable {
|
||||
sane.programs.sxmoApps.enableFor.user.colin = true;
|
||||
|
||||
# some programs (e.g. fractal/nheko) **require** a "Secret Service Provider"
|
||||
services.gnome.gnome-keyring.enable = true;
|
||||
|
||||
# TODO: probably need to enable pipewire
|
||||
|
||||
networking.useDHCP = false;
|
||||
networking.networkmanager.enable = true;
|
||||
networking.wireless.enable = lib.mkForce false;
|
||||
@@ -149,7 +173,9 @@ in
|
||||
# TODO: not all of these fonts seem to be mapped to the correct icon
|
||||
fonts.fonts = [ pkgs.nerdfonts ];
|
||||
|
||||
# i believe sxmo recomments a different audio stack
|
||||
# sxmo has first-class support only for pulseaudio and alsa -- not pipewire.
|
||||
# however, pipewire can emulate pulseaudio support via `services.pipewire.pulse.enable = true`
|
||||
# after which the stock pulseaudio binaries magically work
|
||||
# administer with pw-cli, pw-mon, pw-top commands
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
@@ -161,27 +187,7 @@ in
|
||||
|
||||
# TODO: could use `displayManager.sessionPackages`?
|
||||
environment.systemPackages = with pkgs; [
|
||||
bc
|
||||
bemenu
|
||||
bonsai
|
||||
conky
|
||||
gojq
|
||||
inotify-tools
|
||||
jq
|
||||
libnotify
|
||||
lisgd
|
||||
mako
|
||||
superd
|
||||
sway
|
||||
swayidle
|
||||
sxmo-utils
|
||||
wob
|
||||
wvkbd
|
||||
xdg-user-dirs
|
||||
|
||||
# X11 only?
|
||||
xdotool
|
||||
|
||||
cfg.deviceHooks
|
||||
cfg.hooks
|
||||
] ++ lib.optionals (cfg.terminal != null) [ pkgs."${cfg.terminal}" ]
|
||||
@@ -192,13 +198,9 @@ in
|
||||
# TODO: only need the share/sxmo directly linked
|
||||
"${pkgs.sxmo-utils}/share"
|
||||
];
|
||||
} // lib.optionalAttrs (cfg.terminal != null) {
|
||||
TERMCMD = lib.mkDefault (if cfg.terminal == "vte" then "vte-2.91" else cfg.terminal);
|
||||
} // lib.optionalAttrs (cfg.keyboard != null) {
|
||||
KEYBOARD = lib.mkDefault (if cfg.keyboard == "wvkbd" then "wvkbd-mobintl" else cfg.keyboard);
|
||||
} // cfg.settings;
|
||||
|
||||
sane.user.fs.".cache/sxmo/sxmo.noidle" = sane-lib.fs.wantedText "";
|
||||
sane.user.fs.".cache/sxmo/sxmo.noidle" = lib.mkIf cfg.noidle (sane-lib.fs.wantedText "");
|
||||
|
||||
|
||||
## greeter
|
||||
@@ -248,6 +250,15 @@ in
|
||||
in "${sway-as-greeter}/bin/sway-as-greeter";
|
||||
};
|
||||
|
||||
systemd.services."sxmo-set-permissions" = {
|
||||
description = "configure specific /sys and /dev nodes to be writable by sxmo scripts";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.sxmo-utils}/bin/sxmo_setpermissions.sh";
|
||||
};
|
||||
wantedBy = [ "display-manager.service" ];
|
||||
};
|
||||
|
||||
sane.fs."/var/log/sway" = lib.mkIf (cfg.greeter == "sway") {
|
||||
dir.acl.mode = "0777";
|
||||
wantedBeforeBy = [ "greetd.service" "display-manager.service" ];
|
||||
|
@@ -11,6 +11,7 @@
|
||||
name = cfg.lan-ip;
|
||||
value = [ host ];
|
||||
}) config.sane.hosts.by-name)
|
||||
|
||||
(lib.mapAttrs' (host: cfg: {
|
||||
# -hn suffixed name for communication over my wg-home VPN.
|
||||
# hn = "home network"
|
||||
|
@@ -4,8 +4,14 @@ let
|
||||
inherit (lib) attrValues filterAttrs mkMerge mkOption types;
|
||||
cfg = config.sane.hosts;
|
||||
|
||||
host = types.submodule ({ config, ... }: {
|
||||
host = types.submodule ({ config, name, ... }: {
|
||||
options = {
|
||||
names = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = ''
|
||||
all names by which this host is reachable
|
||||
'';
|
||||
};
|
||||
ssh.user_pubkey = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
@@ -48,6 +54,11 @@ let
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
names = [ name ]
|
||||
++ lib.optional (config.wg-home.ip != null) "${name}-hn";
|
||||
};
|
||||
});
|
||||
in
|
||||
{
|
||||
|
@@ -26,7 +26,7 @@ in
|
||||
type = types.bool;
|
||||
};
|
||||
sane.nixcache.substituters = mkOption {
|
||||
type = types.listOf types.string;
|
||||
type = types.listOf types.str;
|
||||
default =
|
||||
# TODO: make these blacklisted entries injectable
|
||||
(lib.optional (hostName != "servo") "https://nixcache.uninsane.org")
|
||||
|
@@ -10,7 +10,7 @@
|
||||
};
|
||||
|
||||
config = lib.mkIf config.sane.roles.ac {
|
||||
sane.yggdrasil.enable = true;
|
||||
services.i2p.enable = true;
|
||||
# sane.yggdrasil.enable = true;
|
||||
# services.i2p.enable = true;
|
||||
};
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ in
|
||||
config = mkMerge [
|
||||
({
|
||||
sane.programs.docsets.config.rustPkgs = [
|
||||
"lemmy-server"
|
||||
# "lemmy-server"
|
||||
"mx-sanebot"
|
||||
];
|
||||
})
|
||||
|
@@ -33,6 +33,11 @@ in
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
sane.services.wg-home.enableWan = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "whether to make this port visible on the WAN";
|
||||
};
|
||||
sane.services.wg-home.ip = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
@@ -50,7 +55,12 @@ in
|
||||
# this config defines both the endpoint (server) and client configs
|
||||
|
||||
# for convenience, have both the server and client use the same port for their wireguard connections.
|
||||
networking.firewall.allowedUDPPorts = [ 51820 ];
|
||||
sane.ports.ports."51820" = {
|
||||
protocol = [ "udp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = cfg.enableWan;
|
||||
description = "colin-wireguard";
|
||||
};
|
||||
networking.wireguard.interfaces.wg-home = {
|
||||
listenPort = 51820;
|
||||
privateKeyFile = "/run/wg-home.priv";
|
||||
|
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 1369733,
|
||||
"content_type": "application/rss+xml; charset=utf-8",
|
||||
"description": "Every company has a story. Learn the playbooks that built the world’s greatest companies — and how you can apply them as a founder, operator, or investor.",
|
||||
"favicon": null,
|
||||
"hubs": [],
|
||||
"is_podcast": true,
|
||||
"is_push": false,
|
||||
"item_count": 173,
|
||||
"last_seen": "2023-01-11T15:26:37.515527+00:00",
|
||||
"last_updated": "2022-12-19T07:22:28+00:00",
|
||||
"score": 18,
|
||||
"self_url": "https://acquired.libsyn.com/rss",
|
||||
"site_name": null,
|
||||
"site_url": null,
|
||||
"title": "Acquired",
|
||||
"url": "https://acquired.libsyn.com/rss",
|
||||
"velocity": 0.066,
|
||||
"version": "rss20"
|
||||
}
|
@@ -1,21 +1,23 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 443732,
|
||||
"content_type": "application/rss+xml; charset=utf-8",
|
||||
"description": "Ben and David are joined by expert founders and investors \u2014 writing the next generation of great company stories in real-time.\n\nWe go behind the scenes on their journeys and bring back emerging insights and lessons that are useful for anyone in the tech and investing ecosystems.\n\nAcquired covers yesterday. ACQ2 covers tomorrow.",
|
||||
"content_length": 567579,
|
||||
"content_type": "text/xml; charset=utf-8",
|
||||
"description": "ACQ2 is Ben and David's conversations with expert founders and investors.",
|
||||
"favicon": "",
|
||||
"favicon_data_uri": "",
|
||||
"hubs": [],
|
||||
"hubs": [
|
||||
"https://pubsubhubbub.appspot.com/"
|
||||
],
|
||||
"is_podcast": true,
|
||||
"is_push": false,
|
||||
"item_count": 92,
|
||||
"last_updated": "2023-03-02T17:03:15+00:00",
|
||||
"score": 10,
|
||||
"self_url": "https://acquiredlpbonussecretsecret.libsyn.com/",
|
||||
"site_name": "ACQ2 by Acquired",
|
||||
"site_url": "https://acquiredlpbonussecretsecret.libsyn.com",
|
||||
"title": "ACQ2 by Acquired",
|
||||
"url": "https://acquiredlpbonussecretsecret.libsyn.com",
|
||||
"velocity": 0.057,
|
||||
"is_push": true,
|
||||
"item_count": 91,
|
||||
"last_updated": "2023-05-09T06:51:48+00:00",
|
||||
"score": 24,
|
||||
"self_url": "https://feeds.transistor.fm/acq2",
|
||||
"site_name": "ACQ2: The Acquired Interviews",
|
||||
"site_url": "https://feeds.transistor.fm",
|
||||
"title": "ACQ2: The Acquired Interviews",
|
||||
"url": "https://feeds.transistor.fm/acq2",
|
||||
"velocity": 0.054,
|
||||
"version": "rss20"
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 1579416,
|
||||
"content_type": "text/xml; charset=utf-8",
|
||||
"description": "Every company has a story.",
|
||||
"favicon": "",
|
||||
"favicon_data_uri": "",
|
||||
"hubs": [
|
||||
"https://pubsubhubbub.appspot.com/"
|
||||
],
|
||||
"is_podcast": true,
|
||||
"is_push": true,
|
||||
"item_count": 178,
|
||||
"last_updated": "2023-05-30T05:02:40+00:00",
|
||||
"score": 24,
|
||||
"self_url": "https://feeds.transistor.fm/acquired",
|
||||
"site_name": "",
|
||||
"site_url": "https://feeds.transistor.fm",
|
||||
"title": "Acquired",
|
||||
"url": "https://feeds.transistor.fm/acquired",
|
||||
"velocity": 0.064,
|
||||
"version": "rss20"
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 918085,
|
||||
"content_type": "application/xml; charset=utf-8",
|
||||
"description": "A show that cuts through all the political drivel and media misinformation to give you a straight take on one big news story of the week.",
|
||||
"favicon": "",
|
||||
"favicon_data_uri": "",
|
||||
"hubs": [],
|
||||
"is_podcast": true,
|
||||
"is_push": false,
|
||||
"item_count": 238,
|
||||
"last_updated": "2023-06-06T16:03:38+00:00",
|
||||
"score": 10,
|
||||
"self_url": "https://feeds.acast.com/public/shows/1d1223a2-9d05-473b-9e79-c2b65b71d676",
|
||||
"site_name": "",
|
||||
"site_url": "",
|
||||
"title": "Deconstructed",
|
||||
"url": "https://feeds.acast.com/public/shows/1d1223a2-9d05-473b-9e79-c2b65b71d676",
|
||||
"velocity": 0.123,
|
||||
"version": "rss20"
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 1131706,
|
||||
"content_type": "application/xml; charset=utf-8",
|
||||
"description": "The people behind The Intercept\u2019s fearless reporting and incisive commentary discuss the crucial issues of our time.",
|
||||
"favicon": "",
|
||||
"favicon_data_uri": "",
|
||||
"hubs": [],
|
||||
"is_podcast": true,
|
||||
"is_push": false,
|
||||
"item_count": 261,
|
||||
"last_updated": "2023-06-07T09:30:43+00:00",
|
||||
"score": 10,
|
||||
"self_url": "https://feeds.acast.com/public/shows/f5b64019-68c3-57d4-b70b-043e63e5cbf6",
|
||||
"site_name": "",
|
||||
"site_url": "",
|
||||
"title": "Intercepted",
|
||||
"url": "https://feeds.acast.com/public/shows/f5b64019-68c3-57d4-b70b-043e63e5cbf6",
|
||||
"velocity": 0.111,
|
||||
"version": "rss20"
|
||||
}
|
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 235911,
|
||||
"content_length": 145311,
|
||||
"content_type": "application/xml; charset=utf-8",
|
||||
"description": "<p>The Portal is an exploration into discovery, including conversations with thought leaders. Host Eric Weinstein, Managing Director of Thiel Capital, brings his unique expertise and diverse roster of guests for a wide range of discussions, including science, culture, business, and capitalism. The show will feature people whose lives demonstrate that portals into what we would normally consider impossible, are indeed possible. Guests include presidential candidate Andrew Yang, NY Times bestselling author Sam Harris, and retired Navy Seal and creator of the hit business podcast Jocko Willink.</p>",
|
||||
"favicon": null,
|
||||
"favicon": "",
|
||||
"favicon_data_uri": "",
|
||||
"hubs": [],
|
||||
"is_podcast": true,
|
||||
"is_push": false,
|
||||
"item_count": 44,
|
||||
"last_seen": "2023-01-11T14:47:44.995855+00:00",
|
||||
"last_updated": "2020-12-02T07:50:55+00:00",
|
||||
"score": -12,
|
||||
"self_url": "https://www.omnycontent.com/d/playlist/9b7dacdf-a925-4f95-84dc-ac46003451ff/1713c520-edb6-43a3-b1b9-acb8002fdae7/58e33a0c-f86b-41c5-a11c-acb8002fdaf5/podcast.rss",
|
||||
"site_name": null,
|
||||
"site_url": null,
|
||||
"score": 8,
|
||||
"self_url": "",
|
||||
"site_name": "",
|
||||
"site_url": "",
|
||||
"title": "The Portal",
|
||||
"url": "https://www.omnycontent.com/d/playlist/9b7dacdf-a925-4f95-84dc-ac46003451ff/1713c520-edb6-43a3-b1b9-acb8002fdae7/58e33a0c-f86b-41c5-a11c-acb8002fdaf5/podcast.rss",
|
||||
"url": "https://feed.cdnstream1.com/zjb/feed/download/d9/8a/71/d98a71ac-d1a3-4d92-ab64-64b4ff3192d1.xml",
|
||||
"velocity": 0.082,
|
||||
"version": "rss20"
|
||||
}
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 809084,
|
||||
"content_type": "application/xml+rss; charset=utf-8",
|
||||
"description": "A show that cuts through all the political drivel and media misinformation to give you a straight take on one big news story of the week.",
|
||||
"favicon": null,
|
||||
"hubs": [],
|
||||
"is_podcast": true,
|
||||
"is_push": false,
|
||||
"item_count": 217,
|
||||
"last_seen": "2023-01-11T13:40:50.240217+00:00",
|
||||
"last_updated": "2023-01-06T10:37:50+00:00",
|
||||
"score": 16,
|
||||
"self_url": "https://feeds.acast.com/public/shows/1d1223a2-9d05-473b-9e79-c2b65b71d676",
|
||||
"site_name": null,
|
||||
"site_url": null,
|
||||
"title": "Deconstructed",
|
||||
"url": "https://rss.prod.firstlook.media/deconstructed/podcast.rss",
|
||||
"velocity": 0.122,
|
||||
"version": "rss20"
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"bozo": 0,
|
||||
"content_length": 1034995,
|
||||
"content_type": "application/xml+rss; charset=utf-8",
|
||||
"description": "The people behind The Intercept’s fearless reporting and incisive commentary discuss the crucial issues of our time.",
|
||||
"favicon": null,
|
||||
"hubs": [],
|
||||
"is_podcast": true,
|
||||
"is_push": false,
|
||||
"item_count": 243,
|
||||
"last_seen": "2023-01-11T14:04:41.283509+00:00",
|
||||
"last_updated": "2022-12-21T10:30:43+00:00",
|
||||
"score": 16,
|
||||
"self_url": "https://feeds.acast.com/public/shows/f5b64019-68c3-57d4-b70b-043e63e5cbf6",
|
||||
"site_name": null,
|
||||
"site_url": null,
|
||||
"title": "Intercepted",
|
||||
"url": "https://rss.prod.firstlook.media/intercepted/podcast.rss",
|
||||
"velocity": 0.112,
|
||||
"version": "rss20"
|
||||
}
|
@@ -2,12 +2,14 @@
|
||||
|
||||
{
|
||||
imports = [
|
||||
./dns.nix
|
||||
./feeds.nix
|
||||
./fs
|
||||
./ids.nix
|
||||
./programs.nix
|
||||
./image.nix
|
||||
./persist
|
||||
./ports.nix
|
||||
./services
|
||||
./sops.nix
|
||||
./ssh.nix
|
||||
|
146
modules/dns.nix
Normal file
146
modules/dns.nix
Normal file
@@ -0,0 +1,146 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with builtins;
|
||||
let
|
||||
cfg = config.sane.dns;
|
||||
toml = pkgs.formats.toml { };
|
||||
recordFormatters = {
|
||||
# quote rules for zone files:
|
||||
# - any character may be encoded by `\DDD`, where `DDD` represents its ascii value in base 8.
|
||||
# - any non-digit `X` may be encoded by `\X`.
|
||||
# - stated in: <https://www.ietf.org/rfc/rfc1035.txt>: 5.1 Format
|
||||
# - visible in <trust-dns:crates/proto/src/serialize/txt/zone_lex.rs:escape_seq>
|
||||
# for us, we can just replace `\` => `\\ and `"` -> `\"`
|
||||
TXT = value: "\"" + (lib.escape [ "\\" "\"" ] value) + "\"";
|
||||
};
|
||||
# proto: "INET", etc
|
||||
# rrtype: "TXT", "A", "CNAME", etc
|
||||
fmtRecord = proto: rrtype: name: value:
|
||||
let
|
||||
formatter = recordFormatters."${rrtype}" or lib.id;
|
||||
in
|
||||
"${name}\t${proto}\t${rrtype}\t${formatter value}";
|
||||
fmtRecordList = proto: rrtype: name: values: concatStringsSep
|
||||
"\n"
|
||||
(map (fmtRecord proto rrtype name) values)
|
||||
;
|
||||
fmtRecordAttrs = proto: rrtype: rrAttrs:
|
||||
concatStringsSep
|
||||
"\n"
|
||||
(
|
||||
attrValues (
|
||||
mapAttrs
|
||||
(name: fmtRecordList proto rrtype name)
|
||||
rrAttrs
|
||||
)
|
||||
);
|
||||
# format other .zone files to include into this one
|
||||
fmtIncludes = paths: concatStringsSep
|
||||
"\n"
|
||||
(map (path: "$INCLUDE ${path}") paths);
|
||||
|
||||
genZone = zcfg: ''
|
||||
$TTL ${toString zcfg.TTL}
|
||||
${fmtRecordAttrs "IN" "SOA" zcfg.inet.SOA}
|
||||
${fmtRecordAttrs "IN" "A" zcfg.inet.A}
|
||||
${fmtRecordAttrs "IN" "CNAME" zcfg.inet.CNAME}
|
||||
${fmtRecordAttrs "IN" "MX" zcfg.inet.MX}
|
||||
${fmtRecordAttrs "IN" "NS" zcfg.inet.NS}
|
||||
${fmtRecordAttrs "IN" "SRV" zcfg.inet.SRV}
|
||||
${fmtRecordAttrs "IN" "TXT" zcfg.inet.TXT}
|
||||
${fmtIncludes zcfg.include}
|
||||
${zcfg.extraConfig}
|
||||
'';
|
||||
|
||||
# (listOf ty) type which also accepts single-assignment of `ty`.
|
||||
# it's used to allow the user to write:
|
||||
# CNAME."foo" = "bar";
|
||||
# as shorthand for
|
||||
# CNAME."foo" = [ "bar" ];
|
||||
listOrUnit = with lib; ty: types.coercedTo ty (elem: [ elem ]) (types.listOf ty);
|
||||
in
|
||||
{
|
||||
options = {
|
||||
sane.dns = with lib; {
|
||||
zones = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
description = "zone name. defaults to the attribute name in zones";
|
||||
default = null;
|
||||
};
|
||||
TTL = mkOption {
|
||||
type = types.int;
|
||||
description = "default TTL";
|
||||
default = 3600;
|
||||
};
|
||||
include = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "paths of other zone files to $INCLUDE into this one";
|
||||
default = [];
|
||||
};
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
description = "extra lines to append to the zone file";
|
||||
default = "";
|
||||
};
|
||||
inet = {
|
||||
SOA = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "Start of Authority record(s)";
|
||||
default = {};
|
||||
};
|
||||
A = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "IPv4 address record(s)";
|
||||
default = {};
|
||||
};
|
||||
CNAME = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "canonical name record(s)";
|
||||
default = {};
|
||||
};
|
||||
MX = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "mail exchanger record(s)";
|
||||
default = {};
|
||||
};
|
||||
NS = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "name server record(s)";
|
||||
default = {};
|
||||
};
|
||||
SRV = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "service record(s)";
|
||||
default = {};
|
||||
};
|
||||
TXT = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "text record(s)";
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
|
||||
file = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
instead of using the generated zone file, use the specified path (user should populate the file specified here).
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = {};
|
||||
description = "Declarative zone config";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
sane.services.trust-dns.zones = mapAttrs (_name: zcfg: {
|
||||
text = genZone zcfg;
|
||||
}) cfg.zones;
|
||||
};
|
||||
}
|
@@ -25,7 +25,7 @@ lib.mkIf config.sane.persist.enable
|
||||
"nosuid"
|
||||
"allow_other"
|
||||
"passfile=${key}"
|
||||
"defaults"
|
||||
# "defaults" # "unknown flag: --defaults. Try 'gocryptfs -help'"
|
||||
];
|
||||
noCheck = true;
|
||||
};
|
||||
|
@@ -35,7 +35,7 @@ lib.mkIf config.sane.persist.enable
|
||||
"nodev"
|
||||
"nosuid"
|
||||
"quiet"
|
||||
"defaults"
|
||||
# "defaults" # "unknown flag: --defaults. Try 'gocryptfs -help'"
|
||||
];
|
||||
noCheck = true;
|
||||
};
|
||||
|
113
modules/ports.nix
Normal file
113
modules/ports.nix
Normal file
@@ -0,0 +1,113 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.sane.ports;
|
||||
|
||||
portOpts = with lib; types.submodule {
|
||||
options = {
|
||||
protocol = mkOption {
|
||||
type = types.listOf (types.enum [ "udp" "tcp" ]);
|
||||
};
|
||||
visibleTo.lan = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
# XXX: if a service is visible to the WAN, it ends up visible to the LAN as well.
|
||||
# technically solvable (explicitly drop packets delivered from LAN IPs) but doesn't make much sense.
|
||||
};
|
||||
visibleTo.wan = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
visibleTo.ovpn = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
# XXX: behaves more or less the same as `lan` visibility.
|
||||
# OVPN passes everything by default.
|
||||
# TODO: have *this* drive what we forward from wireguard namespace to main namespace
|
||||
};
|
||||
description = mkOption {
|
||||
type = types.str;
|
||||
default = "colin-${config.net.hostName}";
|
||||
description = ''
|
||||
short description of why this port is open.
|
||||
this is shown, for example, in an upstream's UPnP status page.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# gives networking.firewall value for a given "${port}" = portCfg.
|
||||
firewallConfigForPort = port: portCfg:
|
||||
# any form of visibility means we need to open the firewall
|
||||
lib.mkIf (portCfg.visibleTo.lan || portCfg.visibleTo.wan || portCfg.visibleTo.ovpn) {
|
||||
allowedTCPPorts = lib.optional (lib.elem "tcp" portCfg.protocol) (lib.toInt port);
|
||||
allowedUDPPorts = lib.optional (lib.elem "udp" portCfg.protocol) (lib.toInt port);
|
||||
};
|
||||
in
|
||||
{
|
||||
options = with lib; {
|
||||
sane.ports = {
|
||||
openFirewall = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
};
|
||||
openUpnp = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
};
|
||||
upnpRenewInterval = mkOption {
|
||||
default = "1hr";
|
||||
type = types.str;
|
||||
description = "how frequently to renew UPnP leases";
|
||||
};
|
||||
upnpLeaseDuration = mkOption {
|
||||
default = 86400;
|
||||
type = types.int;
|
||||
description = "how long to lease UPnP ports for";
|
||||
};
|
||||
|
||||
ports = mkOption {
|
||||
type = types.attrsOf portOpts;
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkMerge (lib.mapAttrsToList firewallConfigForPort cfg.ports);
|
||||
})
|
||||
(lib.mkIf cfg.openUpnp {
|
||||
systemd.services.upnp-forwards = {
|
||||
description = "forward ports from upstream gateway to this host";
|
||||
serviceConfig.Type = "oneshot";
|
||||
restartTriggers = [(builtins.toJSON cfg)];
|
||||
|
||||
after = [ "network.target" ];
|
||||
script =
|
||||
let
|
||||
portFwd = "${pkgs.sane-scripts.ip-port-forward}/bin/sane-ip-port-forward";
|
||||
forwardsPerCfg = lib.mapAttrsToList
|
||||
(port: portCfg: lib.optionals portCfg.visibleTo.wan
|
||||
(
|
||||
lib.optional (lib.elem "udp" portCfg.protocol) "udp:${port}:${portCfg.description}"
|
||||
++ lib.optional (lib.elem "tcp" portCfg.protocol) "tcp:${port}:${portCfg.description}"
|
||||
)
|
||||
)
|
||||
cfg.ports;
|
||||
forwards = lib.flatten forwardsPerCfg;
|
||||
in ''
|
||||
${portFwd} -v -d ${builtins.toString cfg.upnpLeaseDuration} \
|
||||
${lib.escapeShellArgs forwards}
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers.upnp-forwards = {
|
||||
wantedBy = [ "network.target" ];
|
||||
timerConfig = {
|
||||
OnStartupSec = "1min";
|
||||
OnUnitActiveSec = cfg.upnpRenewInterval;
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
@@ -52,11 +52,17 @@ let
|
||||
};
|
||||
enableFor.user = mkOption {
|
||||
type = types.attrsOf types.bool;
|
||||
default = joinAttrsets (mapAttrsToList (otherName: otherPkg:
|
||||
optionalAttrs
|
||||
(otherName != name && elem name otherPkg.suggestedPrograms && otherPkg.enableSuggested)
|
||||
(filterAttrs (user: en: en) otherPkg.enableFor.user)
|
||||
) cfg);
|
||||
default =
|
||||
let
|
||||
suggestedBy = mapAttrsToList (otherName: otherPkg:
|
||||
optionalAttrs
|
||||
(otherName != name && elem name otherPkg.suggestedPrograms && otherPkg.enableSuggested)
|
||||
(filterAttrs (user: en: en) otherPkg.enableFor.user)
|
||||
) cfg;
|
||||
in
|
||||
# we can just // the attrs since each set is flat and the only value
|
||||
# each attr can have here is `true`, never `false`
|
||||
lib.foldl' (prev: next: prev // next) {} suggestedBy;
|
||||
description = ''
|
||||
place this program on the PATH for some specified user(s).
|
||||
'';
|
||||
|
@@ -5,8 +5,9 @@ let
|
||||
cfg = config.sane.services.dyn-dns;
|
||||
getIp = pkgs.writeShellScript "dyn-dns-query-wan" ''
|
||||
# preferred method and fallback
|
||||
${pkgs.sane-scripts}/bin/sane-ip-check-router-wan || \
|
||||
${pkgs.sane-scripts}/bin/sane-ip-check
|
||||
# OPNsense router broadcasts its UPnP endpoint every 30s
|
||||
timeout 60 ${pkgs.sane-scripts.ip-check-upnp}/bin/sane-ip-check-upnp || \
|
||||
${pkgs.sane-scripts.ip-check}/bin/sane-ip-check
|
||||
'';
|
||||
in
|
||||
{
|
||||
|
@@ -7,50 +7,6 @@ with lib;
|
||||
let
|
||||
cfg = config.sane.services.trust-dns;
|
||||
toml = pkgs.formats.toml { };
|
||||
recordFormatters = {
|
||||
# quote rules for zone files:
|
||||
# - any character may be encoded by `\DDD`, where `DDD` represents its ascii value in base 8.
|
||||
# - any non-digit `X` may be encoded by `\X`.
|
||||
# - stated in: <https://www.ietf.org/rfc/rfc1035.txt>: 5.1 Format
|
||||
# - visible in <trust-dns:crates/proto/src/serialize/txt/zone_lex.rs:escape_seq>
|
||||
# for us, we can just replace `\` => `\\ and `"` -> `\"`
|
||||
TXT = value: "\"" + (lib.escape [ "\\" "\"" ] value) + "\"";
|
||||
};
|
||||
fmtRecord = proto: rrtype: name: value:
|
||||
let
|
||||
formatter = recordFormatters."${rrtype}" or lib.id;
|
||||
in
|
||||
"${name}\t${proto}\t${rrtype}\t${formatter value}";
|
||||
fmtRecordList = proto: rrtype: name: values: concatStringsSep
|
||||
"\n"
|
||||
(map (fmtRecord proto rrtype name) values)
|
||||
;
|
||||
fmtRecordAttrs = proto: rrtype: rrAttrs:
|
||||
concatStringsSep
|
||||
"\n"
|
||||
(
|
||||
attrValues (
|
||||
mapAttrs
|
||||
(name: fmtRecordList proto rrtype name)
|
||||
rrAttrs
|
||||
)
|
||||
);
|
||||
fmtIncludes = paths: concatStringsSep
|
||||
"\n"
|
||||
(map (path: "$INCLUDE ${path}") paths);
|
||||
|
||||
genZone = zcfg: ''
|
||||
$TTL ${toString zcfg.TTL}
|
||||
${fmtRecordAttrs "IN" "SOA" zcfg.inet.SOA}
|
||||
${fmtRecordAttrs "IN" "A" zcfg.inet.A}
|
||||
${fmtRecordAttrs "IN" "CNAME" zcfg.inet.CNAME}
|
||||
${fmtRecordAttrs "IN" "MX" zcfg.inet.MX}
|
||||
${fmtRecordAttrs "IN" "NS" zcfg.inet.NS}
|
||||
${fmtRecordAttrs "IN" "SRV" zcfg.inet.SRV}
|
||||
${fmtRecordAttrs "IN" "TXT" zcfg.inet.TXT}
|
||||
${fmtIncludes zcfg.include}
|
||||
${zcfg.extraConfig}
|
||||
'';
|
||||
|
||||
configFile = toml.generate "trust-dns.toml" {
|
||||
listen_addrs_ipv4 = cfg.listenAddrsIPv4;
|
||||
@@ -58,20 +14,10 @@ let
|
||||
mapAttrs (zname: zcfg: rec {
|
||||
zone = if zcfg.name == null then zname else zcfg.name;
|
||||
zone_type = "Primary";
|
||||
file = if zcfg.file == null then
|
||||
pkgs.writeText "${zone}.zone" (genZone zcfg)
|
||||
else
|
||||
zcfg.file;
|
||||
file = zcfg.file;
|
||||
}) cfg.zones
|
||||
);
|
||||
};
|
||||
|
||||
# (listOf ty) type which also accepts single-assignment of `ty`.
|
||||
# it's used to allow the user to write:
|
||||
# CNAME."foo" = "bar";
|
||||
# as shorthand for
|
||||
# CNAME."foo" = [ "bar" ];
|
||||
listOrUnit = ty: types.coercedTo ty (elem: [ elem ]) (types.listOf ty);
|
||||
in
|
||||
{
|
||||
options = {
|
||||
@@ -80,6 +26,14 @@ in
|
||||
default = false;
|
||||
type = types.bool;
|
||||
};
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.trust-dns;
|
||||
description = ''
|
||||
trust-dns package to use.
|
||||
should provide bin/named, which will be invoked with --config x and --zonedir d and maybe -q.
|
||||
'';
|
||||
};
|
||||
listenAddrsIPv4 = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
@@ -89,101 +43,65 @@ in
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
zonedir = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "/";
|
||||
description = ''
|
||||
where the `file` option in zones.* is relative to.
|
||||
'';
|
||||
};
|
||||
# reference <nixpkgs:nixos/modules/services/web-servers/nginx/vhost-options.nix>
|
||||
zones = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
type = types.attrsOf (types.submodule ({ config, name, ... }: {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
description = "zone name. defaults to the attribute name in zones";
|
||||
default = name;
|
||||
};
|
||||
text = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
};
|
||||
TTL = mkOption {
|
||||
type = types.int;
|
||||
description = "default TTL";
|
||||
default = 3600;
|
||||
};
|
||||
include = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "paths of other zone files to $INCLUDE into this one";
|
||||
default = [];
|
||||
};
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
description = "extra lines to append to the zone file";
|
||||
default = "";
|
||||
};
|
||||
inet = {
|
||||
SOA = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "Start of Authority record(s)";
|
||||
default = {};
|
||||
};
|
||||
A = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "IPv4 address record(s)";
|
||||
default = {};
|
||||
};
|
||||
CNAME = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "canonical name record(s)";
|
||||
default = {};
|
||||
};
|
||||
MX = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "mail exchanger record(s)";
|
||||
default = {};
|
||||
};
|
||||
NS = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "name server record(s)";
|
||||
default = {};
|
||||
};
|
||||
SRV = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "service record(s)";
|
||||
default = {};
|
||||
};
|
||||
TXT = mkOption {
|
||||
type = types.attrsOf (listOrUnit types.str);
|
||||
description = "text record(s)";
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
|
||||
file = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "instead of using the generated zone file, use the specified path";
|
||||
type = types.nullOr (types.either types.path types.str);
|
||||
description = ''
|
||||
path to a .zone file.
|
||||
if omitted, will be generated from the `text` option.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
config = {
|
||||
file = lib.mkIf (config.text != null) (pkgs.writeText "${config.name}.zone" config.text);
|
||||
};
|
||||
}));
|
||||
default = {};
|
||||
description = "Declarative zone config";
|
||||
};
|
||||
|
||||
generatedZones = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
description = "generated zone text for each zone";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
sane.services.trust-dns.generatedZones = mapAttrs (zone: zcfg: genZone zcfg) cfg.zones;
|
||||
networking.firewall.allowedTCPPorts = [ 53 ];
|
||||
networking.firewall.allowedUDPPorts = [ 53 ];
|
||||
sane.ports.ports."53" = {
|
||||
protocol = [ "udp" "tcp" ];
|
||||
visibleTo.lan = true;
|
||||
visibleTo.wan = true;
|
||||
description = "colin-dns-hosting";
|
||||
};
|
||||
|
||||
systemd.services.trust-dns = {
|
||||
description = "trust-dns DNS server";
|
||||
serviceConfig = {
|
||||
ExecStart =
|
||||
let
|
||||
flags = lib.optionalString cfg.quiet "-q";
|
||||
flags = lib.optional cfg.quiet "-q" ++
|
||||
lib.optionals (cfg.zonedir != null) [ "--zonedir" cfg.zonedir ];
|
||||
flagsStr = builtins.concatStringsSep " " flags;
|
||||
in ''
|
||||
${pkgs.trust-dns}/bin/named \
|
||||
${cfg.package}/bin/named \
|
||||
--config ${configFile} \
|
||||
--zonedir / ${flags}
|
||||
${flagsStr}
|
||||
'';
|
||||
Type = "simple";
|
||||
Restart = "on-failure";
|
||||
|
14
nixpatches/2023-05-31-toplevel-alsa.patch
Normal file
14
nixpatches/2023-05-31-toplevel-alsa.patch
Normal file
@@ -0,0 +1,14 @@
|
||||
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
|
31
nixpatches/2023-06-02-qt6-qtwebengine-cross.patch
Normal file
31
nixpatches/2023-06-02-qt6-qtwebengine-cross.patch
Normal file
@@ -0,0 +1,31 @@
|
||||
diff --git a/pkgs/development/libraries/qt-6/modules/qtwebengine.nix b/pkgs/development/libraries/qt-6/modules/qtwebengine.nix
|
||||
index fadbc5d2bfa..e4f2aec5a32 100644
|
||||
--- a/pkgs/development/libraries/qt-6/modules/qtwebengine.nix
|
||||
+++ b/pkgs/development/libraries/qt-6/modules/qtwebengine.nix
|
||||
@@ -97,6 +97,9 @@
|
||||
, xnu
|
||||
}:
|
||||
|
||||
+let
|
||||
+ buildPython = buildPackages.python3.withPackages (ps: with ps; [ html5lib ]);
|
||||
+in
|
||||
qtModule {
|
||||
pname = "qtwebengine";
|
||||
qtInputs = [ qtdeclarative qtwebchannel qtwebsockets qtpositioning ];
|
||||
@@ -108,7 +111,7 @@ qtModule {
|
||||
gperf
|
||||
ninja
|
||||
pkg-config
|
||||
- (python3.withPackages (ps: with ps; [ html5lib ]))
|
||||
+ buildPython
|
||||
which
|
||||
gn
|
||||
nodejs
|
||||
@@ -304,6 +307,7 @@ qtModule {
|
||||
|
||||
preConfigure = ''
|
||||
export NINJAFLAGS="-j$NIX_BUILD_CORES"
|
||||
+ export CMAKE_PREFIX_PATH="${buildPython}/bin:$CMAKE_PREFIX_PATH"
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
@@ -0,0 +1,60 @@
|
||||
diff --git a/pkgs/applications/video/jellyfin-media-player/default.nix b/pkgs/applications/video/jellyfin-media-player/default.nix
|
||||
index e781f80e455..d1990294141 100644
|
||||
--- a/pkgs/applications/video/jellyfin-media-player/default.nix
|
||||
+++ b/pkgs/applications/video/jellyfin-media-player/default.nix
|
||||
@@ -1,7 +1,6 @@
|
||||
{ lib
|
||||
, fetchFromGitHub
|
||||
, fetchzip
|
||||
-, mkDerivation
|
||||
, stdenv
|
||||
, Cocoa
|
||||
, CoreAudio
|
||||
@@ -12,21 +11,20 @@
|
||||
, libGL
|
||||
, libX11
|
||||
, libXrandr
|
||||
+, libsForQt5
|
||||
, libvdpau
|
||||
, mpv
|
||||
, ninja
|
||||
, pkg-config
|
||||
, python3
|
||||
-, qtbase
|
||||
-, qtwayland
|
||||
-, qtwebchannel
|
||||
-, qtwebengine
|
||||
-, qtx11extras
|
||||
, jellyfin-web
|
||||
, withDbus ? stdenv.isLinux, dbus
|
||||
}:
|
||||
|
||||
-mkDerivation rec {
|
||||
+let
|
||||
+ inherit (libsForQt5) qtbase qtwayland qtwebchannel qtwebengine qtx11extras wrapQtAppsHook;
|
||||
+in
|
||||
+stdenv.mkDerivation rec {
|
||||
pname = "jellyfin-media-player";
|
||||
version = "1.9.1";
|
||||
|
||||
@@ -69,6 +67,7 @@ mkDerivation rec {
|
||||
ninja
|
||||
pkg-config
|
||||
python3
|
||||
+ wrapQtAppsHook
|
||||
];
|
||||
|
||||
cmakeFlags = [
|
||||
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
|
||||
index eb309c9b283..d8a718db698 100644
|
||||
--- a/pkgs/top-level/all-packages.nix
|
||||
+++ b/pkgs/top-level/all-packages.nix
|
||||
@@ -5289,7 +5289,7 @@ with pkgs;
|
||||
|
||||
jellyfin-ffmpeg = callPackage ../development/libraries/jellyfin-ffmpeg { };
|
||||
|
||||
- jellyfin-media-player = libsForQt5.callPackage ../applications/video/jellyfin-media-player {
|
||||
+ jellyfin-media-player = callPackage ../applications/video/jellyfin-media-player {
|
||||
inherit (darwin.apple_sdk.frameworks) CoreFoundation Cocoa CoreAudio MediaPlayer;
|
||||
# Disable pipewire to avoid segfault, see https://github.com/jellyfin/jellyfin-media-player/issues/341
|
||||
mpv = wrapMpv (mpv-unwrapped.override { pipewireSupport = false; }) { };
|
@@ -1,15 +1,15 @@
|
||||
diff --git a/pkgs/servers/web-apps/lemmy/pin.json b/pkgs/servers/web-apps/lemmy/pin.json
|
||||
index b2a1f1923ce..621b5945b6b 100644
|
||||
index 5b7b9aa49a5..6cd30d294d8 100644
|
||||
--- a/pkgs/servers/web-apps/lemmy/pin.json
|
||||
+++ b/pkgs/servers/web-apps/lemmy/pin.json
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
- "version": "0.17.2",
|
||||
- "serverSha256": "sha256-fkpMVm52XLyrk9RfzJpthT8fctIilawAIgfK+4TXHvU=",
|
||||
- "serverCargoSha256": "sha256-AC6EP612uaeGfqHbrHrz89h0tsNlMceEg6GxEsm1QMA=",
|
||||
- "version": "0.17.4",
|
||||
- "serverSha256": "sha256-nztT6o5Tur64dMWII+wf5CBVJBJ59MGXKdS5OJO0SSc=",
|
||||
- "serverCargoSha256": "sha256-3In2W+cSVtMkaKrn1hWOVL/V/qkKlH30qGPi3rNdpQI=",
|
||||
+ "version": "88a0d2feec3f9b4a06f2d8d090894111afcbd9e2",
|
||||
+ "serverSha256": "sha256-jVa7SckpH21TG+i1yjJOkhEgjnZ0Zgk2IUP7sCdtv1Y=",
|
||||
+ "serverCargoSha256": "sha256-trp/TCGtAtZlKdZk2CaJ3E9Lj95cq797PLWUF/DD6/M=",
|
||||
"uiSha256": "sha256-0Zhm6Jgc6rlN4c7ryRnR45+fZEdzQhuOXSwU8Wz0D5g=",
|
||||
"uiSha256": "sha256-Ebc4VzuCJhPoO16qCgSVyYFXH7YcymxcGcN/Sgyg5Gs=",
|
||||
"uiYarnDepsSha256": "sha256-aZAclSaFZJvuK+FpCBWboGaVEOEJTxq2jnWk0A6iAFw="
|
||||
}
|
@@ -52,20 +52,12 @@ in [
|
||||
# TODO: why doesn't this apply?
|
||||
# ./2023-03-04-ccache-cross-fix.patch
|
||||
|
||||
# 2023-04-11: bambu-studio: init at unstable-2023-01-11
|
||||
# 2023-04-11: bambu-studio: init at 01.06.02.04
|
||||
(fetchpatch' {
|
||||
prUrl = "https://github.com/NixOS/nixpkgs/pull/206495";
|
||||
hash = "sha256-RbQzAtFTr7Nrk2YBcHpKQMYoPlFMVSXNl96B/lkKluQ=";
|
||||
hash = "sha256-jl6SZwSDhQTlpM5FyGaFU/svwTb1ySdKtvWMgsneq3A=";
|
||||
})
|
||||
|
||||
# update to newer lemmy-server.
|
||||
# should be removable when > 0.17.2 releases?
|
||||
# removing this now causes:
|
||||
# INFO lemmy_server::code_migrations: No Local Site found, creating it.
|
||||
# Error: LemmyError { message: None, inner: duplicate key value violates unique constraint "local_site_site_id_key", context: "SpanTrace" }
|
||||
# though perhaps this error doesn't occur on fresh databases (idk).
|
||||
./2023-04-29-lemmy.patch
|
||||
|
||||
(fetchpatch' {
|
||||
title = "cargo-docset: init at 0.3.1";
|
||||
saneCommit = "5a09e84c6159ce545029483384580708bc04c08f";
|
||||
@@ -73,17 +65,6 @@ in [
|
||||
hash = "sha256-Z1HOps3w/WvxAiyUAHWszKqwS9EwA6rf4XfgPGp+2sQ=";
|
||||
})
|
||||
|
||||
(fetchpatch' {
|
||||
title = "nixos/lemmy: support nginx";
|
||||
saneCommit = "4c86db6dcb78795ac9bb514d9c779fd591070b23";
|
||||
hash = "sha256-G7jGhSPUp9BMxh2yTzo0KUUVabMJeZ28YTA+0iPldRI=";
|
||||
})
|
||||
|
||||
(fetchpatch' {
|
||||
title = "feedbackd: 0.1.0 -> 0.2.0";
|
||||
saneCommit = "a0186a5782708a640cd6eaad6e9742b9cccebe9d";
|
||||
hash = "sha256-f8he7pQow4fZkTVVqU/A5KgovZA7m7MccRQNTnDxw5o=";
|
||||
})
|
||||
# (fetchpatch' {
|
||||
# # phoc: 0.25.0 -> 0.27.0
|
||||
# # TODO: move wayland-scanner & glib to nativeBuildInputs
|
||||
@@ -129,14 +110,6 @@ in [
|
||||
hash = "sha256-+g3XhmBt/udhbBDiVyfWnfXKvZTvDurlvPblQ9HYp3s=";
|
||||
})
|
||||
|
||||
(fetchpatch' {
|
||||
# 2023/05/24: merged upstream
|
||||
# hare: unstable-2023-03-15 -> unstable-2023-04-23
|
||||
# + harec: unstable-2023-02-18 -> unstable-2023-04-25
|
||||
prUrl = "https://github.com/NixOS/nixpkgs/pull/233732";
|
||||
hash = "sha256-SGDKvsMiK3Pq57JEj/MamDBX5jBXwV/E5jclKO2NAUs=";
|
||||
})
|
||||
|
||||
# (fetchpatch' {
|
||||
# title = "hare-json: init at unstable-2023-01-31";
|
||||
# saneCommit = "260f9c6ac4e3564acbceb46aa4b65fbb652f8e23";
|
||||
@@ -158,6 +131,52 @@ in [
|
||||
hash = "sha256-9XKPNg7TewicfbMgiASpYysTs5aduIVP+4onz+noc/0=";
|
||||
})
|
||||
|
||||
# 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 causes:
|
||||
# INFO lemmy_server::code_migrations: No Local Site found, creating it.
|
||||
# Error: LemmyError { message: None, inner: duplicate key value violates unique constraint "local_site_site_id_key", context: "SpanTrace" }
|
||||
# more specifically, lemmy can't find the site because it receives an error from diesel:
|
||||
# Err(DeserializationError("Unrecognized enum variant"))
|
||||
# this is likely some mis-ordered db migrations
|
||||
# or perhaps the whole set of migrations here isn't being running right.
|
||||
# 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 = "sequoia: 0.28.0 -> 0.30.1";
|
||||
prUrl = "https://github.com/NixOS/nixpkgs/pull/237698";
|
||||
saneCommit = "71f47689d11e09b6ff70cbd4238e386b50d46899";
|
||||
hash = "sha256-cadnRzZ0sjwdSc845zFtgYzLrsPGsZ9ShELibvQWLUU=";
|
||||
})
|
||||
|
||||
(fetchpatch' {
|
||||
title = "koreader: 2023.04 -> 2023.05.1";
|
||||
saneCommit = "a5c471bd263abe93e291239e0078ac4255a94262";
|
||||
hash = "sha256-m++Vv/FK7cxONCz6n0MLO3CiKNrRH0ttFmoC1Xmba+A=";
|
||||
})
|
||||
|
||||
# (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";
|
||||
# saneCommit = "b168bf862d53535151b9142a15fbd53e18e688c5";
|
||||
# hash = "sha256-dDa2mrCJ416PIYsDH9ya/4aQdqtp4BwzIisa8HdVFxo=";
|
||||
# })
|
||||
|
||||
# for raspberry pi: allow building u-boot for rpi 4{,00}
|
||||
# TODO: remove after upstreamed: https://github.com/NixOS/nixpkgs/pull/176018
|
||||
# (it's a dupe of https://github.com/NixOS/nixpkgs/pull/112677 )
|
||||
|
@@ -82,11 +82,11 @@ in {
|
||||
ibus # "error: cannot run test program while cross compiling"
|
||||
jellyfin-web # in node-dependencies-jellyfin-web: "node: command not found" (nodePackages don't cross compile)
|
||||
# libgccjit # "../../gcc-9.5.0/gcc/jit/jit-result.c:52:3: error: 'dlclose' was not declared in this scope" (needed by emacs!)
|
||||
# libsForQt5 # qtbase # make: g++: No such file or directory
|
||||
# libsForQt5 # if we emulate qt5, we're better off emulating libsForQt5 else qt complains about multiple versions of qtbase
|
||||
perlInterpreters # perl5.36.0-Module-Build perl5.36.0-Test-utf8 (see tracking issues ^)
|
||||
# qgnomeplatform
|
||||
# qtbase
|
||||
qt5 # qt5.qtx11extras fails, but we can't selectively emulate it
|
||||
# qt5 # qt5.qtbase, qt5.qtx11extras fails, but we can't selectively emulate them.
|
||||
# qt6 # "You need to set QT_HOST_PATH to cross compile Qt."
|
||||
# sequoia # "/nix/store/q8hg17w47f9xr014g36rdc2gi8fv02qc-clang-aarch64-unknown-linux-gnu-12.0.1-lib/lib/libclang.so.12: cannot open shared object file: No such file or directory"', /build/sequoia-0.27.0-vendor.tar.gz/bindgen/src/lib.rs:1975:31"
|
||||
# splatmoji
|
||||
@@ -247,6 +247,14 @@ in {
|
||||
nativeBuildInputs = upstream.nativeBuildInputs ++ [ final.git ];
|
||||
});
|
||||
|
||||
cozy = prev.cozy.override {
|
||||
cozy = prev.cozy.upstream.cozy.override {
|
||||
# fixes runtime error: "Settings schema 'org.gtk.Settings.FileChooser' is not installed"
|
||||
# otherwise gtk3+ schemas aren't added to XDG_DATA_DIRS
|
||||
inherit (emulated) wrapGAppsHook;
|
||||
};
|
||||
};
|
||||
|
||||
dante = prev.dante.override {
|
||||
# fixes: "configure: error: error: getaddrinfo() error value count too low"
|
||||
inherit (emulated) stdenv;
|
||||
@@ -378,8 +386,17 @@ in {
|
||||
# };
|
||||
# fixes: "src/meson.build:106:0: ERROR: Program 'glib-compile-resources' not found or not executable"
|
||||
file-roller = mvToNativeInputs [ final.glib ] super.file-roller;
|
||||
gnome-bluetooth = super.gnome-bluetooth.override {
|
||||
# fixes -msse2, -mfpmath=sse flags
|
||||
wrapGAppsHook4 = final.wrapGAppsHook;
|
||||
};
|
||||
# fixes: "meson.build:75:6: ERROR: Program 'gtk-update-icon-cache' not found or not executable"
|
||||
gnome-clocks = addNativeInputs [ final.gtk4 ] super.gnome-clocks;
|
||||
gnome-clocks = (
|
||||
addNativeInputs [ final.gtk4 ] super.gnome-clocks
|
||||
).override {
|
||||
# fixes -msse2, -mfpmath=sse flags
|
||||
wrapGAppsHook4 = final.wrapGAppsHook;
|
||||
};
|
||||
# fixes: "src/meson.build:3:0: ERROR: Program 'glib-compile-resources' not found or not executable"
|
||||
gnome-color-manager = mvToNativeInputs [ final.glib ] super.gnome-color-manager;
|
||||
# fixes "subprojects/gvc/meson.build:30:0: ERROR: Program 'glib-mkenums mkenums' not found or not executable"
|
||||
@@ -470,7 +487,7 @@ in {
|
||||
gnome-user-share = addNativeInputs [ final.glib ] super.gnome-user-share;
|
||||
# fixes: "FileNotFoundError: [Errno 2] No such file or directory: 'gtk4-update-icon-cache'"
|
||||
gnome-weather = addNativeInputs [ final.gtk4 ] super.gnome-weather;
|
||||
mutter = super.mutter.overrideAttrs (orig: {
|
||||
mutter = (super.mutter.overrideAttrs (orig: {
|
||||
nativeBuildInputs = orig.nativeBuildInputs ++ [
|
||||
final.glib # fixes "clutter/clutter/meson.build:281:0: ERROR: Program 'glib-mkenums mkenums' not found or not executable"
|
||||
final.buildPackages.gobject-introspection # allows to build without forcing `introspection=false` (which would break gnome-shell)
|
||||
@@ -481,7 +498,10 @@ in {
|
||||
];
|
||||
mesonFlags = lib.remove "-Ddocs=true" orig.mesonFlags;
|
||||
outputs = lib.remove "devdoc" orig.outputs;
|
||||
});
|
||||
})).override {
|
||||
# fixes -msse2, -mfpmath=sse flags
|
||||
wrapGAppsHook4 = final.wrapGAppsHook;
|
||||
};
|
||||
# nautilus = super.nautilus.override {
|
||||
# # fixes: "meson.build:123:0: ERROR: Dependency "libxml-2.0" not found, tried pkgconfig"
|
||||
# # new failure mode: "/nix/store/grqh2wygy9f9wp5bgvqn4im76v82zmcx-binutils-2.39/bin/ld: /nix/store/f7yr5z123d162p5457jh3wzkqm7x8yah-glib-2.74.3/lib/libglib-2.0.so: error adding symbols: file in wrong format"
|
||||
@@ -497,7 +517,9 @@ in {
|
||||
super.nautilus
|
||||
).override {
|
||||
# fixes -msse2, -mfpmath=sse flags
|
||||
wrapGAppsHook4 = final.wrapGAppsHook;
|
||||
# wrapGAppsHook4 = final.wrapGAppsHook;
|
||||
# fixes -msse2, -mfpmath=ssh flags AND "Settings schema 'org.gtk.gtk4.Settings.FileChooser' is not installed"
|
||||
wrapGAppsHook4 = emulated.wrapGAppsHook4;
|
||||
};
|
||||
});
|
||||
|
||||
@@ -635,12 +657,21 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
jellyfin-media-player = prev.jellyfin-media-player.overrideAttrs (upstream: {
|
||||
meta = upstream.meta // {
|
||||
platforms = upstream.meta.platforms ++ [
|
||||
"aarch64-linux"
|
||||
];
|
||||
};
|
||||
jellyfin-media-player = mvToBuildInputs
|
||||
[ final.libsForQt5.wrapQtAppsHook ] # this shouldn't be: but otherwise we get mixed qtbase deps
|
||||
(prev.jellyfin-media-player.overrideAttrs (upstream: {
|
||||
meta = upstream.meta // {
|
||||
platforms = upstream.meta.platforms ++ [
|
||||
"aarch64-linux"
|
||||
];
|
||||
};
|
||||
}));
|
||||
jellyfin-media-player-qt6 = prev.jellyfin-media-player-qt6.overrideAttrs (upstream: {
|
||||
# nativeBuildInputs => result targets x86.
|
||||
# buildInputs => result targets correct platform, but doesn't wrap the runtime deps
|
||||
# TODO: fix the hook in qt6 itself?
|
||||
depsHostHost = upstream.depsHostHost or [] ++ [ final.qt6.wrapQtAppsHook ];
|
||||
nativeBuildInputs = lib.remove [ final.qt6.wrapQtAppsHook ] upstream.nativeBuildInputs;
|
||||
});
|
||||
# jellyfin-web = prev.jellyfin-web.override {
|
||||
# # in node-dependencies-jellyfin-web: "node: command not found"
|
||||
@@ -658,6 +689,18 @@ in {
|
||||
./kitty-no-docs.patch
|
||||
];
|
||||
});
|
||||
komikku = prev.komikku.override {
|
||||
# GI_TYPELIB_PATH points to x86_64 types in the default build, only when using wrapGAppsHook4
|
||||
wrapGAppsHook4 = final.wrapGAppsHook;
|
||||
};
|
||||
koreader = (prev.koreader.override {
|
||||
# fixes runtime error: luajit: ./ffi/util.lua:757: attempt to call field 'pack' (a nil value)
|
||||
inherit (emulated) luajit;
|
||||
}).overrideAttrs (upstream: {
|
||||
nativeBuildInputs = upstream.nativeBuildInputs ++ [
|
||||
final.autoPatchelfHook
|
||||
];
|
||||
});
|
||||
libgweather = rmNativeBuildInputs [ final.glib ] (prev.libgweather.override {
|
||||
# alternative to emulating python3 is to specify it in `buildInputs` instead of `nativeBuildInputs` (upstream),
|
||||
# but presumably that's just a different way to emulate it.
|
||||
@@ -677,18 +720,24 @@ in {
|
||||
# buildInputs = upstream.buildInputs ++ [ final.vala ];
|
||||
# });
|
||||
|
||||
libsForQt5 = prev.libsForQt5.overrideScope' (self: super: {
|
||||
qgpgme = super.qgpgme.overrideAttrs (orig: {
|
||||
# fix so it can find the MOC compiler
|
||||
# it looks like it might not *need* to propagate qtbase, but so far unclear
|
||||
nativeBuildInputs = orig.nativeBuildInputs ++ [ self.qtbase ];
|
||||
propagatedBuildInputs = lib.remove self.qtbase orig.propagatedBuildInputs;
|
||||
});
|
||||
phonon = super.phonon.overrideAttrs (orig: {
|
||||
# fixes "ECM (required version >= 5.60), Extra CMake Modules"
|
||||
buildInputs = orig.buildInputs ++ [ final.extra-cmake-modules ];
|
||||
});
|
||||
});
|
||||
# libsForQt5 = prev.libsForQt5.overrideScope' (self: super: {
|
||||
# qgpgme = super.qgpgme.overrideAttrs (orig: {
|
||||
# # fix so it can find the MOC compiler
|
||||
# # it looks like it might not *need* to propagate qtbase, but so far unclear
|
||||
# nativeBuildInputs = orig.nativeBuildInputs ++ [ self.qtbase ];
|
||||
# propagatedBuildInputs = lib.remove self.qtbase orig.propagatedBuildInputs;
|
||||
# });
|
||||
# phonon = super.phonon.overrideAttrs (orig: {
|
||||
# # fixes "ECM (required version >= 5.60), Extra CMake Modules"
|
||||
# buildInputs = orig.buildInputs ++ [ final.extra-cmake-modules ];
|
||||
# });
|
||||
# });
|
||||
# libsForQt5 = prev.libsForQt5.overrideScope' (self: super: {
|
||||
# # emulate all the qt5 packages, but rework `libsForQt5.callPackage` and `mkDerivation`
|
||||
# # to use non-emulated stdenv by default.
|
||||
# mkDerivation = self.mkDerivationWith final.stdenv.mkDerivation;
|
||||
# callPackage = self.newScope { inherit (self) qtCompatVersion qtModule srcs; inherit (final) stdenv; };
|
||||
# });
|
||||
|
||||
# fixes: "ar: command not found"
|
||||
# `ar` is provided by bintools
|
||||
@@ -959,34 +1008,106 @@ in {
|
||||
# inherit (emulated.qt5) qtModule;
|
||||
# };
|
||||
# });
|
||||
# qt6 = prev.qt6.overrideScope' (self: super: {
|
||||
# # inherit (emulated.qt6) qtModule;
|
||||
# qtbase = super.qtbase.overrideAttrs (upstream: {
|
||||
# # cmakeFlags = upstream.cmakeFlags ++ lib.optionals (final.stdenv.buildPlatform != final.stdenv.hostPlatform) [
|
||||
# cmakeFlags = upstream.cmakeFlags ++ lib.optionals (final.stdenv.buildPlatform != final.stdenv.hostPlatform) [
|
||||
# # "-DCMAKE_CROSSCOMPILING=True" # fails to solve QT_HOST_PATH error
|
||||
# "-DQT_HOST_PATH=${final.buildPackages.qt6.full}"
|
||||
# ];
|
||||
# });
|
||||
# qtModule = args: (super.qtModule args).overrideAttrs (upstream: {
|
||||
# # the nixpkgs comment about libexec seems to be outdated:
|
||||
# # it's just that cross-compiled syncqt.pl doesn't get its #!/usr/bin/env shebang replaced.
|
||||
# preConfigure = lib.replaceStrings
|
||||
# ["${lib.getDev self.qtbase}/libexec/syncqt.pl"]
|
||||
# ["perl ${lib.getDev self.qtbase}/libexec/syncqt.pl"]
|
||||
# upstream.preConfigure;
|
||||
# });
|
||||
# # qtwayland = super.qtwayland.overrideAttrs (upstream: {
|
||||
# # preConfigure = "fixQtBuiltinPaths . '*.pr?'";
|
||||
# # });
|
||||
# # qtwayland = super.qtwayland.override {
|
||||
# # inherit (self) qtbase;
|
||||
# # };
|
||||
# # qtbase = super.qtbase.override {
|
||||
# # # fixes: "You need to set QT_HOST_PATH to cross compile Qt."
|
||||
# # inherit (emulated) stdenv;
|
||||
# # };
|
||||
# });
|
||||
qt5 = emulated.qt5.overrideScope' (self: super: {
|
||||
# emulate all the qt5 packages, but rework `libsForQt5.callPackage` and `mkDerivation`
|
||||
# to use non-emulated stdenv by default.
|
||||
mkDerivation = self.mkDerivationWith final.stdenv.mkDerivation;
|
||||
callPackage = self.newScope { inherit (self) qtCompatVersion qtModule srcs; inherit (final) stdenv; };
|
||||
});
|
||||
qt6 = prev.qt6.overrideScope' (self: super: {
|
||||
# # inherit (emulated.qt6) qtModule;
|
||||
# qtbase = super.qtbase.overrideAttrs (upstream: {
|
||||
# # cmakeFlags = upstream.cmakeFlags ++ lib.optionals (final.stdenv.buildPlatform != final.stdenv.hostPlatform) [
|
||||
# cmakeFlags = upstream.cmakeFlags ++ lib.optionals (final.stdenv.buildPlatform != final.stdenv.hostPlatform) [
|
||||
# # "-DCMAKE_CROSSCOMPILING=True" # fails to solve QT_HOST_PATH error
|
||||
# "-DQT_HOST_PATH=${final.buildPackages.qt6.full}"
|
||||
# ];
|
||||
# });
|
||||
# qtModule = args: (super.qtModule args).overrideAttrs (upstream: {
|
||||
# # the nixpkgs comment about libexec seems to be outdated:
|
||||
# # it's just that cross-compiled syncqt.pl doesn't get its #!/usr/bin/env shebang replaced.
|
||||
# preConfigure = lib.replaceStrings
|
||||
# ["${lib.getDev self.qtbase}/libexec/syncqt.pl"]
|
||||
# ["perl ${lib.getDev self.qtbase}/libexec/syncqt.pl"]
|
||||
# upstream.preConfigure;
|
||||
# });
|
||||
# # qtwayland = super.qtwayland.overrideAttrs (upstream: {
|
||||
# # preConfigure = "fixQtBuiltinPaths . '*.pr?'";
|
||||
# # });
|
||||
# # qtwayland = super.qtwayland.override {
|
||||
# # inherit (self) qtbase;
|
||||
# # };
|
||||
# # qtbase = super.qtbase.override {
|
||||
# # # fixes: "You need to set QT_HOST_PATH to cross compile Qt."
|
||||
# # inherit (emulated) stdenv;
|
||||
# # };
|
||||
|
||||
qtwebengine = super.qtwebengine.overrideAttrs (upstream: {
|
||||
# depsBuildBuild = upstream.depsBuildBuild or [] ++ [ final.pkg-config ];
|
||||
# XXX: qt seems to use its own terminology for "host" and "target":
|
||||
# - <https://www.qt.io/blog/qt6-development-hosts-and-targets>
|
||||
# - "host" = machine invoking the compiler
|
||||
# - "target" = machine on which the resulting qtwebengine.so binaries will run
|
||||
# XXX: NIX_CFLAGS_COMPILE_<machine> is how we get the `-isystem <dir>` flags.
|
||||
# probably we shouldn't blindly copy these from host machine to build machine,
|
||||
# as the headers could reasonably make different assumptions.
|
||||
preConfigure = upstream.preConfigure + ''
|
||||
# export PKG_CONFIG_HOST="$PKG_CONFIG"
|
||||
export PKG_CONFIG_HOST="$PKG_CONFIG_FOR_BUILD"
|
||||
# expose -isystem <zlib> to x86 builds
|
||||
export NIX_CFLAGS_COMPILE_x86_64_unknown_linux_gnu="$NIX_CFLAGS_COMPILE"
|
||||
export NIX_LDFLAGS_x86_64_unknown_linux_gnu="-L${final.buildPackages.zlib}/lib"
|
||||
'';
|
||||
patches = upstream.patches or [] ++ [
|
||||
# ./qtwebengine-host-pkg-config.patch
|
||||
# alternatively, look at dlopenBuildInputs
|
||||
./qtwebengine-host-cc.patch
|
||||
];
|
||||
# patch the qt pkg-config script to show us more debug info
|
||||
postPatch = upstream.postPatch or "" + ''
|
||||
sed -i s/options.debug/True/g src/3rdparty/chromium/build/config/linux/pkg-config.py
|
||||
'';
|
||||
nativeBuildInputs = upstream.nativeBuildInputs ++ [
|
||||
final.bintools-unwrapped # for readelf
|
||||
final.buildPackages.cups # for cups-config
|
||||
final.buildPackages.fontconfig
|
||||
final.buildPackages.glib
|
||||
final.buildPackages.harfbuzz
|
||||
final.buildPackages.icu
|
||||
final.buildPackages.libjpeg
|
||||
final.buildPackages.libpng
|
||||
final.buildPackages.libwebp
|
||||
final.buildPackages.nss
|
||||
# final.gcc-unwrapped.libgcc # for libgcc_s.so
|
||||
final.buildPackages.zlib
|
||||
];
|
||||
depsBuildBuild = upstream.depsBuildBuild or [] ++ [ final.pkg-config ];
|
||||
# buildInputs = upstream.buildInputs ++ [
|
||||
# final.gcc-unwrapped.libgcc # for libgcc_s.so. this gets loaded during build, suggesting i surely messed something up
|
||||
# ];
|
||||
# buildInputs = upstream.buildInputs ++ [
|
||||
# final.gcc-unwrapped.libgcc
|
||||
# ];
|
||||
# nativeBuildInputs = upstream.nativeBuildInputs ++ [
|
||||
# final.icu
|
||||
# ];
|
||||
# buildInputs = upstream.buildInputs ++ [
|
||||
# final.icu
|
||||
# ];
|
||||
# env.NIX_DEBUG="1";
|
||||
# env.NIX_DEBUG="7";
|
||||
# cmakeFlags = lib.remove "-DQT_FEATURE_webengine_system_icu=ON" upstream.cmakeFlags;
|
||||
cmakeFlags = upstream.cmakeFlags ++ lib.optionals (final.stdenv.hostPlatform != final.stdenv.buildPlatform) [
|
||||
# "--host-cc=${final.buildPackages.stdenv.cc}/bin/cc"
|
||||
# "--host-cxx=${final.buildPackages.stdenv.cc}/bin/c++"
|
||||
# these are my own vars, used by my own patch
|
||||
"-DCMAKE_HOST_C_COMPILER=${final.buildPackages.stdenv.cc}/bin/gcc"
|
||||
"-DCMAKE_HOST_CXX_COMPILER=${final.buildPackages.stdenv.cc}/bin/g++"
|
||||
"-DCMAKE_HOST_AR=${final.buildPackages.stdenv.cc}/bin/ar"
|
||||
"-DCMAKE_HOST_NM=${final.buildPackages.stdenv.cc}/bin/nm"
|
||||
];
|
||||
});
|
||||
});
|
||||
|
||||
rmlint = prev.rmlint.override {
|
||||
# fixes "Checking whether the C compiler works... no"
|
||||
@@ -1134,7 +1255,14 @@ in {
|
||||
addNativeInputs [ final.wayland-scanner ] (
|
||||
mvToNativeInputs [ final.gettext final.glib ] prev.xdg-desktop-portal-gnome
|
||||
)
|
||||
);
|
||||
).override {
|
||||
# fixes -msse2, -mfpmath=sse flags
|
||||
wrapGAppsHook4 = final.wrapGAppsHook;
|
||||
};
|
||||
# "fatal error: urcu.h: No such file or directory"
|
||||
# xfsprogs wants to compile things for the build target (BUILD_CC)
|
||||
# xfsprogs = useEmulatedStdenv prev.xfsprogs;
|
||||
xfsprogs = addNativeInputs [ final.liburcu ] prev.xfsprogs;
|
||||
# webkitgtk = prev.webkitgtk.override { stdenv = final.ccacheStdenv; };
|
||||
# webp-pixbuf-loader = prev.webp-pixbuf-loader.override {
|
||||
# # fixes "Builder called die: Cannot wrap '/nix/store/kpp8qhzdjqgvw73llka5gpnsj0l4jlg8-gdk-pixbuf-aarch64-unknown-linux-gnu-2.42.10/bin/gdk-pixbuf-thumbnailer' because it is not an executable file"
|
||||
@@ -1150,6 +1278,10 @@ in {
|
||||
});
|
||||
# XXX: aarch64 webp-pixbuf-loader wanted by gdk-pixbuf-loaders.cache.drv, wanted by aarch64 gnome-control-center
|
||||
|
||||
# "extract-binary-wrapper-cmd: line 2: strings: command not found"
|
||||
# XXX: technically this belongs in pkgs/build-support/setup-hooks/make-binary-wrapper/default.nix ?
|
||||
wrapFirefox = browser: args: addNativeInputs [ final.bintools-unwrapped ] (prev.wrapFirefox browser args);
|
||||
|
||||
wvkbd = (
|
||||
# "wayland-scanner: no such program"
|
||||
mvToNativeInputs [ final.wayland-scanner ] prev.wvkbd
|
||||
|
35
overlays/qtwebengine-host-cc.patch
Normal file
35
overlays/qtwebengine-host-cc.patch
Normal file
@@ -0,0 +1,35 @@
|
||||
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
|
||||
index 771446ece..c20da0d56 100644
|
||||
--- a/src/CMakeLists.txt
|
||||
+++ b/src/CMakeLists.txt
|
||||
@@ -172,7 +172,11 @@ if(CMAKE_CROSSCOMPILING AND NOT IOS AND NOT MACOS)
|
||||
CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${QT_HOST_PATH}/lib/cmake/Qt6/qt.toolchain.cmake
|
||||
-DWEBENGINE_ROOT_BUILD_DIR=${PROJECT_BINARY_DIR}
|
||||
-DWEBENGINE_ROOT_SOURCE_DIR=${WEBENGINE_ROOT_SOURCE_DIR}
|
||||
- -DGN_TARGET_CPU=${TEST_architecture_arch}
|
||||
+ -DGN_TARGET_CPU=${CMAKE_HOST_SYSTEM_PROCESSOR}
|
||||
+ -DCMAKE_C_COMPILER=${CMAKE_HOST_C_COMPILER}
|
||||
+ -DCMAKE_CXX_COMPILER=${CMAKE_HOST_CXX_COMPILER}
|
||||
+ -DCMAKE_AR=${CMAKE_HOST_AR}
|
||||
+ -DCMAKE_NM=${CMAKE_HOST_NM}
|
||||
-DCMAKE_C_FLAGS=
|
||||
-DCMAKE_CXX_FLAGS=
|
||||
-DQT_FEATURE_qtwebengine_build=${QT_FEATURE_qtwebengine_build}
|
||||
diff --git a/src/host/CMakeLists.txt b/src/host/CMakeLists.txt
|
||||
index 2b92ebe85..e2ff58b35 100644
|
||||
--- a/src/host/CMakeLists.txt
|
||||
+++ b/src/host/CMakeLists.txt
|
||||
@@ -22,11 +22,11 @@ project(QtWebEngineConfigure
|
||||
find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals Core)
|
||||
|
||||
set(buildDir ${CMAKE_CURRENT_BINARY_DIR})
|
||||
-configure_gn_toolchain(host ${TEST_architecture_arch} ${TEST_architecture_arch}
|
||||
+configure_gn_toolchain(host ${CMAKE_HOST_SYSTEM_PROCESSOR} ${CMAKE_HOST_SYSTEM_PROCESSOR}
|
||||
${WEBENGINE_ROOT_SOURCE_DIR}/src/host/BUILD.toolchain.gn.in
|
||||
${buildDir}/host_toolchain
|
||||
)
|
||||
-get_v8_arch(GN_V8_HOST_CPU ${GN_TARGET_CPU} ${TEST_architecture_arch})
|
||||
+get_v8_arch(GN_V8_HOST_CPU ${GN_TARGET_CPU} ${CMAKE_HOST_SYSTEM_PROCESSOR})
|
||||
configure_gn_toolchain(v8 ${GN_V8_HOST_CPU} ${GN_TARGET_CPU}
|
||||
${WEBENGINE_ROOT_SOURCE_DIR}/src/host/BUILD.toolchain.gn.in
|
||||
${buildDir}/v8_toolchain)
|
14
overlays/qtwebengine-host-pkg-config.patch
Normal file
14
overlays/qtwebengine-host-pkg-config.patch
Normal file
@@ -0,0 +1,14 @@
|
||||
diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
|
||||
index 03d19992f..5ce54ca9d 100644
|
||||
--- a/cmake/Functions.cmake
|
||||
+++ b/cmake/Functions.cmake
|
||||
@@ -720,9 +720,6 @@ endfunction()
|
||||
function(create_pkg_config_wrapper wrapperName wrapperCmd)
|
||||
file(WRITE ${wrapperName}
|
||||
"#!/bin/sh\n"
|
||||
- "unset PKG_CONFIG_LIBDIR\n"
|
||||
- "unset PKG_CONFIG_PATH\n"
|
||||
- "unset PKG_CONFIG_SYSROOT_DIR\n"
|
||||
"exec ${wrapperCmd} \"$@\""
|
||||
)
|
||||
file(CHMOD ${wrapperName} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
|
24
pkgs/additional/alsa-ucm-conf-sane/default.nix
Normal file
24
pkgs/additional/alsa-ucm-conf-sane/default.nix
Normal file
@@ -0,0 +1,24 @@
|
||||
{ alsa-ucm-conf }:
|
||||
alsa-ucm-conf.overrideAttrs (upstream: {
|
||||
# upstream alsa ships with PinePhone audio configs, but they don't actually produce sound.
|
||||
# see: <https://github.com/alsa-project/alsa-ucm-conf/pull/134>
|
||||
# these audio files come from some revision of:
|
||||
# - <https://gitlab.manjaro.org/manjaro-arm/packages/community/phosh/alsa-ucm-pinephone>
|
||||
#
|
||||
# alternative to patching is to plumb `ALSA_CONFIG_UCM2 = "${./ucm2}"` environment variable into the relevant places
|
||||
# e.g. `systemd.services.pulseaudio.environment`.
|
||||
# that leaves more opportunity for gaps (i.e. missing a service),
|
||||
# on the other hand this method causes about 500 packages to be rebuilt (including qt5 and webkitgtk).
|
||||
#
|
||||
# note that with these files, the following audio device support:
|
||||
# - headphones work.
|
||||
# - "internal earpiece" works.
|
||||
# - "internal speaker" doesn't work.
|
||||
# - "analog output" doesn't work.
|
||||
postPatch = upstream.postPatch or "" + ''
|
||||
cp ${./ucm2/PinePhone}/* ucm2/Allwinner/A64/PinePhone/
|
||||
# fix the self-contained ucm files i source from to have correct path within the alsa-ucm-conf source tree
|
||||
sed -i 's:"HiFi.conf":"/Allwinner/A64/PinePhone/HiFi.conf":' ucm2/Allwinner/A64/PinePhone/PinePhone.conf
|
||||
sed -i 's:"VoiceCall.conf":"/Allwinner/A64/PinePhone/VoiceCall.conf":' ucm2/Allwinner/A64/PinePhone/PinePhone.conf
|
||||
'';
|
||||
})
|
18
pkgs/additional/gpodder-adaptive/default.nix
Normal file
18
pkgs/additional/gpodder-adaptive/default.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{ gpodder
|
||||
, fetchFromGitHub
|
||||
, libhandy
|
||||
}:
|
||||
gpodder.overrideAttrs (upstream: rec {
|
||||
pname = "gpodder-adaptive";
|
||||
version = "3.11.1+1";
|
||||
src = fetchFromGitHub {
|
||||
owner = "gpodder";
|
||||
repo = "gpodder";
|
||||
rev = "adaptive/${version}";
|
||||
hash = "sha256-pn5sh8CLV2Civ26PL3rrkkUdoobu7SIHXmWKCZucBhw=";
|
||||
};
|
||||
|
||||
buildInputs = upstream.buildInputs ++ [
|
||||
libhandy
|
||||
];
|
||||
})
|
@@ -31,8 +31,8 @@ in
|
||||
# repeat imports are deduplicated by url, even when offline.
|
||||
postBuild = ''
|
||||
makeWrapper $out/bin/gpodder $out/bin/gpodder-configured \
|
||||
--run "$out/bin/gpodder-remove-extra ~/.config/gpodderFeeds.opml" \
|
||||
--run "$out/bin/gpo import ~/.config/gpodderFeeds.opml" \
|
||||
--run "$out/bin/gpodder-remove-extra ~/.config/gpodderFeeds.opml || true" \
|
||||
--run "$out/bin/gpo import ~/.config/gpodderFeeds.opml || true" \
|
||||
|
||||
# fix up the .desktop file to invoke our wrapped application
|
||||
orig_desktop=$(readlink $out/share/applications/gpodder.desktop)
|
||||
|
@@ -0,0 +1,24 @@
|
||||
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
|
||||
index bcebe43..a15b0ef 100644
|
||||
--- a/src/CMakeLists.txt
|
||||
+++ b/src/CMakeLists.txt
|
||||
@@ -107,8 +107,8 @@ endif()
|
||||
set(RESOURCE_ROOT .)
|
||||
if(APPLE)
|
||||
set(RESOURCE_ROOT Resources)
|
||||
- add_resources(TARGET ${MAIN_TARGET} SOURCES ${CMAKE_CURRENT_BINARY_DIR}/../dist/ DEST ${RESOURCE_ROOT}/web-client/desktop)
|
||||
- add_resources(TARGET ${MAIN_TARGET} SOURCES ${CMAKE_SOURCE_DIR}/native/ DEST ${RESOURCE_ROOT}/web-client/extension)
|
||||
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../../jellyfin-web/ DESTINATION ${RESOURCE_ROOT}/web-client/desktop)
|
||||
+ install(DIRECTORY ${CMAKE_SOURCE_DIR}/native/ DESTINATION ${RESOURCE_ROOT}/web-client/extension)
|
||||
endif()
|
||||
|
||||
if(NOT APPLE)
|
||||
@@ -121,7 +121,7 @@ if(NOT APPLE)
|
||||
install(FILES ${loc}/qtwebengine_devtools_resources.pak DESTINATION resources)
|
||||
endif()
|
||||
endforeach()
|
||||
- install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../dist/ DESTINATION ${INSTALL_RESOURCE_DIR}/web-client/desktop)
|
||||
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../../jellyfin-web/ DESTINATION ${INSTALL_RESOURCE_DIR}/web-client/desktop)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/native/ DESTINATION ${INSTALL_RESOURCE_DIR}/web-client/extension)
|
||||
endif()
|
||||
|
@@ -0,0 +1,13 @@
|
||||
diff --git a/src/input/InputComponent.cpp b/src/input/InputComponent.cpp
|
||||
index 0f5f129..94596b6 100644
|
||||
--- a/src/input/InputComponent.cpp
|
||||
+++ b/src/input/InputComponent.cpp
|
||||
@@ -132,7 +132,7 @@ void InputComponent::handleAction(const QString& action)
|
||||
else
|
||||
{
|
||||
qDebug() << "Invoking slot" << qPrintable(recvSlot->m_slot.data());
|
||||
- QGenericArgument arg0 = QGenericArgument();
|
||||
+ QMetaMethodArgument arg0;
|
||||
|
||||
if (recvSlot->m_hasArguments)
|
||||
arg0 = Q_ARG(const QString&, hostArguments);
|
@@ -0,0 +1,14 @@
|
||||
diff --git a/CMakeModules/QtConfiguration.cmake b/CMakeModules/QtConfiguration.cmake
|
||||
index d74a484..fb678ad 100644
|
||||
--- a/CMakeModules/QtConfiguration.cmake
|
||||
+++ b/CMakeModules/QtConfiguration.cmake
|
||||
@@ -53,8 +53,7 @@ foreach(COMP ${components})
|
||||
find_package(Qt6 REQUIRED COMPONENTS Gui)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Quick)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Widgets)
|
||||
- find_package(Qt6 REQUIRED COMPONENTS WebEngineQuick)
|
||||
- find_package(Qt6 REQUIRED COMPONENTS WebEngineCore)
|
||||
+ find_package(Qt6 REQUIRED COMPONENTS WebEngine)
|
||||
find_package(Qt6 REQUIRED COMPONENTS OpenGL)
|
||||
find_package(Qt6 REQUIRED COMPONENTS DBus)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user