135 lines
3.9 KiB
Bash
135 lines
3.9 KiB
Bash
#!/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
|