Compare commits

..

2 Commits

Author SHA1 Message Date
20bdad9132 add missing dns.nix module 2023-06-07 23:36:15 +00:00
7aaab9eb30 WIP: DNS: split the zone generation out of trust-dns
this is in preparation for upstreaming parts of this into nixpkgs
2023-06-07 23:34:00 +00:00
285 changed files with 4367 additions and 22796 deletions

View File

@@ -16,8 +16,6 @@ directly here; even the sources for those packages is often kept here too.
[uninsane-org]: https://uninsane.org
## Layout
- `doc/`
- instructions for tasks i find myself doing semi-occasionally in this repo.
- `hosts/`
- the bulk of config which isn't factored with external use in mind.
- that is, if you were to add this repo to a flake.nix for your own use,
@@ -39,7 +37,9 @@ directly here; even the sources for those packages is often kept here too.
- inline code for wholly custom packages (e.g. `pkgs/additional/sane-scripts/` for CLI tools
that are highly specific to my setup).
- `scripts/`
- scripts which aren't reachable on a deployed system, but may aid manual deployments
- scripts which are referenced by other things in this repo.
- these aren't generally user-facing, but they're factored out so that they can
be invoked directly when i need to debug.
- `secrets/`
- encrypted keys, API tokens, anything which one or more of my machines needs
read access to but shouldn't be world-readable.
@@ -106,6 +106,3 @@ this repo exists in a few known locations:
if you want to contact me for questions, or collaborate to split something useful into a shared repo, etc,
you can reach me via any method listed [here](https://uninsane.org/about).
patches, for this repo or any other i host, will be warmly welcomed in any manner you see fit:
`git send-email`, DM'ing the patch over Matrix/Lemmy/ActivityPub/etc, even a literal PR where you
link me to your own clone.

56
TODO.md
View File

@@ -1,10 +1,8 @@
## BUGS
- why i need to manually restart `wireguard-wg-ovpns` on servo periodically
- else DNS fails
- fix epiphany URL bar input on moby
- else DNS fails
## REFACTORING:
### sops/secrets
- attach secrets to the thing they're used by (sane.programs)
- rework secrets to leverage `sane.fs`
@@ -15,13 +13,13 @@
- will make it easier to test new services?
### upstreaming
- split out a sxmo module usable by NUR consumers
- 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
- REVIEW/integrate jellyfin dataDir config: <https://github.com/NixOS/nixpkgs/pull/233617>
- remove `libsForQt5.callPackage` broadly: <https://github.com/NixOS/nixpkgs/issues/180841>
- fix or abandon Whalebird
## IMPROVEMENTS:
@@ -32,50 +30,46 @@
- have `sane.programs` be wrapped such that they run in a cgroup?
- at least, only give them access to the portion of the fs they *need*.
- Android takes approach of giving each app its own user: could hack that in here.
- **systemd-run** takes a command and runs it in a temporary scope (cgroup)
- presumably uses the same options as systemd services
- see e.g. <https://github.com/NixOS/nixpkgs/issues/113903#issuecomment-857296349>
- flatpak does this, somehow
- apparmor? SElinux? (desktop) "portals"?
- see Spectrum OS; Alyssa Ross; etc
- bubblewrap-based sandboxing: <https://github.com/nixpak/nixpak>
- canaries for important services
- e.g. daily email checks; daily backup checks
- integrate `nix check` into Gitea actions?
### user experience
- neovim: set up language server (lsp; rnix-lsp; nvim-lspconfig)
- Helix: make copy-to-system clipboard be the default
- firefox/librewolf: persist history
- just not cookies or tabs
- firefox/librewolf: don't show browserpass/sponsorblock/metamask "first run" on every boot
- moby: improve gPodder launch time
- moby: theme GTK apps (i.e. non-adwaita styles)
- especially, make the menubar collapsible
- try Gradience tool specifically for theming adwaita? <https://linuxphoneapps.org/apps/com.github.gradienceteam.gradience/>
- moby: replace jellyfin-desktop with jellyfin-vue?
- allows (maybe) to cache media for offline use
- "newer" jellyfin client
- not packaged for nix
- find a nice desktop ActivityPub client
- package Nix/NixOS docs for Zeal
- install [doc-browser](https://github.com/qwfy/doc-browser)
- this supports both dash (zeal) *and* the datasets from <https://devdocs.io> (which includes nix!)
- install [devhelp](https://wiki.gnome.org/Apps/Devhelp) (gnome)
- auto-mount servo
- have xdg-open parse `<repo:...> URIs (or adjust them so that it _can_ parse)
- sane-bt-search: show details like 5.1 vs stereo, h264 vs h265
- uninsane.org: make URLs relative to allow local use (and as offline homepage)
- email: fix so that local mail doesn't go to junk
- git sendmail flow adds the DKIM signatures, but gets delivered locally w/o having the sig checked, so goes into Junk
- could change junk filter from "no DKIM success" to explicit "DKIM failed"
- `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
### perf
- add `pkgs.impure-cached.<foo>` package set to build things with ccache enabled
- every package here can be auto-generated, and marked with some env var so that it doesn't pollute the pure package set
- would be super handy for package prototyping!
- why does nixos-rebuild switch take 5 minutes when net is flakey?
- trying to auto-mount servo?
- something to do with systemd services restarting/stalling
- maybe wireguard & its refresh operation, specifically?
- get moby to build without binfmt emulation (i.e. make all emulation explicit)
- then i can distribute builds across servo + desko, and also allow servo to pull packages from desko w/o worrying about purity
- fix OOM for large builds like webkitgtk
- these use significant /tmp space.
- either place /tmp on encrypted-cleared-at-boot storage
- which probably causes each CPU load for the encryption
- **or set up encrypted swap**
- encrypted swap could remove the need for my encrypted-cleared-at-boot stuff
## NEW FEATURES:
- add a FTP-accessible file share to servo
- just /var/www?
- migrate MAME cabinet to nix
- boot it from PXE from servo?
- enable IPv6

View File

@@ -1,13 +0,0 @@
to ship `pkgs.foo` on some host, either:
- add it as an entry in `suggestedPrograms` to the appropriate category in `hosts/common/programs/assorted.nix`, or
- `sane.programs.foo.enableFor.user.colin = true` in `hosts/by-name/myhost/default.nix`
if the program needs customization (persistence, configs, secrets):
- add a file for it at `hosts/common/programs/<foo>.nix`
- set the options, `sane.programs.foo.{fs,persist}`
if it's unclear what fs paths a program uses:
- run one of these commands, launch the program, run it again, and `diff`:
- `du -x --apparent-size ~`
- `find ~ -xdev`
- or, inspect the whole tmpfs root with `ncdu -x /`

64
flake.lock generated
View File

@@ -1,15 +1,12 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1687709756,
"narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=",
"lastModified": 1678901627,
"narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7",
"rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6",
"type": "github"
},
"original": {
@@ -21,11 +18,11 @@
"mobile-nixos": {
"flake": false,
"locked": {
"lastModified": 1690059310,
"narHash": "sha256-4zcoDp8wwZVfGSzXltC5x+eH4kDWC/eJpyQNgr7shAA=",
"lastModified": 1683422260,
"narHash": "sha256-79zaClbubRkBNlJ04OSADILuLQHH48N5fu296hEWYlw=",
"owner": "nixos",
"repo": "mobile-nixos",
"rev": "56fc9f9619f305f0865354975a98d22410eed127",
"rev": "ba4638836e94a8f16d1d1f9e8c0530b86078029c",
"type": "github"
},
"original": {
@@ -39,11 +36,11 @@
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1687251388,
"narHash": "sha256-E9cVlgeCvzPbA/G3mCDCzz8TdRwXyGYzIjmwcvIfghg=",
"lastModified": 1684319086,
"narHash": "sha256-5wwlkWqP1cQUPXp/PJsi09FkgAule5yBghngRZZbUQg=",
"owner": "edolstra",
"repo": "nix-serve",
"rev": "d6df5bd8584f37e22cff627db2fc4058a4aab5ee",
"rev": "e6e3d09438e803daa5374ad8edf1271289348456",
"type": "github"
},
"original": {
@@ -69,27 +66,27 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1690066826,
"narHash": "sha256-6L2qb+Zc0BFkh72OS9uuX637gniOjzU6qCDBpjB2LGY=",
"lastModified": 1684632198,
"narHash": "sha256-SdxMPd0WmU9MnDBuuy7ouR++GftrThmSGL7PCQj/uVI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ce45b591975d070044ca24e3003c830d26fea1c8",
"rev": "d0dade110dc7072d67ce27826cfe9ab2ab0cf247",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "release-23.05",
"ref": "release-22.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unpatched": {
"locked": {
"lastModified": 1691006197,
"narHash": "sha256-DbtxVWPt+ZP5W0Usg7jAyTomIM//c3Jtfa59Ht7AV8s=",
"lastModified": 1684935479,
"narHash": "sha256-6QMMsXMr2nhmOPHdti2j3KRHt+bai2zw+LJfdCl97Mk=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "66aedfd010204949cb225cf749be08cb13ce1813",
"rev": "f91ee3065de91a3531329a674a45ddcb3467a650",
"type": "github"
},
"original": {
@@ -116,11 +113,11 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1690199016,
"narHash": "sha256-yTLL72q6aqGmzHq+C3rDp3rIjno7EJZkFLof6Ika7cE=",
"lastModified": 1684637723,
"narHash": "sha256-0vAxL7MVMhGbTkAyvzLvleELHjVsaS43p+PR1h9gzNQ=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "c36df4fe4bf4bb87759b1891cab21e7a05219500",
"rev": "4ccdfb573f323a108a44c13bb7730e42baf962a9",
"type": "github"
},
"original": {
@@ -129,21 +126,6 @@
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"uninsane-dot-org": {
"inputs": {
"flake-utils": "flake-utils",
@@ -152,11 +134,11 @@
]
},
"locked": {
"lastModified": 1691106178,
"narHash": "sha256-3mZ9gTvMpbZA9ea9ovoQpn2wKuQY0QZ7MDdEjArYdAQ=",
"lastModified": 1684528780,
"narHash": "sha256-QdYxjcTCCLPv++1v9tJBL98nn/AFx0fmzlgzcLK6KRE=",
"ref": "refs/heads/master",
"rev": "f4d91aa201b6e49af690f250d4786bd1d8b4dcfd",
"revCount": 205,
"rev": "f3747a1dad3d34880613821faf26357ba432d3d7",
"revCount": 194,
"type": "git",
"url": "https://git.uninsane.org/colin/uninsane"
},

View File

@@ -23,6 +23,9 @@
# preferably, i would rewrite the human-readable https URLs to nix-specific github: URLs with a helper,
# but `inputs` is required to be a strict attrset: not an expression.
inputs = {
# <https://github.com/nixos/nixpkgs/tree/nixos-22.11>
# nixpkgs-stable.url = "github:nixos/nixpkgs?ref=nixos-22.11";
# branch workflow:
# - daily:
# - nixos-unstable cut from master after enough packages have been built in caches.
@@ -94,17 +97,7 @@
evalHost = { name, local, target }: nixpkgs.lib.nixosSystem {
system = target;
modules = [
{
nixpkgs = (if (local != null) then {
buildPlatform = local;
} else {}) // {
# TODO: does the earlier `system` arg to nixosSystem make its way here?
hostPlatform.system = target;
};
# nixpkgs.buildPlatform = local; # set by instantiate.nix instead
# nixpkgs.config.replaceStdenv = { pkgs }: pkgs.ccacheStdenv;
}
(import ./hosts/instantiate.nix { hostName = name; })
(import ./hosts/instantiate.nix { localSystem = local; hostName = name; })
self.nixosModules.default
self.nixosModules.passthru
{
@@ -113,6 +106,12 @@
self.overlays.sane-all
];
}
({ lib, ... }: {
# TODO: does the earlier `system` arg to nixosSystem make its way here?
nixpkgs.hostPlatform.system = target;
# nixpkgs.buildPlatform = local; # set by instantiate.nix instead
# nixpkgs.config.replaceStdenv = { pkgs }: pkgs.ccacheStdenv;
})
];
};
in {
@@ -178,10 +177,15 @@
disable-flakey-tests = final: prev: import ./overlays/disable-flakey-tests.nix final prev;
pkgs = final: prev: import ./overlays/pkgs.nix final prev;
pins = final: prev: import ./overlays/pins.nix final prev;
preferences = final: prev: import ./overlays/preferences.nix final prev;
optimizations = final: prev: import ./overlays/optimizations.nix final prev;
passthru = final: prev:
let
stable =
if inputs ? "nixpkgs-stable" then (
final': prev': {
stable = inputs.nixpkgs-stable.legacyPackages."${prev'.stdenv.hostPlatform.system}";
}
) else (final': prev': {});
mobile = (import "${mobile-nixos}/overlay/overlay.nix");
uninsane = uninsane-dot-org.overlay;
# nix-serve' = nix-serve.overlay;
@@ -192,10 +196,11 @@
inherit (nix-serve.packages."${next.system}") nix-serve;
};
in
(mobile final prev)
// (uninsane final prev)
// (nix-serve' final prev)
;
(stable final prev)
// (mobile final prev)
// (uninsane final prev)
// (nix-serve' final prev)
;
};
nixosModules = rec {
@@ -244,74 +249,32 @@
apps."x86_64-linux" =
let
pkgs = self.legacyPackages."x86_64-linux";
deployScript = host: addr: action: pkgs.writeShellScript "deploy-${host}" ''
nix build '.#nixosConfigurations.${host}.config.system.build.toplevel' --out-link ./result-${host} $@
sudo nix sign-paths -r -k /run/secrets/nix_serve_privkey $(readlink ./result-${host})
# XXX: this triggers another config eval & (potentially) build.
# if the config changed between these invocations, the above signatures might not apply to the deployed config.
# let the user handle that edge case by re-running this whole command
nixos-rebuild --flake '.#${host}' ${action} --target-host colin@${addr} --use-remote-sudo $@
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 $@
'';
in {
help = {
type = "app";
program = let
helpMsg = builtins.toFile "nixos-config-help-message" ''
commands:
- `nix run '.#help'`
- show this message
- `nix run '.#update-feeds'`
- updates metadata for all feeds
- `nix run '.#init-feed' <url>`
- `nix run '.#deploy-{lappy,moby,moby-test,servo}' [nixos-rebuild args ...]`
- `nix run '.#check-nur'`
'';
in builtins.toString (pkgs.writeShellScript "nixos-config-help" ''
cat ${helpMsg}
'');
};
update-feeds = {
type = "app";
program = "${pkgs.feeds.updateScript}";
};
init-feed = {
# use like `nix run '.#init-feed' uninsane.org`
type = "app";
program = "${pkgs.feeds.initFeedScript}";
};
deploy-lappy = {
type = "app";
program = ''${deployScript "lappy" "lappy" "switch"}'';
};
deploy-moby-test = {
# `nix run '.#deploy-moby-test'`
type = "app";
program = ''${deployScript "moby" "moby-hn" "test"}'';
program = ''${deployScript "test"}'';
};
deploy-moby = {
# `nix run '.#deploy-moby-switch'`
type = "app";
program = ''${deployScript "moby" "moby-hn" "switch"}'';
};
deploy-servo = {
type = "app";
program = ''${deployScript "servo" "servo" "switch"}'';
};
check-nur = {
# `nix run '.#check-nur'`
# validates that my repo can be included in the Nix User Repository
type = "app";
program = builtins.toString (pkgs.writeShellScript "check-nur" ''
cd ${./.}/integrations/nur
NIX_PATH= NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM=1 nix-env -f . -qa \* --meta --xml \
--allowed-uris https://static.rust-lang.org \
--option restrict-eval true \
--option allow-import-from-derivation true \
--drv-path --show-trace \
-I nixpkgs=$(nix-instantiate --find-file nixpkgs) \
-I ../../
'');
program = ''${deployScript "switch"}'';
};
};

View File

@@ -4,11 +4,6 @@
./fs.nix
];
# sane.guest.enable = true;
# services.distccd.enable = true;
# sane.programs.distcc.enableFor.user.guest = true;
sops.secrets.colin-passwd.neededForUsers = true;
sane.roles.build-machine.enable = true;
@@ -22,11 +17,8 @@
sane.gui.sway.enable = true;
sane.programs.iphoneUtils.enableFor.user.colin = true;
sane.programs.steam.enableFor.user.colin = true;
sane.programs.guiApps.suggestedPrograms = [ "desktopGuiApps" ];
sane.programs.consoleUtils.suggestedPrograms = [ "consoleMediaUtils" "desktopConsoleUtils" ];
# sane.programs.devPkgs.enableFor.user.colin = true;
boot.loader.efi.canTouchEfiVariables = false;
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
@@ -36,7 +28,6 @@
# don't enable wifi by default: it messes with connectivity.
systemd.services.iwd.enable = false;
systemd.services.wpa_supplicant.enable = false;
# default config: https://man.archlinux.org/man/snapper-configs.5
# defaults to something like:
@@ -50,6 +41,17 @@
ALLOW_USERS = [ "colin" ];
};
programs.steam = {
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
};
sane.user.persist.plaintext = [
".steam"
".local/share/Steam"
];
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
system.stateVersion = "21.05";
}

View File

@@ -2,10 +2,17 @@
{
sane.persist.root-on-tmpfs = true;
# increase /tmp space (defaults to 50% of RAM) for building large nix things.
# we need a /tmp for building large nix things.
# a cross-compiled kernel, particularly, will easily use 30+GB of tmp
fileSystems."/tmp".options = [ "size=64G" ];
fileSystems."/tmp" = {
device = "none";
fsType = "tmpfs";
options = [
"mode=777"
"size=64G"
"defaults"
];
};
fileSystems."/nix" = {
# device = "/dev/disk/by-uuid/985a0a32-da52-4043-9df7-615adec2e4ff";
device = "/dev/disk/by-uuid/0ab0770b-7734-4167-88d9-6e4e20bb2a56";

View File

@@ -19,7 +19,6 @@
"desktopGuiApps"
"stepmania"
];
sane.programs.consoleUtils.suggestedPrograms = [ "consoleMediaUtils" "desktopConsoleUtils" ];
sops.secrets.colin-passwd.neededForUsers = true;
@@ -34,6 +33,9 @@
ALLOW_USERS = [ "colin" ];
};
# TODO: only here for debugging
# services.ipfs.enable = true;
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
system.stateVersion = "21.05";
}

View File

@@ -2,6 +2,15 @@
{
sane.persist.root-on-tmpfs = true;
# we need a /tmp of default size (half RAM) for building large nix things
fileSystems."/tmp" = {
device = "none";
fsType = "tmpfs";
options = [
"mode=777"
"defaults"
];
};
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/75230e56-2c69-4e41-b03e-68475f119980";

View File

@@ -1,6 +1,6 @@
# doesn't actually *enable* anything,
# but sets up any modules such that if they *were* enabled, they'll act as expected.
{ pkgs, ... }:
{ ... }:
{
sane.gui.sxmo = {
greeter = "sway";
@@ -28,11 +28,5 @@
# see <repo:mil/sxmo-utils:scripts/deviceprofiles>
# SXMO_DEVICE_NAME = "pine64,pinephone-1.2";
};
package = pkgs.sxmo-utils.overrideAttrs (base: {
postPatch = (base.postPatch or "") + ''
# after volume-button navigation mode, restore full keyboard functionality
cp ${./xkb_mobile_normal_buttons} ./configs/xkb/xkb_mobile_normal_buttons
'';
});
};
}

View File

@@ -1,26 +1,13 @@
# Pinephone
# other setups to reference:
# - <https://hamblingreen.gitlab.io/2022/03/02/my-pinephone-setup.html>
# - sxmo Arch user. lots of app recommendations
#
# wikis, resources, ...:
# - Linux Phone Apps: <https://linuxphoneapps.org/>
# - massive mobile-friendly app database
# - Mobian wiki: <https://wiki.mobian-project.org/doku.php?id=start>
# - recommended apps, chatrooms
{ config, pkgs, lib, ... }:
{
imports = [
./bootloader.nix
./firmware.nix
./fs.nix
./gps.nix
./kernel.nix
./polyfill.nix
];
sane.roles.client = true;
sane.zsh.showDeadlines = false; # unlikely to act on them when in shell
sane.services.wg-home.enable = true;
sane.services.wg-home.ip = config.sane.hosts.by-name."moby".wg-home.ip;
@@ -31,31 +18,31 @@
sops.secrets.colin-passwd.neededForUsers = true;
sane.programs.web-browser.config = {
# compromise impermanence for the sake of usability
persistCache = "private";
persistData = "private";
# i don't do crypto stuff on moby
addons.ether-metamask.enable = false;
# addons.sideberry.enable = false;
};
sane.user.persist.plaintext = [
# TODO: make this just generally conditional upon pulse being enabled?
".config/pulse" # persist pulseaudio volume
];
sane.gui.sxmo.enable = true;
sane.programs.guiApps.suggestedPrograms = [ "handheldGuiApps" ];
sane.gui.phosh.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
sane.programs.soundconverter.enableFor.user.colin = false;
# sane.programs.firefox.mime.priority = 300; # prefer other browsers when possible
# HACK/TODO: make `programs.P.env.VAR` behave according to `mime.priority`
# sane.programs.firefox.env = lib.mkForce {};
# sane.programs.epiphany.env.BROWSER = "epiphany";
# sane.programs.firefox.enableFor.user.colin = false; # use epiphany instead
# sane.programs.mpv.enableFor.user.colin = true;
boot.loader.efi.canTouchEfiVariables = false;
# /boot space is at a premium. default was 20.
# even 10 can be too much
# TODO: compress moby kernels!
boot.loader.generic-extlinux-compatible.configurationLimit = 8;
# mobile.bootloader.enable = false;
# mobile.boot.stage-1.enable = false;
@@ -114,50 +101,6 @@
services.wireplumber.environment.ALSA_CONFIG_UCM2 = ucm-env;
};
services.udev.extraRules = let
chmod = "${pkgs.coreutils}/bin/chmod";
chown = "${pkgs.coreutils}/bin/chown";
in ''
# make Pinephone flashlight writable by user.
# taken from postmarketOS: <repo:postmarketOS/pmaports:device/main/device-pine64-pinephone/60-flashlight.rules>
SUBSYSTEM=="leds", DEVPATH=="*/*:flash", RUN+="${chmod} g+w /sys%p/brightness /sys%p/flash_strobe", RUN+="${chown} :video /sys%p/brightness /sys%p/flash_strobe"
# make Pinephone front LEDs writable by user.
SUBSYSTEM=="leds", DEVPATH=="*/*:indicator", RUN+="${chmod} g+w /sys%p/brightness", RUN+="${chown} :video /sys%p/brightness"
'';
hardware.opengl.driSupport = true;
services.xserver.displayManager.job.preStart = let
dmesg = "${pkgs.util-linux}/bin/dmesg";
grep = "${pkgs.gnugrep}/bin/grep";
modprobe = "${pkgs.kmod}/bin/modprobe";
in ''
# common boot failure:
# blank screen (no backlight even), with the following log:
# ```syslog
# sun8i-dw-hdmi 1ee0000.hdmi: Couldn't get the HDMI PHY
# ...
# sun4i-drm display-engine: Couldn't bind all pipelines components
# ...
# sun8i-dw-hdmi: probe of 1ee0000.hdmi failed with error -17
# ```
#
# in particular, that `probe ... failed` occurs *only* on failed boots
# (the other messages might sometimes occur even on successful runs?)
#
# reloading the sun8i hdmi driver usually gets the screen on, showing boot text.
# then restarting display-manager.service gets us to the login.
#
# NB: the above log is default level. though less specific, there's a `err` level message that also signals this:
# sun4i-drm display-engine: failed to bind 1ee0000.hdmi (ops sun8i_dw_hdmi_ops [sun8i_drm_hdmi]): -17
if (${dmesg} --kernel --level err --color=never --notime | ${grep} -q 'sun4i-drm display-engine: failed to bind 1ee0000.hdmi')
then
echo "reprobing sun8i_drm_hdmi"
# if a command here fails it errors the whole service, so prefer to log instead
${modprobe} -r sun8i_drm_hdmi || echo "failed to unload sun8i_drm_hdmi"
${modprobe} sun8i_drm_hdmi || echo "failed to load sub8i_drm_hdmi"
fi
'';
}

View File

@@ -1,24 +0,0 @@
# pinephone GPS happens in EG25 modem
# serial control interface to modem is /dev/ttyUSB2
# after enabling GPS, readout is /dev/ttyUSB1
#
# minimal process to enable modem and GPS:
# - `echo 1 > /sys/class/modem-power/modem-power/device/powered`
# - `screen /dev/ttyUSB2 115200`
# - `AT+QGPSCFG="nmeasrc",1`
# - `AT+QGPS=1`
#
# now, something like `gpsd` can directly read from /dev/ttyUSB1.
#
# initial GPS fix can take 15+ minutes.
# meanwhile, services like eg25-manager can speed this up by uploading assisted GPS data to the modem.
#
# geoclue somehow fits in here as a geospatial provider that leverages GPS and also other sources like radio towers
{ ... }:
{
services.gpsd.enable = true;
services.gpsd.devices = [ "/dev/ttyUSB1" ];
# TODO: enable eg25-manager, and bring online both the modem and GPS on boot
}

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 118 KiB

View File

@@ -1,179 +1,23 @@
# this file configures preferences per program, without actually enabling any programs.
# the goal is to separate the place where we decide *what* to use (i.e. `sane.programs.firefox.enable = true` -- at the toplevel)
# from where we specific how that thing should behave *if* it's in use.
#
# NixOS backgrounds:
# - <https://github.com/NixOS/nixos-artwork>
# - <https://github.com/NixOS/nixos-artwork/issues/50> (colorful; unmerged)
# - <https://github.com/NixOS/nixos-artwork/pull/60/files> (desktop-oriented; clean; unmerged)
# - <https://itsfoss.com/content/images/2023/04/nixos-tutorials.png>
{ lib, pkgs, sane-lib, ... }:
let
# TODO: generate this from the .svg
# bg = ./nixos-bg-02.png;
bg = pkgs.runCommand "nixos-bg.png" { nativeBuildInputs = [ pkgs.inkscape ]; } ''
inkscape ${./nixos-bg-02.svg} -o $out
'';
in
{ sane-lib, ... }:
{
sane.programs.firefox.config = {
# compromise impermanence for the sake of usability
persistCache = "private";
persistData = "private";
# i don't do crypto stuff on moby
addons.ether-metamask.enable = false;
# sidebery UX doesn't make sense on small screen
addons.sidebery.enable = false;
};
sane.gui.sxmo = {
nogesture = true;
settings = {
### hardware: touch screen
# touch screen
SXMO_LISGD_INPUT_DEVICE = "/dev/input/by-path/platform-1c2ac00.i2c-event";
# vol and power are detected correctly by upstream
### preferences
# notable bemenu options:
# - see `bemenu --help` for all
# -P, --prefix text to show before highlighted item.
# --scrollbar display scrollbar. (none (default), always, autohide)
# -H, --line-height defines the height to make each menu line (0 = default height). (wx)
# -M, --margin defines the empty space on either side of the menu. (wx)
# -W, --width-factor defines the relative width factor of the menu (from 0 to 1). (wx)
# -B, --border defines the width of the border in pixels around the menu. (wx)
# -R --border-radius defines the radius of the border around the menu (0 = no curved borders).
# --ch defines the height of the cursor (0 = scales with line height). (wx)
# --cw defines the width of the cursor. (wx)
# --hp defines the horizontal padding for the entries in single line mode. (wx)
# --fn defines the font to be used ('name [size]'). (wx)
# --tb defines the title background color. (wx)
# --tf defines the title foreground color. (wx)
# --fb defines the filter background color. (wx)
# --ff defines the filter foreground color. (wx)
# --nb defines the normal background color. (wx)
# --nf defines the normal foreground color. (wx)
# --hb defines the highlighted background color. (wx)
# --hf defines the highlighted foreground color. (wx)
# --fbb defines the feedback background color. (wx)
# --fbf defines the feedback foreground color. (wx)
# --sb defines the selected background color. (wx)
# --sf defines the selected foreground color. (wx)
# --ab defines the alternating background color. (wx)
# --af defines the alternating foreground color. (wx)
# --scb defines the scrollbar background color. (wx)
# --scf defines the scrollbar foreground color. (wx)
# --bdr defines the border color. (wx)
#
# colors are specified as `#RRGGBB`
# defaults:
# --ab "#222222"
# --af "#bbbbbb"
# --bdr "#005577"
# --border 3
# --cb "#222222"
# --center
# --cf "#bbbbbb"
# --fb "#222222"
# --fbb "#eeeeee"
# --fbf "#222222"
# --ff "#bbbbbb"
# --fixed-height
# --fn 'Sxmo 14'
# --hb "#005577"
# --hf "#eeeeee"
# --line-height 20
# --list 16
# --margin 40
# --nb "#222222"
# --nf "#bbbbbb"
# --no-overlap
# --no-spacing
# --sb "#323232"
# --scb "#005577"
# --scf "#eeeeee"
# --scrollbar autohide
# --tb "#005577"
# --tf "#eeeeee"
# --wrap
BEMENU_OPTS = let
bg = "#1d1721"; # slight purple
fg0 = "#d8d8d8"; # inactive text (light grey)
fg1 = "#ffffff"; # active text (white)
accent0 = "#1f5e54"; # darker but saturated teal
accent1 = "#418379"; # teal (matches nixos-bg)
accent2 = "#5b938a"; # brighter but muted teal
in lib.concatStringsSep " " [
"--wrap --scrollbar autohide --fixed-height"
"--center --margin 45"
"--no-spacing"
# XXX: font size doesn't seem to take effect (would prefer larger)
"--fn 'Sxmo 14' --line-height 22 --border 3"
"--bdr '${accent0}'" # border
"--scf '${accent2}' --scb '${accent0}'" # scrollbar
"--tb '${accent0}' --tf '${fg0}'" # title
"--fb '${accent0}' --ff '${fg1}'" # filter (i.e. text that's been entered)
"--hb '${accent1}' --hf '${fg1}'" # selected item
"--nb '${bg}' --nf '${fg0}'" # normal lines (even)
"--ab '${bg}' --af '${fg0}'" # alternated lines (odd)
"--cf '${accent0}' --cb '${accent0}'" # cursor (not very useful)
];
DEFAULT_COUNTRY = "US";
# BEMENU lines (wayland DMENU):
# - camera is 9th entry
# - flashlight is 10th entry
# - config is 14th entry. inside that:
# - autorotate is 11th entry
# - system menu is 19th entry
# - close is 20th entry
# - power is 15th entry
# - close is 16th entry
SXMO_BEMENU_LANDSCAPE_LINES = "11"; # default 8
SXMO_BEMENU_PORTRAIT_LINES = "16"; # default 16
SXMO_BG_IMG = "${bg}";
SXMO_LOCK_IDLE_TIME = "15"; # how long between screenoff -> lock -> back to screenoff (default: 8)
# gravity: how far to tilt the device before the screen rotates
# for a given setting, normal <-> invert requires more movement then left <-> right
# i.e. the settingd doesn't feel completely symmetric
# SXMO_ROTATION_GRAVITY default is 16374
# SXMO_ROTATION_GRAVITY = "12800"; # uncomfortably high
# SXMO_ROTATION_GRAVITY = "12500"; # kinda uncomfortable when walking
SXMO_ROTATION_GRAVITY = "12000";
SXMO_SCREENSHOT_DIR = "/home/colin/Pictures"; # default: "$HOME"
# test new scales by running `swaymsg -- output DSI-1 scale x.y`
# SXMO_SWAY_SCALE = "1.5"; # hard to press gPodder icons
SXMO_SWAY_SCALE = "1.8";
# SXMO_SWAY_SCALE = "2";
SXMO_WORKSPACE_WRAPPING = "5"; # how many workspaces. default: 4
# wvkbd layers:
# - full
# - landscape
# - special (e.g. coding symbols like ~)
# - emoji
# - nav
# - simple (like landscape, but no parens/tab/etc; even fewer chars)
# - simplegrid (simple, but grid layout)
# - dialer (digits)
# - cyrillic
# - arabic
# - persian
# - greek
# - georgian
WVKBD_LANDSCAPE_LAYERS = "landscape,special,emoji";
WVKBD_LAYERS = "full,special,emoji";
};
package = pkgs.sxmo-utils.overrideAttrs (base: {
postPatch = (base.postPatch or "") + ''
cat <<EOF >> ./configs/default_hooks/sxmo_hook_start.sh
# rotate UI based on physical display angle by default
sxmo_daemons.sh start autorotate sxmo_autorotate.sh
EOF
'';
});
};
# 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)"
'';
}

View File

@@ -18,16 +18,10 @@
sane.roles.build-machine.enable = true;
sane.roles.build-machine.emulation = false;
sane.zsh.showDeadlines = false; # ~/knowledge doesn't always exist
sane.programs.consoleUtils.suggestedPrograms = [
"desktopConsoleUtils"
"sane-scripts.stop-all-servo"
];
sane.services.dyn-dns.enable = true;
sane.services.wg-home.enable = true;
sane.services.wg-home.enableWan = true;
sane.services.wg-home.ip = config.sane.hosts.by-name."servo".wg-home.ip;
sane.nixcache.substituters.servo = false;
sane.nixcache.substituters.desko = false;
# sane.services.duplicity.enable = true; # TODO: re-enable after HW upgrade
# automatically log in at the virtual consoles.

View File

@@ -2,6 +2,15 @@
{
sane.persist.root-on-tmpfs = true;
# we need a /tmp for building large nix things
fileSystems."/tmp" = {
device = "none";
fsType = "tmpfs";
options = [
"mode=777"
"defaults"
];
};
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/cc81cca0-3cc7-4d82-a00c-6243af3e7776";
@@ -35,7 +44,7 @@
sane.persist.sys.plaintext = [
# TODO: this is overly broad; only need media and share directories to be persisted
{ user = "colin"; group = "users"; path = "/var/lib/uninsane"; }
{ user = "colin"; group = "users"; directory = "/var/lib/uninsane"; }
];
# make sure large media is stored to the HDD
sane.persist.sys.ext = [
@@ -43,22 +52,21 @@
user = "colin";
group = "users";
mode = "0777";
path = "/var/lib/uninsane/media/Videos";
directory = "/var/lib/uninsane/media/Videos";
}
{
user = "colin";
group = "users";
mode = "0777";
path = "/var/lib/uninsane/media/freeleech";
}
{
user = "colin";
group = "users";
mode = "0777";
path = "/var/lib/uninsane/media/datasets";
directory = "/var/lib/uninsane/media/freeleech";
}
];
# in-memory compressed RAM (seems to be dynamically sized)
# zramSwap = {
# enable = true;
# };
# btrfs doesn't easily support swapfiles
# swapDevices = [
# { device = "/nix/persist/swapfile"; size = 4096; }

View File

@@ -13,7 +13,7 @@ in
lib.mkIf false
{
sane.persist.sys.plaintext = [
{ inherit user group; mode = "0700"; path = svc-dir; }
{ inherit user group; mode = "0700"; directory = svc-dir; }
];
services.calibre-web.enable = true;
@@ -30,5 +30,5 @@ lib.mkIf false
proxyPass = "http://${ip}:${builtins.toString port}";
};
};
sane.dns.zones."uninsane.org".inet.CNAME."calibre" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."calibre" = "native";
}

