#!/bin/bash

# activate PLT HF on Standalone SG and EntGW Appliances over Inventory
#
#Author: Mihai Dumitru <mihai-radu.dumitru.ext@unify.com>
#
#HOC:
#
#2017-09-12 - v0.1 - mihai
# - initial creation 
#2017-09-14 - v0.2 - mihai
# - bugfix display of EntGW appliances and in case of no SG/EntGW appliances
#2018-03-01 - v0.3 - mihai
# - OSFOURK-9234 - Update to softgate standalone does not work
#2019-07-03 - v0.4 - mihai
# - OSFOURK-12895 - NA16455672: V8R2.22-Confusing answer to "os4k_update_plt_hf_on_sgs_and_entgws status" command
#2021-02-25 - v0.5 - mihai
# - OSFOURK-17845 os4k_update will not check the version
#2021-05-19 - v10.1.6 - Gregor
# - OSFOURK-18567 provide command update_gwmanager, appliance specific argument, (support STMIX), daemonize ....
#2021-05-21 - v10.1.7 - Gregor
# - OSFOURK-18567 generate stripped HF for STMIX, use full or stripped HF depending on target
#2021-05-31 - v10.1.8 - Gregor
# - OSFOURK-18567 provide appliance specific argument also for normal update
#2021-10-07 - v10.1.9 - Gregor
# - OSFOURK-18567 xpath needs -e option for query on SLES15
#2021-11-15 - v10.1.10 - Gregor
# - OSFOURK-19984 include EntGWs in the inventory query
#2022-03-08 - v10.1.11 - Gregor
# - OSFOURK-20250 V10R1.24.0 - STMIX remains at Platform HF update is running..., exit 3 if still running
#2022-03-31 - v10.1.12 - Gregor
# - exit 4 and exit 5 for better feedback to GW Manager
#2022-05-10 - v10.1.13 - Gregor
# - OSFOURK-21362 reduce waiting time on remote appliance after update from 10 to 1 minute
#2023-08-11 - v10.1.14 - Gregor
# - OSFOURK-25184 PRB000069383 os4k_update_plt_hf_on_sgs_and_entgws did not transfer and activate Plt HF V10 R1.42.x for SG Standalones and STMIX in one step
#2024-01-08 - v10.1.15 - Gregor
# - OSFOURK-25184 PRB000069383 os4k_update_plt_hf_on_sgs_and_entgws did not transfer and activate Plt HF V10 R1.42.x for STMIX in the first call due to CHECKSUM error
#2024-01-08 - v10.1.16 - Gregor
# - OSFOURK-25184 PRB000069383 os4k_update_plt_hf_on_sgs_and_entgws harden the re-packaging for STMIX with head
#2024-05-31 - v10.1.17 - Gregor & Mihai
# - OSFOURK-27479 PRB000076481: PLT-HF update on STMIX is not finished OK from host perspective if the STMIX has to restart during the update process (e.g. due to java update)
#2025-01-27 - v10.1.187 - Gregor
# - OSFOURK-28812 PLT-HF update of SG/EntGW/STMIX should work also in network bandwidth limited scenarios, use 5M as chunk size for Gateway Manager, but 2M for console
. /etc/profile
VER="10.1.18"


# exit codes
#
# 0 success
# 1 generic error
# 3 Update already in progress on at least one appliance (single usage lock)
# 4 All Standalone SoftGate, Enterprise Gateway and STMIX appliances are up2date or have wrong basis RLC version. No update needed or possible
# 5 no selected appliance needing an Plt HF update
# 6 ERROR : hotfix file not found


GWMANAGER_MODE=0
chunk_size="2M"  # 2M chunk size to support low bandwidth scenarios 

LOGFILE=/var/log/webservice/update_plt_hf_via_inventory.log
MAX_LOGSIZE=$((1024*1024))
MAX_LOGS=2

initialize_logging() {
    exec >> "$LOGFILE" 2>&1
}

