diff --git a/hosts/by-name/servo/services/cryptocurrencies/bitcoin.nix b/hosts/by-name/servo/services/cryptocurrencies/bitcoin.nix index b2ca2d396..a31045689 100644 --- a/hosts/by-name/servo/services/cryptocurrencies/bitcoin.nix +++ b/hosts/by-name/servo/services/cryptocurrencies/bitcoin.nix @@ -22,7 +22,7 @@ let _bitcoindWithExternalIp = pkgs.writeShellScriptBin "bitcoind" '' set -xeu externalip="$(cat /var/lib/tor/onion/bitcoind/hostname)" - exec ${bitcoind}/bin/bitcoind "-externalip=$externalip" "$@" + exec ${lib.getExe' bitcoind "bitcoind"} "-externalip=$externalip" "$@" ''; # the package i provide to services.bitcoind ends up on system PATH, and used by other tools like clightning. # therefore, even though services.bitcoind only needs `bitcoind` binary, provide all the other bitcoin-related binaries (notably `bitcoin-cli`) as well: diff --git a/hosts/by-name/servo/services/cryptocurrencies/clightning.nix b/hosts/by-name/servo/services/cryptocurrencies/clightning.nix index bad71805f..b35fe8439 100644 --- a/hosts/by-name/servo/services/cryptocurrencies/clightning.nix +++ b/hosts/by-name/servo/services/cryptocurrencies/clightning.nix @@ -124,7 +124,7 @@ # peerswap: # - config example: # XXX: peerswap crashes clightning on launch. stacktrace is useless. - # plugin={pkgs.peerswap}/bin/peerswap + # plugin={lib.getExe' pkgs.peerswap "peerswap"} # peerswap-db-path=/var/lib/clightning/peerswap/swaps # peerswap-policy-path=... ''; diff --git a/hosts/by-name/servo/services/ejabberd.nix b/hosts/by-name/servo/services/ejabberd.nix index a85db2eb9..26012a112 100644 --- a/hosts/by-name/servo/services/ejabberd.nix +++ b/hosts/by-name/servo/services/ejabberd.nix @@ -457,13 +457,12 @@ lib.mkIf false mod_version = {}; }; }); - sed = "${pkgs.gnused}/bin/sed"; in '' ip=$(cat '${config.sane.services.dyn-dns.ipPath}') # config is 444 (not 644), so we want to write out-of-place and then atomically move # TODO: factor this out into `sane-woop` helper? rm -f /var/lib/ejabberd/ejabberd.yaml.new - ${sed} "s/%ANATIVE%/$ip/g" ${config-in} > /var/lib/ejabberd/ejabberd.yaml.new + ${lib.getExe pkgs.gnused} "s/%ANATIVE%/$ip/g" ${config-in} > /var/lib/ejabberd/ejabberd.yaml.new mv /var/lib/ejabberd/ejabberd.yaml{.new,} ''; diff --git a/hosts/by-name/servo/services/export/sftpgo/default.nix b/hosts/by-name/servo/services/export/sftpgo/default.nix index 04f6c3893..6266c3ee2 100644 --- a/hosts/by-name/servo/services/export/sftpgo/default.nix +++ b/hosts/by-name/servo/services/export/sftpgo/default.nix @@ -141,7 +141,7 @@ in }; data_provider = { driver = "memory"; - external_auth_hook = "${external_auth_hook}/bin/external_auth_hook"; + external_auth_hook = lib.getExe external_auth_hook; # track_quota: # - 0: disable quota tracking # - 1: quota is updated on every upload/delete, even if user has no quota restriction diff --git a/hosts/by-name/servo/services/gitea.nix b/hosts/by-name/servo/services/gitea.nix index 18d78a0fb..b47bf276c 100644 --- a/hosts/by-name/servo/services/gitea.nix +++ b/hosts/by-name/servo/services/gitea.nix @@ -86,7 +86,7 @@ ENABLED = true; FROM = "notify.git@uninsane.org"; PROTOCOL = "sendmail"; - SENDMAIL_PATH = "${pkgs.postfix}/bin/sendmail"; + SENDMAIL_PATH = lib.getExe' pkgs.postfix "sendmail"; SENDMAIL_ARGS = "--"; # most "sendmail" programs take options, "--" will prevent an email address being interpreted as an option. }; time = { diff --git a/hosts/by-name/servo/services/goaccess.nix b/hosts/by-name/servo/services/goaccess.nix index 9c3a0238e..71d2c091c 100644 --- a/hosts/by-name/servo/services/goaccess.nix +++ b/hosts/by-name/servo/services/goaccess.nix @@ -11,7 +11,7 @@ lib.mkIf false #< 2024/09/30: disabled because i haven't used it in several mon description = "GoAccess server monitoring"; serviceConfig = { ExecStart = '' - ${pkgs.goaccess}/bin/goaccess \ + ${lib.getExe pkgs.goaccess} \ -f /var/log/nginx/public.log \ --log-format=VCOMBINED \ --real-time-html \ @@ -23,7 +23,7 @@ lib.mkIf false #< 2024/09/30: disabled because i haven't used it in several mon --port=7890 \ -o /var/lib/goaccess/index.html ''; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + ExecReload = "${lib.getExe' pkgs.coreutils "kill"} -HUP $MAINPID"; Type = "simple"; Restart = "on-failure"; RestartSec = "10s"; diff --git a/hosts/by-name/servo/services/jackett/default.nix b/hosts/by-name/servo/services/jackett/default.nix index 22caa2556..cbc904d3a 100644 --- a/hosts/by-name/servo/services/jackett/default.nix +++ b/hosts/by-name/servo/services/jackett/default.nix @@ -18,7 +18,7 @@ in serviceConfig.ExecStartPre = [ "${lib.getExe pkgs.sane-scripts.ip-check} --no-upnp --expect ${config.sane.netns.ovpns.netnsPubIpv4}" ]; # abort if public IP is not as expected # patch in `--ListenPublic` so that it's reachable from the netns veth. # this also makes it reachable from the VPN pub address. oh well. - serviceConfig.ExecStart = lib.mkForce "${cfg.package}/bin/Jackett --ListenPublic --NoUpdates --DataFolder '${cfg.dataDir}'"; + serviceConfig.ExecStart = lib.mkForce "${lib.getExe' cfg.package "Jackett"} --ListenPublic --NoUpdates --DataFolder '${cfg.dataDir}'"; serviceConfig.RestartSec = "30s"; # hardening (systemd-analyze security jackett) diff --git a/hosts/by-name/servo/services/lemmy.nix b/hosts/by-name/servo/services/lemmy.nix index 07f380997..31f482ddb 100644 --- a/hosts/by-name/servo/services/lemmy.nix +++ b/hosts/by-name/servo/services/lemmy.nix @@ -144,7 +144,7 @@ in { # CLI args: systemd.services.pict-rs = { serviceConfig.ExecStart = lib.mkForce (lib.concatStringsSep " " [ - "${lib.getBin pict-rs}/bin/pict-rs run" + (lib.getExe pict-rs) "--media-video-max-frame-count" (builtins.toString (30*60*60)) "--media-process-timeout 120" "--media-video-allow-audio" # allow audio diff --git a/hosts/by-name/servo/services/matrix/default.nix b/hosts/by-name/servo/services/matrix/default.nix index e7e275e3c..bedccf2da 100644 --- a/hosts/by-name/servo/services/matrix/default.nix +++ b/hosts/by-name/servo/services/matrix/default.nix @@ -71,20 +71,20 @@ in ]; systemd.services.matrix-synapse.postStart = lib.optionalString ntfy '' - ACCESS_TOKEN=$(${pkgs.coreutils}/bin/cat ${config.sops.secrets.matrix_access_token.path}) - TOPIC=$(${pkgs.coreutils}/bin/cat ${config.sops.secrets.ntfy-sh-topic.path}) + ACCESS_TOKEN=$(${lib.getExe' pkgs.coreutils "cat"} ${config.sops.secrets.matrix_access_token.path}) + TOPIC=$(${lib.getExe' pkgs.coreutils "cat"} ${config.sops.secrets.ntfy-sh-topic.path}) echo "ensuring ntfy push gateway" - ${pkgs.curl}/bin/curl \ + ${lib.getExe pkgs.curl} \ --header "Authorization: Bearer $ACCESS_TOKEN" \ --data "{ \"app_display_name\": \"ntfy-adapter\", \"app_id\": \"ntfy.uninsane.org\", \"data\": { \"url\": \"https://ntfy.uninsane.org/_matrix/push/v1/notify\", \"format\": \"event_id_only\" }, \"device_display_name\": \"ntfy-adapter\", \"kind\": \"http\", \"lang\": \"en-US\", \"profile_tag\": \"\", \"pushkey\": \"$TOPIC\" }" \ localhost:8008/_matrix/client/v3/pushers/set echo "registered push gateways:" - ${pkgs.curl}/bin/curl \ + ${lib.getExe pkgs.curl} \ --header "Authorization: Bearer $ACCESS_TOKEN" \ localhost:8008/_matrix/client/v3/pushers \ - | ${pkgs.jq}/bin/jq . + | ${lib.getExe pkgs.jq} . ''; diff --git a/hosts/by-name/servo/services/nginx.nix b/hosts/by-name/servo/services/nginx.nix index 9cb59c317..f7d19e5f9 100644 --- a/hosts/by-name/servo/services/nginx.nix +++ b/hosts/by-name/servo/services/nginx.nix @@ -235,7 +235,7 @@ in # to accept it. system.activationScripts.generate-x509-self-signed.text = '' mkdir -p /var/www/certs/wildcard - test -f /var/www/certs/wildcard/key.pem || ${pkgs.openssl}/bin/openssl \ + test -f /var/www/certs/wildcard/key.pem || ${lib.getExe pkgs.openssl} \ req -x509 -newkey rsa:4096 \ -keyout /var/www/certs/wildcard/key.pem \ -out /var/www/certs/wildcard/cert.pem \ diff --git a/hosts/by-name/servo/services/ntfy/ntfy-sh.nix b/hosts/by-name/servo/services/ntfy/ntfy-sh.nix index 3dce05429..91448d0cd 100644 --- a/hosts/by-name/servo/services/ntfy/ntfy-sh.nix +++ b/hosts/by-name/servo/services/ntfy/ntfy-sh.nix @@ -59,7 +59,7 @@ lib.mkIf false #< 2024/09/30: disabled because i haven't used it in several mon # note that this will fail upon first run, i.e. before ntfy has created its db. # just restart the service. topic=$(cat ${config.sops.secrets.ntfy-sh-topic.path}) - ${pkgs.ntfy-sh}/bin/ntfy access everyone "$topic" read-write + ${lib.getExe' pkgs.ntfy-sh "ntfy"} access everyone "$topic" read-write ''; diff --git a/hosts/by-name/servo/services/ntfy/ntfy-waiter.nix b/hosts/by-name/servo/services/ntfy/ntfy-waiter.nix index a97a01bea..77bb5c0c1 100644 --- a/hosts/by-name/servo/services/ntfy/ntfy-waiter.nix +++ b/hosts/by-name/servo/services/ntfy/ntfy-waiter.nix @@ -14,7 +14,7 @@ let silence = port - portLow; flags = lib.optional cfg.verbose "--verbose"; cli = [ - "${cfg.package}/bin/ntfy-waiter" + (lib.getExe cfg.package) "--port" "${builtins.toString port}" "--silence" diff --git a/hosts/by-name/servo/services/pleroma.nix b/hosts/by-name/servo/services/pleroma.nix index d51dc1f49..04ecfbc59 100644 --- a/hosts/by-name/servo/services/pleroma.nix +++ b/hosts/by-name/servo/services/pleroma.nix @@ -46,7 +46,7 @@ in config :pleroma, Pleroma.Emails.Mailer, enabled: true, adapter: Swoosh.Adapters.Sendmail, - cmd_path: "${pkgs.postfix}/bin/sendmail" + cmd_path: "${lib.getExe' pkgs.postfix "sendmail"}" config :pleroma, Pleroma.User, restricted_nicknames: [ "admin", "uninsane", "root" ] diff --git a/hosts/by-name/servo/services/prosody/default.nix b/hosts/by-name/servo/services/prosody/default.nix index 05909c34d..e6e2417ca 100644 --- a/hosts/by-name/servo/services/prosody/default.nix +++ b/hosts/by-name/servo/services/prosody/default.nix @@ -279,7 +279,7 @@ in -- s2s_require_encryption = true -- c2s_require_encryption = true '' + lib.optionalString config.services.ntfy-sh.enable '' - ntfy_binary = "${pkgs.ntfy-sh}/bin/ntfy" + ntfy_binary = "${lib.getExe' pkgs.ntfy-sh "ntfy"}" ntfy_topic = readAll("/run/secrets/ntfy-sh-topic") ''; }; diff --git a/hosts/by-name/servo/services/transmission/default.nix b/hosts/by-name/servo/services/transmission/default.nix index 1b126fb27..2586e77f7 100644 --- a/hosts/by-name/servo/services/transmission/default.nix +++ b/hosts/by-name/servo/services/transmission/default.nix @@ -104,7 +104,7 @@ in # - TR_TORRENT_NAME - Name of torrent (not filename) # - TR_TORRENT_TRACKERS - A comma-delimited list of the torrent's trackers' announce URLs script-torrent-done-enabled = true; - script-torrent-done-filename = "${torrent-done}/bin/torrent-done"; + script-torrent-done-filename = lib.getExe torrent-done; }; systemd.services.transmission = { @@ -138,7 +138,7 @@ in systemd.services.backup-torrents = { description = "archive torrents to storage not owned by transmission"; script = '' - ${pkgs.rsync}/bin/rsync -arv /var/lib/transmission/.config/transmission-daemon/torrents/ /var/backup/torrents/ + ${lib.getExe pkgs.rsync} -arv /var/lib/transmission/.config/transmission-daemon/torrents/ /var/backup/torrents/ ''; }; systemd.timers.backup-torrents = { diff --git a/hosts/common/boot.nix b/hosts/common/boot.nix index 761b06666..a384bd41f 100644 --- a/hosts/common/boot.nix +++ b/hosts/common/boot.nix @@ -3,13 +3,12 @@ boot.initrd.supportedFilesystems = [ "ext4" "btrfs" "ext2" "ext3" "vfat" ]; # useful emergency utils boot.initrd.extraUtilsCommands = '' - copy_bin_and_libs ${pkgs.btrfs-progs}/bin/btrfstune - copy_bin_and_libs ${pkgs.util-linux}/bin/{cfdisk,lsblk,lscpu} - copy_bin_and_libs ${pkgs.gptfdisk}/bin/{cgdisk,gdisk} - copy_bin_and_libs ${pkgs.smartmontools}/bin/smartctl - copy_bin_and_libs ${pkgs.e2fsprogs}/bin/resize2fs - '' + lib.optionalString pkgs.stdenv.hostPlatform.isx86_64 '' - copy_bin_and_libs ${pkgs.nvme-cli}/bin/nvme # doesn't cross compile + copy_bin_and_libs ${lib.getExe' pkgs.btrfs-progs "btrfstune"} + copy_bin_and_libs ${lib.getExe' pkgs.util-linux "{cfdisk,lsblk,lscpu}"} + copy_bin_and_libs ${lib.getExe' pkgs.gptfdisk "{cgdisk,gdisk}"} + copy_bin_and_libs ${lib.getExe' pkgs.smartmontools "smartctl"} + copy_bin_and_libs ${lib.getExe' pkgs.e2fsprogs "resize2fs"} + copy_bin_and_libs ${lib.getExe pkgs.nvme-cli} ''; boot.kernelParams = [ "boot.shell_on_fail" diff --git a/hosts/common/home/mime.nix b/hosts/common/home/mime.nix index 5499126c4..493253253 100644 --- a/hosts/common/home/mime.nix +++ b/hosts/common/home/mime.nix @@ -58,14 +58,14 @@ let mkdir -p $out/share/applications for i in $(cat $pathsPath); do if [ -e "$i/share/applications" ]; then - ${pkgs.buildPackages.xorg.lndir}/bin/lndir -silent $i/share/applications $out/share/applications + ${lib.getExe pkgs.buildPackages.xorg.lndir} -silent $i/share/applications $out/share/applications fi done runHook postBuild ''; postBuild = '' # rebuild `mimeinfo.cache`, used by file openers to show the list of *all* apps, not just the user's defaults. - ${pkgs.buildPackages.desktop-file-utils}/bin/update-desktop-database $out/share/applications + ${lib.getExe' pkgs.buildPackages.desktop-file-utils "update-desktop-database"} $out/share/applications ''; }); diff --git a/hosts/common/programs/avahi.nix b/hosts/common/programs/avahi.nix index 21c8ec074..4e342e61a 100644 --- a/hosts/common/programs/avahi.nix +++ b/hosts/common/programs/avahi.nix @@ -59,13 +59,13 @@ in networking.firewall.extraCommands = lib.mkIf cfg.enabled (with pkgs; '' # after an outgoing mDNS query to the multicast address, open FW for incoming responses. # ipset -! means "don't fail if set already exists" - ${ipset}/bin/ipset create -! mdns hash:ip,port timeout 10 - ${iptables}/bin/iptables -A OUTPUT -d 239.255.255.250/32 -p udp -m udp --dport 5353 -j SET --add-set mdns src,src --exist - ${iptables}/bin/iptables -A INPUT -p udp -m set --match-set mdns dst,dst -j ACCEPT + ${lib.getExe' ipset "ipset"} create -! mdns hash:ip,port timeout 10 + ${lib.getExe' iptables "iptables"} -A OUTPUT -d 239.255.255.250/32 -p udp -m udp --dport 5353 -j SET --add-set mdns src,src --exist + ${lib.getExe' iptables "iptables"} -A INPUT -p udp -m set --match-set mdns dst,dst -j ACCEPT # IPv6 ruleset. ff02::/16 means *any* link-local multicast group (so this is probably more broad than it needs to be) - ${ipset}/bin/ipset create -! mdns6 hash:ip,port timeout 10 family inet6 - ${iptables}/bin/ip6tables -A OUTPUT -d ff02::/16 -p udp -m udp --dport 5353 -j SET --add-set mdns6 src,src --exist - ${iptables}/bin/ip6tables -A INPUT -p udp -m set --match-set mdns6 dst,dst -j ACCEPT + ${lib.getExe' ipset "ipset"} create -! mdns6 hash:ip,port timeout 10 family inet6 + ${lib.getExe' iptables "ip6tables"} -A OUTPUT -d ff02::/16 -p udp -m udp --dport 5353 -j SET --add-set mdns6 src,src --exist + ${lib.getExe' iptables "ip6tables"} -A INPUT -p udp -m set --match-set mdns6 dst,dst -j ACCEPT ''); systemd.services.avahi-daemon = lib.mkIf cfg.enabled { diff --git a/hosts/common/programs/brightnessctl.nix b/hosts/common/programs/brightnessctl.nix index 959a4524e..a87d0e635 100644 --- a/hosts/common/programs/brightnessctl.nix +++ b/hosts/common/programs/brightnessctl.nix @@ -13,8 +13,8 @@ in }; services.udev.extraRules = let - chmod = "${pkgs.coreutils}/bin/chmod"; - chown = "${pkgs.coreutils}/bin/chown"; + chmod = lib.getExe' pkgs.coreutils "chmod"; + chown = lib.getExe' pkgs.coreutils "chown"; in lib.mkIf cfg.enabled '' # make backlight controllable by members of `video` SUBSYSTEM=="backlight", RUN+="${chown} :video $sys$devpath/brightness", RUN+="${chmod} g+w $sys$devpath/brightness" diff --git a/hosts/common/programs/eg25-control.nix b/hosts/common/programs/eg25-control.nix index 7f71f123c..6ca5d01a0 100644 --- a/hosts/common/programs/eg25-control.nix +++ b/hosts/common/programs/eg25-control.nix @@ -49,7 +49,7 @@ in # - eg25-control-gps: moves new/ into cache/ # - but it moved the result (possibly incomplete) of eg25-control-freshen-agps, incorrectly # in practice, i don't expect much issue from this. - ExecStart = "${cfg.package}/bin/eg25-control --ensure-agps-cache --verbose"; + ExecStart = "${lib.getExe cfg.package} --ensure-agps-cache --verbose"; Restart = "no"; User = "colin"; @@ -61,8 +61,8 @@ in }; services.udev.extraRules = let - chmod = "${pkgs.coreutils}/bin/chmod"; - chown = "${pkgs.coreutils}/bin/chown"; + chmod = lib.getExe' pkgs.coreutils "chmod"; + chown = lib.getExe' pkgs.coreutils "chown"; in lib.optionalString cfg.enabled '' # make Modem controllable by user DRIVER=="modem-power", RUN+="${chmod} g+w /sys%p/powered", RUN+="${chown} :networkmanager /sys%p/powered" diff --git a/hosts/common/programs/firefox/default.nix b/hosts/common/programs/firefox/default.nix index ff9f8ddc2..10a953601 100644 --- a/hosts/common/programs/firefox/default.nix +++ b/hosts/common/programs/firefox/default.nix @@ -91,7 +91,7 @@ let echo "unzipping omni.ja" # N.B. `zip` exits non-zero even on successful extraction, if the file didn't 100% obey spec - ${pkgs.buildPackages.unzip}/bin/unzip $out/lib/${cfg.browser.libName}/browser/omni.ja -d omni || true + ${lib.getExe pkgs.buildPackages.unzip} $out/lib/${cfg.browser.libName}/browser/omni.ja -d omni || true echo "removing old omni.ja" rm $out/lib/${cfg.browser.libName}/browser/omni.ja @@ -105,7 +105,7 @@ let ${lib.getExe pkgs.buildPackages.gnused} -i s'/command="cmd_close" modifiers="accel"/command="cmd_close" modifiers="accel,shift"/' omni/chrome/browser/content/browser/browser.xhtml echo "re-zipping omni.ja" - pushd omni; ${pkgs.buildPackages.zip}/bin/zip $out/lib/${cfg.browser.libName}/browser/omni.ja -r ./*; popd + pushd omni; ${lib.getExe pkgs.buildPackages.zip} $out/lib/${cfg.browser.libName}/browser/omni.ja -r ./*; popd echo "omni.ja AFTER:" ls -l $out/lib/${cfg.browser.libName}/browser/omni.ja diff --git a/hosts/common/programs/fontconfig.nix b/hosts/common/programs/fontconfig.nix index ccf55a0da..3ecf39148 100644 --- a/hosts/common/programs/fontconfig.nix +++ b/hosts/common/programs/fontconfig.nix @@ -40,7 +40,7 @@ let cache = (pkgs.makeFontsCache { fontDirectories = config.fonts.packages; }).overrideAttrs (upstream: { buildCommand = lib.replaceStrings [ "fc-cache" ] - [ "${pkgs.stdenv.hostPlatform.emulator pkgs.buildPackages} ${pkgs.fontconfig.bin}/bin/fc-cache" ] + [ "${pkgs.stdenv.hostPlatform.emulator pkgs.buildPackages} ${lib.getExe' pkgs.fontconfig.bin "fc-cache"}" ] upstream.buildCommand ; }); diff --git a/hosts/common/programs/git.nix b/hosts/common/programs/git.nix index e93e4b0dc..3798967d6 100644 --- a/hosts/common/programs/git.nix +++ b/hosts/common/programs/git.nix @@ -54,7 +54,7 @@ in # - diff.tool = "difftastic"; difftool.prompt = false; - "difftool \"difftastic\"".cmd = ''${pkgs.difftastic}/bin/difft "$LOCAL" "$REMOTE"''; + "difftool \"difftastic\"".cmd = ''${lib.getExe pkgs.difftastic} "$LOCAL" "$REMOTE"''; # now run `git difftool` to use difftastic git # render dates as YYYY-MM-DD HH:MM:SS +TZ diff --git a/hosts/common/programs/gnome-keyring/default.nix b/hosts/common/programs/gnome-keyring/default.nix index 25fb26bc7..bd24eeb7d 100644 --- a/hosts/common/programs/gnome-keyring/default.nix +++ b/hosts/common/programs/gnome-keyring/default.nix @@ -1,5 +1,5 @@ # TODO: gnome-keyring has portal integration? ($out/share/xdg-desktop-portal) -{ pkgs, ... }: +{ lib, pkgs, ... }: { sane.programs.gnome-keyring = { packageUnwrapped = pkgs.rmDbusServices pkgs.gnome-keyring; @@ -53,7 +53,7 @@ mkdir -m 0700 -p $XDG_RUNTIME_DIR/keyring exec gnome-keyring-daemon --start --foreground --components=secrets ''; - in "${gkr-start}/bin/gnome-keyring-daemon-start"; + in lib.getExe gkr-start; }; }; } diff --git a/hosts/common/programs/mako.nix b/hosts/common/programs/mako.nix index 545e135be..46e6329e7 100644 --- a/hosts/common/programs/mako.nix +++ b/hosts/common/programs/mako.nix @@ -54,7 +54,7 @@ services.mako = { description = "mako desktop notification daemon"; partOf = [ "graphical-session" ]; - command = "${config.sane.programs.mako.package}/bin/mako"; + command = lib.getExe config.sane.programs.mako.package; }; }; } diff --git a/hosts/common/programs/mimeo/default.nix b/hosts/common/programs/mimeo/default.nix index ffd697a8d..ed4d5fb6a 100644 --- a/hosts/common/programs/mimeo/default.nix +++ b/hosts/common/programs/mimeo/default.nix @@ -22,7 +22,7 @@ let enabledPrograms; fmtAssoc = regex: desktop: '' - ${mimeo-open-desktop}/bin/mimeo-open-desktop ${desktop} %U + ${lib.getExe mimeo-open-desktop} ${desktop} %U ${regex} ''; assocs = builtins.map @@ -31,10 +31,10 @@ let assocs' = lib.flatten assocs; fmtFallbackAssoc = mimeType: desktop: if mimeType == "x-scheme-handler/http" then '' - ${mimeo-open-desktop}/bin/mimeo-open-desktop ${desktop} %U + ${lib.getExe mimeo-open-desktop} ${desktop} %U ^http://.* '' else if mimeType == "x-scheme-handler/https" then '' - ${mimeo-open-desktop}/bin/mimeo-open-desktop ${desktop} %U + ${lib.getExe mimeo-open-desktop} ${desktop} %U ^https://.* '' else ""; fmtFallbackAssoc' = mimeType: desktop: diff --git a/hosts/common/programs/mopidy.nix b/hosts/common/programs/mopidy.nix index bc3da0ebf..3c6b49d6f 100644 --- a/hosts/common/programs/mopidy.nix +++ b/hosts/common/programs/mopidy.nix @@ -22,7 +22,7 @@ let pathsToLink = [ "/${mopidyPackages.python.sitePackages}" ]; nativeBuildInputs = [ makeWrapper ]; postBuild = '' - makeWrapper ${mopidy}/bin/mopidy $out/bin/mopidy \ + makeWrapper ${lib.getExe mopidy} $out/bin/mopidy \ --prefix PYTHONPATH : $out/${mopidyPackages.python.sitePackages} ''; }; diff --git a/hosts/common/programs/ntfy-sh.nix b/hosts/common/programs/ntfy-sh.nix index 207ea4a62..c99e448ae 100644 --- a/hosts/common/programs/ntfy-sh.nix +++ b/hosts/common/programs/ntfy-sh.nix @@ -32,7 +32,7 @@ in topic=$(cat ~/.config/ntfy-sh/topic) exec ntfy sub "https://ntfy.uninsane.org:2587/$topic" ''; - in "${sub}/bin/ntfy-sub"; + in lib.getExe sub; }; }; } diff --git a/hosts/common/programs/sane-input-handler/default.nix b/hosts/common/programs/sane-input-handler/default.nix index 7b1c76256..acfe48d49 100644 --- a/hosts/common/programs/sane-input-handler/default.nix +++ b/hosts/common/programs/sane-input-handler/default.nix @@ -117,7 +117,7 @@ in # after = [ "graphical-session.target" ]; # wantedBy = [ "graphical-session.target" ]; - # serviceConfig.ExecStart = "${config.sane.programs.actkbd.package}/bin/actkbd -c /home/colin/.config/actkbd/actkbd.conf"; + # serviceConfig.ExecStart = "${lib.getExe config.sane.programs.actkbd.package} -c /home/colin/.config/actkbd/actkbd.conf"; # }; # }; diff --git a/hosts/common/programs/seatd.nix b/hosts/common/programs/seatd.nix index 2ac5be1c9..2b8ad4ebe 100644 --- a/hosts/common/programs/seatd.nix +++ b/hosts/common/programs/seatd.nix @@ -54,7 +54,7 @@ lib.mkMerge [ restartIfChanged = false; serviceConfig.Type = "simple"; - serviceConfig.ExecStart = "${cfg.package}/bin/seatd -g seat --bunpen-debug=4"; + serviceConfig.ExecStart = "${lib.getExe cfg.package} -g seat --bunpen-debug=4"; serviceConfig.Group = "seat"; # serviceConfig.AmbientCapabilities = [ # "CAP_DAC_OVERRIDE" diff --git a/hosts/common/programs/shadow.nix b/hosts/common/programs/shadow.nix index 231440bd9..0f71ae8fa 100644 --- a/hosts/common/programs/shadow.nix +++ b/hosts/common/programs/shadow.nix @@ -10,7 +10,7 @@ in }; } (lib.mkIf cfg.enabled { - services.getty.loginProgram = "${cfg.package}/bin/login"; + services.getty.loginProgram = lib.getExe' cfg.package "login"; security.pam.services.login.startSession = lib.mkForce false; #< disable systemd integration }) ]; diff --git a/hosts/common/programs/splatmoji.nix b/hosts/common/programs/splatmoji.nix index e84bb2cf4..81f5b28d2 100644 --- a/hosts/common/programs/splatmoji.nix +++ b/hosts/common/programs/splatmoji.nix @@ -1,7 +1,7 @@ # borrows from: # - default config: # - wayland: -{ pkgs, ... }: +{ lib, pkgs, ... }: { sane.programs.splatmoji = { @@ -33,9 +33,9 @@ # XXX: hardcode the package paths here. all these packages are sandboxed identically # to `splatmoji` itself, so there's zero benefit to acquiring them via the environment; # doing so would in fact be costlier. - paste_command=${pkgs.wtype}/bin/wtype -M Ctrl -k v - xdotool_command=${pkgs.wtype}/bin/wtype - xsel_command=${pkgs.findutils}/bin/xargs ${pkgs.wl-clipboard}/bin/wl-copy + paste_command=${lib.getExe pkgs.wtype} -M Ctrl -k v + xdotool_command=${lib.getExe pkgs.wtype} + xsel_command=${lib.getExe' pkgs.findutils "xargs"} ${lib.getExe' pkgs.wl-clipboard "wl-copy"} ''; # alternative tweaks: # rofi_command=${pkgs.wofi}/bin/wofi --dmenu --insensitive --cache-file /dev/null diff --git a/hosts/common/programs/sway/default.nix b/hosts/common/programs/sway/default.nix index 8be770632..56aec1ea6 100644 --- a/hosts/common/programs/sway/default.nix +++ b/hosts/common/programs/sway/default.nix @@ -18,7 +18,7 @@ let # (consider: nested sway sessions, where sway actually has a reason to read these) exec env -u DISPLAY -u WAYLAND_DISPLAY \ "DESIRED_WAYLAND_DISPLAY=$WAYLAND_DISPLAY" \ - ${configuredSway}/bin/sway \ + ${lib.getExe configuredSway} \ 2>&1 ''; in diff --git a/hosts/common/programs/swayidle.nix b/hosts/common/programs/swayidle.nix index c9890adf7..260302ad1 100644 --- a/hosts/common/programs/swayidle.nix +++ b/hosts/common/programs/swayidle.nix @@ -69,7 +69,7 @@ in # XXX: this turns the screen/touch off, and then there's no way to turn it back ON # unless you've configured that elsewhere (e.g. sane-input-handler) enable = lib.mkDefault false; - command = "${screenOff}/bin/screen-off"; + command = lib.getExe screenOff; delay = lib.mkDefault 1500; # 1500s = 25min }; config.actions.lock = { diff --git a/hosts/common/programs/waybar/waybar-top.nix b/hosts/common/programs/waybar/waybar-top.nix index 9c4686edf..4937fbac3 100644 --- a/hosts/common/programs/waybar/waybar-top.nix +++ b/hosts/common/programs/waybar/waybar-top.nix @@ -39,7 +39,7 @@ in # # N.B.: for this to behave well with multiple MPRIS clients, # `playerctld` must be enabled. see: - exec = "${waybar-media}/bin/waybar-media"; + exec = lib.getExe waybar-media; return-type = "json"; interval = 2; format = "{icon}{}"; diff --git a/hosts/common/programs/zsh/starship.nix b/hosts/common/programs/zsh/starship.nix index 67d568ee9..0f914e7dc 100644 --- a/hosts/common/programs/zsh/starship.nix +++ b/hosts/common/programs/zsh/starship.nix @@ -18,7 +18,7 @@ let in { sane.programs.zsh.fs = lib.mkIf enabled { ".config/zsh/.zshrc".symlink.text = '' - eval "$(${pkgs.starship}/bin/starship init zsh)" + eval "$(${lib.getExe pkgs.starship} init zsh)" ''; ".config/starship.toml".symlink.target = let x1b = builtins.fromJSON '' "\u001b" ''; # i.e `^[` diff --git a/hosts/modules/hal/pine64-pinephone/default.nix b/hosts/modules/hal/pine64-pinephone/default.nix index 5880a9880..6e2b46922 100644 --- a/hosts/modules/hal/pine64-pinephone/default.nix +++ b/hosts/modules/hal/pine64-pinephone/default.nix @@ -123,8 +123,8 @@ in }; services.udev.extraRules = let - chmod = "${pkgs.coreutils}/bin/chmod"; - chown = "${pkgs.coreutils}/bin/chown"; + chmod = lib.getExe' pkgs.coreutils "chmod"; + chown = lib.getExe' pkgs.coreutils "chown"; in '' # make Pinephone flashlight writable by user. # taken from postmarketOS: @@ -135,9 +135,9 @@ in ''; systemd.services.unl0kr.preStart = let - dmesg = "${pkgs.util-linux}/bin/dmesg"; - grep = "${pkgs.gnugrep}/bin/grep"; - modprobe = "${pkgs.kmod}/bin/modprobe"; + dmesg = lib.getExe' pkgs.util-linux "dmesg"; + grep = lib.getExe pkgs.gnugrep; + modprobe = lib.getExe' pkgs.kmod "modprobe"; in '' # common boot failure: # blank screen (no backlight even), with the following log: diff --git a/hosts/modules/wg-home.nix b/hosts/modules/wg-home.nix index 40ed12b5b..cb9446c4d 100644 --- a/hosts/modules/wg-home.nix +++ b/hosts/modules/wg-home.nix @@ -92,10 +92,10 @@ in } // (lib.optionalAttrs cfg.forwardToWan { # documented here: postSetup = '' - ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING --source ${cfg.ip}/24 ! --destination ${cfg.ip}/24 -j MASQUERADE + ${lib.getExe' pkgs.iptables "iptables"} -t nat -A POSTROUTING --source ${cfg.ip}/24 ! --destination ${cfg.ip}/24 -j MASQUERADE ''; postShutdown = '' - ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING --source ${cfg.ip}/24 ! --destination ${cfg.ip}/24 -j MASQUERADE + ${lib.getExe' pkgs.iptables "iptables"} -t nat -D POSTROUTING --source ${cfg.ip}/24 ! --destination ${cfg.ip}/24 -j MASQUERADE ''; })); diff --git a/modules/ports.nix b/modules/ports.nix index fe49edc4c..8db8f071e 100644 --- a/modules/ports.nix +++ b/modules/ports.nix @@ -49,7 +49,7 @@ let RestartSec = "3min"; ExecStart = let - portFwd = "${pkgs.sane-scripts.ip-port-forward}/bin/sane-ip-port-forward"; + portFwd = lib.getExe pkgs.sane-scripts.ip-port-forward; forwards = builtins.map (proto: "${proto}:${port}:${portCfg.description}") portCfg.protocol; in '' ${portFwd} -v -d ${builtins.toString cfg.upnpLeaseDuration} \ diff --git a/modules/services/clightning.nix b/modules/services/clightning.nix index 5a39f5fdb..e56277ff7 100644 --- a/modules/services/clightning.nix +++ b/modules/services/clightning.nix @@ -149,7 +149,7 @@ in requires = [ "bitcoind-${cfg.bitcoindName}.service" ]; after = [ "bitcoind-${cfg.bitcoindName}.service" ]; - serviceConfig.ExecStart = "${cfg.package}/bin/lightningd --lightning-dir=${cfg.dataDir}"; + serviceConfig.ExecStart = "${lib.getExe' cfg.package "lightningd"} --lightning-dir=${cfg.dataDir}"; serviceConfig.User = cfg.user; serviceConfig.Restart = "always"; serviceConfig.RestartSec = "30s"; diff --git a/modules/services/dropbear.nix b/modules/services/dropbear.nix index e0623a253..0f9485f0b 100644 --- a/modules/services/dropbear.nix +++ b/modules/services/dropbear.nix @@ -31,7 +31,7 @@ in serviceConfig.Type = "simple"; # N.B.: dropbear ssh key format is incompatible with OpenSSH's. # also, needs to be manually generated on first run (`dropbearkey -t rsa -f /etc/ssh/host_keys/dropbear_rsa_host_key -s 4096`) - serviceConfig.ExecStart = "${cfg.package}/bin/dropbear -F -p ${builtins.toString cfg.port} -r /etc/ssh/host_keys/dropbear_rsa_host_key -r /etc/ssh/host_keys/dropbear_ed25519_host_key"; + serviceConfig.ExecStart = "${lib.getExe' cfg.package "dropbear"} -F -p ${builtins.toString cfg.port} -r /etc/ssh/host_keys/dropbear_rsa_host_key -r /etc/ssh/host_keys/dropbear_ed25519_host_key"; }; }; } diff --git a/modules/services/dyn-dns.nix b/modules/services/dyn-dns.nix index 89f0747f8..f68f0b4c5 100644 --- a/modules/services/dyn-dns.nix +++ b/modules/services/dyn-dns.nix @@ -6,8 +6,8 @@ let getIp = pkgs.writeShellScript "dyn-dns-query-wan" '' # preferred method and fallback # OPNsense router broadcasts its UPnP endpoint every 30s - timeout 60 ${pkgs.sane-scripts.ip-check}/bin/sane-ip-check --json || \ - ${pkgs.sane-scripts.ip-check}/bin/sane-ip-check --json --no-upnp + timeout 60 ${lib.getExe pkgs.sane-scripts.ip-check} --json || \ + ${lib.getExe pkgs.sane-scripts.ip-check} --json --no-upnp ''; in { @@ -63,8 +63,8 @@ in before = cfg.restartOnChange; script = let - jq = "${pkgs.jq}/bin/jq"; - sed = "${pkgs.gnused}/bin/sed"; + jq = lib.getExe pkgs.jq; + sed = lib.getExe pkgs.gnused; in '' mkdir -p "$(dirname '${cfg.ipPath}')" mkdir -p "$(dirname '${cfg.upnpPath}')" @@ -113,8 +113,8 @@ in description = "react to the system's WAN IP changing"; serviceConfig.Type = "oneshot"; script = if cfg.restartOnChange != [] then '' - ${pkgs.systemd}/bin/systemctl restart ${toString cfg.restartOnChange} - '' else "${pkgs.coreutils}/bin/true"; + ${lib.getExe' pkgs.systemd "systemctl"} restart ${toString cfg.restartOnChange} + '' else lib.getExe' pkgs.coreutils "true"; }; }; } diff --git a/modules/services/eg25-manager.nix b/modules/services/eg25-manager.nix index 3e3398fc3..db810be9d 100644 --- a/modules/services/eg25-manager.nix +++ b/modules/services/eg25-manager.nix @@ -27,10 +27,10 @@ in systemd.services.eg25-manager = { serviceConfig = { Type = "simple"; - ExecStart = "${cfg.package}/bin/eg25-manager --config ${eg25-config-toml}"; + ExecStart = "${lib.getExe cfg.package} --config ${eg25-config-toml}"; ExecStartPre = pkgs.writeShellScript "unload-modem-power" '' # see issue: - ${pkgs.kmod}/bin/modprobe -r modem_power && echo "WARNING: kernel configured with CONFIG_MODEM_POWER=y, may be incompatible with eg25-manager" || true + ${lib.getExe' pkgs.kmod "modprobe"} -r modem_power && echo "WARNING: kernel configured with CONFIG_MODEM_POWER=y, may be incompatible with eg25-manager" || true ''; Restart = "on-failure"; @@ -61,7 +61,7 @@ in # wantedBy = [ "eg25-manager.service" ]; # before = [ "eg25-manager.service" ]; # script = '' - # ${pkgs.kmod}/bin/modprobe -r modem_power && echo "WARNING: kernel configured with CONFIG_MODEM_POWER=y, may be incompatible with eg25-manager" || true + # ${lib.getExe' pkgs.kmod "modprobe"} -r modem_power && echo "WARNING: kernel configured with CONFIG_MODEM_POWER=y, may be incompatible with eg25-manager" || true # ''; # }; }; diff --git a/modules/services/hickory-dns/default.nix b/modules/services/hickory-dns/default.nix index 402b84abe..0b4e0a8a5 100644 --- a/modules/services/hickory-dns/default.nix +++ b/modules/services/hickory-dns/default.nix @@ -96,7 +96,7 @@ let }); mkSystemdService = flavor: { includes, listenAddrsIpv4, listenAddrsIpv6, port, substitutions, extraConfig, ... }: let - sed = "${pkgs.gnused}/bin/sed"; + sed = lib.getExe pkgs.gnused; baseConfig = ( lib.filterAttrsRecursive (_: v: v != null) config.services.hickory-dns.settings ) // { @@ -292,7 +292,7 @@ in # run a hook whenever networking details change, so the DNS zone can be updated to reflect this environment.etc."NetworkManager/dispatcher.d/60-hickory-dns-nmhook" = lib.mkIf cfg.asSystemResolver { - source = "${hickory-dns-nmhook}/bin/hickory-dns-nmhook"; + source = lib.getExe hickory-dns-nmhook; }; # allow NetworkManager (via hickory-dns-nmhook) to restart hickory-dns when necessary diff --git a/modules/services/kiwix-serve.nix b/modules/services/kiwix-serve.nix index 305c7da9b..6e23e4d6d 100644 --- a/modules/services/kiwix-serve.nix +++ b/modules/services/kiwix-serve.nix @@ -44,7 +44,7 @@ in args = maybeListenAddress ++ ["-p" cfg.port] ++ cfg.zimPaths; in { description = "Deliver ZIM file(s) articles via HTTP"; - serviceConfig.ExecStart = "${cfg.package}/bin/kiwix-serve ${lib.escapeShellArgs args}"; + serviceConfig.ExecStart = "${lib.getExe' cfg.package "kiwix-serve"} ${lib.escapeShellArgs args}"; serviceConfig.Type = "simple"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; diff --git a/modules/users/default.nix b/modules/users/default.nix index 6de2350ca..a4b473e21 100644 --- a/modules/users/default.nix +++ b/modules/users/default.nix @@ -116,7 +116,7 @@ let config = { readiness.waitCommand = lib.mkMerge [ (lib.mkIf (config.readiness.waitDbus != null) - ''${pkgs.systemdMinimal}/bin/busctl --user status "${config.readiness.waitDbus}" > /dev/null'' + ''${lib.getExe' pkgs.systemdMinimal "busctl"} --user status "${config.readiness.waitDbus}" > /dev/null'' ) (lib.mkIf (config.readiness.waitExists != []) # e.g.: test -e /foo -a -e /bar diff --git a/pkgs/by-name/crust-firmware-pinephone/package.nix b/pkgs/by-name/crust-firmware-pinephone/package.nix index 16c40cfe4..66d190ee6 100644 --- a/pkgs/by-name/crust-firmware-pinephone/package.nix +++ b/pkgs/by-name/crust-firmware-pinephone/package.nix @@ -35,7 +35,7 @@ stdenv.mkDerivation (finalAttrs: { ]); # postPatch = '' - # substituteInPlace Makefile --replace "= lex" '= ${buildPackages.flex}/bin/flex' + # substituteInPlace Makefile --replace "= lex" '= ${lib.getExe' buildPackages.flex "flex"}' # ''; env.CROSS_COMPILE = "or1k-elf-"; diff --git a/pkgs/by-name/feeds/template.nix b/pkgs/by-name/feeds/template.nix index dd0240ef3..e18e6b08a 100644 --- a/pkgs/by-name/feeds/template.nix +++ b/pkgs/by-name/feeds/template.nix @@ -1,7 +1,8 @@ -{ lib -, stdenv -, fetchurl -, update-feed +{ + lib, + stdenv, + fetchurl, + update-feed, }: # feed-specific args @@ -14,7 +15,7 @@ stdenv.mkDerivation { inherit url; }; passthru.updateScript = [ - "${update-feed}/bin/update.py" url jsonPath + (lib.getExe update-feed) url jsonPath ]; meta = { description = "metadata about any feeds available at ${feedName}"; diff --git a/pkgs/by-name/koreader-from-src/package.nix b/pkgs/by-name/koreader-from-src/package.nix index cb8b27662..b8dbe1e6c 100644 --- a/pkgs/by-name/koreader-from-src/package.nix +++ b/pkgs/by-name/koreader-from-src/package.nix @@ -436,11 +436,11 @@ stdenv.mkDerivation (finalAttrs: with finalAttrs; let ''; symlinkThirdpartyBins = outdir: '' - ln -sf "${lib.getBin dropbear}/bin/dropbear" "${outdir}/dropbear" - ln -sf "${lib.getExe gnutar}" "${outdir}/tar" - ln -sf "${lib.getBin openssh}/libexec/sftp-server" "${outdir}/sftp-server" - ln -sf "${lib.getBin sdcv}/bin/sdcv" "${outdir}/sdcv" - ln -sf "${lib.getBin zsync}/bin/zsync" "${outdir}/zsync2" + ln -sf ${lib.getExe' dropbear "dropbear"} ${outdir}/dropbear + ln -sf ${lib.getExe gnutar} ${outdir}/tar + ln -sf ${lib.getBin openssh}/libexec/sftp-server ${outdir}/sftp-server + ln -sf ${lib.getExe sdcv} ${outdir}/sdcv + ln -sf ${lib.getExe' zsync "zsync"} ${outdir}/zsync2 ''; in { pname = "koreader-from-src"; diff --git a/pkgs/by-name/mcg/package.nix b/pkgs/by-name/mcg/package.nix index 47402aa42..ecaf42b07 100644 --- a/pkgs/by-name/mcg/package.nix +++ b/pkgs/by-name/mcg/package.nix @@ -27,7 +27,7 @@ stdenv.mkDerivation rec { postPatch = '' substituteInPlace src/meson.build \ - --replace-fail "python.find_installation('python3').full_path()" "'${pythonEnv}/bin/python3'" + --replace-fail "python.find_installation('python3').full_path()" "'${lib.getExe pythonEnv}'" ''; nativeBuildInputs = [ diff --git a/pkgs/by-name/phog/package.nix b/pkgs/by-name/phog/package.nix index e9b7d739a..887a842a9 100644 --- a/pkgs/by-name/phog/package.nix +++ b/pkgs/by-name/phog/package.nix @@ -70,7 +70,7 @@ stdenv.mkDerivation rec { ''; - mesonFlags = [ "-Dcompositor=${phoc}/bin/phoc" ]; + mesonFlags = [ "-Dcompositor=${lib.getExe phoc}" ]; depsBuildBuild = [ pkg-config diff --git a/pkgs/by-name/signal-desktop-from-src/package.nix b/pkgs/by-name/signal-desktop-from-src/package.nix index 8aa628090..c026eb5a5 100644 --- a/pkgs/by-name/signal-desktop-from-src/package.nix +++ b/pkgs/by-name/signal-desktop-from-src/package.nix @@ -362,7 +362,7 @@ buildNpmPackage rec { # electron should auto-detect x11 v.s. wayland: launching with `NIXOS_OZONE_WL=1` is an optional way to force it when debugging. # xdg-utils: needed for ozone-platform-hint=auto to work # else `LaunchProcess: failed to execvp: xdg-settings` - makeShellWrapper ${electron'}/bin/electron $out/bin/signal-desktop \ + makeShellWrapper ${lib.getExe electron'} $out/bin/signal-desktop \ "''${gappsWrapperArgs[@]}" \ --add-flags $out/lib/Signal/resources/app.asar \ --suffix PATH : ${lib.makeBinPath [ xdg-utils ]} \