#!/bin/ksh # ######################################################################## # # snaps - Check if you can upgrade your OpenBSD OS base to # last -current snapshot # # Copyright (c) 2017-2020, Fred Galusik # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # 3. Neither the name of the copyright holder nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ######################################################################## set -ue ### ### VARS ### VERSION=2.0 # choose your MIRROR true "${MIRROR:=$(grep -v "^#" /etc/installurl)}" # curl is mandatory if [ ! "$(which curl 2>/dev/null)" ]; then echo "WARNING: 'curl' is requested to run this program. Aborting..." exit 1 fi CURL=$(whereis curl) # ARCH=$(uname -m) SHA=SHA256 BASE=/snapshots/${ARCH}/ BASEF=/snapshots/${ARCH}/${SHA} PKGSF=/snapshots/packages/${ARCH}/${SHA} GET='/usr/bin/ftp -n -m -C' LOGF=/var/log/snaps.log ### ### ### usage() { echo "${0##*/} ${VERSION}" echo "Usage: ${0##*/} [-scalfuph]" echo "" echo " -s check \$MIRROR freshness & choose to sysupgrade or not" echo " -c check BASE and PACKAGES build dates from \$MIRROR" echo " -a check BASE and PACKAGES build dates from all available mirrors" echo " -l list date and \$MIRROR of the 3 last upgrade using this script" echo " -f read the online FAQ : Following -current and using snapshots" echo " -u upgrade snaps to last version" echo " -p update ports tree to -current" echo " -h print this help and exit" echo "" echo "MIRROR is based upon /etc/installurl and set to: ${MIRROR}" echo "" echo "You can set it manually:" echo "\$ MIRROR=http://mirrors.ircam.fr/pub/OpenBSD snaps -c" echo "" } s_root() { if [[ $(id -u) != "0" ]]; then echo "WARNING: You need to be root to do this! Aborting..." 1>&2 exit 1 fi } s_toupgrade() { REMOTESNAPS='https://framagit.org/fredg/snaps/raw/master/snaps' LASTSNAPS=/tmp/snaps echo "Checking snaps release..." if [[ -f "${LASTSNAPS}" ]]; then rm -f "${LASTSNAPS}" fi if $GET -V -o "${LASTSNAPS}" "${REMOTESNAPS}"; then REMOTEVERSION=$(awk -F '=' '/^VERSION=/ { print $2 }' "${LASTSNAPS}") if [ "${VERSION}" != "${REMOTEVERSION}" ]; then echo "WARNING: snaps is not up-to-date !" echo "Last version: ${REMOTEVERSION}" echo "To upgrade, run 'snaps -u'" else echo "GOOD: snaps is up-to-date." fi else echo "WARNING: Remote snaps not reachable ! Check the connection." fi echo "" } s_upgrade() { SELFPATH=$(dirname "$(readlink -f -- "$0")") echo "Downloading last snaps version..." $GET -o "${SELFPATH}" "${REMOTESNAPS}" } get_log() { if [[ -f "${LOGF}" ]]; then tail -n 3 ${LOGF} else echo "No ${LOGF} file. Seems you have not yet played with snaps." exit 1 fi } s_upports() { echo "Updating Ports tree..." cd /usr/ports || exit 1 /usr/bin/cvs up -Pd || exit 1 echo "New Ports tree fetched!" } s_cur() { CURRENTSYS=$(sed q /var/run/dmesg.boot) echo "=== LOCAL BASE BUILD DATE ===" echo "${CURRENTSYS}" } s_when() { CURLB="$(${CURL} -sI "${MIRROR}${BASEF}" | grep Last-Modified)" CURLP="$(${CURL} -sI "${MIRROR}${PKGSF}" | grep Last-Modified)" echo "=== ONLINE BASE AND PACKAGES BUILD DATES ===" echo "From ${MIRROR}" echo "Base (${ARCH}) => ${CURLB}" echo "Packages (${ARCH}) => ${CURLP}" } s_sysup() { NOW=$(date "+ %Y-%m-%d %R") echo "" echo -n "Do you want to run 'sysupgrade -s' ? (y/n): " read -r _c case ${_c} in y|Y) ;; *) echo "Aborting..." exit 1 ;; esac echo "${NOW} FROM ${MIRROR}${BASE}" >> ${LOGF} /usr/sbin/sysupgrade -s } read_faq() { FAQ='https://www.openbsd.org/faq/current.html' if [ "$(which links 2>/dev/null)" ]; then READ='links -dump' elif [ "$(which lynx 2>/dev/null)" ]; then READ='lynx --dump' else echo "WARNING: You need 'links' or 'lynx' to read the online FAQ/CURRENT. Aborting..." exit 1 fi ${READ} ${FAQ} | less } all_mirrors() { echo "Checking mirrors..." HTTPSLIST='https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/www/httpslist' MIRRORLIST=$(${CURL} ${HTTPSLIST} | awk '{print $1}') echo "" for _m in ${MIRRORLIST} do CB="$(${CURL} -sI "${_m}${BASEF}" | grep Last-Modified |\ sed 's/Last-Modified: //')" CP="$(${CURL} -sI "${_m}${PKGSF}" | grep Last-Modified |\ sed 's/Last-Modified: //')" # only print mirror which give an answer # FIXME try to figure out how to print 1 mirror per line if [ "${CB}" ]; then echo "${_m}" echo "${CB}" echo "${CP}" echo "" fi done } ## ## Run ## if [ $# -eq 0 ]; then usage exit 1 fi case $1 in -s) s_root s_toupgrade s_cur echo "" s_when s_sysup ;; -c) s_cur s_when ;; -a) all_mirrors ;; -l) get_log ;; -f) read_faq ;; -u) s_upgrade ;; -p) s_upports ;; -h|*) usage exit 1 ;; esac