diff --git a/flake.nix b/flake.nix index 29c8f3d..66249c1 100644 --- a/flake.nix +++ b/flake.nix @@ -96,6 +96,6 @@ python = import ./hosts/common/shells/python { inherit pkgs; }; }; - formatter = pkgs.nixfmt-rfc-style; + formatter."x86_64-linux" = pkgs.nixfmt-rfc-style; }; } diff --git a/hosts/common/configs/system/backup/backup.completion.zsh b/hosts/common/configs/system/backup/backup.completion.zsh new file mode 100644 index 0000000..4600624 --- /dev/null +++ b/hosts/common/configs/system/backup/backup.completion.zsh @@ -0,0 +1,16 @@ +_backup_completion() { + local options=( + '-m[specify partition to mount for backup]:partition:($(_partitions))' + '-b[specify backup directory]:backup directory:_files -/' + ) + local curcontext="$curcontext" state line + typeset -A opt_args + + _partitions() { + lsblk -rno NAME | sed 's/^/\/dev\//' + } + + _arguments -s $options +} + +compdef _backup_completion backup diff --git a/hosts/common/configs/system/backup/backup.sh b/hosts/common/configs/system/backup/backup.sh new file mode 100644 index 0000000..77d75e5 --- /dev/null +++ b/hosts/common/configs/system/backup/backup.sh @@ -0,0 +1,64 @@ +if [[ "${EUID}" -ne 0 ]]; then + echo "Please run the script as root." + exit 1 +fi + +usage() { + echo "Usage: $0 [-m partition] [-b backup_location]" + exit 1 +} + +cleanup() { + if [ -d "/persist.bak" ]; then btrfs -q subvolume delete "/persist.bak"; fi + if [ -n "${backup_location}" ] && [ -f "${backup_location}.tmp" ]; then rm "${backup_location}.tmp"; fi + + if [ -n "${mount_location}" ]; then + if mount | grep -q "${mount_location}"; then umount "${mount_location}"; fi + if [ -d "${mount_location}" ]; then rmdir "${mount_location}"; fi + fi +} + +partition="" +backup_location="" +mount_location="" + +trap cleanup EXIT + +while getopts "m:b:" opt; do + case "${opt}" in + m) partition="${OPTARG}" ;; + b) backup_location="${OPTARG}" ;; + *) usage ;; + esac +done + +if [ -n "${partition}" ]; then + mount_location=$(mktemp -d /mnt/backup.XXXXXX) + echo "Mounting ${partition} at ${mount_location}..." + mount "${partition}" "${mount_location}" +fi + +if [ -z "${mount_location}" ]; then + if [[ "${backup_location}" != /* ]]; then + backup_location="$(realpath "${backup_location}")" + fi +else + if [[ "${backup_location}" = /* ]]; then + echo "Error: When a partition is mounted, backup_location must be relative." + exit 1 + fi + + backup_location="$(realpath "${mount_location}/${backup_location}")" +fi + +backup_location="${backup_location}/$(hostname)-$(date +%Y-%m-%d-%H-%M-%S).btrfs.gz" + +echo "Creating /persist snapshot..." +btrfs -q subvolume snapshot -r "/persist" "/persist.bak" + +echo "Creating backup at ${backup_location}..." +btrfs -q send "/persist.bak" | gzip > "${backup_location}.tmp" + +mv "${backup_location}.tmp" "${backup_location}" + +echo "Backup completed successfully!" diff --git a/hosts/common/configs/system/backup/default.nix b/hosts/common/configs/system/backup/default.nix new file mode 100644 index 0000000..9c0e152 --- /dev/null +++ b/hosts/common/configs/system/backup/default.nix @@ -0,0 +1,20 @@ +{ pkgs, ... }: +{ + environment.systemPackages = [ + (pkgs.writeShellApplication { + name = "backup"; + runtimeInputs = with pkgs; [ + btrfs-progs + coreutils-full + util-linux + ]; + text = builtins.readFile ./backup.sh; + }) + ]; + + home-manager.sharedModules = [ + { + programs.zsh.initExtra = builtins.readFile ./backup.completion.zsh; + } + ]; +} diff --git a/hosts/common/configs/user/console/kubernetes/default.nix b/hosts/common/configs/user/console/kubernetes/default.nix index 636d68c..7e18072 100644 --- a/hosts/common/configs/user/console/kubernetes/default.nix +++ b/hosts/common/configs/user/console/kubernetes/default.nix @@ -27,13 +27,13 @@ fi } - _kubeswitch-completion() { + _kubeswitch_completion() { local dir="$HOME/.kube" local config="$dir/config" compadd -- ''${(f)"$(find "$dir" -maxdepth 1 \( -type f -o -type l \) -not -name 'config' -exec basename {} \;)"} } - compdef _kubeswitch-completion kubeswitch + compdef _kubeswitch_completion kubeswitch ''; p10k.extraRightPromptElements = [ "kubecontext" ]; diff --git a/hosts/common/configs/user/console/nix-develop/default.nix b/hosts/common/configs/user/console/nix-develop/default.nix index f6bb465..7c06794 100644 --- a/hosts/common/configs/user/console/nix-develop/default.nix +++ b/hosts/common/configs/user/console/nix-develop/default.nix @@ -7,23 +7,27 @@ home-manager.users.${user}.programs.zsh = { shellAliases.nd = "nix-develop"; - initExtra = let - devShells = lib.strings.concatStringsSep " " (lib.attrsets.mapAttrsToList (key: _: key) inputs.self.devShells); - in '' - nix-develop() { - if [ -z "$1" ]; then - echo "Usage: nix-develop " - return 1 - fi - nix develop self#"$1" -c "$SHELL" - } + initExtra = + let + devShells = lib.strings.concatStringsSep " " ( + lib.attrsets.mapAttrsToList (key: _: key) inputs.self.devShells + ); + in + '' + nix-develop() { + if [ -z "$1" ]; then + echo "Usage: nix-develop " + return 1 + fi + nix develop self#"$1" -c "$SHELL" + } - _nix-develop-completion() { - local shells=(${devShells}) - compadd -- $shells - } + _nix-develop_completion() { + local shells=(${devShells}) + compadd -- $shells + } - compdef _nix-develop-completion nix-develop - ''; + compdef _nix-develop_completion nix-develop + ''; }; } diff --git a/hosts/common/configs/user/console/nix-direnv/default.nix b/hosts/common/configs/user/console/nix-direnv/default.nix index 8202947..050990a 100644 --- a/hosts/common/configs/user/console/nix-direnv/default.nix +++ b/hosts/common/configs/user/console/nix-direnv/default.nix @@ -16,34 +16,38 @@ zsh = { shellAliases.nde = "nix-direnv"; - initExtra = let - devShells = lib.strings.concatStringsSep " " (lib.attrsets.mapAttrsToList (key: _: key) inputs.self.devShells); - in '' - nix-direnv() { - if [ -z "$1" ]; then - echo "use flake" > .envrc - else - echo "use flake self#$1" > .envrc - fi - - if git rev-parse --is-inside-work-tree &> /dev/null && ! grep -q "^\.envrc$" .gitignore .git/info/exclude; then - echo "Do you want to hide the .envrc file from git? (y/N)" - read -r answer - if [[ "$answer" =~ ^[Yy]$ ]]; then - echo ".envrc" >> .git/info/exclude + initExtra = + let + devShells = lib.strings.concatStringsSep " " ( + lib.attrsets.mapAttrsToList (key: _: key) inputs.self.devShells + ); + in + '' + nix-direnv() { + if [ -z "$1" ]; then + echo "use flake" > .envrc + else + echo "use flake self#$1" > .envrc fi - fi - direnv allow - } + if git rev-parse --is-inside-work-tree &> /dev/null && ! grep -q "^\.envrc$" .gitignore .git/info/exclude; then + echo "Do you want to hide the .envrc file from git? (y/N)" + read -r answer + if [[ "$answer" =~ ^[Yy]$ ]]; then + echo ".envrc" >> .git/info/exclude + fi + fi - _nix-direnv-completion() { - local shells=(${devShells}) - compadd -- $shells - } + direnv allow + } - compdef _nix-direnv-completion nix-direnv - ''; + _nix-direnv_completion() { + local shells=(${devShells}) + compadd -- $shells + } + + compdef _nix-direnv_completion nix-direnv + ''; p10k.extraRightPromptElements = [ "direnv" ]; }; diff --git a/hosts/common/configs/user/gui/theme/options.nix b/hosts/common/configs/user/gui/theme/options.nix index 1cc2443..73ed5be 100644 --- a/hosts/common/configs/user/gui/theme/options.nix +++ b/hosts/common/configs/user/gui/theme/options.nix @@ -533,6 +533,6 @@ in } ); - programs.zsh.initExtra = builtins.readFile ./theme.completion.sh; + programs.zsh.initExtra = builtins.readFile ./theme.completion.zsh; }; } diff --git a/hosts/common/configs/user/gui/theme/theme.completion.sh b/hosts/common/configs/user/gui/theme/theme.completion.zsh similarity index 81% rename from hosts/common/configs/user/gui/theme/theme.completion.sh rename to hosts/common/configs/user/gui/theme/theme.completion.zsh index d5faec1..ae2caec 100644 --- a/hosts/common/configs/user/gui/theme/theme.completion.sh +++ b/hosts/common/configs/user/gui/theme/theme.completion.zsh @@ -1,4 +1,4 @@ -_theme-completion() { +_theme_completion() { local options=( '-m[set mode: light, dark, or toggle]:mode:(light dark toggle)' '-w[set wallpaper: specify file path]:file:_files' @@ -8,4 +8,4 @@ _theme-completion() { _arguments -s $options } -compdef _theme-completion theme +compdef _theme_completion theme diff --git a/hosts/common/configs/user/gui/theme/theme.sh b/hosts/common/configs/user/gui/theme/theme.sh index d48ba6b..4874380 100644 --- a/hosts/common/configs/user/gui/theme/theme.sh +++ b/hosts/common/configs/user/gui/theme/theme.sh @@ -18,8 +18,9 @@ toggle_mode() { fi } -show_usage() { +usage() { echo "Usage: theme [-m {light|dark|toggle}] [-w ]" + exit 1 } finish() { @@ -42,8 +43,7 @@ while getopts "m:w:" opt; do toggle_mode ;; *) - show_usage - exit 1 + usage ;; esac ;; @@ -51,8 +51,7 @@ while getopts "m:w:" opt; do set_wallpaper "$OPTARG" ;; *) - show_usage - exit 1 + usage ;; esac done diff --git a/hosts/eirene/default.nix b/hosts/eirene/default.nix index 2cfa9f3..03f50b7 100644 --- a/hosts/eirene/default.nix +++ b/hosts/eirene/default.nix @@ -7,6 +7,7 @@ (import ./format.nix { device = "/dev/disk/by-id/nvme-SAMSUNG_MZVL22T0HBLB-00BL2_S64RNE0R602762"; }) ./hardware + ../common/configs/system/backup ../common/configs/system/bluetooth ../common/configs/system/boot ../common/configs/system/brightnessctl diff --git a/hosts/elara/default.nix b/hosts/elara/default.nix index efaa0e2..e899ddb 100644 --- a/hosts/elara/default.nix +++ b/hosts/elara/default.nix @@ -11,6 +11,7 @@ # elara runs on an external drive on eirene ../eirene/hardware + ../common/configs/system/backup ../common/configs/system/bluetooth ../common/configs/system/boot ../common/configs/system/brightnessctl