Pre-requisites check script
Published 30 January 2023
You can check your machine against the Redgate Clone pre-requisites by running the following command:
- curl -sSL https://rd.gt/3RL6ioU | sudo bash
To run the script manually:
- Copy the contents of the script below and save it to the file
pre-requisite-check.sh
- Ensure that the script is executable and if not run
chmod +x ./pre-requisite-check.sh
- The script requires superuser permissions so will need to be executed with sudo, i.e.
sudo ./pre-requisite-check.sh
- #!/usr/bin/env bash
- #############################################################################################################################
- # Name : prerequisite-check.sh
- # Description : Checks a Linux machine against the Redgate Clone prerequisites and requirements
- # i.e. the items listed here https://documentation.red-gate.com/x/nANsC
- #############################################################################################################################
- ###################################################### Requirements #########################################################
- expected_os_name_ubuntu="ubuntu"
- expected_os_name_rhel="red hat enterprise linux"
- minimum_os_version_ubuntu="22.04"
- minimum_os_version_rhel="8.0"
- minimum_cpu_count=8
- minimum_ram_size_in_gib=16
- expected_system_disk_partition_table_type="gpt"
- minimum_system_disk_size_human_readable="80Gi"
- minimum_data_disk_size_human_readable="100Gi"
- minimum_root_size_human_readable="2Gi"
- minimum_home_size_human_readable="4Gi"
- minimum_tmp_size_human_readable="3Gi"
- minimum_var_size_human_readable="50Gi"
- minimum_usr_size_human_readable="8Gi"
- ###################################################### Script setup #########################################################
- set -Eeuo pipefail
- if [[ $(uname | tr '[:upper:]' '[:lower:]') != "linux" ]]; then
- echo "This script can only be run on a Linux environment, but environment type $(uname) was detected."
- exit 1
- fi
- if [[ $(/usr/bin/id -u) -ne 0 ]]; then
- echo "This script requires root permissions. Please rerun using sudo."
- exit 1
- fi
- errors=()
- function report_and_exit() {
- echo
- if [ ${#errors[@]} != 0 ]; then
- echo "Found the following errors..."
- for error in "${errors[@]}"; do
- echo " • $error"
- done
- exit 1
- else
- echo "No errors were found!"
- exit 0
- fi
- }
- section_start_error_count=0
- function start_section() {
- section_start_error_count=${#errors[@]}
- printf " Checking %s requirements... " "$1"
- }
- function end_section() {
- if [[ $section_start_error_count -eq ${#errors[@]} ]]; then
- echo "OK"
- else
- echo "FAIL"
- fi
- }
- echo "Checking Redgate Clone host VM pre-requisites (https://documentation.red-gate.com/x/kgARCQ)..."
- ####################################################### OS checks ###########################################################
- start_section "OS"
- if ls /etc/*-release 1> /dev/null 2>&1; then
- os_name=$(cat /etc/*-release | grep "^NAME=" | cut -d'"' -f2 | tr '[:upper:]' '[:lower:]')
- os_version=$(cat /etc/*-release | grep "^VERSION_ID=" | cut -d= -f2 | xargs)
- if [ "$os_name" == "$expected_os_name_ubuntu" ] || [ "$os_name" == "$expected_os_name_rhel" ]; then
- if [[ -z "${os_version// }" ]]; then
- errors+=("The $os_name version could not be detected. Redgate Clone requires at least version $minimum_os_version.")
- else
- is_rhel8=
- if [ "$os_name" == "$expected_os_name_ubuntu" ]; then
- minimum_os_version=$minimum_os_version_ubuntu
- else
- minimum_os_version=$minimum_os_version_rhel
- major_version=$(printf %.1s "$os_version")
- if [ "$major_version" == "8" ]; then
- is_rhel8=true
- fi
- fi
- if [[ $(printf "%s\n%s" "$minimum_os_version" "$os_version" | sort -V | head -n1) != "$minimum_os_version" ]]; then
- errors+=("The $os_name version must be at least $minimum_os_version but was detected to be $os_version.")
- fi
- fi
- else
- errors+=("The operating system must be $expected_os_name_rhel or $expected_os_name_ubuntu but it was detected to be $os_name.")
- end_section
- report_and_exit # Exit early as the other checks may not work as expected.
- fi
- else
- errors+=("The operating system must be $expected_os_name_rhel or $expected_os_name_ubuntu but the distribution could not be detected. The uname command returns \"$(uname -a)\".")
- end_section
- report_and_exit # Exit early as the other checks may not work as expected.
- fi
- end_section
- #################################################### Hardware checks ########################################################
- start_section "CPU"
- cpu_count=$(nproc --all)
- if [ "$cpu_count" -lt "$minimum_cpu_count" ]
- then
- errors+=("Redgate Clone requires a minimum of $minimum_cpu_count vCPUs, but $cpu_count were detected.")
- fi
- end_section
- start_section "RAM"
- if [[ $(which dmidecode) ]]; then
- ram_size_in_gib=$(dmidecode -t memory | grep "^[[:space:]]Size:" | cut -d: -f2 | tr -d ' B' | grep -v -x -F "NoModuleInstalled" | numfmt --from=iec | awk 'BEGIN {count=0;} {count+=$1;} END {print count/1073741824;}')
- if [ "$ram_size_in_gib" -lt "$minimum_ram_size_in_gib" ]
- then
- errors+=("Redgate Clone requires a minimum of ${minimum_ram_size_in_gib}Gi RAM, but ${ram_size_in_gib}Gi was detected.")
- fi
- else
- errors+=("The amount of RAM could not be detected because the dmidecode utility is missing. Redgate Clone requires a minimum of ${minimum_ram_size_in_gib}Gi RAM.")
- fi
- end_section
- ###################################################### Disk checks ##########################################################
- start_section "storage"
- minimum_system_disk_size=$(numfmt --from=auto $minimum_system_disk_size_human_readable)
- minimum_data_disk_size=$(numfmt --from=auto $minimum_data_disk_size_human_readable)
- system_disk=$(lsblk --bytes --output NAME,MOUNTPOINT,PKNAME --list --paths | awk '{if($2=="/")print $3}')
- system_disk_size=$(lsblk --bytes --output NAME,SIZE --list --paths | awk '{if($1=="'"$system_disk"'")print $2}')
- if [ "$is_rhel8" = true ]; then
- system_partition_table_type=$(sudo fdisk -l 2> /dev/null | awk '/Disklabel type:/ {print $3}')
- else
- system_partition_table_type=$(lsblk --output NAME,PTTYPE --list --paths | awk '{if($1=="'"$system_disk"'")print $2}')
- fi
- if [ "$((system_disk_size))" -lt "$((minimum_system_disk_size))" ]; then
- system_disk_size_human_readable=$(numfmt --to=iec-i "$system_disk_size")
- errors+=("The system disk needs to be at least $minimum_system_disk_size_human_readable in size. Disk $system_disk was detected to be the system disk but its size is only $system_disk_size_human_readable.")
- fi
- if [ "$system_partition_table_type" != "$expected_system_disk_partition_table_type" ]; then
- errors+=("The system disk's partition table type must be $expected_system_disk_partition_table_type but was detected to be $system_partition_table_type.")
- fi
- if [ "$is_rhel8" = true ]; then
- possible_data_disks=$(lsblk --bytes --output NAME,SIZE,TYPE | awk '($2 >= '"$minimum_data_disk_size"' && $3 == "disk") {print "/dev/"$1;}' | tr ' ' '\n')
- else
- possible_data_disks=$(lsblk --bytes --output NAME,SIZE,TYPE,PATH | awk '($2 >= '"$minimum_data_disk_size"' && $3 == "disk") {print $4;}' | tr ' ' '\n')
- fi
- data_disks=()
- declare -A filesystems
- for blockdevice in $possible_data_disks; do
- filesystem_count=$(lsblk --noheadings --fs --output NAME,FSTYPE --list "$blockdevice" | awk 'BEGIN {count=0;} {if ($2) count+=1} END {print count;}')
- if [ "$filesystem_count" -eq 0 ]
- then
- data_disks+=("$blockdevice")
- else
- filesystems[$blockdevice]=$filesystem_count
- fi
- done
- if [ ${#data_disks[@]} == 0 ]; then
- filesystem_list=""
- for key in "${!filesystems[@]}"; do
- filesystem_list+=" Device $key is large enough but already has ${filesystems[$key]} existing filesystems."
- done
- errors+=("No disks were detected that have a size greater than $minimum_data_disk_size_human_readable and have no existing filesystems.$filesystem_list")
- fi
- # check if they are using LVM volumes and if so if there is enough space assigned to the root, home, tmp, var and usr directories
- if command -v lvs &> /dev/null
- then
- if [ -n "$(lvs)" ]; then
- root_lv=$(lsblk --output NAME,MOUNTPOINT --list --paths | awk '{if($2=="/")print $1}')
- home_lv=$(lsblk --output NAME,MOUNTPOINT --list --paths | awk '{if($2=="/home")print $1}')
- tmp_lv=$(lsblk --output NAME,MOUNTPOINT --list --paths | awk '{if($2=="/tmp")print $1}')
- var_lv=$(lsblk --output NAME,MOUNTPOINT --list --paths | awk '{if($2=="/var")print $1}')
- usr_lv=$(lsblk --output NAME,MOUNTPOINT --list --paths | awk '{if($2=="/usr")print $1}')
- check_lv() {
- lv=$1
- minimum_size=$2
- directory=$3
- if [[ $lv == *"/dev/mapper"* ]]; then
- lv_size=$(lsblk --bytes --output NAME,SIZE --list --paths | awk '{if($1=="'"$lv"'")print $2}')
- if [ "$((lv_size))" -lt "$((minimum_size))" ]; then
- lv_size_human_readable=$(numfmt --to=iec-i "$lv_size")
- errors+=("The $directory directory needs to be at least $(numfmt --to=iec-i "$minimum_size") in size. Logical volume $lv was detected to be the $directory directory but its size is only $lv_size_human_readable.")
- fi
- else
- errors+=("The $directory directory is not on an LVM.")
- fi
- }
- minimum_root_size=$(numfmt --from=auto $minimum_root_size_human_readable)
- minimum_home_size=$(numfmt --from=auto $minimum_home_size_human_readable)
- minimum_tmp_size=$(numfmt --from=auto $minimum_tmp_size_human_readable)
- minimum_usr_size=$(numfmt --from=auto $minimum_usr_size_human_readable)
- minimum_var_size=$(numfmt --from=auto $minimum_var_size_human_readable)
- check_lv "$root_lv" "$minimum_root_size" "/"
- check_lv "$home_lv" "$minimum_home_size" "/home"
- check_lv "$tmp_lv" "$minimum_tmp_size" "/tmp"
- check_lv "$var_lv" "$minimum_var_size" "/var"
- check_lv "$usr_lv" "$minimum_usr_size" "/usr"
- fi
- fi
- end_section
- ################################################# Internet connectivity #####################################################
- start_section "Internet connectivity"
- set +e
- if ! curl --silent --head --retry 3 --output /dev/null http://www.google.com/; then
- errors+=("Internet connectivity was not detected.")
- fi
- set -e
- end_section
- ################################################# Installation script availability #####################################################
- start_section "Installation script availability"
- readonly INSTALLATION_TEST_URL=https://k8s.kurl.sh/cloning-capability-app
- set +e
- if ! curl --silent --head --retry 3 --output /dev/null $INSTALLATION_TEST_URL; then
- errors+=("Unable to reach the URL hosting the installation script: $INSTALLATION_TEST_URL.")
- fi
- set -e
- end_section
- ################################################ Kernel configuration values ####################################################
- start_section "Kernel configuration"
- max_user_instances=$(sysctl fs.inotify.max_user_instances | awk '{print $NF}')
- if [ "$max_user_instances" -lt 512 ]
- then
- errors+=("The kernel configuration fs.inotify.max_user_instances should be set to at least 512 but was detected to be $max_user_instances.")
- fi
- max_io_request=$(sysctl fs.aio-max-nr | awk '{print $NF}')
- if [ "$max_io_request" -lt 1048576 ]
- then
- errors+=("The kernel configuration fs.aio-max-nr should be set to at least 1048576 but was detected to be $max_io_request.")
- fi
- end_section
- ################################################ Report findings to user ####################################################
- report_and_exit