File switch-enterprise-nu-mirror of Package yup

#!/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
# 19 Sep 2007 : v0.28
#               Change the way we check if zmd has settled (Bug 309861). Now we
#               check for pending services rather than # of available updates, since an 
#               up-to-date system would fail the first of these checks.
#               Added more checks on whether zmd has settled. Misc cosmetics.
#               Improved handling of rug errors in stage 5 and 6
# 02 Oct 2007 : v0.33
#               By default update the SDK if it is installed unless $UPDATE_SDK = NO
#               Verify existence of the various repositories (currently only 
#               checks for nfs and http based repos) and exit on errors
#               prior to adding services. Misc cosmetics.

#
# !!!!! 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=""

# This script will check if the SLE 10 SDK is installed and upgrade it 
# assuming that updates for the SLE-10-SDK-* are also mirrored with
# yup and exist in the update repo tree of SLE (for naming reasons).
# If you for some reason do NOT want to upgrade the SDK along with the OS
# (not having the SDK at the same level as the OS can lead to problems)
# you must change
# UPDATE_SDK to NO.
UPDATE_SDK="YES" 

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


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

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

# Functions start
is_anything_pending ()
{
# Check if ZMD has any services in pending state
i=0
SOMETHING_IS_PENDING="YES"
while [[ $i -lt 6 ]] ; do
  if ! [[ `rug sl | grep -i Pending` ]] ; then
    SOMETHING_IS_PENDING="NO"
    break
  else
    echo "Waiting for services to get out of pending state"
    sleep 30
  fi
  ((i++))
done
if [[ $SOMETHING_IS_PENDING = "YES" ]] ; then
  echo "ZMD does not settle from pending state - exiting..."
  exit 2
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
# Since we may get "An instance of ZMD is already running" although 
# /etc/init.d/zmd status reports it as unused, we add yet another delay
sleep 30

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

time_stamp ()
{
# Create time stamp in log file
echo "------------------------------------------------------------------- "
date
echo "------------------------------------------------------------------- "
}

check_if_repo_exists ()
{
# If the file repodata/repomd.xml file exists in a service URL
# we consider the repository to be existing
# Unfortunately we currently only support this check for http-based
# repository access
if [[ $REPO_PROTOCOL == "http" ]] ; then
  curl -f -o /dev/null $REPO"repodata/repomd.xml" 1>/dev/null 2>&1
  if [ $? != 0 ] ;then
    repo_error
    exit 5
  fi
elif [[ $REPO_PROTOCOL = "nfs" ]] ; then
  REPO_SHARE=`echo $REPO | awk -F ":" '{print $2}' \
  | sed -e "s/\/\///g" | sed -e "s/^$REPO_HOST//g"`
  mount -t nfs -o ro $REPO_HOST":"$REPO_SHARE $TMPDIR
  MOUNT_RC=$?
  if [ $MOUNT_RC != 0 ] ;then
    repo_error
    exit 5
  fi
  if ! test -r $TMPDIR"/repodata/repomd.xml" ; then
    repo_error
    umount $TMPDIR
    exit 5
  fi
  umount $TMPDIR
elif [[ $REPO_PROTOCOL = "https" ]] ; then
  # Feel free to implement checks for this protocol
  echo "Repo existence not implemented for $REPO_PROTOCOL"
fi
}

repo_error ()
{
  echo "The following repository does not exist or is inconsistent :" 
  echo "The following repository does not exist or is inconsistent :" >&2
  echo ">>>>> "$REPO "<<<<<"
  echo ">>>>> "$REPO "<<<<<" >&2
  echo ; echo "Aborting execution ..."
  echo ; echo "Aborting execution ..." >&2
}
# Functions end

time_stamp
# Initialize variable(s)
SDK_10_0_INSTALLED="NO"
SCRIPTNAME=`basename $0`
TMPDIR=/tmp/$SCRIPTNAME.$$

# Detect product (SLES/SLED)
if grep -i "suse linux enterprise desktop" /etc/SuSE-release >/dev/null 2>&1 ; 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 >/dev/null 2>&1 ; then
    ARCH="i586"
  elif grep -i "x86_64" /etc/SuSE-release >/dev/null 2>&1 ; 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 \/$ >/dev/null 2>&1 ; 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"

# Determine access protocol to update repository
case `echo $UPDATE_ROOT | awk -F ":" '{print $1}'` in
  http  )  REPO_PROTOCOL="http" ;;
  https )  REPO_PROTOCOL="https" ;;
  nfs   )  REPO_PROTOCOL="nfs" 
           REPO_HOST=`echo $UPDATE_ROOT | awk -F ":" '{print $2}' \
           | awk -F "/" '{print $3}'`
           test -w $TMPDIR || mkdir $TMPDIR ;;
esac

# Verify existence of the repositories
REPO=$OLD_UPDATES_SERVICE_URL
check_if_repo_exists
REPO=$NEW_SP_ONLINE_URL
check_if_repo_exists
REPO=$NEW_SP_UPDATES_URL
check_if_repo_exists

