Compare commits
23 commits
master
...
release-21
Author | SHA1 | Date | |
---|---|---|---|
d93d56ab8c | |||
d14adb99f3 | |||
5eb2102aef | |||
834d863dd2 | |||
236c6ec214 | |||
e997bf4c98 | |||
7244c6715c | |||
7049cf37a9 | |||
ef6799c1ce | |||
0bdbdea2e2 | |||
ef6b316265 | |||
a8d00f5c03 | |||
47ae373e74 | |||
2e527cf33c | |||
2860d7e3bb | |||
28b9ae40c4 | |||
697cc8c68e | |||
e0bfb57d62 | |||
93ad8661c7 | |||
6ce1d64073 | |||
9437177e82 | |||
3e93c4e8b2 | |||
4daff26495 |
4
.github/workflows/github_pages.yml
vendored
4
.github/workflows/github_pages.yml
vendored
|
@ -10,8 +10,8 @@ jobs:
|
||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- uses: cachix/install-nix-action@v15
|
- uses: cachix/install-nix-action@v17
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-unstable
|
||||||
- uses: cachix/cachix-action@v10
|
- uses: cachix/cachix-action@v10
|
||||||
|
|
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
|
@ -11,10 +11,10 @@ jobs:
|
||||||
os: [ubuntu-latest, macos-latest]
|
os: [ubuntu-latest, macos-latest]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- uses: cachix/install-nix-action@v15
|
- uses: cachix/install-nix-action@v17
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
nix_path: nixpkgs=channel:nixos-21.11
|
||||||
- uses: cachix/cachix-action@v10
|
- uses: cachix/cachix-action@v10
|
||||||
with:
|
with:
|
||||||
name: nix-community
|
name: nix-community
|
||||||
|
|
|
@ -32,7 +32,7 @@ will write to your dconf store and cannot tell whether a configuration
|
||||||
that it is about to be overwritten was from a previous Home Manager
|
that it is about to be overwritten was from a previous Home Manager
|
||||||
generation or from manual configuration.
|
generation or from manual configuration.
|
||||||
|
|
||||||
Home Manager targets [NixOS][] unstable and NixOS version 21.05 (the
|
Home Manager targets [NixOS][] unstable and NixOS version 21.11 (the
|
||||||
current stable version), it may or may not work on other Linux
|
current stable version), it may or may not work on other Linux
|
||||||
distributions and NixOS versions.
|
distributions and NixOS versions.
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ Home Manager is developed against `nixpkgs-unstable` branch, which
|
||||||
often causes it to contain tweaks for changes/packages not yet
|
often causes it to contain tweaks for changes/packages not yet
|
||||||
released in stable NixOS. To avoid breaking users' configurations,
|
released in stable NixOS. To avoid breaking users' configurations,
|
||||||
Home Manager is released in branches corresponding to NixOS releases
|
Home Manager is released in branches corresponding to NixOS releases
|
||||||
(e.g. `release-21.05`). These branches get fixes, but usually not new
|
(e.g. `release-21.11`). These branches get fixes, but usually not new
|
||||||
modules. If you need a module to be backported, then feel free to open
|
modules. If you need a module to be backported, then feel free to open
|
||||||
an issue.
|
an issue.
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
[[sec-release-21.11]]
|
[[sec-release-21.11]]
|
||||||
== Release 21.11
|
== Release 21.11
|
||||||
|
|
||||||
This is the current unstable branch and the information in this
|
The 21.11 release branch became the stable branch in November, 2021.
|
||||||
section is therefore not final.
|
|
||||||
|
|
||||||
[[sec-release-21.11-highlights]]
|
[[sec-release-21.11-highlights]]
|
||||||
=== Highlights
|
=== Highlights
|
||||||
|
|
1
format
1
format
|
@ -24,7 +24,6 @@ find . -name '*.nix' \
|
||||||
! -path ./modules/manual.nix \
|
! -path ./modules/manual.nix \
|
||||||
! -path ./modules/misc/news.nix \
|
! -path ./modules/misc/news.nix \
|
||||||
! -path ./modules/programs/bash.nix \
|
! -path ./modules/programs/bash.nix \
|
||||||
! -path ./modules/programs/gpg.nix \
|
|
||||||
! -path ./modules/programs/ssh.nix \
|
! -path ./modules/programs/ssh.nix \
|
||||||
! -path ./modules/programs/zsh.nix \
|
! -path ./modules/programs/zsh.nix \
|
||||||
! -path ./modules/services/gpg-agent.nix \
|
! -path ./modules/services/gpg-agent.nix \
|
||||||
|
|
|
@ -10,6 +10,23 @@ function errorEcho() {
|
||||||
echo $* >&2
|
echo $* >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeByName() {
|
||||||
|
nix profile list \
|
||||||
|
| { grep "$1" || test $? = 1; } \
|
||||||
|
| cut -d ' ' -f 4 \
|
||||||
|
| xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG
|
||||||
|
}
|
||||||
|
|
||||||
|
function setNixProfileCommands() {
|
||||||
|
if [[ -e ~/.nix-profile/manifest.json ]] ; then
|
||||||
|
LIST_OUTPATH_CMD="nix profile list"
|
||||||
|
REMOVE_CMD="removeByName"
|
||||||
|
else
|
||||||
|
LIST_OUTPATH_CMD="nix-env -q --outpath"
|
||||||
|
REMOVE_CMD="nix-env -q"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function setVerboseAndDryRun() {
|
function setVerboseAndDryRun() {
|
||||||
if [[ -v VERBOSE ]]; then
|
if [[ -v VERBOSE ]]; then
|
||||||
export VERBOSE_ARG="--verbose"
|
export VERBOSE_ARG="--verbose"
|
||||||
|
@ -263,9 +280,9 @@ function doBuild() {
|
||||||
setFlakeAttribute
|
setFlakeAttribute
|
||||||
if [[ -v FLAKE_CONFIG_URI ]]; then
|
if [[ -v FLAKE_CONFIG_URI ]]; then
|
||||||
doBuildFlake \
|
doBuildFlake \
|
||||||
"${DRY_RUN+--dry-run} \
|
|
||||||
"${NO_OUT_LINK+--no-link} \
|
|
||||||
"$FLAKE_CONFIG_URI.activationPackage" \
|
"$FLAKE_CONFIG_URI.activationPackage" \
|
||||||
|
${DRY_RUN+--dry-run} \
|
||||||
|
${NO_OUT_LINK+--no-link} \
|
||||||
|| return
|
|| return
|
||||||
else
|
else
|
||||||
doBuildAttr \
|
doBuildAttr \
|
||||||
|
@ -294,8 +311,8 @@ function doSwitch() {
|
||||||
setFlakeAttribute
|
setFlakeAttribute
|
||||||
if [[ -v FLAKE_CONFIG_URI ]]; then
|
if [[ -v FLAKE_CONFIG_URI ]]; then
|
||||||
doBuildFlake \
|
doBuildFlake \
|
||||||
--out-link "$generation" \
|
|
||||||
"$FLAKE_CONFIG_URI.activationPackage" \
|
"$FLAKE_CONFIG_URI.activationPackage" \
|
||||||
|
--out-link "$generation" \
|
||||||
&& "$generation/activate" || return
|
&& "$generation/activate" || return
|
||||||
else
|
else
|
||||||
doBuildAttr \
|
doBuildAttr \
|
||||||
|
@ -371,8 +388,9 @@ function doExpireGenerations() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function doListPackages() {
|
function doListPackages() {
|
||||||
|
setNixProfileCommands
|
||||||
local outPath
|
local outPath
|
||||||
outPath="$(nix-env -q --out-path | grep -o '/.*home-manager-path$')"
|
outPath="$($LIST_OUTPATH_CMD | grep -o '/.*home-manager-path$')"
|
||||||
if [[ -n "$outPath" ]] ; then
|
if [[ -n "$outPath" ]] ; then
|
||||||
nix-store -q --references "$outPath" | sed 's/[^-]*-//'
|
nix-store -q --references "$outPath" | sed 's/[^-]*-//'
|
||||||
else
|
else
|
||||||
|
@ -447,6 +465,7 @@ function doShowNews() {
|
||||||
|
|
||||||
function doUninstall() {
|
function doUninstall() {
|
||||||
setVerboseAndDryRun
|
setVerboseAndDryRun
|
||||||
|
setNixProfileCommands
|
||||||
|
|
||||||
echo "This will remove Home Manager from your system."
|
echo "This will remove Home Manager from your system."
|
||||||
|
|
||||||
|
@ -464,7 +483,7 @@ function doUninstall() {
|
||||||
HOME_MANAGER_CONFIG="$(mktemp --tmpdir home-manager.XXXXXXXXXX)"
|
HOME_MANAGER_CONFIG="$(mktemp --tmpdir home-manager.XXXXXXXXXX)"
|
||||||
echo "{ lib, ... }: { home.file = lib.mkForce {}; }" > "$HOME_MANAGER_CONFIG"
|
echo "{ lib, ... }: { home.file = lib.mkForce {}; }" > "$HOME_MANAGER_CONFIG"
|
||||||
doSwitch
|
doSwitch
|
||||||
$DRY_RUN_CMD nix-env -e home-manager-path || true
|
$DRY_RUN_CMD $REMOVE_CMD home-manager-path || true
|
||||||
rm "$HOME_MANAGER_CONFIG"
|
rm "$HOME_MANAGER_CONFIG"
|
||||||
$DRY_RUN_CMD rm $VERBOSE_ARG -r \
|
$DRY_RUN_CMD rm $VERBOSE_ARG -r \
|
||||||
"${XDG_DATA_HOME:-$HOME/.local/share}/home-manager"
|
"${XDG_DATA_HOME:-$HOME/.local/share}/home-manager"
|
||||||
|
|
|
@ -239,7 +239,7 @@ in
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleanOldGen() {
|
function cleanOldGen() {
|
||||||
if [[ ! -v oldGenPath ]] ; then
|
if [[ ! -v oldGenPath || ! -e "$oldGenPath/home-files" ]] ; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -260,7 +260,17 @@ in
|
||||||
|
|
||||||
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
|
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
|
||||||
echo "Creating profile generation $newGenNum"
|
echo "Creating profile generation $newGenNum"
|
||||||
|
if [[ -e "$genProfilePath"/manifest.json ]] ; then
|
||||||
|
# Remove all packages from "$genProfilePath"
|
||||||
|
# `nix profile remove '.*' --profile "$genProfilePath"` was not working, so here is a workaround:
|
||||||
|
nix profile list --profile "$genProfilePath" \
|
||||||
|
| cut -d ' ' -f 4 \
|
||||||
|
| xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG --profile "$genProfilePath"
|
||||||
|
$DRY_RUN_CMD nix profile install $VERBOSE_ARG --profile "$genProfilePath" "$newGenPath"
|
||||||
|
else
|
||||||
$DRY_RUN_CMD nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath"
|
$DRY_RUN_CMD nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath"
|
||||||
|
fi
|
||||||
|
|
||||||
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath"
|
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath"
|
||||||
else
|
else
|
||||||
echo "No change so reusing latest profile generation $oldGenNum"
|
echo "No change so reusing latest profile generation $oldGenNum"
|
||||||
|
|
|
@ -578,30 +578,49 @@ in
|
||||||
if config.submoduleSupport.externalPackageInstall
|
if config.submoduleSupport.externalPackageInstall
|
||||||
then
|
then
|
||||||
''
|
''
|
||||||
|
if [[ -e "$nixProfilePath"/manifest.json ]] ; then
|
||||||
|
nix profile list \
|
||||||
|
| { grep 'home-manager-path$' || test $? = 1; } \
|
||||||
|
| awk -F ' ' '{ print $4 }' \
|
||||||
|
| cut -d ' ' -f 4 \
|
||||||
|
| xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG
|
||||||
|
else
|
||||||
if nix-env -q | grep '^home-manager-path$'; then
|
if nix-env -q | grep '^home-manager-path$'; then
|
||||||
$DRY_RUN_CMD nix-env -e home-manager-path
|
$DRY_RUN_CMD nix-env -e home-manager-path
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
''
|
''
|
||||||
else
|
else
|
||||||
''
|
''
|
||||||
if ! $DRY_RUN_CMD nix-env -i ${cfg.path} ; then
|
if [[ -e "$nixProfilePath"/manifest.json ]] ; then
|
||||||
|
INSTALL_CMD="nix profile install"
|
||||||
|
LIST_CMD="nix profile list"
|
||||||
|
REMOVE_CMD_SYNTAX='nix profile remove {number | store path}'
|
||||||
|
else
|
||||||
|
INSTALL_CMD="nix-env -i"
|
||||||
|
LIST_CMD="nix-env -q"
|
||||||
|
REMOVE_CMD_SYNTAX='nix-env -e {package name}'
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! $DRY_RUN_CMD $INSTALL_CMD ${cfg.path} ; then
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
|
||||||
Oops, nix-env failed to install your new Home Manager profile!
|
Oops, nix-env failed to install your new Home Manager profile!
|
||||||
|
|
||||||
Perhaps there is a conflict with a package that was installed using
|
Perhaps there is a conflict with a package that was installed using
|
||||||
'nix-env -i'? Try running
|
'$INSTALL_CMD'? Try running
|
||||||
|
|
||||||
nix-env -q
|
$LIST_COMMAND
|
||||||
|
|
||||||
and if there is a conflicting package you can remove it with
|
and if there is a conflicting package you can remove it with
|
||||||
|
|
||||||
nix-env -e {package name}
|
$REMOVE_CMD_SYNTAX
|
||||||
|
|
||||||
Then try activating your Home Manager configuration again.
|
Then try activating your Home Manager configuration again.
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
unset INSTALL_CMD LIST_CMD REMOVE_CMD_SYNTAX
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ function setupVars() {
|
||||||
local profilesPath="$nixStateDir/profiles/per-user/$USER"
|
local profilesPath="$nixStateDir/profiles/per-user/$USER"
|
||||||
local gcPath="$nixStateDir/gcroots/per-user/$USER"
|
local gcPath="$nixStateDir/gcroots/per-user/$USER"
|
||||||
|
|
||||||
|
declare -gr nixProfilePath="$profilesPath/profile"
|
||||||
declare -gr genProfilePath="$profilesPath/home-manager"
|
declare -gr genProfilePath="$profilesPath/home-manager"
|
||||||
declare -gr newGenPath="@GENERATION_DIR@";
|
declare -gr newGenPath="@GENERATION_DIR@";
|
||||||
declare -gr newGenGcPath="$gcPath/current-home"
|
declare -gr newGenGcPath="$gcPath/current-home"
|
||||||
|
|
|
@ -8,8 +8,9 @@ let
|
||||||
|
|
||||||
isDagEntry = e: isAttrs e && (e ? data) && (e ? after) && (e ? before);
|
isDagEntry = e: isAttrs e && (e ? data) && (e ? after) && (e ? before);
|
||||||
|
|
||||||
dagContentType = elemType:
|
dagEntryOf = elemType:
|
||||||
types.submodule ({ name, ... }: {
|
let
|
||||||
|
submoduleType = types.submodule ({ name, ... }: {
|
||||||
options = {
|
options = {
|
||||||
data = mkOption { type = elemType; };
|
data = mkOption { type = elemType; };
|
||||||
after = mkOption { type = with types; uniq (listOf str); };
|
after = mkOption { type = with types; uniq (listOf str); };
|
||||||
|
@ -19,6 +20,15 @@ let
|
||||||
data._module.args.dagName = name;
|
data._module.args.dagName = name;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
maybeConvert = v: if isDagEntry v then v else dag.entryAnywhere v;
|
||||||
|
in mkOptionType {
|
||||||
|
name = "dagEntryOf";
|
||||||
|
description = "DAG entry of ${elemType.description}";
|
||||||
|
# leave the checking to the submodule type
|
||||||
|
merge = loc: defs:
|
||||||
|
submoduleType.merge loc
|
||||||
|
(map (def: def // { value = maybeConvert def.value; }) defs);
|
||||||
|
};
|
||||||
|
|
||||||
in rec {
|
in rec {
|
||||||
# A directed acyclic graph of some inner type.
|
# A directed acyclic graph of some inner type.
|
||||||
|
@ -29,21 +39,16 @@ in rec {
|
||||||
# "actual" attribute name a new submodule argument is provided with
|
# "actual" attribute name a new submodule argument is provided with
|
||||||
# the name `dagName`.
|
# the name `dagName`.
|
||||||
dagOf = elemType:
|
dagOf = elemType:
|
||||||
let
|
let attrEquivalent = types.attrsOf (dagEntryOf elemType);
|
||||||
convertAllToDags = let
|
|
||||||
maybeConvert = n: v: if isDagEntry v then v else dag.entryAnywhere v;
|
|
||||||
in map (def: def // { value = mapAttrs maybeConvert def.value; });
|
|
||||||
|
|
||||||
attrEquivalent = types.attrsOf (dagContentType elemType);
|
|
||||||
in mkOptionType rec {
|
in mkOptionType rec {
|
||||||
name = "dagOf";
|
name = "dagOf";
|
||||||
description = "DAG of ${elemType.description}s";
|
description = "DAG of ${elemType.description}s";
|
||||||
check = isAttrs;
|
inherit (attrEquivalent) check merge emptyValue;
|
||||||
merge = loc: defs: attrEquivalent.merge loc (convertAllToDags defs);
|
|
||||||
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<name>" ]);
|
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<name>" ]);
|
||||||
getSubModules = elemType.getSubModules;
|
getSubModules = elemType.getSubModules;
|
||||||
substSubModules = m: dagOf (elemType.substSubModules m);
|
substSubModules = m: dagOf (elemType.substSubModules m);
|
||||||
functor = (defaultFunctor name) // { wrapped = elemType; };
|
functor = (defaultFunctor name) // { wrapped = elemType; };
|
||||||
|
nestedTypes.elemType = elemType;
|
||||||
};
|
};
|
||||||
|
|
||||||
# A directed acyclic graph of some inner type OR a list of that
|
# A directed acyclic graph of some inner type OR a list of that
|
||||||
|
|
|
@ -15,8 +15,6 @@ in {
|
||||||
"direnv"
|
"direnv"
|
||||||
"enableNixDirenvIntegration"
|
"enableNixDirenvIntegration"
|
||||||
] [ "programs" "direnv" "nix-direnv" "enable" ])
|
] [ "programs" "direnv" "nix-direnv" "enable" ])
|
||||||
(mkRemovedOptionModule [ "programs" "direnv" "nix-direnv" "enableFlakes" ]
|
|
||||||
"Flake support is now always enabled.")
|
|
||||||
];
|
];
|
||||||
|
|
||||||
meta.maintainers = [ maintainers.rycee ];
|
meta.maintainers = [ maintainers.rycee ];
|
||||||
|
@ -81,6 +79,7 @@ in {
|
||||||
<link
|
<link
|
||||||
xlink:href="https://github.com/nix-community/nix-direnv">nix-direnv</link>,
|
xlink:href="https://github.com/nix-community/nix-direnv">nix-direnv</link>,
|
||||||
a fast, persistent use_nix implementation for direnv'';
|
a fast, persistent use_nix implementation for direnv'';
|
||||||
|
enableFlakes = mkEnableOption "Flake support in nix-direnv";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -93,9 +92,11 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
xdg.configFile."direnv/direnvrc" = let
|
xdg.configFile."direnv/direnvrc" = let
|
||||||
|
package =
|
||||||
|
pkgs.nix-direnv.override { inherit (cfg.nix-direnv) enableFlakes; };
|
||||||
text = concatStringsSep "\n" (optional (cfg.stdlib != "") cfg.stdlib
|
text = concatStringsSep "\n" (optional (cfg.stdlib != "") cfg.stdlib
|
||||||
++ optional cfg.nix-direnv.enable
|
++ optional cfg.nix-direnv.enable
|
||||||
"source ${pkgs.nix-direnv}/share/nix-direnv/direnvrc");
|
"source ${package}/share/nix-direnv/direnvrc");
|
||||||
in mkIf (text != "") { inherit text; };
|
in mkIf (text != "") { inherit text; };
|
||||||
|
|
||||||
programs.bash.initExtra = mkIf cfg.enableBashIntegration (
|
programs.bash.initExtra = mkIf cfg.enableBashIntegration (
|
||||||
|
|
|
@ -6,9 +6,7 @@ let
|
||||||
cfg = config.programs.gpg;
|
cfg = config.programs.gpg;
|
||||||
|
|
||||||
mkKeyValue = key: value:
|
mkKeyValue = key: value:
|
||||||
if isString value
|
if isString value then "${key} ${value}" else optionalString value key;
|
||||||
then "${key} ${value}"
|
|
||||||
else optionalString value key;
|
|
||||||
|
|
||||||
cfgText = generators.toKeyValue {
|
cfgText = generators.toKeyValue {
|
||||||
inherit mkKeyValue;
|
inherit mkKeyValue;
|
||||||
|
@ -21,8 +19,132 @@ let
|
||||||
} cfg.scdaemonSettings;
|
} cfg.scdaemonSettings;
|
||||||
|
|
||||||
primitiveType = types.oneOf [ types.str types.bool ];
|
primitiveType = types.oneOf [ types.str types.bool ];
|
||||||
in
|
|
||||||
|
publicKeyOpts = { config, ... }: {
|
||||||
|
options = {
|
||||||
|
text = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Text of an OpenPGP public key.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
source = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = ''
|
||||||
|
Path of an OpenPGP public key file.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
trust = mkOption {
|
||||||
|
type = types.nullOr (types.enum [
|
||||||
|
"unknown"
|
||||||
|
1
|
||||||
|
"never"
|
||||||
|
2
|
||||||
|
"marginal"
|
||||||
|
3
|
||||||
|
"full"
|
||||||
|
4
|
||||||
|
"ultimate"
|
||||||
|
5
|
||||||
|
]);
|
||||||
|
default = null;
|
||||||
|
apply = v:
|
||||||
|
if isString v then
|
||||||
{
|
{
|
||||||
|
unknown = 1;
|
||||||
|
never = 2;
|
||||||
|
marginal = 3;
|
||||||
|
full = 4;
|
||||||
|
ultimate = 5;
|
||||||
|
}.${v}
|
||||||
|
else
|
||||||
|
v;
|
||||||
|
description = ''
|
||||||
|
The amount of trust you have in the key ownership and the care the
|
||||||
|
owner puts into signing other keys. The available levels are
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>unknown</literal> or <literal>1</literal></term>
|
||||||
|
<listitem><para>I don't know or won't say.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>never</literal> or <literal>2</literal></term>
|
||||||
|
<listitem><para>I do NOT trust.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>marginal</literal> or <literal>3</literal></term>
|
||||||
|
<listitem><para>I trust marginally.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>full</literal> or <literal>4</literal></term>
|
||||||
|
<listitem><para>I trust fully.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>ultimate</literal> or <literal>5</literal></term>
|
||||||
|
<listitem><para>I trust ultimately.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</para><para>
|
||||||
|
See <link xlink:href="https://www.gnupg.org/gph/en/manual/x334.html"/>
|
||||||
|
for more.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
source =
|
||||||
|
mkIf (config.text != null) (pkgs.writeText "gpg-pubkey" config.text);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
importTrustBashFunctions = let gpg = "${cfg.package}/bin/gpg";
|
||||||
|
in ''
|
||||||
|
function gpgKeyId() {
|
||||||
|
${gpg} --show-key --with-colons "$1" \
|
||||||
|
| grep ^pub: \
|
||||||
|
| cut -d: -f5
|
||||||
|
}
|
||||||
|
|
||||||
|
function importTrust() {
|
||||||
|
local keyIds trust
|
||||||
|
IFS='\n' read -ra keyIds <<< "$(gpgKeyId "$1")"
|
||||||
|
trust="$2"
|
||||||
|
for id in "''${keyIds[@]}" ; do
|
||||||
|
{ echo trust; echo "$trust"; (( trust == 5 )) && echo y; echo quit; } \
|
||||||
|
| ${gpg} --no-tty --command-fd 0 --edit-key "$id"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
'';
|
||||||
|
|
||||||
|
keyringFiles = let
|
||||||
|
gpg = "${cfg.package}/bin/gpg";
|
||||||
|
|
||||||
|
importKey = { source, trust, ... }: ''
|
||||||
|
${gpg} --import ${source}
|
||||||
|
${optionalString (trust != null)
|
||||||
|
''importTrust "${source}" ${toString trust}''}
|
||||||
|
'';
|
||||||
|
|
||||||
|
importKeys = concatMapStringsSep "\n" importKey cfg.publicKeys;
|
||||||
|
in pkgs.runCommand "gpg-pubring" { buildInputs = [ cfg.package ]; } ''
|
||||||
|
export GNUPGHOME
|
||||||
|
GNUPGHOME=$(mktemp -d)
|
||||||
|
|
||||||
|
${importTrustBashFunctions}
|
||||||
|
${importKeys}
|
||||||
|
|
||||||
|
mkdir $out
|
||||||
|
cp $GNUPGHOME/pubring.kbx $out/pubring.kbx
|
||||||
|
if [[ -e $GNUPGHOME/trustdb.gpg ]] ; then
|
||||||
|
cp $GNUPGHOME/trustdb.gpg $out/trustdb.gpg
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
in {
|
||||||
options.programs.gpg = {
|
options.programs.gpg = {
|
||||||
enable = mkEnableOption "GnuPG";
|
enable = mkEnableOption "GnuPG";
|
||||||
|
|
||||||
|
@ -31,11 +153,13 @@ in
|
||||||
default = pkgs.gnupg;
|
default = pkgs.gnupg;
|
||||||
defaultText = literalExpression "pkgs.gnupg";
|
defaultText = literalExpression "pkgs.gnupg";
|
||||||
example = literalExpression "pkgs.gnupg23";
|
example = literalExpression "pkgs.gnupg23";
|
||||||
description = "The Gnupg package to use (also used the gpg-agent service).";
|
description =
|
||||||
|
"The Gnupg package to use (also used the gpg-agent service).";
|
||||||
};
|
};
|
||||||
|
|
||||||
settings = mkOption {
|
settings = mkOption {
|
||||||
type = types.attrsOf (types.either primitiveType (types.listOf types.str));
|
type =
|
||||||
|
types.attrsOf (types.either primitiveType (types.listOf types.str));
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
{
|
{
|
||||||
no-comments = false;
|
no-comments = false;
|
||||||
|
@ -53,7 +177,8 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
scdaemonSettings = mkOption {
|
scdaemonSettings = mkOption {
|
||||||
type = types.attrsOf (types.either primitiveType (types.listOf types.str));
|
type =
|
||||||
|
types.attrsOf (types.either primitiveType (types.listOf types.str));
|
||||||
example = literalExpression ''
|
example = literalExpression ''
|
||||||
{
|
{
|
||||||
disable-ccid = true;
|
disable-ccid = true;
|
||||||
|
@ -68,11 +193,54 @@ in
|
||||||
|
|
||||||
homedir = mkOption {
|
homedir = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
example = literalExpression "\"\${config.xdg.dataHome}/gnupg\"";
|
example = literalExpression ''"''${config.xdg.dataHome}/gnupg"'';
|
||||||
default = "${config.home.homeDirectory}/.gnupg";
|
default = "${config.home.homeDirectory}/.gnupg";
|
||||||
defaultText = literalExpression "\"\${config.home.homeDirectory}/.gnupg\"";
|
defaultText =
|
||||||
|
literalExpression ''"''${config.home.homeDirectory}/.gnupg"'';
|
||||||
description = "Directory to store keychains and configuration.";
|
description = "Directory to store keychains and configuration.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mutableKeys = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
If set to <literal>true</literal>, you may manage your keyring as a user
|
||||||
|
using the <literal>gpg</literal> command. Upon activation, the keyring
|
||||||
|
will have managed keys added without overwriting unmanaged keys.
|
||||||
|
</para><para>
|
||||||
|
If set to <literal>false</literal>, the path
|
||||||
|
<filename>$GNUPGHOME/pubring.kbx</filename> will become an immutable
|
||||||
|
link to the Nix store, denying modifications.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
mutableTrust = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
If set to <literal>true</literal>, you may manage trust as a user using
|
||||||
|
the <command>gpg</command> command. Upon activation, trusted keys have
|
||||||
|
their trust set without overwriting unmanaged keys.
|
||||||
|
</para><para>
|
||||||
|
If set to <literal>false</literal>, the path
|
||||||
|
<filename>$GNUPGHOME/trustdb.gpg</filename> will be
|
||||||
|
<emphasis>overwritten</emphasis> on each activation, removing trust for
|
||||||
|
any unmanaged keys. Be careful to make a backup of your old
|
||||||
|
<filename>trustdb.gpg</filename> before switching to immutable trust!
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
publicKeys = mkOption {
|
||||||
|
type = types.listOf (types.submodule publicKeyOpts);
|
||||||
|
example = literalExpression ''
|
||||||
|
[ { source = ./pubkeys.txt; } ]
|
||||||
|
'';
|
||||||
|
default = [ ];
|
||||||
|
description = ''
|
||||||
|
A list of public keys to be imported into GnuPG. Note, these key files
|
||||||
|
will be copied into the world-readable Nix store.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
@ -80,7 +248,8 @@ in
|
||||||
personal-cipher-preferences = mkDefault "AES256 AES192 AES";
|
personal-cipher-preferences = mkDefault "AES256 AES192 AES";
|
||||||
personal-digest-preferences = mkDefault "SHA512 SHA384 SHA256";
|
personal-digest-preferences = mkDefault "SHA512 SHA384 SHA256";
|
||||||
personal-compress-preferences = mkDefault "ZLIB BZIP2 ZIP Uncompressed";
|
personal-compress-preferences = mkDefault "ZLIB BZIP2 ZIP Uncompressed";
|
||||||
default-preference-list = mkDefault "SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed";
|
default-preference-list = mkDefault
|
||||||
|
"SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed";
|
||||||
cert-digest-algo = mkDefault "SHA512";
|
cert-digest-algo = mkDefault "SHA512";
|
||||||
s2k-digest-algo = mkDefault "SHA512";
|
s2k-digest-algo = mkDefault "SHA512";
|
||||||
s2k-cipher-algo = mkDefault "AES256";
|
s2k-cipher-algo = mkDefault "AES256";
|
||||||
|
@ -102,12 +271,56 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
home.packages = [ cfg.package ];
|
home.packages = [ cfg.package ];
|
||||||
home.sessionVariables = {
|
home.sessionVariables = { GNUPGHOME = cfg.homedir; };
|
||||||
GNUPGHOME = cfg.homedir;
|
|
||||||
};
|
|
||||||
|
|
||||||
home.file."${cfg.homedir}/gpg.conf".text = cfgText;
|
home.file."${cfg.homedir}/gpg.conf".text = cfgText;
|
||||||
|
|
||||||
home.file."${cfg.homedir}/scdaemon.conf".text = scdaemonCfgText;
|
home.file."${cfg.homedir}/scdaemon.conf".text = scdaemonCfgText;
|
||||||
|
|
||||||
|
# Link keyring if keys are not mutable
|
||||||
|
home.file."${cfg.homedir}/pubring.kbx" =
|
||||||
|
mkIf (!cfg.mutableKeys && cfg.publicKeys != [ ]) {
|
||||||
|
source = "${keyringFiles}/pubring.kbx";
|
||||||
|
};
|
||||||
|
|
||||||
|
home.activation = {
|
||||||
|
createGpgHomedir =
|
||||||
|
hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
|
||||||
|
$DRY_RUN_CMD mkdir -m700 -p $VERBOSE_ARG ${escapeShellArg cfg.homedir}
|
||||||
|
'';
|
||||||
|
|
||||||
|
importGpgKeys = let
|
||||||
|
gpg = "${cfg.package}/bin/gpg";
|
||||||
|
|
||||||
|
importKey = { source, trust, ... }:
|
||||||
|
# Import mutable keys
|
||||||
|
optional cfg.mutableKeys
|
||||||
|
"$DRY_RUN_CMD ${gpg} $QUIET_ARG --import ${source}"
|
||||||
|
|
||||||
|
# Import mutable trust
|
||||||
|
++ optional (trust != null && cfg.mutableTrust)
|
||||||
|
''$DRY_RUN_CMD importTrust "${source}" ${toString trust}'';
|
||||||
|
|
||||||
|
anyTrust = any (k: k.trust != null) cfg.publicKeys;
|
||||||
|
|
||||||
|
importKeys = concatStringsSep "\n" (concatMap importKey cfg.publicKeys);
|
||||||
|
|
||||||
|
# If any key/trust should be imported then create the block. Otherwise
|
||||||
|
# leave it empty.
|
||||||
|
block = concatStringsSep "\n" (optional (importKeys != "") ''
|
||||||
|
export GNUPGHOME=${escapeShellArg cfg.homedir}
|
||||||
|
if [[ ! -v VERBOSE ]]; then
|
||||||
|
QUIET_ARG="--quiet"
|
||||||
|
else
|
||||||
|
QUIET_ARG=""
|
||||||
|
fi
|
||||||
|
${importTrustBashFunctions}
|
||||||
|
${importKeys}
|
||||||
|
unset GNUPGHOME QUIET_ARG keyId importTrust
|
||||||
|
'' ++ optional (!cfg.mutableTrust && anyTrust) ''
|
||||||
|
install -m 0700 ${keyringFiles}/trustdb.gpg "${cfg.homedir}/trustdb.gpg"'');
|
||||||
|
in mkIf (cfg.publicKeys != [ ])
|
||||||
|
(lib.hm.dag.entryAfter [ "linkGeneration" ] block);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,14 +44,15 @@ let
|
||||||
}
|
}
|
||||||
''));
|
''));
|
||||||
|
|
||||||
channelString = concatStringsSep cnl (flip mapAttrsToList cfg.networks (k: v:
|
channelString = concatStringsSep cnl (concatLists
|
||||||
concatStringsSep cnl (flip mapAttrsToList v.channels (c: cv: ''
|
(flip mapAttrsToList cfg.networks (k: v:
|
||||||
|
(flip mapAttrsToList v.channels (c: cv: ''
|
||||||
{
|
{
|
||||||
chatnet = "${k}";
|
chatnet = "${k}";
|
||||||
name = "${c}";
|
name = "${c}";
|
||||||
autojoin = "${boolStr cv.autoJoin}";
|
autojoin = "${boolStr cv.autoJoin}";
|
||||||
}
|
}
|
||||||
''))));
|
'')))));
|
||||||
|
|
||||||
channelType = types.submodule {
|
channelType = types.submodule {
|
||||||
options = {
|
options = {
|
||||||
|
|
|
@ -530,20 +530,20 @@ let
|
||||||
|
|
||||||
uiOptions = with cfg.config.ui;
|
uiOptions = with cfg.config.ui;
|
||||||
concatStringsSep " " [
|
concatStringsSep " " [
|
||||||
"ncurses_set_title=${if setTitle then "true" else "false"}"
|
"terminal_set_title=${if setTitle then "true" else "false"}"
|
||||||
"ncurses_status_on_top=${
|
"terminal_status_on_top=${
|
||||||
if (statusLine == "top") then "true" else "false"
|
if (statusLine == "top") then "true" else "false"
|
||||||
}"
|
}"
|
||||||
"ncurses_assistant=${assistant}"
|
"terminal_assistant=${assistant}"
|
||||||
"ncurses_enable_mouse=${if enableMouse then "true" else "false"}"
|
"terminal_enable_mouse=${if enableMouse then "true" else "false"}"
|
||||||
"ncurses_change_colors=${if changeColors then "true" else "false"}"
|
"terminal_change_colors=${if changeColors then "true" else "false"}"
|
||||||
"${optionalString (wheelDownButton != null)
|
"${optionalString (wheelDownButton != null)
|
||||||
"ncurses_wheel_down_button=${wheelDownButton}"}"
|
"terminal_wheel_down_button=${wheelDownButton}"}"
|
||||||
"${optionalString (wheelUpButton != null)
|
"${optionalString (wheelUpButton != null)
|
||||||
"ncurses_wheel_up_button=${wheelUpButton}"}"
|
"terminal_wheel_up_button=${wheelUpButton}"}"
|
||||||
"${optionalString (shiftFunctionKeys != null)
|
"${optionalString (shiftFunctionKeys != null)
|
||||||
"ncurses_shift_function_key=${toString shiftFunctionKeys}"}"
|
"terminal_shift_function_key=${toString shiftFunctionKeys}"}"
|
||||||
"ncurses_builtin_key_parser=${
|
"terminal_builtin_key_parser=${
|
||||||
if useBuiltinKeyParser then "true" else "false"
|
if useBuiltinKeyParser then "true" else "false"
|
||||||
}"
|
}"
|
||||||
];
|
];
|
||||||
|
|
|
@ -35,10 +35,10 @@ let
|
||||||
${configStr}}
|
${configStr}}
|
||||||
''
|
''
|
||||||
else
|
else
|
||||||
mkKeyValue {
|
(mkKeyValue {
|
||||||
sep = " ";
|
sep = " ";
|
||||||
end = "";
|
end = "";
|
||||||
} name value;
|
} name value) + "\n";
|
||||||
|
|
||||||
toRasi = attrs: concatStringsSep "\n" (mapAttrsToList mkRasiSection attrs);
|
toRasi = attrs: concatStringsSep "\n" (mapAttrsToList mkRasiSection attrs);
|
||||||
|
|
||||||
|
@ -266,9 +266,9 @@ in {
|
||||||
location = (getAttr cfg.location locationsMap);
|
location = (getAttr cfg.location locationsMap);
|
||||||
xoffset = cfg.xoffset;
|
xoffset = cfg.xoffset;
|
||||||
yoffset = cfg.yoffset;
|
yoffset = cfg.yoffset;
|
||||||
theme = themeName;
|
|
||||||
} // cfg.extraConfig);
|
} // cfg.extraConfig);
|
||||||
};
|
# @theme must go after configuration but attrs are output in alphabetical order ('@' first)
|
||||||
|
} + (optionalString (themeName != null) (toRasi { "@theme" = themeName; }));
|
||||||
|
|
||||||
xdg.dataFile = mkIf (themePath != null) (if themePath == "custom" then {
|
xdg.dataFile = mkIf (themePath != null) (if themePath == "custom" then {
|
||||||
"rofi/themes/${themeName}.rasi".text = toRasi cfg.theme;
|
"rofi/themes/${themeName}.rasi".text = toRasi cfg.theme;
|
||||||
|
|
|
@ -170,6 +170,18 @@ in
|
||||||
now.
|
now.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enableBashIntegration = mkEnableOption "Bash integration" // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
enableZshIntegration = mkEnableOption "Zsh integration" // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
enableFishIntegration = mkEnableOption "Fish integration" // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -206,9 +218,9 @@ in
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
programs.bash.initExtra = gpgInitStr;
|
programs.bash.initExtra = mkIf cfg.enableBashIntegration gpgInitStr;
|
||||||
programs.zsh.initExtra = gpgInitStr;
|
programs.zsh.initExtra = mkIf cfg.enableZshIntegration gpgInitStr;
|
||||||
programs.fish.interactiveShellInit = ''
|
programs.fish.interactiveShellInit = mkIf cfg.enableFishIntegration ''
|
||||||
set -gx GPG_TTY (tty)
|
set -gx GPG_TTY (tty)
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,10 @@ let
|
||||||
|
|
||||||
home.username = config.users.users.${name}.name;
|
home.username = config.users.users.${name}.name;
|
||||||
home.homeDirectory = config.users.users.${name}.home;
|
home.homeDirectory = config.users.users.${name}.home;
|
||||||
|
|
||||||
|
# Make activation script use same version of Nix as system as a whole.
|
||||||
|
# This avoids problems with Nix not being in PATH.
|
||||||
|
home.extraActivationPath = [ config.nix.package ];
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
] ++ cfg.sharedModules;
|
] ++ cfg.sharedModules;
|
||||||
|
@ -130,7 +134,7 @@ in
|
||||||
system.activationScripts.postActivation.text =
|
system.activationScripts.postActivation.text =
|
||||||
concatStringsSep "\n" (mapAttrsToList (username: usercfg: ''
|
concatStringsSep "\n" (mapAttrsToList (username: usercfg: ''
|
||||||
echo Activating home-manager configuration for ${username}
|
echo Activating home-manager configuration for ${username}
|
||||||
sudo -u ${username} -i ${pkgs.writeShellScript "activation-${username}" ''
|
sudo -u ${username} -s --set-home ${pkgs.writeShellScript "activation-${username}" ''
|
||||||
${lib.optionalString (cfg.backupFileExtension != null)
|
${lib.optionalString (cfg.backupFileExtension != null)
|
||||||
"export HOME_MANAGER_BACKUP_EXT=${lib.escapeShellArg cfg.backupFileExtension}"}
|
"export HOME_MANAGER_BACKUP_EXT=${lib.escapeShellArg cfg.backupFileExtension}"}
|
||||||
${lib.optionalString cfg.verbose "export VERBOSE=1"}
|
${lib.optionalString cfg.verbose "export VERBOSE=1"}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (lib) concatStringsSep hm mkMerge mkOption types;
|
inherit (lib) concatStringsSep hm mkIf mkMerge mkOption types;
|
||||||
|
|
||||||
dag = lib.hm.dag;
|
dag = lib.hm.dag;
|
||||||
|
|
||||||
|
@ -14,10 +14,14 @@ in {
|
||||||
options.tested.dag = mkOption { type = hm.types.dagOf types.str; };
|
options.tested.dag = mkOption { type = hm.types.dagOf types.str; };
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
tested = mkMerge [
|
tested.dag = mkMerge [
|
||||||
{ dag.after = "after"; }
|
{ never = mkIf false "never"; }
|
||||||
{ dag.before = dag.entryBefore [ "after" ] "before"; }
|
{ after = mkMerge [ "after" (mkIf false "neither") ]; }
|
||||||
{ dag.between = dag.entryBetween [ "after" ] [ "before" ] "between"; }
|
{ before = dag.entryBefore [ "after" ] (mkIf true "before"); }
|
||||||
|
{
|
||||||
|
between =
|
||||||
|
mkIf true (dag.entryBetween [ "after" ] [ "before" ] "between");
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
home.file."result.txt".text = result;
|
home.file."result.txt".text = result;
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
{ gpg-override-defaults = ./override-defaults.nix; }
|
{
|
||||||
|
gpg-immutable-keyfiles = ./immutable-keyfiles.nix;
|
||||||
|
gpg-mutable-keyfiles = ./mutable-keyfiles.nix;
|
||||||
|
gpg-override-defaults = ./override-defaults.nix;
|
||||||
|
}
|
||||||
|
|
52
tests/modules/programs/gpg/immutable-keyfiles.nix
Normal file
52
tests/modules/programs/gpg/immutable-keyfiles.nix
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.gpg = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
mutableKeys = false;
|
||||||
|
mutableTrust = false;
|
||||||
|
|
||||||
|
publicKeys = [
|
||||||
|
{
|
||||||
|
source = pkgs.fetchurl {
|
||||||
|
url =
|
||||||
|
"https://keybase.io/rycee/pgp_keys.asc?fingerprint=36cacf52d098cc0e78fb0cb13573356c25c424d4";
|
||||||
|
sha256 = "082mjy6llvrdry6i9r5gx97nw9d89blnam7bghza4ynsjk1mmx6c";
|
||||||
|
};
|
||||||
|
trust = 1; # "unknown"
|
||||||
|
}
|
||||||
|
{
|
||||||
|
source = pkgs.fetchurl {
|
||||||
|
url = "https://www.rsync.net/resources/pubkey.txt";
|
||||||
|
sha256 = "16nzqfb1kvsxjkq919hxsawx6ydvip3md3qyhdmw54qx6drnxckl";
|
||||||
|
};
|
||||||
|
trust = "never";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertFileNotRegex activate "^export GNUPGHOME='/home/hm-user/.gnupg'$"
|
||||||
|
|
||||||
|
assertFileRegex activate \
|
||||||
|
'^install -m 0700 /nix/store/[0-9a-z]*-gpg-pubring/trustdb.gpg "/home/hm-user/.gnupg/trustdb.gpg"$'
|
||||||
|
|
||||||
|
# Setup GPGHOME
|
||||||
|
export GNUPGHOME=$(mktemp -d)
|
||||||
|
cp -r $TESTED/home-files/.gnupg/* $GNUPGHOME
|
||||||
|
TRUSTDB=$(grep -o '/nix/store/[0-9a-z]*-gpg-pubring/trustdb.gpg' $TESTED/activate)
|
||||||
|
install -m 0700 $TRUSTDB $GNUPGHOME/trustdb.gpg
|
||||||
|
|
||||||
|
# Export Trust
|
||||||
|
export WORKDIR=$(mktemp -d)
|
||||||
|
${pkgs.gnupg}/bin/gpg -q --export-ownertrust > $WORKDIR/gpgtrust.txt
|
||||||
|
|
||||||
|
# Check Trust
|
||||||
|
assertFileRegex $WORKDIR/gpgtrust.txt \
|
||||||
|
'^36CACF52D098CC0E78FB0CB13573356C25C424D4:2:$'
|
||||||
|
|
||||||
|
assertFileRegex $WORKDIR/gpgtrust.txt \
|
||||||
|
'^BB847B5A69EF343CEF511B29073C282D7D6F806C:3:$'
|
||||||
|
'';
|
||||||
|
}
|
30
tests/modules/programs/gpg/mutable-keyfiles.nix
Normal file
30
tests/modules/programs/gpg/mutable-keyfiles.nix
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.gpg = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
publicKeys = [
|
||||||
|
{
|
||||||
|
source = builtins.toFile "key1" "key1";
|
||||||
|
trust = 1;
|
||||||
|
}
|
||||||
|
{ source = builtins.toFile "key2" "key2"; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
test.stubs.gnupg = { };
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertFileContains activate "export GNUPGHOME='/home/hm-user/.gnupg'"
|
||||||
|
|
||||||
|
assertFileContains activate "unset GNUPGHOME QUIET_ARG keyId importTrust"
|
||||||
|
|
||||||
|
assertFileRegex activate \
|
||||||
|
'^\$DRY_RUN_CMD @gnupg@/bin/gpg \$QUIET_ARG --import /nix/store/[0-9a-z]*-key1$'
|
||||||
|
assertFileRegex activate \
|
||||||
|
'^\$DRY_RUN_CMD importTrust "/nix/store/[0-9a-z]*-key1" 1$'
|
||||||
|
assertFileRegex activate \
|
||||||
|
'^\$DRY_RUN_CMD @gnupg@/bin/gpg \$QUIET_ARG --import /nix/store/[0-9a-z]*-key2$'
|
||||||
|
'';
|
||||||
|
}
|
|
@ -23,6 +23,8 @@ with lib;
|
||||||
nmt.script = ''
|
nmt.script = ''
|
||||||
assertFileExists home-files/bar/foopg/gpg.conf
|
assertFileExists home-files/bar/foopg/gpg.conf
|
||||||
assertFileContent home-files/bar/foopg/gpg.conf ${./override-defaults-expected.conf}
|
assertFileContent home-files/bar/foopg/gpg.conf ${./override-defaults-expected.conf}
|
||||||
|
|
||||||
|
assertFileNotRegex activate "^unset GNUPGHOME keyId importTrust$"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
configuration {
|
configuration {
|
||||||
location: 0;
|
location: 0;
|
||||||
theme: "custom";
|
|
||||||
xoffset: 0;
|
xoffset: 0;
|
||||||
yoffset: 0;
|
yoffset: 0;
|
||||||
}
|
}
|
||||||
|
@theme "custom"
|
||||||
|
|
Loading…
Reference in a new issue