View File

@@ -7,7 +7,6 @@
./email
./ejabberd.nix
./freshrss.nix
./ftp
./gitea.nix
./goaccess.nix
./ipfs.nix
@@ -18,7 +17,6 @@
./lemmy.nix
./matrix
./navidrome.nix
./nfs.nix
./nixserve.nix
./nginx.nix
./pict-rs.nix

View File

@@ -20,7 +20,7 @@
# lib.mkIf false
{
sane.persist.sys.plaintext = [
{ user = "ejabberd"; group = "ejabberd"; path = "/var/lib/ejabberd"; }
{ user = "ejabberd"; group = "ejabberd"; directory = "/var/lib/ejabberd"; }
];
sane.ports.ports."3478" = {
protocol = [ "tcp" "udp" ];
@@ -115,7 +115,7 @@
useACMEHost = "uninsane.org";
};
sane.dns.zones."uninsane.org".inet = {
sane.services.trust-dns.zones."uninsane.org".inet = {
# XXX: SRV records have to point to something with a A/AAAA record; no CNAMEs
A."xmpp" = "%ANATIVE%";
CNAME."muc.xmpp" = "xmpp";

View File

@@ -24,7 +24,7 @@
enableACME = true;
};
sane.dns.zones."uninsane.org".inet = {
sane.services.trust-dns.zones."uninsane.org".inet = {
CNAME."imap" = "native";
};

View File

@@ -20,9 +20,9 @@ in
{
sane.persist.sys.plaintext = [
# TODO: mode? could be more granular
{ user = "opendkim"; group = "opendkim"; path = "/var/lib/opendkim"; }
{ user = "root"; group = "root"; path = "/var/lib/postfix"; }
{ user = "root"; group = "root"; path = "/var/spool/mail"; }
{ user = "opendkim"; group = "opendkim"; directory = "/var/lib/opendkim"; }
{ user = "root"; group = "root"; directory = "/var/lib/postfix"; }
{ user = "root"; group = "root"; directory = "/var/spool/mail"; }
# *probably* don't need these dirs:
# "/var/lib/dhparams" # https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/dhparams.nix
# "/var/lib/dovecot"
@@ -50,7 +50,7 @@ in
};
sane.dns.zones."uninsane.org".inet = {
sane.services.trust-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";

View File

@@ -16,7 +16,7 @@
mode = "0400";
};
sane.persist.sys.plaintext = [
{ user = "freshrss"; group = "freshrss"; path = "/var/lib/freshrss"; }
{ user = "freshrss"; group = "freshrss"; directory = "/var/lib/freshrss"; }
];
services.freshrss.enable = true;
@@ -59,5 +59,5 @@
# the routing is handled by services.freshrss.virtualHost
};
sane.dns.zones."uninsane.org".inet.CNAME."rss" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."rss" = "native";
}

View File

@@ -1,70 +0,0 @@
# docs:
# - <https://github.com/drakkan/sftpgo>
# - config options: <https://github.com/drakkan/sftpgo/blob/main/docs/full-configuration.md>
# - config defaults: <https://github.com/drakkan/sftpgo/blob/main/sftpgo.json>
# - nixos options: <repo:nixos/nixpkgs:nixos/modules/services/web-apps/sftpgo.nix>
#
# sftpgo is a FTP server that also supports WebDAV, SFTP, and web clients.
{ lib, pkgs, sane-lib, ... }:
let
authProgram = pkgs.static-nix-shell.mkBash {
pname = "sftpgo_external_auth_hook";
src = ./.;
};
in
{
# Client initiates a FTP "control connection" on port 21.
# - this handles the client -> server commands, and the server -> client status, but not the actual data
# - file data, directory listings, etc need to be transferred on an ephemeral "data port".
# - 50000-50100 is a common port range for this.
sane.ports.ports = {
"21" = {
protocol = [ "tcp" ];
visibleTo.lan = true;
description = "colin-FTP server";
};
} // (sane-lib.mapToAttrs
(port: {
name = builtins.toString port;
value = {
protocol = [ "tcp" ];
visibleTo.lan = true;
description = "colin-FTP server data port range";
};
})
(lib.range 50000 50100)
);
services.sftpgo = {
enable = true;
settings = {
ftpd = {
bindings = [{
address = "10.0.10.5";
port = 21;
debug = true;
}];
# active mode is susceptible to "bounce attacks", without much benefit over passive mode
disable_active_mode = true;
hash_support = true;
passive_port_range = {
start = 50000;
end = 50100;
};
banner = ''
Welcome, friends, to Colin's read-only FTP server! Also available via NFS on the same host.
Please let me know if anything's broken or not as it should be. Otherwise, browse and DL freely :)
'';
};
data_provider = {
driver = "memory";
external_auth_hook = "${authProgram}/bin/sftpgo_external_auth_hook";
};
};
};
}

View File

@@ -1,55 +0,0 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash
# vim: set filetype=bash :
#
# available environment variables:
# - SFTPGO_AUTHD_USERNAME
# - SFTPGO_AUTHD_USER
# - SFTPGO_AUTHD_IP
# - SFTPGO_AUTHD_PROTOCOL = { "DAV", "FTP", "HTTP", "SSH" }
# - SFTPGO_AUTHD_PASSWORD
# - SFTPGO_AUTHD_PUBLIC_KEY
# - SFTPGO_AUTHD_KEYBOARD_INTERACTIVE
# - SFTPGO_AUTHD_TLS_CERT
#
# user permissions:
# - see <repo:drakkan/sftpgo:internal/dataprovider/user.go>
# - "*" = grant all permissions
# - read-only perms:
# - "list" = list files and directories
# - "download"
# - rw perms:
# - "upload"
# - "overwrite" = allow uploads to replace existing files
# - "delete" = delete files and directories
# - "delete_files"
# - "delete_dirs"
# - "rename" = rename files and directories
# - "rename_files"
# - "rename_dirs"
# - "create_dirs"
# - "create_symlinks"
# - "chmod"
# - "chown"
# - "chtimes" = change atime/mtime (access and modification times)
#
# home_dir:
# - it seems (empirically) that a user can't cd above their home directory.
# though i don't have a reference for that in the docs.
# TODO: don't reuse /var/nfs/export here. formalize this some other way.
if [ "$SFTPGO_AUTHD_USERNAME" = "anonymous" ]; then
echo '{'
echo ' "status":1,'
echo ' "username":"anonymous","expiration_date":0,'
echo ' "home_dir":"/var/nfs/export","uid":65534,"gid":65534,"max_sessions":0,"quota_size":0,"quota_files":100000,'
echo ' "permissions":{'
echo ' "/":["list", "download"]'
echo ' },'
echo ' "upload_bandwidth":0,"download_bandwidth":0,'
echo ' "filters":{"allowed_ip":[],"denied_ip":[]},"public_keys":[]'
echo '}'
else
echo '{"username":""}'
fi

View File

@@ -4,7 +4,7 @@
{
sane.persist.sys.plaintext = [
# TODO: mode? could be more granular
{ user = "git"; group = "gitea"; path = "/var/lib/gitea"; }
{ user = "git"; group = "gitea"; directory = "/var/lib/gitea"; }
];
services.gitea.enable = true;
services.gitea.user = "git"; # default is 'gitea'
@@ -98,7 +98,7 @@
};
};
sane.dns.zones."uninsane.org".inet.CNAME."git" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."git" = "native";
sane.ports.ports."22" = {
protocol = [ "tcp" ];

View File

@@ -64,5 +64,5 @@
};
};
sane.dns.zones."uninsane.org".inet.CNAME."sink" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."sink" = "native";
}

