untrusted comment: verify with openbsd-65-base.pub
RWSZaRmt1LEQTzbjRTJp4rRUBy970yZKqERUmaaq965C4F1PqNkjQ+Lx6VslXx4DBDiAHBA0RU9E3sTMEZTZZ/7qKUPCAAnJyQg=

OpenBSD 6.5 errata 012, October 3, 2019:

Add the sysupgrade utility, that can be used to upgrade system to the
next release or a new snapshot.

Apply by doing:
   signify -Vep /etc/signify/openbsd-65-base.pub -x 012_sysupgrade.patch.sig \
       -m - | (cd /usr/src && patch -p0)

And then install sysupgrade:
   cd /usr/src/usr.sbin/sysupgrade
   make obj
   make
   make install

Index: usr.sbin/Makefile
===================================================================
RCS file: /cvs/src/usr.sbin/Makefile,v
retrieving revision 1.205
diff -u -p -r1.205 usr/sbin/Makefile
--- usr.sbin/Makefile   5 Apr 2019 21:07:11 -0000       1.205
+++ usr.sbin/Makefile   1 Oct 2019 21:10:47 -0000
@@ -17,9 +17,9 @@ SUBDIR=       ac accton acme-client acpidump a
       rmt route6d rpc.bootparamd rpc.lockd rpc.statd \
       sa sasyncd sensorsd slaacctl slowcgi smtpd \
       snmpctl snmpd spamdb switchctl switchd syslogc syslogd sysmerge \
-       syspatch tcpdrop tcpdump tftp-proxy tftpd tokenadm tokeninit \
-       traceroute trpt unbound unwindctl usbdevs user vmd vmctl vipw \
-       watchdogd wsconscfg wsfontload wsmoused zdump zic
+       syspatch sysupgrade tcpdrop tcpdump tftp-proxy tftpd tokenadm \
+       tokeninit traceroute trpt unbound unwindctl usbdevs user vmd vmctl \
+       vipw watchdogd wsconscfg wsfontload wsmoused zdump zic

