source: src-sh/pc-updatemanager/pc-updatemanager @ a3b102b

9.2-releasereleng/10.0releng/10.0.1
Last change on this file since a3b102b was a3b102b, checked in by Kris Moore <kris@…>, 12 months ago

Improve how we run major updates, try to download as many PKGNG packages beforehand
as possible, so that if it fails, it does so before we get to the freebsd-update portion

  • Property mode set to 100755
File size: 13.7 KB
Line 
1#!/bin/sh
2# Script which performs updating services
3############################################################################
4
5# Source our functions
6. /usr/local/share/pcbsd/scripts/functions.sh
7
8# Set the program location
9PROGDIR="/usr/local/share/pcbsd/pc-updatemanager" ; export PROGDIR
10
11# Start by sourcing /etc/profile
12# This grabs any HTTP_ / FTP_ PROXY variables
13. /etc/profile
14
15PCBSD_ETCCONF="/usr/local/etc/pcbsd.conf"
16export PCBSD_ETCCONF
17
18# Set the pub openssl key
19SKEY="${PROGDIR}/conf/security.key" ; export SKEY
20
21# Directory to store downloaded updates
22DOWNLOADDIR="/usr/local/tmp"
23
24# Get the system version we are checking for updates to
25SYSVER="`uname -r | cut -d '-' -f 1-2`" ; export SYSVER
26
27# Get the system type
28SYSTYPE="`pbreg get /PC-BSD/SysType`" ; export SYSTYPE
29
30# Set the config location
31UPDATECONF="${PROGDIR}/conf/sysupdate.conf"
32
33# Set the system arch type
34ARCH=`uname -m`
35
36# Default pcbsd.conf file
37PCBSD_ETCCONF="/usr/local/etc/pcbsd.conf"
38
39# Patchset Data
40PATCHSERVER="`cat ${UPDATECONF} | grep '^UPDATESERVER:' | cut -d ' ' -f 2`"
41PATCHSET="`cat ${UPDATECONF} | grep '^PATCHSET:' | cut -d ' ' -f 2`"
42PATCHFILE="${PATCHSET}.upd"
43PATCHURL="${PATCHSERVER}/${PATCHFILE}"
44PATCHTMPDIR=`mktemp -d /tmp/.sysupdateXXXXXX`
45PATCHTMPFILE="${PATCHTMPDIR}/sysupdate-${SYSVER}.upd"
46
47MUSTAGEDIR="${DOWNLOADDIR}/update-stagedir"
48
49# Enable ftp passive mode for file transfers
50FTP_PASSIVE_MODE="YES" ; export FTP_PASSIVE_MODE
51
52if [ ! -d "${DOWNLOADDIR}" ]; then mkdir -p ${DOWNLOADDIR}; fi
53
54
55# Trigger File for Tray Application
56TRIGGERFILE="/tmp/.sysupdatetraytrigger"
57
58DBDIR="/var/db/pc-updatemanager"
59INSDIR="${DBDIR}/installed"
60IGNDIR="${DBDIR}/ignored"
61
62
63######################################################################
64# Done with config values
65######################################################################
66
67show_usage() {
68        echo "$0 - Usage
69----
70  check                 - Check for system updates
71  install <tag>,<tag2>  - Install system updates
72  pkgcheck              - Check for updates to packages
73  pkgupdate             - Install packages updates
74"       
75
76        exit 1
77}
78
79# Run-command, don't halt if command exits with non-0
80rc_nohalt()
81{
82  CMD="$1"
83 
84  if [ -z "${CMD}" ] ; then
85    exit_err "Error: missing argument in rc_nohalt()"
86  fi
87
88  ${CMD}
89}
90
91# Run-command, halt if command exits with non-0
92rc_halt()
93{
94  CMD="$@"
95
96  if [ -z "${CMD}" ] ; then
97    exit_err "Error: missing argument in rc_halt()"
98  fi
99
100  ${CMD}
101  STATUS=$?
102  if [ ${STATUS} -ne 0 ] ; then
103    exit_err "Error ${STATUS}: ${CMD}"
104  fi
105}
106
107get_update_file() {
108
109  # Now fetch the update file
110  get_file "${PATCHURL}" "${PATCHTMPFILE}" 1 >/dev/null 2>/dev/null
111  if [ $? -ne 0 ] ; then
112     rm ${PATCHTMPFILE} 2>/dev/null
113     is_net_up
114     if [ $? -eq 0 ] ; then
115       echo "No updates available for $SYSVER!" ; exit 0
116     else
117       exit_err "Could not contact update server!"
118     fi
119  fi
120
121  # Now fetch the update file signature
122  get_file "${PATCHURL}.sha1" "${PATCHTMPFILE}.sha1" 1 >/dev/null 2>/dev/null
123  if [ $? -ne 0 ] ; then
124     rm ${PATCHTMPFILE}.sha1 2>/dev/null
125     is_net_up
126     if [ $? -eq 0 ] ; then
127       echo "No updates available for $SYSVER!" ; exit 0
128     else
129       exit_err "Could not contact update server!"
130     fi
131  fi
132
133  # Lets verify the signature of the file
134  openssl dgst -sha1 -verify ${SKEY} \
135        -signature ${PATCHTMPFILE}.sha1 \
136        ${PATCHTMPFILE} >/dev/null 2>/dev/null
137  if [ $? -ne 0 ] ; then
138     rm ${PATCHTMPFILE} 2>/dev/null
139     rm ${PATCHTMPFILE}.sha1 2>/dev/null
140     exit_err "Update file failed verification..."
141  fi
142
143  # Done with the signature we can discard
144  rm ${PATCHTMPFILE}.sha1
145
146}
147
148do_check() {
149  # Setup our variable, we have no patches so far
150  PATCHFOUND="0" 
151
152  while read line
153  do
154     echo $line | grep -q "^MU:"
155     if [ $? -eq 0 ] ; then
156        parse_mu_update_line "$line"
157        continue
158     fi
159     echo $line | grep -q "^SA:"
160     if [ $? -eq 0 ] ; then
161        parse_sa_update_line "$line"
162        continue
163     fi
164  done < ${PATCHTMPFILE}
165
166  # If no patches
167  if [ "${PATCHFOUND}" = "0" ]; then 
168     # No available updates
169     echo "Your system is up to date!"
170  fi
171
172  rm ${PATCHTMPFILE}
173
174};
175
176parse_mu_update_line()
177{
178   local line="$1"
179
180   # Check if this is a major update we can install
181   local sysUpOVer=`echo $line | cut -d ':' -f 2`
182   local sysUpNVer=`echo $line | cut -d ':' -f 3`
183
184   # Is this an update for our version?
185   if [ "$SYSVER" != "$sysUpOVer" ] ; then return; fi
186
187   if [ $PATCHFOUND -eq 0 ] ; then
188      echo ""
189      echo "The following updates are available:"
190      echo "------------------------------------"
191   fi
192   echo "NAME: FreeBSD System Update to ${sysUpNVer}" 
193   echo "TYPE: SYSUPDATE" 
194   echo "TAG: fbsd-${sysUpNVer}"
195   echo "VERSION: ${sysUpNVer}" 
196   echo ""
197   echo "To install: \"pc-updatemanager install fbsd-${sysUpNVer}\""
198   echo ""
199   echo ""
200
201   PATCHFOUND="`expr ${PATCHFOUND} + 1`" 
202}
203
204parse_sa_update_line()
205{
206   local line="$1"
207
208   # Check if this is an update we can install
209   local saVer=`echo $line | cut -d ':' -f 2`
210   local saArch=`echo $line | cut -d ':' -f 3`
211   local saType=`echo $line | cut -d ':' -f 4`
212   local saIdent="`echo $line | cut -d ':' -f 5`"
213
214   # For this version?
215   if [ "$SYSVER" != "$saVer" ] ; then return ; fi
216
217   # For this system arch?
218   if [ "$ARCH" != "$saArch" -a "$saArch" != "noarch" ] ; then return ; fi
219
220   # For this system type?
221   if [ "$SYSTYPE" != "$saType" -a "$saType" != "both" ] ; then return ; fi
222
223   # Already installed?
224   if [ -e "${INSDIR}/${SYSVER}/$saIdent" ] ; then return ; fi
225
226   if [ $PATCHFOUND -eq 0 ] ; then
227      echo ""
228      echo "The following updates are available:"
229      echo "------------------------------------"
230   fi
231   local saDesc="`echo $line | cut -d ':' -f 6`"
232   local saSize=`echo $line | cut -d ':' -f 8`
233   local saDetail="http://trac.pcbsd.org`echo $line | cut -d ':' -f 10`"
234   local saDate="`echo $line | cut -d ':' -f 11`"
235
236   echo "NAME: ${saDesc}" 
237   echo "TYPE: PATCH" 
238   echo "TAG: ${saIdent}"
239   echo "DETAILS: ${saDetail}"
240   echo "DATE: ${saDate}"
241   echo "SIZE: ${saSize}Mb" 
242   echo " "
243   echo "To install: \"pc-updatemanager install ${saIdent}\""
244   echo " "
245
246   PATCHFOUND="`expr ${PATCHFOUND} + 1`" 
247}
248
249start_pcbsd_patch() {
250  local up="$1"
251  local saIdent=""
252  local saVer=""
253  local saArch=""
254  local saPlat=""
255  local saUrl=""
256  local saDesc=""
257  local saCsum=""
258  local patchLine=""
259  if [ -e "${INSDIR}/${SYSVER}/${up}" ]; then
260     rm ${PATCHTMPFILE}
261     exit_err "Patch $up already installed!"
262  fi
263
264  while read line
265  do
266    echo $line | grep -q "^SA:"
267    if [ $? -ne 0 ] ; then continue; fi
268    saIdent="`echo $line | cut -d ':' -f 5`"
269    # Look for the right stand-alone update
270    if [ "$saIdent" != "$up" ] ; then continue ; fi
271    saVer=`echo $line | cut -d ':' -f 2`
272    saArch=`echo $line | cut -d ':' -f 3`
273    saType=`echo $line | cut -d ':' -f 4`
274    # Does this update apply to this system arch?
275    if [ "$saArch" != "$ARCH" -a "$saArch" != "noarch" ] ; then
276       rm ${PATCHTMPFILE}
277       exit_err "Patch $up is not for this system arch type!"
278    fi
279    # For this version?
280    if [ "$saVer" != "$SYSVER" ] ; then
281       rm ${PATCHTMPFILE}
282       exit_err "Patch $up is not for this system version!"
283    fi
284
285    # For this system type?
286    if [ "$SYSTYPE" != "$saType" -a "$saType" != "both" ] ; then
287       rm ${PATCHTMPFILE}
288       exit_err "Patch $up is not for this system type!"
289    fi
290
291    # Got here? We have a patch ready to go
292    patchLine="$line"
293    break
294  done < ${PATCHTMPFILE}
295
296  # Did we find the patch?
297  if [ -z "$patchLine" ] ; then
298     rm ${PATCHTMPFILE}
299     exit_err "Patch $up not found!"
300  fi
301
302  # Get the patch details
303  saVer=`echo $patchLine | cut -d ':' -f 2`
304  saArch=`echo $patchLine | cut -d ':' -f 3`
305  saPlat=`echo $patchLine | cut -d ':' -f 4`
306  saIdent="`echo $patchLine | cut -d ':' -f 5`"
307  saDesc="`echo $patchLine | cut -d ':' -f 6`"
308  saUrl="`echo $patchLine | cut -d ':' -f 7`"
309  saCsum="`echo $patchLine | cut -d ':' -f 9`"
310  local FILENAME="`basename $saUrl`"
311
312  # Start downloading the patch
313  touch ${TRIGGERFILE}
314  echo "DOWNLOADING: ${saIdent}"
315  echo "DOWNLOADING: ${saIdent}" >${TRIGGERFILE}
316
317  # Get the file
318  get_file_from_mirrors "/${saUrl}" "${DOWNLOADDIR}/${FILENAME}"
319  if [ $? -ne 0 ] ; then
320     rm ${PATCHTMPFILE}
321     echo "FAILED: ${saIdent}" >${TRIGGERFILE}
322     exit_err "Failed to download: ${saIdent}"
323  fi
324
325  # Check the sha256 checksum
326  if [ "$saCsum" != "`sha256 -q ${DOWNLOADDIR}/${FILENAME} 2>/dev/null`" ]
327  then
328     # Download MD5 doesn't match! Delete the file
329     rm ${PATCHTMPFILE}
330     rm ${DOWNLOADDIR}/${FILENAME}
331     echo "FAILED: ${saIdent}" >${TRIGGERFILE}
332     exit_err "Failed to download: ${saIdent}"
333  else
334     echo "DOWNLOADFINISHED: ${saIdent}"
335     echo "DOWNLOADFINISHED: ${saIdent}" >${TRIGGERFILE}
336  fi
337
338  echo "INSTALLING: ${saIdent}" >${TRIGGERFILE}
339  sleep 1
340
341  PATCHTMPDIR="`mktemp -d ${DOWNLOADDIR}/patchInstallXXXXX`"
342  rc_halt "tar xvJf ${DOWNLOADDIR}/${FILENAME} -C ${PATCHTMPDIR}" 2>/dev/null
343  PATCHDIR="$PATCHTMPDIR" ; export PATCHDIR
344  cd ${PATCHTMPDIR}
345  sh update.sh
346  if [ $? -eq 0 ]; then
347     touch "${INSDIR}/${SYSVER}/${saIdent}"
348     echo "INSTALLFINISHED: ${saIdent}"
349     echo "INSTALLFINISHED: ${saIdent}" >${TRIGGERFILE}
350  else
351     rm ${PATCHTMPFILE}
352     rm -rf ${PATCHTMPDIR}
353     rm ${DOWNLOADDIR}/${FILENAME}
354     echo "INSTALLFAILED: ${saIdent}" >${TRIGGERFILE}
355     exit_err "INSTALLFAILED: ${saIdent}"
356  fi
357
358  rc_halt "rm -rf ${PATCHTMPDIR}"
359  rc_halt "rm ${DOWNLOADDIR}/${FILENAME}"
360}
361
362start_major_fbsd_update() {
363  local rel=`echo $1 | sed 's|fbsd-||g'`
364
365  # Lets backup the old pkg.conf file
366  cp /usr/local/etc/pkg.conf /usr/local/etc/pkg.conf.preUpgrade
367
368  # Set the new pkg.conf file to the new repo
369  local arch=`uname -m`
370  echo "packagesite: http://ftp.pcbsd.org/pub/mirror/packages/$rel/$arch" >/usr/local/etc/pkg.conf
371  echo "PUBKEY: /usr/local/etc/pkg-pubkey.cert" >>/usr/local/etc/pkg.conf
372  echo "PKG_CACHEDIR: /usr/local/tmp" >>/usr/local/etc/pkg.conf
373
374  # Lets pre-download all packages
375  download_cache_packages "pkg upgrade -f"
376
377  # Download update files from freebsd-update
378  freebsd-update --non-interactive -r "$rel" upgrade
379  if [ $? -ne 0 ] ; then
380     cp /usr/local/etc/pkg.conf.preUpgrade /usr/local/etc/pkg.conf
381     exit_err "Failed running \"freebsd-update -r $rel upgrade\"..."
382  fi
383
384  # Now install freebsd-update files
385  freebsd-update --non-interactive install
386  if [ $? -ne 0 ] ; then
387     cp /usr/local/etc/pkg.conf.preUpgrade /usr/local/etc/pkg.conf
388     exit_err "Failed running \"freebsd-update install\"..."
389  fi
390
391  # Now its time to force a pkg-update of all packages to their new FreeBSD compiled versions
392  pc-updatemanager pkgupdate -f
393
394  # Now re-extract overlay files again to grab any new changes from a port we just updated
395  if [ "$SYSTYPE" = "PCBSD" ]; then
396    pc-extractoverlay desktop
397  fi
398  if [ "$SYSTYPE" = "TRUEOS" ]; then
399    pc-extractoverlay server
400  fi
401
402  echo "Major update finished!" 
403  echo "Please reboot the system for changes to take effect." 
404}
405
406do_install() {
407        # Make sure we are root and have specified updates to install
408        if [ `id -u` != "0" ] ; then exit_err "Must be run as root!" ; fi
409        if [ -z "$1" ] ; then exit_err "No updates specified to install!"; fi
410
411        # Begin to update the selected items
412        for up in `echo $1 | sed 's|,| |g'`
413        do
414          # If this is a major update, start it up!
415          echo $up | grep -q "^fbsd-" 
416          if [ $? -eq 0 ] ; then
417            start_major_fbsd_update "$up"
418            exit 0
419          elif [ "$up" == "pkg-updates" ] ; then
420            # Check if this is a pkg-update request or regular patch
421            start_pkg_updates
422            continue
423          else
424            echo $up | grep -q "^release-" 
425            if [ $? -eq 0 ] ; then
426              start_major_update "$up"
427              continue
428            fi 
429
430            # Doing regular pcbsd patch
431            start_pcbsd_patch "${up}"
432            continue
433          fi
434
435        done 
436
437        # All Finished!
438        rm ${PATCHTMPFILE}
439        exit 0
440}
441
442is_net_up() {
443        ping -c 1 www.pcbsd.org >/dev/null 2>/dev/null
444        return $?
445}
446
447checkup_pkgs() {
448
449  # Checkout the installed pkgs and compare to master list
450  rc_halt "pkg-static update"
451  pkg-static upgrade -n >/tmp/.pkgData.$$
452  grep -q "Upgrading" /tmp/.pkgData.$$
453  if [ $? -ne 0 ] ; then
454     echo "All packages are up to date!"
455     rm /tmp/.pkgData.$$
456     return 0
457  fi
458
459  # Display the pkg update data
460  cat /tmp/.pkgData.$$
461  rm /tmp/.pkgData.$$
462  echo ""
463  echo "To start the upgrade run \"${0} pkgupdate\""
464  return 0
465}
466
467update_pkgs()
468{
469  if [ -n "$1" -a "$1" != "-f" ] ; then
470     exit_err "Invalid option $1 passed"
471  fi
472
473  # Lets pre-download all the packages
474  download_cache_packages "pkg-static upgrade -U -n $1"
475
476  check_pkg_conflicts "upgrade -U -F -y $1"
477  if [ $? -ne 0 ] ; then
478     exit 1
479  fi
480
481  # Start the package update!
482  pkg-static upgrade -U -y ${1}
483  result=$?
484
485  # Lets now re-extract our overlay data to grab any adjusted port files
486  pc-extractoverlay ports >/dev/null 2>/dev/null
487
488  # Now re-extract overlay files to ensure we do file fixing / massaging
489  if [ "$SYSTYPE" = "PCBSD" ]; then
490    pc-extractoverlay desktop
491  fi
492  if [ "$SYSTYPE" = "TRUEOS" ]; then
493    pc-extractoverlay server
494  fi
495
496  if [ $result -ne 0 ] ; then
497     echo "Failed updating..."
498  fi
499  exit $result
500}
501
502# Check if we have an update folder for the version we are on
503if [ ! -d "${AVAILDIR}/${SYSVER}" ] ; then mkdir -p ${AVAILDIR}/${SYSVER} ; fi
504
505if [ "`id -u`" = "0" ] ; then
506  # Make the installed directory for this version
507  if [ ! -d "${INSDIR}/${SYSVER}" ] ; then mkdir -p ${INSDIR}/${SYSVER} ; fi
508
509  # Make the ignore directory for this version
510  if [ ! -d "${IGNDIR}/${SYSVER}" ] ; then mkdir -p ${IGNDIR}/${SYSVER} ; fi
511fi
512
513case $1 in
514           check) get_update_file
515                  do_check ;;
516        pkgcheck) checkup_pkgs ;;
517       pkgupdate) update_pkgs "$2" ;;
518         install) get_update_file
519                  do_install "${2}" ;;
520        *) show_usage ;;
521esac
522
523exit 0
Note: See TracBrowser for help on using the repository browser.