View File

@@ -12,7 +12,7 @@ lib.mkIf false # i don't actively use ipfs anymore
{
sane.persist.sys.plaintext = [
# TODO: mode? could be more granular
{ user = "261"; group = "261"; path = "/var/lib/ipfs"; }
{ user = "261"; group = "261"; directory = "/var/lib/ipfs"; }
];
networking.firewall.allowedTCPPorts = [ 4001 ];
@@ -34,7 +34,7 @@ lib.mkIf false # i don't actively use ipfs anymore
};
};
sane.dns.zones."uninsane.org".inet.CNAME."ipfs" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."ipfs" = "native";
# services.ipfs.enable = true;
services.kubo.localDiscovery = true;

View File

@@ -3,7 +3,7 @@
{
sane.persist.sys.plaintext = [
# TODO: mode? we only need this to save Indexer creds ==> migrate to config?
{ user = "root"; group = "root"; path = "/var/lib/jackett"; }
{ user = "root"; group = "root"; directory = "/var/lib/jackett"; }
];
services.jackett.enable = true;
@@ -24,10 +24,9 @@
locations."/" = {
# proxyPass = "http://ovpns.uninsane.org:9117";
proxyPass = "http://10.0.1.6:9117";
recommendedProxySettings = true;
};
};
sane.dns.zones."uninsane.org".inet.CNAME."jackett" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."jackett" = "native";
}

View File

@@ -41,7 +41,7 @@
};
sane.persist.sys.plaintext = [
{ user = "jellyfin"; group = "jellyfin"; mode = "0700"; path = "/var/lib/jellyfin"; }
{ user = "jellyfin"; group = "jellyfin"; mode = "0700"; directory = "/var/lib/jellyfin"; }
];
sane.fs."/var/lib/jellyfin/config/logging.json" = {
# "Emby.Dlna" logging: <https://jellyfin.org/docs/general/networking/dlna>
@@ -121,7 +121,7 @@
};
};
sane.dns.zones."uninsane.org".inet.CNAME."jelly" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."jelly" = "native";
services.jellyfin.enable = true;
}

View File

@@ -13,5 +13,5 @@
locations."/".proxyPass = "http://127.0.0.1:8013";
};
sane.dns.zones."uninsane.org".inet.CNAME."w" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."w" = "native";
}

View File

@@ -5,7 +5,7 @@ let
in
{
sane.persist.sys.plaintext = [
{ inherit user group; mode = "0700"; path = stateDir; }
{ inherit user group; mode = "0700"; directory = stateDir; }
];
services.komga.enable = true;
@@ -18,5 +18,5 @@ in
proxyPass = "http://127.0.0.1:${builtins.toString port}";
};
};
sane.dns.zones."uninsane.org".inet.CNAME."komga" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."komga" = "native";
}

View File

@@ -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,7 +32,6 @@ 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:
@@ -55,5 +54,5 @@ in {
enableACME = true;
};
sane.dns.zones."uninsane.org".inet.CNAME."lemmy" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."lemmy" = "native";
}

View File

