This commit is contained in:
David Tomaschik
2026-06-30 10:47:42 -07:00
17 changed files with 398 additions and 74 deletions

View File

@@ -1,6 +1,7 @@
tap "dart-lang/dart" tap "dart-lang/dart", trusted: true
tap "holtwick/tap" tap "espressif/eim"
tap "sass/sass" tap "holtwick/tap", trusted: true
tap "sass/sass", trusted: true
brew "ack" brew "ack"
brew "acme.sh" brew "acme.sh"
@@ -20,9 +21,11 @@ brew "devcontainer"
brew "dfu-util" brew "dfu-util"
brew "difftastic" brew "difftastic"
brew "direnv" brew "direnv"
brew "dua-cli"
brew "duck" brew "duck"
brew "dust" brew "dust"
brew "earthly" brew "earthly"
brew "espressif/eim/eim", trusted: true
brew "esptool" brew "esptool"
brew "fish" brew "fish"
brew "fq" brew "fq"
@@ -31,11 +34,14 @@ brew "ghidra", link: false
brew "git" brew "git"
brew "git-delta" brew "git-delta"
brew "git-lfs" brew "git-lfs"
brew "git-xet"
brew "glib"
brew "gnupg" brew "gnupg"
brew "go" brew "go"
brew "gradle" brew "gradle"
brew "hashcat"
brew "hf" brew "hf"
brew "holtwick/tap/bx" brew "holtwick/tap/bx", trusted: true
brew "htop" brew "htop"
brew "httpie" brew "httpie"
brew "hugo" brew "hugo"
@@ -44,7 +50,9 @@ brew "john-jumbo"
brew "jq" brew "jq"
brew "kubeconform" brew "kubeconform"
brew "kubectx" brew "kubectx"
brew "libgcrypt"
brew "librsvg" brew "librsvg"
brew "libslirp"
brew "lima" brew "lima"
brew "minikube" brew "minikube"
brew "mise" brew "mise"
@@ -56,23 +64,27 @@ brew "ollama"
brew "p7zip" brew "p7zip"
brew "pipenv" brew "pipenv"
brew "pipx" brew "pipx"
brew "pixman"
brew "pkgconf" brew "pkgconf"
brew "protobuf" brew "protobuf"
brew "pwgen" brew "pwgen"
brew "pwntools" brew "pwntools"
brew "python@3.13" brew "python@3.13"
brew "python@3.14"
brew "qemu" brew "qemu"
brew "restic" brew "restic"
brew "ripgrep" brew "ripgrep"
brew "ruby" brew "ruby", link: false
brew "ruby@3.3" brew "ruby@3.3"
brew "rustup" brew "rustup"
brew "sass/sass/migrator" brew "sass/sass/migrator"
brew "sass/sass/sass" brew "sass/sass/sass"
brew "sdl2-compat"
brew "shellcheck" brew "shellcheck"
brew "smartmontools" brew "smartmontools"
brew "starship" brew "starship"
brew "tmux" brew "tmux"
brew "todoist-cli"
brew "uv" brew "uv"
brew "virtualenvwrapper" brew "virtualenvwrapper"
brew "wget" brew "wget"
@@ -101,7 +113,6 @@ cask "raycast"
cask "rectangle" cask "rectangle"
cask "scroll-reverser" cask "scroll-reverser"
cask "temurin" cask "temurin"
cask "veracrypt"
cask "wezterm" cask "wezterm"
cask "zulu@17" cask "zulu@17"
@@ -121,11 +132,12 @@ if !is_corp?
brew "virt-manager" brew "virt-manager"
cask "claude-code" cask "claude-code"
cask "codex"
cask "cryptomator" cask "cryptomator"
cask "keepassxc" cask "keepassxc"
cask "gcloud-cli" cask "gcloud-cli"
cask "google-cloud-sdk"
cask "keybase" cask "keybase"
cask "orbstack" cask "orbstack"
cask "jordanbaird-ice" cask "jordanbaird-ice@beta"
cask "veracrypt"
end end

1
CLAUDE.md Symbolic link
View File

@@ -0,0 +1 @@
AGENTS.md

212
bin/newnote Executable file
View File

