#!/bin/bash
export LANG=C

# Script to upgrade a host, which is subscribed to an enterprise-internal
# mirror of the Novell update service, to SLE?10 SP1.
# It is assumed that the update tree has the structure that yup builds.

# 05 Jul 2007 Andreas Taschner
#
# Changelog :
# 01 Aug 2007 : Fixed typos in info messages
#               More informational messages in log about progress
#               Eliminate "...failed" messages on console when shutting down ZMD
#               Proactively kill zen-updater desktop task as it sometimes gets 
#               confused and abends
# 03 Aug 2007 : Add support for SDK
# 30 Aug 2007 : Add explicit installation of product-sdk10-sp1 patch to 
#               to ensure the product verion of SDK gets updated
# 31 Aug 2007 : Unsubscribe from the SLE?10-SP1-Online catalog after upgrade, 
#               but keep it in the list to preserve virtual SP1 installation source
# 05 Sep 2007 : Minimized the need for manual intervention to customize the script
#               Add extra restart of ZMD after stage 4
# 06 Sep 2007 : Syntax-check of $UPDATE_ROOT

#
# !!!!! M A N U A L   I N T E R V E N T I O N   R E Q U I R E D !!!!!
#
# Change at least the UPDATE_ROOT parameter below to fit the setup in your environment
# 

echo "ADAPT THE CONFIGURATION BELOW THEN DELETE THIS AND THE NEXT LINE"
exit 1

# Specify the URL of the top of your update repository tree, 
# eg. http://your.server.example.com/SLE10-YUP/
# Remember the trailing slash !
UPDATE_ROOT=""

# If architecture is different from i586 or x86_64, you must set $ARCH
ARCH=""

# If you are subscribed to a mirror of the SDK updates, then change 
# SUBSCRIBED_TO_SDK_REPO to YES.
# It is assumed that updates for the SDK is a subtree created by
# yup and exist in the update repo tree of SLE (for naming reasons)
SUBSCRIBED_TO_SDK_REPO="NO"

#####################################################
# No need to change anything below this line        #
#####################################################


if [ `id -u` != 0 ]; then
    echo "You need to be root to run this script"
    exit 1
fi

# Log file
exec >> /var/log/YaST2/switchUpdateServer.log

# Functions start
check_for_updates ()
{
# Check if ZMD has landed on its feet and sees updates
i=0
ZMD_FOUND_UPDATES="NO"
while [[ $i -lt 4 ]] ; do
  NO_OF_UPDATES=`rug lu | wc -l | awk 'BEGIN{FS=" "}{print $1}'`
  if [[ $NO_OF_UPDATES -gt 5 ]] ; then
    ZMD_FOUND_UPDATES="YES"
    break
  else
    echo "Waiting for ZMD to refresh update list"
    sleep 15
  fi
  ((i++))
done
if [[ $ZMD_FOUND_UPDATES = "NO" ]] ; then
  echo "ZMD not able to find updates in catalog - exiting"
  exit 1
fi
}

restart_zmd_firmly ()
{
# It is a cumbersome process to choke ZMD completely ...
ZMD_STILL_RUNNING="YES"
/usr/sbin/rczmd stop 2>&1
i=0
while [[ $i -lt 10 ]] ; do
  /usr/sbin/rczmd status
  if [[ $? -eq 3 ]] ; then
    ZMD_STILL_RUNNING="NO"
    break
  else
    echo "Waiting for ZMD to terminate properly"
    sleep 20
    rczmd stop 2>&1
  fi
  ((i++))
done
if [[ $ZMD_STILL_RUNNING = "YES" ]] ; then
  echo "Pulling the plug on ZMD"
  killall -9 zmd
  sleep 10
fi

echo "Restarting ZMD"
rczmd start
# Wait for ZMD to calm down
sleep 60
check_for_updates
}

time_stamp ()
{
echo "------------------------------------------------------------------- "
date
echo "------------------------------------------------------------------- "
}
# Functions end

time_stamp

# Detect product (SLES/SLED)
if grep -i "suse linux enterprise desktop" /etc/SuSE-release ; then
  PRODUCT="sled"
  PRODUCT_CAPS="SLED"
else
  PRODUCT="sles"
  PRODUCT_CAPS="SLES"
fi

# Detect architechture (i586 or x86_64 unless specified in $ARCH)
if [[ $ARCH = "" ]]; then 
  if grep -i "i586" /etc/SuSE-release ; then
    ARCH="i586"
  elif grep -i "x86_64" /etc/SuSE-release ; then
    ARCH="x86_64"
  fi
