xref: /freebsd/tools/build/beinstall.sh (revision fc3bfe916e603950f509aeec656fa7112646971d)
1462819bbSWill Andrews#!/bin/sh
2462819bbSWill Andrews#
3462819bbSWill Andrews# Copyright (c) 2016 Will Andrews
4462819bbSWill Andrews# All rights reserved.
5462819bbSWill Andrews#
6462819bbSWill Andrews# Redistribution and use in source and binary forms, with or without
7462819bbSWill Andrews# modification, are permitted provided that the following conditions
8462819bbSWill Andrews# are met:
9462819bbSWill Andrews# 1. Redistributions of source code must retain the above copyright
10462819bbSWill Andrews#    notice, this list of conditions and the following disclaimer
11462819bbSWill Andrews#    in this position and unchanged.
12462819bbSWill Andrews# 2. Redistributions in binary form must reproduce the above copyright
13462819bbSWill Andrews#    notice, this list of conditions and the following disclaimer in the
14462819bbSWill Andrews#    documentation and/or other materials provided with the distribution.
15462819bbSWill Andrews#
16462819bbSWill Andrews# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17462819bbSWill Andrews# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18462819bbSWill Andrews# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19462819bbSWill Andrews# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20462819bbSWill Andrews# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21462819bbSWill Andrews# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22462819bbSWill Andrews# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23462819bbSWill Andrews# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24462819bbSWill Andrews# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25462819bbSWill Andrews# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26462819bbSWill Andrews#
27462819bbSWill Andrews# $FreeBSD$
28462819bbSWill Andrews#
29462819bbSWill Andrews##
30462819bbSWill Andrews# Install a boot environment using the current FreeBSD source tree.
31462819bbSWill Andrews# Requires a fully built world & kernel.
32462819bbSWill Andrews#
33462819bbSWill Andrews# Non-base tools required: beadm, pkg
34462819bbSWill Andrews#
35462819bbSWill Andrews# In a sandbox for the new boot environment, this script also runs etcupdate
36462819bbSWill Andrews# and pkg upgrade automatically in the sandbox.  Upon successful completion,
37462819bbSWill Andrews# the system will be ready to boot into the new boot environment.  Upon
38462819bbSWill Andrews# failure, the target boot environment will be destroyed.  In all cases, the
39462819bbSWill Andrews# running system is left untouched.
40462819bbSWill Andrews#
41462819bbSWill Andrews## Usage:
42462819bbSWill Andrews# beinstall [optional world/kernel flags e.g. KERNCONF]
43462819bbSWill Andrews#
44462819bbSWill Andrews## User modifiable variables - set these in the environment if desired.
45462819bbSWill Andrews# If not empty, 'pkg upgrade' will be skipped.
46462819bbSWill AndrewsNO_PKG_UPGRADE="${NO_PKG_UPGRADE:-""}"
47462819bbSWill Andrews# Config updater - 'etcupdate' and 'mergemaster' are supported.  Set to an
48462819bbSWill Andrews# empty string to skip.
49462819bbSWill AndrewsCONFIG_UPDATER="${CONFIG_UPDATER:-"etcupdate"}"
50462819bbSWill Andrews# Flags for etcupdate if used.
51462819bbSWill AndrewsETCUPDATE_FLAGS="${ETCUPDATE_FLAGS:-"-F"}"
52462819bbSWill Andrews# Flags for mergemaster if used.
53462819bbSWill AndrewsMERGEMASTER_FLAGS="${MERGEMASTER_FLAGS:-"-iFU"}"
54462819bbSWill Andrews
55462819bbSWill Andrews
56462819bbSWill Andrews########################################################################
57462819bbSWill Andrews## Constants
58462819bbSWill AndrewsETCUPDATE_CMD="etcupdate"
59462819bbSWill AndrewsMERGEMASTER_CMD="mergemaster"
60462819bbSWill Andrews
61462819bbSWill Andrews## Functions
62462819bbSWill Andrewscleanup() {
63462819bbSWill Andrews	[ -z "${cleanup_commands}" ] && return
64462819bbSWill Andrews	echo "Cleaning up ..."
65462819bbSWill Andrews	for command in ${cleanup_commands}; do
66462819bbSWill Andrews		${command}
67462819bbSWill Andrews	done
68462819bbSWill Andrews}
69462819bbSWill Andrews
70462819bbSWill Andrewserrx() {
71462819bbSWill Andrews	cleanup
72*fc3bfe91SEitan Adler	echo "error: $@"
73462819bbSWill Andrews	exit 1
74462819bbSWill Andrews}
75462819bbSWill Andrews
76462819bbSWill Andrewsrmdir_be() {
77462819bbSWill Andrews	chflags -R noschg ${BE_MNTPT}
78462819bbSWill Andrews	rm -rf ${BE_MNTPT}
79462819bbSWill Andrews}
80462819bbSWill Andrews
81462819bbSWill Andrewscleanup_be() {
82462819bbSWill Andrews	beadm destroy -F ${BENAME}
83462819bbSWill Andrews}
84462819bbSWill Andrews
85462819bbSWill Andrewsupdate_mergemaster() {
86462819bbSWill Andrews	mergemaster -m $(pwd) -D ${BE_MNTPT} -t ${BE_MM_ROOT} ${MERGEMASTER_FLAGS}
87462819bbSWill Andrews}
88462819bbSWill Andrews
89462819bbSWill Andrewsupdate_etcupdate() {
90462819bbSWill Andrews	etcupdate -s $(pwd) -D ${BE_MNTPT} ${ETCUPDATE_FLAGS} || return $?
91462819bbSWill Andrews	etcupdate resolve -D ${BE_MNTPT}
92462819bbSWill Andrews}
93462819bbSWill Andrews
94462819bbSWill Andrews
95462819bbSWill Andrewscleanup_commands=""
96462819bbSWill Andrewstrap 'errx "Interrupt caught"' HUP INT TERM
97462819bbSWill Andrews
98462819bbSWill Andrews[ "$(whoami)" != "root" ] && errx "Must be run as root"
99462819bbSWill Andrews
100462819bbSWill Andrews[ ! -f "Makefile.inc1" ] && errx "Must be in FreeBSD source tree"
101462819bbSWill Andrewsobjdir=$(make -V .OBJDIR 2>/dev/null)
102462819bbSWill Andrews[ ! -d "${objdir}" ] && errx "Must have built FreeBSD from source tree"
103462819bbSWill Andrews
1047d4a3185SWill Andrews# May be a worktree, in which case .git is a file, not a directory.
1057d4a3185SWill Andrewsif [ -e .git ] ; then
106462819bbSWill Andrews    commit_time=$(git show --format='%ct' 2>/dev/null | head -1)
107462819bbSWill Andrews    [ $? -ne 0 ] && errx "Can't lookup git commit timestamp"
108462819bbSWill Andrews    commit_ts=$(date -r ${commit_time} '+%Y%m%d.%H%M%S')
109462819bbSWill Andrewselif [ -d .svn ] ; then
110*fc3bfe91SEitan Adler      if [ -e /usr/bin/svnlite ]; then
111*fc3bfe91SEitan Adler        svn=/usr/bin/svnlite
112*fc3bfe91SEitan Adler      elif [ -e /usr/local/bin/svn ]; then
113*fc3bfe91SEitan Adler        svn=/usr/local/bin/svn
1141ff30c6aSBrad Davis      else
115*fc3bfe91SEitan Adler        errx "Unable to find subversion"
1161ff30c6aSBrad Davis      fi
117*fc3bfe91SEitan Adler      commit_ts="$( "$svn" info --show-item last-changed-date | sed -e 's/\..*//' -e 's/T/./' -e 's/-//g' -e s'/://g' )"
118462819bbSWill Andrews    [ $? -ne 0 ] && errx "Can't lookup Subversion commit timestamp"
119462819bbSWill Andrewselse
120*fc3bfe91SEitan Adler    errx "Unable to determine source control type"
121462819bbSWill Andrewsfi
122462819bbSWill Andrews
123462819bbSWill Andrewscommit_ver=$(${objdir}/bin/freebsd-version/freebsd-version -u 2>/dev/null)
124462819bbSWill Andrews[ -z "${commit_ver}" ] && errx "Unable to determine FreeBSD version"
125462819bbSWill Andrews
126462819bbSWill AndrewsBENAME="${commit_ver}-${commit_ts}"
127462819bbSWill Andrews
128462819bbSWill AndrewsBE_TMP=$(mktemp -d /tmp/beinstall.XXXXXX)
129462819bbSWill Andrews[ $? -ne 0 -o ! -d ${BE_TMP} ] && errx "Unable to create mountpoint"
130462819bbSWill Andrews[ -z "$NO_CLEANUP_BE" ] && cleanup_commands="rmdir_be ${cleanup_commands}"
131462819bbSWill AndrewsBE_MNTPT=${BE_TMP}/mnt
132462819bbSWill AndrewsBE_MM_ROOT=${BE_TMP}/mergemaster # mergemaster will create
133462819bbSWill Andrewsmkdir -p ${BE_MNTPT}
134462819bbSWill Andrews
135462819bbSWill Andrewsbeadm create ${BENAME} >/dev/null || errx "Unable to create BE ${BENAME}"
136462819bbSWill Andrews[ -z "$NO_CLEANUP_BE" ] && cleanup_commands="cleanup_be ${cleanup_commands}"
137462819bbSWill Andrews
138462819bbSWill Andrewsbeadm mount ${BENAME} ${BE_TMP}/mnt || errx "Unable to mount BE ${BENAME}."
139462819bbSWill Andrews
140462819bbSWill Andrewsecho "Mounted ${BENAME} to ${BE_MNTPT}, performing install/update ..."
141*fc3bfe91SEitan Adlermake "$@" DESTDIR=${BE_MNTPT} installkernel || errx "Installkernel failed!"
142*fc3bfe91SEitan Adlermake "$@" DESTDIR=${BE_MNTPT} installworld || errx "Installworld failed!"
143462819bbSWill Andrews
144462819bbSWill Andrewsif [ -n "${CONFIG_UPDATER}" ]; then
145462819bbSWill Andrews	"update_${CONFIG_UPDATER}"
146462819bbSWill Andrews	[ $? -ne 0 ] && errx "${CONFIG_UPDATER} failed!"
147462819bbSWill Andrewsfi
148462819bbSWill Andrews
149462819bbSWill AndrewsBE_PKG="chroot ${BE_MNTPT} env ASSUME_ALWAYS_YES=true pkg"
150462819bbSWill Andrewsif [ -z "${NO_PKG_UPGRADE}" ]; then
151462819bbSWill Andrews	${BE_PKG} update || errx "Unable to update pkg"
152462819bbSWill Andrews	${BE_PKG} upgrade || errx "Unable to upgrade pkgs"
153462819bbSWill Andrewsfi
154462819bbSWill Andrews
155462819bbSWill Andrewsbeadm unmount ${BENAME} || errx "Unable to unmount BE"
156462819bbSWill Andrewsrmdir_be
157462819bbSWill Andrewsbeadm activate ${BENAME} || errx "Unable to activate BE"
158462819bbSWill Andrewsecho
159462819bbSWill Andrewsbeadm list
160462819bbSWill Andrewsecho
161462819bbSWill Andrewsecho "Boot environment ${BENAME} setup complete; reboot to use it."
162