rotate_logs() {
    if [ -f "$LOGFILE" ]; then
        if [ "$(stat -c %s "$LOGFILE")" -gt "$MAX_LOGSIZE" ]; then
            log "Rotating & Archiving log $LOGFILE"
            # Remove oldest log
            rm -f "${LOGFILE}.${MAX_LOGS}.bz2"

            # Shift archived log numbers
            for count in $(seq 1 $((MAX_LOGS-1)) | tac); do
                if [ -f "${LOGFILE}.${count}.bz2" ]; then
                    mv -f "${LOGFILE}.${count}.bz2" "${LOGFILE}.$((count+1)).bz2"
                fi
            done

            # Move current log to first archived copy
            mv -f "$LOGFILE" "${LOGFILE}.1"
            bzip2 "${LOGFILE}.1"

            # Reopen log file
            initialize_logging
        fi
    fi
}

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S'): ${FUNCNAME[1]:-MAIN}: $*" >> "$LOGFILE"
}

function update_inv_cbk_script() {
    #update inventory callback scripts
    [ -e /usr/bin/os4k_update_plt_hf_on_sgs_and_entgws.cbk ] || {
        [ -e /opt/dscxl/share/inventory_cbk_conf ] || return 0
        echo /usr/bin/os4k_update_plt_hf_on_sgs_and_entgws.cbk > /opt/dscxl/share/inventory_cbk_conf/OS4K_UPDATE_PLT_HF_ON_SGS_AND_ENTGWS.cbks
        cat > /usr/bin/os4k_update_plt_hf_on_sgs_and_entgws.cbk << '_EOF_CBK_SCRIPT_'
#!/bin/bash
# first 2 parames are discard client ID and feature name
/usr/bin/os4k_update_plt_hf_on_sgs_and_entgws _lock_ _inventory_notif_ $@
_EOF_CBK_SCRIPT_
        chmod 755 /usr/bin/os4k_update_plt_hf_on_sgs_and_entgws.cbk
    }
}

update_inv_cbk_script

function check_primary()
{
	#sanity check that we are on primary in case script is called directly by the user
	ps -ef | grep -i lxc | grep -v grep | grep -q -i assistant || {
		echo "`date` This script can be called only from the Primary Node (= Node on which Assistant is running)"
		exit 22
	}
}

function provideSTMIXPltHF()
{
	curbighf=$1
	cursmallhf=$2
	log "provideSTMIXPltHF called for ${curbighf} ${cursmallhf}"
	if [ -r ${cursmallhf} ]; then
		log "${cursmallhf} already exists, continuing"
		return 0;
	fi
	stmix_datafile=/opt/yaps/data_stmix
	if [ ! -r ${stmix_datafile} ]; then
		log "can not generate STMIX Plt HF because STMIX data file: ${stmix_datafile} does not exist"
		return 1;
	fi
	current_hotfix_rpms_dir="/var/opt/soco2/current_hotfix_rpms"
	gen_dir="/var/opt/soco2/tmp2_current_hotfix_rpms_for_STMIX/"
	xtract_dir="/var/opt/soco2/tmp1_current_hotfix_rpms_for_STMIX"
	rm -rfv ${gen_dir} ${xtract_dir}
	mkdir -pv ${gen_dir} ${xtract_dir}
	curdir=`pwd`
	log "extracting plt HF ${curbighf} to extract dir ${xtract_dir}"
	tar --directory=${xtract_dir} -x -v -f ${curbighf}
	potential_packages=`cat ${stmix_datafile} | grep -v "# don't edit first" | grep -v "^section:" | grep -v "^APSline:" | grep -v "^general:" | grep -v "^version:" | awk -F: '{print $1}'`
	cd ${xtract_dir}
	for package in ${potential_packages}
	do
		available_package=`ls ${package}*rpm | head -1`
		if [ -e "${available_package}" ]; then
			log "packaging ${available_package} for STMIX"
			cp -v ${available_package} ${gen_dir}
		else
			log "skipping ${package} for STMIX as it does not exist"
		fi
	done
	cp -v *.info pkg.sh hf.sh1 ${gen_dir}
	cd ${gen_dir}
	log "generating STMIX plt HF ${cursmallhf} in directory ${gen_dir}"
	tar -c -v -f ${cursmallhf} *
	rc=$?
	log "tar -c return code: ${rc}"
	cd ${curdir}
	log "cleanup intermediary directories"
	rm -rvf ${gen_dir} ${xtract_dir}
	ls -l ${cursmallhf}
	return ${rc}
}