fi

# Construct the service URLs and names
# Add trailing slash to $UPDATE_ROOT in case forgotten
if ! echo $UPDATE_ROOT| grep \/$ ; then
 UPDATE_ROOT=$UPDATE_ROOT"/"
fi
OLD_UPDATES_SERVICE_URL=$UPDATE_ROOT$PRODUCT_CAPS"10-Updates/"$PRODUCT"-10-"$ARCH"/"
NEW_SP_ONLINE_URL=$UPDATE_ROOT$PRODUCT_CAPS"10-SP1-Online/"$PRODUCT"-10-"$ARCH"/"
NEW_SP_ONLINE_NAME=$PRODUCT_CAPS"10-SP1-Online"
NEW_SP_UPDATES_URL=$UPDATE_ROOT$PRODUCT_CAPS"10-SP1-Updates/"$PRODUCT"-10-"$ARCH"/"
NEW_SP_UPDATES_NAME=$PRODUCT_CAPS"10-SP1-Updates"

# Check if the machine is indeed already subscribed to $OLD_UPDATES_SERVICE_URL
# If not, then we do it
SUBSCRIBED_TO_OLD_SERVICE="NO"
i=0
while [[ $i -lt 4 ]] ; do
  OLD_CATALOG=''
  OLD_CATALOG=$(rug --no-abbrev sl |grep -i -F "active" | grep -F "$OLD_UPDATES_SERVICE_URL" | \
          awk -F "|" '{print $4}' | sed 's/ //g')
  if [[ $OLD_CATALOG != '' ]] ; then
    rug ca |grep -i "yes" | grep -F "$OLD_CATALOG"
    if [ $? -eq 0 ] ; then
      SUBSCRIBED_TO_OLD_SERVICE="YES"
      break
    else
      echo "Not subscribed to the old update service catalog - subscribing ..."
      rug sub $OLD_CATALOG
    fi
  else
      echo "Old update service not in the service list - adding it ..."
      rug sa -t zypp $OLD_UPDATES_SERVICE_URL SLEx10-Updates
  fi
  ((i++))
done
if [[ $SUBSCRIBED_TO_OLD_SERVICE = "NO" ]] ; then
  echo "Not able to subscribe to old update service - exiting"
  exit 2
fi

# SDK
if [[ $SUBSCRIBED_TO_SDK_REPO = "YES" ]] ; then
  # Construct the service URLs and names
  OLD_SDK_SERVICE_URL=$UPDATE_ROOT"SLE10-SDK-Updates/sles-10-"$ARCH"/"
  NEW_SDK_SP_ONLINE_URL=$UPDATE_ROOT"SLE10-SDK-SP1-Online/sles-10-"$ARCH"/"
  NEW_SDK_SP_ONLINE_NAME="SLE10-SDK-SP1-Online"
  NEW_SDK_SP_UPDATES_URL=$UPDATE_ROOT"SLE10-SDK-SP1-Updates/sles-10-"$ARCH"/"
  NEW_SDK_SP_UPDATES_NAME="SLE10-SDK-SP1-Updates"
  # Check if the machine is indeed already subscribed to $OLD_SDK_SERVICE_URL
  # If not, then we do it
  SUBSCRIBED_TO_OLD_SERVICE="NO"
  i=0
  while [[ $i -lt 4 ]] ; do
    OLD_SDK_CATALOG=''
    OLD_SDK_CATALOG=$(rug --no-abbrev sl |grep -i -F "active" | grep -F "$OLD_SDK_SERVICE_URL" | \
            awk -F "|" '{print $4}' | sed 's/ //g')
    if [[ $OLD_SDK_CATALOG != '' ]] ; then
      rug ca |grep -i "yes" | grep -F "$OLD_SDK_CATALOG"
      if [ $? -eq 0 ] ; then
        SUBSCRIBED_TO_OLD_SERVICE="YES"
        break
      else
        echo "Not subscribed to the old SDK update service catalog - subscribing ..."
        rug sub $OLD_SDK_CATALOG
      fi
    else
        echo "Old SDK update service not in the service list - adding it ..."
        rug sa -t zypp $OLD_SDK_SERVICE_URL SDK10-Updates
    fi
    ((i++))
  done
  if [[ $SUBSCRIBED_TO_OLD_SERVICE = "NO" ]] ; then
    echo "Not able to subscribe to old SDK update service - exiting"
    exit 2
  fi
fi
# SDK end

time_stamp

