mirror of
https://github.com/Swarsel/.dotfiles.git
synced 2025-12-06 09:07:21 +01:00
feat: new deploy system, allows for in-repo pii
This commit is contained in:
parent
7e11641fe7
commit
a11c7854d1
19 changed files with 1251 additions and 412 deletions
1
.envrc
Normal file
1
.envrc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
use flake
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -4,3 +4,4 @@ result
|
||||||
*.~undo-tree~
|
*.~undo-tree~
|
||||||
*.iso
|
*.iso
|
||||||
.pre-commit-config.yaml
|
.pre-commit-config.yaml
|
||||||
|
.direnv
|
||||||
|
|
|
||||||
10
.sops.yaml
10
.sops.yaml
|
|
@ -21,6 +21,16 @@ creation_rules:
|
||||||
- *toto
|
- *toto
|
||||||
- *surface
|
- *surface
|
||||||
- *nbl
|
- *nbl
|
||||||
|
- path_regex: secrets/repo/[^/]+$
|
||||||
|
key_groups:
|
||||||
|
- pgp:
|
||||||
|
- *swarsel
|
||||||
|
age:
|
||||||
|
- *winters
|
||||||
|
- *toto
|
||||||
|
- *surface
|
||||||
|
- *nbl
|
||||||
|
- *sync
|
||||||
- path_regex: secrets/certs/[^/]+\.(yaml|json|env|ini)$
|
- path_regex: secrets/certs/[^/]+\.(yaml|json|env|ini)$
|
||||||
key_groups:
|
key_groups:
|
||||||
- pgp:
|
- pgp:
|
||||||
|
|
|
||||||
|
|
@ -340,66 +340,74 @@ In this section I am creating some attributes that define general concepts of my
|
||||||
They are defined in [[#h:5e3e21e0-57af-4dad-b32f-6400af9b7aab][Overlays (additions, overrides, nixpkgs-stable)]]. The way this is handled was simplified in =647a2ae feat: simplify overlay structure=; however, the old structure might be easier to understand as a reference.
|
They are defined in [[#h:5e3e21e0-57af-4dad-b32f-6400af9b7aab][Overlays (additions, overrides, nixpkgs-stable)]]. The way this is handled was simplified in =647a2ae feat: simplify overlay structure=; however, the old structure might be easier to understand as a reference.
|
||||||
|
|
||||||
#+begin_src nix :tangle no :noweb-ref flakeoutputgeneral
|
#+begin_src nix :tangle no :noweb-ref flakeoutputgeneral
|
||||||
inherit lib;
|
inherit lib;
|
||||||
|
|
||||||
# nixosModules = import ./modules/nixos { inherit lib; };
|
# nixosModules = import ./modules/nixos { inherit lib; };
|
||||||
# homeModules = import ./modules/home { inherit lib; };
|
# homeModules = import ./modules/home { inherit lib; };
|
||||||
packages = lib.swarselsystems.forEachSystem (pkgs: import ./pkgs { inherit lib pkgs; });
|
packages = lib.swarselsystems.forEachSystem (pkgs: import ./pkgs { inherit lib pkgs; });
|
||||||
formatter = lib.swarselsystems.forEachSystem (pkgs: pkgs.nixpkgs-fmt);
|
formatter = lib.swarselsystems.forEachSystem (pkgs: pkgs.nixpkgs-fmt);
|
||||||
overlays = import ./overlays { inherit self lib inputs; };
|
overlays = import ./overlays { inherit self lib inputs; };
|
||||||
|
|
||||||
apps = lib.swarselsystems.forAllSystems (system:
|
apps = lib.swarselsystems.forAllSystems (system:
|
||||||
let
|
let
|
||||||
appNames = [
|
appNames = [
|
||||||
"swarsel-bootstrap"
|
"swarsel-bootstrap"
|
||||||
"swarsel-install"
|
"swarsel-install"
|
||||||
"swarsel-rebuild"
|
"swarsel-rebuild"
|
||||||
"swarsel-postinstall"
|
"swarsel-postinstall"
|
||||||
];
|
|
||||||
appSet = lib.swarselsystems.mkApps system appNames self;
|
|
||||||
in
|
|
||||||
|
|
||||||
appSet // {
|
|
||||||
default = appSet.swarsel-bootstrap;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
devShells = lib.swarselsystems.forAllSystems (system:
|
|
||||||
let
|
|
||||||
pkgs = lib.swarselsystems.pkgsFor.${system};
|
|
||||||
checks = self.checks.${system};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
default = pkgs.mkShell {
|
|
||||||
NIX_CONFIG = "experimental-features = nix-command flakes";
|
|
||||||
inherit (checks.pre-commit-check) shellHook;
|
|
||||||
buildInputs = checks.pre-commit-check.enabledPackages;
|
|
||||||
nativeBuildInputs = [
|
|
||||||
pkgs.nix
|
|
||||||
pkgs.home-manager
|
|
||||||
pkgs.git
|
|
||||||
pkgs.just
|
|
||||||
pkgs.age
|
|
||||||
pkgs.ssh-to-age
|
|
||||||
pkgs.sops
|
|
||||||
pkgs.statix
|
|
||||||
pkgs.deadnix
|
|
||||||
pkgs.nixpkgs-fmt
|
|
||||||
];
|
];
|
||||||
};
|
appSet = lib.swarselsystems.mkApps system appNames self;
|
||||||
}
|
in
|
||||||
);
|
|
||||||
|
|
||||||
templates = import ./templates { inherit lib; };
|
appSet // {
|
||||||
|
default = appSet.swarsel-bootstrap;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
checks = lib.swarselsystems.forAllSystems (system:
|
devShells = lib.swarselsystems.forAllSystems (system:
|
||||||
let
|
let
|
||||||
pkgs = lib.swarselsystems.pkgsFor.${system};
|
pkgs = lib.swarselsystems.pkgsFor.${system};
|
||||||
in
|
checks = self.checks.${system};
|
||||||
import ./checks { inherit self inputs system pkgs; }
|
in
|
||||||
);
|
{
|
||||||
|
default = pkgs.mkShell {
|
||||||
|
NIX_CONFIG = ''
|
||||||
|
plugin-files = ${pkgs.nix-plugins.overrideAttrs (o: {
|
||||||
|
buildInputs = [pkgs.nixVersions.latest pkgs.boost];
|
||||||
|
patches = (o.patches or []) ++ [ "${self}/nix/nix-plugins.patch" ];
|
||||||
|
})}/lib/nix/plugins
|
||||||
|
extra-builtins-file = ${self + /nix/extra-builtins.nix}
|
||||||
|
'';
|
||||||
|
inherit (checks.pre-commit-check) shellHook;
|
||||||
|
|
||||||
diskoConfigurations.default = import .templates/hosts/nixos/disk-config.nix;
|
buildInputs = checks.pre-commit-check.enabledPackages;
|
||||||
|
nativeBuildInputs = [
|
||||||
|
# (builtins.trace "alarm: we pinned nix_2_24 because of https://github.com/shlevy/nix-plugins/issues/20" pkgs.nixVersions.nix_2_24) # Always use the nix version from this flake's nixpkgs version, so that nix-plugins (below) doesn't fail because of different nix versions.
|
||||||
|
pkgs.nix
|
||||||
|
pkgs.home-manager
|
||||||
|
pkgs.git
|
||||||
|
pkgs.just
|
||||||
|
pkgs.age
|
||||||
|
pkgs.ssh-to-age
|
||||||
|
pkgs.sops
|
||||||
|
pkgs.statix
|
||||||
|
pkgs.deadnix
|
||||||
|
pkgs.nixpkgs-fmt
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
templates = import ./templates { inherit lib; };
|
||||||
|
|
||||||
|
checks = lib.swarselsystems.forAllSystems (system:
|
||||||
|
let
|
||||||
|
pkgs = lib.swarselsystems.pkgsFor.${system};
|
||||||
|
in
|
||||||
|
import ./checks { inherit self inputs system pkgs; }
|
||||||
|
);
|
||||||
|
|
||||||
|
diskoConfigurations.default = import .templates/hosts/nixos/disk-config.nix;
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Pre-commit-hooks (Checks)
|
** Pre-commit-hooks (Checks)
|
||||||
|
|
@ -849,7 +857,7 @@ My work machine. Built for more security, this is the gold standard of my config
|
||||||
sharedOptions;
|
sharedOptions;
|
||||||
|
|
||||||
home-manager.users."${primaryUser}" = {
|
home-manager.users."${primaryUser}" = {
|
||||||
home.stateVersion = lib.mkForce "23.05";
|
# home.stateVersion = lib.mkForce "23.05";
|
||||||
swarselsystems = lib.recursiveUpdate
|
swarselsystems = lib.recursiveUpdate
|
||||||
{
|
{
|
||||||
isLaptop = true;
|
isLaptop = true;
|
||||||
|
|
@ -3685,6 +3693,136 @@ AppImage version of mgba in which the lua scripting works.
|
||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
**** swarsel-deploy
|
||||||
|
|
||||||
|
#+begin_src nix :tangle pkgs/swarsel-deploy/default.nix
|
||||||
|
# heavily inspired from https://github.com/oddlama/nix-config/blob/d42cbde676001a7ad8a3cace156e050933a4dcc3/pkgs/deploy.nix
|
||||||
|
{ name, bc, nix-output-monitor, writeShellApplication, ... }:
|
||||||
|
writeShellApplication {
|
||||||
|
runtimeInputs = [ bc nix-output-monitor ];
|
||||||
|
inherit name;
|
||||||
|
text = ''
|
||||||
|
set -euo pipefail
|
||||||
|
shopt -s lastpipe # allow cmd | readarray
|
||||||
|
|
||||||
|
function die() {
|
||||||
|
echo "error: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
function show_help() {
|
||||||
|
echo 'Usage: deploy [OPTIONS] <host,...> [ACTION]'
|
||||||
|
echo "Builds, pushes and activates nixosConfigurations on target systems."
|
||||||
|
echo ""
|
||||||
|
echo 'ACTION:'
|
||||||
|
echo ' switch [default] Switch immediately to the new configuration and make it the boot default'
|
||||||
|
echo ' boot Make the configuration the new boot default'
|
||||||
|
echo " test Activate the configuration but don't make it the boot default"
|
||||||
|
echo " dry-activate Don't activate, just show what would be done"
|
||||||
|
echo ""
|
||||||
|
echo 'OPTIONS: [passed to nix build]'
|
||||||
|
}
|
||||||
|
|
||||||
|
function time_start() {
|
||||||
|
T_START=$(date +%s.%N)
|
||||||
|
}
|
||||||
|
|
||||||
|
function time_next() {
|
||||||
|
T_END=$(date +%s.%N)
|
||||||
|
T_LAST=$(${bc}/bin/bc <<< "scale=1; ($T_END - $T_START)/1")
|
||||||
|
T_START="$T_END"
|
||||||
|
}
|
||||||
|
|
||||||
|
cd ~/.dotfiles
|
||||||
|
USER_FLAKE_DIR=$(git rev-parse --show-toplevel 2> /dev/null || pwd) ||
|
||||||
|
die "Could not determine current working directory. Something went very wrong."
|
||||||
|
[[ -e "$USER_FLAKE_DIR/flake.nix" ]] ||
|
||||||
|
die "Could not determine location of your project's flake.nix. Please run this at or below your main directory containing the flake.nix."
|
||||||
|
cd "$USER_FLAKE_DIR"
|
||||||
|
|
||||||
|
[[ $# -gt 0 ]] || {
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
OPTIONS=()
|
||||||
|
POSITIONAL_ARGS=()
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
"help" | "--help" | "-help" | "-h")
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
-*) OPTIONS+=("$1") ;;
|
||||||
|
,*) POSITIONAL_ARGS+=("$1") ;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ ''${#POSITIONAL_ARGS[@]} -ge 1 ]] ||
|
||||||
|
die "Missing argument: <hosts...>"
|
||||||
|
[[ ''${#POSITIONAL_ARGS[@]} -le 2 ]] ||
|
||||||
|
die "Too many arguments given."
|
||||||
|
|
||||||
|
tr , '\n' <<< "''${POSITIONAL_ARGS[0]}" | sort -u | readarray -t HOSTS
|
||||||
|
ACTION="''${POSITIONAL_ARGS[1]-switch}"
|
||||||
|
|
||||||
|
# Expand flake paths for hosts definitions
|
||||||
|
declare -A TOPLEVEL_FLAKE_PATHS
|
||||||
|
for host in "''${HOSTS[@]}"; do
|
||||||
|
TOPLEVEL_FLAKE_PATHS["$host"]=".#nixosConfigurations.$host.config.system.build.toplevel"
|
||||||
|
done
|
||||||
|
|
||||||
|
time_start
|
||||||
|
|
||||||
|
# Get outputs of all derivations (should be cached)
|
||||||
|
declare -A TOPLEVEL_STORE_PATHS
|
||||||
|
for host in "''${HOSTS[@]}"; do
|
||||||
|
toplevel="''${TOPLEVEL_FLAKE_PATHS["$host"]}"
|
||||||
|
echo "[1;36m Building [m📦 [34m$host[m"
|
||||||
|
nix build --no-link "''${OPTIONS[@]}" --show-trace --log-format internal-json -v "$toplevel" |& ${nix-output-monitor}/bin/nom --json ||
|
||||||
|
die "Failed to get derivation path for $host from ''${TOPLEVEL_FLAKE_PATHS["$host"]}"
|
||||||
|
TOPLEVEL_STORE_PATHS["$host"]=$(nix build --no-link --print-out-paths "''${OPTIONS[@]}" "$toplevel")
|
||||||
|
time_next
|
||||||
|
echo "[1;32m Built [m✅ [34m$host[m [33m''${TOPLEVEL_STORE_PATHS["$host"]}[m [90min ''${T_LAST}s[m"
|
||||||
|
done
|
||||||
|
|
||||||
|
current_host=$(hostname)
|
||||||
|
|
||||||
|
for host in "''${HOSTS[@]}"; do
|
||||||
|
store_path="''${TOPLEVEL_STORE_PATHS["$host"]}"
|
||||||
|
|
||||||
|
if [ "$host" = "$current_host" ]; then
|
||||||
|
echo -e "\033[1;36m Running locally for $host... \033[m"
|
||||||
|
ssh_prefix="sudo"
|
||||||
|
else
|
||||||
|
echo -e "\033[1;36m Copying \033[m➡️ \033[34m$host\033[m"
|
||||||
|
nix copy --to "ssh://$host" "$store_path"
|
||||||
|
time_next
|
||||||
|
echo -e "\033[1;32m Copied \033[m✅ \033[34m$host\033[m \033[90min ''${T_LAST}s\033[m"
|
||||||
|
ssh_prefix="ssh $host --"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\033[1;36m Applying \033[m⚙️ \033[34m$host\033[m"
|
||||||
|
prev_system=$($ssh_prefix readlink -e /nix/var/nix/profiles/system)
|
||||||
|
$ssh_prefix /run/current-system/sw/bin/nix-env --profile /nix/var/nix/profiles/system --set "$store_path" ||
|
||||||
|
die "Failed to set system profile"
|
||||||
|
$ssh_prefix "$store_path"/bin/switch-to-configuration "$ACTION" ||
|
||||||
|
echo "Error while activating new system" >&2
|
||||||
|
|
||||||
|
if [[ -n $prev_system ]]; then
|
||||||
|
$ssh_prefix nvd --color always diff "$prev_system" "$store_path" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
time_next
|
||||||
|
echo -e "\033[1;32m Applied \033[m✅ \033[34m$host\033[m \033[90min ''${T_LAST}s\033[m"
|
||||||
|
done
|
||||||
|
cd -
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
||||||
|
#+end_src
|
||||||
|
|
||||||
**** sshrm
|
**** sshrm
|
||||||
|
|
||||||
This programs simply runs ssh-keygen on the last host that I tried to ssh into. I need this frequently when working with cloud-init usually.
|
This programs simply runs ssh-keygen on the last host that I tried to ssh into. I need this frequently when working with cloud-init usually.
|
||||||
|
|
@ -3886,6 +4024,10 @@ Modules that need to be loaded on the NixOS level. Note that these will not be a
|
||||||
autologin = lib.mkDefault true;
|
autologin = lib.mkDefault true;
|
||||||
nswitch-rcm = lib.mkDefault true;
|
nswitch-rcm = lib.mkDefault true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
server = {
|
||||||
|
ssh = lib.mkDefault true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -4490,8 +4632,6 @@ TODO
|
||||||
{
|
{
|
||||||
home-manager.users."${linuxUser}".imports = [
|
home-manager.users."${linuxUser}".imports = [
|
||||||
# put home-manager imports here that are for all normal hosts
|
# put home-manager imports here that are for all normal hosts
|
||||||
inputs.sops-nix.homeManagerModules.sops
|
|
||||||
inputs.nix-index-database.hmModules.nix-index
|
|
||||||
"${self}/modules/home/common"
|
"${self}/modules/home/common"
|
||||||
"${self}/modules/home/server"
|
"${self}/modules/home/server"
|
||||||
"${self}/modules/home/optional"
|
"${self}/modules/home/optional"
|
||||||
|
|
@ -4597,6 +4737,83 @@ TODO
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
*** Auxiliary files
|
||||||
|
**** extra-builtins
|
||||||
|
|
||||||
|
#+begin_src nix :tangle nix/extra-builtins.nix
|
||||||
|
|
||||||
|
{ exec, ... }:
|
||||||
|
let
|
||||||
|
assertMsg = pred: msg: pred || builtins.throw msg;
|
||||||
|
hasSuffix =
|
||||||
|
suffix: content:
|
||||||
|
let
|
||||||
|
lenContent = builtins.stringLength content;
|
||||||
|
lenSuffix = builtins.stringLength suffix;
|
||||||
|
in
|
||||||
|
lenContent >= lenSuffix && builtins.substring (lenContent - lenSuffix) lenContent content == suffix;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Instead of calling sops directly here, we call a wrapper script that will cache the output
|
||||||
|
# in a predictable path in /tmp, which allows us to only require the password for each encrypted
|
||||||
|
# file once.
|
||||||
|
sopsImportEncrypted =
|
||||||
|
nixFile:
|
||||||
|
assert assertMsg (builtins.isPath nixFile)
|
||||||
|
"The file to decrypt must be given as a path to prevent impurity.";
|
||||||
|
assert assertMsg (hasSuffix ".nix.age" nixFile)
|
||||||
|
"The content of the decrypted file must be a nix expression and should therefore end in .nix.age";
|
||||||
|
exec [
|
||||||
|
./sops-decrypt-and-cache.sh
|
||||||
|
nixFile
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
#+end_src
|
||||||
|
**** sops-decrypt-and-cache
|
||||||
|
|
||||||
|
#+begin_src shell :tangle nix/sops-decrypt-and-cache.sh
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
print_out_path=false
|
||||||
|
if [[ $1 == "--print-out-path" ]]; then
|
||||||
|
print_out_path=true
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
file="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
basename="$file"
|
||||||
|
# store path prefix or ./ if applicable
|
||||||
|
[[ $file == "/nix/store/"* ]] && basename="${basename#*"-"}"
|
||||||
|
[[ $file == "./"* ]] && basename="${basename#"./"}"
|
||||||
|
|
||||||
|
# Calculate a unique content-based identifier (relocations of
|
||||||
|
# the source file in the nix store should not affect caching)
|
||||||
|
new_name="$(sha512sum "$file")"
|
||||||
|
new_name="${new_name:0:32}-${basename//"/"/"%"}"
|
||||||
|
|
||||||
|
# Derive the path where the decrypted file will be stored
|
||||||
|
out="/var/tmp/nix-import-encrypted/$UID/$new_name"
|
||||||
|
umask 077
|
||||||
|
mkdir -p "$(dirname "$out")"
|
||||||
|
|
||||||
|
# Decrypt only if necessary
|
||||||
|
if [[ ! -e $out ]]; then
|
||||||
|
agekey=$(sudo ssh-to-age -private-key -i /etc/ssh/sops || sudo ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key)
|
||||||
|
SOPS_AGE_KEY="$agekey" sops decrypt --output "$out" "$file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Print out path or decrypted content
|
||||||
|
if [[ $print_out_path == true ]]; then
|
||||||
|
echo "$out"
|
||||||
|
else
|
||||||
|
cat "$out"
|
||||||
|
fi
|
||||||
|
#+end_src
|
||||||
** NixOS
|
** NixOS
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: h:6da812f5-358c-49cb-aff2-0a94f20d70b3
|
:CUSTOM_ID: h:6da812f5-358c-49cb-aff2-0a94f20d70b3
|
||||||
|
|
@ -4858,6 +5075,14 @@ We enable the use of =home-manager= as a NixoS module. A nice trick here is the
|
||||||
home-manager = lib.mkIf config.swarselsystems.withHomeManager {
|
home-manager = lib.mkIf config.swarselsystems.withHomeManager {
|
||||||
useGlobalPkgs = true;
|
useGlobalPkgs = true;
|
||||||
useUserPackages = true;
|
useUserPackages = true;
|
||||||
|
verbose = true;
|
||||||
|
sharedModules = [
|
||||||
|
inputs.nix-index-database.hmModules.nix-index
|
||||||
|
inputs.sops-nix.homeManagerModules.sops
|
||||||
|
{
|
||||||
|
home.stateVersion = lib.mkDefault config.system.stateVersion;
|
||||||
|
}
|
||||||
|
];
|
||||||
extraSpecialArgs = { inherit (inputs) self; };
|
extraSpecialArgs = { inherit (inputs) self; };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -6450,7 +6675,7 @@ This dynamically uses systemd boot or Lanzaboote depending on `config.swarselsys
|
||||||
lanzaboote = lib.mkIf (!config.swarselsystems.initialSetup && config.swarselsystems.isSecureBoot) {
|
lanzaboote = lib.mkIf (!config.swarselsystems.initialSetup && config.swarselsystems.isSecureBoot) {
|
||||||
enable = true;
|
enable = true;
|
||||||
pkiBundle = "/var/lib/sbctl";
|
pkiBundle = "/var/lib/sbctl";
|
||||||
configurationLimit = 3;
|
configurationLimit = 6;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -6555,6 +6780,7 @@ Here we just define some aliases for rebuilding the system, and we allow some in
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
gnupg
|
gnupg
|
||||||
nix-index
|
nix-index
|
||||||
|
nvd
|
||||||
ssh-to-age
|
ssh-to-age
|
||||||
git
|
git
|
||||||
emacs
|
emacs
|
||||||
|
|
@ -6695,6 +6921,8 @@ Here we just define some aliases for rebuilding the system, and we allow some in
|
||||||
:CUSTOM_ID: h:f3db197d-1d03-4bf8-b59f-f9891b358f0b
|
:CUSTOM_ID: h:f3db197d-1d03-4bf8-b59f-f9891b358f0b
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
|
Here I am forcing =startWhenNeeded= to false so that the value will not be set to true in containers = this would be a problem because it would delay ssh host key generation.
|
||||||
|
|
||||||
#+begin_src nix :tangle modules/nixos/server/ssh.nix
|
#+begin_src nix :tangle modules/nixos/server/ssh.nix
|
||||||
{ self, lib, config, ... }:
|
{ self, lib, config, ... }:
|
||||||
{
|
{
|
||||||
|
|
@ -6702,6 +6930,18 @@ Here we just define some aliases for rebuilding the system, and we allow some in
|
||||||
config = lib.mkIf config.swarselsystems.modules.server.ssh {
|
config = lib.mkIf config.swarselsystems.modules.server.ssh {
|
||||||
services.openssh = {
|
services.openssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
startWhenNeeded = lib.mkForce false;
|
||||||
|
settings = {
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
KbdInteractiveAuthentication = false;
|
||||||
|
PermitRootLogin = "yes";
|
||||||
|
};
|
||||||
|
hostKeys = [
|
||||||
|
{
|
||||||
|
path = "/etc/ssh/ssh_host_ed25519_key";
|
||||||
|
type = "ed25519";
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
users.users."${config.swarselsystems.mainUser}".openssh.authorizedKeys.keyFiles = [
|
users.users."${config.swarselsystems.mainUser}".openssh.authorizedKeys.keyFiles = [
|
||||||
(self + /secrets/keys/ssh/yubikey.pub)
|
(self + /secrets/keys/ssh/yubikey.pub)
|
||||||
|
|
@ -10166,6 +10406,7 @@ This is just a separate container for derivations defined in [[#h:64a5cc16-6b16-
|
||||||
fhs
|
fhs
|
||||||
swarsel-bootstrap
|
swarsel-bootstrap
|
||||||
swarsel-displaypower
|
swarsel-displaypower
|
||||||
|
swarsel-deploy
|
||||||
swarselzellij
|
swarselzellij
|
||||||
sshrm
|
sshrm
|
||||||
|
|
||||||
|
|
@ -10266,7 +10507,7 @@ It is very convenient to have SSH aliases in place for machines that I use. This
|
||||||
};
|
};
|
||||||
"winters" = {
|
"winters" = {
|
||||||
hostname = "192.168.1.2";
|
hostname = "192.168.1.2";
|
||||||
user = "swarsel";
|
user = "root";
|
||||||
};
|
};
|
||||||
"minecraft" = {
|
"minecraft" = {
|
||||||
hostname = "130.61.119.129";
|
hostname = "130.61.119.129";
|
||||||
|
|
@ -10943,8 +11184,10 @@ Currently I only use it as before with =initExtra= though.
|
||||||
{
|
{
|
||||||
hg = "history | grep";
|
hg = "history | grep";
|
||||||
hmswitch = "home-manager --flake ${flakePath}#$(whoami)@$(hostname) switch |& nom";
|
hmswitch = "home-manager --flake ${flakePath}#$(whoami)@$(hostname) switch |& nom";
|
||||||
nswitch = "sudo nixos-rebuild --flake ${flakePath}#$(hostname) --show-trace --log-format internal-json -v switch |& nom --json";
|
# nswitch = "sudo nixos-rebuild --flake ${flakePath}#$(hostname) --show-trace --log-format internal-json -v switch |& nom --json";
|
||||||
nboot = "sudo nixos-rebuild --flake ${flakePath}#$(hostname) --show-trace --log-format internal-json -v boot |& nom --json";
|
nswitch = "swarsel-deploy $(hostname) switch";
|
||||||
|
# nboot = "sudo nixos-rebuild --flake ${flakePath}#$(hostname) --show-trace --log-format internal-json -v boot |& nom --json";
|
||||||
|
nboot = "swarsel-deploy $(hostname) boot";
|
||||||
magit = "emacsclient -nc -e \"(magit-status)\"";
|
magit = "emacsclient -nc -e \"(magit-status)\"";
|
||||||
config = "git --git-dir=$HOME/.cfg/ --work-tree=$HOME";
|
config = "git --git-dir=$HOME/.cfg/ --work-tree=$HOME";
|
||||||
g = "git";
|
g = "git";
|
||||||
|
|
|
||||||
10
flake.nix
10
flake.nix
|
|
@ -128,10 +128,18 @@
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
default = pkgs.mkShell {
|
default = pkgs.mkShell {
|
||||||
NIX_CONFIG = "experimental-features = nix-command flakes";
|
NIX_CONFIG = ''
|
||||||
|
plugin-files = ${pkgs.nix-plugins.overrideAttrs (o: {
|
||||||
|
buildInputs = [pkgs.nixVersions.latest pkgs.boost];
|
||||||
|
patches = (o.patches or []) ++ [ "${self}/nix/nix-plugins.patch" ];
|
||||||
|
})}/lib/nix/plugins
|
||||||
|
extra-builtins-file = ${self + /nix/extra-builtins.nix}
|
||||||
|
'';
|
||||||
inherit (checks.pre-commit-check) shellHook;
|
inherit (checks.pre-commit-check) shellHook;
|
||||||
|
|
||||||
buildInputs = checks.pre-commit-check.enabledPackages;
|
buildInputs = checks.pre-commit-check.enabledPackages;
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
# (builtins.trace "alarm: we pinned nix_2_24 because of https://github.com/shlevy/nix-plugins/issues/20" pkgs.nixVersions.nix_2_24) # Always use the nix version from this flake's nixpkgs version, so that nix-plugins (below) doesn't fail because of different nix versions.
|
||||||
pkgs.nix
|
pkgs.nix
|
||||||
pkgs.home-manager
|
pkgs.home-manager
|
||||||
pkgs.git
|
pkgs.git
|
||||||
|
|
|
||||||
995
index.html
995
index.html
File diff suppressed because it is too large
Load diff
|
|
@ -71,8 +71,6 @@ in
|
||||||
{
|
{
|
||||||
home-manager.users."${linuxUser}".imports = [
|
home-manager.users."${linuxUser}".imports = [
|
||||||
# put home-manager imports here that are for all normal hosts
|
# put home-manager imports here that are for all normal hosts
|
||||||
inputs.sops-nix.homeManagerModules.sops
|
|
||||||
inputs.nix-index-database.hmModules.nix-index
|
|
||||||
"${self}/modules/home/common"
|
"${self}/modules/home/common"
|
||||||
"${self}/modules/home/server"
|
"${self}/modules/home/server"
|
||||||
"${self}/modules/home/optional"
|
"${self}/modules/home/optional"
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
fhs
|
fhs
|
||||||
swarsel-bootstrap
|
swarsel-bootstrap
|
||||||
swarsel-displaypower
|
swarsel-displaypower
|
||||||
|
swarsel-deploy
|
||||||
swarselzellij
|
swarselzellij
|
||||||
sshrm
|
sshrm
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
};
|
};
|
||||||
"winters" = {
|
"winters" = {
|
||||||
hostname = "192.168.1.2";
|
hostname = "192.168.1.2";
|
||||||
user = "swarsel";
|
user = "root";
|
||||||
};
|
};
|
||||||
"minecraft" = {
|
"minecraft" = {
|
||||||
hostname = "130.61.119.129";
|
hostname = "130.61.119.129";
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,14 @@
|
||||||
home-manager = lib.mkIf config.swarselsystems.withHomeManager {
|
home-manager = lib.mkIf config.swarselsystems.withHomeManager {
|
||||||
useGlobalPkgs = true;
|
useGlobalPkgs = true;
|
||||||
useUserPackages = true;
|
useUserPackages = true;
|
||||||
|
verbose = true;
|
||||||
|
sharedModules = [
|
||||||
|
inputs.nix-index-database.hmModules.nix-index
|
||||||
|
inputs.sops-nix.homeManagerModules.sops
|
||||||
|
{
|
||||||
|
home.stateVersion = lib.mkDefault config.system.stateVersion;
|
||||||
|
}
|
||||||
|
];
|
||||||
extraSpecialArgs = { inherit (inputs) self; };
|
extraSpecialArgs = { inherit (inputs) self; };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
lanzaboote = lib.mkIf (!config.swarselsystems.initialSetup && config.swarselsystems.isSecureBoot) {
|
lanzaboote = lib.mkIf (!config.swarselsystems.initialSetup && config.swarselsystems.isSecureBoot) {
|
||||||
enable = true;
|
enable = true;
|
||||||
pkiBundle = "/var/lib/sbctl";
|
pkiBundle = "/var/lib/sbctl";
|
||||||
configurationLimit = 3;
|
configurationLimit = 6;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
gnupg
|
gnupg
|
||||||
nix-index
|
nix-index
|
||||||
|
nvd
|
||||||
ssh-to-age
|
ssh-to-age
|
||||||
git
|
git
|
||||||
emacs
|
emacs
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,18 @@
|
||||||
config = lib.mkIf config.swarselsystems.modules.server.ssh {
|
config = lib.mkIf config.swarselsystems.modules.server.ssh {
|
||||||
services.openssh = {
|
services.openssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
startWhenNeeded = lib.mkForce false;
|
||||||
|
settings = {
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
KbdInteractiveAuthentication = false;
|
||||||
|
PermitRootLogin = "yes";
|
||||||
|
};
|
||||||
|
hostKeys = [
|
||||||
|
{
|
||||||
|
path = "/etc/ssh/ssh_host_ed25519_key";
|
||||||
|
type = "ed25519";
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
users.users."${config.swarselsystems.mainUser}".openssh.authorizedKeys.keyFiles = [
|
users.users."${config.swarselsystems.mainUser}".openssh.authorizedKeys.keyFiles = [
|
||||||
(self + /secrets/keys/ssh/yubikey.pub)
|
(self + /secrets/keys/ssh/yubikey.pub)
|
||||||
|
|
|
||||||
26
nix/extra-builtins.nix
Normal file
26
nix/extra-builtins.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
{ exec, ... }:
|
||||||
|
let
|
||||||
|
assertMsg = pred: msg: pred || builtins.throw msg;
|
||||||
|
hasSuffix =
|
||||||
|
suffix: content:
|
||||||
|
let
|
||||||
|
lenContent = builtins.stringLength content;
|
||||||
|
lenSuffix = builtins.stringLength suffix;
|
||||||
|
in
|
||||||
|
lenContent >= lenSuffix && builtins.substring (lenContent - lenSuffix) lenContent content == suffix;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# Instead of calling sops directly here, we call a wrapper script that will cache the output
|
||||||
|
# in a predictable path in /tmp, which allows us to only require the password for each encrypted
|
||||||
|
# file once.
|
||||||
|
sopsImportEncrypted =
|
||||||
|
nixFile:
|
||||||
|
assert assertMsg (builtins.isPath nixFile)
|
||||||
|
"The file to decrypt must be given as a path to prevent impurity.";
|
||||||
|
assert assertMsg (hasSuffix ".nix.age" nixFile)
|
||||||
|
"The content of the decrypted file must be a nix expression and should therefore end in .nix.age";
|
||||||
|
exec [
|
||||||
|
./sops-decrypt-and-cache.sh
|
||||||
|
nixFile
|
||||||
|
];
|
||||||
|
}
|
||||||
21
nix/nix-plugins.patch
Normal file
21
nix/nix-plugins.patch
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
diff --git a/extra-builtins.cc b/extra-builtins.cc
|
||||||
|
index 3a0f90e..bb10f8b 100644
|
||||||
|
--- a/extra-builtins.cc
|
||||||
|
+++ b/extra-builtins.cc
|
||||||
|
@@ -1,9 +1,9 @@
|
||||||
|
-#include <config.h>
|
||||||
|
-#include <primops.hh>
|
||||||
|
-#include <globals.hh>
|
||||||
|
-#include <config-global.hh>
|
||||||
|
-#include <eval-settings.hh>
|
||||||
|
-#include <common-eval-args.hh>
|
||||||
|
-#include <filtering-source-accessor.hh>
|
||||||
|
+#include <nix/cmd/common-eval-args.hh>
|
||||||
|
+#include <nix/expr/eval-settings.hh>
|
||||||
|
+#include <nix/expr/primops.hh>
|
||||||
|
+#include <nix/fetchers/filtering-source-accessor.hh>
|
||||||
|
+#include <nix/store/globals.hh>
|
||||||
|
+#include <nix/util/configuration.hh>
|
||||||
|
+#include <nix/util/config-global.hh>
|
||||||
|
|
||||||
|
#include "nix-plugins-config.h"
|
||||||
40
nix/sops-decrypt-and-cache.sh
Executable file
40
nix/sops-decrypt-and-cache.sh
Executable file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
print_out_path=false
|
||||||
|
if [[ $1 == "--print-out-path" ]]; then
|
||||||
|
print_out_path=true
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
file="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
basename="$file"
|
||||||
|
# store path prefix or ./ if applicable
|
||||||
|
[[ $file == "/nix/store/"* ]] && basename="${basename#*"-"}"
|
||||||
|
[[ $file == "./"* ]] && basename="${basename#"./"}"
|
||||||
|
|
||||||
|
# Calculate a unique content-based identifier (relocations of
|
||||||
|
# the source file in the nix store should not affect caching)
|
||||||
|
new_name="$(sha512sum "$file")"
|
||||||
|
new_name="${new_name:0:32}-${basename//"/"/"%"}"
|
||||||
|
|
||||||
|
# Derive the path where the decrypted file will be stored
|
||||||
|
out="/var/tmp/nix-import-encrypted/$UID/$new_name"
|
||||||
|
umask 077
|
||||||
|
mkdir -p "$(dirname "$out")"
|
||||||
|
|
||||||
|
# Decrypt only if necessary
|
||||||
|
if [[ ! -e $out ]]; then
|
||||||
|
agekey=$(sudo ssh-to-age -private-key -i /etc/ssh/sops || sudo ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key)
|
||||||
|
SOPS_AGE_KEY="$agekey" sops decrypt --output "$out" "$file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Print out path or decrypted content
|
||||||
|
if [[ $print_out_path == true ]]; then
|
||||||
|
echo "$out"
|
||||||
|
else
|
||||||
|
cat "$out"
|
||||||
|
fi
|
||||||
124
pkgs/swarsel-deploy/default.nix
Normal file
124
pkgs/swarsel-deploy/default.nix
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
# heavily inspired from https://github.com/oddlama/nix-config/blob/d42cbde676001a7ad8a3cace156e050933a4dcc3/pkgs/deploy.nix
|
||||||
|
{ name, bc, nix-output-monitor, writeShellApplication, ... }:
|
||||||
|
writeShellApplication {
|
||||||
|
runtimeInputs = [ bc nix-output-monitor ];
|
||||||
|
inherit name;
|
||||||
|
text = ''
|
||||||
|
set -euo pipefail
|
||||||
|
shopt -s lastpipe # allow cmd | readarray
|
||||||
|
|
||||||
|
function die() {
|
||||||
|
echo "error: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
function show_help() {
|
||||||
|
echo 'Usage: deploy [OPTIONS] <host,...> [ACTION]'
|
||||||
|
echo "Builds, pushes and activates nixosConfigurations on target systems."
|
||||||
|
echo ""
|
||||||
|
echo 'ACTION:'
|
||||||
|
echo ' switch [default] Switch immediately to the new configuration and make it the boot default'
|
||||||
|
echo ' boot Make the configuration the new boot default'
|
||||||
|
echo " test Activate the configuration but don't make it the boot default"
|
||||||
|
echo " dry-activate Don't activate, just show what would be done"
|
||||||
|
echo ""
|
||||||
|
echo 'OPTIONS: [passed to nix build]'
|
||||||
|
}
|
||||||
|
|
||||||
|
function time_start() {
|
||||||
|
T_START=$(date +%s.%N)
|
||||||
|
}
|
||||||
|
|
||||||
|
function time_next() {
|
||||||
|
T_END=$(date +%s.%N)
|
||||||
|
T_LAST=$(${bc}/bin/bc <<< "scale=1; ($T_END - $T_START)/1")
|
||||||
|
T_START="$T_END"
|
||||||
|
}
|
||||||
|
|
||||||
|
cd ~/.dotfiles
|
||||||
|
USER_FLAKE_DIR=$(git rev-parse --show-toplevel 2> /dev/null || pwd) ||
|
||||||
|
die "Could not determine current working directory. Something went very wrong."
|
||||||
|
[[ -e "$USER_FLAKE_DIR/flake.nix" ]] ||
|
||||||
|
die "Could not determine location of your project's flake.nix. Please run this at or below your main directory containing the flake.nix."
|
||||||
|
cd "$USER_FLAKE_DIR"
|
||||||
|
|
||||||
|
[[ $# -gt 0 ]] || {
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
OPTIONS=()
|
||||||
|
POSITIONAL_ARGS=()
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
"help" | "--help" | "-help" | "-h")
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
-*) OPTIONS+=("$1") ;;
|
||||||
|
*) POSITIONAL_ARGS+=("$1") ;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ ''${#POSITIONAL_ARGS[@]} -ge 1 ]] ||
|
||||||
|
die "Missing argument: <hosts...>"
|
||||||
|
[[ ''${#POSITIONAL_ARGS[@]} -le 2 ]] ||
|
||||||
|
die "Too many arguments given."
|
||||||
|
|
||||||
|
tr , '\n' <<< "''${POSITIONAL_ARGS[0]}" | sort -u | readarray -t HOSTS
|
||||||
|
ACTION="''${POSITIONAL_ARGS[1]-switch}"
|
||||||
|
|
||||||
|
# Expand flake paths for hosts definitions
|
||||||
|
declare -A TOPLEVEL_FLAKE_PATHS
|
||||||
|
for host in "''${HOSTS[@]}"; do
|
||||||
|
TOPLEVEL_FLAKE_PATHS["$host"]=".#nixosConfigurations.$host.config.system.build.toplevel"
|
||||||
|
done
|
||||||
|
|
||||||
|
time_start
|
||||||
|
|
||||||
|
# Get outputs of all derivations (should be cached)
|
||||||
|
declare -A TOPLEVEL_STORE_PATHS
|
||||||
|
for host in "''${HOSTS[@]}"; do
|
||||||
|
toplevel="''${TOPLEVEL_FLAKE_PATHS["$host"]}"
|
||||||
|
echo "[1;36m Building [m📦 [34m$host[m"
|
||||||
|
nix build --no-link "''${OPTIONS[@]}" --show-trace --log-format internal-json -v "$toplevel" |& ${nix-output-monitor}/bin/nom --json ||
|
||||||
|
die "Failed to get derivation path for $host from ''${TOPLEVEL_FLAKE_PATHS["$host"]}"
|
||||||
|
TOPLEVEL_STORE_PATHS["$host"]=$(nix build --no-link --print-out-paths "''${OPTIONS[@]}" "$toplevel")
|
||||||
|
time_next
|
||||||
|
echo "[1;32m Built [m✅ [34m$host[m [33m''${TOPLEVEL_STORE_PATHS["$host"]}[m [90min ''${T_LAST}s[m"
|
||||||
|
done
|
||||||
|
|
||||||
|
current_host=$(hostname)
|
||||||
|
|
||||||
|
for host in "''${HOSTS[@]}"; do
|
||||||
|
store_path="''${TOPLEVEL_STORE_PATHS["$host"]}"
|
||||||
|
|
||||||
|
if [ "$host" = "$current_host" ]; then
|
||||||
|
echo -e "\033[1;36m Running locally for $host... \033[m"
|
||||||
|
ssh_prefix="sudo"
|
||||||
|
else
|
||||||
|
echo -e "\033[1;36m Copying \033[m➡️ \033[34m$host\033[m"
|
||||||
|
nix copy --to "ssh://$host" "$store_path"
|
||||||
|
time_next
|
||||||
|
echo -e "\033[1;32m Copied \033[m✅ \033[34m$host\033[m \033[90min ''${T_LAST}s\033[m"
|
||||||
|
ssh_prefix="ssh $host --"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\033[1;36m Applying \033[m⚙️ \033[34m$host\033[m"
|
||||||
|
prev_system=$($ssh_prefix readlink -e /nix/var/nix/profiles/system)
|
||||||
|
$ssh_prefix /run/current-system/sw/bin/nix-env --profile /nix/var/nix/profiles/system --set "$store_path" ||
|
||||||
|
die "Failed to set system profile"
|
||||||
|
$ssh_prefix "$store_path"/bin/switch-to-configuration "$ACTION" ||
|
||||||
|
echo "Error while activating new system" >&2
|
||||||
|
|
||||||
|
if [[ -n $prev_system ]]; then
|
||||||
|
$ssh_prefix nvd --color always diff "$prev_system" "$store_path" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
time_next
|
||||||
|
echo -e "\033[1;32m Applied \033[m✅ \033[34m$host\033[m \033[90min ''${T_LAST}s\033[m"
|
||||||
|
done
|
||||||
|
cd -
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
@ -52,6 +52,10 @@
|
||||||
autologin = lib.mkDefault true;
|
autologin = lib.mkDefault true;
|
||||||
nswitch-rcm = lib.mkDefault true;
|
nswitch-rcm = lib.mkDefault true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
server = {
|
||||||
|
ssh = lib.mkDefault true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
38
secrets/repo/packages.nix.age
Normal file
38
secrets/repo/packages.nix.age
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"data": "ENC[AES256_GCM,data:HOKAicZWRXn7EJdyLKfRuX1OFyWAZJKl5hteN3VzZfjlg+RuSg0/Q3xAxkc0spc2tUnwFLbtJsGkEip+ze9wpAYD6tvk9lDorgZY,iv:Yfz7LZcH0rVZ8cGCGiq0k03b1vB1H0b2pblXDjudMH8=,tag:IQW2IrBMcFBtbxx7SGg7vg==,type:str]",
|
||||||
|
"sops": {
|
||||||
|
"age": [
|
||||||
|
{
|
||||||
|
"recipient": "age1h72072slm2pthn9m2qwjsyy2dsazc6hz97kpzh4gksvv0r2jqecqul8w63",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3QjVKRENZV3d0TzlyNEhp\ndGcwaGNOT01wRlc5eW5JYjFHUUNONVFyNjM0CitnUHExUThpVmtkazFmOWt5N2J3\naGdoTUY3Y3JjL3hXRDVha3V1L3U4bFEKLS0tIGhjT3BGdWRZYkZCdHNRdDRMQnpi\nVi9hR2JTRVk2UUlQRHVXS0RLN2tpT3cKDSpdUF5s/rYEWRG9BDF53BAWzfkFAblH\nl+uwzdKc9+bxda5fwe7EFFxlJ+AYSqhyUcVqLV+NQO97avOdARadrg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"recipient": "age16vzhcvz8tyxj8e0f47fy0z4p3dsg0ak4vl52ut3l07a0tz465cxslmhevl",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzc2lGU0ZUMmlHbXNXTzdi\ndzlkaVg0WC92ZUg1WXpPZnRJWU5aalRnVGxNCmJVQUVvM0lDSzMvWlZtcWtmZVVH\nYVI0dkpJa3hRTUI3VHFYSmpsZ1FhQWcKLS0tIHhHVHdyRzM5ZVhsbnBSZHdMSDRv\nMGNvaXNNdnoxM2RMNWJQd0gwZWdlYWcK4lGnEXO4D1cJV/U6yC7GRHhanVnDRCS4\nX3WZsvLHZob6bpmK+G/5zA+OQnmqXTSBNxgd3jMEHaJOMPAtVonyWA==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"recipient": "age1zlnxraee6tddr07xn59mx5rdexw8qxryd53eqlsajasfhfy78fkq705dfg",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArSGg4NmtiVzBwYUVlWDJ4\nK3h2OFBkbmI4aEpTMUlaQk5wcUluMU11TWlvCklCY0F2VUZEYVNCREdKdkJsbmww\nZjBJYjZGOHBhWk9sblRSM2x5NGNlRlkKLS0tIGpiQnY5QkNpVGpTWk1pV2kxNTN5\nRiswRlFJYktTYUwrd3lTUmFydTBRV0EKRX2dBU+aohpa03F54M1MgrGQtfxvW88n\nZI36m8M7EgA1ij6dhnlKxEDcYSIx/dd5cu+IMBujrDewuSaU7HhyNQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"recipient": "age16lnmuuxfuxxtty3atnhut8wseppwnhp7rdhmxqd5tdvs9qnjffjq42sqyy",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuaEpCNEpwNXhRQ1FQWi9W\nRVdXazVtS3BlVE5oRnd5Y1RkdUZ5Sm9HN1hnCm82YWhWRzQzNW1iZVFTTDJScDJy\nTHA5d1ZhTUlSNU9vUllqVG5NSmk4TXcKLS0tIHAwOFk3cFFuTXZrdUN4cjlaWTM4\nLzJWUk95QWROMFFsa3l2NmJhS2pEaTAKwjzQ+Fh1A8bE/Jajf3mviDgLE0ECv/u+\nDG9yegxklNGJr/F82bkYtCizruMMPrBUq9WiM58/og98IuuSC+D2MA==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"recipient": "age1glge4e97vgqzh332mqs5990vteezu2m8k4wq3z35jk0q8czw3gks2d7a3h",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnNENFYjZpZmZHaHdPU2pj\nelQvUWRjcENCSVVNSmU4MWwvVlRkbUFaajBZClhMR1d1VHIzSkdGMmx1bXo0R2t4\nUkMxN3d1WjlZOVRML0tOQmJQNEJ3VmsKLS0tIEt2ejYzUUVSOVZZMVh3blViM2xG\nNXdkZk91WndaYmRiN1dVaDhxZ1l5eDQKFTUi+3P9SBPrIyxPGs5E8BoYAVXXcJ6P\n+9yNQ465s7Zeq4ExVFleqleubhIfYlShxMyQlIbOeE8AVqubN7kyLQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastmodified": "2025-06-10T17:55:09Z",
|
||||||
|
"mac": "ENC[AES256_GCM,data:sh/ZOcT86S9gDWv2tzSefWR0jbT/1HsW1UGt67yxTFSp4w+koKk6fZxkRVBefu31DANObn1NR7re3xX3YPVRQ2oiov3tLg+hOmdBziXr7xg43vhWGQQTXk9/g7K3Bv9XCy+mISw2R92FZ4lmo9PhJV96aDnd+CUInR+OTHxfceU=,iv:efFyYq5rcQ97Y2sidFbdkiX9hndznR/doRNKz2r85iY=,tag:NzSxZWDlXi8q0+OWaRMK9Q==,type:str]",
|
||||||
|
"pgp": [
|
||||||
|
{
|
||||||
|
"created_at": "2025-06-10T14:51:46Z",
|
||||||
|
"enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTAQ/9FPkVx1F30ZnXGBRkOmZkf7Gfh6K4o5JtI12cdZsajsjR\nwO8ScNT8H/imnShKGmchg/oaeq/3Tr9UJgwWm+RFeeJ/i0RbmsS+0gHVhoHKjQev\nF5Fa4s/Af1XJld6A+zOCAt9QJrNOxe1Wthrv8L4DbCpuO/bV8rurLC6k/2GXbHeO\nfVnCi0aptosxNz4C73HRLMCX7MNsE+uhiRA/kPpDzLmWvh4/6GE50874dakk8ygg\n6uQ7RRJ5ULoQKUxjvk++wvc8uhYuplcDe6pbbM3Q9NIzjEf1Ef2g6wGiXyZ+QpWU\ntE5ScTCDxzhcund8zgk/JNmajIhup3qQG64ex8rnhvlICtUWBtHVtRsf0nVvylCz\nuI2TN4KbuyuHU4lTVETCuML+8VI7zkGmUvh2Kp3ib7uXcnuFrakPy/cFWBBzd2a1\nebvYnoZL34uzXBrWXI9fidQWIiNpvqVbM2HnRC9dMyXGgP+Yr6IasX8g2tAAC6DY\nMw4IEBwtcCLxlGFYCxD47GcDCr6z95oC8Smg7L2x0KqyZEh3M6OS+z9HSVKy2Nz7\n0pFJwUQAqP3RZMLML/ZB+kcSx+g6I0tKGSegBIBHJ9Em8CTOWhuYTOu9DweRKtA7\nIx0DNBXtLn5nNNJlXJvaz55ggDtR2egoXiM9a+TDcW83qSRRNvtWYrkEuFrc7RmF\nAgwDC9FRLmchgYQBEACRk/NKKVN+qWu8EPuyAd3gkDOFPmKwnqZxYra86J0qpBr1\nNeCKGAFIV+VePnhDWW2KQeZYNpxQn4qJ5zaLO7cXMFwMhQgxmanih3lyS28Z5RkL\nm2xNnSr60M1qSm4Q04orv/WreBtzoAKWUh6mnXvf1Wldz1v2Bm2TT9GKkanb2EzB\noVr2tXTU3ZO2jbCeGab4c68RkzgGCK5RlJJhW05+9/b7gN2nK4GmxpWzlL6f62v9\n5ZJmMfJFvix6d0sE+1bToGL6SpM7jb51RlapUNXRXhG9z+74PwmwPPHNVzXlt8ne\nYzIYFpE7rTzP/0hYF0WnDIQANk/1nt7z6qV6cxD0tN88GPzMJYRuSYih4M8kNsiE\nkhxkKU4Aj7RjNwoMjTqquQtzmiL0Faak1HH22gr8jvLIwnVFtV70BndNro90a94Z\n1UZI+ip94DTRqRoCInLGcIO7LrDho6npOucusZtMObnzqxU2GDfoKWv+HW93boV8\nRvFv6bPGCmFvFbVnhO5UHV9E/8RVdIfYKavbo5w6qGy1DNPr3yrDeUP9k0dBV6sK\nhgTX5lxPPmO/U4DN1AltP3+LhjxhO9qGZ+rXSvjt38v/59gHq9JYtYZnaxQ0WxIU\nc/jWLPt5RKNmmXw4FFP5h4TotJXysxs9iPaH4t48zPbxoxYgzV7/NCMHNYgAANJe\nAUwDGCm5kyyzXDhiWG8xbZgwBBdsDnVWO7cCOQjzW1n+inZoNb4S+YjflVvckWdL\n89Lk0qtZceMis9AWYdF123jAH3okPDRjUtkLWy4dqjToqaYyQpG+YFMI+5j0ig==\n=JSDc\n-----END PGP MESSAGE-----",
|
||||||
|
"fp": "4BE7925262289B476DBBC17B76FD3810215AE097"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"unencrypted_suffix": "_unencrypted",
|
||||||
|
"version": "3.10.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue