#!/bin/bash
#*****************************************************************************
#*****************************************************************************
# This script is not meant to be run standalone. It is always sourced by the
# master install script "sw"
#*****************************************************************************
#*****************************************************************************
(return 0 2>/dev/null) && sourced=1 || sourced=0
VMNG_CONFIG_LOC="/opt/web-app/etc"
VMNG_DST_LOC="/opt/data"
VMNG_EXTRA_PKGS="extra-packages.tar.gz"
VMNG_UPGRADE_CONTEXT="upgrade-context.json"
D_VMNG_EXTRA_PKGS="${VMNG_DST_LOC}/extra-packages"
VMNG_TOP_TEMP="${VMNG_DST_LOC}/temp/"
VMNG_TEMP="${VMNG_TOP_TEMP}/vmng/"
PYTHON2="/usr/bin/python2"
PYTHON3="/usr/bin/python3"
check_upgrade_context=1
sw_check_upgrade_context() {
check_upgrade_context=1
major_ver=$(cat /etc/version | cut -d "." -f 1)
minor_ver=$(cat /etc/version | cut -d "." -f 2)
if [ "$major_ver" -eq 20 ] && [ "$minor_ver" -ge 6 ]; then
check_upgrade_context=0
fi
if [ "$major_ver" -gt 20 ]; then
check_upgrade_context=0
fi
sw_log "${FUNCNAME[0]}: check_upgrade_context = $check_upgrade_context"
}
sw_hook_vmng_install() {
local ver=$1
# signature has been validated.
# copy and extract extra-packages to the right path in /opt/data/
local l_dest_dir="${D_VMNG_EXTRA_PKGS}/${ver}/"
mkdir -p "$l_dest_dir"
tar xzf $VMNG_TEMP/${VMNG_EXTRA_PKGS} -C "$l_dest_dir" --strip 1
#store the original tar.gz for sw reset case
mv $VMNG_TEMP/${VMNG_EXTRA_PKGS} $l_dest_dir
sw_log "${FUNCNAME[0]}: Extracted contents of all ${VMNG_EXTRA_PKGS} to ${l_dest_dir}"
rm -rf ${VMNG_TEMP}
# Opportunistically call to prepare new version from the vantage point of the current version.
# i.e. Don't die.
sw_hook_prepare ${ver}
return 0
}
# This as a sub-install script and the purpose of this script file is to
# complement/replace the master install script operations.
# During install or remove, if there are some behavioral changes to apply we do
# it in this sw_hook.sh script.
#
# These functions provide a hook into sw for install, remove operations
# The hook can do one of the following (& specific return code implies specific
# things as described below):
#
# 0. No-OP (return 0)
# - For eg. Nothing specific to be done. The master install script "sw"
# will continue with everything as is including untar for install and
# remove all for remove case
#
# 101. Replace untar step in the operation so that personality specific things
# can be done (return 101). In case of remove it could be additional removal from
# additional partitions.
# - For eg. in an install operation untar step alone is replaced and the steps
# before and after are left as is. So "sw" will continue but assumes that
# untar is done
#
# 102. Substitute the whole operation for a specific personality (return 102) from untar step
# - For eg. takeover the complete install operation
#
# -1. "Hell broke lose" so die...
#
sw_hook_extract()
{
local d_temp_dir=$1 # destination dir where the img will be extracted
local l_img=$2 # complete tar.gz
local l_tar_tmp_file=$3 #contents of tar file
local size=0
local total_space=$(BLOCKSIZE=1 df "$d_temp_dir" | sed 's/^[^ ]* *\([0-9]*\) .*$/\1/')
local avail_space=$(BLOCKSIZE=1 df "$d_temp_dir" | sed 's/^[^ ]* *[0-9]* *[0-9]* *\([0-9]*\) .*$/\1/')
local one_pct=$((${total_space} / 100))
local max_size=$((${avail_space} - ${one_pct}))
for val in $(sed 's/^[^ ]* [^ ]* *\([0-9]*\) .*$/\1/' "${l_tar_tmp_file}"); do
size=$(($size + $val))
done
sw_log "${FUNCNAME[0]}: Checking size ${size} against maxsize ${max_size}"
if [ ${size} -gt ${max_size} ]; then
sw_log "Error: Insufficient space in ${d_temp_dir} for ${l_img} to use. Make available ${size} bytes free before installation."
die "Error: Disk space is not enough to install new image. Please set current software version as the default version and remove unused software versions first"
fi
if [ "x$sw_current_personality" == "xvmanage" ] && [[ ! -f /opt/web-app/etc/skip_downgrade_check ]]; then
five_gb=$((5*1024*1024*1024))
opt_data_sizeK=$(df --output=avail /opt/data/ | tail -1)
opt_data_size=$((opt_data_sizeK * 1024))
required_avail_space=$((${size} + ${five_gb}))
if [ ${required_avail_space} -gt ${max_size} ]; then
sw_log "required_avail_space is ${required_avail_space} and max_size is ${max_size}"
sw_log "Error: Insufficient space in /opt/data for ${l_img} to use. Make available ${required_avail_space} bytes in /opt/data free before installation."
die "Error: /opt/data space is not enough to install new image. Please set current software version as the default version and remove unused software versions first"
fi
fi
mkdir "$d_temp_dir"/root
omask=$(umask)
umask 0077
tar --no-same-permissions -oxzf "$l_img" -C "$d_temp_dir"/root
l_ret_code=$?
if [ $l_ret_code -eq 0 ]; then
sw_log "${FUNCNAME[0]}: untar of image $l_img to $d_temp_dir successful"
(cd "$d_temp_dir"/root && md5sum -c --quiet md5sum) || die "${FUNCNAME[0]}: Incorrect md5sum of image"
umask "$omask"
else
umask "$omask"
rm -rf "$d_temp_dir"/root
die "Error: untar of image $l_img to $d_temp_dir failed"
fi
}
sw_hook_vmng_move_and_validate()
{
local l_tar_tmp_file="$1"
local l_found_extra=$(grep ${VMNG_EXTRA_PKGS} "${l_tar_tmp_file}" | awk '{print $6}')
if [ "x$l_found_extra" == "x${VMNG_EXTRA_PKGS}" ]; then
sw_log "${FUNCNAME[0]}: Found the vmanage extra packages: $l_found_extra, extracting it"
#Now do signature verification on the file
validate $VMNG_TOP_TEMP/root "$l_found_extra"
ret=$?
if [ $ret -eq 0 ]; then
sw_log "${FUNCNAME[0]}: Signature validation of ${VMNG_EXTRA} successful - ${VMNG_TEMP} ${l_found_extra}"
mkdir -p $VMNG_TEMP
mv $VMNG_TOP_TEMP/root/${VMNG_EXTRA_PKGS} $VMNG_TEMP
else
sw_log "${FUNCNAME[0]}: Error: signature validation of ${VMNG_EXTRA} failed - ${VMNG_TEMP} ${l_found_extra}"
return 1
fi
fi
}
sw_hook_install()
{
# arg1 - The file that has the tar ball contents listing
# arg2 - The kinda operation install/verify/verify_vmanage
# arg3 - The tar file extract destination directory
# arg4 - The actuall tar ball image file
if [ "x$sw_current_personality" == "xvmanage" ]; then
# vmanage specific install stuff goes in here
sw_log "$(basename "$0"): $@ - vmanage sw install case"
local l_tar_tmp_file=$1
local l_dest_dir=$3
local l_img=$4
rm -rf ${VMNG_TOP_TEMP}
mkdir -p ${VMNG_TOP_TEMP}
sw_hook_extract ${VMNG_TOP_TEMP} "$l_img" "$l_tar_tmp_file"
#vmanage moves its contents and sig and cert files to vmanage specific temp file
sw_hook_vmng_move_and_validate "$l_tar_tmp_file"
ret=$?
if [ $ret -eq 0 ]; then
sw_log "$(basename "$0"): vmanage validation successful"
else
sw_log "$(basename "$0"): vmanage validation failed"
rm -rf ${VMNG_TOP_TEMP}
die "Error: signature validation of vmangage component failed"
fi
mount -o ro,loop ${VMNG_TOP_TEMP}/root/rootfs.img /mnt
new_version=$(cat /mnt/etc/version)
umount /mnt
#Check if we have enough space in /boot to fit in the new image contents
#max_size calculation is already done in "sw" so leverage that variable
#to avoid confusion copying that to a local var
local l_max_size=${max_size}
local l_size=$(du -s --block-size=1 ${VMNG_TOP_TEMP}/root/ | awk '{prin