feat: USDA-dash now uses encrypted .env files
All checks were successful
CI / Format Check (push) Successful in 2s
CI / Flake Check (push) Successful in 1m42s
CI / Evaluate Key Configurations (nix-builder) (push) Successful in 14s
CI / Evaluate Key Configurations (nix-desktop1) (push) Successful in 8s
CI / Evaluate Key Configurations (nix-laptop1) (push) Successful in 9s
CI / Evaluate Artifacts (installer-iso-nix-laptop1) (push) Successful in 20s
CI / Evaluate Artifacts (lxc-nix-builder) (push) Successful in 13s
CI / Build and Publish Documentation (push) Successful in 10s
All checks were successful
CI / Format Check (push) Successful in 2s
CI / Flake Check (push) Successful in 1m42s
CI / Evaluate Key Configurations (nix-builder) (push) Successful in 14s
CI / Evaluate Key Configurations (nix-desktop1) (push) Successful in 8s
CI / Evaluate Key Configurations (nix-laptop1) (push) Successful in 9s
CI / Evaluate Artifacts (installer-iso-nix-laptop1) (push) Successful in 20s
CI / Evaluate Artifacts (lxc-nix-builder) (push) Successful in 13s
CI / Build and Publish Documentation (push) Successful in 10s
This commit is contained in:
66
fleet/fs.nix
66
fleet/fs.nix
@@ -27,42 +27,44 @@ in
|
||||
};
|
||||
filesystem = {
|
||||
device = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The main disk device to use for automated partitioning and installation.
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The main disk device to use for automated partitioning and installation.
|
||||
|
||||
When set, enables disko for declarative disk management with:
|
||||
- 1GB EFI boot partition
|
||||
- Optional swap partition (see swapSize)
|
||||
- Root partition using remaining space
|
||||
When set, enables disko for declarative disk management with:
|
||||
- 1GB EFI boot partition
|
||||
- Optional swap partition (see swapSize)
|
||||
- Root partition using remaining space
|
||||
|
||||
Leave null for systems that don't need disk partitioning (containers, WSL).
|
||||
'';
|
||||
example = "/dev/nvme0n1";
|
||||
};
|
||||
useSwap = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to create and use a swap partition.
|
||||
Disable for systems with ample RAM or SSDs where swap is undesirable.
|
||||
'';
|
||||
};
|
||||
swapSize = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Size of the swap partition (e.g., "16G", "32G").
|
||||
Leave null for systems that don't need disk partitioning (containers, WSL).
|
||||
'';
|
||||
example = "/dev/nvme0n1";
|
||||
};
|
||||
useSwap = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to create and use a swap partition.
|
||||
Disable for systems with ample RAM or SSDs where swap is undesirable.
|
||||
'';
|
||||
};
|
||||
swapSize = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Size of the swap partition (e.g., "16G", "32G").
|
||||
|
||||
Recommended sizes:
|
||||
- 8-16GB for desktops with 16GB+ RAM
|
||||
- 32GB for laptops (enables hibernation)
|
||||
- Match RAM size for systems <8GB RAM
|
||||
'';
|
||||
example = "32G";
|
||||
Recommended sizes:
|
||||
- 8-16GB for desktops with 16GB+ RAM
|
||||
- 32GB for laptops (enables hibernation)
|
||||
- Match RAM size for systems <8GB RAM
|
||||
'';
|
||||
example = "32G";
|
||||
};
|
||||
};
|
||||
}; }; };
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
|
||||
46
secrets.nix
46
secrets.nix
@@ -54,27 +54,10 @@ let
|
||||
in
|
||||
lenStr >= lenSuffix && lib.substring (lenStr - lenSuffix) lenSuffix str == suffix;
|
||||
|
||||
hasPrefix =
|
||||
prefix: str:
|
||||
let
|
||||
lenPrefix = lib.stringLength prefix;
|
||||
in
|
||||
lib.stringLength str >= lenPrefix && lib.substring 0 lenPrefix str == prefix;
|
||||
|
||||
nameValuePair = name: value: { inherit name value; };
|
||||
|
||||
secretsPath = ./secrets;
|
||||
|
||||
# Helper to convert SSH public key content to age public key
|
||||
sshToAge =
|
||||
sshPubKey:
|
||||
let
|
||||
# This is a simple check - in practice, use ssh-to-age tool
|
||||
# For now, we'll just use the keys as-is if they look like age keys
|
||||
trimmed = lib.replaceStrings [ "\n" ] [ "" ] sshPubKey;
|
||||
in
|
||||
if lib.substring 0 4 trimmed == "age1" then trimmed else null; # Will need manual conversion with ssh-to-age
|
||||
|
||||
# Read all directories in secrets/
|
||||
secretDirs = if lib.pathExists secretsPath then lib.readDir secretsPath else { };
|
||||
|
||||
@@ -181,22 +164,23 @@ let
|
||||
|
||||
# Generate wildcard rules for each directory to allow creating new secrets
|
||||
wildcardRules = lib.listToAttrs (
|
||||
lib.concatMap (
|
||||
dir:
|
||||
[
|
||||
# Match with and without .age extension for ragenix compatibility
|
||||
(nameValuePair "secrets/${dir}/*" {
|
||||
publicKeys = let
|
||||
lib.concatMap (dir: [
|
||||
# Match with and without .age extension for ragenix compatibility
|
||||
(nameValuePair "secrets/${dir}/*" {
|
||||
publicKeys =
|
||||
let
|
||||
recipients = getRecipients "secrets/${dir}/dummy.age";
|
||||
in unique (lib.filter (k: k != null && k != "") recipients);
|
||||
})
|
||||
(nameValuePair "secrets/${dir}/*.age" {
|
||||
publicKeys = let
|
||||
in
|
||||
unique (lib.filter (k: k != null && k != "") recipients);
|
||||
})
|
||||
(nameValuePair "secrets/${dir}/*.age" {
|
||||
publicKeys =
|
||||
let
|
||||
recipients = getRecipients "secrets/${dir}/dummy.age";
|
||||
in unique (lib.filter (k: k != null && k != "") recipients);
|
||||
})
|
||||
]
|
||||
) (lib.filter (d: d != "admins") directories)
|
||||
in
|
||||
unique (lib.filter (k: k != null && k != "") recipients);
|
||||
})
|
||||
]) (lib.filter (d: d != "admins") directories)
|
||||
);
|
||||
|
||||
in
|
||||
|
||||
@@ -54,27 +54,10 @@ let
|
||||
in
|
||||
lenStr >= lenSuffix && lib.substring (lenStr - lenSuffix) lenSuffix str == suffix;
|
||||
|
||||
hasPrefix =
|
||||
prefix: str:
|
||||
let
|
||||
lenPrefix = lib.stringLength prefix;
|
||||
in
|
||||
lib.stringLength str >= lenPrefix && lib.substring 0 lenPrefix str == prefix;
|
||||
|
||||
nameValuePair = name: value: { inherit name value; };
|
||||
|
||||
secretsPath = ./secrets;
|
||||
|
||||
# Helper to convert SSH public key content to age public key
|
||||
sshToAge =
|
||||
sshPubKey:
|
||||
let
|
||||
# This is a simple check - in practice, use ssh-to-age tool
|
||||
# For now, we'll just use the keys as-is if they look like age keys
|
||||
trimmed = lib.replaceStrings [ "\n" ] [ "" ] sshPubKey;
|
||||
in
|
||||
if lib.substring 0 4 trimmed == "age1" then trimmed else null; # Will need manual conversion with ssh-to-age
|
||||
|
||||
# Read all directories in secrets/
|
||||
secretDirs = if lib.pathExists secretsPath then lib.readDir secretsPath else { };
|
||||
|
||||
|
||||
@@ -195,7 +195,10 @@ in
|
||||
# This is needed because age can't reliably use OpenSSH private keys directly
|
||||
# Must run before agenix tries to decrypt secrets
|
||||
system.activationScripts.convertSshToAge = {
|
||||
deps = [ "users" "groups" ];
|
||||
deps = [
|
||||
"users"
|
||||
"groups"
|
||||
];
|
||||
text = ''
|
||||
mkdir -p /etc/age
|
||||
if [ -f /etc/ssh/ssh_host_ed25519_key ]; then
|
||||
|
||||
Reference in New Issue
Block a user