155 lines
3.9 KiB
Bash
155 lines
3.9 KiB
Bash
#!/bin/bash
|
|
|
|
# Shared distro helpers for install scripts.
|
|
|
|
SCRIPT_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="${REPO_ROOT:-$(dirname "$(dirname "$SCRIPT_LIB_DIR")")}"
|
|
REBOOT_MARKER="${REBOOT_MARKER:-$REPO_ROOT/.setup-reboot-required}"
|
|
|
|
if [ -f /etc/os-release ]; then
|
|
. /etc/os-release
|
|
OS="${ID}"
|
|
OS_LIKE="${ID_LIKE:-}"
|
|
elif [ "$(uname -s)" = "Darwin" ]; then
|
|
OS="macos"
|
|
OS_LIKE="darwin"
|
|
else
|
|
echo "Unable to detect operating system: /etc/os-release not found and host is not macOS."
|
|
return 1 2>/dev/null || exit 1
|
|
fi
|
|
|
|
is_arch_family() {
|
|
[[ "$OS" == "arch" || "$OS" == "manjaro" || " $OS_LIKE " == *" arch "* ]]
|
|
}
|
|
|
|
is_debian_family() {
|
|
[[ "$OS" == "ubuntu" || "$OS" == "debian" || " $OS_LIKE " == *" debian "* ]]
|
|
}
|
|
|
|
is_fedora_family() {
|
|
[[ "$OS" == "fedora" || "$OS" == "bazzite" || " $OS_LIKE " == *" fedora "* || " $OS_LIKE " == *" rhel "* ]]
|
|
}
|
|
|
|
is_macos() {
|
|
[[ "$OS" == "macos" ]]
|
|
}
|
|
|
|
is_atomic_fedora() {
|
|
is_fedora_family && command -v rpm-ostree >/dev/null 2>&1 && [ -f /run/ostree-booted ]
|
|
}
|
|
|
|
mark_reboot_required() {
|
|
touch "$REBOOT_MARKER"
|
|
echo ""
|
|
echo " REBOOT REQUIRED: Fedora atomic package layering finished."
|
|
echo " Please reboot, then rerun the same make target."
|
|
echo ""
|
|
}
|
|
|
|
get_atomic_requested_packages() {
|
|
local python_bin=""
|
|
local candidate
|
|
|
|
for candidate in python3 python /usr/libexec/platform-python; do
|
|
if command -v "$candidate" >/dev/null 2>&1; then
|
|
python_bin="$candidate"
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ -z "$python_bin" ]; then
|
|
return 0
|
|
fi
|
|
|
|
rpm-ostree status --json 2>/dev/null | "$python_bin" -c '
|
|
import json, sys
|
|
|
|
try:
|
|
data = json.load(sys.stdin)
|
|
except Exception:
|
|
raise SystemExit(0)
|
|
|
|
for deployment in data.get("deployments", []):
|
|
if deployment.get("booted"):
|
|
for key in ("requested-packages", "requested-local-packages"):
|
|
for package in deployment.get(key, []):
|
|
if package:
|
|
print(package)
|
|
break
|
|
'
|
|
}
|
|
|
|
install_packages() {
|
|
local packages=("$@")
|
|
|
|
if [ ${#packages[@]} -eq 0 ]; then
|
|
return 0
|
|
fi
|
|
|
|
if is_arch_family; then
|
|
sudo pacman -S --noconfirm --needed "${packages[@]}"
|
|
return 0
|
|
fi
|
|
|
|
if is_debian_family; then
|
|
sudo DEBIAN_FRONTEND=noninteractive apt-get update
|
|
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}"
|
|
return 0
|
|
fi
|
|
|
|
if is_fedora_family; then
|
|
if is_atomic_fedora; then
|
|
local requested_pkg
|
|
local missing_packages=()
|
|
declare -A requested_packages=()
|
|
local pkg
|
|
|
|
while IFS= read -r requested_pkg; do
|
|
[ -n "$requested_pkg" ] && requested_packages["$requested_pkg"]=1
|
|
done < <(get_atomic_requested_packages)
|
|
|
|
for pkg in "${packages[@]}"; do
|
|
if rpm -q "$pkg" >/dev/null 2>&1; then
|
|
continue
|
|
fi
|
|
|
|
if [ -n "${requested_packages[$pkg]:-}" ]; then
|
|
continue
|
|
fi
|
|
|
|
missing_packages+=("$pkg")
|
|
done
|
|
|
|
if [ ${#missing_packages[@]} -eq 0 ]; then
|
|
return 0
|
|
fi
|
|
|
|
sudo rpm-ostree install "${missing_packages[@]}"
|
|
mark_reboot_required
|
|
return 42
|
|
fi
|
|
|
|
sudo dnf install -y "${packages[@]}"
|
|
return 0
|
|
fi
|
|
|
|
if is_macos; then
|
|
if ! command -v brew >/dev/null 2>&1; then
|
|
echo "Homebrew is required on macOS. Install it from https://brew.sh first."
|
|
return 1
|
|
fi
|
|
|
|
local pkg
|
|
for pkg in "${packages[@]}"; do
|
|
if brew list --formula "$pkg" >/dev/null 2>&1; then
|
|
continue
|
|
fi
|
|
brew install "$pkg"
|
|
done
|
|
return 0
|
|
fi
|
|
|
|
echo "Unsupported OS: $OS"
|
|
return 1
|
|
}
|