Files
Simone 2241d6af7f feat(setup): add ci shell alias helper + install it from setup-host
scripts/install-ci-alias.sh installs `ci` (runs the orchestrator as ci-runner
via the prod venv) and `ci-me` (current user). Idempotent, marker-bounded;
supports --system (/etc/profile.d), --uninstall. setup-host-linux.sh gains a
step [7/7] that installs it system-wide, passing CI_PROD_PYTHON/CI_RUN_USER.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 00:11:36 +02:00

106 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# install-ci-alias.sh — install a `ci` shell helper that runs the CI
# orchestrator as the ci-runner service user against the production venv.
#
# After install: ci validate host == sudo -u ci-runner \
# /opt/ci/venv/bin/python -m ci_orchestrator validate host
#
# Usage:
# ./scripts/install-ci-alias.sh # install into the current user's
# # ~/.bashrc and ~/.zshrc (if present)
# ./scripts/install-ci-alias.sh --system # install system-wide via
# # /etc/profile.d/ci-alias.sh (needs sudo)
# ./scripts/install-ci-alias.sh --uninstall # remove the installed block
#
# Idempotent: re-running updates the block in place instead of duplicating it.
set -euo pipefail
PROD_PY="${CI_PROD_PYTHON:-/opt/ci/venv/bin/python}"
RUN_USER="${CI_RUN_USER:-ci-runner}"
MARK_BEGIN="# >>> ci-orchestrator alias >>>"
MARK_END="# <<< ci-orchestrator alias <<<"
log() { printf '[install-ci-alias] %s\n' "$*"; }
die() { printf '[install-ci-alias] ERROR: %s\n' "$*" >&2; exit 1; }
block() {
cat <<EOF
${MARK_BEGIN}
# Run the CI orchestrator as the ${RUN_USER} service user (production venv).
ci() { sudo -u ${RUN_USER} ${PROD_PY} -m ci_orchestrator "\$@"; }
# Same, but as the current user (no sudo) — handy for read-only commands.
ci-me() { ${PROD_PY} -m ci_orchestrator "\$@"; }
${MARK_END}
EOF
}
strip_block() {
# Remove an existing marked block from $1 (in place). No-op if absent.
local file="$1"
[ -f "$file" ] || return 0
if grep -qF "$MARK_BEGIN" "$file"; then
# Delete everything between the markers, inclusive.
sed -i "/$(printf '%s' "$MARK_BEGIN" | sed 's/[].[*^$/]/\\&/g')/,/$(printf '%s' "$MARK_END" | sed 's/[].[*^$/]/\\&/g')/d" "$file"
# Drop a possible trailing blank line left behind.
sed -i -e :a -e '/^\n*$/{$d;N;ba}' "$file" 2>/dev/null || true
fi
}
install_into() {
local file="$1"
strip_block "$file"
{ printf '\n'; block; } >> "$file"
log "updated $file"
}
uninstall_from() {
local file="$1"
if [ -f "$file" ] && grep -qF "$MARK_BEGIN" "$file"; then
strip_block "$file"
log "removed block from $file"
fi
}
main() {
local mode="user" action="install"
case "${1:-}" in
--system) mode="system" ;;
--uninstall) action="uninstall" ;;
"" ) ;;
* ) die "unknown argument: $1 (use --system or --uninstall)" ;;
esac
# Sanity: warn (don't fail) if the production venv is missing.
[ -x "$PROD_PY" ] || log "WARNING: $PROD_PY not found — alias installed anyway; fix the venv before use."
if [ "$mode" = "system" ]; then
local target="/etc/profile.d/ci-alias.sh"
if [ "$action" = "uninstall" ]; then
sudo rm -f "$target" && log "removed $target"
else
block | sudo tee "$target" >/dev/null
sudo chmod 0644 "$target"
log "installed $target (applies to all login shells)"
fi
else
local files=()
[ -f "$HOME/.bashrc" ] && files+=("$HOME/.bashrc")
[ -f "$HOME/.zshrc" ] && files+=("$HOME/.zshrc")
# If neither exists, create ~/.bashrc so the alias lands somewhere.
[ ${#files[@]} -eq 0 ] && files+=("$HOME/.bashrc")
for f in "${files[@]}"; do
if [ "$action" = "uninstall" ]; then uninstall_from "$f"; else install_into "$f"; fi
done
fi
if [ "$action" = "install" ]; then
log "done. Open a new shell, or run: source ~/.bashrc"
log "try: ci validate host"
else
log "done. Open a new shell to drop the alias."
fi
}
main "$@"