# Check if the machine is indeed already subscribed to $OLD_UPDATES_SERVICE_URL
# If not, then we do it
SERVICE_OR_CAT_CHANGED="NO"
SUBSCRIBED_TO_OLD_SERVICE="NO"
i=0
while [[ $i -lt 4 ]] ; do
  OLD_CATALOG=''
  # Handle missing trailing slash in existing service URL
  TMP_OLD_URL=`echo $OLD_UPDATES_SERVICE_URL | sed -e "s/\/$//g"`
  OLD_CATALOG=$(rug --no-abbrev sl |grep -i -F "active" | grep -F "$TMP_OLD_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 ..."
      SERVICE_OR_CAT_CHANGED="YES"
      rug sub $OLD_CATALOG
    fi
  else
      echo "Old update service not in the service list - adding it ..."
      SERVICE_OR_CAT_CHANGED="YES"
      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 3
fi

# SDK
if [[ $UPDATE_SDK = "YES" ]] ; then
  # Check if the SDK product is installed
  QUERYPOOL="/usr/lib/zmd/query-pool"
  if [ ! -x $QUERYPOOL ]; then
    QUERYPOOL="/usr/lib64/zmd/query-pool"
    if [ ! -x $QUERYPOOL ]; then
        # query-pool not found
        echo "query-pool command not found" >&2
        echo "query-pool command not found"
        exit 6;
    fi
  fi
   if [[ `/usr/lib/zmd/query-pool products @system \
   | grep "SUSE-Linux-Enterprise-SDK" | grep "10-0"` ]] ; then
     SDK_10_0_INSTALLED="YES"
  fi
  if [[ $SDK_10_0_INSTALLED = "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"
    # Verify existence of the repositories
    REPO=$OLD_SDK_SERVICE_URL
    check_if_repo_exists
    REPO=$NEW_SDK_SP_ONLINE_URL
    check_if_repo_exists
    REPO=$NEW_SDK_SP_UPDATES_URL
    check_if_repo_exists
    # 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=''
      # Handle missing trailing slash in existing service URL
      TMP_OLD_URL=`echo $OLD_SDK_SERVICE_URL | sed -e "s/\/$//g"`
      OLD_SDK_CATALOG=$(rug --no-abbrev sl |grep -i -F "active" | grep -F "$TMP_OLD_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 ..."
          SERVICE_OR_CAT_CHANGED="YES"
          rug sub $OLD_SDK_CATALOG
        fi
      else
          echo "Old SDK update service not in the service list - adding it ..."
          SERVICE_OR_CAT_CHANGED="YES"
          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 4
    fi
  fi
fi
# SDK end

time_stamp

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

# In case we added a service - check if we are cool
if [[ $SERVICE_OR_CAT_CHANGED == 'YES' ]] ; then
  is_anything_pending
fi

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 [[ $UPDATE_SDK = "YES" ]] && [[ $SDK_10_0_INSTALLED = "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
is_anything_pending

echo "Installing updates - stage 1 of 6 - "$PRODUCT"p1o-liby2util-devel"
rug in -y -t patch ${PRODUCT}p1o-liby2util-devel
# The above patch requires 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 [[ $UPDATE_SDK = "YES" ]] && [[ $SDK_10_0_INSTALLED = "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 [[ $UPDATE_SDK = "YES" ]] && [[ $SDK_10_0_INSTALLED = "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
is_anything_pending

# 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
is_anything_pending

echo "Installing updates - stage 5 of 6 - ${PRODUCT}p1-perl-Bootloader"
rug in -y -t patch ${PRODUCT}p1-perl-Bootloader
# Sometimes rug fails with weird errors at this point, so we
# need to check on the returncode and restart zmd if it is non-zero
# Sorry about the clumsy coding
if [ $? -ne 0 ] ; then
  echo "Stage 5 failed so we restart zmd and try once more - only once"
  restart_zmd_firmly
  time_stamp
  sleep 300
  is_anything_pending
  echo "Installing updates - stage 5 of 6 - ${PRODUCT}p1-perl-Bootloader - second try..."
  rug in -y -t patch ${PRODUCT}p1-perl-Bootloader
fi

echo "Installing updates - stage 6 of 6 - post-SP1 updates"
rug up -y --agree-to-third-party-licences
# Sometimes rug fails with weird errors at this point, so we
# need to check on the returncode and restart zmd if it is non-zero
# Sorry about the clumsy coding
if [ $? -ne 0 ] ; then
  echo "Stage 6 failed so we restart zmd and try once more - only once"
  restart_zmd_firmly
  time_stamp
  sleep 300
  is_anything_pending
  echo "Installing updates - stage 6 of 6 - post-SP1 updates - second try..."
  rug up -y --agree-to-third-party-licences
fi
echo "Done."

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

# Clean up
test -w $TMPDIR && rm -r $TMPDIR ;
# reboot
openSUSE Build Service is sponsored by