diff --git a/.envrc b/.envrc index 527c643..30bb3c7 100644 --- a/.envrc +++ b/.envrc @@ -1,2 +1,2 @@ watch_file ./devshells/satellite.nix -use flake .#satellite +use flake .#satellite --accept-flake-config diff --git a/justfile b/justfile new file mode 100644 index 0000000..0a4be5c --- /dev/null +++ b/justfile @@ -0,0 +1,159 @@ +[private] +default: + @just --list + +hostname := `hostname` + +# {{{ Nixos rebuilds +[doc("Wrapper around `nixos-rebuild`, taking care of the generic arguments")] +[group("nix")] +nixos-rebuild action="rebuild" host=hostname: + #!/usr/bin/env python3 + import subprocess + + host = "{{host}}" + users = { + 'tethys': 'adrielus', + 'lapetus': 'adrielus', + 'calypso': 'moon', + } + + args = [ + "nixos-rebuild", + "{{action}}", + "--show-trace", + "--fast", + "--accept-flake-config", + "--flake", + ".#{{host}}" + ] + + if "{{host}}" == "{{hostname}}": + print("๐งฌ Switching nixos configuration (locally) for '{{BLUE + host + NORMAL}}'") + args.prepend("sudo") + else: + print("๐งฌ Switching nixos configuration (remotely) for '{{BLUE + host + NORMAL}}'") + args.append("--use-remote-sudo") + args += ["--target-host", f"{users[host]}@{host}"] + + subprocess.run(args, check=True) + print("๐ All done!") +# }}} +# {{{ Miscellaneous nix commands +[doc("Build the custom ISO provided by the flake")] +[group("nix")] +build-iso: + nix build .#nixosConfigurations.iso.config.system.build.isoImage + +[doc("Bumps flake inputs that usually need to be as up to date as possible")] +[group("nix")] +bump-common: + nix flake update \ + nixpkgs-unstable \ + neovim-nightly-overlay \ + firefox-addons \ + base16-schemes +# }}} + +# {{{ Age / sops related thingies +[doc("Save the user's SSH key as a key usable by sops")] +[group("secrets")] +ssh-to-age: + @echo "๐ Creating sops directory" >&2 + mkdir -p ~/.config/sops/age + + @echo "๐ Converting ssh key to age" >&2 + ssh-to-age -private-key -i ~/.ssh/id_ed25519 > ~/.config/sops/age/keys.txt + +[doc("Print the public age key used by sops on this machine")] +[group("secrets")] +age-public-key: ssh-to-age + @echo "๐ Printing public age key" >&2 + age-keygen -y ~/.config/sops/age/keys.txt + +[doc("Rekey every secrets file in the repository")] +[group("secrets")] +sops-rekey: + #!/usr/bin/env python3 + import glob + import subprocess + + paths = glob.glob("./**/secrets.yaml", recursive=True) + for file in paths: + print(f"๐ Rekeying {file}") + subprocess.run(["sops", "updatekeys", "--yes", file], check=True) + + print(f"๐ Successfully rekeyed {len(paths)} files!") + +[doc("Export keys to the hermes USB device")] +[group("secrets")] +export-keys: + #!/usr/bin/env bash + set -euo pipefail # Fail on errors and whatnot + + dir=/hermes/secrets/{{hostname}}/ + mkdir -p $dir + + cp /persist/state/etc/ssh/ssh* $dir + cp /home/*/.ssh/id* $dir + + # Perhaps I should ask this as a prompt instead? + touch $dir/disk.key + echo "๐ซ Don't forget to provide a disk encryption key!" +# }}} +# {{{ Rsync +# TODO: move this to some sort of oneshot service +[doc("Give every machine access to the restic backups")] +[group("secrets")] +update-rsync-keys: + #!/usr/bin/env bash + set -euo pipefail # Fail on errors and whatnot + shopt -s nullglob # Make globs expand to [] if no match + + keys=(hosts/nixos/*/keys/*.pub) + + if [ "${#keys[@]}" -eq 0 ]; then + echo "โ No SSH public keys found. Exiting." >&2 + exit 1 + fi + + tmpfile=$(mktemp) + url=$(cat hosts/nixos/common/optional/services/restic/url.txt) + + echo "๐ Copying ${#keys[@]} keys to $url" + cat ${keys[@]} > $tmpfile + scp $tmpfile $url:.ssh/authorized_keys + + rm -f $tmpfile + echo "๐ Successfully updated rsync.net SSH keys!" +# }}} + +# {{{ DNS +[doc("Prints the differences between the current and desired DNS records")] +[group("dns")] +dns-diff: + nix run .#octodns-sync -- + +[doc("Syncs DNS records using octodns")] +[group("dns")] +dns-push: + nix run .#octodns-sync -- --doit + +[doc("Clears every DNS record")] +[group("dns")] +dns-clear zoneid bearer: + #!/usr/bin/env bash + set -euo pipefail # Fail on errors and whatnot + + # Taken from https://developers.cloudflare.com/dns/zone-setups/troubleshooting/delete-all-records/ + curl --silent "https://api.cloudflare.com/client/v4/zones/{{zoneid}}/dns_records?per_page=50000" \ + --header "Authorization: Bearer {{bearer}}" \ + | jq --raw-output '.result[].id' | while read id + do + echo "๐งน Deleting '$id' record in zone '{{zoneid}}'" + curl --silent --request DELETE "https://api.cloudflare.com/client/v4/zones/{{zoneid}}/dns_records/$id" \ + --header "Authorization: Bearer {{bearer}}" + done + + echo "๐ All done!" +# }}} diff --git a/scripts/age-public-key.sh b/scripts/age-public-key.sh deleted file mode 100755 index c6298ed..0000000 --- a/scripts/age-public-key.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -nix-shell -p age --run "age-keygen -y ~/.config/sops/age/keys.txt" diff --git a/scripts/build-iso.sh b/scripts/build-iso.sh deleted file mode 100755 index 4a595ae..0000000 --- a/scripts/build-iso.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -nix build .#nixosConfigurations.iso.config.system.build.isoImage diff --git a/scripts/dns/delete-all-records.sh b/scripts/dns/delete-all-records.sh deleted file mode 100755 index 565c1f6..0000000 --- a/scripts/dns/delete-all-records.sh +++ /dev/null @@ -1,14 +0,0 @@ -zoneid=$1 -bearer=$2 - -# Taken from https://developers.cloudflare.com/dns/zone-setups/troubleshooting/delete-all-records/ -curl --silent "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records?per_page=50000" \ ---header "Authorization: Bearer $bearer" \ -| jq --raw-output '.result[].id' | while read id -do - echo "๐งน Deleting '$id' record in zone '$zoneid'" - curl --silent --request DELETE "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records/$id" \ ---header "Authorization: Bearer $bearer" -done - -echo "๐ All done!" diff --git a/scripts/github/.gitignore b/scripts/github/.gitignore deleted file mode 100644 index f500967..0000000 --- a/scripts/github/.gitignore +++ /dev/null @@ -1 +0,0 @@ -repos.json diff --git a/scripts/github/README.md b/scripts/github/README.md deleted file mode 100755 index 84cb349..0000000 --- a/scripts/github/README.md +++ /dev/null @@ -1 +0,0 @@ -This dir contains a collection of helpers I have used when changing my github username. In particular, I created a github org with my old name, forked all my repos there, automatically adding disclaimers to the readme about the location moving. That way, a malicious user cannot create an account with my old name and inject malicious code into locations like the old url for my nvim plugin, which some people might still be using. diff --git a/scripts/github/fetch-repos.sh b/scripts/github/fetch-repos.sh deleted file mode 100755 index 064919e..0000000 --- a/scripts/github/fetch-repos.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -gh repo list --limit 200 --json name,description,url,sshUrl,owner,visibility,isArchived,isFork \ - | jq > ./repos.json diff --git a/scripts/github/rename.py b/scripts/github/rename.py deleted file mode 100755 index 7ddc8d2..0000000 --- a/scripts/github/rename.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env nix-shell -#!nix-shell -p python3 -i python3 -import json -import os -import subprocess -import tempfile -import shutil - -file_path = './repos.json' -general_org = "temporarymoon" # Get it? Because forks involve many trees, which like, form a canopy or whatever... :/ -fork_org = "starlitcanopy" -future_name = "prescientmoon" -current_name = "mateiadrielrafael" - -with open(file_path, 'r') as file: - data = json.load(file) - -print(f"Parsed {len(data)} repos") - -with tempfile.TemporaryDirectory() as temp_dir: - print(f"Temporary directory: {temp_dir}") - for repo in data: - name = repo["name"] - url = repo["url"] - org = fork_org if repo['isFork'] else general_org - fork = f"{org}/{name}" - - os.chdir(temp_dir) - - if repo["isFork"]: - subprocess.run(f"gh api repos/{current_name}/{name}/transfer -f new_owner={org}", shell=True) - else: - subprocess.run(f"gh repo fork {url} --clone --org {org} --default-branch-only", shell=True) - os.chdir(f"{temp_dir}/{name}") - - # Create the readme if it doesn't exist - if not os.path.exists("README.md"): - with open("README.md", 'w') as file: - file.write('') - - # Read the existing content of the readme - with open("README.md", 'r') as file: - existing_content = file.read() - - future = f"{future_name}/{name}" - - # Add disclaimer at top - text_to_prepend = f"# ๐ง This repo has been moved to [{future}](https://github.com/{future}) ๐ง\n" - - with open("README.md", 'w') as file: - file.write(text_to_prepend + existing_content) - - # Commit changes - subprocess.run("git add .", shell=True) - subprocess.run("git commit -m 'Added movement notice to readme [skip-ci]'", shell=True) - subprocess.run("git push", shell=True) - - # Fix visibility and archive repo - visibility = repo["visibility"] - if visibility != "public": - subprocess.run(f"gh repo edit {fork} --visibility {visibility}", shell=True) - subprocess.run(f"gh repo archive {fork} --yes", shell=True) - shutil.rmtree(f"{temp_dir}/{name}") - - print(f"Done moving to {fork}") diff --git a/scripts/live.sh b/scripts/live.sh index 580e102..ad55e2a 100755 --- a/scripts/live.sh +++ b/scripts/live.sh @@ -2,6 +2,8 @@ #!nix-shell ../devshells/bootstrap/shell.nix #!nix-shell -i bash +# TODO: convert to justfile + # Check if at least one argument is provided if [ "$#" != "2" ] && [ "$#" != "3" ]; then echo "โ Usage: $0 <host> <disko-mode> [action]" diff --git a/scripts/rebuild.sh b/scripts/rebuild.sh deleted file mode 100755 index 5977212..0000000 --- a/scripts/rebuild.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -sudo nixos-rebuild switch \ - --show-trace \ - --fast \ - --accept-flake-config \ - --flake .#$(hostname) diff --git a/scripts/repl.sh b/scripts/repl.sh deleted file mode 100755 index c8cfb4f..0000000 --- a/scripts/repl.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -nix repl .#nixosConfigurations.$1.config diff --git a/scripts/save-keys.sh b/scripts/save-keys.sh deleted file mode 100755 index 40c2644..0000000 --- a/scripts/save-keys.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -dir=/hermes/secrets/$(hostname)/ -mkdir -p $dir -cp /persist/state/etc/ssh/ssh* $dir -cp /home/*/.ssh/id* $dir -touch $dir/disk.key - -echo "๐ซ Don't forget to provide a disk encryption key!" diff --git a/scripts/setup-rsync-ssh.sh b/scripts/setup-rsync-ssh.sh deleted file mode 100755 index 8a59a41..0000000 --- a/scripts/setup-rsync-ssh.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -# Create tmp file -tmpfile=$(mktemp) - -# Concat files -cat hosts/nixos/*/keys/*.pub > $tmpfile - -# Copy concat result -scp $tmpfile $(cat hosts/nixos/common/optional/services/restic/url.txt):.ssh/authorized_keys - -# Cleanup file -rm -rf $tmpfile diff --git a/scripts/sops-rekey.sh b/scripts/sops-rekey.sh deleted file mode 100755 index aa59227..0000000 --- a/scripts/sops-rekey.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env nix-shell -#!nix-shell -p sops -i bash - -# https://askubuntu.com/questions/1010707/how-to-enable-the-double-star-globstar-operator -# Enable the ** operator -shopt -s globstar - -for file in ./**/secrets.yaml; do - echo "๐ Rekeying $file" - sops updatekeys --yes $file -done - -echo "๐ All done!" diff --git a/scripts/ssh-to-age.sh b/scripts/ssh-to-age.sh deleted file mode 100755 index 875c544..0000000 --- a/scripts/ssh-to-age.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -echo "๐ Creating sops directory" -mkdir -p ~/.config/sops/age - -echo "๐ Converting ssh key to age" -nix-shell -p ssh-to-age --run "ssh-to-age -private-key -i ~/.ssh/id_ed25519 > ~/.config/sops/age/keys.txt" - -echo "๐ All done"