@@ -0,0 +1,212 @@
#!/usr/bin/env bash
# Exit on error, undefined variables, and pipe failures
set -euo pipefail
show_help() {
cat << EOF
Usage: $(basename "$0") [options] <note_name_or_path>
Create a new note in your Obsidian vault.
Options:
-v, --vault <dir> Specify the Obsidian vault directory.
--overwrite Overwrite the file if it already exists.
-h, --help Show this help message.
EOF
}
VAULT_DIR=""
OVERWRITE="false"
NOTE_PATH=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
-v|--vault)
if [[ -z "${2:-}" ]]; then
echo "Error: --vault requires a directory path." >&2
exit 1
fi
VAULT_DIR="$2"
shift 2
;;
--overwrite)
OVERWRITE="true"
shift
;;
-h|--help)
show_help
exit 0
;;
-*)
echo "Error: Unknown option: $1" >&2
show_help
exit 1
;;
*)
if [[ -n "$NOTE_PATH" ]]; then
echo "Error: Multiple note paths provided: $NOTE_PATH and $1" >&2
exit 1
fi
NOTE_PATH="$1"
shift
;;
esac
done
if [[ -z "$NOTE_PATH" ]]; then
echo "Error: Missing note path/name." >&2
show_help
exit 1
fi
# 1. Find the Obsidian vault.
if [[ -n "$VAULT_DIR" ]]; then
# -v/--vault was passed. Check that the directory exists and contains a .obsidian directory.
if [[ ! -d "$VAULT_DIR" ]]; then
echo "Error: Specified vault directory does not exist: $VAULT_DIR" >&2
exit 1
fi
if [[ ! -d "$VAULT_DIR/.obsidian" ]]; then
echo "Error: Specified directory is not an Obsidian vault (missing .obsidian): $VAULT_DIR" >&2
exit 1
fi
VAULT_DIR="$(cd "$VAULT_DIR" && pwd)"
else
# Search directories upward for a parent (or current) directory containing a .obsidian subdirectory.
# Stop at the user's home directory or a filesystem boundary.
CURRENT_DIR="$PWD"
FOUND_VAULT=""
get_device_id() {
local dir="$1"
if [[ "$(uname)" == "Darwin" ]]; then
stat -f '%d' "$dir" 2>/dev/null || echo ""
else
stat -c '%d' "$dir" 2>/dev/null || echo ""
fi
}
CURRENT_DEV="$(get_device_id "$CURRENT_DIR")"
while [[ "$CURRENT_DIR" != "/" && "$CURRENT_DIR" != "$HOME" ]]; do
if [[ -d "$CURRENT_DIR/.obsidian" ]]; then
FOUND_VAULT="$CURRENT_DIR"
break
fi
PARENT_DIR="$(dirname "$CURRENT_DIR")"
if [[ "$PARENT_DIR" == "$CURRENT_DIR" ]]; then
break
fi
# Check filesystem boundary
PARENT_DEV="$(get_device_id "$PARENT_DIR")"
if [[ -n "$CURRENT_DEV" && -n "$PARENT_DEV" && "$CURRENT_DEV" != "$PARENT_DEV" ]]; then
break
fi
CURRENT_DIR="$PARENT_DIR"
CURRENT_DEV="$PARENT_DEV"
done
# Check the last checked directory (could be HOME or /)
if [[ -z "$FOUND_VAULT" && -d "$CURRENT_DIR/.obsidian" ]]; then
FOUND_VAULT="$CURRENT_DIR"
fi
if [[ -n "$FOUND_VAULT" ]]; then
VAULT_DIR="$FOUND_VAULT"
else
# Fallback paths in order: ~/Notes, ~/Obsidian/Notes, ~/Personal/Notes, ~/Projects/Notes.
FALLBACKS=(
"$HOME/Notes"
"$HOME/notes"
"$HOME/Obsidian/Notes"
"$HOME/Obsidian/notes"
"$HOME/Personal/Notes"
"$HOME/Personal/notes"
"$HOME/Projects/Notes"
"$HOME/Projects/notes"
)
for path in "${FALLBACKS[@]}"; do
if [[ -d "$path" && -d "$path/.obsidian" ]]; then
VAULT_DIR="$(cd "$path" && pwd)"
break
fi
done
fi
fi
if [[ -z "$VAULT_DIR" ]]; then
echo "Error: Could not find an Obsidian vault. Please specify one with -v/--vault." >&2
exit 1
fi
# Strip leading slash from NOTE_PATH to handle relative paths properly
NOTE_PATH="${NOTE_PATH#/}"
# 2. Determine if current working directory is within the vault.
# Resolve physical paths to handle symlinks cleanly.
RESOLVED_PWD="$(pwd -P)"
RESOLVED_VAULT="$(cd "$VAULT_DIR" && pwd -P)"
if [[ "$RESOLVED_PWD" == "$RESOLVED_VAULT" || "$RESOLVED_PWD" == "$RESOLVED_VAULT"/* ]]; then
# Within the vault, treat relative to CWD
TARGET_FILE="$PWD/$NOTE_PATH"
else
# Not within the vault, treat relative to vault root
TARGET_FILE="$VAULT_DIR/$NOTE_PATH"
fi
TARGET_DIR="$(dirname "$TARGET_FILE")"
TARGET_BASE="$(basename "$TARGET_FILE")"
# If there's no file extension on the argument, add .md.
if [[ "$TARGET_BASE" != *.* ]]; then
TARGET_BASE="$TARGET_BASE.md"
fi
TARGET_FILE="$TARGET_DIR/$TARGET_BASE"
# If the necessary directory components don't exist, create them.
if [[ ! -d "$TARGET_DIR" ]]; then
mkdir -p "$TARGET_DIR"
fi
# 3. If the file exists and there's no --overwrite argument, throw an error.
if [[ -f "$TARGET_FILE" && "$OVERWRITE" != "true" ]]; then
echo "Error: File already exists: $TARGET_FILE (use --overwrite to replace it)" >&2
exit 1
fi
# 4. If the path ends in .md (case-insensitive), generate appropriate YAML front matter and write it to the new file.
if [[ "${TARGET_BASE,,}" == *.md ]]; then
NOTE_TITLE="${TARGET_BASE%.*}"
CURRENT_DATE="$(date +"%Y-%m-%d %H:%M")"
cat << EOF > "$TARGET_FILE"
---
title: "$NOTE_TITLE"
date: $CURRENT_DATE
tags: []
---
EOF
else
# Just touch the file to ensure it exists
touch "$TARGET_FILE"
fi
# 5. Open the user's $EDITOR (falling back to vim/vi if unset) pointing to the new file.
EDITOR="${EDITOR:-}"
if [[ -z "$EDITOR" ]]; then
if command -v vim >/dev/null 2>&1; then
EDITOR="vim"
else
EDITOR="vi"
fi
fi
exec "$EDITOR" "$TARGET_FILE"

View File

@@ -18,7 +18,7 @@ HOST_SPECIFIC_SCRIPT="${RESTIC_SCRIPTS_DIR}/${HOSTNAME}"
# Check if the script exists and is executable # Check if the script exists and is executable
if [[ -f "${HOST_SPECIFIC_SCRIPT}" && -x "${HOST_SPECIFIC_SCRIPT}" ]]; then if [[ -f "${HOST_SPECIFIC_SCRIPT}" && -x "${HOST_SPECIFIC_SCRIPT}" ]]; then
echo "Executing restic script for hostname: ${HOSTNAME}" echo "Executing restic script for hostname: ${HOSTNAME}"
"${HOST_SPECIFIC_SCRIPT}" "${HOST_SPECIFIC_SCRIPT}" "$@"
else else
echo "Error: No executable restic script found for hostname '${HOSTNAME}' at '${HOST_SPECIFIC_SCRIPT}'." >&2 echo "Error: No executable restic script found for hostname '${HOSTNAME}' at '${HOST_SPECIFIC_SCRIPT}'." >&2
echo "Please create an executable script at that path if you want to use this functionality." >&2 echo "Please create an executable script at that path if you want to use this functionality." >&2

View File

@@ -76,7 +76,8 @@ run_self_test() {
cat <<EOF > "${target}" cat <<EOF > "${target}"
${key_man} ${key_man}
${key1} # This should be removed as it's now managed # This is a manual annotation for key1
${key1}
EOF EOF
echo "Executing script in test mode..." echo "Executing script in test mode..."
@@ -107,6 +108,9 @@ EOF
echo -n "Check masking... " echo -n "Check masking... "
if ! grep -q "masked" "${target}"; then echo "OK"; else echo "FAIL"; exit 1; fi if ! grep -q "masked" "${target}"; then echo "OK"; else echo "FAIL"; exit 1; fi
echo -n "Check user comment preservation... "
if grep -q "This is a manual annotation for key1" "${target}"; then echo "OK"; else echo "FAIL"; exit 1; fi
echo "Self-test passed successfully!" echo "Self-test passed successfully!"
exit 0 exit 0
} }
@@ -138,6 +142,40 @@ mkdir -p "$(dirname "${TARGET_FILE}")"
TMP_FILE=$(mktemp) TMP_FILE=$(mktemp)
CLEANUP_FILES+=("${TMP_FILE}") CLEANUP_FILES+=("${TMP_FILE}")
# Build a map of key-signature -> user comments from the existing target file.
# Comments above keys are preserved into the managed block (# Source: lines are excluded).
# Multiple comment lines are joined with SUBSEP (\034) for safe transport through AWK.
USER_COMMENTS_FILE=$(mktemp)
CLEANUP_FILES+=("${USER_COMMENTS_FILE}")
if [[ -f "${TARGET_FILE}" ]]; then
awk -v begin="${BEGIN_MARKER}" -v end="${END_MARKER}" '
BEGIN { pending="" }
$0 == begin { pending=""; next }
$0 == end { pending=""; next }
/^# Source:/ { next }
/^[[:space:]]*#/ {
pending = (pending == "" ? $0 : pending SUBSEP $0)
next
}
/^[[:space:]]*$/ { pending=""; next }
{
n = split($0, parts, " ")
sig = ""
for (i=1; i<=n; i++) {
sig = (sig == "" ? parts[i] : sig " " parts[i])
if (parts[i] ~ /^(ssh-|ecdsa-|sk-)/ && i < n) {
sig = sig " " parts[i+1]
break
}
}
if (sig != "" && pending != "") {
print sig "\t" pending
}
pending = ""
}
' "${TARGET_FILE}" > "${USER_COMMENTS_FILE}"
fi
collect_keys() { collect_keys() {
local dirs=("${@}") local dirs=("${@}")
for dir in "${dirs[@]}"; do for dir in "${dirs[@]}"; do
@@ -158,7 +196,17 @@ collect_keys() {
} }
# Use a HEREDOC for the complex AWK script to avoid shell interpolation issues # Use a HEREDOC for the complex AWK script to avoid shell interpolation issues
MANAGED_BLOCK=$(collect_keys "${SOURCE_DIRS[@]}" | awk -F'\t' ' MANAGED_BLOCK=$(collect_keys "${SOURCE_DIRS[@]}" | awk -F'\t' -v user_comments_file="${USER_COMMENTS_FILE}" '
BEGIN {
while ((getline line < user_comments_file) > 0) {
tab = index(line, "\t")
if (tab > 0) {
sig = substr(line, 1, tab - 1)
user_comments[sig] = substr(line, tab + 1)
}
}
close(user_comments_file)
}
{ {
# Splitting on the first tab manually to be robust # Splitting on the first tab manually to be robust
tab_idx = index($0, "\t") tab_idx = index($0, "\t")
@@ -191,6 +239,12 @@ END {
for (i=1; i<=count; i++) { for (i=1; i<=count; i++) {
sig = order[i] sig = order[i]
print "# Source: " sources[sig] print "# Source: " sources[sig]
if (sig in user_comments) {
n = split(user_comments[sig], comment_lines, SUBSEP)
for (j=1; j<=n; j++) {
print comment_lines[j]
}
}
print keys[sig] print keys[sig]
} }
}') }')

View File

@@ -28,6 +28,9 @@ alias clear-gpg-agent="echo RELOADAGENT | gpg-connect-agent"
# Earthly ssh # Earthly ssh
alias earthly='earthly --ssh-auth-sock ""' alias earthly='earthly --ssh-auth-sock ""'
# ESP-IDF
alias activate_idf="source ~/.espressif/tools/activate_idf_v*.sh"
if [ "$(uname)" = "Linux" ]; then if [ "$(uname)" = "Linux" ]; then
# Cryptsetup alias # Cryptsetup alias
alias luksFormat='cryptsetup luksFormat --type=luks2 --pbkdf-memory=2560000 --pbkdf=argon2id -i 15000 -s 512 -h sha256 -c aes-xts-plain64' alias luksFormat='cryptsetup luksFormat --type=luks2 --pbkdf-memory=2560000 --pbkdf=argon2id -i 15000 -s 512 -h sha256 -c aes-xts-plain64'

View File

@@ -39,16 +39,3 @@ disabled = true
[kubernetes] [kubernetes]
disabled = false disabled = false
detect_folders = ["k8s"] detect_folders = ["k8s"]
[custom.gemini_context]
description = "Displays the current Gemini CLI context"
when = "test -n \"$GEMINI_CLI_HOME\""
command = """
context_dir=\"${XDG_CONFIG_HOME:-$HOME/.config}/gemini\"
if [[ \"$GEMINI_CLI_HOME\" == $context_dir/* ]]; then
basename \"$GEMINI_CLI_HOME\"
fi
"""
style = "bold blue"
format = "♊[$output](blue) "
shell = ["/bin/sh", "-c"]

View File

@@ -45,3 +45,6 @@
hibernationfile hibernationfile
sleepimage sleepimage
swapfile swapfile
# Android and other big tools
/Users/*/.android

View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDYQOAB5bJ9DjMXyY67GEI99kK1LG8XF+cWJ4md52rPnOeJd0da7l26bn9NtXCma6DP5gZQArfxHsPh7I4SbYJRYxTCCCE/Jsd8mLB22DcoeY+MqPA2g71j3KrYsvuJC++9GHK2Xc7ZRmhAugEmC/NAdtORBVhtBSAUgyCmUczKHoCAqHmq8j54En8kRYjbvlHPpDsNoRuhcH5uDGBIVkbV7UtBl2oUlRNVw7grs6XS7cPU2zCQSxcrRRuAfV4hmGG2eKaPpieNg0MAAbR0G5ssWW3IuYwd1ys5wA0YQuWUhxadUuYc46/cqyyoVIFlfjxCVTX+2w3900SDPOF/YrOwctAb23+78WN6GPnAmmS3zcmXTGsJiw/mmyBlqYI/JdSgrgI+COlcP0rlF/uklzEywfD91m1lno1u2IApdAumZWHR8aFnpHQXfI6rWc1o/V+RBpz5Xe6D2h9CPT3AE303BV09HGmidb0t6bCKoabTDwvE+KojIcbKBji6g8V6KTM=

View File

@@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOP0EQthckpi83EoFXtbPnn4Ytd7FYW6Nb3W9ZahqOKhNAqv1owot957ihKHtGKFnYr0Jwgp0TNOdpz6nV9wwCo= david@zazu

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINFlZdKMzY8S/znw16R3X9jO+BaJ30NloH9XWtftjYh6 david@baymax.local

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBeDzE5KLJh2a9p0u702H9+rvaB1HoLLBU1I2Lx6NUbC david@scar

View File

@@ -0,0 +1 @@
sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBF8YzO0pEZ9DKHyqgPZpwlv6s4FBYDunIV23R4VUfiC3dw3P1vX9+tDO2+K65v+0vL2rAuBr5ZAHmDxiY8PzDwoAAAAEc3NoOg== david@zazu-sk

View File

@@ -214,7 +214,7 @@ if [[ $- == *i* ]] ; then
if [[ ! -f "$DUMPFILE" || ( -n "$newest_comp" && "$newest_comp" -nt "$DUMPFILE" ) ]]; then if [[ ! -f "$DUMPFILE" || ( -n "$newest_comp" && "$newest_comp" -nt "$DUMPFILE" ) ]]; then
compinit -i -d "$DUMPFILE" compinit -i -d "$DUMPFILE"
# Asynchronously compile the dump file with an atomic rename # Asynchronously compile the dump file with an atomic rename
{ zcompile "$DUMPFILE.zwc.tmp" "$DUMPFILE" && mv -f "$DUMPFILE.zwc.tmp" "$DUMPFILE.zwc" } &! { zcompile "$DUMPFILE.zwc.$$.tmp" "$DUMPFILE" && mv -f "$DUMPFILE.zwc.$$.tmp" "$DUMPFILE.zwc" } &!
else else
compinit -C -i -d "$DUMPFILE" compinit -C -i -d "$DUMPFILE"
fi fi

View File

@@ -28,6 +28,27 @@ have_command() {
command -v "${1}" >/dev/null 2>&1 command -v "${1}" >/dev/null 2>&1
} }
raw_sha256sum() {
local file="${1}"
if [[ -z "${file}" ]]; then
echo "Error: No file specified" >&2
return 1
fi
if [[ ! -f "${file}" ]]; then
echo "Error: File not found: ${file}" >&2
return 1
fi
if have_command sha256sum ; then
sha256sum "${file}" | awk '{print $1}'
elif have_command shasum ; then
shasum -a 256 "${file}" | awk '{print $1}'
else
echo "Error: Neither sha256sum nor shasum is available" >&2
return 1
fi
}
sudo_group() { sudo_group() {
if [[ "$(id -u)" -eq 0 ]] ; then if [[ "$(id -u)" -eq 0 ]] ; then
return 0 return 0
@@ -65,48 +86,6 @@ link_directory_contents() {
done done
} }
ssh_key_already_installed() {
# Return 1 if the key isn't already installed, 0 if it is
local AK="${HOME}/.ssh/authorized_keys"
if [[ ! -f "$AK" ]] ; then
return 1
fi
# Extract the key data (field 2) from the key file, ignoring comments
local key_data
key_data=$(awk '/^ssh-/ {print $2}' "$1")
if [[ -z "${key_data}" ]]; then
# Not a valid key file
return 1
fi
# Use grep with fixed-string matching to see if the key is present.
# The exit code of grep is 0 on match, 1 on no match, which is perfect.
grep -F -q -- "${key_data}" "${AK}"
}
install_ssh_keys() {
# Install SSH keys
verbose 'Installing SSH keys...'
local AK="${HOME}/.ssh/authorized_keys"
local key
local keydir
if [[ "${TRUST_ALL_KEYS}" = 1 ]] ; then
keydir="${BASEDIR}/keys/ssh"
else
keydir="${BASEDIR}/keys/ssh/trusted"
fi
for key in "${keydir}"/* ; do
if [[ ! -f "${key}" ]] ; then
continue
fi
if ssh_key_already_installed "${key}" ; then
verbose "Key $(basename "${key}") already installed..."
continue
fi
echo "# $(basename "${key}") added from skel on $(date +%Y-%m-%d)" >> "${AK}"
cat "${key}" >> "${AK}"
done
}
install_gpg_keys() { install_gpg_keys() {
have_command gpg || \ have_command gpg || \
return 0 return 0
@@ -120,7 +99,7 @@ install_known_hosts() {
verbose 'Installing known hosts...' >&2 verbose 'Installing known hosts...' >&2
local skel_hosts="${BASEDIR}/keys/known_hosts" local skel_hosts="${BASEDIR}/keys/known_hosts"
local user_hosts="${HOME}/.ssh/known_hosts" local user_hosts="${HOME}/.ssh/known_hosts"
local merge_script="${BASEDIR}/skeltools/merge_authorized_keys" local merge_script="${BASEDIR}/skeltools/merge_known_hosts"
if [[ ! -f "${skel_hosts}" ]]; then if [[ ! -f "${skel_hosts}" ]]; then
return 0 return 0
@@ -151,7 +130,10 @@ install_known_hosts() {
} }
install_keys() { install_keys() {
install_ssh_keys if [[ -x "${BASEDIR}/bin/update-authorized-keys" ]]; then
verbose 'Installing SSH keys via update-authorized-keys...'
printf 'y\n' | "${BASEDIR}/bin/update-authorized-keys"
fi
install_gpg_keys install_gpg_keys
install_known_hosts install_known_hosts
} }
@@ -174,7 +156,6 @@ save_prefs() {
echo "BASEDIR=\"${BASEDIR}\"" echo "BASEDIR=\"${BASEDIR}\""
echo "MINIMAL=\"${MINIMAL}\"" echo "MINIMAL=\"${MINIMAL}\""
echo "INSTALL_KEYS=\"${INSTALL_KEYS}\"" echo "INSTALL_KEYS=\"${INSTALL_KEYS}\""
echo "TRUST_ALL_KEYS=\"${TRUST_ALL_KEYS}\""
echo "VERBOSE=\"${VERBOSE}\"" echo "VERBOSE=\"${VERBOSE}\""
} >| "$pref_file" } >| "$pref_file"
} }
@@ -208,6 +189,15 @@ install_dotfiles() {
install_starship() { install_starship() {
if have_command starship ; then return 0 ; fi if have_command starship ; then return 0 ; fi
if have_command brew ; then
verbose "Attempting to install Starship via Homebrew..."
if brew install starship ; then
return 0
fi
echo "brew install starship failed, trying other methods..." >&2
fi
if have_command apt-get && sudo_group ; then if have_command apt-get && sudo_group ; then
if maybe_sudo apt-get install -qy starship ; then if maybe_sudo apt-get install -qy starship ; then
return 0 return 0
@@ -215,7 +205,9 @@ install_starship() {
echo "apt-get install starship failed, installing locally" >&2 echo "apt-get install starship failed, installing locally" >&2
fi fi
local tmpd local tmpd
tmpd="$(mktemp -d tmp.starship.XXXXXX)" tmpd="$(mktemp -d tmp.starship.XXXXXX)" || return 1
trap '[[ -n "${tmpd}" && -d "${tmpd}" ]] && rm -rf "${tmpd}"' EXIT
local install_path="${tmpd}/install.sh" local install_path="${tmpd}/install.sh"
if have_command curl ; then if have_command curl ; then
curl -sSL --show-error -o "${install_path}" https://starship.rs/install.sh curl -sSL --show-error -o "${install_path}" https://starship.rs/install.sh
@@ -223,22 +215,30 @@ install_starship() {
wget -q -O "${install_path}" --https-only https://starship.rs/install.sh wget -q -O "${install_path}" --https-only https://starship.rs/install.sh
else else
echo "No curl or wget available!!" >&2 echo "No curl or wget available!!" >&2
rm -rf "${tmpd}"
trap - EXIT
return 1 return 1
fi fi
local dl_hash local dl_hash
dl_hash="$(sha256sum "${install_path}" | awk '{print $1}')" dl_hash="$(raw_sha256sum "${install_path}")"
if [[ "$dl_hash" != "${STARSHIP_INSTALL_HASH}" ]] ; then if [[ "$dl_hash" != "${STARSHIP_INSTALL_HASH}" ]] ; then
echo "Hash check failed!!" >&2 echo "Hash check failed!!" >&2
echo "Expected: ${STARSHIP_INSTALL_HASH}, got ${dl_hash} on ${install_path}" >&2 echo "Expected: ${STARSHIP_INSTALL_HASH}, got ${dl_hash} on ${install_path}" >&2
rm -rf "${tmpd}"
trap - EXIT
return 1 return 1
fi fi
if sudo_group ; then if sudo_group ; then
if maybe_sudo sh "${install_path}" ; then if maybe_sudo sh "${install_path}" ; then
rm -rf "${tmpd}"
trap - EXIT
return 0 return 0
fi fi
echo "root installation failed, falling back to user-local" >&2 echo "root installation failed, falling back to user-local" >&2
fi fi
sh "${install_path}" -b "${LOCAL_BIN}" sh "${install_path}" -b "${LOCAL_BIN}"
rm -rf "${tmpd}"
trap - EXIT
} }
install_main() { install_main() {
@@ -313,7 +313,6 @@ read_saved_prefs
: ${BASEDIR:=${SCRIPT_DIR}} : ${BASEDIR:=${SCRIPT_DIR}}
: ${MINIMAL:=0} : ${MINIMAL:=0}
: ${INSTALL_KEYS:=1} : ${INSTALL_KEYS:=1}
: ${TRUST_ALL_KEYS:=0}
: ${VERBOSE:=0} : ${VERBOSE:=0}
: ${SAVE:=1} : ${SAVE:=1}

View File

@@ -1,3 +1,51 @@
|1|ZWm0E5aueYzKuoY8OrGAI2ZUdWI=|L8KgVjGyomaw47OGrhpPnipXDKU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKX08QrgyP7du28Re9NlKxLm6aJFUD4F2vWBCuiqo7KNrIPbgjVP9yOwy2gXueC6fbuVQj/C4BdnkgHw9hFXbC0= |1|ZWm0E5aueYzKuoY8OrGAI2ZUdWI=|L8KgVjGyomaw47OGrhpPnipXDKU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKX08QrgyP7du28Re9NlKxLm6aJFUD4F2vWBCuiqo7KNrIPbgjVP9yOwy2gXueC6fbuVQj/C4BdnkgHw9hFXbC0=
|1|MjwrIkZqV0wbZ7pWue9nsFREyhk=|lGN2O8BcMHleUkD4yBtYRXSm1Yw= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwbTUJWJ3mytxrYPKrzRDIuBRd+/X/3T/QT2gudQfDN/mxkAMTg+uLoObXnUOtfhXD+lXP/s/GKXoPmsV/ausSz2YxBrQQXH7SwCpUq5GRXcl5s43JAJ1MbQq2EA5pa1CEBzUgd/Osu/WaVsKwfABV7QeKhblMfM0a5XcsfawqVbMJ0q/egYiSsWRVTU2iNMXILChJT6WUVoUiDENRnW98iy1qQgY0ge6hr7Gh6m23Fg6yfYDBQrqszbTfFYlqGe54bGlnxZvGp+Ybas02D29whAHwdNCSmDWXW0EvSpyt9WZUm0WOQt3t9RXpKeKLrWH4V/5BFYrONY1GsKuE783tw== |1|MjwrIkZqV0wbZ7pWue9nsFREyhk=|lGN2O8BcMHleUkD4yBtYRXSm1Yw= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwbTUJWJ3mytxrYPKrzRDIuBRd+/X/3T/QT2gudQfDN/mxkAMTg+uLoObXnUOtfhXD+lXP/s/GKXoPmsV/ausSz2YxBrQQXH7SwCpUq5GRXcl5s43JAJ1MbQq2EA5pa1CEBzUgd/Osu/WaVsKwfABV7QeKhblMfM0a5XcsfawqVbMJ0q/egYiSsWRVTU2iNMXILChJT6WUVoUiDENRnW98iy1qQgY0ge6hr7Gh6m23Fg6yfYDBQrqszbTfFYlqGe54bGlnxZvGp+Ybas02D29whAHwdNCSmDWXW0EvSpyt9WZUm0WOQt3t9RXpKeKLrWH4V/5BFYrONY1GsKuE783tw==
|1|UsEB5ylyIdmc4gs4TsYqE570DWY=|HAKqUTgFyTzodg8h6veV5jIa9GY= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC75TncmMQKEnnyw1S/uHcvs88d2M1NTMSUZyqdvFbx/uRB2rlrJiQHK8vyvN+fgRH5x8vde+vz/lAFgySV9RoS676cMuBIC8usF8REX2ghSXiSoGw35gd2ztGiDdU7FLUQYW+8FkR1soRjKZgyHqP/NCr4jBXjqDawDE33MA5LdmYy7fl1RN3oK4sY+LIoUWVv5x1aJdV86m0zbciavpU5szL++rnwcx+nWjDFFP4ntH1XyPGftyYpIAZwX+2Vl0+uMgv6sHazOx1E6vOIMx1UapCeLyWXzJ49P8K4iBZcNPH6h9aYllF4PIJ97Auh+fpFKBPfmHLq4iKCz4kKByy7 |1|UsEB5ylyIdmc4gs4TsYqE570DWY=|HAKqUTgFyTzodg8h6veV5jIa9GY= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC75TncmMQKEnnyw1S/uHcvs88d2M1NTMSUZyqdvFbx/uRB2rlrJiQHK8vyvN+fgRH5x8vde+vz/lAFgySV9RoS676cMuBIC8usF8REX2ghSXiSoGw35gd2ztGiDdU7FLUQYW+8FkR1soRjKZgyHqP/NCr4jBXjqDawDE33MA5LdmYy7fl1RN3oK4sY+LIoUWVv5x1aJdV86m0zbciavpU5szL++rnwcx+nWjDFFP4ntH1XyPGftyYpIAZwX+2Vl0+uMgv6sHazOx1E6vOIMx1UapCeLyWXzJ49P8K4iBZcNPH6h9aYllF4PIJ97Auh+fpFKBPfmHLq4iKCz4kKByy7
# ts-jumpbox.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u4
ts-jumpbox.systemoverlord.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKwbpYiRqlgLKbaUlt1k4ms14+vTW8LKequepWdqDUUx
# ts-jumpbox.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u4
ts-jumpbox.systemoverlord.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC2itf2fAUO5OB7BNAL9Js8pmxIwzLnOxRMexf5KGswUQRvaZwtw1CitJiyEcYWBt7zksd/Pupmp42ikPVoH7myQlWRbeEmJEIlMvkFF0pjAWj9kGKVLyFDbqXSkewKtXwbJHSo0l+mEOyq8NLlOwAA977BzNTn4z3KQEfYBQQEqISa8NuLpVOFvtQfvBlW+Xeh6+rIm54gdJVDWRimvZ5/FUMaRHPBdMFcXZW1GpraAHjHMeJXTIJs10qFy+5RwGTL5UlvssI+IPAIAW7o0goWmCnrlTjhvJ3Mnwq2lQhAuH/aDqVTptXwMni8tkvPFEC4LeoXG9pmb04Fd6bxY4RnvWuTmcvqOGAxJmZcqOYp1qWhyIF4TTB5l4h3J27sUtluEkTbIGtxTcPjFYLLC1lyIweoQSjWTmi5Z4wz1qfxIYZY1UXnyAjILvLAA5XAIpTgVfDx9KMAFdRrqaKN1MMFvfkTy7CZOfIkWhBwuOxMmtknsiJi8INZc+2CWUuI3Q8=
# ts-jumpbox.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u4
ts-jumpbox.systemoverlord.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFs4yUU1aYjy5kq0vr8PFEJUA5s90lYzFTXwHuL9JwtL/wi7tC3I1ifyQnzfZIT8ORMHNGdz/DjNyKkE/rfDhEc=
# ts-jumpbox.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u4
# ts-jumpbox.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u4
# omega.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u2
omega.systemoverlord.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQD7TIDPujGWOMkltfBUKoXOIX9W6KBbqT4qfANNivyjvYeS2joncfoCHTws3vTofHjfyzUSFpnjJSjbwoqTK38CsqSMx06KgpOiiz03+OVbtoBKiwY7smYXh2/vB53+EV4fnM1u/6AqAn0FYT/lUjaY6kBWDppW7PbFKRtO+wShMNfbaY1BTDyEEZRU3PCxR4UDXFO7fQLBiQb/XOyxsSXdRtP6BPrpqxUSq/hNchRo4AP08wtEY5iW9po1RMOFAMKPDND34CyWGbtfnpUCAk9jwKrKDRibRZgIe/xWNcXY9P9zuCSMByB3npo2lG2Em/usiO2awY1pcfrHrlfxJFnD+rzQ9LELwvSB8kPd5xlxZjqmNIvACGEYzR2zdbeOXy+G7biQ7cgELIFRF9aDKOe68sSss3SdS2suAXpqtNBE6l8T9u2jUD0po5EsDcNXPHCS8YLq4wyTpkeDAchX4xm8srycvPD9h4UAE9k+QqjkkbUQw/xpx0SL4pq8Xi6VuO0=
# omega.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u2
omega.systemoverlord.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBL9cVRkixwE7KL112abP+GosO9+MiVUZQqUdRh4ps5O733cJ8tvkqLVkJhEejIFX6BLlmh/l+j/mD4Z8dL/YqmU=
# omega.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u2
omega.systemoverlord.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMoxyWy+cXdpxh/KOhbvzB8Tq7NgWTHofOOpeVzuESe0
# omega.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u2
# omega.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u2
# xi.systemoverlord.com:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
# xi.systemoverlord.com:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
xi.systemoverlord.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCosFo3gGbGQ7PvHzVZ50umQNEILsqkHWnDi2FqHBCV/pQKUlZVuBO2HT0MiV3QkascJ58P4Jj1Ft/ILKvrU5/dDsW8xVs3vJlmHPrmovD93VwuarzlokmzxWPFOEPZIPcQcQcMCt6k4p/6Pb6hbmPGML2N7XGQHGVDFcflusx07wj56lP9xUtdOLcIo9u3rgw2puXqxUNRtx12Dfo9rjGiFFCXCrvFV5BG4utHKSyAOckJQ/oTzy++idM7jaPbnQ0qjH4GMHm2HN8bmWJdHjc6BeBEW4iQrUxNeisM/hKiICZ3kUmeEynx6IlgEXm0UT+AhxZL7BQo9X45pj5AvaU5
# xi.systemoverlord.com:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
xi.systemoverlord.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBN49oL4rzjwfz5F7cUuVhqe9vRzDAE16O5NQvslhpOx3VA7g8qjyK4SmhhRll+N7vS7OvUqswjEIOXFdK2DUGq8=
# xi.systemoverlord.com:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
xi.systemoverlord.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIg6N+lwA6feLnLDlm6Ssp45YjnaeCCQSBzeidmAb7FY
# xi.systemoverlord.com:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1
# chi.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u4
chi.systemoverlord.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7jSON+Pum/scQMwiBH0jI2fKfQ4q6YKBf/Q/uU7RiEzr3g5lRLA3RtFfWYlxSVqRdlQgeTvIRqG6VMQjtxm/UiLaNT82dVSgoSwJnODVWsKzWQNY1nkhGgd/Ue/XQrBi6UFB7QU7iiIHn8FmJDh05jLv4ymp3DuUM6W066cHqVMSslVhsioAJeZJdpFFK0WXbWs8PT83LT1LERP8CMWuaVlF4UxWwaxROA4WwWaUtiMm0e7T9AgCkHmmEWJemrJqkKUBU0BaqyIvF2bP4tNrZXM8EzT+2Dg25BWS6DzP/d7m8umrpQrYP7cbhK0jzNXw/niEjQ7f8ZiuguRGwWBKX0XjMPY36uiBE/bkGiyF2t27nSPyoA/I2CYtArAabVmiNTeK6qpgf1Xo+aBFuotS3+4Ql+9kfzO9ZL05xIBC2PzvL1pqWmTHI4GICLS2EdMks8LW5ZxvjMS0OdrVf1KaMgmr8TbJT+NIqs1SF3H5kmWUtMvQd4YJgU+o88/sO9LM=
# chi.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u4
chi.systemoverlord.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIo6eEuZ1F1GGnkJqkyUTj4oGZlcADbmdahSiwif6pWcx6uGdSemPjQmhFknPbzpzH8HIUtrg/NSBGAjwVINz5Q=
# chi.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u4
chi.systemoverlord.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINVUVuOLnuVRiUptQxn+HlUtgv4i5+DMK4uyN4voCB1R
# chi.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u4
# chi.systemoverlord.com:22 SSH-2.0-OpenSSH_10.0p2 Debian-7+deb13u4
# tau.systemoverlord.com:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u3
tau.systemoverlord.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMUffrd05Q6iyHj1vbvBzD+xWqR6c/YivTieWVim+b2wHEEYyh7eHXzldXZdLP3QOQHXWc68QwfSav5jsrVhsxk=
# tau.systemoverlord.com:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u3
tau.systemoverlord.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/vDSvxXQa20+5OjgQpzxMQZR3m80fsIzHNqfjjAGlVTfPuccMnfCXNgQc8mY8qQTMxbBU4ZlSjntjyIBhWoj5flrTpVjHJgAkntu1dhtDYOp8sd+9CsR/40SX/1l8d6fRzuPSZaVO+RpF9Ym/MrxYH8YprBswl4pzT3/DVCgq3DDNocLzmyjMCgQJXxYpKhlnRSxhLvPHeAi4p0/gHmYhtQe4r0DZ/QaU6a/4bU2shGQyKBUUJbRTrNYwAEukZk+U5AkoQ7N43THB1PtdC0PwmaD2yXHiKzR/6SfLWRBE6TqyQKB0R8+lWWIU5s0Nu512UUS78bchkTtU0mgTpQWP
# tau.systemoverlord.com:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u3
tau.systemoverlord.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9+GZcp2imEoxDKY3rxdwGARZ6o/vmPCqrRF9ghxhLa
# tau.systemoverlord.com:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u3
# tau.systemoverlord.com:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u3
# zeta.systemoverlord.com:22 SSH-2.0-OpenSSH_10.3p1 Debian-4
zeta.systemoverlord.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBOPOADAIuJ/khxquXi1/wHyJUp1LqmfLVuHnGoqYouZc7AKcwWDOd30p5bSbrgGMXQC6oflMUsL1VL8hyqZPhs=
# zeta.systemoverlord.com:22 SSH-2.0-OpenSSH_10.3p1 Debian-4
zeta.systemoverlord.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDWTvGafS9utruAmLpDdohEiEWSWVq3H6Mj1Z/hwnjVn67UncYDwLJjZem22r6qnW9h8hF9qpIG+XtU9Yk4iEvUk2H9S3gb7UOxwJ29lx2ckFp8V8Ml9t9gwrNpCVL+oiLm+iCmYMctksWbNXuiGRX22/qfeiM2zwyV3tEWbs/ePtVs5RX0EhbqPR5NHazy0NspE+lLsKeoGT5KsjyehStY69ER4iPKJzeiUxYfXj9wafniNiPZPV9jCDH4DIhkUWoOc1DF0cItVGLRnAWFoAEaWoIfC4ou33cuIfk810kf9uwSTgjVtGiGOC9Pemfc3RsFiUtlg4wpyAerBIvJlvrMAdPRhd1Pteg6QzWYbz0/3dGtyURjRg3uZQIiMre3zHHSKDQbdBL5C+9dM+d/PMdN+86GgwfymPHLoUsRpoY/1yxxqq8Zjc7D40amParpXHOkPzMLJy1F8d10QB52ZDx/7ivuPK55WaWiL3jcBLdim/I2te8EWwR0IgKGlkRYL88=
# zeta.systemoverlord.com:22 SSH-2.0-OpenSSH_10.3p1 Debian-4
zeta.systemoverlord.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLOty9tztaPoyNUY50daxN3l8rM5+Eg1vMfqefgHWLT
# zeta.systemoverlord.com:22 SSH-2.0-OpenSSH_10.3p1 Debian-4
# zeta.systemoverlord.com:22 SSH-2.0-OpenSSH_10.3p1 Debian-4