#!/bin/bash # # Update your system automatically! # # Packages from different sources are downloaded, under sub-shells, into the # PACKAGE_DIR where they can be installed on reboot. # # A failure encountered at any point should abort any pending package updates # to install. # # To enable sbotools updates, make the /etc/sbotools/sbotools.conf file exist # and configure PKG_DIR to point to the same path as STAGING_DIR. # Set to "yes" to send notification to stdout, causing cron to send an email. NOTIFY="${NOTIFY:-no}" # Reboot after this period for install after a successful update. # # Set to empty to disable reboot or 'now' to reboot immediately. export REBOOT_TIME="${REBOOT_TIME:-""}" # Packages are copied here on successful download. export PACKAGE_DIR="${PACKAGE_DIR:-/var/spool/slack-autoupdate}" # Packages are temperarily stored here until success. export STAGING_DIR="${STAGING_DIR:-/var/cache/slack-autoupdate/staging}" # Information of interest to the admin on success. export UPDATE_INFO="${UPDATE_INFO:-$STAGING_DIR/info.txt}" # Information of interest to the admin on failure. export UPDATE_ERROR="${UPDATE_ERROR:-$STAGING_DIR/error.txt}" # Avoid concurrently running with another instance. if [ "$(ls /var/lock/autoupdate.* 2>/dev/null)" ]; then echo "Another instance of autoupdate is running. If this is not correct, you can remove /var/lock/autoupdate.* files and run autoupdate again." \ >>"$PACKAGE_DIR/$(basename "$UPDATE_ERROR")" if [ "$NOTIFY" = "yes" ]; then cat "$PACKAGE_DIR/$(basename "$UPDATE_ERROR")" fi exit 1 fi touch /var/lock/autoupdate.$$ trap "rm -f /var/lock/autoupdate.$$" EXIT # Keep it simple stupid, install pending updates first. mkdir --parents "$PACKAGE_DIR" if [ -n "$(find "$PACKAGE_DIR" -name "*.t*z")" ]; then exit 0 fi # Make the set of package updates available atomically by storing them in a # temporary location until completion. rm -fr "$STAGING_DIR" mkdir --parents "$STAGING_DIR" if ! OUTPUT="$( # Capture this subshell's error output to standard output. exec 2>&1 echo "Checking updates for slackpkg..." slackpkg -batch=on -default_answer=n update || exit "$?" CHANGELOG_TXT="$(mktemp /tmp/slack-autoupdate.XXXXXX)" PACKAGE_UPDATES="$(mktemp /tmp/slack-autoupdate.XXXXXX)" trap "rm -f ${CHANGELOG_TXT} ${PACKAGE_UPDATES}" EXIT slackpkg -batch=on -default_answer=n upgrade-all \ | grep "\.t.z$" \ | tee "$PACKAGE_UPDATES" \ || exit "$?" if [ ! -s "$PACKAGE_UPDATES" ]; then # No updates exit 0 fi # # We need slackpkg to support downloading an exact package file to a provided # location. The following is a workaround. # SOURCE=$(sed -n ' # Remove leading and trailing blanks s/^[[:blank:]]*// s/[[:blank:]]*$// # Only one token is allowed per line /[[:blank:]]/d # A single solidus should end the URI s,[/]*$,/, # Print the lines beginning with one of the URI schemes we look for \@^file://@p \@^cdrom://@p \@^local://@p \@^https\{0,1\}://@p \@^ftps\{0,1\}://@p' /etc/slackpkg/mirrors) while read PKG; do PKG_URL="$( grep "${PKG}$" /var/lib/slackpkg/CHECKSUMS.md5 \ | tr -s ' ' \ | cut -f 2 -d ' ' )" || exit "$?" wget \ --quiet \ --directory-prefix="$STAGING_DIR" \ "${SOURCE}${PKG_URL}" \ "${SOURCE}${PKG_URL}.asc" \ || exit "$?" done <"$PACKAGE_UPDATES" gpg2 --verify-files "$STAGING_DIR"/*.asc || exit "$?" ( # Provide update information to the user. # Redirect this subshell's standard output to info file. exec 1>>"$UPDATE_INFO" LAST_INSTALLED_PACKAGE="$( grep \ "$(ls /var/log/packages | sed "s/$/\\\|/g" | tr --delete '\n')XXXXX" \ /var/lib/slackpkg/ChangeLog.txt \ | head -n 1 )" echo "Slackware updates" echo grep --before-context 10000 "$LAST_INSTALLED_PACKAGE" /var/lib/slackpkg/ChangeLog.txt echo ) )"; then >>"$UPDATE_ERROR" echo -e "slackpkg:\n\n$OUTPUT" fi if ! OUTPUT="$( exec 2>&1 echo "Checking updates for sbotools..." if [ ! -f /etc/sbotools/sbotools.conf ] \ || [ "$(sed -n 's/PKG_DIR=//p' /etc/sbotools/sbotools.conf)" != "$STAGING_DIR" ]; then # Assume sbotools is disabled. exit 0 fi source /etc/profile.d/*.sh PACKAGE_UPDATES=$(mktemp /tmp/slack-autoupdate.XXXXXX) trap "rm -f ${PACKAGE_UPDATES}" EXIT (sbocheck | tee $PACKAGE_UPDATES) || exit 1 if grep -i "no updates available" "$PACKAGE_UPDATES"; then exit 0 fi sboupgrade \ --all \ --noinstall \ --nointeractive \ || exit "$?" ( exec 1>>"$UPDATE_INFO" echo "Slackbuild updates" echo cat "$PACKAGE_UPDATES" echo ) )"; then if [ -f "$UPDATE_ERROR" ]; then >>"$UPDATE_ERROR" echo "" >>"$UPDATE_ERROR" echo "" fi >>"$UPDATE_ERROR" echo -e "sbotools:\n\n$OUTPUT" fi # Make updates atomic. if [ -f "$UPDATE_ERROR" ]; then mv "$UPDATE_ERROR" "$PACKAGE_DIR" mv "$UPDATE_INFO" "$PACKAGE_DIR" exit 1 fi mv "$STAGING_DIR"/* "$PACKAGE_DIR/" rm -fr "$STAGING_DIR" if [ -z "$(find "$PACKAGE_DIR" -name "*.t*z" -or -name "info.txt" -or -name "error.txt")" ]; then # No updates exit 0 fi if [ "$NOTIFY" = "yes" ]; then if [ -f "$UPDATE_ERROR" ]; then echo "Failures were encountered while trying to download updates" echo "" cat "$UPDATE_ERROR" elif [ -f "$UPDATE_INFO" ]; then echo "Updates pending installation" echo "" cat "$UPDATE_INFO" fi fi if [ -n "$REBOOT_TIME" ]; then nohup shutdown -r "$REBOOT_TIME" >/dev/null 2>&1 & fi