function update_appliance()
{
			an_appl=$1
			is_STMIX=0
			log "update_appliance called for ${an_appl}"
			log "check if STMIX or SG/EntGW"
			if [[ "${an_appl}" == *"900" ]]; then
				log "appliance ID ${an_appl} is SG or EntGW"
				hf_toUse=$curhf
				hf_toUseshort=$curhfshort
				ht_toUsepltmd5sum=$pltmd5sum
			else
				log "appliance ID ${an_appl} is STMIX"
				hf_toUse=$curhf_STMIX
				hf_toUseshort=$curhfshort_STMIX
				ht_toUsepltmd5sum=$pltmd5sum_STMIX
				is_STMIX=1
			fi
			log "hf_toUse=$hf_toUse hf_toUseshort=$hf_toUseshort ht_toUsepltmd5sum=$ht_toUsepltmd5sum $is_STMIX"

			#dummy initial status file
			echo in transfer > /dev/os4k_update_plt_hf_on_sgs_and_entgws.$an_appl.upd_running
			chmod 777 /dev/os4k_update_plt_hf_on_sgs_and_entgws.$an_appl.upd_running
			echo Initializing update on appliance ID $an_appl
			echo Transferring $curhfshort to the appliance ...
			/opt/inventory/inventory command1 $an_appl rm -rf /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf
			/opt/inventory/inventory command1 $an_appl mkdir -p /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf
			rm -rf /var/tmp/split-plt-hf-push-to-entgw
			mkdir -p /var/tmp/split-plt-hf-push-to-entgw
			pushd /var/tmp/split-plt-hf-push-to-entgw 1>/dev/null 2>&1
			echo "${hf_toUseshort}" > /var/tmp/split-plt-hf-push-to-entgw/hfname.txt
			/opt/inventory/inventory put $an_appl /var/tmp/split-plt-hf-push-to-entgw/hfname.txt /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf/hfname.txt
			if [ "${chunk_size}" = "" ]; then
				echo "chunk size not defined, using 2M as default"
				chunk_size=2M
			fi 
			echo "Using chunk size ${chunk_size} for transfer"
			split -b ${chunk_size} ${hf_toUse} PLTHF.
			for achunk in $(echo PLTHF*); do
				/opt/inventory/inventory put $an_appl /var/tmp/split-plt-hf-push-to-entgw/$achunk /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf/$achunk
				echo -en .
			done
			popd 1>/dev/null 2>&1
			rm -rf /var/tmp/split-plt-hf-push-to-entgw
			/opt/inventory/inventory put $an_appl /usr/bin/os4k_update_plt_hf_on_sgs_and_entgws /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf/os4k_update_plt_hf_on_sgs_and_entgws
			/opt/inventory/inventory put $an_appl /opt/yaps/script/swupdated /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf/swupdated
			echo " "
			echo Initiating update on the appliance ...
			if /opt/inventory/inventory command1 $an_appl bash /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf/os4k_update_plt_hf_on_sgs_and_entgws _lock_ _appl_update_ ${ht_toUsepltmd5sum}; then
				echo `date` Update on the appliance $an_appl is now running ...
			else
				echo `date` ERROR : Update on the appliance $an_appl FAILED to start
			fi
}

log "### Script $0 (VER=${VER}) called with parameter: $@"

if [ "x$1" = "xupdate_gwmanager" ]; then
  GWMANAGER_MODE=1
  chunk_size="5M"
  initialize_logging
fi

if [ "x$1" = "x_lock_" ]; then
	shift
	if [ "x$1" = "xupdate_gwmanager" ]; then
    GWMANAGER_MODE=1
    chunk_size="5M"
    initialize_logging
  fi
else
	touch /dev/os4k_update_plt_hf_on_sgs_and_entgws.lock
	if [ ${GWMANAGER_MODE} = 1 ]; then
	  # in GW manager mode fail/return immediately if you can not get the lock
    log "trying to get the flock in GW Manager mode "
	  flock -x --nonblock /dev/os4k_update_plt_hf_on_sgs_and_entgws.lock /bin/bash $0 _lock_ $*
	  rc=$?
	  if [ "${rc}" = 1 ]; then
	    log "could not get the flock, exiting "
	  fi
	else
	  flock -x -w 60 /dev/os4k_update_plt_hf_on_sgs_and_entgws.lock /bin/bash $0 _lock_ $*
	  rc=$?
	fi
	exit ${rc}
fi


case $1 in
	#ret code 0 if no update is in progress
	#ret code 1 if some appliance is in progress
	status)
		check_primary
		#get list of SG, EntGW and STMIX detailed - use deployment 21 (SG, STMIX) and 70 (EntGW), but skip iSG (hwTypeNumber 30)
		aline=$(2>/dev/null /opt/inventory/inventory appliance_list --full --include-stmix | xpath -e '//appliance[(deploymentNumber="70" or deploymentNumber="21") and not (hwTypeNumber="30")]/id|//appliance[(deploymentNumber="70" or deploymentNumber="21") and not (hwTypeNumber="30")]/label|//appliance[(deploymentNumber="70" or deploymentNumber="21") and not (hwTypeNumber="30")]/soco2Version' 2>/dev/null | sed -e "s/<\//§\n/g" | sed -e "s/.*>//g")
		arrIds="§"
		arrLbls="§"
		arrVers="§"
		index=0
		applcount=0
		while [ 1 ]; do
			anelem=`echo -en ${aline%%§*}`
			anelem=${anelem%+*}
			[ "x" = "x$anelem" ] && break
			aline=${aline#*§}
			case $index in
				0)
					arrIds="$arrIds${anelem}§"
					index=1
					;;
				1)
					arrLbls="$arrLbls${anelem}§"
					index=2
					;;
				2)
					if [[ $anelem =~ ^V ]]; then
						arrVers="$arrVers${anelem}§"
						index=0
						applcount=$(($applcount+1))
					else
						arrIds="${arrIds%§*§}§"
						arrLbls="${arrLbls%§*§}§"
						arrIds="$arrIds${anelem}§"
						index=1
					fi
					;;
			esac
		done
		>/dev/os4k_update_plt_hf_on_sgs_and_entgws.cache
		echo "APPLCOUNT=$applcount" >/dev/os4k_update_plt_hf_on_sgs_and_entgws.cache
		echo "ARR_IDs=(${arrIds//§/ })" >>/dev/os4k_update_plt_hf_on_sgs_and_entgws.cache
		echo "ARR_LBs=(${arrLbls//§/ })" >>/dev/os4k_update_plt_hf_on_sgs_and_entgws.cache
		echo "ARR_VERs=(${arrVers//§/ })" >>/dev/os4k_update_plt_hf_on_sgs_and_entgws.cache
		source /dev/os4k_update_plt_hf_on_sgs_and_entgws.cache
		arrNeedUpdate=""
		noneinprogress=true
		myver=$(getydata -v)
		asyapsrelease=$(rpm -q --queryformat %{RELEASE} ASyaps)
		if [ $APPLCOUNT -gt 0 ]; then
			for i in `eval echo {0..$(($APPLCOUNT-1))}` ; do
				[ -e /dev/os4k_update_plt_hf_on_sgs_and_entgws.${ARR_IDs[$i]}.upd_running ] && {
					[ $((`date +%s` - `stat -c %Y /dev/os4k_update_plt_hf_on_sgs_and_entgws.${ARR_IDs[$i]}.upd_running`)) -gt 1800 ] && {
						rm -f /dev/os4k_update_plt_hf_on_sgs_and_entgws.${ARR_IDs[$i]}.upd_running
						echo "WARNING : Cleared leftover status file for appliance : ${ARR_IDs[$i]}"
					}
				}
				if [ -e /dev/os4k_update_plt_hf_on_sgs_and_entgws.${ARR_IDs[$i]}.upd_running ]; then
					#TODO - imporvement - check the age of the file before using it - if the file exists unmodified since more than for e.g. 30 minutes then delete it as it probably means some error happened
					# deleting it would force a requesr of the actual status
					noneinprogress=false
					[ "x$2" = "x--only-fill-cache" ] || echo Update is running on ${ARR_LBs[$i]} : $(cat /dev/os4k_update_plt_hf_on_sgs_and_entgws.${ARR_IDs[$i]}.upd_running)
				else
					if [ "x$myver" = "x${ARR_VERs[$i]}" ]; then
						tgtasyapsrelease=$(/opt/inventory/inventory command1 ${ARR_IDs[$i]} rpm -q --queryformat %{RELEASE} ASyaps)
						if [ "x$tgtasyapsrelease" = "x$asyapsrelease" ]; then
							[ "x$2" = "x--only-fill-cache" ] || echo ${ARR_LBs[$i]} is up2date. PLT Version : ${ARR_VERs[$i]}
						else
							[ "x$2" = "x--only-fill-cache" ] || echo ${ARR_LBs[$i]} "(ID ${ARR_IDs[$i]})" needs an update. Current PLT Version : ${ARR_VERs[$i]} RC${tgtasyapsrelease##*\.}. PLT Version on Host : $myver RC${asyapsrelease##*\.}
							arrNeedUpdate="$arrNeedUpdate${ARR_IDs[$i]} "
						fi
					else
                        #OSFOURK-17845 do not do the update if fixrelease version is different
                        myfixreleaseversion=${myver%.*}
                        applfixreleaseversion=${ARR_VERs[$i]}
                        applfixreleaseversion=${applfixreleaseversion%.*}
                        if [ "x$myfixreleaseversion" = "x$applfixreleaseversion" ]; then
                            [ "x$2" = "x--only-fill-cache" ] || echo ${ARR_LBs[$i]} "(ID ${ARR_IDs[$i]})" needs an update. Current PLT Version : ${ARR_VERs[$i]}. PLT Version on Host : $myver
                            arrNeedUpdate="$arrNeedUpdate${ARR_IDs[$i]} "
                        else
							[ "x$2" = "x--only-fill-cache" ] || echo ${ARR_LBs[$i]} "(ID ${ARR_IDs[$i]})" needs an update but must be OS-Updated first from Assistant Gateway Manager. Current PLT Version : ${ARR_VERs[$i]}. PLT Version on Host : $myver
                        fi
					fi
				fi
			done
		else
			echo "`date` No online Standalone SoftGate, Enterprise Gateway or STMIX Appliances found."
		fi
		echo "ARR_NeedUpdate=($arrNeedUpdate)" >>/dev/os4k_update_plt_hf_on_sgs_and_entgws.cache
		$noneinprogress
		exit $?
		;;
	update | update_gwmanager)
		targetAppliances=$2
		log "Starting update/update_gwmanager targetAppliances=${targetAppliances}"
		check_primary
		[ "x`getydata -s general -k sub_cv`" = "x00" ] && {
			echo "`date` Current OS4K Platform version is : `getydata -v`"
			echo "No Platform HotFix has been applied on the Host."
			echo "Nothing to do."
			echo " "
			exit 0
		}
		bash $0 _lock_ status --only-fill-cache
		[ $? -eq 1 ] && {
			echo "`date` Update already in progress on at least one appliance. Check with \"status\" or \"monitor\" commands"
			exit 3
		}
		source /dev/os4k_update_plt_hf_on_sgs_and_entgws.cache
		[ ${#ARR_NeedUpdate[@]} -eq 0 ] && {
			echo `date` All Standalone SoftGate, Enterprise Gateway and STMIX appliances are up2date or have wrong basis RLC version. No update needed or possible. rc=4
			echo " "
			bash $0 _lock_ status
			exit 4
		}
		bash $0 _lock_ status
		echo " "
		curhf=/var/opt/soco2/current_hotfix/PLT-`getydata -v`.tar
		curhf_STMIX=/var/opt/soco2/current_hotfix/PLT-STMIX-`getydata -v`.tar
		1>/dev/null 2>/dev/null ls $curhf || {
			echo "`date` ERROR : file $curhf not found. Listing complete /var/opt/soco2/current_hotfix directory : "
			ls -al /var/opt/soco2/current_hotfix
			echo " "
			exit 6
		}
		curhfshort=${curhf##*/}
		curhfshort_STMIX=${curhf_STMIX##*/}
		pltmd5sum=`md5sum ${curhf} | awk '{print $1}'`
		# generate the stripped STMIX HF if necessary
		provideSTMIXPltHF ${curhf} ${curhf_STMIX}
		pltmd5sum_STMIX=`md5sum ${curhf_STMIX} | awk '{print $1}'`
        rm -f /usr/bin/os4k_update_plt_hf_on_sgs_and_entgws.cbk
        update_inv_cbk_script
		if [ "${GWMANAGER_MODE}" = 1 ]; then
		  # when called from GW Manager exit immediately to not block the rcon
		  shift; # shift the update_gwmanager command

			# check if there is at least one suitable appliance to be updated before going into the background
			update_needed_for_at_least_one_appliance=0
			for anappl in ${ARR_NeedUpdate[@]}; do
				if [ "${targetAppliances}" = "" ]; then
					log "No targetAppliances specified, update all. We have to go into backround"
					update_needed_for_at_least_one_appliance=1
				else
					if [[ "${targetAppliances}" == *"${anappl}"* ]]; then
						log "target ID ${anappl} selected for update, continue"
						update_needed_for_at_least_one_appliance=1
					else
						log "target ID ${anappl} not selected, skipping"
						continue
					fi
				fi
			done
			if [ "${update_needed_for_at_least_one_appliance}" = "0" ]; then
				echo "`date` no selected appliance needing an Plt HF update, returning rc=5"
				exit 5
			fi
		
		  setsid /bin/bash $0 _lock_ _internal_update_gwmanager_ $* &
		  exit 0
    fi
		for anappl in ${ARR_NeedUpdate[@]}; do
		  if [ "${targetAppliances}" = "" ]; then
				log "No targetAppliances specified, update all"
			else
				if [[ "${targetAppliances}" == *"${anappl}"* ]]; then
					log "target ID ${anappl} selected for update, continue"
				else
					log "target ID ${anappl} not selected, skipping"
					continue
				fi
			fi
			update_appliance $anappl
		done
		echo " "
	  if [ "${targetAppliances}" = "" ]; then
			echo "`date` Update launched on all appliances. Use \"status\" or \"monitor\" commands to see the progress."
		else
			echo "`date` Update launched on selected appliances: ${targetAppliances}. Use \"status\" or \"monitor\" commands to see the progress."
		fi
		exit 0
		;;
	_internal_update_gwmanager_)
		targetAppliances=$2
		echo "`date` Starting _internal_update_gwmanager_ targetAppliances=${targetAppliances}"
		source /dev/os4k_update_plt_hf_on_sgs_and_entgws.cache
		chunk_size="5M"  # when called from GWM use bigger 5M chunks to get better speed / performance
		curhf=/var/opt/soco2/current_hotfix/PLT-`getydata -v`.tar
		curhf_STMIX=/var/opt/soco2/current_hotfix/PLT-STMIX-`getydata -v`.tar
		curhfshort=${curhf##*/}
		curhfshort_STMIX=${curhf_STMIX##*/}
		pltmd5sum=`md5sum $curhf | awk '{print $1}'`
		pltmd5sum_STMIX=`md5sum ${curhf_STMIX} | awk '{print $1}'`

		for anappl in ${ARR_NeedUpdate[@]}; do
		  if [ "${targetAppliances}" = "" ]; then
				log "No targetAppliances specified, update all"
			else
				if [[ "${targetAppliances}" == *"${anappl}"* ]]; then
					log "target ID ${anappl} selected for update, continue"
				else
					log "target ID ${anappl} not selected, skipping"
					continue
				fi
			fi
			update_appliance $anappl
		done
		
		echo "`date` Ending _internal_update_gwmanager_."
	;;
	_appl_update_)
		shift
		pltmd5sum=$1
		curhfshort=`cat /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf/hfname.txt`
		curhf=/var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf/$curhfshort
		pushd /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf 1>/dev/null 2>&1
		cat PLTHF* > $curhfshort
		rm -f PLTHF*
		popd 1>/dev/null 2>&1
		curmd5=`md5sum $curhf | awk '{print $1}'`
		echo "Found on appliance following HF : $curhfshort with checksum $curmd5"
		if [ "x$pltmd5sum" = "x$curmd5" ]; then
			echo "`date` Checksum is OK. Launching Update in the background ..."
			(
				cd /
				#close all FDs
				pushd /proc/$$/fd 1>/dev/null 2>&1
				for afd in $(ls -1); do
					eval exec $afd'>&-'	
				done
				setsid /bin/bash $0 _lock_ _internal_do_appl_update_ $curhf &
			)
			exit 0
		fi
		echo "`date` ERROR : Checksum $curmd5 is NOT OK, expecting: $pltmd5sum, Aborting ..."
		bash $0 _lock_ _send_notif_ CLEAN
		exit 1
		;;
	_internal_do_appl_update_)
		#relocate HF somewhere else
		mkdir -p /var/opt/Assistant/data/SWS/os4k_platform_hotfix
		rm -f /var/opt/Assistant/data/SWS/os4k_platform_hotfix/PLT*tar
		mv /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf/PLT*tar /var/opt/Assistant/data/SWS/os4k_platform_hotfix
		#update Update Daemon
		cp /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf/swupdated /opt/yaps/script/swupdated
		cp /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf/swupdated /opt/yaps/script/swupdated.old
		chmod 755 /opt/yaps/script/swupdated*
		chmod 755 /var/opt/os4k_update_plt_hf_on_sgs_and_entgws-last-plt-hf/os4k_update_plt_hf_on_sgs_and_entgws
		#update /opt/ha/bin/upgrade_successful.sh to make sure it handles deployment 21 right
		rm -rf /tmp/updsuc.sh.patch.enc /tmp/updsuc.patch
		cat > /tmp/updsuc.sh.patch.enc << '_EOF_UPDSUC_PATCH_'
begin 600 -
M+2TM("]O<'0O:&$O8FEN+W5P9W)A9&5?<W5C8V5S<V9U;"YS:"YB86L),C`Q
M-RTP.2TQ-"`Q,SHT.#HS-BXP,#`P,#`P,#`@*S`S,#`**RLK('5P9W)A9&5?
M<W5C8V5S<V9U;"YS:`DR,#$W+3`Y+3$T(#$S.C0Y.C`T+C`P,#`P,#`P,"`K
M,#,P,`I`0"`M,3,Q+#<@*S$S,2PW($!`"B!R8STP"B`*("-F;W(@16YT1U<@
M:G5S="!C:&5C:R!W96)S97)V:6-E"BUI9B!;("(D9&5P;&]Y;65N="(@/2`B
M-S`B(%T[('1H96X**VEF(%L@(B1D97!L;WEM96YT(B`]("(W,"(@72!\?"!;
M("(D9&5P;&]Y;65N="(@/2`B,C$B(%T[('1H96X*("`@8VAE8VM?<F5S;W5R
M8V4@(G)S8S1K7W=E8G-E<G9I8V4B("1-05A?4U1!4E154%]424U%7U=%0E-%
M4E9)0T4@("`@(`H@("!R8STD/PH@("!I9B!;("(D<F,B(#T@(C$B(%T[('1H
#96X*
`
end
_EOF_UPDSUC_PATCH_
		cat /tmp/updsuc.sh.patch.enc | uudecode > /tmp/updsuc.patch
		patch /opt/ha/bin/upgrade_successful.sh /tmp/updsuc.patch
		#launch update sync
		bash $0 _lock_ _send_notif_ update started at `date`
		update_status_file=/var/log/webservice/update-status.log
		if [ -f /var/opt/soco/stmix ]; then 
			update_status_file=/var/opt/soco/log/update-status.log
		fi
		rm -f ${update_status_file}
		mkdir -p /var/log/webservice/
		/opt/yaps/script/swupdated -extract hfactivate
		#wait max 1 hour for the upgrade log
		secspassed=0
		while [ ! -e ${update_status_file}  ] ; do
			sleep 10
			secspassed=$(($secspassed + 10))
			[ $secspassed -gt 3600 ] && break
		done
		bash $0 _lock_ _send_notif_ update finished at `date`. verifying results ...
		sleep 20
		#no matter which result restart inventory client
		/etc/init.d/inventoryd restart
        #OSFOURK-27479 PRB000076481: PLT-HF update on STMIX is not finished OK from host perspective if the STMIX has to restart during the update process (e.g. due to java update)
		# wait for inventory PING REPLY max 5 minutes after update no matter which is the result
		for i in {1..5}; do
			sleep 60
			/opt/inventory/inventory-client.sh notification OS4K_UPDATE_PLT_HF_ON_SGS_AND_ENTGWS PING 2>&1 | grep REPLY && break
		done
		
		if grep -q "<rc>0<" ${update_status_file}; then
			bash $0 _lock_ _send_notif_ OK
		else
			bash $0 _lock_ _send_notif_ ERROR : failed with reason `grep -q "<rc>" ${update_status_file}`
			sleep 60
			bash $0 _lock_ _send_notif_ CLEAN
		fi
		exit 0
		;;
	_send_notif_)
		shift
		(
			cd /
			#close all FDs
			pushd /proc/$$/fd 1>/dev/null 2>&1
			for afd in $(ls -1); do
				eval exec $afd'>&-'	
			done
			setsid /bin/bash $0 _lock_ _internal_send_notif_ $* &
		)
		exit 0
		;;
	_internal_send_notif_)
		shift
		/opt/inventory/inventory-client.sh notification OS4K_UPDATE_PLT_HF_ON_SGS_AND_ENTGWS $*
		exit 0
		;;
	_inventory_notif_)
		shift
		clientid=$1
		shift
		#shift feature name
		shift
		#alive check that inventory works again
		[ "$1" = "PING" ] && echo REPLY && exit 0
		echo $* > /dev/os4k_update_plt_hf_on_sgs_and_entgws.$clientid.upd_running
		[ "$1" = "OK" ] && rm -f /dev/os4k_update_plt_hf_on_sgs_and_entgws.$clientid.upd_running
		[ "$1" = "CLEAN" ] && rm -f /dev/os4k_update_plt_hf_on_sgs_and_entgws.$clientid.upd_running
		exit 0
		;;
	monitor)
		check_primary
		while [ 1 ]; do
			clear
			echo "`date` StdSG/EntGW Appliances PLT HF Update status ..."
			echo "(output will refresh every 10 seconds)"
			echo " "
			bash $0 _lock_ status && break
			sleep 10
		done
		exit 0
		;;
	*)
        echo "Usage : $0 {status|update [<appliance_ID>[,<appliance_ID>]]|monitor}"
        exit 1
        ;;
esac

exit 0
