Well, what annoyed me in the past was that I had to patch each XenServer patch by patch (no bulk applying) and when used in combination with UCS blades (especially if those have >250GB RAM), it takes ages to keep a pool up-to-date. So I ended up writing yet another script (I know why I hate Citrix XenServer … the XenCenter GUI is lacking sooooo much) which will download new patches from a directory on a HTTP server and then print the lines necessary to apply the patches to all hosts in a pool.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
#!/bin/bash # # Updates a XenServer to the most current release # TMPDIR=$( mktemp -d ) # Figure out the XS release XS_REL="$( grep PRODUCT_VERSION /etc/xensource-inventory | cut -d\' -f2 )" #set -x # Gather the Patchlist/UUID list UUID="$( xe patch-list | grep ^uuid | awk '{ print $5 }' )" XSNAME="$( xe patch-list | grep name-label | awk '{ print $4 }' )" declare -a pUUID=($UUID) declare -a pXS=($XSNAME) count=${#pUUID[@]} count=$((count-1)) for i in $( seq 0 $count ); do echo "${pXS[$i]}: ${pUUID[$i]}" done | sort # Now get the current patchlist PATCH_LIST="$( wget -q -O $TMPDIR/digest http://xen.heimdaheim.de/patches/$XS_REL/digest )" for xs in "${pXS[@]}"; do sed -i "/$xs/d" $TMPDIR/digest done if [ "$( cat $TMPDIR/digest )" != "" ]; then for file in $( cat $TMPDIR/digest ); do wget -q -O $TMPDIR/$file http://xen.heimdaheim.de/patches/$XS_REL/$file done POOL_MASTER="$( xe host-list uuid=$( xe pool-list | grep master | \ awk '{ print $4 }' ) | grep name-label | awk '{ print $4 }' )" while true; do read -p "New XenServer updates found. Should we continue ? (y/n) " yn case $yn in [Yy]* ) break;; [Nn]* ) rm -rf $TMPDIR; exit;; * ) echo "Please answer yes or no.";; esac done # Upload the patchfiles to the pool master for xs in $( grep -v iso $TMPDIR/digest ); do echo -n "Uploading XS patch $xs" xe patch-upload file-name=$TMPDIR/$xs 1>/dev/null echo "..." done UUID="$( xe patch-list | grep ^uuid | awk '{ print $5 }' )" XSNAME="$( xe patch-list | grep name-label | awk '{ print $4 }' )" declare -a PUID=($UUID) declare -a XS=($XSNAME) count=${#PUID[@]} count=$((count-1)) # Write the stuff to a csv, so we can sort it for i in $( seq 0 $count ); do echo "${XS[$i]};${PUID[$i]}" done | sort > $TMPDIR/patchlist.csv echo "The following commands need to be issued on the pool master $POOL_MASTER:" echo for patch in $( cat $TMPDIR/patchlist.csv ); do XS="$( echo $patch | cut -d\; -f1 )" UUID="$( echo $patch | cut -d\; -f2 )" for host in $( xe host-list | grep ^uuid | awk '{ print $5 }' ); do echo "xe patch-apply host-uuid=$host uuid=${UUID}" done echo done if [ "$( grep iso $TMPDIR/digest )" != "" ] ; then echo echo "The following commands need to be issued on each host individually:" for xs in $( grep iso $TMPDIR/digest ); do cp -f $TMPDIR/$xs /root echo "$xs needs to be installed manually." echo "This can be achieved with the following commands:" echo " mount -o loop /root/$xs /mnt" echo " cd /mnt" echo " ./install.sh" echo " cd" echo " umount /mnt" done fi else echo "No updates found!" fi rm -rf $TMPDIR |
There’s just a little caveat (not because of the script – but of XenServer’s design): if you switch the pool master before the updates are applied to all host, you’ll need to manually delete the patches from the pool (xe patch-delete) and rerun the script on the new pool master …