summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.sops.yaml2
-rw-r--r--flake.lock30
-rw-r--r--flake.nix37
-rw-r--r--hm/conf/git.nix39
-rw-r--r--hm/env/swayidle.nix16
-rw-r--r--hm/shell/fish.nix1
-rw-r--r--hosts/desktop/disko.nix2
-rw-r--r--hosts/thinkpad/disko.nix2
-rw-r--r--os/srv/sops.nix9
-rw-r--r--scripts/default.nix33
-rw-r--r--scripts/install.sh83
-rw-r--r--scripts/setup.sh108
-rw-r--r--secrets/secrets.yaml (renamed from secrets.yaml)6
13 files changed, 256 insertions, 112 deletions
diff --git a/.sops.yaml b/.sops.yaml
index 632d783..af3bba6 100644
--- a/.sops.yaml
+++ b/.sops.yaml
@@ -4,7 +4,7 @@ keys:
- &host_pendrive age1sx8ut0arwlrp7n7qvlaele8mq93pyvzc0ddetlk47cnyx935gcusdceq9q
creation_rules:
- - path_regex: secrets.yaml$
+ - path_regex: secrets/.*\.yaml$
key_groups:
- age:
- *host_szpont
diff --git a/flake.lock b/flake.lock
index a27060d..ce08c3c 100644
--- a/flake.lock
+++ b/flake.lock
@@ -136,11 +136,11 @@
]
},
"locked": {
- "lastModified": 1770818644,
- "narHash": "sha256-DYS4jIRpRoKOzJjnR/QqEd/MlT4OZZpt8CrBLv+cjsE=",
+ "lastModified": 1770915843,
+ "narHash": "sha256-ZwU5wXKNqpOQvjNz6aBp1j5peiBZow1++6pLnk5VAhs=",
"owner": "nix-community",
"repo": "home-manager",
- "rev": "0acbd1180697de56724821184ad2c3e6e7202cd7",
+ "rev": "6a1f7101d2c3ee87d485a87880d73b4665c6a4bd",
"type": "github"
},
"original": {
@@ -175,11 +175,11 @@
]
},
"locked": {
- "lastModified": 1770768285,
- "narHash": "sha256-VHslWcx9wSkWgGKnZwFa9TgsY7pmDBZ5mIdRAXLKViI=",
+ "lastModified": 1770857573,
+ "narHash": "sha256-pSeFA1qRAdivDrrKoybJ1DOcbkXx2v/ExIc6n0DbT4U=",
"owner": "nix-community",
"repo": "neovim-nightly-overlay",
- "rev": "2934421063ec25f994956a892ce3603d73254b3d",
+ "rev": "31e79c73c444b2e51eb34f2305792809839c58e8",
"type": "github"
},
"original": {
@@ -191,11 +191,11 @@
"neovim-src": {
"flake": false,
"locked": {
- "lastModified": 1770763009,
- "narHash": "sha256-oJCLtEd9uRG9mLdH/QYrpeZyr4UhE0WXBrsxKd/lcVU=",
+ "lastModified": 1770810897,
+ "narHash": "sha256-6F/Z/UQxalaSoqewSQ4fL8zSws3Vy4wgA5DgyTaeqTo=",
"owner": "neovim",
"repo": "neovim",
- "rev": "1e9143879d6b05bf7e4ed2a59d64d18418d2594f",
+ "rev": "6b4ec2264e1d8ba027b85f3883d532c5068be92a",
"type": "github"
},
"original": {
@@ -271,11 +271,11 @@
]
},
"locked": {
- "lastModified": 1770761134,
- "narHash": "sha256-65Xg7Rfx9Cj/D+OUF7KZUcYSQPbToBDZpqUfFUAKuwc=",
+ "lastModified": 1770913930,
+ "narHash": "sha256-yjquFNZCWM+QPaf5laJUlLvye70NQ0Mwtf6J3fmKVYI=",
"owner": "KaylorBen",
"repo": "nixcord",
- "rev": "f77d6e05efd34581cbc30e7f426496285711bcde",
+ "rev": "9269a49b885f43ce3de5ed874db6d4dd7b22514f",
"type": "github"
},
"original": {
@@ -286,11 +286,11 @@
},
"nixos-hardware": {
"locked": {
- "lastModified": 1770631810,
- "narHash": "sha256-b7iK/x+zOXbjhRqa+XBlYla4zFvPZyU5Ln2HJkiSnzc=",
+ "lastModified": 1770882871,
+ "narHash": "sha256-nw5g+xl3veea+maxJ2/81tMEA/rPq9aF1H5XF35X+OE=",
"owner": "NixOS",
"repo": "nixos-hardware",
- "rev": "2889685785848de940375bf7fea5e7c5a3c8d502",
+ "rev": "af04cb78aa85b2a4d1c15fc7270347e0d0eda97b",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index 11d2419..eaba51f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -66,18 +66,19 @@
};
outputs =
- {
- self,
- nixpkgs,
- sops-nix,
- ...
- }@inputs:
+ { self, nixpkgs, ... }@inputs:
let
+ system = "x86_64-linux";
+ pkgs = import nixpkgs {
+ inherit system;
+ config.allowUnfree = true;
+ };
+ scripts = import ./scripts { inherit pkgs; };
mkHost =
{
hostname,
- path,
user ? "adam",
+ path ? ./hosts/${hostname}/configuration.nix,
}:
nixpkgs.lib.nixosSystem {
specialArgs = {
@@ -86,28 +87,30 @@
};
modules = [
path
- sops-nix.nixosModules.sops
{ networking.hostName = hostname; }
];
};
in
{
+ apps."x86_64-linux" = {
+ install = {
+ type = "app";
+ program = "${scripts.install}/bin/nixos-install";
+ };
+ setup = {
+ type = "app";
+ program = "${scripts.setup}/bin/nixos-setup";
+ };
+ };
nixosConfigurations = {
szpont = mkHost {
hostname = "szpont";
path = ./hosts/desktop/configuration.nix;
};
- laptop = mkHost {
- hostname = "laptop";
- path = ./hosts/laptop/configuration.nix;
- };
- thinkpad = mkHost {
- hostname = "thinkpad";
- path = ./hosts/thinkpad/configuration.nix;
- };
+ laptop = mkHost { hostname = "laptop"; };
+ thinkpad = mkHost { hostname = "thinkpad"; };
pendrive = mkHost {
hostname = "pendrive";
- path = ./hosts/pendrive/configuration.nix;
user = "user";
};
};
diff --git a/hm/conf/git.nix b/hm/conf/git.nix
index b297153..67fcaa4 100644
--- a/hm/conf/git.nix
+++ b/hm/conf/git.nix
@@ -1,4 +1,9 @@
-{ config, lib, ... }:
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
let
cfg = config.hm.conf.git;
in
@@ -8,11 +13,39 @@ in
programs.git = {
enable = true;
lfs.enable = true;
+ signing = {
+ key = "EF69F2FB25C8B5A66918EA91A38ACEAB9656CD94";
+ signByDefault = true;
+ };
settings = {
- user.name = "adikro";
- user.email = "adikro@disroot.org";
+ user = {
+ name = "adikro";
+ email = "adikro@disroot.org";
+ };
init.defaultBranch = "main";
+ push.autoSetupRemote = true;
+ pull.rebase = true;
+ "url \"git@codeberg.org:\"".insteadOf = "https://codeberg.org/";
};
+ ignores = [
+ "*.swp"
+ "result"
+ ".direnv/"
+ "secrets/*.tmp"
+ ];
+ hooks.pre-commit = pkgs.writeShellScript "sops-pre-commit" ''
+ for file in secrets/*.yaml; do
+ if [[ -f "$file" ]]; then
+ if ! ${pkgs.ripgrep}/bin/rg -q "sops" "$file"; then
+ echo "--------------------------------------------------------"
+ echo "ABORTING COMMIT: Unencrypted file detected: $file"
+ echo "Please run 'sops -e -i $file' before committing."
+ echo "--------------------------------------------------------"
+ exit 1
+ fi
+ fi
+ done
+ '';
};
};
}
diff --git a/hm/env/swayidle.nix b/hm/env/swayidle.nix
index 94e819a..1150948 100644
--- a/hm/env/swayidle.nix
+++ b/hm/env/swayidle.nix
@@ -1,4 +1,9 @@
-{ config, lib, pkgs, ... }:
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
let
cfg = config.hm.env.swayidle;
in
@@ -9,11 +14,14 @@ in
enable = true;
systemdTarget = "graphical-session.target";
events = {
- before-sleep = "${pkgs.swaylock-effects}/bin/swaylock -f";
- lock = "${pkgs.swaylock-effects}/bin/swaylock -f";
+ # before-sleep = "${pkgs.swaylock-effects}/bin/swaylock -f";
+ lock = "${pkgs.swaylock-effects}/bin/swaylock -f";
};
timeouts = [
- { timeout = 300; command = "${pkgs.swaylock-effects}/bin/swaylock -f"; }
+ {
+ timeout = 600;
+ command = "${pkgs.swaylock-effects}/bin/swaylock -f";
+ }
{
timeout = 600;
command = "niri msg action power-off-monitors";
diff --git a/hm/shell/fish.nix b/hm/shell/fish.nix
index a417274..d7f7248 100644
--- a/hm/shell/fish.nix
+++ b/hm/shell/fish.nix
@@ -25,6 +25,7 @@ in
nd = "nix develop .";
nos = "nh os switch .";
nob = "nh os boot .";
+ nus = "nh os switch . -u";
nfu = "nix flake update";
md = "mkdir -p";
diff --git a/hosts/desktop/disko.nix b/hosts/desktop/disko.nix
index cda1979..86d1e71 100644
--- a/hosts/desktop/disko.nix
+++ b/hosts/desktop/disko.nix
@@ -110,7 +110,7 @@
content = {
type = "luks";
name = "crypted_storage";
- keyFile = "/tmp/storage.key";
+ keyFile = "/tmp/crypt.key";
content = {
type = "btrfs";
extraArgs = [ "-f" ];
diff --git a/hosts/thinkpad/disko.nix b/hosts/thinkpad/disko.nix
index 31427d3..8b41240 100644
--- a/hosts/thinkpad/disko.nix
+++ b/hosts/thinkpad/disko.nix
@@ -122,7 +122,7 @@
content = {
type = "luks";
name = "crypted_storage";
- keyFile = "/tmp/storage.key";
+ keyFile = "/tmp/crypt.key";
settings.allowDiscards = true;
content = {
type = "btrfs";
diff --git a/os/srv/sops.nix b/os/srv/sops.nix
index 67cf8f7..e5233d6 100644
--- a/os/srv/sops.nix
+++ b/os/srv/sops.nix
@@ -2,6 +2,7 @@
config,
lib,
pkgs,
+ inputs,
username,
...
}:
@@ -9,10 +10,12 @@ let
cfg = config.os.srv.sops;
in
{
+ imports = [ inputs.sops-nix.nixosModules.sops ];
+
options.os.srv.sops.enable = lib.mkEnableOption "enables sops-nix secret storing";
config = lib.mkIf cfg.enable {
sops = {
- defaultSopsFile = ../../secrets.yaml;
+ defaultSopsFile = ../../secrets/secrets.yaml;
defaultSopsFormat = "yaml";
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
@@ -21,12 +24,12 @@ in
"obs/websocket_password".owner = username;
root_password.neededForUsers = true;
user_password.neededForUsers = true;
- storage_key = { };
+ crypt_key = { };
};
};
boot.initrd.secrets = {
- "/tmp/storage.key" = config.sops.secrets.storage_key.path;
+ "/tmp/crypt.key" = config.sops.secrets.crypt_key.path;
};
environment.systemPackages = with pkgs; [
diff --git a/scripts/default.nix b/scripts/default.nix
new file mode 100644
index 0000000..983216d
--- /dev/null
+++ b/scripts/default.nix
@@ -0,0 +1,33 @@
+{ pkgs }:
+let
+ commonInputs = with pkgs; [
+ git
+ gnupg
+ sops
+ nix
+ coreutils
+ util-linux
+ nixos-facter
+ ];
+in
+{
+ install = pkgs.writeShellApplication {
+ name = "nixos-install";
+ runtimeInputs = commonInputs ++ [ pkgs.disko-install ];
+ text = builtins.readFile ./install.sh;
+ };
+
+ setup = pkgs.writeShellApplication {
+ name = "nixos-setup";
+ runtimeInputs =
+ commonInputs
+ ++ (with pkgs; [
+ ssh-to-age
+ ripgrep
+ sd
+ nh
+ fd
+ ]);
+ text = builtins.readFile ./setup.sh;
+ };
+}
diff --git a/scripts/install.sh b/scripts/install.sh
index 9173646..8a8c3d7 100644
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -3,25 +3,23 @@ set -euo pipefail
# --- Defaults ---
HOSTNAME=""
-MAIN_DISK="/dev/nvme0n1"
-STORAGE_DISK=""
+DISKS=()
+KEY_LOCATION="./private.asc"
REPO_URL="https://codeberg.org/adikro/nixos-config.git"
-TEMP_CONFIG="/tmp/config/etc/nixos-config"
+TEMP_CONFIG="/tmp/config/etc/nixos"
USE_FACTER=true
WRITE_EFI=true
# --- Parse Arguments ---
-# Added 'g' (generate-config) and 'n' (no-efi) to options
-PARSED_ARGS=$(getopt -z -o h:m:s:r:c:gn --long hostname:,main:,storage:,repo:,config:,generate-config,no-efi -- "$@")
+PARSED_ARGS=$(getopt -o h:d:r:k:gn --long hostname:,disk:,repo:,key:,generate-config,no-efi -- "$@")
eval set -- "$PARSED_ARGS"
while true; do
case "$1" in
-h|--hostname) HOSTNAME="$2"; shift 2 ;;
- -m|--main) MAIN_DISK="$2"; shift 2 ;;
- -s|--storage) STORAGE_DISK="$2"; shift 2 ;;
+ -d|--disk) DISKS+=("$2"); shift 2 ;;
-r|--repo) REPO_URL="$2"; shift 2 ;;
- -c|--config) TEMP_CONFIG="$2"; shift 2 ;;
+ -k|--key) KEY_LOCATION="$2"; shift 2 ;;
-g|--generate-config) USE_FACTER=false; shift ;;
-n|--no-efi) WRITE_EFI=false; shift ;;
--) shift; break ;;
@@ -30,9 +28,13 @@ while true; do
done
# --- Validation ---
-if [[ -z "$HOSTNAME" || -z "$MAIN_DISK" ]]; then
- echo "Usage: sudo ./install.sh --hostname <name> [options]"
- echo "Options: --main <disk> --storage <disk> --repo <url> --config <path> --generate-config --no-efi"
+if [[ -z "$HOSTNAME" || ${#DISKS[@]} -eq 0 ]]; then
+ echo "Usage: sudo nix run .#install -- -h <name> -d main:/dev/nvme0n1 [-d storage:/dev/sda]"
+ exit 1
+fi
+
+if [[ ! -f "$KEY_LOCATION" ]]; then
+ echo "Error: Private key not found at $KEY_LOCATION. Cannot proceed without GPG."
exit 1
fi
@@ -40,17 +42,15 @@ fi
echo "------------------------------------------------------------"
echo "INSTALLATION PLAN"
echo " Hostname: $HOSTNAME"
-echo " Main Disk: $MAIN_DISK"
-echo " Storage Disk: ${STORAGE_DISK:-None}"
-echo " Hardware Mode: $([ "$USE_FACTER" = true ] && echo "Facter" || echo "Legacy Generate-Config")"
-echo " Write EFI: $WRITE_EFI"
-echo " Repo URL: $REPO_URL"
+echo " Target Disks:"
+for disk in "${DISKS[@]}"; do echo " - $disk"; done
echo "------------------------------------------------------------"
-read -p "Proceed with formatting? (y/N): " confirm
+read -p "Warning: This will format the disks listed above. Proceed? (y/N): " confirm
[[ "$confirm" != [yY] ]] && exit 1
-echo "### 1. Preparing GPG ###"
-gpg --import ./private.asc || echo "GPG key already present."
+echo "### 1. Importing GPG Key ###"
+export GPG_TTY=$(tty)
+gpg --import "$KEY_LOCATION"
echo "### 2. Cloning Configuration ###"
sudo rm -rf "$TEMP_CONFIG"
@@ -58,44 +58,31 @@ git clone "$REPO_URL" "$TEMP_CONFIG"
cd "$TEMP_CONFIG"
echo "### 3. Hardware Configuration ###"
-mkdir -p "./hosts/$HOSTNAME"
+HOST_DIR="./hosts/$HOSTNAME"
+mkdir -p "$HOST_DIR"
if [ "$USE_FACTER" = true ]; then
- echo "Running Facter scan..."
- # Note: Using your specified format for the command
- sudo nix run github:nix-community/nixos-facter -- -o "./hosts/$HOSTNAME/facter.json"
- git add "./hosts/$HOSTNAME/facter.json"
+ nixos-facter -o "$HOST_DIR/facter.json"
+ git add "$HOST_DIR/facter.json"
else
- echo "Generating legacy hardware config..."
sudo nixos-generate-config --no-filesystems --root /tmp/nixos-gen-root
- sudo mv /tmp/nixos-gen-root/etc/nixos/hardware-configuration.nix "./hosts/$HOSTNAME/hardware-configuration.nix"
- sudo rm -rf /tmp/nixos-gen-root
- git add "./hosts/$HOSTNAME/hardware-configuration.nix"
+ mv /tmp/nixos-gen-root/etc/nixos/hardware-configuration.nix "$HOST_DIR/hardware-configuration.nix"
+ git add "$HOST_DIR/hardware-configuration.nix"
fi
echo "### 4. SOPS Key Extraction ###"
-if [[ -n "$STORAGE_DISK" ]]; then
- echo "Extracting storage_key..."
- nix shell nixpkgs#sops -c sops -d --extract '["storage_key"]' secrets.yaml > /tmp/storage.key
+if printf '%s\n' "${DISKS[@]}" | rg -qv "^main:"; then
+ sops -d --extract '["crypt_key"]' secrets/secrets.yaml > /tmp/crypt.key
fi
echo "### 5. Disko Install ###"
-DISKO_ARGS=(
- --flake ".#$HOSTNAME"
- --disk main "$MAIN_DISK"
-)
-
-# Conditionally add the EFI flag
-if [ "$WRITE_EFI" = true ]; then
- DISKO_ARGS+=(--write-efi-boot-entries)
-fi
-
-# Append storage disk if defined
-if [[ -n "$STORAGE_DISK" ]]; then
- DISKO_ARGS+=(--disk storage "$STORAGE_DISK")
-fi
+DISKO_ARGS=(--flake ".#$HOSTNAME")
+for pair in "${DISKS[@]}"; do
+ IFS=":" read -r D_NAME D_DEV <<< "$pair"
+ DISKO_ARGS+=(--disk "$D_NAME" "$D_DEV")
+done
+[[ "$WRITE_EFI" == true ]] && DISKO_ARGS+=(--write-efi-boot-entries)
-sudo nix run 'github:nix-community/disko/latest#disko-install' -- "${DISKO_ARGS[@]}"
+sudo disko-install "${DISKO_ARGS[@]}"
-echo "------------------------------------------------------------"
-echo "INSTALL COMPLETE. Remove pendrive and reboot."
+echo "INSTALL COMPLETE. Reboot and run setup script."
diff --git a/scripts/setup.sh b/scripts/setup.sh
index a3b0cb2..fb9a603 100644
--- a/scripts/setup.sh
+++ b/scripts/setup.sh
@@ -1,22 +1,98 @@
#!/usr/bin/env bash
-# Automate the post-reboot steps
-sudo mkdir -p /mnt/usb && sudo mount /dev/sdb1 /mnt/usb
-gpg --import /mnt/usb/private.asc
-gpg --import /mnt/usb/public.asc
-gpg --import-ownertrust /mnt/usb/trust.txt
+set -euo pipefail
-# Setup the repo properly
+# --- Defaults ---
+HOSTNAME=$(hostname)
+USB_DEVICE=""
+REPO_URL="git@codeberg.org:adikro/nixos-config.git"
+KEY_LOCATION=""
+USE_FACTER=true
+
+# --- Parse Arguments ---
+PARSED_ARGS=$(getopt -o u:h:r:k:g --long usb:,hostname:,repo:,key:,generate-config -- "$@")
+eval set -- "$PARSED_ARGS"
+
+while true; do
+ case "$1" in
+ -u|--usb) USB_DEVICE="$2"; shift 2 ;;
+ -h|--hostname) HOSTNAME="$2"; shift 2 ;;
+ -r|--repo) REPO_URL="$2"; shift 2 ;;
+ -k|--key) KEY_LOCATION="$2"; shift 2 ;;
+ -g|--generate-config) USE_FACTER=false; shift ;;
+ --) shift; break ;;
+ *) echo "Internal error!"; exit 1 ;;
+ esac
+done
+
+echo "### 1. GPG Key Preparation ###"
+export GPG_TTY=$(tty)
+
+if [[ -n "$KEY_LOCATION" ]]; then
+ gpg --import "$KEY_LOCATION"
+elif [[ -n "$USB_DEVICE" ]]; then
+ echo "Mounting $USB_DEVICE..."
+ sudo mkdir -p /mnt/usb
+ findmnt -rno SOURCE "$USB_DEVICE" >/dev/null || sudo mount "$USB_DEVICE" /mnt/usb
+
+ echo "Searching USB for private.asc..."
+ KEY_FILE=$(sudo fd -H -t f "private.asc" /mnt/usb --max-results 1)
+
+ if [[ -n "$KEY_FILE" ]]; then
+ KEY_DIR=$(dirname "$KEY_FILE")
+ echo "Found keys in $KEY_DIR. Importing..."
+ (
+ cd "$KEY_DIR"
+ gpg --import private.asc
+ [[ -f "public.asc" ]] && gpg --import public.asc
+ [[ -f "trust.txt" ]] && gpg --import-ownertrust trust.txt
+ )
+ else
+ echo "Error: private.asc not found on $USB_DEVICE"
+ sudo umount /mnt/usb; exit 1
+ fi
+ sudo umount /mnt/usb
+else
+ gpg -K | grep -q "sec" || { echo "No keys found. Use --usb or --key."; exit 1; }
+fi
+
+echo "### 2. Repo Setup ###"
sudo mkdir -p /etc/nixos
-sudo chown -R $USER:users /etc/nixos
-git clone git@codeberg.org:adikro/nixos-config.git /etc/nixos
+sudo chown -R "$USER":users /etc/nixos
+[[ ! -d "/etc/nixos/.git" ]] && git clone "$REPO_URL" /etc/nixos
+cd /etc/nixos
-# Fix hardware config for the actual live system
-sudo rm /etc/nixos/hosts/desktop/hardware-configuration.nix
-sudo nixos-generate-config --no-filesystems --root /
-# Move it to the right place
-sudo mv /etc/nixos/hardware-configuration.nix /etc/nixos/hosts/desktop/
+echo "### 3. Hardware Refresh ###"
+HOST_DIR="./hosts/$HOSTNAME"
+mkdir -p "$HOST_DIR"
+if [ "$USE_FACTER" = true ]; then
+ nixos-facter -o "$HOST_DIR/facter.json"
+else
+ sudo nixos-generate-config --no-filesystems --root /
+ mv /etc/nixos/hardware-configuration.nix "$HOST_DIR/hardware-configuration.nix"
+fi
-# Update SOPS with new SSH key
+echo "### 4. SOPS Rotation ###"
NEW_AGE=$(ssh-to-age < /etc/ssh/ssh_host_ed25519_key.pub)
-echo "New Age Key: $NEW_AGE"
-# You'll still need to manually edit .sops.yaml unless you use 'sed' to replace the key
+if grep -q "&host_$HOSTNAME" .sops.yaml; then
+ sd "(&host_$HOSTNAME\s+-) age1.*" "\$1 $NEW_AGE" .sops.yaml
+else
+ sd "(keys:\n)" "\$1 - &host_$HOSTNAME $NEW_AGE\n" .sops.yaml
+ sd "(age:\n(.*\n)*?\s+age:\n)" "\$1 - *host_$HOSTNAME\n" .sops.yaml
+fi
+
+sops updatekeys secrets/secrets.yaml -y
+
+echo "### 5. System Rebuild ###"
+git add .
+nh os switch . -u -H "$HOSTNAME"
+
+echo "### 6. Git Finalization ###"
+[[ $(git remote) =~ "origin" ]] && git remote rename origin codeberg
+git remote set-url codeberg "$REPO_URL"
+git add .
+git commit -m "chore($HOSTNAME): hardware refresh and sops rotation" || echo "No changes."
+
+read -p "Push to Codeberg? (y/N): " push_confirm
+[[ "$push_confirm" == [yY] ]] && git push -u codeberg main
+
+echo "SETUP COMPLETE. Rebooting is recommended."
diff --git a/secrets.yaml b/secrets/secrets.yaml
index 5b2db9c..6c24d82 100644
--- a/secrets.yaml
+++ b/secrets/secrets.yaml
@@ -1,6 +1,6 @@
user_password: ENC[AES256_GCM,data:lPSKNpHWQYQZvLFmK1NIqvcDTsXWe8lMnBuqATtkyQjjswFrBjreM5hp1l360VByGOupzG5c2Fz9W1ZCC/eYRrmbldJcSiMdYw==,iv:A6If6CSWoRNGR/CV/QBt8UH1N9BKp9xEnOOMcrSAET4=,tag:Ommq47gaEm86/ByCV1dlBA==,type:str]
root_password: ENC[AES256_GCM,data:F2M3P5JTpP9bnO494jnLA/Hs2ndQRYhgN9Z9LiEgTYYQPvMdi0DGI5dN6rh+5Dhm0a9eqGSOpU+4rWYX6cXOp+Um2exKr0O8YQ==,iv:WZtTsAMhg+qzE66/v2DUsG50Voc3vJF+1X19LNNsG3Q=,tag:cpQu7W/SMfilYxnbsgi/RQ==,type:str]
-storage_key: ENC[AES256_GCM,data:GuprvpeHvlcEHtTzt0vrUfCApMQU/DOHSkdNB7nvFm6tFGatCRZdeT5aEJ00mMDhCZidm2SF3hRpv4P9ErLhLEIDCyQPQsA417ojgCvObTXXftWxLalCo/ZwME0rUG1/Amco04dL8sT8mvxE3TIImvFVJRuK3DwMWUG7Y27rGX8QglHKbumSkQtzjs6G2fDkUSebV7kPvvvLtvKlDYswZEnuQ3bBIFN0ZJvewAhOh/GoSq9RKmvNVgGj7VPqG2oFQ0t7pxlb9HLutC+PNQnw3u8iKDtOazCHiVEX4Q5RoxYsUCqrQtEWSNOKgpdRhNMWpe4SNk6KCcZ9KE4Sx6V26EXCTqnZbxQ/XGMTYkTbEWJPgqi8Oc6hluuelN36qd3D6zrARmMoyMTdvr9Ig8Kzxtlq1KAA8H+BEvvNvCXFIumB2FX7qAywNurV68UAH5+uSJBsgPBFEisi7cVHCJtMAUuRc3KnFjEbXC5HgNZd4fKynk4dSdAzuZRcB3+xKpHEDFEy2RMfG7GShKmXyRV7VwSz5Suu9c9UKmgyZ2lQqLaAufdwneIMROAYx603h/Tfx8aO7gjGrUqvFB1ACLiS+1f6QRxGRNxLD7x92xheXZnIbKWjKUC6y6vQI5S36NN6720zcQZFBmDlLPG7WNhI6idcqrTn473zaYOdm6zlCWbmOqzmoz/0EVmwnsVifKjrWHne02l41ywnP99OoPCy3X0dL4HOXkkxJnxAQljmnqm/DAv3Fg9ZglEBKzEBNUPfy42Wf0cLQCb4SZt+5ztrzFq8o+AkAiH5tSXFN/LPUz4GZN2cc12Gad4LDrVwGSvcntP79hAudnohQeqAG49HCE5cCBd1L4CNDCnp6Skpi9eUczjt6JHBrwME2nQIBgZaUqXHvh6hTc3/Y7lx,iv:Ng9EN8ykjB9ew4v9slmVe02MZOkvuoLonbgqU6RdI60=,tag:a/nGLG1NmooeI1yKBiOZrg==,type:str]
+crypt_key: ENC[AES256_GCM,data:tVX0vYrrzGiiGc1oxnxMosksDpYBZM8qJyrYpSyKXBFhgOEjgGRssQCiQRXjQA633Gi3QV9P1ldLprhpIn6tI7AtBdiklI2DbJkkpkzWw22IEu/5k6nk8HfcxM0QAbXAxAbVC3mIx48guQjFJrxWBvxgKXjDR0c8i2PW6mvstz8okSn+XXPJq+FMsAIxx00ZWiP48nYct/8/uZ223w0LPtjQySS/x+n+ycDfjRIKAkgKEgMgP+ouHZGL3Foy6LyNaFtYQr4QrgQAnKoXX7dkxPuwfQQeJNgg5O5Eav1eof5+s+KwQzflwFW/SBX8ScTH9PQ9SAsJl061JOqlzs34To1sWwoIkFj348kSreGXmCdqwIv4m72nZemRiDjS/NVT4zBjsVgX1pAbPDmBRym/619d7Q3FoKPS2jjdn6dO9fUgZZsGylb1gUjIBSY5HkVl0rbtaniXZh57edwGyDLES66pSVEUWnewnBn+ZODV/Z/EmQBF8i2KkZyWBfAixz9zQpDTgDHGsSiyJrbtZonqvWTEjAA3kp2GlXM7oGo0HcINrtUNPoL5MMErkbwIky8OUBmwnSyFl7XAD3dbk+3cijOQhkLWx6pW8bd10p7AZsfEFfxhUPoY6J9rBdpr/VCny9ARolChIGKcFDBKQehbdGOquxCiUPoKgRpSE0RTC1+Z7KeXWdB5tTEXW3I1boqo20AI3hYOlyOtegceASmE/vi7ohSIUdfpQ6nF9qMZPncAW+0IBqt+v+4yOXwzhwrPVocWF71BLk32wHDTvTS0Dy4xTPNL0lukJiVNvZ4bMSgPX+OUp12QnZ+MNSpiQ2G+kLV4LtHby72S8+ZIShWLlZB6/T6QywdMJMkTLe/nKqvvx133FGxgVqD+59VRNkkdTMz5dSyAgTbco/dy,iv:QgIlhNNyUTVnrV5YDEcNbf73NAHD7ZI9eu3IpuC3oSA=,tag:3uULpLYqcoi6SF6fq345Eg==,type:str]
syncthing:
gui_password: ENC[AES256_GCM,data:9sivtxELQRCD+q1OFMmL9OwMnem22VxFRN9twVdnMlTMmtxplO/KmezuLt+SUpfhDne0i9cTliiqCm16bQb3fFQWplJIyQDRgIGr1Y7r4boGtvJ95oSIW3bmwJW+IkYyYysKbcNrTGfdWVS6lJWYfenhonNfWESxqo1CW81BxBY=,iv:tYxoE/pxBBFrbiuc3ZVJe9rZfnVo9QSJOtl1NlPHyNg=,tag:eUwgow5ZkkuMoXrUAZughg==,type:str]
obs:
@@ -25,8 +25,8 @@ sops:
b3E5bmZpN0tUclZjck4wUjFBUklOelkKf3v/9uVOgDp7olWyV50PMISVq8Ixf4+S
vLuXJ0kMeTuiW5CweAW9HiD01nwC+aRZaPn5JCLMoxWy/VVgMNNx1g==
-----END AGE ENCRYPTED FILE-----
- lastmodified: "2026-02-10T21:12:45Z"
- mac: ENC[AES256_GCM,data:BqKVfu9u/tjELHkoWs2d/FKRgHp0trWJq/nZdunasotsMyxHO0AI5EtIMnRGnkBB+HTHnnIASYo+0ZymyG7z6satKnz1jKNA3vHLweWASSPOWzN3mgtkGKOJPDgYIHbes4Rb/GXpcUgVtmBRHFbIwF1FNYo7EK1YN2EKgTKkXxI=,iv:IGcWyftYTYKrgqf3LOGfBnoPLuOWgJK4q6/0aAvE3Dg=,tag:OdWdG/VrKCH9cCBkpiAe2w==,type:str]
+ lastmodified: "2026-02-12T18:12:27Z"
+ mac: ENC[AES256_GCM,data:X4w7bP1yh8fv9T1g0foqmLGy8d0BJBR82FYUplBbmvoxLELz56cTKs4+SKZ0p9u3OGd2IBtb8HlJCtv2bvllXbFm3dCrQBA6GYJ0yktIgijLuEA4m1iInc3EHh2il4I7/QXcrN/0ogCaNKqLUFsuqJSFQeDy06EZsazkm1xQp04=,iv:abXrgqa9UoTd5ENtOsm6b95ADdBcfrZwUrBaxWq+U3s=,tag:o6ug+kehSzHK2FXCQB1tiw==,type:str]
pgp:
- created_at: "2026-02-09T13:58:02Z"
enc: |-