@@ -11,7 +11,7 @@
];
sane.persist.sys.plaintext = [
{ user = "matrix-synapse"; group = "matrix-synapse"; path = "/var/lib/matrix-synapse"; }
{ user = "matrix-synapse"; group = "matrix-synapse"; directory = "/var/lib/matrix-synapse"; }
];
services.matrix-synapse.enable = true;
# this changes the default log level from INFO to WARN.
@@ -132,7 +132,7 @@
};
};
sane.dns.zones."uninsane.org".inet = {
sane.services.trust-dns.zones."uninsane.org".inet = {
CNAME."matrix" = "native";
CNAME."web.matrix" = "native";
};

View File

@@ -6,7 +6,7 @@
lib.mkIf false
{
sane.persist.sys.plaintext = [
{ user = "matrix-synapse"; group = "matrix-synapse"; path = "/var/lib/mx-puppet-discord"; }
{ user = "matrix-synapse"; group = "matrix-synapse"; directory = "/var/lib/mx-puppet-discord"; }
];
services.matrix-synapse.settings.app_service_config_files = [

View File

@@ -1,14 +1,16 @@
# config docs:
# - <https://github.com/matrix-org/matrix-appservice-irc/blob/develop/config.sample.yaml>
# TODO: /quit message for bridged users reveals to IRC users that i'm using a bridge;
# probably want to remove that.
{ config, lib, ... }:
let
ircServer = { name, additionalAddresses ? [], sasl ? true, port ? 6697 }: let
ircServer = { name, additionalAddresses ? [], sasl ? true }: let
lowerName = lib.toLower name;
in {
# XXX sasl: appservice doesn't support NickServ identification (only SASL, or PASS if sasl = false)
inherit name additionalAddresses sasl port;
inherit name additionalAddresses sasl;
port = 6697;
ssl = true;
botConfig = {
# bot has no presence in IRC channel; only real Matrix users
@@ -103,15 +105,9 @@ in
sane.persist.sys.plaintext = [
# TODO: mode?
{ user = "matrix-appservice-irc"; group = "matrix-appservice-irc"; path = "/var/lib/matrix-appservice-irc"; }
{ 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
];
@@ -149,7 +145,6 @@ in
};
"irc.oftc.net" = ircServer {
name = "oftc";
sasl = false;
# notable channels:
# - #sxmo
# - #sxmo-offtopic
@@ -158,10 +153,4 @@ 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";
};
}

View File

@@ -3,8 +3,8 @@
{ config, pkgs, ... }:
{
sane.persist.sys.plaintext = [
{ user = "mautrix-signal"; group = "mautrix-signal"; path = "/var/lib/mautrix-signal"; }
{ user = "signald"; group = "signald"; path = "/var/lib/signald"; }
{ user = "mautrix-signal"; group = "mautrix-signal"; directory = "/var/lib/mautrix-signal"; }
{ user = "signald"; group = "signald"; directory = "/var/lib/signald"; }
];
# allow synapse to read the registration file

View File

@@ -2,7 +2,7 @@
{
sane.persist.sys.plaintext = [
{ user = "navidrome"; group = "navidrome"; path = "/var/lib/navidrome"; }
{ user = "navidrome"; group = "navidrome"; directory = "/var/lib/navidrome"; }
];
services.navidrome.enable = true;
services.navidrome.settings = {
@@ -36,5 +36,5 @@
locations."/".proxyPass = "http://127.0.0.1:4533";
};
sane.dns.zones."uninsane.org".inet.CNAME."music" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."music" = "native";
}

View File

@@ -1,67 +0,0 @@
# 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" ];
};
}

View File

@@ -101,8 +101,7 @@ in
};
# allow ActivityPub clients to discover how to reach @user@uninsane.org
# see: https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3361/
# not sure this makes sense while i run multiple AP services (pleroma, lemmy)
# TODO: waiting on https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3361/
# locations."/.well-known/nodeinfo" = {
# proxyPass = "http://127.0.0.1:4000";
# extraConfig = pleromaExtraConfig;
@@ -135,8 +134,8 @@ in
sane.persist.sys.plaintext = [
# TODO: mode?
{ user = "acme"; group = "acme"; path = "/var/lib/acme"; }
{ user = "colin"; group = "users"; path = "/var/www/sites"; }
{ user = "acme"; group = "acme"; directory = "/var/lib/acme"; }
{ user = "colin"; group = "users"; directory = "/var/www/sites"; }
];
# let's encrypt default chain looks like:

View File

@@ -14,7 +14,7 @@
'';
};
sane.dns.zones."uninsane.org".inet.CNAME."nixcache" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."nixcache" = "native";
sane.services.nixserve.enable = true;
sane.services.nixserve.secretKeyFile = config.sops.secrets.nix_serve_privkey.path;

View File

@@ -6,7 +6,7 @@ let
in
{
sane.persist.sys.plaintext = lib.mkIf cfg.enable [
{ user = "pict-rs"; group = "pict-rs"; path = cfg.dataDir; }
{ user = "pict-rs"; group = "pict-rs"; directory = cfg.dataDir; }
];
systemd.services.pict-rs.serviceConfig = {

View File

@@ -1,21 +1,14 @@
# docs:
# - <https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/pleroma.nix>
# - <https://docs.pleroma.social/backend/configuration/cheatsheet/>
# example config:
# - <https://git.pleroma.social/pleroma/pleroma/-/blob/develop/config/config.exs>
# - https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/pleroma.nix
# - https://docs.pleroma.social/backend/configuration/cheatsheet/
#
# to run it in a oci-container: <https://github.com/barrucadu/nixfiles/blob/master/services/pleroma.nix>
#
# admin frontend: <https://fed.uninsane.org/pleroma/admin>
# to run it in a oci-container: https://github.com/barrucadu/nixfiles/blob/master/services/pleroma.nix
{ config, pkgs, ... }:
let
logLevel = "warn";
# logLevel = "debug";
in
{
sane.persist.sys.plaintext = [
{ user = "pleroma"; group = "pleroma"; path = "/var/lib/pleroma"; }
# TODO: mode? could be more granular
{ user = "pleroma"; group = "pleroma"; directory = "/var/lib/pleroma"; }
];
services.pleroma.enable = true;
services.pleroma.secretConfigFile = config.sops.secrets.pleroma_secrets.path;
@@ -103,22 +96,10 @@ in
backends: [{ExSyslogger, :ex_syslogger}]
config :logger, :ex_syslogger,
level: :${logLevel}
# policies => list of message rewriting facilities to be enabled
# transparence => whether to publish these rules in node_info (and /about)
config :pleroma, :mrf,
policies: [Pleroma.Web.ActivityPub.MRF.SimplePolicy],
transparency: true
# reject => { host, reason }
config :pleroma, :mrf_simple,
reject: [ {"threads.net", "megacorp"}, {"*.threads.net", "megacorp"} ]
# reject: [ [host: "threads.net", reason: "megacorp"], [host: "*.threads.net", reason: "megacorp"] ]
level: :warn
# level: :debug
# XXX colin: not sure if this actually _does_ anything
# better to steal emoji from other instances?
# - <https://docs.pleroma.social/backend/configuration/cheatsheet/#mrf_steal_emoji>
config :pleroma, :emoji,
shortcode_globs: ["/emoji/**/*.png"],
groups: [
@@ -167,7 +148,6 @@ in
# inherit kTLS;
locations."/" = {
proxyPass = "http://127.0.0.1:4000";
recommendedProxySettings = true;
# documented: https://git.pleroma.social/pleroma/pleroma/-/blob/develop/installation/pleroma.nginx
extraConfig = ''
# XXX colin: this block is in the nixos examples: i don't understand all of it
@@ -186,24 +166,23 @@ in
add_header Referrer-Policy same-origin;
add_header X-Download-Options noopen;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# # proxy_set_header Host $http_host;
# proxy_set_header Host $host;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# proxy_set_header Host $http_host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# colin: added this due to Pleroma complaining in its logs
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-Proto $scheme;
# NB: this defines the maximum upload size
client_max_body_size 16m;
'';
};
};
sane.dns.zones."uninsane.org".inet.CNAME."fed" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."fed" = "native";
sops.secrets."pleroma_secrets" = {
owner = config.users.users.pleroma.name;

View File

@@ -3,7 +3,7 @@
{
sane.persist.sys.plaintext = [
# TODO: mode?
{ user = "postgres"; group = "postgres"; path = "/var/lib/postgresql"; }
{ user = "postgres"; group = "postgres"; directory = "/var/lib/postgresql"; }
];
services.postgresql.enable = true;
# services.postgresql.dataDir = "/opt/postgresql/13";

View File

@@ -10,7 +10,7 @@
lib.mkIf false
{
sane.persist.sys.plaintext = [
{ user = "prosody"; group = "prosody"; path = "/var/lib/prosody"; }
{ user = "prosody"; group = "prosody"; directory = "/var/lib/prosody"; }
];
sane.ports.ports."5222" = {
protocol = [ "tcp" ];

View File

@@ -3,7 +3,7 @@
{
sane.persist.sys.plaintext = [
# TODO: mode? we need this specifically for the stats tracking in .config/
{ user = "transmission"; group = "transmission"; path = "/var/lib/transmission"; }
{ user = "transmission"; group = "transmission"; directory = "/var/lib/transmission"; }
];
services.transmission.enable = true;
services.transmission.settings = {
@@ -75,6 +75,6 @@
};
};
sane.dns.zones."uninsane.org".inet.CNAME."bt" = "native";
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."bt" = "native";
}

View File

@@ -1,27 +1,17 @@
{ config, lib, pkgs, ... }:
{ config, pkgs, ... }:
{
services.trust-dns.enable = true;
sane.services.trust-dns.enable = true;
services.trust-dns.settings.listen_addrs_ipv4 = [
sane.services.trust-dns.listenAddrsIPv4 = [
# specify each address explicitly, instead of using "*".
# this ensures responses are sent from the address at which the request was received.
config.sane.hosts.by-name."servo".lan-ip
"10.0.1.5"
];
# don't bind to IPv6 until i explicitly test that stack
services.trust-dns.settings.listen_addrs_ipv6 = [];
services.trust-dns.quiet = true;
# services.trust-dns.debug = true;
sane.services.trust-dns.quiet = true;
sane.ports.ports."53" = {
protocol = [ "udp" "tcp" ];
visibleTo.lan = true;
visibleTo.wan = true;
description = "colin-dns-hosting";
};
sane.dns.zones."uninsane.org".TTL = 900;
sane.services.trust-dns.zones."uninsane.org".TTL = 900;
# SOA record structure: <https://en.wikipedia.org/wiki/SOA_record#Structure>
# SOA MNAME RNAME (... rest)
@@ -31,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.dns.zones."uninsane.org".inet = {
sane.services.trust-dns.zones."uninsane.org".inet = {
SOA."@" = ''
ns1.uninsane.org. admin-dns.uninsane.org. (
2022122101 ; Serial
@@ -61,15 +51,16 @@
];
};
services.trust-dns.settings.zones = [ "uninsane.org" ];
sane.services.trust-dns.zones."uninsane.org".file = "uninsane.org.zone";
sane.services.trust-dns.zonedir = null;
services.trust-dns.package =
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.dns.zones."uninsane.org".rendered;
zone-template = config.sane.services.trust-dns.zones."uninsane.org".file;
in pkgs.writeShellScriptBin "named" ''
# compute wan/lan values
mkdir -p ${zone-dir}/{ovpn,wan,lan}
@@ -100,17 +91,6 @@
exit 1
'';
systemd.services.trust-dns.serviceConfig = {
DynamicUser = lib.mkForce false;
User = "trust-dns";
Group = "trust-dns";
};
users.groups.trust-dns = {};
users.users.trust-dns = {
group = "trust-dns";
isSystemUser = true;
};
sane.services.dyn-dns.restartOnChange = [ "trust-dns.service" ];
networking.nat.enable = true;

View File

@@ -13,7 +13,7 @@
./programs
./secrets.nix
./ssh.nix
./users
./users.nix
./vpn.nix
];
@@ -23,6 +23,9 @@
sane.programs.sysadminUtils.enableFor.system = lib.mkDefault true;
sane.programs.consoleUtils.enableFor.user.colin = lib.mkDefault true;
# some services which use private directories error if the parent (/var/lib/private) isn't 700.
sane.fs."/var/lib/private".dir.acl.mode = "0700";
nixpkgs.config.allowUnfree = true;
nixpkgs.config.allowBroken = true; # NIXPKGS_ALLOW_BROKEN
@@ -40,39 +43,48 @@
# does the builder use some content-addressed db to efficiently dedupe?
nix.settings.auto-optimise-store = true;
systemd.services.nix-daemon.serviceConfig = {
# the nix-daemon manages nix builders
# kill nix-daemon subprocesses when systemd-oomd detects an out-of-memory condition
# see:
# - nixos PR that enabled systemd-oomd: <https://github.com/NixOS/nixpkgs/pull/169613>
# - systemd's docs on these properties: <https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html#ManagedOOMSwap=auto%7Ckill>
#
# systemd's docs warn that without swap, systemd-oomd might not be able to react quick enough to save the system.
# see `man oomd.conf` for further tunables that may help.
#
# alternatively, apply this more broadly with `systemd.oomd.enableSystemSlice = true` or `enableRootSlice`
# TODO: also apply this to the guest user's slice (user-1100.slice)
# TODO: also apply this to distccd
ManagedOOMMemoryPressure = "kill";
ManagedOOMSwap = "kill";
fonts = {
enableDefaultFonts = true;
fonts = with pkgs; [ font-awesome noto-fonts-emoji hack-font ];
fontconfig.enable = true;
fontconfig.defaultFonts = {
emoji = [ "Font Awesome 6 Free" "Noto Color Emoji" ];
monospace = [ "Hack" ];
serif = [ "DejaVu Serif" ];
sansSerif = [ "DejaVu Sans" ];
};
};
system.activationScripts.nixClosureDiff = {
supportsDryActivation = true;
text = ''
# show which packages changed versions or are new/removed in this upgrade
# source: <https://github.com/luishfonseca/dotfiles/blob/32c10e775d9ec7cc55e44592a060c1c9aadf113e/modules/upgrade-diff.nix>
${pkgs.nvd}/bin/nvd --nix-bin-dir=${pkgs.nix}/bin diff /run/current-system "$systemConfig"
'';
};
# XXX: twitter-color-emoji doesn't cross-compile; but not-fonts-emoji does
# fonts = {
# enableDefaultFonts = true;
# fonts = with pkgs; [ font-awesome twitter-color-emoji hack-font ];
# fontconfig.enable = true;
# fontconfig.defaultFonts = {
# emoji = [ "Font Awesome 6 Free" "Twitter Color Emoji" ];
# monospace = [ "Hack" ];
# serif = [ "DejaVu Serif" ];
# sansSerif = [ "DejaVu Sans" ];
# };
# };
# disable non-required packages like nano, perl, rsync, strace
environment.defaultPackages = [];
# programs.vim.defaultEditor = true;
environment.variables = {
EDITOR = "vim";
# git claims it should use EDITOR, but it doesn't!
GIT_EDITOR = "vim";
# TODO: these should be moved to `home.sessionVariables` (home-manager)
# Electron apps should use native wayland backend:
# https://nixos.wiki/wiki/Slack#Wayland
# Discord under sway crashes with this.
# NIXOS_OZONE_WL = "1";
# LIBGL_ALWAYS_SOFTWARE = "1";
};
# dconf docs: <https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/desktop_migration_and_administration_guide/profiles>
# this lets programs temporarily write user-level dconf settings (aka gsettings).
# they're written to ~/.config/dconf/user, unless `DCONF_PROFILE` is set to something other than the default of /etc/dconf/profile/user
# find keys/values with `dconf dump /`
programs.dconf.enable = true;
programs.dconf.packages = [
@@ -85,7 +97,6 @@
'';
})
];
# sane.programs.glib.enableFor.user.colin = true; # for `gsettings`
# link debug symbols into /run/current-system/sw/lib/debug
# hopefully picked up by gdb automatically?

View File

@@ -1,6 +1,3 @@
# where to find good stuff?
# - podcast rec thread: <https://lemmy.ml/post/1565858>
#
# candidates:
# - The Nonlinear Library (podcast): <https://forum.effectivealtruism.org/posts/JTZTBienqWEAjGDRv/listen-to-more-ea-content-with-the-nonlinear-library>
# - has ~10 posts per day, text-to-speech; i would need better tagging before adding this
@@ -82,14 +79,12 @@ let
(fromDb "feeds.transistor.fm/acquired" // tech)
## ACQ2 - more "Acquired" episodes
(fromDb "acquiredlpbonussecretsecret.libsyn.com" // tech)
# The Intercept - Deconstructed
(fromDb "rss.acast.com/deconstructed")
# (fromDb "rss.prod.firstlook.media/deconstructed/podcast.rss" // pol) #< possible URL rot
# The Intercept - Deconstructed; also available: <rss.acast.com/deconstructed>
(fromDb "rss.prod.firstlook.media/deconstructed/podcast.rss" // pol)
## The Daily
(mkPod "https://feeds.simplecast.com/54nAGcIl" // pol // daily)
# The Intercept - Intercepted
(fromDb "rss.acast.com/intercepted-with-jeremy-scahill")
# (fromDb "rss.prod.firstlook.media/intercepted/podcast.rss" // pol) #< possible URL rot
# The Intercept - Intercepted; also available: <https://rss.acast.com/intercepted-with-jeremy-scahill>
(fromDb "rss.prod.firstlook.media/intercepted/podcast.rss" // pol)
(fromDb "podcast.posttv.com/itunes/post-reports.xml" // pol)
## Eric Weinstein
(fromDb "rss.art19.com/the-portal" // rat)
@@ -107,8 +102,6 @@ let
(fromDb "feeds.megaphone.fm/recodedecode" // tech)
## Matrix (chat) Live
(fromDb "feed.podbean.com/matrixlive/feed.xml" // tech)
(fromDb "cast.postmarketos.org" // tech)
(fromDb "podcast.thelinuxexp.com" // tech)
## Michael Malice - Your Welcome -- also available here: <https://origin.podcastone.com/podcast?categoryID2=2232>
(fromDb "rss.art19.com/your-welcome" // pol)
(fromDb "seattlenice.buzzsprout.com" // pol)
@@ -119,18 +112,12 @@ let
## The Witch Trials of J.K. Rowling
## - <https://www.thefp.com/witchtrials>
(mkPod "https://feeds.megaphone.fm/RUNMED9919162779" // pol // infrequent)
## Atlas Obscura
(fromDb "feeds.simplecast.com/xKJ93w_w" // uncat)
## Ezra Klein Show
(fromDb "feeds.simplecast.com/82FI35Px" // pol)
## Wireshark Podcast o_0
(fromDb "sharkbytes.transistor.fm" // tech)
];
texts = [
# AGGREGATORS (> 1 post/day)
(fromDb "lwn.net" // tech)
# (fromDb "lesswrong.com" // rat)
(fromDb "lesswrong.com" // rat)
# (fromDb "econlib.org" // pol)
# AGGREGATORS (< 1 post/day)
@@ -172,11 +159,10 @@ let
(fromDb "ianthehenry.com" // tech)
(fromDb "bitbashing.io" // tech)
(fromDb "idiomdrottning.org" // uncat)
(mkText "http://boginjr.com/feed" // tech // infrequent)
(mkText "https://anish.lakhwara.com/home.html" // tech // weekly)
(fromDb "jefftk.com" // tech)
(fromDb "pomeroyb.com" // tech)
# (mkText "https://til.simonwillison.net/tils/feed.atom" // tech // weekly)
(mkText "https://til.simonwillison.net/tils/feed.atom" // tech // weekly)
# TECH PROJECTS
(fromDb "blog.rust-lang.org" // tech)
@@ -226,7 +212,6 @@ let
(fromDb "preposterousuniverse.com" // rat)
(mkSubstack "eliqian" // rat // weekly)
(mkText "https://acoup.blog/feed" // rat // weekly)
(fromDb "mindingourway.com" // rat)
## mostly dating topics. not advice, or humor, but looking through a social lens
(fromDb "putanumonit.com" // rat)

View File

@@ -1,134 +1,72 @@
# docs
# - x-systemd options: <https://www.freedesktop.org/software/systemd/man/systemd.mount.html>
{ pkgs, ... }:
{ pkgs, sane-lib, ... }:
let fsOpts = rec {
common = [
let sshOpts = rec {
fsType = "fuse.sshfs";
optionsBase = [
"x-systemd.automount"
"_netdev"
"noatime"
"user" # allow any user with access to the device to mount the fs
"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"
];
sshColin = ssh ++ [
optionsColin = optionsBase ++ [
"transform_symlinks"
"idmap=user"
"uid=1000"
"gid=100"
];
sshRoot = ssh ++ [
optionsRoot = optionsBase ++ [
# 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
{
# some services which use private directories error if the parent (/var/lib/private) isn't 700.
sane.fs."/var/lib/private".dir.acl.mode = "0700";
# in-memory compressed RAM
# defaults to compressing at most 50% size of RAM
# claimed compression ratio is about 2:1
# - but on moby w/ zstd default i see 4-7:1 (ratio lowers as it fills)
# note that idle overhead is about 0.05% of capacity (e.g. 2B per 4kB page)
# docs: <https://www.kernel.org/doc/Documentation/blockdev/zram.txt>
#
# to query effectiveness:
# `cat /sys/block/zram0/mm_stat`. whitespace separated fields:
# - *orig_data_size* (bytes)
# - *compr_data_size* (bytes)
# - mem_used_total (bytes)
# - mem_limit (bytes)
# - mem_used_max (bytes)
# - *same_pages* (pages which are e.g. all zeros (consumes no additional mem))
# - *pages_compacted* (pages which have been freed thanks to compression)
# - huge_pages (incompressible)
#
# see also:
# - `man zramctl`
zramSwap.enable = true;
# how much ram can be swapped into the zram device.
# this shouldn't be higher than the observed compression ratio.
# the default is 50% (why?)
# 100% should be "guaranteed" safe so long as the data is even *slightly* compressible.
# but it decreases working memory under the heaviest of loads by however much space the compressed memory occupies (e.g. 50% if 2:1; 25% if 4:1)
zramSwap.memoryPercent = 100;
# 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/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
];

View File

@@ -23,6 +23,7 @@
# non-free firmware
hardware.enableRedistributableFirmware = true;
services.fwupd.enable = true;
# powertop will default to putting USB devices -- including HID -- to sleep after TWO SECONDS
powerManagement.powertop.enable = false;

View File

@@ -1,7 +1,7 @@
{ ... }:
{
imports = [
./keyring
./keyring.nix
./mime.nix
./ssh.nix
./xdg-dirs.nix

View File

@@ -0,0 +1,11 @@
{ config, sane-lib, ... }:
{
sane.user.persist.private = [ ".local/share/keyrings" ];
sane.user.fs."private/.local/share/keyrings/default" = {
generated.script.script = builtins.readFile ../../../scripts/init-keyring;
# TODO: is this `wantedBy` needed? can we inherit it?
wantedBy = [ config.sane.fs."/home/colin/private".unit ];
};
}

View File

@@ -1,17 +0,0 @@
{ config, pkgs, sane-lib, ... }:
let
init-keyring = pkgs.static-nix-shell.mkBash {
pname = "init-keyring";
src = ./.;
};
in
{
sane.user.persist.private = [ ".local/share/keyrings" ];
sane.user.fs."private/.local/share/keyrings/default" = {
generated.command = [ "${init-keyring}/bin/init-keyring" ];
wantedBy = [ config.sane.fs."/home/colin/private".unit ];
wantedBeforeBy = [ ]; # don't created this as part of `multi-user.target`
};
}

View File

@@ -1,28 +1,43 @@
{ config, lib, ...}:
{ config, sane-lib, ...}:
let
# ProgramConfig -> { "<mime-type>" = { priority, desktop }; }
weightedMimes = prog: builtins.mapAttrs (_key: desktop: { priority = prog.mime.priority; desktop = desktop; }) prog.mime.associations;
# [ { "<mime-type>" = { priority, desktop } ]; } ] -> { "<mime-type>" = [ { priority, desktop } ... ]; }
mergeMimes = mimes: lib.foldAttrs (item: acc: [item] ++ acc) [] mimes;
# [ { priority, desktop } ... ] -> Self
sortOneMimeType = associations: builtins.sort (l: r: assert l.priority != r.priority; l.priority < r.priority) associations;
sortMimes = mimes: builtins.mapAttrs (_k: sortOneMimeType) mimes;
removePriorities = mimes: builtins.mapAttrs (_k: associations: builtins.map (a: a.desktop) associations) mimes;
# [ ProgramConfig ]
enabledPrograms = builtins.filter (p: p.enabled) (builtins.attrValues config.sane.programs);
# [ { "<mime-type>" = { prority, desktop } ]
enabledWeightedMimes = builtins.map weightedMimes enabledPrograms;
www = config.sane.programs.web-browser.config.browser.desktop;
pdf = "org.gnome.Evince.desktop";
md = "obsidian.desktop";
thumb = "org.gnome.gThumb.desktop";
video = "vlc.desktop";
# audio = "mpv.desktop";
audio = "vlc.desktop";
in
{
# the xdg mime type for a file can be found with:
# - `xdg-mime query filetype path/to/thing.ext`
# the default handler for a mime type can be found with:
# - `xdg-mime query default <mimetype>` (e.g. x-scheme-handler/http)
#
# we can have single associations or a list of associations.
# there's also options to *remove* [non-default] associations from specific apps
xdg.mime.enable = true;
xdg.mime.defaultApplications = removePriorities (sortMimes (mergeMimes enabledWeightedMimes));
xdg.mime.defaultApplications = {
# AUDIO
"audio/flac" = audio;
"audio/mpeg" = audio;
"audio/x-vorbis+ogg" = audio;
# IMAGES
"image/heif" = thumb; # apple codec
"image/png" = thumb;
"image/jpeg" = thumb;
# VIDEO
"video/mp4" = video;
"video/quicktime" = video;
"video/webm" = video;
"video/x-matroska" = video;
# HTML
"text/html" = www;
"x-scheme-handler/http" = www;
"x-scheme-handler/https" = www;
"x-scheme-handler/about" = www;
"x-scheme-handler/unknown" = www;
# RICH-TEXT DOCUMENTS
"application/pdf" = pdf;
"text/markdown" = md;
};
}

View File

@@ -1,29 +1,26 @@
# TODO: this should be moved to users/colin.nix
{ config, lib, ... }:
{ config, lib, sane-lib, ... }:
with lib;
let
host = config.networking.hostName;
user-pubkey-full = config.sane.ssh.pubkeys."colin@${host}" or {};
user-pubkey = user-pubkey-full.asUserKey or null;
host-keys = lib.filter (k: k.user == "root") (lib.attrValues config.sane.ssh.pubkeys);
known-hosts-text = lib.concatStringsSep
host-keys = filter (k: k.user == "root") (attrValues config.sane.ssh.pubkeys);
known-hosts-text = concatStringsSep
"\n"
(builtins.map (k: k.asHostKey) host-keys)
(map (k: k.asHostKey) host-keys)
;
in
{
# ssh key is stored in private storage
sane.user.persist.private = [
{ type = "file"; path = ".ssh/id_ed25519"; }
];
sane.user.fs.".ssh/id_ed25519.pub" = lib.mkIf (user-pubkey != null) {
symlink.text = user-pubkey;
};
sane.user.fs.".ssh/known_hosts".symlink.text = known-hosts-text;
sane.user.persist.private = [ ".ssh/id_ed25519" ];
sane.user.fs.".ssh/id_ed25519.pub" =
mkIf (user-pubkey != null) (sane-lib.fs.wantedText user-pubkey);
sane.user.fs.".ssh/known_hosts" = sane-lib.fs.wantedText known-hosts-text;
users.users.colin.openssh.authorizedKeys.keys =
let
user-keys = lib.filter (k: k.user == "colin") (lib.attrValues config.sane.ssh.pubkeys);
user-keys = filter (k: k.user == "colin") (attrValues config.sane.ssh.pubkeys);
in
builtins.map (k: k.asUserKey) user-keys;
map (k: k.asUserKey) user-keys;
}

View File

@@ -1,9 +1,9 @@
{ ... }:
{ lib, sane-lib, ...}:
{
# XDG defines things like ~/Desktop, ~/Downloads, etc.
# these clutter the home, so i mostly don't use them.
sane.user.fs.".config/user-dirs.dirs".symlink.text = ''
sane.user.fs.".config/user-dirs.dirs" = sane-lib.fs.wantedText ''
XDG_DESKTOP_DIR="$HOME/.xdg/Desktop"
XDG_DOCUMENTS_DIR="$HOME/dev"
XDG_DOWNLOAD_DIR="$HOME/tmp"
@@ -16,5 +16,5 @@
# prevent `xdg-user-dirs-update` from overriding/updating our config
# see <https://manpages.ubuntu.com/manpages/bionic/man5/user-dirs.conf.5.html>
sane.user.fs.".config/user-dirs.conf".symlink.text = "enabled=False";
sane.user.fs.".config/user-dirs.conf" = sane-lib.fs.wantedText "enabled=False";
}

View File

@@ -40,10 +40,6 @@
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.trust-dns.uid = 2411;
sane.ids.trust-dns.gid = 2411;
sane.ids.colin.uid = 1000;
sane.ids.guest.uid = 1100;

View File

@@ -11,37 +11,17 @@
# - `man iwd.config` for global config
# - `man iwd.network` for per-SSID config
# use `iwctl` to control
# networking.networkmanager.wifi.backend = "iwd";
# networking.wireless.iwd.enable = true;
# networking.wireless.iwd.settings = {
# # auto-connect to a stronger network if signal drops below this value
# # bedroom -> bedroom connection is -35 to -40 dBm
# # bedroom -> living room connection is -60 dBm
# General.RoamThreshold = "-52"; # default -70
# General.RoamThreshold5G = "-52"; # default -76
# };
# plugins mostly add support for establishing different VPN connections.
# the default plugin set includes mostly proprietary VPNs:
# - fortisslvpn (Fortinet)
# - iodine (DNS tunnels)
# - l2tp
# - openconnect (Cisco Anyconnect / Juniper / ocserv)
# - openvpn
# - vpnc (Cisco VPN)
# - sstp
#
# i don't use these, and notably they drag in huge dependency sets and don't cross compile well.
# e.g. openconnect drags in webkitgtk (for SSO)!
networking.networkmanager.plugins = lib.mkForce [];
networking.networkmanager.wifi.backend = "iwd";
networking.wireless.iwd.enable = true;
networking.wireless.iwd.settings = {
# auto-connect to a stronger network if signal drops below this value
# bedroom -> bedroom connection is -35 to -40 dBm
# bedroom -> living room connection is -60 dBm
General.RoamThreshold = "-52"; # default -70
General.RoamThreshold5G = "-52"; # default -76
};
networking.firewall.allowedUDPPorts = [
1900 # to received UPnP advertisements. required by sane-ip-check-upnp
];
# keyfile.path = where networkmanager should look for connection credentials
networking.networkmanager.extraConfig = ''
[keyfile]
path=/var/lib/NetworkManager/system-connections
'';
}

View File

@@ -5,9 +5,6 @@
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"
"nixpkgs-overlays=${../../..}/hosts/common/nix-path/overlay"
];
}

View File

@@ -6,11 +6,13 @@
sane.persist.stores.private.prefix = "/home/colin";
sane.persist.sys.plaintext = [
# TODO: these should be private.. somehow
"/var/log"
"/var/backup" # for e.g. postgres dumps
];
sane.persist.sys.cryptClearOnBoot = [
# TODO: move elsewhere
"/var/lib/alsa" # preserve output levels, default devices
"/var/lib/colord" # preserve color calibrations (?)
"/var/lib/machines" # maybe not needed, but would be painful to add a VM and forget.
"/var/lib/systemd/backlight" # backlight brightness
"/var/lib/systemd/coredump"
];
}

View File

@@ -2,8 +2,5 @@
{ ... }:
{
sane.programs.aerc = {
secrets.".config/aerc/accounts.conf" = ../../../secrets/common/aerc_accounts.conf.bin;
mime.associations."x-scheme-handler/mailto" = "aerc.desktop";
};
sane.programs.aerc.secrets.".config/aerc/accounts.conf" = ../../../secrets/common/aerc_accounts.conf.bin;
}

View File

@@ -1,254 +0,0 @@
{ pkgs, ... }:
let
declPackageSet = pkgs: {
package = null;
suggestedPrograms = pkgs;
};
in
{
sane.programs = {
# PACKAGE SETS
"sane-scripts.backup" = declPackageSet [
"sane-scripts.backup-ls"
"sane-scripts.backup-restore"
];
"sane-scripts.bittorrent" = declPackageSet [
"sane-scripts.bt-add"
"sane-scripts.bt-rm"
"sane-scripts.bt-search"
"sane-scripts.bt-show"
];
"sane-scripts.dev" = declPackageSet [
"sane-scripts.dev-cargo-loop"
"sane-scripts.git-init"
];
"sane-scripts.cli" = declPackageSet [
"sane-scripts.deadlines"
"sane-scripts.find-dotfiles"
"sane-scripts.ip-check"
"sane-scripts.ip-reconnect"
"sane-scripts.private-change-passwd"
"sane-scripts.private-do"
"sane-scripts.private-init"
"sane-scripts.private-lock"
"sane-scripts.private-unlock"
"sane-scripts.rcp"
"sane-scripts.reboot"
"sane-scripts.reclaim-boot-space"
"sane-scripts.reclaim-disk-space"
"sane-scripts.secrets-dump"
"sane-scripts.secrets-unlock"
"sane-scripts.secrets-update-keys"
"sane-scripts.shutdown"
"sane-scripts.ssl-dump"
"sane-scripts.sudo-redirect"
"sane-scripts.sync-from-servo"
"sane-scripts.vpn-down"
"sane-scripts.vpn-up"
"sane-scripts.which"
"sane-scripts.wipe-browser"
];
"sane-scripts.sys-utils" = declPackageSet [
"sane-scripts.ip-port-forward"
];
sysadminUtils = declPackageSet [
"btrfs-progs"
"cacert.unbundled" # some services require unbundled /etc/ssl/certs
"cryptsetup"
"dig"
"efibootmgr"
"fatresize"
"fd"
"file"
# "fwupd"
"gawk"
"git"
"gptfdisk"
"hdparm"
"htop"
"iftop"
"inetutils" # for telnet
"iotop"
"iptables"
"jq"
"killall"
"lsof"
"miniupnpc"
"nano"
# "ncdu" # ncurses disk usage. doesn't cross compile (zig)
"neovim"
"netcat"
"nethogs"
"nmap"
"openssl"
"parted"
"pciutils"
"powertop"
"pstree"
"ripgrep"
"screen"
"smartmontools"
"socat"
"strace"
"subversion"
"tcpdump"
"tree"
"usbutils"
"wget"
"wirelesstools" # iwlist
];
sysadminExtraUtils = declPackageSet [
"backblaze-b2"
"duplicity"
"sane-scripts.backup"
"sqlite" # to debug sqlite3 databases
];
# TODO: split these into smaller groups.
# - moby doesn't want a lot of these.
# - categories like
# - dev?
# - debugging?
consoleUtils = declPackageSet [
"alsaUtils" # for aplay, speaker-test
# "cdrtools"
"clinfo"
"dmidecode"
"dtrx" # `unar` alternative, "Do The Right eXtraction"
"efivar"
# "flashrom"
"git" # needed as a user package, for config.
# "gnupg"
# "gocryptfs"
# "gopass"
# "gopass-jsonapi"
"helix" # text editor
"kitty" # TODO: move to GUI, but `ssh servo` from kitty sets `TERM=xterm-kitty` in the remove and breaks things
"libsecret" # for managing user keyrings. TODO: what needs this? lift into the consumer
"lm_sensors" # for sensors-detect. TODO: what needs this? lift into the consumer
"lshw"
# "memtester"
"neovim" # needed as a user package, for swap persistence
# "nettools"
# "networkmanager"
# "nixos-generators"
"nmon"
# "node2nix"
# "oathToolkit" # for oathtool
# "ponymix"
"pulsemixer"
"python3"
# "python3Packages.eyeD3" # music tagging
"ripgrep" # needed as a user package so that its user-level config file can be installed
"rsync"
"sane-scripts.bittorrent"
"sane-scripts.cli"
"snapper"
"sops"
"speedtest-cli"
# "ssh-to-age"
"sudo"
# "tageditor" # music tagging
# "unar"
"wireguard-tools"
"xdg-terminal-exec"
"xdg-utils" # for xdg-open
# "yarn"
"zsh"
];
desktopConsoleUtils = declPackageSet [
"gh" # MS GitHub cli
"nix-index"
"nixpkgs-review"
"sane-scripts.dev"
"sequoia"
];
consoleMediaUtils = declPackageSet [
"ffmpeg"
"imagemagick"
"sox"
"yt-dlp"
];
tuiApps = declPackageSet [
"aerc" # email client
"msmtp" # sendmail
"offlineimap" # email mailbox sync
"sfeed" # RSS fetcher
"visidata" # TUI spreadsheet viewer/editor
"w3m" # web browser
];
iphoneUtils = declPackageSet [
"ifuse"
"ipfs"
"libimobiledevice"
"sane-scripts.sync-from-iphone"
];
devPkgs = declPackageSet [
"clang"
"nodejs"
"tree-sitter"
];
# INDIVIDUAL PACKAGE DEFINITIONS
dino.persist.private = [ ".local/share/dino" ];
# creds, but also 200 MB of node modules, etc
discord.persist.private = [ ".config/discord" ];
# `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" ];
fluffychat-moby.persist.plaintext = [ ".local/share/chat.fluffy.fluffychat" ];
# 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" ];
# 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 an "unable to connect to Tor" error when pressing the "connect" button
# - still required as of 2023/07/14
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" ];
};
}

View File

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

View File

@@ -1,11 +0,0 @@
{ ... }:
{
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
];
};
}

View File

@@ -1,58 +1,422 @@
{ pkgs, ... }:
{ config, lib, 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
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
visidata # TUI spreadsheet viewer/editor
w3m
;
};
# TODO: split these into smaller groups.
# - transcoders (ffmpeg, imagemagick) only wanted on desko/lappy ("powerutils"?)
consolePkgs = {
inherit (pkgs)
alsaUtils # for aplay, speaker-test
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
./chatty.nix
./cozy.nix
./element-desktop.nix
./epiphany.nix
./evince.nix
./firefox.nix
./fontconfig.nix
./fractal.nix
./fwupd.nix
./git.nix
./gnome-feeds.nix
./gnome-keyring.nix
./gpodder.nix
./gthumb.nix
./helix.nix
./imagemagick.nix
./jellyfin-media-player.nix
./kitty
./komikku.nix
./koreader
./libreoffice.nix
./lemoa.nix
./megapixels.nix
./mepo.nix
./mpv.nix
./msmtp.nix
./neovim.nix
./newsflash.nix
./nheko.nix
./nix-index.nix
./obsidian.nix
./offlineimap.nix
./ripgrep.nix
./sfeed.nix
./splatmoji.nix
./steam.nix
./sublime-music.nix
./tangram.nix
./tuba.nix
./vlc.nix
./web-browser.nix
./wireshark.nix
./xarchiver.nix
./zeal.nix
./zsh
];
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" ];
};
# 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
};
};
}

View File

@@ -1,9 +0,0 @@
{ ... }:
{
sane.programs.element-desktop = {
# creds/session keys, etc
persist.private = [ ".config/Element" ];
suggestedPrograms = [ "gnome-keyring" ];
};
}

View File

@@ -1,45 +0,0 @@
# epiphany web browser
# - GTK4/webkitgtk
#
# usability notes:
# - touch-based scroll works well (for moby)
# - URL bar constantly resets cursor to the start of the line as i type
# - maybe due to the URLbar suggestions getting in the way
{ pkgs, ... }:
{
sane.programs.epiphany = {
# XXX(2023/07/08): running on moby without this hack fails, with:
# - `bwrap: Can't make symlink at /var/run: File exists`
# this could be due to:
# - epiphany is somewhere following a symlink into /var/run instead of /run
# - (nothing in `env` or in this repo touches /var/run)
# - no xdg-desktop-portal is installed (unlikely)
#
# a few other users have hit this, in different contexts:
# - <https://gitlab.gnome.org/GNOME/gnome-builder/-/issues/1164>
# - <https://github.com/flatpak/flatpak/issues/3477>
# - <https://github.com/NixOS/nixpkgs/issues/197085>
package = pkgs.epiphany.overrideAttrs (upstream: {
preFixup = ''
gappsWrapperArgs+=(
--set WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS "1"
);
'' + (upstream.preFixup or "");
});
persist.private = [
".cache/epiphany"
".local/share/epiphany"
# also .config/epiphany, but appears empty
];
mime.priority = 200; # default priority is 100: install epiphany only as a fallback
mime.associations = let
desktop = "org.gnome.Epiphany.desktop";
in {
"text/html" = desktop;
"x-scheme-handler/http" = desktop;
"x-scheme-handler/https" = desktop;
"x-scheme-handler/about" = desktop;
"x-scheme-handler/unknown" = desktop;
};
};
}

View File

@@ -1,4 +0,0 @@
{ ... }:
{
sane.programs.evince.mime.associations."application/pdf" = "org.gnome.Evince.desktop";
}

View File

@@ -1,15 +0,0 @@
{ config, lib, pkgs, ... }:
{
fonts = lib.mkIf config.sane.programs.fontconfig.enabled {
fontconfig.enable = true;
fontconfig.defaultFonts = {
emoji = [ "Font Awesome 6 Free" "Noto Color Emoji" ];
monospace = [ "Hack" ];
serif = [ "DejaVu Serif" ];
sansSerif = [ "DejaVu Sans" ];
};
#vvv enables dejavu_fonts, freefont_ttf, gyre-fonts, liberation_ttf, unifont, noto-fonts-emoji
enableDefaultPackages = true;
packages = with pkgs; [ font-awesome noto-fonts-emoji hack-font ];
};
}

View File

@@ -1,12 +0,0 @@
{ pkgs, ... }:
{
sane.programs.fractal = {
# package = pkgs.fractal-latest;
package = pkgs.fractal-next;
# XXX by default fractal stores its state in ~/.local/share/stable/<UUID>.
persist.private = [ ".local/share/stable" ];
suggestedPrograms = [ "gnome-keyring" ];
};
}

View File

@@ -1,7 +0,0 @@
{ config, lib, ... }:
{
services.fwupd = lib.mkIf config.sane.programs.fwupd.enabled {
# enables the dbus service, which i think the frontend speaks to.
enable = true;
};
}

View File

@@ -1,8 +1,6 @@
{ lib, pkgs, ... }:
let
# TODO: use formats.gitIni or lib.generators.toGitINI
# - see: <repo:nixos/nixpkgs:pkgs/pkgs-lib/formats.nix>
mkCfg = lib.generators.toINI { };
in
{
@@ -13,15 +11,7 @@ in
user.name = "Colin";
user.email = "colin@uninsane.org";
alias.br = "branch";
alias.co = "checkout";
alias.cp = "cherry-pick";
alias.d = "difftool";
alias.dif = "diff"; # common typo
alias.difsum = "diff --compact-summary"; #< show only the list of files which changed, not contents
alias.rb = "rebase";
alias.st = "status";
alias.stat = "status";
alias.co = "checkout";
# difftastic docs:
# - <https://difftastic.wilfred.me.uk/git.html>
@@ -32,10 +22,5 @@ in
# render dates as YYYY-MM-DD HH:MM:SS +TZ
log.date = "iso";
sendemail.annotate = "yes";
sendemail.confirm = "always";
stash.showPatch = true;
};
}

View File

@@ -1,10 +0,0 @@
{ config, lib, pkgs, ... }:
{
sane.programs.gnome-keyring = {
package = pkgs.gnome.gnome-keyring;
};
# adds gnome-keyring as a xdg-data-portal (xdg.portal)
services.gnome.gnome-keyring = lib.mkIf config.sane.programs.gnome-keyring.enabled {
enable = true;
};
}

View File

@@ -7,8 +7,7 @@ let
wanted-feeds = feeds.filterByFormat ["podcast"] all-feeds;
in {
sane.programs.gpodder = {
package = pkgs.gpodder-adaptive-configured;
# package = pkgs.gpodder-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

View File

@@ -1,13 +0,0 @@
{ pkgs, ... }:
{
sane.programs.gthumb = {
# compile without webservices to avoid the expensive webkitgtk dependency
package = pkgs.gthumb.override { withWebservices = false; };
mime.associations = {
"image/heif" = "org.gnome.gThumb.desktop"; # apple codec
"image/png" = "org.gnome.gThumb.desktop";
"image/jpeg" = "org.gnome.gThumb.desktop";
"image/svg+xml" = "org.gnome.gThumb.desktop";
};
};
}

View File

@@ -1,22 +0,0 @@
# Helix text editor
# debug log: `~/.cache/helix/helix.log`
# binary name is `hx`
{ ... }:
{
sane.programs.helix = {
# grammars need to be persisted when developing them
# - `hx --grammar fetch` and `hx --grammar build`
# but otherwise, they ship as part of HELIX_RUNTIME, in the nix store
# persist.plaintext = [ ".config/helix/runtime/grammars" ];
fs.".config/helix/config.toml".symlink.text = ''
# docs: <https://docs.helix-editor.com/configuration.html>
[editor.soft-wrap]
enable = true
[editor.whitespace.render]
space = "all"
tab = "all"
newline = "none"
'';
};
}

View File

@@ -1,9 +0,0 @@
{ pkgs, ... }:
{
sane.programs.imagemagick = {
package = pkgs.imagemagick.override {
ghostscriptSupport = true;
};
suggestedPrograms = [ "ghostscript" ];
};
}

View File

@@ -2,9 +2,7 @@
{
sane.programs.jellyfin-media-player = {
# package = pkgs.jellyfin-media-player;
# qt6 version is slightly buggy, but also most qtwebengine apps (e.g. zeal) are on qt5
# so using qt6 would force yet *another* qtwebengine compile.
package = pkgs.jellyfin-media-player;
# package = pkgs.jellyfin-media-player-qt6;
# jellyfin stores things in a bunch of directories: this one persists auth info.

View File

@@ -1,17 +1,14 @@
{ lib, ... }:
{ ... }:
{
sane.programs.kitty = {
fs.".config/kitty/kitty.conf".symlink.text = ''
# docs: https://sw.kovidgoyal.net/kitty/conf/
# disable terminal bell (when e.g. you backspace too many times)
enable_audio_bell no
sane.programs.kitty.fs.".config/kitty/kitty.conf".symlink.text = ''
# docs: https://sw.kovidgoyal.net/kitty/conf/
# disable terminal bell (when e.g. you backspace too many times)
enable_audio_bell no
map ctrl+n new_os_window_with_cwd
include ${./PaperColor_dark.conf}
'';
env.TERMINAL = lib.mkDefault "kitty";
};
map ctrl+n new_os_window_with_cwd
include ${./PaperColor_dark.conf}
'';
# include ${pkgs.kitty-themes}/themes/PaperColor_dark.conf

View File

@@ -1,8 +0,0 @@
{ ... }:
{
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" ];
};
}

View File

@@ -1,42 +0,0 @@
-- 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

View File

@@ -1,48 +0,0 @@
{ config, lib, pkgs, 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
# - in practice, most articles don't work with download_full_article = false
# enable_filter = true => only render content that matches the filter_element css selector.
let fields = [
(lib.escapeShellArg feed.url)
"limit = 5"
"download_full_article = true"
"include_images = true"
"enable_filter = false"
"filter_element = \"\""
]; in "{ ${lib.concatStringsSep ", " fields } }"
) wantedFeeds;
in {
sane.programs.koreader = {
package = pkgs.koreader-from-src;
# koreader applies these lua "patches" at boot:
# - <https://github.com/koreader/koreader/wiki/User-patches>
# - TODO: upstream this patch to koreader
# 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" ];
};
}

View File

@@ -1,7 +0,0 @@
{ ... }:
{
sane.programs.lemoa = {
# creds
persist.private = [ ".local/share/io.github.lemmygtk.lemoa" ];
};
}

View File

@@ -1,20 +1,14 @@
{ pkgs, ... }:
{ ... }:
{
sane.programs.libreoffice = {
# package = pkgs.libreoffice-bin;
# package = pkgs.libreoffice-still;
package = pkgs.libreoffice-fresh;
# disable first-run stuff
fs.".config/libreoffice/4/user/registrymodifications.xcu".symlink.text = ''
<?xml version="1.0" encoding="UTF-8"?>
<oor:items xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item oor:path="/org.openoffice.Office.Common/Misc"><prop oor:name="FirstRun" oor:op="fuse"><value>false</value></prop></item>
<item oor:path="/org.openoffice.Office.Common/Misc"><prop oor:name="ShowTipOfTheDay" oor:op="fuse"><value>false</value></prop></item>
</oor:items>
'';
# <item oor:path="/org.openoffice.Setup/Product"><prop oor:name="LastTimeDonateShown" oor:op="fuse"><value>1667693880</value></prop></item>
# <item oor:path="/org.openoffice.Setup/Product"><prop oor:name="LastTimeGetInvolvedShown" oor:op="fuse"><value>1667693880</value></prop></item>
};
# libreoffice: disable first-run stuff
sane.programs.libreoffice-fresh.fs.".config/libreoffice/4/user/registrymodifications.xcu".symlink.text = ''
<?xml version="1.0" encoding="UTF-8"?>
<oor:items xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item oor:path="/org.openoffice.Office.Common/Misc"><prop oor:name="FirstRun" oor:op="fuse"><value>false</value></prop></item>
<item oor:path="/org.openoffice.Office.Common/Misc"><prop oor:name="ShowTipOfTheDay" oor:op="fuse"><value>false</value></prop></item>
</oor:items>
'';
# <item oor:path="/org.openoffice.Setup/Product"><prop oor:name="LastTimeDonateShown" oor:op="fuse"><value>1667693880</value></prop></item>
# <item oor:path="/org.openoffice.Setup/Product"><prop oor:name="LastTimeGetInvolvedShown" oor:op="fuse"><value>1667693880</value></prop></item>
}

View File

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

View File

@@ -1,26 +0,0 @@
# docs: <https://git.sr.ht/~mil/mepo>
# irc #mepo:irc.oftc.net
{ config, lib, ... }:
{
sane.programs.mepo = {
persist.plaintext = [ ".cache/mepo/tiles" ];
# ~/.cache/mepo/savestate has precise coordinates and pins: keep those private
persist.private = [
{ type = "file"; path = ".cache/mepo/savestate"; }
];
# give mepo access to gpsd for location data, if that's enabled.
# same with geoclue2.
suggestedPrograms = lib.optional config.services.gpsd.enable "gpsd"
++ lib.optional config.services.geoclue2.enable "geoclue2-with-demo-agent"
;
};
# programs.mepo = lib.mkIf config.sane.programs.mepo.enabled {
# # enable location services (via geoclue)
# enable = true;
# # more precise, via gpsd ("may require additional config")
# # programs.mepo.gpsd.enable = true
# };
}

View File

@@ -1,82 +1,13 @@
# mpv docs:
# - <https://mpv.io/manual/master>
# - <https://github.com/mpv-player/mpv/wiki>
# curated mpv mods/scripts/users:
# - <https://github.com/stax76/awesome-mpv>
{ pkgs, ... }:
{ ... }:
{
sane.programs.mpv = {
package = pkgs.wrapMpv pkgs.mpv-unwrapped {
youtubeSupport = false; #< XXX(2023/08/03): doesn't cross compile until next staging -> master merge
scripts = with pkgs.mpvScripts; [
mpris
# uosc
pkgs.mpv-uosc-latest
];
};
persist.plaintext = [ ".config/mpv/watch_later" ];
fs.".config/mpv/input.conf".symlink.text = ''
# let volume keys be interpreted by the system.
# this is important for sxmo.
VOLUME_UP ignore
VOLUME_DOWN ignore
'';
# format is <key>=%<length>%<value>
fs.".config/mpv/mpv.conf".symlink.text = ''
save-position-on-quit=yes
keep-open=yes
# use uosc instead (for On Screen Controls)
osc=no
# uosc provides its own seeking/volume indicators, so you also don't need this
osd-bar=no
# uosc will draw its own window controls if you disable window border
border=no
save-position-on-quit=%3%yes
keep-open=%3%yes
'';
fs.".config/mpv/script-opts/osc.conf".symlink.text = ''
# make the on-screen controls *always* visible
# unfortunately, this applies to full-screen as well
# - docs: <https://mpv.io/manual/master/#on-screen-controller-visibility>
# if uosc is installed, this file is unused
visibility=always
'';
fs.".config/mpv/script-opts/uosc.conf".symlink.text = let
play_pause_btn = "cycle:play_arrow:pause:no=pause/yes=play_arrow";
rev_btn = "command:replay_10:seek -10";
fwd_btn = "command:forward_30:seek 30";
in ''
# docs:
# - <https://github.com/tomasklaen/uosc>
# - <https://superuser.com/questions/1775550/add-new-buttons-to-mpv-uosc-ui>
timeline_style=bar
timeline_persistency=paused,audio
controls_persistency=paused,audio
volume_persistency=audio
volume_opacity=0.75
# speed_persistency=paused,audio
# vvv want a close button?
top_bar=always
top_bar_persistency=paused
controls=menu,<video>subtitles,<has_many_audio>audio,<has_many_video>video,<has_many_edition>editions,<stream>stream-quality,space,${rev_btn},${play_pause_btn},${fwd_btn},space,speed:1.0,gap,<video>fullscreen
text_border=6.0
font_bold=yes
background_text=ff8080
foreground=ff8080
ui_scale=1.0
'';
mime.priority = 200; # default = 100; 200 means to yield to other apps
mime.associations."audio/flac" = "mpv.desktop";
mime.associations."audio/mpeg" = "mpv.desktop";
mime.associations."audio/x-vorbis+ogg" = "mpv.desktop";
mime.associations."video/mp4" = "mpv.desktop";
mime.associations."video/quicktime" = "mpv.desktop";
mime.associations."video/webm" = "mpv.desktop";
mime.associations."video/x-matroska" = "mpv.desktop";
};
}

View File

@@ -1,25 +0,0 @@
# docs: <https://nixos.wiki/wiki/Msmtp>
# validate with e.g.
# - `echo -e "Content-Type: text/plain\r\nSubject: Test\r\n\r\nHello World" | sendmail test@uninsane.org`
{ config, lib, ... }:
{
sane.programs.msmtp = {
secrets.".config/msmtp/password.txt" = ../../../secrets/common/msmtp_password.txt.bin;
};
programs.msmtp = lib.mkIf config.sane.programs.msmtp.enabled {
enable = true;
accounts = {
default = {
auth = true;
tls = true;
tls_starttls = false; # needed else sendmail hangs
from = "Colin <colin@uninsane.org>";
host = "mx.uninsane.org";
user = "colin";
passwordeval = "cat ~/.config/msmtp/password.txt";
};
};
};
}

View File

@@ -5,21 +5,35 @@ let
inherit (lib) concatMapStrings mkIf optionalString;
# this structure roughly mirrors home-manager's `programs.neovim.plugins` option
plugins = with pkgs.vimPlugins; [
{
# docs: fzf-vim (fuzzy finder): https://github.com/junegunn/fzf.vim
plugin = fzf-vim;
}
{
# docs: surround-nvim: https://github.com/ur4ltz/surround.nvim/
# docs: vim-surround: https://github.com/tpope/vim-surround
{ plugin = vim-surround; }
# docs: fzf-vim (fuzzy finder): https://github.com/junegunn/fzf.vim
{ plugin = fzf-vim; }
({
# docs: tex-conceal-vim: https://github.com/KeitaNakamura/tex-conceal.vim/
plugin = tex-conceal-vim;
type = "viml";
config = ''
" present prettier fractions
let g:tex_conceal_frac=1
'';
})
({
plugin = vim-SyntaxRange;
type = "viml";
config = ''
" enable markdown-style codeblock highlighting for tex code
autocmd BufEnter * call SyntaxRange#Include('```tex', '```', 'tex', 'NonText')
" autocmd Syntax tex set conceallevel=2
'';
})
({
# treesitter syntax highlighting: https://nixos.wiki/wiki/Tree_sitters
# docs: https://github.com/nvim-treesitter/nvim-treesitter
# config taken from: https://github.com/i077/system/blob/master/modules/home/neovim/default.nix
# this is required for tree-sitter to even highlight
plugin = nvim-treesitter.withPlugins (_: nvim-treesitter.allGrammars ++ [
# XXX: this is apparently not enough to enable syntax highlighting!
# nvim-treesitter ships its own queries which may be distinct from e.g. helix.
# the queries aren't included when i ship the grammar in this manner
pkgs.tree-sitter-nix-shell
]);
plugin = nvim-treesitter.withAllGrammars;
type = "lua";
config = ''
require'nvim-treesitter.configs'.setup {
@@ -50,48 +64,15 @@ let
vim.o.foldmethod = 'expr'
vim.o.foldexpr = 'nvim_treesitter#foldexpr()'
'';
}
{
# docs: tex-conceal-vim: https://github.com/KeitaNakamura/tex-conceal.vim/
plugin = tex-conceal-vim;
type = "viml";
config = ''
" present prettier fractions
let g:tex_conceal_frac=1
'';
}
{
# source: <https://github.com/LnL7/vim-nix>
# fixes auto-indent (incl tab size) when editing .nix files
plugin = vim-nix;
}
{
# docs: surround-nvim: https://github.com/ur4ltz/surround.nvim/
# docs: vim-surround: https://github.com/tpope/vim-surround
plugin = vim-surround;
}
{
plugin = vim-SyntaxRange;
type = "viml";
config = ''
" enable markdown-style codeblock highlighting for tex code
autocmd BufEnter * call SyntaxRange#Include('```tex', '```', 'tex', 'NonText')
" autocmd Syntax tex set conceallevel=2
'';
}
})
];
plugin-packages = map (p: p.plugin) plugins;
plugin-config-viml = concatMapStrings (p: optionalString (p.type or "" == "viml") p.config) plugins;
plugin-config-tex = concatMapStrings (p: optionalString (p.type or "" == "viml") p.config) plugins;
plugin-config-lua = concatMapStrings (p: optionalString (p.type or "" == "lua") p.config) plugins;
in
{
# private because there could be sensitive things in the swap
sane.programs.neovim = {
persist.private = [ ".cache/vim-swap" ];
env.EDITOR = "vim";
# git claims it should use EDITOR, but it doesn't!
env.GIT_EDITOR = "vim";
};
sane.programs.neovim.persist.private = [ ".cache/vim-swap" ];
programs.neovim = mkIf config.sane.programs.neovim.enabled {
# neovim: https://github.com/neovim/neovim
@@ -99,7 +80,7 @@ in
viAlias = true;
vimAlias = true;
configure = {
packages.plugins = {
packages.myVimPackage = {
start = plugin-packages;
};
customRC = ''
@@ -135,8 +116,8 @@ in
set list
set listchars=tab:\·,trail:·,extends:,precedes:,nbsp:
""""" PLUGIN CONFIG (vim)
${plugin-config-viml}
""""" PLUGIN CONFIG (tex)
${plugin-config-tex}
""""" PLUGIN CONFIG (lua)
lua <<EOF

View File

@@ -1,9 +0,0 @@
{ ... }:
{
# not strictly necessary, but allows caching articles; offline use, etc.
sane.programs.nheko.persist.private = [
".config/nheko" # config file (including client token)
".cache/nheko" # media cache
".local/share/nheko" # per-account state database
];
}

View File

@@ -1,7 +0,0 @@
{ config, lib, ... }:
{
# provides `nix-locate`, backed by the manually run `nix-index`
sane.programs.nix-index = {
persist.plaintext = [ ".cache/nix-index" ];
};
}

View File

@@ -1,4 +0,0 @@
{ ... }:
{
sane.programs.obsidian.mime.associations."text/markdown" = "obsidian.desktop";
}

View File

@@ -1,28 +0,0 @@
# 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" ];
};
}

View File

@@ -10,11 +10,13 @@
# XXX doesn't seem to understand ~ as shorthand for `$HOME`
history_file=/home/colin/.local/state/splatmoji/history
history_length=5
paste_command=${pkgs.wtype}/bin/wtype -M Ctrl -k v
# TODO: wayland equiv
paste_command=xdotool key ctrl+v
# rofi_command=${pkgs.wofi}/bin/wofi --dmenu --insensitive --cache-file /dev/null
rofi_command=${pkgs.fuzzel}/bin/fuzzel -d -i -w 60
xdotool_command=${pkgs.wtype}/bin/wtype
xsel_command=${pkgs.findutils}/bin/xargs ${pkgs.wl-clipboard}/bin/wl-copy
# TODO: wayland equiv
xsel_command=xsel -b -i
'';
};
}

View File

@@ -1,16 +0,0 @@
{ 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
};
}

View File

@@ -1,42 +0,0 @@
# Tangram is a GTK/webkit browser
# it views each tab as a distinct application, persisted, and where the 'home' button action is specific to each tab.
# it supports ephemeral tabs, but UX is heavily geared to GCing those as early as possible.
{ pkgs, ... }:
let
dconfProfile = pkgs.writeTextFile {
name = "dconf-tangram-profile";
destination = "/etc/dconf/profile/tangram";
text = ''
user-db:tangram
system-db:site
'';
};
in
{
sane.programs.tangram = {
# XXX(2023/07/08): running on moby without disabling the webkit sandbox fails, with:
# - `bwrap: Can't make symlink at /var/run: File exists`
# see epiphany.nix for more info
package = pkgs.tangram.overrideAttrs (upstream: {
preFixup = ''
gappsWrapperArgs+=(
--set WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS "1"
--set DCONF_PROFILE "${dconfProfile}/etc/dconf/profile/tangram"
);
'' + (upstream.preFixup or "");
});
persist.private = [
".cache/Tangram"
".local/share/Tangram"
# dconf achieves atomic writes via `mv`, so a symlink doesn't work
# moreover, i have to persist the *whole* directory:
# - `user-db:tangram/user` causes a schema failure
# - bind-mounting `~/private/.config/dconf/tangram` causes dconf to try a cross-fs `mv`, which fails
# - dconf provides no way to specify an alternate ~/.config/dconf dir, except by overriding XDG_CONFIG_HOME
# { type = "file"; path = ".config/dconf/tangram"; method = "bind"; }
".config/dconf"
];
};
}

View File

@@ -1,4 +0,0 @@
{ ... }:
{
sane.programs.tuba.suggestedPrograms = [ "gnome-keyring" ];
}

View File

@@ -10,13 +10,8 @@ let
in
{
sane.programs.vlc = {
persist.private = [
# vlc remembers play position in ~/.config/vlc/vlc-qt-interface.conf
# filenames are stored in plaintext (unlike mpv, which i think hashes them)
".config/vlc"
# vlc caches artwork. i'm not sure where it gets the artwork (internet? embedded metadata?)
".cache/vlc"
];
# vlc remembers play position in ~/.config/vlc/vlc-qt-interface.conf
persist.plaintext = [ ".config/vlc" ];
fs.".config/vlc/vlcrc".symlink.text = ''
[podcast]
podcast-urls=${podcast-urls}
@@ -25,13 +20,5 @@ in
[qt]
qt-privacy-ask=0
'';
mime.associations."audio/flac" = "vlc.desktop";
mime.associations."audio/mpeg" = "vlc.desktop";
mime.associations."audio/x-vorbis+ogg" = "vlc.desktop";
mime.associations."video/mp4" = "vlc.desktop";
mime.associations."video/quicktime" = "vlc.desktop";
mime.associations."video/webm" = "vlc.desktop";
mime.associations."video/x-matroska" = "vlc.desktop";
};
}

View File

@@ -9,20 +9,21 @@
{ config, lib, pkgs, ...}:
with lib;
let
cfg = config.sane.programs.firefox.config;
mobile-prefs = lib.optionals false pkgs.librewolf-pmos-mobile.extraPrefsFiles;
cfg = config.sane.programs.web-browser.config;
# allow easy switching between firefox and librewolf with `defaultSettings`, below
librewolfSettings = {
browser = pkgs.librewolf-unwrapped;
extraPrefsFiles = pkgs.librewolf-unwrapped.extraPrefsFiles ++ mobile-prefs;
# browser = pkgs.librewolf-unwrapped.overrideAttrs (drv: {
# # this allows side-loading unsigned addons
# MOZ_REQUIRE_SIGNING = false;
# });
libName = "librewolf";
dotDir = ".librewolf";
cacheDir = ".cache/librewolf";
cacheDir = ".cache/librewolf"; # TODO: is it?
desktop = "librewolf.desktop";
};
firefoxSettings = {
browser = pkgs.firefox-esr-unwrapped;
extraPrefsFiles = mobile-prefs;
libName = "firefox";
dotDir = ".mozilla/firefox";
cacheDir = ".cache/mozilla";
@@ -46,7 +47,8 @@ let
package = pkgs.wrapFirefox cfg.browser.browser {
# inherit the default librewolf.cfg
# it can be further customized via ~/.librewolf/librewolf.overrides.cfg
inherit (cfg.browser) extraPrefsFiles libName;
inherit (pkgs.librewolf-unwrapped) extraPrefsFiles;
inherit (cfg.browser) libName;
extraNativeMessagingHosts = optional cfg.addons.browserpass-extension.enable pkgs.browserpass;
# extraNativeMessagingHosts = [ pkgs.gopass-native-messaging-host ];
@@ -70,10 +72,7 @@ let
};
UserMessaging = {
ExtensionRecommendations = false;
FeatureRecommendations = false;
SkipOnboarding = true;
UrlbarInterventions = false;
WhatsNew = false;
};
# these were taken from Librewolf
@@ -145,62 +144,54 @@ in
{
config = mkMerge [
({
sane.programs.firefox.configOption = mkOption {
sane.programs.web-browser.configOption = mkOption {
type = types.submodule configOpts;
default = {};
};
sane.programs.firefox.config.addons = {
sane.programs.web-browser.config.addons = {
# get names from:
# - ~/ref/nix-community/nur-combined/repos/rycee/pkgs/firefox-addons/generated-firefox-addons.nix
# `wget ...xpi`; `unar ...xpi`; `cat */manifest.json | jq '.browser_specific_settings.gecko.id'`
browserpass-extension = {
package = pkgs.firefox-extensions.browserpass-extension;
enable = lib.mkDefault true;
};
bypass-paywalls-clean = {
package = pkgs.firefox-extensions.bypass-paywalls-clean;
# package = addon "browserpass-ce" "browserpass@maximbaz.com" "sha256-sXgUBbRvMnRpeIW1MTkmTcoqtW/8RDXAkxAq1evFkpc=";
package = localAddon pkgs.browserpass-extension;
enable = lib.mkDefault true;
};
# TODO: build bypass-paywalls from source? it's mysteriously disappeared from the Mozilla store.
# bypass-paywalls-clean.package = addon "bypass-paywalls-clean" "{d133e097-46d9-4ecc-9903-fa6a722a6e0e}" "sha256-oUwdqdAwV3DezaTtOMx7A/s4lzIws+t2f08mwk+324k=";
# bypass-paywalls-clean.enable = lib.mkDefault true;
ether-metamask = {
package = pkgs.firefox-extensions.ether-metamask;
enable = lib.mkDefault false; # until i can disable the first-run notification
package = addon "ether-metamask" "webextension@metamask.io" "sha256-G+MwJDOcsaxYSUXjahHJmkWnjLeQ0Wven8DU/lGeMzA=";
enable = lib.mkDefault true;
};
i2p-in-private-browsing = {
package = pkgs.firefox-extensions.i2p-in-private-browsing;
package = addon "i2p-in-private-browsing" "i2ppb@eyedeekay.github.io" "sha256-dJcJ3jxeAeAkRvhODeIVrCflvX+S4E0wT/PyYzQBQWs=";
enable = lib.mkDefault config.services.i2p.enable;
};
sidebery = {
package = pkgs.firefox-extensions.sidebery;
package = addon "sidebery" "{3c078156-979c-498b-8990-85f7987dd929}" "sha256-YONfK/rIjlsrTgRHIt3km07Q7KnpIW89Z9r92ZSCc6w=";
enable = lib.mkDefault true;
};
sponsorblock = {
package = pkgs.firefox-extensions.sponsorblock;
package = addon "sponsorblock" "sponsorBlocker@ajay.app" "sha256-hRsvLaAsVm3dALsTrJqHTNgRFAQcU7XSaGhr5G6+mFs=";
enable = lib.mkDefault true;
};
ublacklist = {
package = pkgs.firefox-extensions.ublacklist;
package = addon "ublacklist" "@ublacklist" "sha256-RqY5iHzbL2qizth7aguyOKWPyINXmrwOlf/OsfqAS48=";
enable = lib.mkDefault true;
};
ublock-origin = {
package = pkgs.firefox-extensions.ublock-origin;
package = addon "ublock-origin" "uBlock0@raymondhill.net" "sha256-eHlQrU/b9X/6sTbHBpGAd+0VsLT7IrVCnd0AQ948lyA=";
enable = lib.mkDefault true;
};
};
})
({
sane.programs.firefox = {
sane.programs.web-browser = {
inherit package;
mime.associations = let
inherit (cfg.browser) desktop;
in {
"text/html" = desktop;
"x-scheme-handler/http" = desktop;
"x-scheme-handler/https" = desktop;
"x-scheme-handler/about" = desktop;
"x-scheme-handler/unknown" = desktop;
};
# env.BROWSER = "${package}/bin/${cfg.browser.libName}";
env.BROWSER = cfg.browser.libName; # used by misc tools like xdg-email, as fallback
# uBlock filter list configuration.
# specifically, enable the GDPR cookie prompt blocker.
# data.toOverwrite.filterLists is additive (i.e. it supplements the default filters)
@@ -219,7 +210,6 @@ in
}
}
'';
# TODO: this is better suited in `extraPrefs` during `wrapFirefox` call
fs."${cfg.browser.dotDir}/${cfg.browser.libName}.overrides.cfg".symlink.text = ''
// if we can't query the revocation status of a SSL cert because the issuer is offline,
// treat it as unrevoked.
@@ -241,22 +231,16 @@ in
'';
};
})
(mkIf config.sane.programs.firefox.enabled {
(mkIf config.sane.programs.web-browser.enabled {
# TODO: move the persistence into the sane.programs API (above)
# flush the cache to disk to avoid it taking up too much tmp.
sane.user.persist.byPath."${cfg.browser.cacheDir}".store =
if (cfg.persistData != null) then
cfg.persistData
else
"cryptClearOnBoot"
;
# flush the cache to disk to avoid it taking up too much tmp
sane.user.persist.byPath."${cfg.browser.cacheDir}" = lib.mkIf (cfg.persistCache != null) {
store = cfg.persistCache;
};
sane.user.persist.byPath."${cfg.browser.dotDir}/default".store =
if (cfg.persistData != null) then
cfg.persistData
else
"cryptClearOnBoot"
;
sane.user.persist.byPath."${cfg.browser.dotDir}/default" = lib.mkIf (cfg.persistData != null) {
store = cfg.persistData;
};
})
];
}

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