Newer
Older
openstack-caracal-dc-dc / scripts / prereqs / install-opentofu.sh
#!/usr/bin/env bash
# scripts/prereqs/install-opentofu.sh [--check|--dry-run]
#
# Prereq installer: OpenTofu `tofu` (>= 1.6.0) -- the IaC runtime every dc-dc
# Stage 1-6 runbook and scripts/opentofu-validate.sh depend on. Idempotent: if a
# new-enough tofu is already on PATH it does nothing. Debian/Ubuntu via the
# official installer's deb method, which lands /usr/bin/tofu (the `tofu` command
# name our tooling expects; the `opentofu` snap may not expose a plain `tofu`).
#
#   --check     report present/absent + version only; exit 0 if OK, 1 if missing/old
#   --dry-run   print what it would do; mutate nothing
#   (no flag)   install if absent/too-old (uses sudo for the deb install)
#
# Registry reach (registry.opentofu.org) is needed later by `tofu init`, not here.
# Exit: 0 ok/installed | 1 check-failed | 2 bad args | 3 unsupported OS | 4 install failed.
# ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
. "$HERE/lib-prereq.sh"
MIN_VER="1.6.0"

pq_parse_mode "$@"; rc=$?
[ "$rc" = "10" ] && { echo "usage: bash scripts/prereqs/install-opentofu.sh [--check|--dry-run]"; exit 0; }
[ "$rc" = "0" ] || exit "$rc"

ver_ge()  { [ "$(printf '%s\n%s\n' "$2" "$1" | sort -V | head -n1)" = "$2" ]; }  # $1 >= $2 ?
cur_ver() { tofu version 2>/dev/null | head -n1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1; }

if pq_have tofu; then
  v="$(cur_ver)"
  if [ -n "$v" ] && ver_ge "$v" "$MIN_VER"; then
    echo "OK: tofu $v present (>= $MIN_VER)"; exit 0
  fi
  echo "PRESENT-BUT-OLD: tofu ${v:-unknown} < $MIN_VER"
else
  echo "ABSENT: tofu not on PATH"
fi
[ "$PQ_CHECK" = "1" ] && exit 1

pq_require_apt tofu || exit 3
tmp="$(mktemp -d)"; trap 'rm -rf "$tmp"' EXIT
inst="$tmp/install-opentofu.sh"
pq_run "download the official OpenTofu installer" -- \
  curl -fsSL https://get.opentofu.org/install-opentofu.sh -o "$inst" \
  || { echo "FAIL: could not download installer (registry/internet reach?)" >&2; exit 4; }
pq_run "run installer (deb method; needs sudo)" -- \
  sudo bash "$inst" --install-method deb \
  || { echo "FAIL: installer exited non-zero" >&2; exit 4; }

[ "$PQ_DRYRUN" = "1" ] && { echo "  (dry-run: no changes made)"; exit 0; }
v="$(cur_ver)"
if pq_have tofu && [ -n "$v" ] && ver_ge "$v" "$MIN_VER"; then
  echo "INSTALLED: tofu $v"; exit 0
fi
echo "FAIL: post-install check did not find tofu >= $MIN_VER on PATH" >&2; exit 4