*.sh: use /bin/sh, not /bin/ksh hashbang
[unleashed-kayak.git] / build_image.sh
blob16eb359e7c03ba8a12c1b664f2842ec2fac2c71a
1 #!/bin/bash
4 # This file and its contents are supplied under the terms of the
5 # Common Development and Distribution License ("CDDL"), version 1.0.
6 # You may only use this file in accordance with the terms of version
7 # 1.0 of the CDDL.
9 # A full copy of the text of the CDDL should have accompanied this
10 # source. A copy of the CDDL is also available via the Internet at
11 # http://www.illumos.org/license/CDDL.
15 # Copyright 2017 OmniTI Computer Consulting, Inc. All rights reserved.
18 fail() {
19 echo "ERROR: $*"
20 exit 1
23 # NOTE --> The URL needs to be updated with every release.
24 # Change "bloody" to whatever release the current branch is.
25 PUBLISHER=unleashed
26 PKGURL1=${PKGURL1-/usr/nightly/packages/i386/nightly/repo.redist}
27 PKGURL2=${PKGURL2-/ws/oi-userland/amd64/repo}
28 : ${GZIP_CMD:=gzip}
29 SRCDIR=$(dirname $0)
30 DIDWORK=0
31 BUILDNUM=${VERSION//r/}
32 if [[ ${SRCDIR:0:1} != "/" ]]; then
33 SRCDIR=`pwd`/$SRCDIR
35 if [[ -z "${1}" ]]; then
36 echo "$0 <zfs pool> [checkpoint]"
37 exit 1
38 else
39 BASE=${1}
40 shift
41 BASEDIR=`zfs get -o value -H mountpoint $BASE`
43 MKFILEDIR=/tmp
44 WORKDIR=$BASEDIR
45 ROOTDIR=$WORKDIR/root
46 SVCCFG_DTD=${ROOTDIR}/usr/share/lib/xml/dtd/service_bundle.dtd.1
47 SVCCFG_REPOSITORY=${ROOTDIR}/etc/svc/repository.db
48 if [[ -f ${PREBUILT_ILLUMOS}/usr/src/cmd/svc/svccfg/svccfg-native ]]; then
49 SVCCFG=${PREBUILT_ILLUMOS}/usr/src/cmd/svc/svccfg/svccfg-native
50 else
51 echo "WARNING -- Not using 'native' svccfg, may hang on build."
52 echo " We recommend a pre-built illumos's svccfg-native."
53 echo " Set PREBUILT_ILLUMOS in your environment to point"
54 echo " to a built illumos-omnios repository."
55 SVCCFG=/usr/sbin/svccfg
57 export WORKDIR ROOTDIR SVCCFG_DTD SVCCFG_REPOSITORY SVCCFG
59 # This was uber-helpful
60 # http://alexeremin.blogspot.com/2008/12/preparing-small-miniroot-with-zfs-and.html
62 PKG=/bin/pkg
64 UNNEEDED_MANIFESTS="application/management/net-snmp.xml
65 application/pkg/pkg-server.xml application/pkg/pkg-mdns.xml
66 system/rmtmpfiles.xml system/mdmonitor.xml
67 system/fm/notify-params.xml system/device/allocate.xml
68 system/device/devices-audio.xml system/auditd.xml
69 system/metasync.xml system/pkgserv.xml system/fcoe_initiator.xml
70 system/metainit.xml system/zonestat.xml
71 system/cron.xml system/rbac.xml system/sac.xml
72 system/auditset.xml system/hotplug.xml
73 system/wusb.xml system/zones.xml
74 system/intrd.xml system/coreadm.xml
75 system/extended-accounting.xml
76 system/scheduler.xml
77 system/logadm-upgrade.xml system/resource-mgmt.xml
78 system/idmap.xml
79 network/ldap/client.xml network/shares/reparsed.xml
80 network/shares/group.xml network/inetd-upgrade.xml
81 network/smb/client.xml network/smb/server.xml
82 network/network-iptun.xml network/ipsec/policy.xml
83 network/ipsec/ipsecalgs.xml network/ipsec/ike.xml
84 network/ipsec/manual-key.xml network/forwarding.xml
85 network/inetd.xml network/npiv_config.xml
86 network/ssl/kssl-proxy.xml network/rpc/metamed.xml
87 network/rpc/mdcomm.xml network/rpc/gss.xml
88 network/rpc/bind.xml network/rpc/keyserv.xml
89 network/rpc/meta.xml network/rpc/metamh.xml
90 network/socket-filter-kssl.xml network/network-netcfg.xml
91 network/nfs/status.xml network/nfs/cbd.xml
92 network/nfs/nlockmgr.xml network/nfs/mapid.xml
93 network/nfs/client.xml network/network-ipqos.xml
94 network/security/ktkt_warn.xml network/security/krb5kdc.xml
95 network/security/kadmin.xml network/network-install.xml
96 network/bridge.xml network/network-initial.xml
97 network/network-ipmgmt.xml network/routing/legacy-routing.xml
98 network/network-service.xml network/network-physical.xml
99 network/network-netmask.xml network/dlmgmt.xml
100 network/network-location.xml network/ibd-post-upgrade.xml
101 network/network-routing-setup.xml network/network-loopback.xml
102 network/dns/client.xml network/dns/install.xml
103 network/dns/multicast.xml platform/i86pc/acpihpd.xml
104 system/hostid.xml system/power.xml system/pfexecd.xml
105 system/consadm.xml system/pools.xml system/console-login.xml
106 system/stmf.xml system/fmd.xml system/utmp.xml
107 system/poold.xml system/dumpadm.xml"
109 SYSTEM="system/boot/real-mode
110 system/boot/loader system/data/hardware-registry
111 system/extended-system-utilities
112 system/file-system/autofs system/file-system/nfs
113 system/file-system/udfs
114 system/flash/fwflash
115 system/ipc
116 system/library/policykit
117 system/library/processor
118 system/library/storage/fibre-channel/hbaapi
119 system/library/storage/fibre-channel/libsun_fc
120 system/library/storage/ima/header-ima
121 system/library/storage/ima
122 system/library/storage/libmpapi
123 system/library/storage/libmpscsi_vhci
124 system/network
125 system/storage/luxadm
126 system/storage/fibre-channel/port-utility"
128 DEBUG_PKGS="developer/debug/mdb"
130 PARTS="system/core-os system/kernel
131 shell/pipe-viewer editor/vim web/curl
132 developer/linker openssh
133 diagnostic/diskinfo shell/bash"
135 PKGS="$PARTS $SYSTEM"
137 if [ -n "$DEBUG" ]; then
138 PKGS="$PKGS $DEBUG_PKGS"
139 BIGROOT=1
141 CULL="python package/pkg snmp"
143 ID=`id -u`
144 if [[ "$ID" != "0" ]]; then
145 echo "must run as root"
146 exit 1
149 chkpt() {
150 SNAP=`zfs list -H -t snapshot $BASE/root@${1} 2> /dev/null`
151 if [[ "$DIDWORK" -ne "0" ]]; then
152 if [[ -n "$SNAP" ]]; then
153 zfs destroy $BASE/root@${1} || \
154 fail "zfs destroy ${1} failed"
156 zfs snapshot $BASE/root@${1} || fail "zfs snapshot failed"
158 if [[ "${1}" != "begin" ]]; then
159 echo " === Proceeding to phase $1 (zfs @${1}) ==="
160 zfs rollback -r $BASE/root@${1} || fail "zfs rollback failed"
161 else
162 echo " === Proceeding to phase $1 ==="
164 CHKPT=$1
165 DIDWORK=1
168 if [[ -n "$1" ]]; then
169 echo "Explicit checkpoint requested: '$1'"
170 CHKPT=$1
171 chkpt $CHKPT
173 if [[ -z "$CHKPT" ]]; then
174 CHKPT="begin"
177 declare -A keep_list
178 load_keep_list() {
179 for datafile in $*
181 FCNT=0
182 while read file
184 if [[ -n "$file" ]]; then
185 keep_list+=([$file]="x")
186 FCNT=$(($FCNT + 1))
188 done < <(cut -f2- -d/ $datafile)
189 echo " --- keeping $FCNT files from $datafile"
190 done
193 step() {
194 CHKPT=""
195 case "$1" in
197 "begin")
198 zfs destroy -r $BASE/root 2> /dev/null
199 zfs create -o compression=off $BASE/root || fail "zfs create failed"
200 chkpt pkg
203 "pkg")
205 echo "Creating image of $PUBLISHER from $PKGURL1"
206 $PKG image-create -F -p $PUBLISHER=$PKGURL1 $ROOTDIR || fail "image-create"
207 $PKG -R $ROOTDIR change-variant arch=i386 # FIXME hack
208 $PKG -R $ROOTDIR set-publisher -p $PKGURL2 || fail 'userland'
209 $PKG -R $ROOTDIR install $PKGS || fail "install"
210 chkpt fixup
213 "fixup")
215 echo "Fixing up install root"
216 (cp $ROOTDIR/etc/vfstab $WORKDIR/vfstab && \
217 awk '{if($3!="/"){print;}}' $WORKDIR/vfstab > $ROOTDIR/etc/vfstab && \
218 echo "/devices/ramdisk:a - / ufs - no nologging" >> $ROOTDIR/etc/vfstab) || \
219 fail "vfstab / updated"
220 rm $WORKDIR/vfstab
221 cp $ROOTDIR/lib/svc/seed/global.db $ROOTDIR/etc/svc/repository.db
223 sed -i '' 's,PASSREQ=YES,PASSREQ=NO,' $ROOTDIR/etc/default/login
225 ${SVCCFG} import ${ROOTDIR}/lib/svc/manifest/milestone/sysconfig.xml
226 for xml in $UNNEEDED_MANIFESTS; do
227 rm -f ${ROOTDIR}/lib/svc/manifest/$xml && echo " --- tossing $xml"
228 done
229 echo " --- initial manifest import"
230 # See if we can transform manifest-import to use the 'native' svccfg.
231 sed 's/\/usr\/sbin\/svccfg/\$SVCCFG/g' \
232 < ${ROOTDIR}/lib/svc/method/manifest-import \
233 > /tmp/manifest-import.$$
234 chmod 0755 /tmp/manifest-import.$$
235 export SVCCFG
236 /tmp/manifest-import.$$ -f ${ROOTDIR}/etc/svc/repository.db \
237 -d ${ROOTDIR}/lib/svc/manifest
238 /bin/rm -f /tmp/manifest-import.$$
240 ${SVCCFG} -s 'system/boot-archive' setprop 'start/exec=:true'
241 ${SVCCFG} -s 'system/manifest-import' setprop 'start/exec=:true'
242 ${SVCCFG} -s 'system/console-login' setprop 'start/exec=:true'
244 cat > $ROOTDIR/etc/inittab <<EOF
245 ap::sysinit:/sbin/autopush -f /etc/iu.ap
246 sp::sysinit:/sbin/soconfig -d /etc/sock2path.d
247 smf::sysinit:/lib/svc/bin/svc.startd
248 sh::respawn:/bin/sh -l </dev/console >/dev/console 2>/dev/console
251 echo "#!/bin/sh" > ${ROOTDIR}/lib/svc/method/manifest-import
252 echo "exit 0" >> ${ROOTDIR}/lib/svc/method/manifest-import
253 chmod 555 ${ROOTDIR}/lib/svc/method/manifest-import
254 chkpt cull
257 "cull")
258 if [[ -z "$BIGROOT" ]]; then
259 load_keep_list data/*
260 while read file
262 if [[ -n "$file" && \
263 ${keep_list[$file]} == "" && \
264 -e "$ROOTDIR/$file" && \
265 ! -d $ROOTDIR/$file ]] ; then
266 rm -f $ROOTDIR/$file
268 done < <(cd $ROOTDIR && find ./ | cut -c3-)
271 chkpt mkfs
274 "mkfs")
275 size=`zfs get -o value -Hp logicalreferenced $BASE/root`
276 size=$((size/1024 + size/1024/10))
277 echo " --- making miniroot ufs image of size ${size}k"
278 /usr/sbin/mkfile ${size}k $MKFILEDIR/miniroot || fail "mkfile"
279 lofidev=`/usr/sbin/lofiadm -a $MKFILEDIR/miniroot`
280 rlofidev=`echo $lofidev |sed s/lofi/rlofi/`
281 yes | /usr/sbin/newfs -m 0 $rlofidev 2> /dev/null > /dev/null || fail "newfs"
282 chkpt mount
285 "mount")
286 mkdir -p $WORKDIR/mnt
287 /usr/sbin/mount -o nologging $lofidev $WORKDIR/mnt || fail "mount"
288 chkpt copy
291 "copy")
292 pushd $ROOTDIR >/dev/null
293 /usr/bin/find . -not '(' -path ./var/pkg/'*' -or -path \
294 ./usr/share/man/'*' -or -path ./usr/share/doc/'*' -or -path \
295 ./usr/lib/python2.7/'*' -or -path ./usr/share/vim/'*' -or \
296 -path ./usr/share/zoneinfo/'*' ')' \
297 | /usr/bin/cpio -pdum $WORKDIR/mnt >/dev/null || fail "populate root"
298 /usr/sbin/devfsadm -r $WORKDIR/mnt > /dev/null
299 popd >/dev/null
301 pushd $SRCDIR >/dev/null
302 install -m 0755 mount_media $WORKDIR/mnt
303 install -m 0644 ksh.profile $WORKDIR/mnt/.profile
304 install -m 0755 install.sh $WORKDIR/mnt/install
305 popd >/dev/null
307 sed -i '' -e 's%^root:NP:%root::%' $WORKDIR/mnt/etc/shadow
309 if [[ -n "$DEBUG" ]]; then
310 cp $SRCDIR/anon.system $WORKDIR/mnt/etc/system
311 cp $SRCDIR/anon.dtrace.conf $WORKDIR/mnt/kernel/drv/dtrace.conf
313 chkpt umount
316 "umount")
317 /usr/sbin/umount $WORKDIR/mnt || fail "umount"
318 /usr/sbin/lofiadm -d $MKFILEDIR/miniroot || fail "lofiadm delete"
319 chkpt compress
322 "compress")
323 digest -a sha1 $MKFILEDIR/miniroot > $WORKDIR/boot_archive.hash
324 $GZIP_CMD -c -f $MKFILEDIR/miniroot > $WORKDIR/boot_archive.gz
325 rm -f $MKFILEDIR/miniroot
326 chmod 644 $WORKDIR/boot_archive*
327 echo " === Finished ==="
328 ls -l $WORKDIR/boot_archive.gz
331 esac
334 while [[ -n "$CHKPT" ]]; do
335 step $CHKPT
336 done