xref: /openbsd-src/usr.sbin/sysupgrade/sysupgrade.sh (revision 4b70baf6e17fc8b27fc1f7fa7929335753fa94c3)
1#!/bin/ksh
2#
3# $OpenBSD: sysupgrade.sh,v 1.12 2019/05/03 15:18:14 florian Exp $
4#
5# Copyright (c) 1997-2015 Todd Miller, Theo de Raadt, Ken Westerback
6# Copyright (c) 2015 Robert Peichaer <rpe@openbsd.org>
7# Copyright (c) 2016, 2017 Antoine Jacoutot <ajacoutot@openbsd.org>
8# Copyright (c) 2019 Christian Weisgerber <naddy@openbsd.org>
9# Copyright (c) 2019 Florian Obser <florian@openbsd.org>
10#
11# Permission to use, copy, modify, and distribute this software for any
12# purpose with or without fee is hereby granted, provided that the above
13# copyright notice and this permission notice appear in all copies.
14#
15# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
16# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
18# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23set -e
24umask 0022
25
26ARCH=$(uname -m)
27SETSDIR=/home/_sysupgrade
28
29ug_err()
30{
31	echo "${1}" 1>&2 && return ${2:-1}
32}
33
34usage()
35{
36	ug_err "usage: ${0##*/} [-fn] [-r | -s] [installurl]"
37}
38
39unpriv()
40{
41	local _file=$2 _user=_syspatch
42
43	if [[ $1 == -f && -n ${_file} ]]; then
44		>${_file}
45		chown "${_user}" "${_file}"
46		shift 2
47	fi
48	(($# >= 1))
49
50	eval su -s /bin/sh ${_user} -c "'$@'"
51}
52
53# Remove all occurrences of first argument from list formed by the remaining
54# arguments.
55rmel() {
56	local _a=$1 _b _c
57
58	shift
59	for _b; do
60		[[ $_a != "$_b" ]] && _c="${_c:+$_c }$_b"
61	done
62	echo -n "$_c"
63}
64
65RELEASE=false
66SNAP=false
67FORCE=false
68REBOOT=true
69
70while getopts fnrs arg; do
71	case ${arg} in
72	f)	FORCE=true;;
73	n)	REBOOT=false;;
74	r)	RELEASE=true;;
75	s)	SNAP=true;;
76	*)	usage;;
77	esac
78done
79
80if $RELEASE && $SNAP; then
81	usage
82fi
83
84set -A _KERNV -- $(sysctl -n kern.version |
85	sed 's/^OpenBSD \([0-9]\)\.\([0-9]\)\([^ ]*\).*/\1.\2 \3/;q')
86
87shift $(( OPTIND -1 ))
88
89case $# in
900)	MIRROR=$(sed 's/#.*//;/^$/d' /etc/installurl) 2>/dev/null ||
91		MIRROR=https://cdn.openbsd.org/pub/OpenBSD
92	;;
931)	MIRROR=$1
94	;;
95*)	usage
96esac
97
98if ! $RELEASE && [[ ${#_KERNV[*]} == 2 ]]; then
99	SNAP=true
100fi
101
102NEXT_VERSION=$(echo ${_KERNV[0]} + 0.1 | bc)
103
104if $SNAP; then
105	URL=${MIRROR}/snapshots/${ARCH}/
106else
107	URL=${MIRROR}/${NEXT_VERSION}/${ARCH}/
108fi
109
110if [[ -e ${SETSDIR} ]]; then
111	eval $(stat -s ${SETSDIR})
112	[[ $st_uid -eq 0 ]] ||
113		 ug_err "${SETSDIR} needs to be owned by root:wheel"
114	[[ $st_gid -eq 0 ]] ||
115		 ug_err "${SETSDIR} needs to be owned by root:wheel"
116	[[ $st_mode -eq 040755 ]] ||
117		ug_err "${SETSDIR} is not a directory with permissions 0755"
118else
119	mkdir -p ${SETSDIR}
120fi
121
122cd ${SETSDIR}
123
124unpriv -f SHA256.sig ftp -Vmo SHA256.sig ${URL}SHA256.sig
125
126if cmp -s /var/db/installed.SHA256.sig SHA256.sig && ! $FORCE; then
127	ug_err "Already on latest snapshot."
128fi
129
130_KEY=openbsd-${_KERNV[0]%.*}${_KERNV[0]#*.}-base.pub
131_NEXTKEY=openbsd-${NEXT_VERSION%.*}${NEXT_VERSION#*.}-base.pub
132
133read _LINE <SHA256.sig
134case ${_LINE} in
135*\ ${_KEY})	SIGNIFY_KEY=/etc/signify/${_KEY} ;;
136*\ ${_NEXTKEY})	SIGNIFY_KEY=/etc/signify/${_NEXTKEY} ;;
137*)		ug_err "invalid signing key" ;;
138esac
139
140[[ -f ${SIGNIFY_KEY} ]] || ug_err "cannot find ${SIGNIFY_KEY}"
141
142unpriv -f SHA256 signify -Veq -p "${SIGNIFY_KEY}" -x SHA256.sig -m SHA256
143
144# INSTALL.*, bsd*, *.tgz
145SETS=$(sed -n -e 's/^SHA256 (\(.*\)) .*/\1/' \
146    -e '/^INSTALL\./p;/^bsd/p;/\.tgz$/p' SHA256)
147
148OLD_FILES=$(ls)
149OLD_FILES=$(rmel SHA256 $OLD_FILES)
150OLD_FILES=$(rmel SHA256.sig $OLD_FILES)
151DL=$SETS
152
153for f in $SETS; do
154	if cksum -C SHA256 $f >/dev/null 2>&1; then
155		DL=$(rmel $f ${DL})
156		OLD_FILES=$(rmel $f ${OLD_FILES})
157	fi
158done
159
160[[ -n ${OLD_FILES} ]] && rm ${OLD_FILES}
161for f in ${DL}; do
162	unpriv -f $f ftp -Vmo ${f} ${URL}${f}
163done
164
165# re-check signature after downloads
166echo Verifying sets.
167unpriv signify -qC -p "${SIGNIFY_KEY}" -x SHA256.sig ${SETS}
168
169cp bsd.rd /nbsd.upgrade
170ln -f /nbsd.upgrade /bsd.upgrade
171rm /nbsd.upgrade
172
173if ${REBOOT}; then
174	echo Upgrading.
175	exec reboot
176else
177	echo "Will upgrade on next reboot"
178fi
179