format nix with rfc style
This commit is contained in:
parent
856df6f692
commit
0814fdc0de
13 changed files with 500 additions and 453 deletions
4
.github/workflows/ci.yaml
vendored
4
.github/workflows/ci.yaml
vendored
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
extra-experimental-features = recursive-nix nix-command flakes
|
||||
- run: nix build
|
||||
- run: nix build .#doc
|
||||
- run: nix fmt . -- --check
|
||||
- run: nix fmt . -- --ci
|
||||
- run: nix flake check
|
||||
tests-darwin:
|
||||
runs-on: macos-latest
|
||||
|
|
@ -27,7 +27,7 @@ jobs:
|
|||
extra-experimental-features = recursive-nix nix-command flakes
|
||||
- run: nix build
|
||||
- run: nix build .#doc
|
||||
- run: nix fmt . -- --check
|
||||
- run: nix fmt . -- --ci
|
||||
- run: nix flake check
|
||||
- name: "Install nix-darwin module"
|
||||
run: |
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
{pkgs ? import <nixpkgs> {}}: {
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
}:
|
||||
{
|
||||
agenix = pkgs.callPackage ./pkgs/agenix.nix { };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,21 @@
|
|||
let
|
||||
user1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH";
|
||||
system1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE";
|
||||
in {
|
||||
"secret1.age".publicKeys = [user1 system1];
|
||||
in
|
||||
{
|
||||
"secret1.age".publicKeys = [
|
||||
user1
|
||||
system1
|
||||
];
|
||||
"secret2.age".publicKeys = [ user1 ];
|
||||
"passwordfile-user1.age".publicKeys = [user1 system1];
|
||||
"-leading-hyphen-filename.age".publicKeys = [user1 system1];
|
||||
"passwordfile-user1.age".publicKeys = [
|
||||
user1
|
||||
system1
|
||||
];
|
||||
"-leading-hyphen-filename.age".publicKeys = [
|
||||
user1
|
||||
system1
|
||||
];
|
||||
"armored-secret.age" = {
|
||||
publicKeys = [ user1 ];
|
||||
armor = true;
|
||||
|
|
|
|||
14
flake.nix
14
flake.nix
|
|
@ -14,15 +14,18 @@
|
|||
systems.url = "github:nix-systems/default";
|
||||
};
|
||||
|
||||
outputs = {
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
darwin,
|
||||
home-manager,
|
||||
systems,
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
eachSystem = nixpkgs.lib.genAttrs (import systems);
|
||||
in {
|
||||
in
|
||||
{
|
||||
nixosModules.age = ./modules/age.nix;
|
||||
nixosModules.default = self.nixosModules.age;
|
||||
|
||||
|
|
@ -34,7 +37,7 @@
|
|||
|
||||
overlays.default = import ./overlay.nix;
|
||||
|
||||
formatter = eachSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
|
||||
formatter = eachSystem (system: nixpkgs.legacyPackages.${system}.nixfmt-tree);
|
||||
|
||||
packages = eachSystem (system: {
|
||||
agenix = nixpkgs.legacyPackages.${system}.callPackage ./pkgs/agenix.nix { };
|
||||
|
|
@ -64,8 +67,7 @@
|
|||
};
|
||||
}
|
||||
];
|
||||
})
|
||||
.system;
|
||||
}).system;
|
||||
})
|
||||
// {
|
||||
x86_64-linux.integration = import ./test/integration.nix {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
with lib;
|
||||
let
|
||||
cfg = config.age;
|
||||
|
||||
ageBin = lib.getExe config.age.package;
|
||||
|
|
@ -22,11 +23,12 @@ with lib; let
|
|||
|
||||
setTruePath = secretType: ''
|
||||
${
|
||||
if secretType.symlink
|
||||
then ''
|
||||
if secretType.symlink then
|
||||
''
|
||||
_truePath="${cfg.secretsMountPoint}/$_agenix_generation/${secretType.name}"
|
||||
''
|
||||
else ''
|
||||
else
|
||||
''
|
||||
_truePath="${secretType.path}"
|
||||
''
|
||||
}
|
||||
|
|
@ -54,7 +56,9 @@ with lib; let
|
|||
umask u=r,g=,o=
|
||||
test -f "${secretType.file}" || echo '[agenix] WARNING: encrypted file ${secretType.file} does not exist!'
|
||||
test -d "$(dirname "$TMP_FILE")" || echo "[agenix] WARNING: $(dirname "$TMP_FILE") does not exist!"
|
||||
LANG=${config.i18n.defaultLocale or "C"} ${ageBin} --decrypt "''${IDENTITIES[@]}" -o "$TMP_FILE" "${secretType.file}"
|
||||
LANG=${
|
||||
config.i18n.defaultLocale or "C"
|
||||
} ${ageBin} --decrypt "''${IDENTITIES[@]}" -o "$TMP_FILE" "${secretType.file}"
|
||||
)
|
||||
chmod ${secretType.mode} "$TMP_FILE"
|
||||
mv -f "$TMP_FILE" "$_truePath"
|
||||
|
|
@ -65,12 +69,9 @@ with lib; let
|
|||
''}
|
||||
'';
|
||||
|
||||
testIdentities =
|
||||
map
|
||||
(path: ''
|
||||
testIdentities = map (path: ''
|
||||
test -f ${path} || echo '[agenix] WARNING: config.age.identityPaths entry ${path} not present!'
|
||||
'')
|
||||
cfg.identityPaths;
|
||||
'') cfg.identityPaths;
|
||||
|
||||
cleanupAndLink = ''
|
||||
_agenix_generation="$(basename "$(readlink "${cfg.secretsDir}")" || echo 0)"
|
||||
|
|
@ -91,11 +92,13 @@ with lib; let
|
|||
++ [ cleanupAndLink ]
|
||||
);
|
||||
|
||||
secretType = types.submodule ({
|
||||
secretType = types.submodule (
|
||||
{
|
||||
config,
|
||||
name,
|
||||
...
|
||||
}: {
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
|
|
@ -124,11 +127,15 @@ with lib; let
|
|||
Permissions mode of the decrypted secret in a format understood by chmod.
|
||||
'';
|
||||
};
|
||||
symlink = mkEnableOption "symlinking secrets to their destination" // {default = true;};
|
||||
symlink = mkEnableOption "symlinking secrets to their destination" // {
|
||||
default = true;
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
mountingScript = let
|
||||
mountingScript =
|
||||
let
|
||||
app = pkgs.writeShellApplication {
|
||||
name = "agenix-home-manager-mount-secrets";
|
||||
runtimeInputs = with pkgs; [ coreutils ];
|
||||
|
|
@ -141,19 +148,21 @@ with lib; let
|
|||
in
|
||||
lib.getExe app;
|
||||
|
||||
userDirectory = dir: let
|
||||
userDirectory =
|
||||
dir:
|
||||
let
|
||||
inherit (pkgs.stdenv.hostPlatform) isDarwin;
|
||||
baseDir =
|
||||
if isDarwin
|
||||
then "$(getconf DARWIN_USER_TEMP_DIR)"
|
||||
else "\${XDG_RUNTIME_DIR}";
|
||||
in "${baseDir}/${dir}";
|
||||
baseDir = if isDarwin then "$(getconf DARWIN_USER_TEMP_DIR)" else "\${XDG_RUNTIME_DIR}";
|
||||
in
|
||||
"${baseDir}/${dir}";
|
||||
|
||||
userDirectoryDescription = dir:
|
||||
userDirectoryDescription =
|
||||
dir:
|
||||
literalExpression ''
|
||||
"''${XDG_RUNTIME_DIR}"/''${dir} on linux or "$(getconf DARWIN_USER_TEMP_DIR)"/''${dir} on darwin.
|
||||
'';
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.age = {
|
||||
package = mkPackageOption pkgs "age" { };
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
with lib;
|
||||
let
|
||||
cfg = config.age;
|
||||
|
||||
isDarwin = lib.attrsets.hasAttrByPath [ "environment" "darwinConfig" ] options;
|
||||
|
|
@ -15,13 +16,14 @@ with lib; let
|
|||
users = config.users.users;
|
||||
|
||||
sysusersEnabled =
|
||||
if isDarwin
|
||||
then false
|
||||
else options.systemd ? sysusers && (config.systemd.sysusers.enable || config.services.userborn.enable);
|
||||
if isDarwin then
|
||||
false
|
||||
else
|
||||
options.systemd ? sysusers && (config.systemd.sysusers.enable || config.services.userborn.enable);
|
||||
|
||||
mountCommand =
|
||||
if isDarwin
|
||||
then ''
|
||||
if isDarwin then
|
||||
''
|
||||
if ! diskutil info "${cfg.secretsMountPoint}" &> /dev/null; then
|
||||
num_sectors=1048576
|
||||
dev=$(hdiutil attach -nomount ram://"$num_sectors" | sed 's/[[:space:]]*$//')
|
||||
|
|
@ -29,7 +31,8 @@ with lib; let
|
|||
mount -t hfs -o nobrowse,nodev,nosuid,-m=0751 "$dev" "${cfg.secretsMountPoint}"
|
||||
fi
|
||||
''
|
||||
else ''
|
||||
else
|
||||
''
|
||||
grep -q "${cfg.secretsMountPoint} ramfs" /proc/mounts ||
|
||||
mount -t ramfs none "${cfg.secretsMountPoint}" -o nodev,nosuid,mode=0751
|
||||
'';
|
||||
|
|
@ -44,10 +47,7 @@ with lib; let
|
|||
chmod 0751 "${cfg.secretsMountPoint}/$_agenix_generation"
|
||||
'';
|
||||
|
||||
chownGroup =
|
||||
if isDarwin
|
||||
then "admin"
|
||||
else "keys";
|
||||
chownGroup = if isDarwin then "admin" else "keys";
|
||||
# chown the secrets mountpoint and the current generation to the keys group
|
||||
# instead of leaving it root:root.
|
||||
chownMountPoint = ''
|
||||
|
|
@ -56,11 +56,12 @@ with lib; let
|
|||
|
||||
setTruePath = secretType: ''
|
||||
${
|
||||
if secretType.symlink
|
||||
then ''
|
||||
if secretType.symlink then
|
||||
''
|
||||
_truePath="${cfg.secretsMountPoint}/$_agenix_generation/${secretType.name}"
|
||||
''
|
||||
else ''
|
||||
else
|
||||
''
|
||||
_truePath="${secretType.path}"
|
||||
''
|
||||
}
|
||||
|
|
@ -87,7 +88,9 @@ with lib; let
|
|||
umask u=r,g=,o=
|
||||
test -f "${secretType.file}" || echo '[agenix] WARNING: encrypted file ${secretType.file} does not exist!'
|
||||
test -d "$(dirname "$TMP_FILE")" || echo "[agenix] WARNING: $(dirname "$TMP_FILE") does not exist!"
|
||||
LANG=${config.i18n.defaultLocale or "C"} ${ageBin} --decrypt "''${IDENTITIES[@]}" -o "$TMP_FILE" "${secretType.file}"
|
||||
LANG=${
|
||||
config.i18n.defaultLocale or "C"
|
||||
} ${ageBin} --decrypt "''${IDENTITIES[@]}" -o "$TMP_FILE" "${secretType.file}"
|
||||
)
|
||||
chmod ${secretType.mode} "$TMP_FILE"
|
||||
mv -f "$TMP_FILE" "$_truePath"
|
||||
|
|
@ -97,12 +100,9 @@ with lib; let
|
|||
''}
|
||||
'';
|
||||
|
||||
testIdentities =
|
||||
map
|
||||
(path: ''
|
||||
testIdentities = map (path: ''
|
||||
test -f ${path} || echo '[agenix] WARNING: config.age.identityPaths entry ${path} not present!'
|
||||
'')
|
||||
cfg.identityPaths;
|
||||
'') cfg.identityPaths;
|
||||
|
||||
cleanupAndLink = ''
|
||||
_agenix_generation="$(basename "$(readlink ${cfg.secretsDir})" || echo 0)"
|
||||
|
|
@ -134,7 +134,9 @@ with lib; let
|
|||
++ (map chownSecret (builtins.attrValues cfg.secrets))
|
||||
);
|
||||
|
||||
secretType = types.submodule ({config, ...}: {
|
||||
secretType = types.submodule (
|
||||
{ config, ... }:
|
||||
{
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
|
|
@ -184,10 +186,14 @@ with lib; let
|
|||
Group of the decrypted secret.
|
||||
'';
|
||||
};
|
||||
symlink = mkEnableOption "symlinking secrets to their destination" // {default = true;};
|
||||
symlink = mkEnableOption "symlinking secrets to their destination" // {
|
||||
default = true;
|
||||
};
|
||||
});
|
||||
in {
|
||||
};
|
||||
}
|
||||
);
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "age" "sshKeyPaths" ] [ "age" "identityPaths" ])
|
||||
];
|
||||
|
|
@ -219,12 +225,14 @@ in {
|
|||
};
|
||||
secretsMountPoint = mkOption {
|
||||
type =
|
||||
types.addCheck types.str
|
||||
(s:
|
||||
(builtins.match "[ \t\n]*" s)
|
||||
== null # non-empty
|
||||
&& (builtins.match ".+/" s) == null) # without trailing slash
|
||||
// {description = "${types.str.description} (with check: non-empty without trailing slash)";};
|
||||
types.addCheck types.str (
|
||||
s:
|
||||
(builtins.match "[ \t\n]*" s) == null # non-empty
|
||||
&& (builtins.match ".+/" s) == null
|
||||
) # without trailing slash
|
||||
// {
|
||||
description = "${types.str.description} (with check: non-empty without trailing slash)";
|
||||
};
|
||||
default = "/run/agenix.d";
|
||||
description = ''
|
||||
Where secrets are created before they are symlinked to {option}`age.secretsDir`
|
||||
|
|
@ -233,14 +241,17 @@ in {
|
|||
identityPaths = mkOption {
|
||||
type = types.listOf types.path;
|
||||
default =
|
||||
if isDarwin
|
||||
then [
|
||||
if isDarwin then
|
||||
[
|
||||
"/etc/ssh/ssh_host_ed25519_key"
|
||||
"/etc/ssh/ssh_host_rsa_key"
|
||||
]
|
||||
else if (config.services.openssh.enable or false)
|
||||
then map (e: e.path) (lib.filter (e: e.type == "rsa" || e.type == "ed25519") config.services.openssh.hostKeys)
|
||||
else [];
|
||||
else if (config.services.openssh.enable or false) then
|
||||
map (e: e.path) (
|
||||
lib.filter (e: e.type == "rsa" || e.type == "ed25519") config.services.openssh.hostKeys
|
||||
)
|
||||
else
|
||||
[ ];
|
||||
defaultText = literalExpression ''
|
||||
if isDarwin
|
||||
then [
|
||||
|
|
@ -277,13 +288,11 @@ in {
|
|||
path = [ pkgs.mount ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = pkgs.writeShellScript "agenix-install" (
|
||||
concatLines [
|
||||
ExecStart = pkgs.writeShellScript "agenix-install" (concatLines [
|
||||
newGeneration
|
||||
installSecrets
|
||||
chownSecrets
|
||||
]
|
||||
);
|
||||
]);
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
replaceVars,
|
||||
ageBin ? "${age}/bin/age",
|
||||
shellcheck,
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
bin = "${placeholder "out"}/bin/agenix";
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# Do not copy this! It is insecure. This is only okay because we are testing.
|
||||
{config, ...}: {
|
||||
{ config, ... }:
|
||||
{
|
||||
system.activationScripts.agenixInstall.deps = [ "installSSHHostKeys" ];
|
||||
|
||||
system.activationScripts.installSSHHostKeys.text = ''
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
nixpkgs ? <nixpkgs>,
|
||||
pkgs ?
|
||||
import <nixpkgs> {
|
||||
pkgs ? import <nixpkgs> {
|
||||
inherit system;
|
||||
config = { };
|
||||
},
|
||||
|
|
@ -10,12 +9,14 @@
|
|||
}:
|
||||
pkgs.nixosTest {
|
||||
name = "agenix-integration";
|
||||
nodes.system1 = {
|
||||
nodes.system1 =
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
options,
|
||||
...
|
||||
}: {
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
../modules/age.nix
|
||||
./install_ssh_host_keys.nix
|
||||
|
|
@ -47,7 +48,9 @@ pkgs.nixosTest {
|
|||
};
|
||||
};
|
||||
|
||||
home-manager.users.user1 = {options, ...}: {
|
||||
home-manager.users.user1 =
|
||||
{ options, ... }:
|
||||
{
|
||||
imports = [
|
||||
../modules/age-home.nix
|
||||
];
|
||||
|
|
@ -71,13 +74,15 @@ pkgs.nixosTest {
|
|||
};
|
||||
};
|
||||
|
||||
testScript = let
|
||||
testScript =
|
||||
let
|
||||
user = "user1";
|
||||
password = "password1234";
|
||||
secret2 = "world!";
|
||||
hyphen-secret = "filename started with hyphen";
|
||||
armored-secret = "Hello World!";
|
||||
in ''
|
||||
in
|
||||
''
|
||||
system1.wait_for_unit("multi-user.target")
|
||||
system1.wait_until_succeeds("pgrep -f 'agetty.*tty1'")
|
||||
system1.sleep(2)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
pkgs,
|
||||
options,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
secret = "hello";
|
||||
testScript = pkgs.writeShellApplication {
|
||||
name = "agenix-integration";
|
||||
|
|
@ -11,7 +12,8 @@
|
|||
grep "${secret}" "${config.age.secrets.system-secret.path}"
|
||||
'';
|
||||
};
|
||||
in {
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./install_ssh_host_keys_darwin.nix
|
||||
../modules/age.nix
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
options,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
}:
|
||||
{
|
||||
imports = [ ../modules/age-home.nix ];
|
||||
|
||||
age = {
|
||||
|
|
@ -18,14 +19,18 @@
|
|||
stateVersion = lib.trivial.release;
|
||||
};
|
||||
|
||||
home.file = let
|
||||
home.file =
|
||||
let
|
||||
name = "agenix-home-integration";
|
||||
in {
|
||||
in
|
||||
{
|
||||
${name}.source = pkgs.writeShellApplication {
|
||||
inherit name;
|
||||
text = let
|
||||
text =
|
||||
let
|
||||
secret = "world!";
|
||||
in ''
|
||||
in
|
||||
''
|
||||
diff -q "${config.age.secrets.user-secret.path}" <(printf '${secret}\n')
|
||||
'';
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue