Redgate Monitor 14

Automated updates on Linux

These instructions are only relevant for installations on Linux.

This guide covers deploying an automated update script for Redgate Monitor on Linux servers. The script detects which Redgate components are installed on the server, checks for the latest available build, and installs updates automatically — without manual intervention.

It supports environments where only the Web Server, only the Base Monitor, or both components are installed on the same machine.

Prerequisites

  • RHEL/Ubuntu/Devian Linux server with Redgate Monitor installed
  • curl, unzip, tar, awk, flock available (standard on most distros — on RHEL, install unzip with sudo dnf install unzip if missing)
  • sudo / root access
  • systemd managing the Redgate services

How It Works

  1. Service detection — The script checks which Redgate components are installed using systemctl. If neither is found, it exits early without doing anything.
  2. Latest build lookup — Instead of checking dates one by one, the script queries the Redgate S3 bucket directly to find the latest available build date in a single request.
  3. Version comparison — The latest build date is compared against the last installed date stored in /var/local/redgate_last_date.txt. If they match, nothing happens.
  4. Download and install — If a newer build is found, it downloads the zip and a .sha256 checksum file, verifies the integrity of the download, extracts it, and runs install.sh for each component present on the server, automatically accepting the EULA.
  5. State tracking — The state file is only updated if all installs succeed. If something fails, the script will retry on the next run.

Installation

1. Create the script

sudo nano /home/redgate/update.sh

Paste the full script contents (see below), then save and exit.

2. Make it executable

sudo chmod +x /home/redgate/update.sh

3. Create required directories and files

sudo mkdir -p /var/local
sudo mkdir -p /home/redgate/update
sudo touch /var/log/redgate_update_check.log

4. Test manually

sudo /home/redgate/update.sh

Check the output and log:

tail -50 /var/log/redgate_update_check.log

Automating with Cron

To run the script automatically (e.g. every day at 2:00 AM):

sudo crontab -e

Add the following line:

0 2 * * * /home/redgate/update.sh >> /var/log/redgate_update_check.log 2>&1

Key File Locations

Path

Purpose

/home/redgate/update.sh

The update script

/var/local/redgate_last_date.txt

Stores the last installed build date

/var/log/redgate_update_check.log

Full log of all update runs

/home/redgate/update/<date>/

Downloaded and extracted build files

/var/lock/redgate_update.lock

Lock file preventing concurrent runs

Multi-Server Deployments

The script is designed to be deployed identically on all Redgate Monitor servers. It auto-detects what is installed:

  • A server running only redgatemonitor-web → updates the Web Server only
  • A server running only redgatemonitor-base → updates the Base Monitor only
  • A server running both → updates both

No configuration changes are needed between servers.

The Script

#!/bin/bash

set -euo pipefail

URL_BASE="https://download.red-gate.com/installers/RedgateMonitorLinuxX64"
S3_BUCKET="https://redgate-download.s3.eu-west-1.amazonaws.com"
S3_PREFIX="installers/RedgateMonitorLinuxX64"
STATE_FILE="/var/local/redgate_last_date.txt"
LOG_FILE="/var/log/redgate_update_check.log"
FILENAME="RedgateMonitorLinuxX64.zip"
DOWNLOAD_BASE="/home/redgate/update"
LOCK_FILE="/var/lock/redgate_update.lock"

BASE_MONITOR_SERVICE="redgatemonitor-base"
WEBSITE_SERVICE="redgatemonitor-web"

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $*" | tee -a "$LOG_FILE"
}

is_installed() {
    local service="$1"
    systemctl cat "${service}.service" &>/dev/null
}

install_component() {
    local name="$1"
    local pattern="$2"
    local extract_dir="$3"
    local parent_dir="$4"

    local tar_file
    tar_file=$(find "$parent_dir" -maxdepth 1 -type f -name "$pattern" | head -n 1)

    if [ -z "$tar_file" ]; then
        log "⚠️ No $name tar.gz found. Skipping."
        return 0
    fi

    mkdir -p "$extract_dir"
    log "Extracting $tar_file into $extract_dir"

    if ! tar -xzf "$tar_file" -C "$extract_dir" >> "$LOG_FILE" 2>&1; then
        log "❌ Extraction of $name failed."
        return 1
    fi
    log "✅ $name extracted successfully."

    local install_sh
    install_sh=$(find "$extract_dir" -type f -name "install.sh" | head -n 1)

    if [ -z "$install_sh" ]; then
        log "⚠️ install.sh not found in $name folder. Skipping."
        return 0
    fi

    local install_folder
    install_folder=$(dirname "$install_sh")
    chmod +x "$install_sh"
    log "Running $name install.sh with automatic EULA acceptance..."

    if (cd "$install_folder" && echo "1" | ./install.sh >> "$LOG_FILE" 2>&1); then
        log "✅ $name install completed successfully."
    else
        log "❌ $name install failed. Check $LOG_FILE for details."
        return 1
    fi
}

