© 2015 Warren Block
Last updated 2015-11-04
Updating the ports tree on FreeBSD.
Introduction
There are several steps to updating the ports tree and checking for installed applications that need to be updated. This can be simplified by automating it.
Update
This script is meant to self-configure. It expects the ports tree to be in /usr/ports, although that can be overridden in the script.
The ports tree is checked to determine whether Subversion or portsnap(8) should be used to update it. I almost always use Subversion, so the portsnap(8) has not really been tested.
If ezjails are present, their ports tree is also updated.
The date of last update is shown for both the host and ezjails to make it easy to check /usr/ports/UPDATING.
The script must be run as root. I call it update.
The Script: update
#!/bin/sh
# Warren Block
# last update 2015-11-04
PORTSDIR="/usr/ports"
AWK="/usr/bin/awk"
BASENAME="/usr/bin/basename"
DATE="/bin/date"
EZJAILADMIN="/usr/local/bin/ezjail-admin"
EZJAILCFGS="/usr/local/etc/ezjail"
GREP="/usr/bin/grep"
JAILDIR="/usr/jails"
JAILS=""
JLS="/usr/sbin/jls"
LS="/bin/ls"
PKG="/usr/local/sbin/pkg"
PORTMASTER="/usr/local/sbin/portmaster"
PORTSNAP="/usr/sbin/portsnap"
PRINTF="/usr/bin/printf"
SORT="/usr/bin/sort"
SVN="/usr/local/bin/svn"
SVNLITE="/usr/bin/svnlite"
TAIL="/usr/bin/tail"
DATEFMT="+%Y-%m-%d"
LOG="/tmp/update.log"
PKGDBDIR="/var/db/pkg"
UPDATEMETHOD=""
startlog() {
echo "update log ${LOG} started `${DATE} ${DATEFMT}`" >> "${LOG}"
}
showit() {
echo "$@" >> "${LOG}"
echo "$@"
}
portsnaporsvn() {
UPDATEMETHOD="svn"
${SVNLITE} info "${PORTSDIR}" 2>&1 1>/dev/null
if [ $? -ne 0 ]; then
UPDATEMETHOD="portsnap"
fi
}
checkrequirements() {
if [ "${UPDATEMETHOD}" = "svn" ]; then
if [ ! -f "${SVN}" ]; then
echo " ** ${SVN} not found, cannot update host"
exit 1
fi
elif [ "${UPDATEMETHOD}" = "portsnap" ]; then
if [ ! -f "${PORTSNAP}" ]; then
echo " ** ${PORTSNAP} not found, cannot update host"
exit 1
fi
fi
if [ ! -f "${PORTMASTER}" ]; then
echo " ** ${PORTMASTER} not found, cannot check host"
exit 1
fi
if [ ! -f "${PKG}" ]; then
echo " ** ${PKG} not found, cannot check package database"
exit 1
fi
}
updatehost() {
showit "updating host with ${UPDATEMETHOD}"
case ${UPDATEMETHOD} in
svn) ${SVN} up "${PORTSDIR}" 2>&1 >>"${LOG}" ;;
portsnap) ${PORTSNAP} fetch update -p "${PORTSDIR}/" 2>&1 >> "${LOG}" ;;
esac
if [ $? -ne 0 ]; then
showit " ** error on host update. log file: ${LOG}"
exit 1
fi
}
checkhost() {
# use --index-only for faster test on the host, although it may not
# be up to date with the actual ports themselves
showit "checking host"
OUTPUT=`${PORTMASTER} -L --index-only | egrep '(ew|ort) version|total install'`
RC=$?
echo "${OUTPUT}" >> "${LOG}"
if [ "${RC}" -ne 0 ]; then
showit " ** error checking host. log file: ${LOG}"
exit 1
fi
if echo "${OUTPUT}" | ${GREP} -q "no new versions available" ; then
# no updates needed
else
OUTPUT=`echo "${OUTPUT}" | ${AWK} '{ print "\t", $0 }'`
showit "${OUTPUT}"
LASTUPDATE=$( ${PRINTF} "\tLast update: " ; ${DATE} -r `${PKG} query %t | ${SORT} | ${TAIL} -n1` ${DATEFMT} )
showit "${LASTUPDATE}"
fi
}
locatejails() {
if [ ! -d "${JAILDIR}" ]; then
echo "no jaildir ${JAILDIR}, skipping jail check" >> "${LOG}"
return
fi
if [ ! -d "${EZJAILCFGS}" ]; then
echo "no ezjail config dir ${EZJAILCFGS}, skipping jail check" >> "${LOG}"
return
fi
cfgs=`${LS} ${EZJAILCFGS}/* 2>/dev/null`
for jail in ${cfgs}; do
jail=`${BASENAME} "${jail}"`
JAILS="${JAILS} ${jail%.norun}"
done
if [ -n "${JAILS}" ]; then
return 0
else
echo "no jails found" >> "${LOG}"
return 1
fi
}
updatebasejail() {
if [ -z "${JAILS}" ]; then
return
fi
if [ -f "${EZJAILADMIN}" ]; then
# update ports in the basejail
showit "updating basejail"
${EZJAILADMIN} update -P >> "${LOG}"
else
showit " ** ${EZJAILADMIN} not found, cannot update basejail"
return 1
fi
}
checkjails() {
for jail in ${JAILS}; do
echo -n "jail: ${jail}"
echo -n "jail: ${jail}" >> "${LOG}"
if ${JLS} name | ${GREP} -q -x ${jail} ; then
showit
else
showit ' (not running)'
fi
PKGDB="${JAILDIR}/${jail}${PKGDBDIR}/local.sqlite"
if [ ! -f "${PKGDB}" ]; then
showit " ** no package database at ${PKGDB}, cannot check port status"
continue
fi
export PKG_DBDIR="${JAILDIR}/${jail}${PKGDBDIR}"
OUTPUT=`${PORTMASTER} -L | egrep '(ew|ort) version|total install'`
if echo "${OUTPUT}" | ${GREP} -q "no new versions available" ; then
# no updates needed
else
OUTPUT=`echo "${OUTPUT}" | ${AWK} '{ print "\t", $0 }'`
showit "${OUTPUT}"
LASTUPDATE=$( ${PRINTF} "\tLast update: " ; ${DATE} -r `${PKG} query %t | ${SORT} | ${TAIL} -n1` ${DATEFMT} )
showit "${LASTUPDATE}"
fi
done
}
startlog
portsnaporsvn
checkrequirements
updatehost
checkhost
if locatejails; then
updatebasejail
checkjails
fi