# hms_load_and_verify.sh Version=1.0.10 #============================================================================== # Copyright and license info is available in the LICENSE file included with # the Server Deployment Package (SDP), and also available online: # https://swarm.workshop.perforce.com/projects/perforce-software-sdp/view/main/LICENSE #------------------------------------------------------------------------------ #============================================================================== # HMS Library Functions. #------------------------------------------------------------------------------ # Function: load_helix_topology # # Input: # $1 - Helix Topology file path # $2 - Helix Topology file required format version. # # The following global arrays are updated: # # * InstanceUserPorts associative array # * InstanceMasterHost associative array # * InstanceServerPort associative array # * InstanceBrokerPort associative array # * InstanceManaged associative array # * InstanceDesc associative array # # Instance definition: # Form: INSTANCE|Name|UserPorts|MasterHost|ServerPort|BrokerPort|Managed|Desc # Example: # INSTANCE|fgs|perforce:1666|helix-01|1999|1666|Friendly Greeting Systems # # Return: # 0 - Instances loaded, syntax verified. # 1 - Errors detected. #------------------------------------------------------------------------------ function load_helix_topology { vvmsg "CALL: load_helix_topology($*)" declare cfgFile=$1 declare reqVersion=$2 declare cfgVersion= declare instance= declare instanceUserPorts= declare instanceMasterHost= declare instanceServerPort= declare instanceBrokerPort= declare instanceManaged= declare instanceDesc= declare instanceComponents= declare componentName= declare componentType= declare componentMasterHost= declare componentURL= declare componentBackupHost= declare componentManaged= declare componentDesc= declare failoverPathName= declare failoverFQName= declare failoverType= declare failoverMasterHost= declare failoverBackupHost= declare failoverInstanceList= declare failoverActive= declare line= declare -a errors declare -i errorCount=0 declare -i i declare -i lineCount=0 msg "Loading instances from [$cfgFile]." if [[ ! -r "$cfgFile" ]]; then errmsg "Cannot read Helix Topology file [$cfgFile]." return 1 fi # The first action is artifically hard-coded to START_IMPORT. while read line; do lineCount+=1 case $line in (\#*|NAME*) continue;; (GLOBAL_OPTIONS*) GlobalOptions=$(echo $line|cut -d '=' -f 2) ;; (VERSION*) cfgVersion=$(echo $line | cut -d '=' -f 2) if [[ "$cfgVersion" > "$reqVersion" ]]; then msg "Verified: Helix Topology file version [$cfgVersion] meets minimum requirement." else errors[$errorCount]="Helix Topology file version [$cfgVersion] is too old. Must be at least ${reqVersion}.0." errorCount+=1 fi ;; (INSTANCE*) # INSTANCE|Name|UserPorts|MasterHost|ServerPort|BrokerPort|Managed|Desc instance="$(echo $line | cut -d '|' -f 2)" instanceUserPorts="$(echo $line | cut -d '|' -f 3)" instanceMasterHost="$(echo $line | cut -d '|' -f 4)" instanceServerPort="$(echo $line | cut -d '|' -f 5)" instanceBrokerPort="$(echo $line | cut -d '|' -f 6)" instanceManaged="$(echo $line | cut -d '|' -f 7)" instanceDesc="$(echo $line | cut -d '|' -f 8)" vvmsg "DBG: Instance=$instance" InstanceUserPorts[$instance]=$instanceUserPorts InstanceMasterHost[$instance]=$instanceMasterHost InstanceServerPort[$instance]=$instanceServerPort InstanceBrokerPort[$instance]=$instanceBrokerPort InstanceManaged[$instance]=$instanceManaged InstanceDesc[$instance]=$instanceDesc vvmsg "DBG: InstanceName=$instance" vvmsg "DBG: InstanceUserPorts[$instance]=${InstanceUserPorts[$instance]}" vvmsg "DBG: InstanceMasterHost[$instance]=${InstanceMasterHost[$instance]}" vvmsg "DBG: InstanceServerPort[$instance]=${InstanceServerPort[$instance]}" vvmsg "DBG: InstanceBrokerPort[$instance]=${InstanceBrokerPort[$instance]}" vvmsg "DBG: InstanceManaged[$instance]=${InstanceManaged[$instance]}" vvmsg "DBG: InstanceDesc[$instance]=${InstanceDesc[$instance]}" ;; (COMPONENT*) # COMPONENT|Instance|Type|Name|MasterHost|BackupHost|Managed|URL|Desc instance="$(echo $line | cut -d '|' -f 2)" componentType="$(echo $line | cut -d '|' -f 3)" componentName="$(echo $line | cut -d '|' -f 4)" componentMasterHost="$(echo $line | cut -d '|' -f 5)" componentBackupHost="$(echo $line | cut -d '|' -f 6)" componentManaged="$(echo $line | cut -d '|' -f 7)" componentURL="$(echo $line | cut -d '|' -f 8)" componentDesc="$(echo $line | cut -d '|' -f 9)" componentFQName="$instance:$componentName" vvmsg "DBG: componentFQName=$componentFQName" vvmsg "DBG: componentType=$componentType" vvmsg "DBG: componentMasterHost=$componentMasterHost" vvmsg "DBG: componentBackupHost=$componentBackupHost" vvmsg "DBG: componentManaged=$componentManaged" vvmsg "DBG: componentURL=$componentURL" vvmsg "DBG: componentDesc=$componentDesc" # Maintain the InstanceComponents associative array (indexed by instance name) # as a space-separated list of components. componentList="${InstanceComponents[$instance]:-Unset}" if [[ $componentList == Unset ]]; then InstanceComponents[$instance]=$componentName else InstanceComponents[$instance]="$componentList $componentName" fi ComponentType[$componentFQName]=$componentType ComponentMasterHost[$componentFQName]=$componentMasterHost ComponentURL[$componentFQName]=$componentURL ComponentBackupHost[$componentFQName]=$componentBackupHost ComponentManaged[$componentFQName]=$componentManaged ComponentDesc[$componentFQName]=$componentDesc ;; (FAILOVER*) # FAILOVER|Name|Type|MasterHost|BackupHost|InstanceList|Active|Desc failoverPathName="$(echo $line | cut -d '|' -f 2)" failoverType="$(echo $line | cut -d '|' -f 3)" failoverMasterHost="$(echo $line | cut -d '|' -f 4)" failoverBackupHost="$(echo $line | cut -d '|' -f 5)" failoverInstanceList="$(echo $line | cut -d '|' -f 6)" failoverActive="$(echo $line | cut -d '|' -f 7)" failoverDesc="$(echo $line | cut -d '|' -f 8)" for instance in $(echo $failoverInstanceList|tr ',' ' '); do vvmsg "DBG: I=$instance" # Maintain the InstanceComponents associative array (indexed by instance name) # as a space-separated list of failover options. failoverOptionList="${InstanceFailoverOptions[$instance]:-Unset}" if [[ $failoverOptionList == Unset ]]; then InstanceFailoverOptions[$instance]=$failoverPathName else InstanceFailoverOptions[$instance]="$failoverOptionList $failoverPathName" fi failoverFQName="$instance:$failoverPathName" FailoverType[$failoverFQName]=$failoverType FailoverMasterHost[$failoverFQName]=$failoverMasterHost FailoverBackupHost[$failoverFQName]=$failoverBackupHost FailoverInstanceList[$failoverFQName]=$failoverInstanceList FailoverActive[$failoverFQName]=$failoverActive FailoverDesc[$failoverFQName]=$failoverDesc done ;; esac done < $cfgFile if [[ $errorCount -eq 0 ]]; then msg "\nVerified: All data passed sanity checks." else msg "\nThe following problems were identified:" i=0; while [[ $i -lt $errorCount ]]; do errmsg "${errors[$i]}" i+=1 done fi if [[ $errorCount -eq 0 ]]; then return 0 else return 1 fi } #------------------------------------------------------------------------------ function show_helix_topology { vvmsg "CALL: show_helix_topology($*)" declare -i i msg "${H}\nLoaded ${#InstanceManaged[*]} instances:\n" printf "%-3s %-16s %-40s %-4s %-5s %-2s %-40s %-s\n" "#" "Instance" "User Ports" "P4D" "P4B" "On" "User P4PORTs" "Description" printf "%-3s %-16s %-40s %-4s %-5s %-2s %-40s %-s\n" "---" "---------------" "---------------------------------------" "----" "-----" "--" "----------------------------------------" "------------------------------------------------" i=1; for instance in ${!InstanceManaged[*]}; do printf "%2d. %-16s %-40s %-4s %-5s %2d %-40s %-s\n" "$i" "$instance" "${InstanceUserPorts[$instance]}" "${InstanceServerPort[$instance]}" "${InstanceBrokerPort[$instance]}" "${InstanceManaged[$instance]}" "${InstanceUserPorts[$instance]}" "${InstanceDesc[$instance]}" i+=1 done for instance in ${!InstanceManaged[*]}; do msg "${H}\nFailover options for Instance $instance:\n" printf "%-3s %-9s %-5s %-16s %-16s %-36s %-2s %-s\n" "#" "Path Name" "Type" "Master Host" "Backup Host" "Instance List" "On" "Description" printf "%-3s %-9s %-5s %-16s %-16s %-36s %-2s %-s\n" "---" "---------" "-----" "----------------" "----------------" "------------------------------------" "--" "----------------------------------------" i=1; for f in ${!FailoverActive[*]}; do [[ $f == "$instance:"* ]] || continue vvmsg "DBG: F=$f" printf "%2d. %-9s %-5s %-16s %-16s %-36s %2d %-s\n" "$i" "${f#*:}" "${FailoverType[$f]}" "${FailoverMasterHost[$f]}" "${FailoverBackupHost[$f]}" "${FailoverInstanceList[$f]}" "${FailoverActive[$f]}" "${FailoverDesc[$f]}" i+=1 done done for instance in ${!InstanceManaged[*]}; do msg "${H}\nComponents for Instance $instance:\n" printf "%-3s %-19s %-9s %-24s %-24s %-2s %-36s %-s\n" "#" "Name" "Type" "Master Host" "Backup Host" "M" "Port/URL" "Description" printf "%-3s %-19s %-9s %-24s %-24s %-2s %-36s %-s\n" "---" "-------------------" "---------" "------------------------" "------------------------" "--" "------------------------------------" "------------------------------" i=1; for f in ${!ComponentManaged[*]}; do [[ $f == "$instance:"* ]] || continue vvmsg "DBG: F=$f" printf "%2d. %-19s %-9s %-24s %-24s %2d %-36s %-s\n" "$i" "${f#*:}" "${ComponentType[$f]}" "${ComponentMasterHost[$f]}" "${ComponentBackupHost[$f]}" "${ComponentManaged[$f]}" "${ComponentURL[$f]}" "${ComponentDesc[$f]}" i+=1 done done }