.if (${YP:L} == "yes")
SUBDIR+=ypbind ypldap yppoll ypset ypserv
diff -urN usr.sbin/sysupgrade/Makefile usr.sbin/sysupgrade/Makefile
--- usr.sbin/sysupgrade/Makefile        Thu Jan  1 01:00:00 1970
+++ usr.sbin/sysupgrade/Makefile        Tue Oct  1 22:58:15 2019
@@ -0,0 +1,11 @@
+#      $OpenBSD$
+
+MAN=   sysupgrade.8
+
+SCRIPT=        sysupgrade.sh
+
+realinstall:
+       ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
+               ${.CURDIR}/${SCRIPT} ${DESTDIR}${BINDIR}/sysupgrade
+
+.include <bsd.prog.mk>
diff -urN usr.sbin/sysupgrade/sysupgrade.8 usr.sbin/sysupgrade/sysupgrade.8
--- usr.sbin/sysupgrade/sysupgrade.8    Thu Jan  1 01:00:00 1970
+++ usr.sbin/sysupgrade/sysupgrade.8    Tue Oct  1 22:58:15 2019
@@ -0,0 +1,87 @@
+.\"    $OpenBSD$
+.\"
+.\" Copyright (c) 2019 Florian Obser <[email protected]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: August 23 2019 $
+.Dt SYSUPGRADE 8
+.Os
+.Sh NAME
+.Nm sysupgrade
+.Nd upgrade system to the next release or a new snapshot
+.Sh SYNOPSIS
+.Nm
+.Op Fl fkn
+.Op Fl r | s
+.Op Ar installurl
+.Sh DESCRIPTION
+.Nm
+is a utility to upgrade
+.Ox
+to the next release or a new snapshot if available.
+.Pp
+.Nm
+downloads the necessary files to
+.Pa /home/_sysupgrade ,
+verifies them with
+.Xr signify 1 ,
+and copies bsd.rd to
+.Pa /bsd.upgrade .
+.Pp
+.Nm
+by default then reboots the system.
+The bootloader will automatically choose
+.Pa /bsd.upgrade ,
+triggering a one-shot upgrade using the files in
+.Pa /home/_sysupgrade .
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl f
+Force an already applied upgrade.
+The default is to upgrade to latest snapshot only if available.
+This option has no effect on releases.
+.It Fl k
+Keep the files in
+.Pa /home/_sysupgrade .
+By default they will be deleted after the upgrade.
+.It Fl n
+Fetch and verify the files and create
+.Pa /bsd.upgrade
+but do not reboot.
+.It Fl r
+Upgrade to the next release.
+This is the default if the system is currently running a release.
+.It Fl s
+Upgrade to a snapshot.
+This is the default if the system is currently running a snapshot.
+.El
+.Sh FILES
+.Bl -tag -width "/home/_sysupgrade" -compact
+.It Pa /etc/installurl
+.Ox
+mirror top-level URL for fetching an upgrade.
+.It Pa /home/_sysupgrade
+Directory the upgrade is downloaded to.
+.It Pa /bsd.upgrade
+The ramdisk kernel to trigger an unattended upgrade.
+.El
+.Sh SEE ALSO
+.Xr signify 1 ,
+.Xr installurl 5 ,
+.Xr release 8
+.Sh HISTORY
+.Nm
+first appeared in
+.Ox 6.6 .
diff -urN /tmp/scratch/sysupgrade.sh usr.sbin/sysupgrade/sysupgrade.sh
--- /tmp/scratch/sysupgrade.sh  Thu Jan  1 01:00:00 1970
+++ usr.sbin/sysupgrade/sysupgrade.sh   Tue Oct  1 22:58:15 2019
@@ -0,0 +1,208 @@
+#!/bin/ksh
+#
+# $OpenBSD$
+#
+# Copyright (c) 1997-2015 Todd Miller, Theo de Raadt, Ken Westerback
+# Copyright (c) 2015 Robert Peichaer <[email protected]>
+# Copyright (c) 2016, 2017 Antoine Jacoutot <[email protected]>
+# Copyright (c) 2019 Christian Weisgerber <[email protected]>
+# Copyright (c) 2019 Florian Obser <[email protected]>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+set -e
+umask 0022
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+ARCH=$(uname -m)
+SETSDIR=/home/_sysupgrade
+
+ug_err()
+{
+       echo "${1}" 1>&2 && return ${2:-1}
+}
+
+usage()
+{
+       ug_err "usage: ${0##*/} [-fkn] [-r | -s] [installurl]"
+}
+
+unpriv()
+{
+       local _file _rc=0 _user=_syspatch
+
+       if [[ $1 == -f ]]; then
+               _file=$2
+               shift 2
+       fi
+       if [[ -n ${_file} ]]; then
+               >${_file}
+               chown "${_user}" "${_file}"
+       fi
+       (($# >= 1))
+
+       eval su -s /bin/sh ${_user} -c "'$@'" || _rc=$?
+
+       [[ -n ${_file} ]] && chown root "${_file}"
+
+       return ${_rc}
+}
+
+# Remove all occurrences of first argument from list formed by the remaining
+# arguments.
+rmel() {
+       local _a=$1 _b _c
+
+       shift
+       for _b; do
+               [[ $_a != "$_b" ]] && _c="${_c:+$_c }$_b"
+       done
+       echo -n "$_c"
+}
+
+RELEASE=false
+SNAP=false
+FORCE=false
+KEEP=false
+REBOOT=true
+
+while getopts fknrs arg; do
+       case ${arg} in
+       f)      FORCE=true;;
+       k)      KEEP=true;;
+       n)      REBOOT=false;;
+       r)      RELEASE=true;;
+       s)      SNAP=true;;
+       *)      usage;;
+       esac
+done
+
+(($(id -u) != 0)) && ug_err "${0##*/}: need root privileges"
+
+if $RELEASE && $SNAP; then
+       usage
+fi
+
+set -A _KERNV -- $(sysctl -n kern.version |
+       sed 's/^OpenBSD \([0-9]\)\.\([0-9]\)\([^ ]*\).*/\1.\2 \3/;q')
+
+shift $(( OPTIND -1 ))
+
+case $# in
+0)     MIRROR=$(sed 's/#.*//;/^$/d' /etc/installurl) 2>/dev/null ||
+               MIRROR=https://cdn.openbsd.org/pub/OpenBSD
+       ;;
+1)     MIRROR=$1
+       ;;
+*)     usage
+esac
+
+if ! $RELEASE && [[ ${#_KERNV[*]} == 2 ]]; then
+       SNAP=true
+fi
+
+NEXT_VERSION=$(echo ${_KERNV[0]} + 0.1 | bc)
+
+if $SNAP; then
+       URL=${MIRROR}/snapshots/${ARCH}/
+else
+       URL=${MIRROR}/${NEXT_VERSION}/${ARCH}/
+fi
+
+if [[ -e ${SETSDIR} ]]; then
+       eval $(stat -s ${SETSDIR})
+       [[ $st_uid -eq 0 ]] ||
+                ug_err "${SETSDIR} needs to be owned by root:wheel"
+       [[ $st_gid -eq 0 ]] ||
+                ug_err "${SETSDIR} needs to be owned by root:wheel"
+       [[ $st_mode -eq 040755 ]] ||
+               ug_err "${SETSDIR} is not a directory with permissions 0755"
+else
+       mkdir -p ${SETSDIR}
+fi
+
+cd ${SETSDIR}
+
+unpriv -f SHA256.sig ftp -Vmo SHA256.sig ${URL}SHA256.sig
+
+_KEY=openbsd-${_KERNV[0]%.*}${_KERNV[0]#*.}-base.pub
+_NEXTKEY=openbsd-${NEXT_VERSION%.*}${NEXT_VERSION#*.}-base.pub
+
+read _LINE <SHA256.sig
+case ${_LINE} in
+*\ ${_KEY})    SIGNIFY_KEY=/etc/signify/${_KEY} ;;
+*\ ${_NEXTKEY})        SIGNIFY_KEY=/etc/signify/${_NEXTKEY} ;;
+*)             ug_err "invalid signing key" ;;
+esac
+
+[[ -f ${SIGNIFY_KEY} ]] || ug_err "cannot find ${SIGNIFY_KEY}"
+
+unpriv -f SHA256 signify -Ve -p "${SIGNIFY_KEY}" -x SHA256.sig -m SHA256
+rm SHA256.sig
+
+if cmp -s /var/db/installed.SHA256 SHA256 && ! $FORCE; then
+       echo "Already on latest snapshot."
+       exit 0
+fi
+
+# INSTALL.*, bsd*, *.tgz
+SETS=$(sed -n -e 's/^SHA256 (\(.*\)) .*/\1/' \
+    -e '/^INSTALL\./p;/^bsd/p;/\.tgz$/p' SHA256)
+
+OLD_FILES=$(ls)
+OLD_FILES=$(rmel SHA256 $OLD_FILES)
+DL=$SETS
+
+[[ -n ${OLD_FILES} ]] && echo Verifying old sets.
+for f in ${OLD_FILES}; do
+       if cksum -C SHA256 $f >/dev/null 2>&1; then
+               DL=$(rmel $f ${DL})
+               OLD_FILES=$(rmel $f ${OLD_FILES})
+       fi
+done
+
+[[ -n ${OLD_FILES} ]] && rm ${OLD_FILES}
+for f in ${DL}; do
+       unpriv -f $f ftp -Vmo ${f} ${URL}${f}
+done
+
+if [[ -n ${DL} ]]; then
+       echo Verifying sets.
+       unpriv cksum -qC SHA256 ${DL}
+fi
+
+${KEEP} && > keep
+
+cat <<__EOT >/auto_upgrade.conf
+Location of sets = disk
+Pathname to the sets = /home/_sysupgrade/
+Set name(s) = done
+Directory does not contain SHA256.sig. Continue without verification = yes
+__EOT
+
+if ! ${KEEP}; then
+       CLEAN=$(echo SHA256 ${SETS} | sed -e 's/ /,/g')
+       cat <<__EOT > /etc/rc.firsttime
+rm -f /home/_sysupgrade/{${CLEAN}}
+__EOT
+fi
+
+install -F -m 700 bsd.rd /bsd.upgrade
+sync
+
+if ${REBOOT}; then
+       echo Upgrading.
+       exec reboot
+else
+       echo "Will upgrade on next reboot"
+fi
Index: distrib/sets/lists//base/mi
===================================================================
RCS file: /cvs/src/distrib/sets/lists/base/mi,v
retrieving revision 1.946
diff -u -p -r1.946 mi
--- distrib/sets/lists//base/mi 5 Apr 2019 21:09:02 -0000       1.946
+++ distrib/sets/lists//base/mi 1 Oct 2019 21:49:24 -0000
@@ -2614,6 +2614,7 @@
./usr/sbin/syslogd
./usr/sbin/sysmerge
./usr/sbin/syspatch
+./usr/sbin/sysupgrade
./usr/sbin/tcpdrop
./usr/sbin/tcpdump
./usr/sbin/tftp-proxy
Index: distrib/sets/lists//man/mi
===================================================================
RCS file: /cvs/src/distrib/sets/lists/man/mi,v
retrieving revision 1.1492
diff -u -p -r1.1492 mi
--- distrib/sets/lists//man/mi  5 Apr 2019 21:09:02 -0000       1.1492
+++ distrib/sets/lists//man/mi  1 Oct 2019 21:49:24 -0000
@@ -2530,6 +2530,7 @@
./usr/share/man/man8/syslogd.8
./usr/share/man/man8/sysmerge.8
./usr/share/man/man8/syspatch.8
+./usr/share/man/man8/sysupgrade.8
./usr/share/man/man8/talkd.8
./usr/share/man/man8/tcpdrop.8
./usr/share/man/man8/tcpdump.8