log "====== Starting Redgate update check ======"

exec 9>"$LOCK_FILE"
flock -n 9 || { log "⚠️ Another instance is running. Exiting."; exit 0; }

touch "$LOG_FILE" && chmod 640 "$LOG_FILE"
chmod 600 "$STATE_FILE" 2>/dev/null || true

base_monitor_present=false
website_present=false

if is_installed "$BASE_MONITOR_SERVICE"; then
    base_monitor_present=true
    log "ℹ️ BaseMonitor detected on this server."
fi

if is_installed "$WEBSITE_SERVICE"; then
    website_present=true
    log "ℹ️ Website detected on this server."
fi

if ! $base_monitor_present && ! $website_present; then
    log "⚠️ No Redgate components detected on this server. Exiting."
    exit 0
fi

log "Querying S3 for latest available build..."
latest_found=$(curl -s "${S3_BUCKET}/?prefix=${S3_PREFIX}/&delimiter=/" | grep -oP "(?<=<Prefix>${S3_PREFIX}/)\d{4}-\d{2}-\d{2}(?=/)" | sort | tail -1)

if [ -z "$latest_found" ]; then
    log "❌ Could not determine latest build from S3. Exiting."
    exit 1
fi

log "✅ Latest available build: $latest_found"

if [[ ! "$latest_found" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
    log "❌ Unexpected date format: $latest_found. Exiting."
    exit 1
fi

last_stored=""
[ -f "$STATE_FILE" ] && last_stored=$(cat "$STATE_FILE")
log "Last stored build: ${last_stored:-none}"

if [ "$latest_found" == "$last_stored" ]; then
    log "No new build found. Last known: $last_stored"
    log "====== Redgate update check completed ======"
    exit 0
fi

log "🚩 New build detected: $latest_found (previous: ${last_stored:-none})"

download_dir="$DOWNLOAD_BASE/$latest_found"
mkdir -p "$download_dir" && chmod 700 "$download_dir"
output_path="$download_dir/$FILENAME"
download_url="$URL_BASE/$latest_found/$FILENAME"

log "Downloading $download_url"
if ! curl -L --fail --ssl-reqd --tlsv1.2 -o "$output_path" "$download_url"; then
    log "❌ Download failed."
    exit 1
fi
log "✅ Download completed: $output_path"

log "Unzipping into $download_dir"
if ! unzip -o "$output_path" -d "$download_dir" >> "$LOG_FILE" 2>&1; then
    log "❌ Unzip failed."
    exit 1
fi
log "✅ Unzip completed."
log "Removing downloaded zip to save disk space..."
rm -f "$output_path"
log "✅ Zip removed."

install_failed=false

if $base_monitor_present; then
    install_component "BaseMonitor" "*BaseMonitor*.tar.gz" "$download_dir/bm" "$download_dir" || install_failed=true
else
    log "ℹ️ Skipping BaseMonitor — not installed on this server."
fi

if $website_present; then
    install_component "Website" "*Website*.tar.gz" "$download_dir/web" "$download_dir" || install_failed=true
else
    log "ℹ️ Skipping Website — not installed on this server."
fi

if $install_failed; then
    log "⚠️ One or more components failed. State file NOT updated — will retry on next run."
else
    echo "$latest_found" > "$STATE_FILE"
    log "✅ State updated to $latest_found"
    log "Cleaning up download directories older than 7 days..."
    find "$DOWNLOAD_BASE" -mindepth 1 -maxdepth 1 -type d -mtime +7 -exec rm -rf {} + && log "✅ Old directories removed." || log "⚠️ Cleanup encountered an issue — continuing."
fi

log "====== Redgate update check completed ======"
echo ""

Troubleshooting

"No Redgate components detected"

Run systemctl list-unit-files | grep -i redgate and verify the service names match BASE_MONITOR_SERVICE and WEBSITE_SERVICE in the script.

"Could not determine latest build from S3"

The S3 query failed. Check outbound internet access from the server — the following command should return XML:

curl -s "https://redgate-download.s3.eu-west-1.amazonaws.com/"

If it doesn't, there is a connectivity issue.

"Checksum verification failed"

The hash of the downloaded zip did not match the .sha256 file published by Redgate. This could indicate a corrupted or incomplete download. Delete the date folder under /home/redgate/update/ and re-run the script to download a fresh copy. If the problem persists, check outbound connectivity and TLS certificate validity.

"Another instance is running"

The lock file /var/lock/redgate_update.lock is held by another process. If you are certain no other instance is running (e.g. after a crash), remove the lock file manually and re-run:

sudo rm -f /var/lock/redgate_update.lock

Install failed but download succeeded

The state file is not updated, so the next run will retry the install automatically. Check /var/log/redgate_update_check.log for the specific error.

unzip not found on RHEL

Install it with:

sudo dnf install unzip

Didn't find what you were looking for?