#!/usr/bin/env bash set -e PREFIX="dev_pkg_" STATE_FILE="/var/lib/ansipa-packages/installed.list" mkdir -p "$(dirname "$STATE_FILE")" # Detect distro if [ -f /etc/os-release ]; then . /etc/os-release DISTRO=$ID else DISTRO="unknown" fi # ----------------------------- # Package install function # ----------------------------- install_pkg() { PKG="$1" case "$DISTRO" in arch) pacman -Sy --noconfirm "$PKG" 2>/dev/null || true ;; debian|ubuntu) apt update -y && apt install -y "$PKG" 2>/dev/null || true ;; rhel|centos|rocky|almalinux) yum install -y "$PKG" 2>/dev/null || dnf install -y "$PKG" 2>/dev/null || true ;; fedora) dnf install -y "$PKG" 2>/dev/null || true ;; opensuse*|sles) zypper install -y "$PKG" 2>/dev/null || true ;; esac } # ----------------------------- # Package uninstall function # ----------------------------- remove_pkg() { PKG="$1" case "$DISTRO" in arch) pacman -Rns --noconfirm "$PKG" 2>/dev/null || true ;; debian|ubuntu) apt remove -y "$PKG" 2>/dev/null || true ;; rhel|centos|rocky|almalinux) yum remove -y "$PKG" 2>/dev/null || dnf remove -y "$PKG" 2>/dev/null || true ;; fedora) dnf remove -y "$PKG" 2>/dev/null || true ;; opensuse*|sles) zypper remove -y "$PKG" 2>/dev/null || true ;; esac } # ----------------------------- # Get FreeIPA install groups # ----------------------------- IPA_GROUPS=$(ipa group-find --pkey-only | awk '/Group name:/{print $NF}' | grep "^$PREFIX" || true) # Extract package names from groups DESIRED_PKGS=() for G in $IPA_GROUPS; do PKG="${G#$PREFIX}" DESIRED_PKGS+=("$PKG") done # ----------------------------- # Get currently installed packages # ----------------------------- case "$DISTRO" in arch) INSTALLED_PKGS=$(pacman -Qq) ;; debian|ubuntu) INSTALLED_PKGS=$(dpkg -l | awk '/^ii/ {print $2}') ;; rhel|centos|rocky|almalinux|fedora) INSTALLED_PKGS=$(rpm -qa --qf "%{NAME}\n") ;; opensuse*|sles) INSTALLED_PKGS=$(rpm -qa --qf "%{NAME}\n") ;; *) INSTALLED_PKGS="" ;; esac # ----------------------------- # Install missing packages and record them # ----------------------------- [[ -f "$STATE_FILE" ]] || touch "$STATE_FILE" for PKG in "${DESIRED_PKGS[@]}"; do if ! echo "$INSTALLED_PKGS" | grep -qx "$PKG"; then echo "[INFO] Installing package: $PKG" install_pkg "$PKG" fi # Record that ansipa manages this package grep -qxF "$PKG" "$STATE_FILE" || echo "$PKG" >> "$STATE_FILE" done # ----------------------------- # Remove packages no longer desired # Only remove packages previously installed by ansipa (tracked in state file). # ----------------------------- while IFS= read -r PKG; do [[ -z "$PKG" ]] && continue # Still desired? Leave it alone. if printf '%s\n' "${DESIRED_PKGS[@]+"${DESIRED_PKGS[@]}"}" | grep -qxF "$PKG"; then continue fi echo "[INFO] Removing package no longer required by any IPA group: $PKG" remove_pkg "$PKG" # Remove from state file grep -vxF "$PKG" "$STATE_FILE" > "${STATE_FILE}.tmp" && mv "${STATE_FILE}.tmp" "$STATE_FILE" done < "$STATE_FILE" # Persist current desired list (union of what's already tracked + newly added) if [[ ${#DESIRED_PKGS[@]} -gt 0 ]]; then printf '%s\n' "${DESIRED_PKGS[@]}" | sort -u > "${STATE_FILE}.tmp" # Merge: keep previously-managed packages that are still desired sort -u "$STATE_FILE" "${STATE_FILE}.tmp" > "${STATE_FILE}.merged" comm -12 "${STATE_FILE}.merged" "${STATE_FILE}.tmp" > "$STATE_FILE" rm -f "${STATE_FILE}.tmp" "${STATE_FILE}.merged" fi