On an Omarchy laptop bootstrap left two of almost everything: VS Code from both pacman and the tarball (two menu entries, one shared ~/.config/Code profile), and kubectl/helm/k9s/kubectx/yq/jq/node/ansible in ~/.local/bin behind mise and pacman copies that always won on PATH. The zsh helpers (op*, grmb, secrets.env) also never reached the bash login shell. - lib/fetch.sh: add `shadowed`, true when another copy of a tool comes earlier on PATH than ~/.local/bin. Always false where zshrc puts ~/.local/bin first, so VM installs are unchanged. - bin/, node/, ansible/: skip tools that are shadowed. - vscode/: defer to any system `code`, and remove a tarball copy this module installed earlier. - bash/: new module; bash port of the zshrc helpers, sourced from ~/.bashrc via a marked block. No-ops without ~/.bashrc. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
2.6 KiB
Bash
Executable File
68 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
# ansible/install.sh — install Ansible into a userland virtualenv and expose
|
|
# its CLIs on PATH. Ansible is Python, not a single binary, so it can't live
|
|
# in bin/ alongside the downloaded release binaries.
|
|
#
|
|
# The venv lives at ~/.local/opt/ansible and its CLIs are symlinked into
|
|
# ~/.local/bin. Both are under $HOME, so they persist across Kasm redeploys;
|
|
# the venv is only rebuilt when missing. Building it needs python3 + venv,
|
|
# which may require a system package on a fresh box (the one place this
|
|
# module uses sudo, via pkg_install).
|
|
set -eu
|
|
|
|
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
|
|
REPO_ROOT="$(dirname -- "$SCRIPT_DIR")"
|
|
|
|
# shellcheck source=../lib/os-detect.sh
|
|
. "$REPO_ROOT/lib/os-detect.sh"
|
|
# shellcheck source=../lib/fetch.sh
|
|
. "$REPO_ROOT/lib/fetch.sh"
|
|
|
|
say() { printf '%s\n' "$*" >&2; }
|
|
|
|
VENV="$HOME/.local/opt/ansible"
|
|
BIN_DIR="$HOME/.local/bin"
|
|
ANSIBLE_CLIS="ansible ansible-playbook ansible-galaxy ansible-vault ansible-config ansible-doc ansible-inventory ansible-console ansible-pull"
|
|
|
|
# Another ansible (mise, pipx, a distro package) already wins on PATH, so this
|
|
# venv would never run -- see `shadowed` in lib/fetch.sh.
|
|
if _winner="$(shadowed ansible)"; then
|
|
say "ansible: $_winner comes first on PATH; skipping (a copy in $BIN_DIR would never run)."
|
|
exit 0
|
|
fi
|
|
|
|
# Verify it actually runs, not just that the file exists: a Kasm redeploy can
|
|
# wipe the system python3 the venv links to, leaving a present-but-broken
|
|
# venv that must be rebuilt.
|
|
if "$VENV/bin/ansible" --version >/dev/null 2>&1; then
|
|
say "ansible venv already present at $VENV."
|
|
else
|
|
rm -rf "$VENV"
|
|
command -v python3 >/dev/null 2>&1 || pkg_install python3
|
|
say "Creating ansible venv at $VENV..."
|
|
if ! python3 -m venv "$VENV" 2>/dev/null; then
|
|
# Debian splits venv/ensurepip into python3-venv; install it and retry.
|
|
say "python venv module missing; installing it..."
|
|
case "$(detect_pkg_family)" in
|
|
debian) pkg_install python3-venv python3-pip ;;
|
|
rhel) pkg_install python3 python3-pip ;;
|
|
*) say "install python3 venv support manually"; exit 1 ;;
|
|
esac
|
|
rm -rf "$VENV"
|
|
python3 -m venv "$VENV"
|
|
fi
|
|
"$VENV/bin/pip" install --quiet --upgrade pip
|
|
say "Installing ansible (this pulls in a lot of collections)..."
|
|
"$VENV/bin/pip" install --quiet ansible
|
|
say "Installed ansible into $VENV."
|
|
fi
|
|
|
|
# Symlink the CLIs into ~/.local/bin (which is on PATH via zsh/zshrc).
|
|
mkdir -p "$BIN_DIR"
|
|
for cli in $ANSIBLE_CLIS; do
|
|
if [ -x "$VENV/bin/$cli" ]; then
|
|
ln -sf "$VENV/bin/$cli" "$BIN_DIR/$cli"
|
|
fi
|
|
done
|
|
say "Linked ansible CLIs into $BIN_DIR."
|