Fix: Add tar.gz fallback for unsupported systems

- The script has been updated to include a fallback mechanism for systems that do not have `dpkg` or `rpm` package managers. This ensures that the agent can be installed on a wider range of Linux distributions, such as Arch Linux, by automatically using the `tar.gz` package when native package managers are not detected.
This commit is contained in:
Tola Leng
2025-07-29 20:54:20 +07:00
parent cad092bc6b
commit ff4938533c
+330 -37
View File
@@ -1,4 +1,3 @@
#!/bin/bash #!/bin/bash
# CheckCle Server Monitoring Agent - One-Click Installation Script # CheckCle Server Monitoring Agent - One-Click Installation Script
@@ -44,7 +43,7 @@ check_root() {
fi fi
} }
# Detect system architecture and package format # Detect system architecture and package format with fallback
detect_system() { detect_system() {
log_info "Detecting system architecture and package format..." log_info "Detecting system architecture and package format..."
@@ -64,28 +63,89 @@ detect_system() {
;; ;;
esac esac
# Detect package format preference # Detect OS and preferred package format
if command -v dpkg >/dev/null 2>&1; then PREFERRED_FORMAT=""
PACKAGE_FORMAT="deb" PREFERRED_MANAGER=""
PACKAGE_MANAGER="dpkg"
elif command -v rpm >/dev/null 2>&1; then if [[ -f /etc/os-release ]]; then
PACKAGE_FORMAT="rpm" OS_ID=$(grep "^ID=" /etc/os-release | cut -d'=' -f2 | tr -d '"')
if command -v yum >/dev/null 2>&1; then OS_LIKE=$(grep "^ID_LIKE=" /etc/os-release 2>/dev/null | cut -d'=' -f2 | tr -d '"' || echo "")
PACKAGE_MANAGER="yum"
elif command -v dnf >/dev/null 2>&1; then log_info "Detected OS: $OS_ID"
PACKAGE_MANAGER="dnf" [[ -n "$OS_LIKE" ]] && log_info "OS family: $OS_LIKE"
else
PACKAGE_MANAGER="rpm" # Determine preferred package format based on OS
fi case "$OS_ID" in
else debian|ubuntu|linuxmint|elementary|pop)
log_error "No supported package manager found (dpkg or rpm required)" PREFERRED_FORMAT="deb"
log_info "This script supports Debian/Ubuntu (.deb) and RHEL/CentOS/Fedora (.rpm) systems" PREFERRED_MANAGER="dpkg"
exit 1 ;;
rhel|centos|fedora|rocky|almalinux|oracle|amazonlinux)
PREFERRED_FORMAT="rpm"
if command -v dnf >/dev/null 2>&1; then
PREFERRED_MANAGER="dnf"
elif command -v yum >/dev/null 2>&1; then
PREFERRED_MANAGER="yum"
else
PREFERRED_MANAGER="rpm"
fi
;;
arch|manjaro|artix|endeavouros)
# Arch-based systems - use tar.gz fallback
log_info "Arch-based system detected, using tar.gz format"
PREFERRED_FORMAT="tar.gz"
PREFERRED_MANAGER="tar"
;;
*)
# Check OS_LIKE for family detection
if [[ "$OS_LIKE" == *"debian"* ]] || [[ "$OS_LIKE" == *"ubuntu"* ]]; then
PREFERRED_FORMAT="deb"
PREFERRED_MANAGER="dpkg"
elif [[ "$OS_LIKE" == *"rhel"* ]] || [[ "$OS_LIKE" == *"fedora"* ]]; then
PREFERRED_FORMAT="rpm"
if command -v dnf >/dev/null 2>&1; then
PREFERRED_MANAGER="dnf"
elif command -v yum >/dev/null 2>&1; then
PREFERRED_MANAGER="yum"
else
PREFERRED_MANAGER="rpm"
fi
elif [[ "$OS_LIKE" == *"arch"* ]]; then
PREFERRED_FORMAT="tar.gz"
PREFERRED_MANAGER="tar"
fi
;;
esac
fi fi
# Construct package filename and URL # If no preferred format detected, check available package managers
PACKAGE_FILENAME="monitoring-agent_1.0.0_${PACKAGE_ARCH}.${PACKAGE_FORMAT}" if [[ -z "$PREFERRED_FORMAT" ]]; then
PACKAGE_URL="${GITHUB_BASE_URL}/${PACKAGE_FILENAME}" if command -v dpkg >/dev/null 2>&1; then
PREFERRED_FORMAT="deb"
PREFERRED_MANAGER="dpkg"
elif command -v rpm >/dev/null 2>&1; then
PREFERRED_FORMAT="rpm"
if command -v dnf >/dev/null 2>&1; then
PREFERRED_MANAGER="dnf"
elif command -v yum >/dev/null 2>&1; then
PREFERRED_MANAGER="yum"
else
PREFERRED_MANAGER="rpm"
fi
else
# Fallback to tar.gz for unsupported systems
log_info "No native package manager found, using tar.gz fallback"
PREFERRED_FORMAT="tar.gz"
PREFERRED_MANAGER="tar"
fi
fi
# Set initial package format and manager
PACKAGE_FORMAT="$PREFERRED_FORMAT"
PACKAGE_MANAGER="$PREFERRED_MANAGER"
# Construct initial package filename and URL
construct_package_url
log_success "System detection complete:" log_success "System detection complete:"
log_info " Architecture: $ARCH -> $PACKAGE_ARCH" log_info " Architecture: $ARCH -> $PACKAGE_ARCH"
@@ -94,6 +154,16 @@ detect_system() {
log_info " Package URL: $PACKAGE_URL" log_info " Package URL: $PACKAGE_URL"
} }
# Construct package URL based on current format
construct_package_url() {
if [[ "$PACKAGE_FORMAT" == "tar.gz" ]]; then
PACKAGE_FILENAME="monitoring-agent_1.0.0_${PACKAGE_ARCH}.tar.gz"
else
PACKAGE_FILENAME="monitoring-agent_1.0.0_${PACKAGE_ARCH}.${PACKAGE_FORMAT}"
fi
PACKAGE_URL="${GITHUB_BASE_URL}/${PACKAGE_FILENAME}"
}
# Validate required environment variables - check both current and sudo environments # Validate required environment variables - check both current and sudo environments
validate_environment() { validate_environment() {
# Check if SERVER_TOKEN is available in current environment or passed as argument # Check if SERVER_TOKEN is available in current environment or passed as argument
@@ -116,7 +186,7 @@ validate_environment() {
[[ -n "$AGENT_ID" ]] && log_info "AGENT_ID: $AGENT_ID" [[ -n "$AGENT_ID" ]] && log_info "AGENT_ID: $AGENT_ID"
} }
# Download package based on detected system # Download package with fallback to tar.gz
download_package() { download_package() {
local temp_dir="/tmp/monitoring-agent-install" local temp_dir="/tmp/monitoring-agent-install"
mkdir -p "$temp_dir" mkdir -p "$temp_dir"
@@ -124,17 +194,211 @@ download_package() {
log_info "Downloading monitoring agent package..." log_info "Downloading monitoring agent package..."
log_info "URL: $PACKAGE_URL" log_info "URL: $PACKAGE_URL"
if curl -L -f -o "$temp_dir/$PACKAGE_FILENAME" "$PACKAGE_URL"; then # Try to download the preferred package format first
DOWNLOADED_PACKAGE="$temp_dir/$PACKAGE_FILENAME" if curl -L -f -s -o "$temp_dir/$PACKAGE_FILENAME" "$PACKAGE_URL" 2>/dev/null; then
log_success "Package downloaded successfully: $PACKAGE_FILENAME" # Verify the file was actually downloaded and has content
if [[ -s "$temp_dir/$PACKAGE_FILENAME" ]]; then
DOWNLOADED_PACKAGE="$temp_dir/$PACKAGE_FILENAME"
log_success "Package downloaded successfully: $PACKAGE_FILENAME"
return 0
else
log_warning "Downloaded file is empty, trying fallback..."
rm -f "$temp_dir/$PACKAGE_FILENAME"
fi
else else
log_error "Failed to download package from: $PACKAGE_URL" log_warning "Failed to download preferred package format: $PACKAGE_FORMAT"
log_info "Please check:" fi
log_info " 1. Internet connectivity"
log_info " 2. Package availability for your architecture ($PACKAGE_ARCH)" # If preferred format failed and it's not tar.gz, try tar.gz fallback
log_info " 3. GitHub repository access" if [[ "$PACKAGE_FORMAT" != "tar.gz" ]]; then
log_warning "Native package ($PACKAGE_FORMAT) not available, trying tar.gz fallback..."
# Switch to tar.gz format
PACKAGE_FORMAT="tar.gz"
PACKAGE_MANAGER="tar"
construct_package_url
log_info "Fallback URL: $PACKAGE_URL"
if curl -L -f -s -o "$temp_dir/$PACKAGE_FILENAME" "$PACKAGE_URL" 2>/dev/null; then
# Verify the file was actually downloaded and has content
if [[ -s "$temp_dir/$PACKAGE_FILENAME" ]]; then
DOWNLOADED_PACKAGE="$temp_dir/$PACKAGE_FILENAME"
log_success "Fallback package downloaded successfully: $PACKAGE_FILENAME"
return 0
else
log_error "Downloaded fallback file is empty"
rm -f "$temp_dir/$PACKAGE_FILENAME"
fi
else
log_error "Failed to download tar.gz fallback"
fi
fi
# Both attempts failed
log_error "Failed to download package from: $PACKAGE_URL"
log_info "Please check:"
log_info " 1. Internet connectivity"
log_info " 2. Package availability for your architecture ($PACKAGE_ARCH)"
log_info " 3. GitHub repository access"
exit 1
}
# Install tar.gz package
install_tar_package() {
log_info "Installing monitoring agent from tar.gz package..."
local temp_extract_dir="/tmp/monitoring-agent-extract"
mkdir -p "$temp_extract_dir"
# Extract tar.gz package
if tar -xzf "$DOWNLOADED_PACKAGE" -C "$temp_extract_dir"; then
log_success "Package extracted successfully"
else
log_error "Failed to extract tar.gz package"
exit 1 exit 1
fi fi
# Install files to their proper locations
log_info "Installing files to system directories..."
# Create necessary directories
mkdir -p /usr/bin
mkdir -p /etc/monitoring-agent
mkdir -p /var/lib/monitoring-agent
mkdir -p /var/log/monitoring-agent
# Detect systemd service directory based on OS
if [[ -d /lib/systemd/system ]]; then
SYSTEMD_DIR="/lib/systemd/system"
elif [[ -d /usr/lib/systemd/system ]]; then
SYSTEMD_DIR="/usr/lib/systemd/system"
else
SYSTEMD_DIR="/etc/systemd/system"
fi
mkdir -p "$SYSTEMD_DIR"
# Copy files from extracted package
if [[ -f "$temp_extract_dir/usr/bin/monitoring-agent" ]]; then
cp "$temp_extract_dir/usr/bin/monitoring-agent" /usr/bin/
chmod +x /usr/bin/monitoring-agent
log_success "Binary installed to /usr/bin/monitoring-agent"
else
log_error "Binary not found in package"
exit 1
fi
if [[ -f "$temp_extract_dir/etc/monitoring-agent/monitoring-agent.env" ]]; then
cp "$temp_extract_dir/etc/monitoring-agent/monitoring-agent.env" /etc/monitoring-agent/
log_success "Configuration template installed"
fi
# Create monitoring-agent user and group if they don't exist
if ! getent group monitoring-agent >/dev/null 2>&1; then
groupadd --system monitoring-agent
log_success "Created monitoring-agent group"
else
log_info "monitoring-agent group already exists"
fi
if ! getent passwd monitoring-agent >/dev/null 2>&1; then
useradd --system --gid monitoring-agent --home-dir /var/lib/monitoring-agent --shell /bin/false --comment "Monitoring Agent" monitoring-agent
log_success "Created monitoring-agent user"
else
log_info "monitoring-agent user already exists"
fi
# Set proper ownership and permissions
chown -R monitoring-agent:monitoring-agent /var/lib/monitoring-agent
chown -R monitoring-agent:monitoring-agent /var/log/monitoring-agent
chown -R monitoring-agent:monitoring-agent /etc/monitoring-agent
chmod 755 /var/lib/monitoring-agent
chmod 755 /var/log/monitoring-agent
chmod 755 /etc/monitoring-agent
# Check if Docker is installed and configure service file accordingly
DOCKER_AVAILABLE=false
if command -v docker >/dev/null 2>&1 && getent group docker >/dev/null 2>&1; then
DOCKER_AVAILABLE=true
# Add monitoring-agent user to docker group if Docker is available
usermod -a -G docker monitoring-agent
log_info "Docker detected, added monitoring-agent user to docker group"
else
log_info "Docker not detected, skipping Docker group configuration"
fi
# Create the systemd service file with proper Docker configuration
create_systemd_service_file "$SYSTEMD_DIR" "$DOCKER_AVAILABLE"
# Clean up extraction directory
rm -rf "$temp_extract_dir"
log_success "Tar.gz package installation completed"
}
# Create systemd service file with Docker configuration
create_systemd_service_file() {
local systemd_dir="$1"
local docker_available="$2"
log_info "Creating systemd service file at $systemd_dir/monitoring-agent.service"
cat > "$systemd_dir/monitoring-agent.service" << 'EOF'
[Unit]
Description=CheckCle Server Monitoring Agent
Documentation=https://github.com/operacle/checkcle-server-agent
After=network.target
Wants=network.target
[Service]
Type=simple
User=monitoring-agent
Group=monitoring-agent
EOF
# Add Docker group only if Docker is available
if [[ "$docker_available" == "true" ]]; then
echo "# Add docker group for Docker monitoring access" >> "$systemd_dir/monitoring-agent.service"
echo "SupplementaryGroups=docker" >> "$systemd_dir/monitoring-agent.service"
else
echo "# Docker not available - skipping Docker group configuration" >> "$systemd_dir/monitoring-agent.service"
fi
# Continue with the rest of the service configuration
cat >> "$systemd_dir/monitoring-agent.service" << 'EOF'
ExecStart=/usr/bin/monitoring-agent
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
# Security settings
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ProtectKernelTunables=yes
ProtectControlGroups=yes
RestrictSUIDSGID=yes
RemoveIPC=yes
RestrictRealtime=yes
# Allow access to system information and configuration
ReadWritePaths=/var/log/monitoring-agent
ReadOnlyPaths=/proc /sys /etc/monitoring-agent
# Network access
PrivateNetwork=no
# Environment
EnvironmentFile=/etc/monitoring-agent/monitoring-agent.env
WorkingDirectory=/var/lib/monitoring-agent
[Install]
WantedBy=multi-user.target
EOF
log_success "Created systemd service file with Docker support: $docker_available"
} }
# Install package based on detected package manager # Install package based on detected package manager
@@ -185,6 +449,10 @@ install_package() {
fi fi
;; ;;
tar)
install_tar_package
;;
*) *)
log_error "Unsupported package manager: $PACKAGE_MANAGER" log_error "Unsupported package manager: $PACKAGE_MANAGER"
exit 1 exit 1
@@ -232,7 +500,7 @@ configure_agent() {
log_info "Final configuration:" log_info "Final configuration:"
log_info " Server Name: $SERVER_NAME" log_info " Server Name: $SERVER_NAME"
log_info " Agent ID: $AGENT_ID" log_info " Agent ID: $AGENT_ID"
log_info " PB API URL: $POCKETBASE_URL" log_info " PocketBase URL: $POCKETBASE_URL"
log_info " IP Address: $IP_ADDRESS" log_info " IP Address: $IP_ADDRESS"
log_info " OS Type: $OS_TYPE" log_info " OS Type: $OS_TYPE"
log_info " Health Check Port: $HEALTH_CHECK_PORT" log_info " Health Check Port: $HEALTH_CHECK_PORT"
@@ -341,7 +609,7 @@ test_installation() {
show_post_install_info() { show_post_install_info() {
echo echo
echo "=============================================" echo "============================================="
echo " CheckCle Server Agent Installation Complete!" echo " Installation Complete!"
echo "=============================================" echo "============================================="
echo echo
log_success "CheckCle Monitoring Agent installed and configured successfully" log_success "CheckCle Monitoring Agent installed and configured successfully"
@@ -350,6 +618,11 @@ show_post_install_info() {
echo " Architecture: $ARCH ($PACKAGE_ARCH)" echo " Architecture: $ARCH ($PACKAGE_ARCH)"
echo " Package: $PACKAGE_FILENAME" echo " Package: $PACKAGE_FILENAME"
echo " Package Manager: $PACKAGE_MANAGER" echo " Package Manager: $PACKAGE_MANAGER"
if [[ "$PACKAGE_FORMAT" == "tar.gz" ]]; then
echo " Installation Type: Manual (tar.gz)"
else
echo " Installation Type: Native package ($PACKAGE_FORMAT)"
fi
echo echo
echo "Configuration: $CONFIG_FILE" echo "Configuration: $CONFIG_FILE"
echo "Service status: systemctl status monitoring-agent" echo "Service status: systemctl status monitoring-agent"
@@ -416,7 +689,12 @@ case "${1:-}" in
echo "System Requirements:" echo "System Requirements:"
echo " - Linux with systemd" echo " - Linux with systemd"
echo " - Supported architectures: x86_64 (amd64), aarch64/arm64" echo " - Supported architectures: x86_64 (amd64), aarch64/arm64"
echo " - Supported distributions: Debian/Ubuntu (.deb), RHEL/CentOS/Fedora (.rpm)" echo " - Supported distributions: Debian/Ubuntu (.deb), RHEL/CentOS/Fedora (.rpm), or any Linux (tar.gz fallback)"
echo
echo "Package Installation Logic:"
echo " 1. Detects OS and tries native package format first (.deb for Debian-based, .rpm for RHEL-based)"
echo " 2. If native package is not available, automatically falls back to tar.gz"
echo " 3. tar.gz works on any Linux distribution with systemd"
echo echo
echo "Required Environment Variables:" echo "Required Environment Variables:"
echo " SERVER_TOKEN Server authentication token" echo " SERVER_TOKEN Server authentication token"
@@ -444,13 +722,28 @@ case "${1:-}" in
systemctl disable monitoring-agent 2>/dev/null || true systemctl disable monitoring-agent 2>/dev/null || true
# Remove based on detected package manager # Remove based on detected package manager
if command -v dpkg >/dev/null 2>&1; then if command -v dpkg >/dev/null 2>&1 && dpkg -l monitoring-agent >/dev/null 2>&1; then
dpkg -r monitoring-agent 2>/dev/null || true dpkg -r monitoring-agent 2>/dev/null || true
elif command -v rpm >/dev/null 2>&1; then log_success "DEB package removed"
elif command -v rpm >/dev/null 2>&1 && rpm -q monitoring-agent >/dev/null 2>&1; then
rpm -e monitoring-agent 2>/dev/null || true rpm -e monitoring-agent 2>/dev/null || true
log_success "RPM package removed"
else
# Manual removal for tar.gz installations
log_info "Performing manual cleanup for tar.gz installation..."
rm -f /usr/bin/monitoring-agent 2>/dev/null || true
rm -rf /etc/monitoring-agent 2>/dev/null || true
rm -f /lib/systemd/system/monitoring-agent.service 2>/dev/null || true
rm -f /usr/lib/systemd/system/monitoring-agent.service 2>/dev/null || true
rm -f /etc/systemd/system/monitoring-agent.service 2>/dev/null || true
userdel monitoring-agent 2>/dev/null || true
groupdel monitoring-agent 2>/dev/null || true
rm -rf /var/lib/monitoring-agent 2>/dev/null || true
rm -rf /var/log/monitoring-agent 2>/dev/null || true
log_success "Manual cleanup completed"
fi fi
rm -rf /etc/monitoring-agent 2>/dev/null || true systemctl daemon-reload 2>/dev/null || true
log_success "Monitoring agent uninstalled" log_success "Monitoring agent uninstalled"
exit 0 exit 0
;; ;;