360 lines
15 KiB
Makefile
360 lines
15 KiB
Makefile
set positional-arguments # makes variables accesible as $1 $2 $@
|
|
export invokedir := invocation_directory()
|
|
export GUM_CHOOSE_HEIGHT := "15"
|
|
export GUM_FILTER_HEIGHT := "15"
|
|
export FZF_DEFAULT_OPTS := "--height 15 --cycle --bind 'ctrl-a:toggle-all' " + env('FZF_DEFAULT_OPTS', "")
|
|
|
|
#export hosts_nixos := `2>/dev/null nix eval .\#nixosConfigurations --apply builtins.attrNames --json`
|
|
#export hosts_fhs := `2>/dev/null nix eval .\#systemConfigs --apply builtins.attrNames --json`
|
|
|
|
@_default:
|
|
just "$(gum filter --placeholder "Pick a recipie..." $(just --summary --unsorted))"
|
|
|
|
eval $hostname=`just _a_host` $attrpath="system.build.toplevel.outPath" *args:
|
|
nix eval --log-format raw ".#nixosConfigurations.\"$hostname\".config.$attrpath" --show-trace "${@:3}"
|
|
eval-vm $hostname=`just _a_host` $attrpath="system.build.toplevel.outPath" *args:
|
|
# nix eval --log-format raw ".#nixosConfigurations.\"$hostname\".config.system.build.vm.outPath" --show-trace "${@:3}"
|
|
nix eval --log-format raw ".#nixosConfigurations.\"$hostname\".config.virtualisation.vmVariant.$attrpath" --show-trace "${@:3}"
|
|
|
|
repl $hostname=`just _a_host`:
|
|
NIX_NO_NOM=1 nixos-rebuild-ng --flake .#"$hostname" repl
|
|
|
|
report hostname=`just _a_host`:
|
|
nix eval .#nixosReports."{{hostname}}" --json --show-trace | yq . --yaml-output --width=999999 | bat --language yaml --style plain --paging never
|
|
|
|
reports:
|
|
nix eval .#nixosReports --json --show-trace | yq . --yaml-output --width=999999 | bat --language yaml --style plain --paging never
|
|
|
|
update:
|
|
git reset flake.lock
|
|
git restore flake.lock
|
|
git pull --rebase --autostash
|
|
nix flake update --commit-lock-file
|
|
@mkdir -p .direnv/
|
|
@printf "%s\n" "$(date +%Y-%m-%d)" > .direnv/pull-date
|
|
|
|
@update-select:
|
|
git reset flake.lock
|
|
git restore flake.lock
|
|
nix eval --file flake.nix --apply 'x: builtins.attrNames x.inputs' --json \
|
|
| (printf "%s\n" --commit-lock-file; jq '.[]' -r | tr '0123456789' '9876543210' | sort | tr '0123456789' '9876543210' | grep -v "^self$") \
|
|
| gum choose --no-limit \
|
|
| xargs nix flake update
|
|
git add flake.lock
|
|
|
|
pull-dconf:
|
|
./users/pbsds/home/profiles/desktop/gnome/dconf-pull.sh
|
|
git diff ./users/pbsds/home/profiles/desktop/gnome/
|
|
-gum confirm "git add --patch?" --default=no \
|
|
&& git add --patch ./users/pbsds/home/profiles/desktop/gnome/
|
|
-gum confirm "git checkout --path?" --default=no \
|
|
&& git checkout --patch ./users/pbsds/home/profiles/desktop/gnome/
|
|
|
|
# todo: support system-manager
|
|
# todo: support home-manager?
|
|
build hostname="" *_:
|
|
nixos-rebuild-ng build --accept-flake-config --show-trace --flake .#"{{hostname}}" "${@:2}"
|
|
|
|
build-vm hostname=`just _a_host` *_:
|
|
nixos-rebuild-ng build-vm --accept-flake-config --show-trace --flake .#"{{hostname}}" "${@:2}"
|
|
|
|
build-vm-and-run $hostname=`just _a_host` *_:
|
|
@# TODO: setup ports?
|
|
@# TODO: attach serial instead of gui?
|
|
@# TODO: headless and ssh?
|
|
@just build-vm "$hostname" "${@:2}"
|
|
./result/bin/run-"$hostname"-vm
|
|
|
|
# build-home $user=`whoami`:
|
|
# #!/usr/bin/env -S bash -euo pipefail
|
|
|
|
test *_:
|
|
sudo nixos-rebuild-ng test --accept-flake-config --show-trace --flake . "$@"
|
|
|
|
switch *_:
|
|
sudo nixos-rebuild-ng switch --accept-flake-config --show-trace --flake . "$@"
|
|
|
|
boot *_:
|
|
sudo nixos-rebuild-ng boot --accept-flake-config --show-trace --flake . "$@"
|
|
|
|
boot-and-reboot *_:
|
|
sudo nixos-rebuild-ng boot --accept-flake-config --show-trace --flake . "$@"
|
|
sudo reboot
|
|
|
|
# TODO: nixos-rebuild-ng
|
|
push $hostname=`just _a_host` cmd=`gum choose test switch boot --header "Select mode..."`:
|
|
#!/usr/bin/env -S bash -euo pipefail
|
|
remote_sudo=1
|
|
gum confirm "Use '--use-remote-sudo'?" || remote_sudo=0
|
|
# build once first for nom output
|
|
(set -x; nixos-rebuild build --flake .#"$hostname") || exit $?
|
|
# target_host="root@$(nix eval --log-format raw ".#nixosConfigurations.\"$hostname\".config.networking.fqdn" --json | jq . -r)"
|
|
target_host="$hostname"
|
|
printf "%s\n" pushing...
|
|
# nixos-rebuild will perform a build still, meaning another full eval...
|
|
# TODO: support a simple copy-closure with no activation on remote
|
|
if [[ "$remote_sudo" -eq 1 ]]; then
|
|
# set -x; NIX_NO_NOM=1 NIX_SSHOPTS="-t" nixos-rebuild {{cmd}} --flake .#"$hostname" --target-host "$target_host" --use-substitutes --use-remote-sudo
|
|
set -x; NIX_NO_NOM=1 IX_SSHOPTS="-o RequestTTY=force" nixos-rebuild {{cmd}} --flake .#"$hostname" --target-host "$target_host" --use-substitutes --use-remote-sudo
|
|
else
|
|
set -x; NIX_NO_NOM=1 nixos-rebuild {{cmd}} --flake .#"$hostname" --target-host "root@$target_host" --use-substitutes
|
|
fi
|
|
|
|
# test-files $hostname=`just _a_host` *filenames:
|
|
# #!/usr/bin/env -S bash -euo pipefail
|
|
# # TODO: remember previous choices
|
|
# [[ -n "$hostname" ]] || { printf >&2 "%s\n" "ERROR: no hostname"; false; }
|
|
# declare -a filenames=("${@:2}")
|
|
# if [[ "${#filenames[@]}" -eq 0 ]]; then
|
|
# etcfiles=$(
|
|
# nix eval ".#nixosConfigurations.\"$hostname\".config.environment.etc" --json \
|
|
# --apply 'builtins.mapAttrs (k: v: { inherit (v) enable target mode; })'
|
|
# )
|
|
# homekeys=$(
|
|
# nix eval ".#nixosConfigurations.\"$hostname\".config.home-manager.users" --json \
|
|
# --apply 'builtins.mapAttrs (user: config: { inherit (config.home) homeDirectory; files = builtins.mapAttrs (k: v: { inherit (v) enable target recursive; }) config.home.file; } )'
|
|
# # | jq 'to_entries[]| .key as $user | .value.homeDirectory as $homeDirectory | .value.files | to_entries[] | select(.value) | [ "config.home-manager.users.\"\($user)\".home.file.\"\(.key)\"", $homeDirectory + "/" + .value.target, .value.target, .key, $user, $homeDirectory] | @tsv' -r
|
|
# )
|
|
# filepathindex=$(
|
|
# jq --null-input -c \
|
|
# --arg hostname "$hostname" \
|
|
# --argjson etcfiles "$etcfiles" \
|
|
# --argjson homekeys "$homekeys" \
|
|
# '{
|
|
# "nixosConfigurations.\"\($hostname)\".config.environment.etc": (
|
|
# $etcfiles | with_entries( select(.value.enable) | { key, value: (.value + { target : ("/etc/" + .value.target) }) } )
|
|
# )
|
|
# } + (
|
|
# $homekeys | with_entries(
|
|
# .key as $user |
|
|
# .value.homeDirectory as $homeDirectory |
|
|
# {
|
|
# key: ("nixosConfigurations.\"\($hostname)\".config.home-manager.users.\"\($user)\".home.file"),
|
|
# value: (
|
|
# .value.files | with_entries(
|
|
# select(.value.enable) | {
|
|
# key,
|
|
# value: (.value + {
|
|
# target: ($homeDirectory + "/" + .value.target),
|
|
# }),
|
|
# }
|
|
# )
|
|
# ),
|
|
# }
|
|
# )
|
|
# )'
|
|
# )
|
|
|
|
# # cache
|
|
# if [[ "$UID" -ne 0 ]]; then
|
|
# mkdir -p .direnv/
|
|
# cat <<<"$filepathindex" >.direnv/just-cache-test-files-"$hostname".json
|
|
# fi
|
|
# else
|
|
# [[ -s .direnv/just-cache-test-files-"$hostname".json ]] || { printf >&2 "%s\n" "ERROR: no cache found"; false; }
|
|
# filepathindex=$(cat .direnv/just-cache-test-files-"$hostname".json)
|
|
# fi
|
|
|
|
# if [[ "${#filenames[@]}" -eq 0 ]]; then
|
|
# filenames=$(
|
|
# set +e
|
|
# jq <<<"$filepathindex" 'to_entries[] | .value | to_entries[] | .value' -r \
|
|
# | fzf --height=50% --reverse --multi -d$'\t' --with-nth 2
|
|
# )
|
|
# [[ -n "$selection" ]]
|
|
# fi
|
|
|
|
# # jq <<<"$filepathindex" . ; false
|
|
|
|
# filepathindex_inverse=$(
|
|
# jq <<<"$filepathindex" 'with_entries( .key as $attr | .value | to_entries[] | {key: .value.target, value: (.value + {attr: $attr, key})} )' -c
|
|
# )
|
|
# # jq <<<"$filepathindex_inverse" . ; false
|
|
|
|
# # jq <<<"$filepathindex" 'to_entries[] | .key as $attr | .value | to_entries[] | @sh "\(.value) \($attr).\("\""+.key+"\"")"' -r
|
|
|
|
# nix_expr=$(
|
|
# printf "%s\n" 'pkgs.writeScript "do" ('
|
|
# printf '"%s\\n" +\n' '#!${pkgs.runtimeShell}'
|
|
# printf '"%s\\n" +\n' 'set -euo pipefail'
|
|
# printf '"%s\\n" +\n' 'sudo : && SUDO=sudo || SUDO=:'
|
|
# printf "%s\n" "${filenames[@]}" |
|
|
# jq -sR --argjson index "$filepathindex_inverse" '
|
|
# split("\n") | map(select(.==""|not) | $index[.] ) | group_by(.attr) | map(
|
|
# " (let cfg = \(.[0].attr); in '"''"'" + (map(
|
|
# if .target | startswith("/etc/") then
|
|
# if .mode == "symlink" and false then "
|
|
# $SUDO ln -sfn ${cfg.\"\(.key)\".source} \(.target | @sh )
|
|
# " else "
|
|
# $SUDO rm -rf \(.target | @sh )
|
|
# $SUDO cp -a ${cfg.\"\(.key)\".source} \(.target | @sh )
|
|
# $SUDO chown -R ${toString cfg.\"\(.key)\".uid}:${toString cfg.\"\(.key)\".gid} \(.target | @sh )
|
|
# $SUDO chmod -R ${toString cfg.\"\(.key)\".uid}:${toString cfg.\"\(.key)\".gid} \(.target | @sh )
|
|
# # TODO: cfg.\"\(.key)\".user
|
|
# # TODO: cfg.\"\(.key)\".group
|
|
# " end
|
|
# else
|
|
# if .recursive then
|
|
# "${lib.getExe pkgs.xorg.lndir} -silent ${cfg.\"\(.key)\".source} \(.target | @sh )\n"
|
|
# else
|
|
# "ln -sfn ${cfg.\"\(.key)\".source} \(.target | @sh )\n"
|
|
# end
|
|
# end
|
|
# ) | join("")) + "'"''"')"
|
|
# ) | join(" + \n")
|
|
# ' -r
|
|
# printf "%s\n" ')'
|
|
# )
|
|
# # printf "%s\n" "$nix_expr" ; false
|
|
|
|
# flake=$(nix flake archive . --json | jq .path -r)
|
|
# nix build --impure --expr "with (builtins.getFlake ''$flake''); let inherit (nixosConfigurations.\"$hostname\") pkgs; in $nix_expr" --show-trace
|
|
# false
|
|
|
|
# # TODO: run the result
|
|
|
|
|
|
inspect:
|
|
nix run -- nixpkgs#nix-inspect -p .
|
|
|
|
inspect-config host=`just _a_host` prefix="":
|
|
nix run -- nixpkgs#nix-inspect -e '(builtins.getFlake "'"$PWD"'").nixosConfigurations."{{host}}".config{{ if prefix == "" { "" } else { "." + prefix } }}'
|
|
|
|
_nixos_attrnames:
|
|
#!/usr/bin/env -S bash -euo pipefail
|
|
hostname=$(hostname)
|
|
cachefile=.direnv/just-cache-nixos-attrnames.txt
|
|
if [[ flake.nix -nt "$cachefile" ]]; then
|
|
hostnames=$(nix eval .#nixosConfigurations --apply builtins.attrNames --json 2>/dev/null | jq '.[]' -r)
|
|
if [[ "$(grep <<<"$hostnames" -Fx "$hostname" | wc -l)" -eq 1 ]]; then
|
|
hostnames="$(printf "%s\n" "$hostname"; grep <<<"$hostnames" -v "^$hostname$")"
|
|
fi
|
|
if [[ "$UID" -ne 0 ]]; then
|
|
mkdir -p .direnv/
|
|
cat <<<"$hostnames" >"$cachefile"
|
|
fi
|
|
else
|
|
hostnames="$(cat $cachefile)"
|
|
fi
|
|
current_remote=$(just remote-current)
|
|
if [[ -n "$current_remote" && "$current_remote" != "$hostname" && "$(grep <<<"$hostnames" -Fx "$current_remote" | wc -l)" -eq 1 ]]; then
|
|
head -n1 <<<"$hostnames"
|
|
printf "%s\n" "$current_remote"
|
|
tail -n+2 <<<"$hostnames" | grep -vFx "$current_remote"
|
|
else
|
|
printf "%s\n" "$hostnames"
|
|
fi
|
|
|
|
@_a_host:
|
|
# just _nixos_attrnames | gum filter --placeholder "Pick a host..."
|
|
# just _nixos_attrnames | fzf --reverse
|
|
just _nixos_attrnames | fzf
|
|
|
|
@_some_hosts:
|
|
# just _nixos_attrnames | gum filter --placeholder "Pick a host..." --no-limit
|
|
# just _nixos_attrnames | fzf --reverse --multi
|
|
just _nixos_attrnames | fzf --multi
|
|
|
|
_nixos_fqdns:
|
|
#!/usr/bin/env -S bash -euo pipefail
|
|
cachefile=.direnv/just-cache-nixos-fqdns.json
|
|
if [[ flake.nix -nt "$cachefile" ]]; then
|
|
mkdir -p .direnv/
|
|
fqdns=$(nix eval .#nixosConfigurations --apply 'builtins.mapAttrs (_: x: x.config.networking.fqdn)' --json 2>/dev/null)
|
|
if [[ "$UID" -ne 0 ]]; then
|
|
cat <<<"$fqdns" >"$cachefile"
|
|
fi
|
|
else
|
|
fqdns=$( cat "$cachefile" )
|
|
fi
|
|
just _nixos_attrnames | jq -R --argjson fqdns "$fqdns" '$fqdns[.]' -r
|
|
|
|
@_a_fqdn:
|
|
# just _nixos_fqdns | gum filter --placeholder "Pick a host..."
|
|
# just _nixos_fqdns | fzf --reverse
|
|
just _nixos_fqdns | fzf
|
|
|
|
@_some_fqdns:
|
|
# just _nixos_fqdns | gum filter --placeholder "Pick a host..." --no-limit
|
|
# just _nixos_fqdns | fzf --reverse --multi
|
|
just _nixos_fqdns | fzf --multi
|
|
|
|
@remote-current:
|
|
# remote-host # slow
|
|
test ! -s .remote.toml || \
|
|
printf "%s\n" "$(tomlq <.remote.toml '.hosts | to_entries[] | select(.value.default==true) | .value.host' -r)"
|
|
|
|
@remote-list:
|
|
tomlq <.remote.toml '.hosts | to_entries[] | "remote-set \(.key+1) # -> \(.value.host)"' -r
|
|
|
|
@remote-set remote=`just remote-current >&2 && just _a_remote_label`:
|
|
remote-set "{{remote}}"
|
|
|
|
motd:
|
|
#!/usr/bin/env -S bash -euo pipefail
|
|
printf "%s\n" "Current remote: $(just remote-current)"
|
|
just remote-list
|
|
printf "\n"
|
|
todos=$(rg 'TODO' | wc -l)
|
|
if [[ "$todos" -gt 10 ]]; then
|
|
printf "%s\n" "There are $todos 'TODO's"
|
|
fi
|
|
|
|
@_a_remote_label:
|
|
just remote-list | gum filter --placeholder "Pick a remote..." | cut -d' ' -f2
|
|
|
|
@_some_remote_labels:
|
|
just remote-list | gum filter --placeholder "Pick remotes..." --no-limit | cut -d' ' -f2
|
|
|
|
@_some_remote_label_names:
|
|
just remote-list | gum filter --placeholder "Pick remotes..." --no-limit | tr ' ' '\t' | cut -f2,5
|
|
|
|
@_a_remote_fqdn:
|
|
just remote-list | gum filter --placeholder "Pick a remote..." | cut -d' ' -f5-
|
|
|
|
@_some_remote_fqdns:
|
|
just remote-list | gum filter --placeholder "Pick remote..." --no-limit | cut -d' ' -f5-
|
|
|
|
_remote_ensure $hostname=`just _a_fqdn`:
|
|
#!/usr/bin/env -S bash -euo pipefail
|
|
if test ! -s .remote.toml; then
|
|
remote-init "$hostname"
|
|
elif tomlq <.remote.toml '.hosts | to_entries[] |.value.host' -r | grep -q "$hostname"; then
|
|
true
|
|
else
|
|
remote-add "$hostname"
|
|
fi
|
|
|
|
@_remote_label_from_fqdn hostname=`just _a_fqdn`:
|
|
tomlq <.remote.toml '.hosts | to_entries[] | select(.value.host == "{{ hostname }}") | .key+1' -r
|
|
|
|
remote-mprocs *cmd:
|
|
#!/usr/bin/env -S bash -euo pipefail
|
|
declare -a cmd=("$@")
|
|
if [[ "${#cmd[@]}" -eq 0 ]]; then
|
|
cmd=($(just --summary --unsorted | xargs printf "just %s\n" | gum filter --placeholder "Pick a recipie..."))
|
|
[[ "${#cmd[@]}" -gt 0 ]]
|
|
fi
|
|
escaped_cmd="$(printf "%q " "${cmd[@]}")"
|
|
declare -a labels=()
|
|
declare -a names=()
|
|
label_names=$(just _some_remote_label_names | grep .)
|
|
readarray -td $'\n' labels < <( cut -f1 <<<"$label_names" )
|
|
readarray -td $'\n' names < <( cut -f2 <<<"$label_names" )
|
|
# TODO: when tmux exits the output is cleared
|
|
# printf "remote --label=%q \"env NIX_NO_NOM=1 ${escaped_cmd//%/%%}\"\n" "${labels[@]}" | xargs -d'\n' mprocs --names "$(IFS=','; printf "%s" "${labels[*]}")"
|
|
printf "tmux new \"remote --label=%q ${escaped_cmd//%/%%} ; read\" \; set-option destroy-unattached\n" "${labels[@]}" | xargs -d'\n' mprocs --names "$(IFS=','; printf "%s" "${names[*]}")"
|
|
|
|
@remote-mprocs-init +$cmd=`printf "just %s\n" $(just --summary --unsorted) | gum filter --placeholder "Pick a recipie..."`:
|
|
just _some_fqdns | xe -s 'just _remote_ensure "$1"; just _remote_label_from_fqdn "$1"' | sed -E 's/(.*)/remote --label="\1" "env NIX_NO_NOM=1 $cmd"/g' | xargs -d'\n' mprocs
|
|
|
|
# TODO: support multiple labels, run in tmux
|
|
#remote label=`just _a_remote_label` cmd=`printf "just %s\n" $(just --summary --unsorted) | gum filter --placeholder "Pick a recipie..."`:
|
|
# remote --label={{label}} {{cmd}}
|
|
|
|
# TODO: packaged as nix-web
|
|
@gorgon:
|
|
# https://codeberg.org/gorgon/gorgon/src/branch/main/nix-web
|
|
# https://discourse.nixos.org/t/a-web-ui-for-the-nix-store-early-beta/35762
|
|
nix run 'git+https://codeberg.org/gorgon/gorgon#nix-web'
|