#!/usr/bin/env bash
# Privileged OS package helper for Limristem eMail.
#
# Replaces the former passwordless sudo rule on /usr/bin/apt-get and /usr/bin/apt.
# That rule was a full root escalation for the service account: apt accepts
# configuration options that run arbitrary commands as root, e.g.
#   sudo -n apt-get -o APT::Update::Pre-Invoke::="/bin/sh -c id" update
# Here the operation is chosen from a fixed set and no caller-supplied argument
# ever reaches apt.
set -euo pipefail

SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=/dev/null
source "$SCRIPT_DIR/libenv.sh"

export DEBIAN_FRONTEND=noninteractive
export PATH=/usr/sbin:/usr/bin:/sbin:/bin

APT_OPTS=(
  -y
  -o DPkg::Lock::Timeout=120
  -o Dpkg::Options::=--force-confdef
  -o Dpkg::Options::=--force-confold
)

usage() {
  cat <<'EOF'
Usage:
  manage-packages.sh update         Refresh the APT package index
  manage-packages.sh full-upgrade   Apply a full upgrade of installed packages
EOF
}

require_root() {
  if [[ $EUID -ne 0 ]]; then
    echo "Run as root." >&2
    exit 1
  fi
}

cmd=${1:-}
# Refuse every extra argument: nothing from the caller is forwarded to apt.
if [[ $# -gt 1 ]]; then
  echo "manage-packages.sh accepts no extra arguments." >&2
  exit 2
fi

case "$cmd" in
  update | full-upgrade)
    require_root
    # dpkg writes across /usr and /etc, so this must escape the app's read-only
    # mount namespace when invoked from the panel/API (see libenv.sh).
    limristem_mail_escape_write_namespace LIMRISTEM_MAIL_PACKAGES_WORKER limristem-mail-packages "$cmd"
    exec /usr/bin/apt-get "${APT_OPTS[@]}" "$cmd"
    ;;
  -h | --help | help | "")
    usage
    exit 0
    ;;
  *)
    echo "Unknown command: $cmd" >&2
    usage >&2
    exit 2
    ;;
esac
