Redgate Clone

Pre-requisites check script

You can check your machine against the Redgate Clone pre-requisites by running the following command:

  1. curl -sSL https://rd.gt/3RL6ioU | sudo bash

To run the script manually:

  1. Copy the contents of the script below and save it to the file pre-requisite-check.sh
  2. Ensure that the script is executable and if not run chmod +x ./pre-requisite-check.sh
  3. The script requires superuser permissions so will need to be executed with sudo, i.e. sudo ./pre-requisite-check.sh
  1. #!/usr/bin/env bash
  2. #############################################################################################################################
  3. # Name : prerequisite-check.sh
  4. # Description : Checks a Linux machine against the Redgate Clone prerequisites and requirements
  5. # i.e. the items listed here https://documentation.red-gate.com/x/nANsC
  6. #############################################################################################################################
  7.  
  8. ###################################################### Requirements #########################################################
  9.  
  10. expected_os_name_ubuntu="ubuntu"
  11. expected_os_name_rhel="red hat enterprise linux"
  12. minimum_os_version_ubuntu="22.04"
  13. minimum_os_version_rhel="8.0"
  14. minimum_cpu_count=8
  15. minimum_ram_size_in_gib=16
  16. expected_system_disk_partition_table_type="gpt"
  17. minimum_system_disk_size_human_readable="80Gi"
  18. minimum_data_disk_size_human_readable="100Gi"
  19. minimum_root_size_human_readable="2Gi"
  20. minimum_home_size_human_readable="4Gi"
  21. minimum_tmp_size_human_readable="3Gi"
  22. minimum_var_size_human_readable="50Gi"
  23. minimum_usr_size_human_readable="8Gi"
  24.  
  25. ###################################################### Script setup #########################################################
  26.  
  27. set -Eeuo pipefail
  28.  
  29. if [[ $(uname | tr '[:upper:]' '[:lower:]') != "linux" ]]; then
  30. echo "This script can only be run on a Linux environment, but environment type $(uname) was detected."
  31. exit 1
  32. fi
  33.  
  34. if [[ $(/usr/bin/id -u) -ne 0 ]]; then
  35. echo "This script requires root permissions. Please rerun using sudo."
  36. exit 1
  37. fi
  38.  
  39. errors=()
  40.  
  41. function report_and_exit() {
  42. echo
  43. if [ ${#errors[@]} != 0 ]; then
  44. echo "Found the following errors..."
  45. for error in "${errors[@]}"; do
  46. echo " • $error"
  47. done
  48. exit 1
  49. else
  50. echo "No errors were found!"
  51. exit 0
  52. fi
  53. }
  54.  
  55. section_start_error_count=0
  56.  
  57. function start_section() {
  58. section_start_error_count=${#errors[@]}
  59. printf " Checking %s requirements... " "$1"
  60. }
  61.  
  62. function end_section() {
  63. if [[ $section_start_error_count -eq ${#errors[@]} ]]; then
  64. echo "OK"
  65. else
  66. echo "FAIL"
  67. fi
  68. }
  69.  
  70. echo "Checking Redgate Clone host VM pre-requisites (https://documentation.red-gate.com/x/kgARCQ)..."
  71.  
  72. ####################################################### OS checks ###########################################################
  73.  
  74. start_section "OS"
  75.  
  76. if ls /etc/*-release 1> /dev/null 2>&1; then
  77. os_name=$(cat /etc/*-release | grep "^NAME=" | cut -d'"' -f2 | tr '[:upper:]' '[:lower:]')
  78. os_version=$(cat /etc/*-release | grep "^VERSION_ID=" | cut -d= -f2 | xargs)
  79.  
  80. if [ "$os_name" == "$expected_os_name_ubuntu" ] || [ "$os_name" == "$expected_os_name_rhel" ]; then
  81. if [[ -z "${os_version// }" ]]; then
  82. errors+=("The $os_name version could not be detected. Redgate Clone requires at least version $minimum_os_version.")
  83. else
  84. is_rhel8=
  85. if [ "$os_name" == "$expected_os_name_ubuntu" ]; then
  86. minimum_os_version=$minimum_os_version_ubuntu
  87. else
  88. minimum_os_version=$minimum_os_version_rhel
  89. major_version=$(printf %.1s "$os_version")
  90. if [ "$major_version" == "8" ]; then
  91. is_rhel8=true
  92. fi
  93. fi
  94.  
  95. if [[ $(printf "%s\n%s" "$minimum_os_version" "$os_version" | sort -V | head -n1) != "$minimum_os_version" ]]; then
  96. errors+=("The $os_name version must be at least $minimum_os_version but was detected to be $os_version.")
  97. fi
  98. fi
  99. else
  100. errors+=("The operating system must be $expected_os_name_rhel or $expected_os_name_ubuntu but it was detected to be $os_name.")
  101. end_section
  102. report_and_exit # Exit early as the other checks may not work as expected.
  103. fi
  104. else
  105. 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)\".")
  106. end_section
  107. report_and_exit # Exit early as the other checks may not work as expected.
  108. fi
  109.  
  110. end_section
  111.  
  112. #################################################### Hardware checks ########################################################
  113.  
  114. start_section "CPU"
  115.  
  116. cpu_count=$(nproc --all)
  117.  
  118. if [ "$cpu_count" -lt "$minimum_cpu_count" ]
  119. then
  120. errors+=("Redgate Clone requires a minimum of $minimum_cpu_count vCPUs, but $cpu_count were detected.")
  121. fi
  122.  
  123. end_section
  124.  
  125. start_section "RAM"
  126.  
  127. if [[ $(which dmidecode) ]]; then
  128. 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;}')
  129. if [ "$ram_size_in_gib" -lt "$minimum_ram_size_in_gib" ]
  130. then
  131. errors+=("Redgate Clone requires a minimum of ${minimum_ram_size_in_gib}Gi RAM, but ${ram_size_in_gib}Gi was detected.")
  132. fi
  133. else
  134. 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.")
  135. fi
  136.  
  137. end_section
  138.  
  139. ###################################################### Disk checks ##########################################################
  140.  
  141. start_section "storage"
  142.  
  143. minimum_system_disk_size=$(numfmt --from=auto $minimum_system_disk_size_human_readable)
  144. minimum_data_disk_size=$(numfmt --from=auto $minimum_data_disk_size_human_readable)
  145.  
  146. system_disk=$(lsblk --bytes --output NAME,MOUNTPOINT,PKNAME --list --paths | awk '{if($2=="/")print $3}')
  147. system_disk_size=$(lsblk --bytes --output NAME,SIZE --list --paths | awk '{if($1=="'"$system_disk"'")print $2}')
  148.  
  149. if [ "$is_rhel8" = true ]; then
  150. system_partition_table_type=$(sudo fdisk -l 2> /dev/null | awk '/Disklabel type:/ {print $3}')
  151. else
  152. system_partition_table_type=$(lsblk --output NAME,PTTYPE --list --paths | awk '{if($1=="'"$system_disk"'")print $2}')
  153. fi
  154.  
  155. if [ "$((system_disk_size))" -lt "$((minimum_system_disk_size))" ]; then
  156. system_disk_size_human_readable=$(numfmt --to=iec-i "$system_disk_size")
  157. 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.")
  158. fi
  159.  
  160. if [ "$system_partition_table_type" != "$expected_system_disk_partition_table_type" ]; then
  161. 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.")
  162. fi
  163.  
  164. if [ "$is_rhel8" = true ]; then
  165. possible_data_disks=$(lsblk --bytes --output NAME,SIZE,TYPE | awk '($2 >= '"$minimum_data_disk_size"' && $3 == "disk") {print "/dev/"$1;}' | tr ' ' '\n')
  166. else
  167. possible_data_disks=$(lsblk --bytes --output NAME,SIZE,TYPE,PATH | awk '($2 >= '"$minimum_data_disk_size"' && $3 == "disk") {print $4;}' | tr ' ' '\n')
  168. fi
  169.  
  170. data_disks=()
  171. declare -A filesystems
  172.  
  173. for blockdevice in $possible_data_disks; do
  174. filesystem_count=$(lsblk --noheadings --fs --output NAME,FSTYPE --list "$blockdevice" | awk 'BEGIN {count=0;} {if ($2) count+=1} END {print count;}')
  175. if [ "$filesystem_count" -eq 0 ]
  176. then
  177. data_disks+=("$blockdevice")
  178. else
  179. filesystems[$blockdevice]=$filesystem_count
  180. fi
  181. done
  182.  
  183. if [ ${#data_disks[@]} == 0 ]; then
  184. filesystem_list=""
  185. for key in "${!filesystems[@]}"; do
  186. filesystem_list+=" Device $key is large enough but already has ${filesystems[$key]} existing filesystems."
  187. done
  188. errors+=("No disks were detected that have a size greater than $minimum_data_disk_size_human_readable and have no existing filesystems.$filesystem_list")
  189. fi
  190.  
  191.  
  192. # 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
  193.  
  194. if command -v lvs &> /dev/null
  195. then
  196. if [ -n "$(lvs)" ]; then
  197. root_lv=$(lsblk --output NAME,MOUNTPOINT --list --paths | awk '{if($2=="/")print $1}')
  198. home_lv=$(lsblk --output NAME,MOUNTPOINT --list --paths | awk '{if($2=="/home")print $1}')
  199. tmp_lv=$(lsblk --output NAME,MOUNTPOINT --list --paths | awk '{if($2=="/tmp")print $1}')
  200. var_lv=$(lsblk --output NAME,MOUNTPOINT --list --paths | awk '{if($2=="/var")print $1}')
  201. usr_lv=$(lsblk --output NAME,MOUNTPOINT --list --paths | awk '{if($2=="/usr")print $1}')
  202.  
  203. check_lv() {
  204. lv=$1
  205. minimum_size=$2
  206. directory=$3
  207.  
  208. if [[ $lv == *"/dev/mapper"* ]]; then
  209. lv_size=$(lsblk --bytes --output NAME,SIZE --list --paths | awk '{if($1=="'"$lv"'")print $2}')
  210. if [ "$((lv_size))" -lt "$((minimum_size))" ]; then
  211. lv_size_human_readable=$(numfmt --to=iec-i "$lv_size")
  212. 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.")
  213. fi
  214. else
  215. errors+=("The $directory directory is not on an LVM.")
  216. fi
  217. }
  218.  
  219.  
  220. minimum_root_size=$(numfmt --from=auto $minimum_root_size_human_readable)
  221. minimum_home_size=$(numfmt --from=auto $minimum_home_size_human_readable)
  222. minimum_tmp_size=$(numfmt --from=auto $minimum_tmp_size_human_readable)
  223. minimum_usr_size=$(numfmt --from=auto $minimum_usr_size_human_readable)
  224. minimum_var_size=$(numfmt --from=auto $minimum_var_size_human_readable)
  225.  
  226. check_lv "$root_lv" "$minimum_root_size" "/"
  227. check_lv "$home_lv" "$minimum_home_size" "/home"
  228. check_lv "$tmp_lv" "$minimum_tmp_size" "/tmp"
  229. check_lv "$var_lv" "$minimum_var_size" "/var"
  230. check_lv "$usr_lv" "$minimum_usr_size" "/usr"
  231. fi
  232. fi
  233.  
  234. end_section
  235.  
  236. ################################################# Internet connectivity #####################################################
  237.  
  238. start_section "Internet connectivity"
  239.  
  240. set +e
  241. if ! curl --silent --head --retry 3 --output /dev/null http://www.google.com/; then
  242. errors+=("Internet connectivity was not detected.")
  243. fi
  244. set -e
  245.  
  246. end_section
  247.  
  248. ################################################# Installation script availability #####################################################
  249.  
  250. start_section "Installation script availability"
  251.  
  252. readonly INSTALLATION_TEST_URL=https://k8s.kurl.sh/cloning-capability-app
  253.  
  254. set +e
  255. if ! curl --silent --head --retry 3 --output /dev/null $INSTALLATION_TEST_URL; then
  256. errors+=("Unable to reach the URL hosting the installation script: $INSTALLATION_TEST_URL.")
  257. fi
  258. set -e
  259.  
  260. end_section
  261.  
  262. ################################################ Kernel configuration values ####################################################
  263.  
  264.  
  265. start_section "Kernel configuration"
  266.  
  267. max_user_instances=$(sysctl fs.inotify.max_user_instances | awk '{print $NF}')
  268.  
  269. if [ "$max_user_instances" -lt 512 ]
  270. then
  271. errors+=("The kernel configuration fs.inotify.max_user_instances should be set to at least 512 but was detected to be $max_user_instances.")
  272. fi
  273.  
  274. max_io_request=$(sysctl fs.aio-max-nr | awk '{print $NF}')
  275.  
  276. if [ "$max_io_request" -lt 1048576 ]
  277. then
  278. errors+=("The kernel configuration fs.aio-max-nr should be set to at least 1048576 but was detected to be $max_io_request.")
  279. fi
  280.  
  281. end_section
  282.  
  283. ################################################ Report findings to user ####################################################
  284.  
  285. report_and_exit

Didn't find what you were looking for?