# Kill zen-updater to prevent ugly pop-ups on desktop when it abends
killall -9 zen-updater

check_for_updates

echo "Adding SP migration updates service"
echo "Adding $NEW_SP_ONLINE_NAME service"
rug service-add -t ZYPP $NEW_SP_ONLINE_URL $NEW_SP_ONLINE_NAME
echo "Subscribing to the catalog..."
rug subscribe $NEW_SP_ONLINE_NAME

# SDK
if [[ $SUBSCRIBED_TO_SDK_REPO = "YES" ]] ; then
  sleep 15
  echo "Adding SDK SP migration updates service"
  rug service-add -t ZYPP $NEW_SDK_SP_ONLINE_URL $NEW_SDK_SP_ONLINE_NAME
  echo "Subscribing to the catalog..."
  rug subscribe $NEW_SDK_SP_ONLINE_NAME
fi
# SDK end

# wait for settle
sleep 15

check_for_updates
echo "Installing updates - stage 1 of 6 - "$PRODUCT"p1o-liby2util-devel"
rug in -y -t patch ${PRODUCT}p1o-liby2util-devel
# The above patch requeres zmd to be restarted
restart_zmd_firmly
time_stamp

# Perform update to SP1 and then add the SP1 product into /var/lib/zypp 

echo "Installing the GA - SP1 migration updates."

if [ $PRODUCT == "sled" ] ; then
	# To force upgrade of gnomeeting to ekiga
        echo "Replacing gnomemeeting with ekiga"
	rug in -y -t patch ${PRODUCT}p1o-ekiga
fi
echo "Installing updates - stage 2 of 6"
rug up -y --agree-to-third-party-licences
time_stamp

echo "Installing updates - stage 3 of 6 - Updating product record(s)"
rug in -y --agree-to-third-party-licences -t patch product-${PRODUCT}10-sp1
time_stamp

# SDK
if [[ $SUBSCRIBED_TO_SDK_REPO = "YES" ]] ; then
  rug in -y -t patch product-sdk10-sp1
fi
# SDK end

# Disable suse_register at every boot
test -d /var/lib/suseRegister || mkdir /var/lib/suseRegister
touch /var/lib/suseRegister/neverRegisterOnBoot

# Clean up services and catalogs
echo "Deleting old updates service"
rug service-delete $OLD_UPDATES_SERVICE_URL
echo "Unsubscribing from SP migration updates catalog"
# We still need the $NEW_SP_ONLINE_NAME catalog for the inst source,
# so we only unsubscribe 
rug unsubscribe $NEW_SP_ONLINE_NAME
echo "Adding $NEW_SP_UPDATE_NAME service"
rug service-add -t ZYPP $NEW_SP_UPDATES_URL $NEW_SP_UPDATES_NAME
echo "Subscribing to the catalog..."
rug subscribe $NEW_SP_UPDATES_NAME

# SDK
if [[ $SUBSCRIBED_TO_SDK_REPO = "YES" ]] ; then
  sleep 60
  echo "Deleting old SDK updates service"
  rug service-delete $OLD_SDK_SERVICE_URL
  echo "Unsubscribing from SDK SP migration updates catalog"
  # We still need the $NEW_SDK_SP_ONLINE_NAME catalog for the inst source,
  # so we only unsubscribe 
  rug unsubscribe $NEW_SDK_SP_ONLINE_NAME
  echo "Adding $NEW_SDK_SP_UPDATES_NAME service"
  rug service-add -t ZYPP $NEW_SDK_SP_UPDATES_URL $NEW_SDK_SP_UPDATES_NAME
  echo "Subscribing to the catalog..."
  rug subscribe $NEW_SDK_SP_UPDATES_NAME
fi
# SDK end

# Wait for ZMD to calm down
sleep 60

# These are post-sp1 but still necessary for some fixes...
echo "Installing updates - stage 4 of 6 - ${PRODUCT}p1-yast2-online-update"
rug in -y -t patch ${PRODUCT}p1-yast2-online-update

# Since zmd periodically chokes here we need to restart and wait for
# a really long time for it to get sober
restart_zmd_firmly
time_stamp
sleep 240

echo "Installing updates - stage 5 of 6 - ${PRODUCT}p1-perl-Bootloader"
rug in -y -t patch ${PRODUCT}p1-perl-Bootloader

echo "Installing updates - stage 6 of 6 - post-SP1 updates"
rug up -y --agree-to-third-party-licences
echo "Done."

echo "You should reboot the machine now since the kernel has been updated."
time_stamp

# reboot
