#!/usr/bin/env bash # Shared helper functions for Fetch ML setup scripts (Ubuntu/Rocky) set -euo pipefail # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # Configuration defaults FETCH_ML_USER="fetchml" FETCH_ML_HOME="/opt/fetchml" SERVICE_DIR="/etc/systemd/system" LOG_DIR="/var/log/fetchml" DATA_DIR="/var/lib/fetchml" CONFIG_DIR="$FETCH_ML_HOME/configs" log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # Download file with checksum verification # Args: url, checksum, dest secure_download() { local url="$1" checksum="$2" dest="$3" curl -fsSL "$url" -o "$dest" echo "$checksum $dest" | sha256sum --check --status || { log_error "Checksum verification failed for $dest" rm -f "$dest" exit 1 } } cleanup_temp() { if [[ -n "${TMP_FILES:-}" ]]; then rm -f $TMP_FILES || true fi } trap cleanup_temp EXIT ensure_user() { if ! id "$FETCH_ML_USER" &>/dev/null; then useradd -m -d "$FETCH_ML_HOME" -s /bin/bash "$FETCH_ML_USER" fi usermod -aG podman "$FETCH_ML_USER" || true } create_directories() { mkdir -p "$FETCH_ML_HOME" "$LOG_DIR" "$DATA_DIR" "$FETCH_ML_HOME/bin" "$CONFIG_DIR" chown -R "$FETCH_ML_USER":"$FETCH_ML_USER" "$FETCH_ML_HOME" "$LOG_DIR" "$DATA_DIR" } setup_systemd_service() { local name="$1" exec="$2" cat > "$SERVICE_DIR/${name}.service" < /etc/logrotate.d/fetch_ml <<'EOF' /var/log/fetchml/*.log { daily missingok rotate 14 compress delaycompress notifempty create 0640 fetchml fetchml } EOF } hardening_steps() { # Increase file limits if ! grep -q fetchml /etc/security/limits.conf; then cat >> /etc/security/limits.conf <<'EOF' fetchml soft nofile 65536 fetchml hard nofile 65536 EOF fi # Enable unattended security upgrades if available if command -v apt-get &>/dev/null; then apt-get install -y unattended-upgrades >/dev/null || true elif command -v dnf &>/dev/null; then dnf install -y dnf-automatic >/dev/null || true fi } selinux_guidance() { if command -v getenforce &>/dev/null; then local mode=$(getenforce) log_info "SELinux mode: $mode" if [[ "$mode" == "Enforcing" ]]; then log_info "Ensure systemd units and directories have proper contexts. Example:" echo " semanage fcontext -a -t bin_t '$FETCH_ML_HOME/bin(/.*)?'" echo " restorecon -Rv $FETCH_ML_HOME/bin" fi fi }