+# Extend the Nix interpreter to enable builtins.extraBuiltins,
+# which provides an unsafe exec.
+# Useful to get secrets from a local password-store.
{ config, lib, pkgs, ... }:
-with lib;
-let cfg = config.nix-plugins;
+let
+ cfg = config.nix-plugins;
+ inherit (lib) types;
+
+ /*
+ # Wrapper around nix to load extra-builtins.nix with nix-plugins.
+ nix-with-extra-builtins = pkgs.writeShellScriptBin "nix-with-extra-builtins" ''
+ ${pkgs.nix}/bin/nix \
+ --option plugin-files ${pkgs.nix-plugins}/lib/nix/plugins/libnix-extra-builtins.so \
+ --option extra-builtins-file ${cfg.extra-builtins} \
+ "$@"
+ '';
+ */
+
+ # Wrapper around pass to call it with exec in extra-builtins.nix.
+ # Unfortunately it can only load secrets which can be represented as a Nix string,
+ # hence without null-byte and such special characters.
+ # FIXME: make a nix-pass-chomp
+ nix-pass = pkgs.writeShellScript "nix-pass" ''
+ set -e
+ f=$(mktemp)
+ trap "shred -u $f" EXIT
+ ${pkgs.pass}/bin/pass show "$1" >"$f"
+ nix-instantiate --eval -E "builtins.readFile $f"
+ '';
+ # Like nix-pass but remove the trailing spaces and newlines at the end of the content.
+ nix-pass-chomp = pkgs.writeShellScript "nix-pass-chomp" ''
+ set -e
+ f=$(mktemp)
+ trap "shred -u $f" EXIT
+ pass="$(${pkgs.pass}/bin/pass show "$1")"
+ printf %s "$pass" >"$f"
+ nix-instantiate --eval -E "builtins.readFile $f"
+ '';
+
+ # Wrapper around pass to call it with exec in extra-builtins.nix and put the output in a file.
+ # Needed for boot.initrd.network.ssh.host*Key.
+ nix-pass-to-file = pkgs.writeShellScript "nix-pass-to-file" ''
+ set -e
+ set -o pipefail
+ ${pkgs.pass}/bin/pass show "$1" |
+ install -D -m 400 /dev/stdin "$2"
+ printf '%s\n' "$2"
+ '';
+
+ # Wrapper around pass to call it with exec in extra-builtins.nix and put the output in a file.
+ # Needed for boot.initrd.network.ssh.host*Key.
+
+ # Wrapper around git to call it with exec in extra-builtins.nix.
+ nix-git = pkgs.writeShellScript "nix-git" ''
+ cd "$1"; shift
+ ${pkgs.git}/bin/git "$@"
+ '';
in
{
options.nix-plugins = {
enable = lib.mkEnableOption "nix-plugins";
- extra-builtins = mkOption {
+ extra-builtins = lib.mkOption {
type = types.lines;
default = ''
- pass = path: exec [ "${config.nix-plugins.nix-pass}/bin/nix-pass" path ];
- pass-to-file = path: file: exec [ "${config.nix-plugins.nix-pass-to-file}/bin/nix-pass-to-file" path file ];
- git = dir: args: exec ([ "${config.nix-plugins.nix-git}/bin/nix-git" (builtins.toPath dir) ] ++ args);
- git-time = dir: path: exec [ "${config.nix-plugins.nix-git}/bin/nix-git" (builtins.toPath dir) "log" "-1" "--format=%ct" "--" path ];
+ pass = path: exec [ "${nix-pass}" path ];
+ pass-chomp = path: exec [ "${nix-pass-chomp}" path ];
+ pass-to-file = path: name: exec [ "${nix-pass-to-file}" path name ];
+ git = dir: args: exec ([ "${nix-git}" dir ] ++ args);
+ git-time = dir: path: exec [ "${nix-git}" dir "log" "-1" "--format=%ct" "--" path ];
+ gpg = args: exec ([ "${pkgs.gnupg}/bin/gpg" ] ++ args);
'';
description = ''
Content put in extra-builtins.nix for nix-plugins.
apply = lines: pkgs.writeText "extra-builtins.nix" (''
{ exec, ... }:
{
- '' + lines + ''
+ '' + lines + ''
}
- '');
- };
-
- nix-with-extra-builtins = mkOption {
- type = types.str;
- apply = pkgs.writeShellScriptBin "nix-with-extra-builtins";
- default = ''
- ${pkgs.nix}/bin/nix \
- --option plugin-files ${pkgs.nix-plugins}/lib/nix/plugins/libnix-extra-builtins.so \
- --option extra-builtins-file ${cfg.extra-builtins} \
- "$@"
- '';
- description = ''
- Wrapper around nix to load extra-builtins.nix with nix-plugins.
- '';
- };
-
- nix-pass = mkOption {
- type = types.str;
- apply = pkgs.writeShellScriptBin "nix-pass";
- default = ''
- set -e
- f=$(mktemp)
- trap "shred -u $f" EXIT
- ${pkgs.pass}/bin/pass show "$1" >$f
- nix-instantiate --eval -E "builtins.readFile $f"
- '';
- /*
- nix-store --add $f
- */
- /*
- set -o pipefail
- ${pkgs.pass}/bin/pass show "$1" |
- ${pkgs.gnused}/bin/sed \
- -e 's:\n:\\n:g;s:\r:\\r:g;s:\t:\\t:g;s:":\\":g;1s:^:":;$s:$:":;'
- */
- description = ''
- Wrapper around pass to call it with exec in extra-builtins.nix.
- Unfortunately it can only load secrets which can be represented as a Nix string,
- hence without null-byte and such special characters.
- '';
- };
-
- nix-pass-to-file = mkOption {
- type = types.str;
- apply = pkgs.writeShellScriptBin "nix-pass-to-file";
- default = ''
- set -e
- set -o pipefail
- ${pkgs.pass}/bin/pass show "$1" |
- install -D -m 400 /dev/stdin "$2"
- printf '%s\n' "$PWD/$2"
- '';
- description = ''
- Wrapper around pass to call it with exec in extra-builtins.nix and put the output in a file.
- Needed for boot.initrd.network.ssh.host*Key.
- '';
- };
-
- nix-git = mkOption {
- type = types.str;
- apply = pkgs.writeShellScriptBin "nix-git";
- default = ''
- cd "$1"; shift
- ${pkgs.git}/bin/git "$@"
- '';
- description = ''
- Wrapper around git to call it with exec in extra-builtins.nix.
- '';
+ '');
};
};
+ config = lib.mkIf cfg.enable {
+ nix.enable = true;
+ nix.nixConf = ''
+ plugin-files = ${pkgs.nix-plugins}/lib/nix/plugins/libnix-extra-builtins.so
+ extra-builtins-file = ${cfg.extra-builtins}
+ '';
+ };
}