mkimage revision 1.7
11.1Sagc#! /bin/sh 21.1Sagc 31.7Schristos# $NetBSD: mkimage,v 1.7 2013/01/13 21:51:47 christos Exp $ 41.1Sagc 51.1Sagc# Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> 61.1Sagc# All rights reserved. 71.1Sagc# 81.1Sagc# Redistribution and use in source and binary forms, with or without 91.1Sagc# modification, are permitted provided that the following conditions 101.1Sagc# are met: 111.1Sagc# 1. Redistributions of source code must retain the above copyright 121.1Sagc# notice, this list of conditions and the following disclaimer. 131.1Sagc# 2. Redistributions in binary form must reproduce the above copyright 141.1Sagc# notice, this list of conditions and the following disclaimer in the 151.1Sagc# documentation and/or other materials provided with the distribution. 161.1Sagc# 171.1Sagc# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 181.1Sagc# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 191.1Sagc# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 201.1Sagc# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 211.1Sagc# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 221.1Sagc# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231.1Sagc# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241.1Sagc# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251.1Sagc# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 261.1Sagc# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271.1Sagc# 281.1Sagc 291.1Sagc# find next available vnd, from kre 301.1Sagcnext_avail () 311.1Sagc{ 321.1Sagc local dev="$1" 331.1Sagc local N=$(( ${#dev} + 1 )) 341.1Sagc local unit units 351.1Sagc 361.1Sagc units=$( 371.1Sagc sysctl -n hw.disknames | 381.1Sagc tr ' ' '\012' | 391.1Sagc grep '^'"${dev}"'[0-9]' | 401.1Sagc sort -n -k 1.$N ) 411.1Sagc 421.1Sagc test -z "${units}" && { 431.1Sagc test -e "/dev/${dev}0a" || { 441.1Sagc echo >&2 "No ${dev}s available!" 451.1Sagc return 1 461.1Sagc } 471.1Sagc echo "${dev}0" 481.1Sagc return 491.1Sagc } 501.1Sagc 511.1Sagc N=0 521.1Sagc for unit in ${units} 531.1Sagc do 541.1Sagc if [ "${unit}" = "${dev}${N}" ] 551.1Sagc then 561.1Sagc N=$(( N + 1 )) 571.1Sagc else 581.1Sagc echo "${dev}${N}" 591.1Sagc return 601.1Sagc fi 611.1Sagc done 621.1Sagc 631.1Sagc test -e /dev/"${dev}${N}a" || { 641.1Sagc echo >&2 "All ${dev}s in use" 651.1Sagc return 1 661.1Sagc } 671.1Sagc 681.1Sagc echo "${dev}${N}" 691.1Sagc} 701.1Sagc 711.1Sagc# find the size of the gzipped files in a .tgz archive 721.1Sagcsizeone() { 731.4Schristos if [ ! -f "$1" ] 741.4Schristos then 751.4Schristos echo "$PROG: Missing set $1" 1>&2 761.4Schristos echo 0 771.4Schristos return; 781.4Schristos fi 791.1Sagc case "$1" in 801.1Sagc *.tgz|*.tar.gz) 811.1Sagc tar tvzf "$1" | awk '{ tot += $5 } END { print tot }' 821.1Sagc ;; 831.1Sagc *.tbz|*.tar.bz2) 841.1Sagc tar tvjf "$1" | awk '{ tot += $5 } END { print tot }' 851.1Sagc ;; 861.1Sagc *) 871.1Sagc echo 0 881.1Sagc ;; 891.1Sagc esac 901.1Sagc} 911.1Sagc 921.4Schristosusage() { 931.4Schristos cat << EOF 1>&2 941.4SchristosUsage: $PROG [-S <setsdir>] [-c <custom-files-dir>] [-h <host-arch>] [-s <size>] 951.4SchristosEOF 961.4Schristosexit 1 971.4Schristos} 981.4Schristos 991.4Schristosfinish() { 1001.4Schristos cleanup 1011.4Schristos ${sudo} umount ${mnt} 1021.4Schristos ${sudo} vnconfig -u ${vnddev} 1031.4Schristos} 1041.4Schristos 1051.4Schristostrap finish 0 1 2 3 15 1061.4SchristosDIR="$(dirname "$0")" 1071.4SchristosPROG="$(basename "$0")" 1081.2Sagcbar="===" 1091.4Schristossudo= 1101.7Schristosmnt="${TMPDIR:-/tmp}/image.$$" 1111.4Schristossrc="/usr/src" 1121.4Schristosobj="/usr/obj" 1131.4Schristos 1141.4Schristos# First pass for options to get the host 1151.4SchristosOPTS="S:c:h:s:x" 1161.4Schristoswhile getopts "$OPTS" f 1171.4Schristosdo 1181.4Schristos case $f in 1191.4Schristos h) h="$OPTARG";; 1201.4Schristos *) ;; 1211.4Schristos esac 1221.4Schristosdone 1231.4Schristos 1241.4Schristosif [ -z "$h" ] 1251.4Schristosthen 1261.4Schristos usage 1271.4Schristosfi 1281.4Schristos 1291.5Schristosif [ ! -f "${DIR}/conf/${h}.conf" ] 1301.4Schristosthen 1311.5Schristos echo $PROG: ${DIR}/conf/${h}.conf is not present 1>&2 1321.4Schristos exit 1 1331.4Schristosfi 1341.4Schristos 1351.5Schristos. "${DIR}/conf/${h}.conf" 1361.4Schristos 1371.4SchristosOPTIND=1 1381.4Schristoswhile getopts "$OPTS" f 1391.4Schristosdo 1401.4Schristos case $f in 1411.4Schristos S) setsdir="$OPTARG";; 1421.4Schristos c) custom="$OPTARG";; 1431.4Schristos h) ;; 1441.4Schristos s) size="$OPTARG";; 1451.4Schristos x) set -x;; 1461.6Schristos *) usage;; 1471.1Sagc esac 1481.1Sagcdone 1491.1Sagc 1501.4Schristosshift $(( "$OPTIND" - 1 )) 1511.4Schristosif [ -n "$1" ]; then 1521.1Sagc # take the next argument as being the image name 1531.1Sagc image="$1" 1541.1Sagc shift 1551.1Sagcfi 1561.1Sagc 1571.1Sagctotal=0 1581.1Sagcfor s in ${sets}; do 1591.4Schristos one="$(sizeone ${setsdir}/${s}.tgz)" 1601.4Schristos total=$(( ${total} + ${one} )) 1611.1Sagcdone 1621.2Sagc# calculate size of custom files 1631.2Sagccustsize=0 1641.2Sagcif [ -d "${custom}" ]; then 1651.2Sagc custsize=$(ls -lR "${custom}" | awk 'NF == 9 { tot += $5 } END { print tot }') 1661.2Sagcfi 1671.4Schristostotal=$(( ( ( ${total} + ${custsize} ) / 1000000 ) + ${overhead} )) 1681.1Sagcif [ $size -eq 0 ]; then 1691.1Sagc # auto-size the pkgs fs 1701.1Sagc size=${total} 1711.1Sagcelse 1721.1Sagc # check that we've been given enough space 1731.1Sagc if [ ${total} -gt ${size} ]; then 1741.4Schristos echo "$PROG: Given size is ${size} MB, but we need ${total} MB" >&2 1751.1Sagc exit 1 1761.1Sagc fi 1771.1Sagcfi 1781.1Sagc 1791.1Sagcecho "${bar} making a new ${size} MB image in ${image} ${bar}" 1801.4Schristosdd if=/dev/zero of=${image} bs=1m count=${size} conv=sparse 1811.1Sagc 1821.1Sagcvnddev=$(next_avail vnd) 1831.1Sagcecho "${bar} mounting image via vnd ${vnddev} ${bar}" 1841.2Sagc${sudo} vnconfig ${vnddev} ${image} 1851.4Schristos${sudo} mkdir -p ${mnt} 1861.4Schristosmake_filesystems 1871.4Schristos 1881.4Schristos${sudo} mkdir -p ${mnt}/etc ${mnt}/dev 1891.1Sagc 1901.1Sagcecho "${bar} installing sets ${bar}" 1911.4Schristos(cd ${mnt} && 1921.1Sagc for s in ${sets}; do 1931.4Schristos if [ -f "${s}" ]; then 1941.4Schristos echo ${s} 1951.4Schristos ${sudo} tar xpzf ${setsdir}/${s}.tgz 1961.4Schristos fi 1971.1Sagc done 1981.1Sagc) 1991.1Sagc 2001.1Sagcecho "${bar} performing customisations ${bar}" 2011.1Sagc 2021.4Schristosmake_fstab 2031.1Sagc 2041.4Schristos${sudo} cat > ${mnt}/etc/rc.conf << EOF 2051.1Sagc# 2061.1Sagc# see rc.conf(5) for more information. 2071.1Sagc# 2081.1Sagc# Use program=YES to enable program, NO to disable it. program_flags are 2091.1Sagc# passed to the program on the command line. 2101.1Sagc# 2111.1Sagc 2121.1Sagc# Load the defaults in from /etc/defaults/rc.conf (if it's readable). 2131.1Sagc# These can be overridden below. 2141.1Sagc# 2151.1Sagcif [ -r /etc/defaults/rc.conf ]; then 2161.1Sagc . /etc/defaults/rc.conf 2171.1Sagcfi 2181.1Sagc 2191.1Sagc# If this is not set to YES, the system will drop into single-user mode. 2201.1Sagc# 2211.1Sagcrc_configured=YES 2221.1Sagc 2231.4Schristoshostname=${h} 2241.1Sagc 2251.4SchristosEOF 2261.1Sagc 2271.4Schristoscustomize 2281.1Sagc 2291.1Sagcfor d in ${specialdirs}; do 2301.4Schristos ${sudo} mkdir -p ${mnt}/${d} 2311.1Sagcdone 2321.1Sagc 2331.4Schristosif [ \( -n "${custom}" \) -a \( -d "${custom}" \) ]; then 2341.2Sagc echo "${bar} user customisations from files in ${custom} ${bar}" 2351.4Schristos (cd ${custom} && ${sudo} pax -rwpe . ${mnt}) 2361.2Sagcfi 2371.1Sagc 2381.1Sagcexit 0 239