programs: allow running binaries in a netns-style firejail

This commit is contained in:
Colin 2024-01-20 11:11:12 +00:00
parent 03fbf42680
commit 59187a0ec0
42 changed files with 114 additions and 53 deletions

View File

@ -15,7 +15,7 @@ in
}; };
}; };
package = pkgs.abaddon.overrideAttrs (upstream: { packageUnwrapped = pkgs.abaddon.overrideAttrs (upstream: {
patches = (upstream.patches or []) ++ [ patches = (upstream.patches or []) ++ [
(pkgs.fetchpatch { (pkgs.fetchpatch {
url = "https://git.uninsane.org/colin/abaddon/commit/eb551f188d34679f75adcbc83cb8d5beb4d19fd6.patch"; url = "https://git.uninsane.org/colin/abaddon/commit/eb551f188d34679f75adcbc83cb8d5beb4d19fd6.patch";

View File

@ -2,7 +2,7 @@
let let
declPackageSet = pkgs: { declPackageSet = pkgs: {
package = null; packageUnwrapped = null;
suggestedPrograms = pkgs; suggestedPrograms = pkgs;
}; };
in in
@ -239,7 +239,7 @@ in
fluffychat-moby.persist.byStore.plaintext = [ ".local/share/chat.fluffy.fluffychat" ]; fluffychat-moby.persist.byStore.plaintext = [ ".local/share/chat.fluffy.fluffychat" ];
font-manager.package = pkgs.font-manager.override { font-manager.packageUnwrapped = pkgs.font-manager.override {
# build without the "Google Fonts" integration feature, to save closure / avoid webkitgtk_4_0 # build without the "Google Fonts" integration feature, to save closure / avoid webkitgtk_4_0
withWebkit = false; withWebkit = false;
}; };
@ -262,7 +262,7 @@ in
# settings (electron app) # settings (electron app)
obsidian.persist.byStore.plaintext = [ ".config/obsidian" ]; obsidian.persist.byStore.plaintext = [ ".config/obsidian" ];
python3-repl.package = pkgs.python3.withPackages (ps: with ps; [ python3-repl.packageUnwrapped = pkgs.python3.withPackages (ps: with ps; [
requests requests
]); ]);

View File

@ -1,7 +1,7 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
sane.programs.audacity = { sane.programs.audacity = {
package = pkgs.audacity.override { packageUnwrapped = pkgs.audacity.override {
# wxGTK32 uses webkitgtk-4.0. # wxGTK32 uses webkitgtk-4.0.
# audacity doesn't actually need webkit though, so diable to reduce closure # audacity doesn't actually need webkit though, so diable to reduce closure
wxGTK32 = pkgs.wxGTK32.override { wxGTK32 = pkgs.wxGTK32.override {

View File

@ -87,7 +87,7 @@ let
in in
{ {
sane.programs.bemenu = { sane.programs.bemenu = {
package = pkgs.bemenu.overrideAttrs (upstream: { packageUnwrapped = pkgs.bemenu.overrideAttrs (upstream: {
nativeBuildInputs = (upstream.nativeBuildInputs or []) ++ [ nativeBuildInputs = (upstream.nativeBuildInputs or []) ++ [
pkgs.makeWrapper pkgs.makeWrapper
]; ];

View File

@ -1,8 +1,8 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
sane.programs.chatty = { sane.programs.chatty = {
# package = chattyNoOauth; # packageUnwrapped = chattyNoOauth;
package = pkgs.chatty-latest; packageUnwrapped = pkgs.chatty-latest;
suggestedPrograms = [ "gnome-keyring" ]; suggestedPrograms = [ "gnome-keyring" ];
persist.byStore.private = [ persist.byStore.private = [
".local/share/chatty" # matrix avatars and files ".local/share/chatty" # matrix avatars and files

View File

@ -56,6 +56,7 @@
./neovim.nix ./neovim.nix
./newsflash.nix ./newsflash.nix
./nheko.nix ./nheko.nix
./nicotine-plus.nix
./nix-index.nix ./nix-index.nix
./notejot.nix ./notejot.nix
./ntfy-sh.nix ./ntfy-sh.nix

View File

@ -1,7 +1,7 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
sane.programs.dialect = { sane.programs.dialect = {
package = pkgs.dialect.overrideAttrs (upstream: { packageUnwrapped = pkgs.dialect.overrideAttrs (upstream: {
# TODO: send upstream # TODO: send upstream
# TODO: figure out how to get audio working # TODO: figure out how to get audio working
# TODO: move to runtimeDependencies? # TODO: move to runtimeDependencies?

View File

@ -7,7 +7,7 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
sane.programs.element-desktop = { sane.programs.element-desktop = {
package = pkgs.element-desktop.override { packageUnwrapped = pkgs.element-desktop.override {
# use pre-build electron because otherwise it takes 4 hrs to build from source. # use pre-build electron because otherwise it takes 4 hrs to build from source.
electron = pkgs.electron-bin; electron = pkgs.electron-bin;
}; };

View File

@ -22,7 +22,7 @@
# #
# TODO: consider `WEBKIT_USE_SINGLE_WEB_PROCESS=1` for better perf # TODO: consider `WEBKIT_USE_SINGLE_WEB_PROCESS=1` for better perf
# - this runs all tabs in 1 process. which is fine, if i'm not a heavy multi-tabber # - this runs all tabs in 1 process. which is fine, if i'm not a heavy multi-tabber
package = pkgs.epiphany.overrideAttrs (upstream: { packageUnwrapped = pkgs.epiphany.overrideAttrs (upstream: {
preFixup = '' preFixup = ''
gappsWrapperArgs+=( gappsWrapperArgs+=(
--set WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS "1" --set WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS "1"

View File

@ -7,7 +7,7 @@ let
in in
{ {
sane.programs.feedbackd = { sane.programs.feedbackd = {
package = pkgs.rmDbusServices pkgs.feedbackd; packageUnwrapped = pkgs.rmDbusServices pkgs.feedbackd;
configOption = with lib; mkOption { configOption = with lib; mkOption {
type = types.submodule { type = types.submodule {

View File

@ -38,7 +38,7 @@ let
# defaultSettings = firefoxSettings; # defaultSettings = firefoxSettings;
defaultSettings = librewolfSettings; defaultSettings = librewolfSettings;
package = (pkgs.wrapFirefox cfg.browser.browser { packageUnwrapped = (pkgs.wrapFirefox cfg.browser.browser {
# inherit the default librewolf.cfg # inherit the default librewolf.cfg
# it can be further customized via ~/.librewolf/librewolf.overrides.cfg # it can be further customized via ~/.librewolf/librewolf.overrides.cfg
inherit (cfg.browser) extraPrefsFiles libName; inherit (cfg.browser) extraPrefsFiles libName;
@ -212,7 +212,7 @@ in
}) })
({ ({
sane.programs.firefox = { sane.programs.firefox = {
inherit package; inherit packageUnwrapped;
suggestedPrograms = [ suggestedPrograms = [
"open-in-mpv" "open-in-mpv"

View File

@ -62,8 +62,8 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
sane.programs.flare-signal = { sane.programs.flare-signal = {
package = pkgs.flare-signal-nixified; packageUnwrapped = pkgs.flare-signal-nixified;
# package = pkgs.flare-signal; # packageUnwrapped = pkgs.flare-signal;
persist.byStore.private = [ persist.byStore.private = [
# everything: conf, state, files, all opaque # everything: conf, state, files, all opaque
".local/share/flare" ".local/share/flare"

View File

@ -23,9 +23,9 @@ let
in in
{ {
sane.programs.fractal = { sane.programs.fractal = {
package = pkgs.fractal-nixified.optimized; packageUnwrapped = pkgs.fractal-nixified.optimized;
# package = pkgs.fractal-latest; # packageUnwrapped = pkgs.fractal-latest;
# package = pkgs.fractal-next; # packageUnwrapped = pkgs.fractal-next;
configOption = with lib; mkOption { configOption = with lib; mkOption {
default = {}; default = {};

View File

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

View File

@ -8,7 +8,7 @@ let
wanted-feeds = feeds.filterByFormat [ "podcast" "video" ] all-feeds; wanted-feeds = feeds.filterByFormat [ "podcast" "video" ] all-feeds;
in { in {
sane.programs.gpodder = { sane.programs.gpodder = {
package = pkgs.gpodder-adaptive-configured.overrideAttrs (base: { packageUnwrapped = pkgs.gpodder-adaptive-configured.overrideAttrs (base: {
# environment variables: # environment variables:
# - GPODDER_HOME (defaults to "~/gPodder") # - GPODDER_HOME (defaults to "~/gPodder")
# - GPODDER_DOWNLOAD_DIR (defaults to "$GPODDER_HOME/Downloads") # - GPODDER_DOWNLOAD_DIR (defaults to "$GPODDER_HOME/Downloads")
@ -19,7 +19,7 @@ in {
"--set" "GPODDER_HOME" "~/.local/share/gPodder" "--set" "GPODDER_HOME" "~/.local/share/gPodder"
]; ];
}); });
# package = pkgs.gpodder-configured; # packageUnwrapped = pkgs.gpodder-configured;
fs.".config/gpodderFeeds.opml".symlink.text = feeds.feedsToOpml wanted-feeds; fs.".config/gpodderFeeds.opml".symlink.text = feeds.feedsToOpml wanted-feeds;
# XXX: we preserve the whole thing because if we only preserve gPodder/Downloads # XXX: we preserve the whole thing because if we only preserve gPodder/Downloads

View File

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

View File

@ -17,7 +17,7 @@ in
}; };
}; };
package = pkgs.gtkcord4.overrideAttrs (upstream: { packageUnwrapped = pkgs.gtkcord4.overrideAttrs (upstream: {
postConfigure = (upstream.postConfigure or "") + '' postConfigure = (upstream.postConfigure or "") + ''
# gtkcord4 uses go-keyring to interface with the org.freedesktop.secrets provider (i.e. gnome-keyring). # gtkcord4 uses go-keyring to interface with the org.freedesktop.secrets provider (i.e. gnome-keyring).
# go-keyring hardcodes `login.keyring` as the keyring to store secrets in, instead of reading `~/.local/share/keyring/default`. # go-keyring hardcodes `login.keyring` as the keyring to store secrets in, instead of reading `~/.local/share/keyring/default`.

View File

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

View File

@ -2,10 +2,10 @@
{ {
sane.programs.jellyfin-media-player = { sane.programs.jellyfin-media-player = {
# package = pkgs.jellyfin-media-player; # packageUnwrapped = pkgs.jellyfin-media-player;
# qt6 version is slightly buggy, but also most qtwebengine apps (e.g. zeal) are on qt5 # 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. # so using qt6 would force yet *another* qtwebengine compile.
# package = pkgs.jellyfin-media-player-qt6; # packageUnwrapped = pkgs.jellyfin-media-player-qt6;
# jellyfin stores things in a bunch of directories: this one persists auth info. # jellyfin stores things in a bunch of directories: this one persists auth info.
# it *might* be possible to populate this externally (it's Qt stuff), but likely to # it *might* be possible to populate this externally (it's Qt stuff), but likely to

View File

@ -35,7 +35,7 @@ let
) wantedFeeds; ) wantedFeeds;
in { in {
sane.programs.koreader = { sane.programs.koreader = {
package = pkgs.koreader-from-src; packageUnwrapped = pkgs.koreader-from-src;
# koreader applies these lua "patches" at boot: # koreader applies these lua "patches" at boot:
# - <https://github.com/koreader/koreader/wiki/User-patches> # - <https://github.com/koreader/koreader/wiki/User-patches>
# the naming is IMPORTANT. these must start with a `2-` in order to be invoked during the right initialization phase # the naming is IMPORTANT. these must start with a `2-` in order to be invoked during the right initialization phase

View File

@ -2,9 +2,9 @@
{ {
sane.programs.libreoffice = { sane.programs.libreoffice = {
# package = pkgs.libreoffice-bin; # packageUnwrapped = pkgs.libreoffice-bin;
# package = pkgs.libreoffice-still; # packageUnwrapped = pkgs.libreoffice-still;
package = pkgs.libreoffice-fresh; packageUnwrapped = pkgs.libreoffice-fresh;
slowToBuild = true; slowToBuild = true;

View File

@ -4,7 +4,7 @@
{ {
sane.programs.mako = { sane.programs.mako = {
# we control mako as a systemd service, so have dbus not automatically activate it. # we control mako as a systemd service, so have dbus not automatically activate it.
package = pkgs.rmDbusServices pkgs.mako; packageUnwrapped = pkgs.rmDbusServices pkgs.mako;
fs.".config/mako/config".symlink.text = '' fs.".config/mako/config".symlink.text = ''
# notification interaction mapping # notification interaction mapping
# "on-touch" defaults to "dismiss", which isn't nice for touchscreens. # "on-touch" defaults to "dismiss", which isn't nice for touchscreens.

View File

@ -45,7 +45,7 @@ let
in in
{ {
sane.programs.mimeo = { sane.programs.mimeo = {
package = pkgs.mimeo.overridePythonAttrs (upstream: { packageUnwrapped = pkgs.mimeo.overridePythonAttrs (upstream: {
nativeBuildInputs = (upstream.nativeBuildInputs or []) ++ [ nativeBuildInputs = (upstream.nativeBuildInputs or []) ++ [
pkgs.copyDesktopItems pkgs.copyDesktopItems
]; ];

View File

@ -29,7 +29,7 @@ let
in in
{ {
sane.programs.mopidy = { sane.programs.mopidy = {
package = mopidyWithExtensions (with pkgs; [ packageUnwrapped = mopidyWithExtensions (with pkgs; [
mopidy-iris # web client: <https://github.com/jaedb/Iris> mopidy-iris # web client: <https://github.com/jaedb/Iris>
mopidy-jellyfin mopidy-jellyfin
mopidy-local mopidy-local

View File

@ -20,7 +20,7 @@ in
}; };
}; };
}; };
package = pkgs.wrapMpv pkgs.mpv-unwrapped { packageUnwrapped = pkgs.wrapMpv pkgs.mpv-unwrapped {
scripts = with pkgs.mpvScripts; [ scripts = with pkgs.mpvScripts; [
mpris mpris
uosc uosc

View File

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

View File

@ -86,8 +86,8 @@ let
in in
{ {
sane.programs.neovim = { sane.programs.neovim = {
# package = config.programs.neovim.finalPackage; # packageUnwrapped = config.programs.neovim.finalPackage;
package = pkgs.wrapNeovimUnstable pkgs.neovim-unwrapped (pkgs.neovimUtils.makeNeovimConfig { packageUnwrapped = pkgs.wrapNeovimUnstable pkgs.neovim-unwrapped (pkgs.neovimUtils.makeNeovimConfig {
withRuby = false; #< doesn't cross-compile w/o binfmt withRuby = false; #< doesn't cross-compile w/o binfmt
viAlias = true; viAlias = true;
vimAlias = true; vimAlias = true;

View File

@ -0,0 +1,10 @@
# soulseek filesharing GUI app
{ ... }:
{
sane.programs.nicotine-plus = {
net = "vpn";
# ".config/nicotine": contains the config file, with plaintext creds.
# TODO: define this as a secret instead of persisting it.
persist.byStore.private = [ ".config/nicotine" ];
};
}

View File

@ -21,7 +21,7 @@ in
}; };
}; };
package = pkgs.signal-desktop-from-src; packageUnwrapped = pkgs.signal-desktop-from-src;
# creds, media # creds, media
persist.byStore.private = [ persist.byStore.private = [

View File

@ -2,7 +2,7 @@
{ {
sane.programs.sublime-music = { sane.programs.sublime-music = {
package = pkgs.sublime-music-mobile; packageUnwrapped = pkgs.sublime-music-mobile;
# sublime music persists any downloaded albums here. # sublime music persists any downloaded albums here.
# it doesn't obey a conventional ~/Music/{Artist}/{Album}/{Track} notation, so no symlinking # it doesn't obey a conventional ~/Music/{Artist}/{Album}/{Track} notation, so no symlinking
# config (e.g. server connection details) is persisted in ~/.config/sublime-music/config.json # config (e.g. server connection details) is persisted in ~/.config/sublime-music/config.json

View File

@ -23,7 +23,7 @@ in
}; };
}; };
package = pkgs.static-nix-shell.mkBash { packageUnwrapped = pkgs.static-nix-shell.mkBash {
pname = "sway-autoscaler"; pname = "sway-autoscaler";
pkgs = [ "jq" "sway" "util-linux" ]; pkgs = [ "jq" "sway" "util-linux" ];
src = ./.; src = ./.;

View File

@ -116,7 +116,7 @@ in
default = {}; default = {};
}; };
# prevent dbus from automatically activating swaync so i can manage it as a systemd service instead # prevent dbus from automatically activating swaync so i can manage it as a systemd service instead
package = pkgs.rmDbusServices (pkgs.swaynotificationcenter.overrideAttrs (upstream: { packageUnwrapped = pkgs.rmDbusServices (pkgs.swaynotificationcenter.overrideAttrs (upstream: {
# allow toggle buttons: # allow toggle buttons:
patches = (upstream.patches or []) ++ [ patches = (upstream.patches or []) ++ [
# (pkgs.fetchpatch { # (pkgs.fetchpatch {

View File

@ -18,7 +18,7 @@ in
# XXX(2023/07/08): running on moby without disabling the webkit sandbox fails, with: # XXX(2023/07/08): running on moby without disabling the webkit sandbox fails, with:
# - `bwrap: Can't make symlink at /var/run: File exists` # - `bwrap: Can't make symlink at /var/run: File exists`
# see epiphany.nix for more info # see epiphany.nix for more info
package = pkgs.tangram.overrideAttrs (upstream: { packageUnwrapped = pkgs.tangram.overrideAttrs (upstream: {
preFixup = '' preFixup = ''
gappsWrapperArgs+=( gappsWrapperArgs+=(
--set WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS "1" --set WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS "1"

View File

@ -1,7 +1,7 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
sane.programs.tor-browser-bundle-bin = { sane.programs.tor-browser-bundle-bin = {
package = pkgs.tor-browser-bundle-bin.override { packageUnwrapped = pkgs.tor-browser-bundle-bin.override {
# hardenedMalloc solves an "unable to connect to Tor" error when pressing the "connect" button # hardenedMalloc solves an "unable to connect to Tor" error when pressing the "connect" button
# - still required as of 2023/07/14 # - still required as of 2023/07/14
useHardenedMalloc = false; useHardenedMalloc = false;

View File

@ -1,6 +1,6 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
sane.programs.xarchiver.package = pkgs.xarchiver.override { sane.programs.xarchiver.packageUnwrapped = pkgs.xarchiver.override {
# unar doesn't cross compile well, so disable support for it # unar doesn't cross compile well, so disable support for it
unar = null; unar = null;
}; };

View File

@ -13,8 +13,8 @@ let
}; };
in { in {
sane.programs.zeal = { sane.programs.zeal = {
# package = pkgs.zeal-qt6; #< TODO: upgrade system to qt6 versions of everything (i.e. jellyfin-media-player, nheko) # packageUnwrapped = pkgs.zeal-qt6; #< TODO: upgrade system to qt6 versions of everything (i.e. jellyfin-media-player, nheko)
package = pkgs.zeal-qt5; packageUnwrapped = pkgs.zeal-qt5;
slowToBuild = true; slowToBuild = true;
persist.byStore.plaintext = [ persist.byStore.plaintext = [
".cache/Zeal" ".cache/Zeal"
@ -29,7 +29,7 @@ in {
type = configOpts; type = configOpts;
default = {}; default = {};
}; };
package = pkgs.symlinkJoin { packageUnwrapped = pkgs.symlinkJoin {
name = "docsets"; name = "docsets";
# build each package with rust docs # build each package with rust docs
paths = map (name: paths = map (name:

View File

@ -1,7 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
declPackageSet = pkgs: { declPackageSet = pkgs: {
package = null; packageUnwrapped = null;
suggestedPrograms = pkgs; suggestedPrograms = pkgs;
}; };
in in
@ -162,6 +162,7 @@ in
"monero-gui" # x86-only "monero-gui" # x86-only
"mumble" "mumble"
# "nheko" # Matrix chat client # "nheko" # Matrix chat client
"nicotine-plus" # soulseek client
# "obsidian" # "obsidian"
"openscad" # 3d modeling "openscad" # 3d modeling
# "rhythmbox" # local music player # "rhythmbox" # local music player

View File

@ -23,7 +23,7 @@ in
config = mkMerge [ config = mkMerge [
{ {
sane.programs.phoshApps = { sane.programs.phoshApps = {
package = null; packageUnwrapped = null;
suggestedPrograms = [ suggestedPrograms = [
"guiApps" "guiApps"
# TODO: see about removing gnome-bluetooth if the in-built gnome-settings bluetooth manager can work # TODO: see about removing gnome-bluetooth if the in-built gnome-settings bluetooth manager can work

View File

@ -169,7 +169,7 @@ in
config = lib.mkMerge [ config = lib.mkMerge [
{ {
sane.programs.swayApps = { sane.programs.swayApps = {
package = null; packageUnwrapped = null;
suggestedPrograms = [ suggestedPrograms = [
"guiApps" "guiApps"
"conky" # for a nice background "conky" # for a nice background

View File

@ -262,7 +262,7 @@ in
config = lib.mkMerge [ config = lib.mkMerge [
{ {
sane.programs.sxmoApps = { sane.programs.sxmoApps = {
package = null; packageUnwrapped = null;
suggestedPrograms = [ suggestedPrograms = [
"guiApps" "guiApps"
"bemenu" # specifically to import its theming "bemenu" # specifically to import its theming

View File

@ -31,9 +31,33 @@ let
) (mkDefaultEnables pkgSpecs) pkgSpecs; ) (mkDefaultEnables pkgSpecs) pkgSpecs;
mkDefaultEnables = lib.mapAttrs (_pname: _pval: { system = false; user = {}; }); mkDefaultEnables = lib.mapAttrs (_pname: _pval: { system = false; user = {}; });
defaultEnables = solveDefaultEnableFor cfg; defaultEnables = solveDefaultEnableFor cfg;
# wrap a package so that its binaries (maybe) run in a sandbox
wrapPkg = { net }: package: (
if net == "clearnet" then
package
else if net == "vpn" then
# TODO: update the package's `.desktop` files to ensure they exec the sandboxed app.
pkgs.symlinkJoin {
inherit (package) name;
paths = [ package ];
postBuild = ''
for p in $(ls "$out/bin/"); do
unlink "$out/bin/$p"
cat <<EOF >> "$out/bin/$p"
#!/bin/sh
exec ${pkgs.sane-scripts.vpn}/bin/sane-vpn do default "${package}/bin/$p" "\$@"
EOF
chmod +x "$out/bin/$p"
done
'';
}
else
throw "unknown net type '${net}'"
);
pkgSpec = with lib; types.submodule ({ config, name, ... }: { pkgSpec = with lib; types.submodule ({ config, name, ... }: {
options = { options = {
package = mkOption { packageUnwrapped = mkOption {
type = types.nullOr types.package; type = types.nullOr types.package;
description = '' description = ''
package, or `null` if the program is some sort of meta set (in which case it much EXPLICITLY be set null). package, or `null` if the program is some sort of meta set (in which case it much EXPLICITLY be set null).
@ -48,6 +72,13 @@ let
# a valid source explicitly. # a valid source explicitly.
lib.getAttrFromPath pkgPath pkgs; lib.getAttrFromPath pkgPath pkgs;
}; };
package = mkOption {
type = types.nullOr types.package;
description = ''
assigned internally.
this is `packageUnwrapped`, but with the binaries possibly wrapped in sandboxing measures.
'';
};
enableFor.system = mkOption { enableFor.system = mkOption {
type = types.bool; type = types.bool;
default = defaultEnables."${name}".system; default = defaultEnables."${name}".system;
@ -161,6 +192,15 @@ let
marking packages like this can be used to achieve faster, but limited, rebuilds/deploys (by omitting the package). marking packages like this can be used to achieve faster, but limited, rebuilds/deploys (by omitting the package).
''; '';
}; };
net = mkOption {
type = types.enum [ "clearnet" "vpn" ];
default = "clearnet";
description = ''
how this app should have its network traffic routed.
- "clearnet" for unsandboxed network.
- "vpn" to route all traffic over the default VPN.
'';
};
configOption = mkOption { configOption = mkOption {
type = types.raw; type = types.raw;
default = mkOption { default = mkOption {
@ -181,6 +221,11 @@ let
passesSlowTest = saneCfg.enableSlowPrograms || !config.slowToBuild; passesSlowTest = saneCfg.enableSlowPrograms || !config.slowToBuild;
in { in {
enabled = (config.enableFor.system || enabledForUser) && passesSlowTest; enabled = (config.enableFor.system || enabledForUser) && passesSlowTest;
package = if config.packageUnwrapped == null then
null
else
wrapPkg { inherit (config) net; } config.packageUnwrapped
;
}; };
}); });
toPkgSpec = with lib; types.coercedTo types.package (p: { package = p; }) pkgSpec; toPkgSpec = with lib; types.coercedTo types.package (p: { package = p; }) pkgSpec;

View File

@ -17,6 +17,10 @@ get_vpns() {
} }
canonicalize_region() { canonicalize_region() {
if [ "$region" = "default" ]; then
# TODO: don't special-case this, but e.g. grab whichever VPN has the lowest `ip rule` priority.
region="us"
fi
if networkctl list "br-$region"; then if networkctl list "br-$region"; then
bridge="br-$region" bridge="br-$region"
elif networkctl list "br-ovpnd-$region"; then elif networkctl list "br-ovpnd-$region"; then