Files
dotfiles/ansible/install.sh
T
noconnorandClaude Opus 5.5 9cb18a795d Coexist with a desktop that already manages its tools (Omarchy)
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>
2026-10-04 23:44:18 -04:00

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."