1 #!/bin/ksh93
   2 #
   3 #
   4 # This file and its contents are supplied under the terms of the
   5 # Common Development and Distribution License ("CDDL"), version 1.0.
   6 # You may only use this file in accordance with the terms of version
   7 # 1.0 of the CDDL.
   8 #
   9 # A full copy of the text of the CDDL should have accompanied this
  10 # source.  A copy of the CDDL is also available via the Internet at
  11 # http://www.illumos.org/license/CDDL.
  12 #
  13 #
  14 # Copyright 2014 Nexenta Systems, Inc. All rights reserved.
  15 #
  16 # Version 2.1
  17 
  18 typeset REPODIR=
  19 typeset TARGETBE=
  20 typeset TARGETMOUNT=
  21 typeset FULLPATH=
  22 typeset DEBPKGS=
  23 typeset -i PKGNUM=0
  24 typeset -i CONSOLE=0
  25 
  26 typeset TMPDIR=/tmp/apt.$$
  27 typeset LOG=/root/upgrade.log.$$
  28 
  29 AWK=/usr/bin/awk
  30 BEADM=/usr/sbin/beadm
  31 MKDIR=/usr/bin/mkdir
  32 BOOTADM=/usr/sbin/bootadm
  33 ECHO=/usr/bin/echo
  34 CAT=/usr/bin/cat
  35 CP=/usr/bin/cp
  36 GREP=/usr/bin/grep
  37 MV=/usr/bin/mv
  38 APTGET=/usr/bin/apt-get
  39 TOUCH=/usr/bin/touch
  40 SED=/usr/bin/sed
  41 
  42 usage()
  43 {
  44         ${ECHO} "Usage:"
  45         ${ECHO} "       $0 -t [BE name] -d [path to local APT] [-v]"
  46         ${ECHO}
  47         ${ECHO} "Example:"
  48         ${ECHO} "       $0 -t rootfs-nmu-\`date +%Y-%m-%d\` -d \$PWD/packages/i386/apt"
  49         exit 0
  50 }
  51 
  52 logcmd() {
  53         if (( CONSOLE == 0 )); then
  54                 ${ECHO} CMD: "$@" >> ${LOG}
  55                 "$@" >> ${LOG} 2>&1
  56         else
  57                 ${ECHO} CMD: "$@" | tee ${LOG}
  58                 "$@" | tee ${LOG} 2>&1
  59         fi
  60 }
  61 
  62 logmsg() {
  63         ${ECHO} "$@" >> ${LOG}
  64         ${ECHO} "$@"
  65 }
  66 
  67 logerr() {
  68         logmsg $@
  69         exit 1
  70 }
  71 
  72 logerrdie() {
  73         logmsg $@
  74         fullabort
  75 }
  76 
  77 fullabort() {
  78         logmsg "\nAborting. See ${LOG} for details\n"
  79         ${ECHO} yes | ${BEADM} destroy -f ${TARGETBE} >/dev/null 2>&1
  80         exit 1
  81 }
  82 
  83 get_clones_dev()
  84 {
  85     typeset TMP=$1
  86     typeset CLONEPKGS
  87     DEVPKGS=$(ls ${TMP}/var/lib/dpkg/info/*.postinst)
  88     for DEVPKG in $DEVPKGS
  89     do
  90         CLONE=$(cat ${DEVPKG} | ${GREP} update_drv | ${GREP} clone | wc -l)
  91         if [[ ${CLONE} > 0 ]]; then
  92                 DEVPKG=$(basename ${DEVPKG} | ${SED} -e 's/\..*$//')
  93                 CLONEPKGS="${CLONEPKGS} ${DEVPKG}"
  94         fi
  95     done
  96     echo ${CLONEPKGS}
  97 }
  98 
  99 rm_package_name()
 100 {
 101     typeset RPKG=$1
 102     shift
 103     typeset RPKGS=$*
 104     typeset FOUND=
 105     for p in ${RPKGS}
 106     do
 107         if [[ ${p} != ${RPKG} ]]; then
 108                 FOUND="${FOUND} $p"
 109         fi
 110     done
 111     echo ${FOUND}
 112 }
 113 
 114 
 115 ###### main ######
 116 
 117 while getopts :d:t:v i ; do
 118         case $i in
 119         d)
 120                 REPODIR="${OPTARG}"
 121                 ;;
 122         t)
 123                 TARGETBE="${OPTARG}"
 124                 ;;
 125         v)
 126                 CONSOLE=1
 127                 ;;
 128         *)
 129                 usage >&2
 130         esac
 131 done
 132 shift $((OPTIND - 1))
 133 
 134 if (( $# != 0 )); then
 135         usage >&2
 136 fi
 137 
 138 [[ -z "${TARGETBE}" ]] && usage >&2
 139 [[ -z "${REPODIR}" ]] && usage >&2
 140 
 141 FULLPATH=$(echo ${REPODIR} | ${GREP} '^\/')
 142 
 143 if [[ -z "${FULLPATH}" ]]; then
 144         logerr "Please use full path for -d option"
 145 fi
 146 
 147 if [[ ! -f ${REPODIR}/conf/distributions ]]; then
 148         logerr "Local APT unavailable, please check your path to repo dir: '${REPODIR}'"
 149 fi
 150 
 151 ${ECHO} "$(basename $0) started at $(date)" > $LOG
 152 
 153 logmsg "===== Creating BE ${TARGETBE}"
 154 logcmd ${MKDIR} -p ${TMPDIR}
 155 logcmd ${BEADM} create ${TARGETBE} || logerr "Cannot create BE"
 156 logcmd ${BEADM} mount ${TARGETBE} ${TMPDIR} || legerrdie "Cannot mount BE"
 157 
 158 logmsg "===== Setting apt sources"
 159 logcmd ${CP} /etc/apt/sources.list /etc/apt/sources.list.saved || logerrdie "Can't save apt sources"
 160 ${ECHO} "deb file://${REPODIR} nza-kernel main" > /etc/apt/sources.list || logerrdie "Can't apply local apt url to sources"
 161 logcmd ${CP} -f /etc/apt/sources.list ${TMPDIR}/etc/apt/sources.list || logerrdie "Can't copy new apt sources to ${TMPDIR}"
 162 
 163 export APT_CLONE_ENV=1
 164 
 165 logcmd ${APTGET} -R ${TMPDIR} update
 166 
 167 PKGNUM=$(${APTGET} -R ${TMPDIR} -s upgrade | ${AWK} '/[0-9]+ upgraded,/{print $1 }')
 168 
 169 if (( PKGNUM == 0 )); then
 170         logerrdie "Nothing to upgrade. Do you want to bump DEB_VERSION?"
 171 fi
 172 
 173 logmsg "===== Installing packages"
 174 logcmd ${APTGET} -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -R ${TMPDIR} install -y --force-yes sunwcsd || logerrdie "Failed to install sunwcsd"
 175 logcmd ${APTGET} -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -R ${TMPDIR} install -y --force-yes sunwcs || logerrdie "Failed to install sunwcs"
 176 logcmd ${APTGET} -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -R ${TMPDIR} install -y --force-yes system-kernel || logerrdie "Failed to install system-kernel"
 177 logcmd ${APTGET} -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -R ${TMPDIR} dist-upgrade -y --force-yes || logerrdie "Failed to install kernel packages"
 178 
 179 logmsg "===== Reconfiguring drivers"
 180 CLONEPKGS=$(get_clones_dev ${TMPDIR})
 181 CLONEPKGS=$(rm_package_name "system-kernel" ${CLONEPKGS})
 182 for CLONPKG in $CLONEPKGS
 183 do
 184     DEBPKGS=$(rm_package_name ${CLONPKG} ${DEBPKGS})
 185 done
 186 DEBPKGS=$(rm_package_name "system-kernel" ${DEBPKGS})
 187 DEBPKGS="system-kernel ${CLONEPKGS} ${DEBPKGS}"
 188 
 189 for DEBPKG in ${DEBPKGS}
 190 do
 191     [[ -f ${TMPDIR}/var/lib/dpkg/info/${DEBPKG}.prerm ]] && ( BASEDIR=${TMPDIR} ${TMPDIR}/var/lib/dpkg/info/${DEBPKG}.prerm upgrade >/dev/null 2>&1 )
 192     [[ -f ${TMPDIR}/var/lib/dpkg/info/${DEBPKG}.postinst ]] && ( BASEDIR=${TMPDIR} ${TMPDIR}/var/lib/dpkg/info/${DEBPKG}.postinst configure >/dev/null 2>&1 )
 193 done
 194 
 195 logmsg "===== Updating boot_archive and activating BE"
 196 logcmd ${BOOTADM} update-archive -R ${TMPDIR} || logerrdie "Can't update boot_archive"
 197 logcmd ${TOUCH} ${TMPDIR}/reconfigure
 198 
 199 logcmd ${CP} /etc/apt/sources.list.saved /etc/apt/sources.list
 200 logcmd ${CP} -f /etc/apt/sources.list ${TMPDIR}/etc/apt/sources.list
 201 
 202 logcmd ${BEADM} umount ${TARGETBE}
 203 logcmd ${BEADM} activate ${TARGETBE}
 204 
 205 ${CAT}<<-EOF
 206 
 207                           * * *
 208                       SYSTEM NOTICE
 209 
 210      The upgrade has completed successfully:
 211        - created new BE '${TARGETBE}'
 212        - created new GRUB menu entry
 213        - upgrade log saved to '$LOG'
 214        - the system is ready to reboot into the new BE
 215 
 216    +------------------------------------------------------------------+
 217    |                                                                  |
 218    |  At this point you have two options:                             |
 219    |                                                                  |
 220    |   1. You can reboot now, make sure that system is healthy.       |
 221    |                                                                  |
 222    |   2. Or, you can simply continue using the system as is and      |
 223    |      reboot to new BE later.                                     |
 224    |                                                                  |
 225    +------------------------------------------------------------------+
 226 EOF
 227 
 228 ${ECHO} "$(basename $0) finished at $(date)" >> $LOG
 229 
 230 exit 0