Fri Jan 20 02:19:47 2012 UTC ()
While the resulting image from mkimage can always be mounted with vnd,
and then modified, it is much easier to let this late, user-oriented
customisation be done automatically.  These mods let mkimage change
information based on files in a "custom" directory, which can be set
in mkimage using -c customdir.

After all other configuration, the files under custom/ will be copied
into the main image.  The files under custom/ are taken into account
when performing autosizing.

Also, generalise the sets directory to point to the current machine
architecture, although this can be overwritten from the command line
by anyone making cross-images.

An example to make a user image with an embedded read-only 100 MB
iSCSI target:

% ./mkimage -c custom
=== making a new 272 MB image in usermode.img ===
272+0 records in
272+0 records out
285212672 bytes transferred in 7.616 secs (37449142 bytes/sec)
=== mounting image via vnd vnd0 ===
/dev/rvnd0a: 272.0MB (557056 sectors) block size 8192, fragment size 1024
        using 6 cylinder groups of 45.34MB, 5803 blks, 11264 inodes.
super-block backups (for fsck_ffs -b #) at:
32, 92880, 185728, 278576, 371424, 464272,
=== installing sets ===
base
etc
modules
=== performing customisations ===
=== making extra directories ===
=== customising /var/tmp ===
=== user customisations from files in custom ===
Filesystem    1K-blocks       Used      Avail %Cap Mounted on
/dev/vnd0a       269967     263958      -7489 102% /mnt
% ls -l -R custom
total 8
drwxr-xr-x  3 agc  agc  512 Jan 18 03:58 etc
drwxr-xr-x  2 agc  agc  512 Jan 18 04:00 iscsi

custom/etc:
total 8
drwxr-xr-x  2 agc  agc  512 Jan 18 03:58 iscsi
-rw-r--r--  1 agc  agc  564 Jan 18 03:58 rc.conf

custom/etc/iscsi:
total 6
-r--r--r--  1 agc  agc  799 Jan 18 04:27 targets

custom/iscsi:
total 102484
-rw-r--r--  1 agc  agc  104857600 Jan 18 04:00 iscsi-target0
% sudo vnconfig vnd0 usermode.img
% sudo mount /dev/vnd0a /mnt
% cat /mnt/etc/iscsi/targets
# $NetBSD: targets,v 1.2 2006/02/16 19:30:57 agc Exp $
#
# Structure of this file:
#
# + an extent is a straight (offset, length) pair of a file or device
#   it's the lowest common storage denominator
#   at least one is needed
# + a device is made up of one or more extents or other devices
#   devices can be added in a hierachical manner, to enhance resilience
# + in this example, no device definitions are necessary, as the target
#   will just use a simple extent for persistent storage
# + a target is made up of 1 or more devices
# The code does not support RAID1 recovery at present

# Simple file showing 1 extent, mapped straight into 1 target

# extent        file or device          start           length
extent0         /iscsi/iscsi-target0    0               100MB

# target        flags   storage         netmask
target0         ro      extent0         0.0.0.0/0
% ls -l /mnt/iscsi/iscsi-target0
-rw-r--r--  1 agc  agc  104857600 Jan 18 04:00 /mnt/iscsi/iscsi-target0
% diff custom/etc/iscsi/targets /mnt/etc/iscsi/targets
%


(agc)
diff -r1.1 -r1.2 src/distrib/utils/embedded/mkimage

cvs diff -r1.1 -r1.2 src/distrib/utils/embedded/mkimage (expand / switch to unified diff)

--- src/distrib/utils/embedded/mkimage 2012/01/15 02:01:02 1.1
+++ src/distrib/utils/embedded/mkimage 2012/01/20 02:19:47 1.2
@@ -1,16 +1,16 @@ @@ -1,16 +1,16 @@
1#! /bin/sh 1#! /bin/sh
2 2
3# $NetBSD: mkimage,v 1.1 2012/01/15 02:01:02 agc Exp $ 3# $NetBSD: mkimage,v 1.2 2012/01/20 02:19:47 agc Exp $
4 4
5# Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> 5# Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
6# All rights reserved. 6# All rights reserved.
7# 7#
8# Redistribution and use in source and binary forms, with or without 8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions 9# modification, are permitted provided that the following conditions
10# are met: 10# are met:
11# 1. Redistributions of source code must retain the above copyright 11# 1. Redistributions of source code must retain the above copyright
12# notice, this list of conditions and the following disclaimer. 12# notice, this list of conditions and the following disclaimer.
13# 2. Redistributions in binary form must reproduce the above copyright 13# 2. Redistributions in binary form must reproduce the above copyright
14# notice, this list of conditions and the following disclaimer in the 14# notice, this list of conditions and the following disclaimer in the
15# documentation and/or other materials provided with the distribution. 15# documentation and/or other materials provided with the distribution.
16# 16#
@@ -73,117 +73,125 @@ sizeone() { @@ -73,117 +73,125 @@ sizeone() {
73 case "$1" in  73 case "$1" in
74 *.tgz|*.tar.gz) 74 *.tgz|*.tar.gz)
75 tar tvzf "$1" | awk '{ tot += $5 } END { print tot }' 75 tar tvzf "$1" | awk '{ tot += $5 } END { print tot }'
76 ;; 76 ;;
77 *.tbz|*.tar.bz2) 77 *.tbz|*.tar.bz2)
78 tar tvjf "$1" | awk '{ tot += $5 } END { print tot }'  78 tar tvjf "$1" | awk '{ tot += $5 } END { print tot }'
79 ;; 79 ;;
80 *) 80 *)
81 echo 0 81 echo 0
82 ;;  82 ;;
83 esac 83 esac
84} 84}
85 85
86setsdir=/usr/build/release/i386/binary/sets 86bar="==="
87size=0 # in MB 87custom=custom
88overhead=8 # in MB 
89image=usermode.img 
90h=usermode1.$(uname -n) 88h=usermode1.$(uname -n)
 89image=usermode.img
 90overhead=8 # in MB
91sets="base etc modules" 91sets="base etc modules"
92usermodedirs="/var.run /var.log /etc.cow /root.cow /pkgs" 92setsdir=/usr/build/release/$(uname -m)/binary/sets
 93size=0 # in MB
93specialdirs="/kern /proc" 94specialdirs="/kern /proc"
94bar="===" 95usermodedirs="/var.run /var.log /etc.cow /root.cow /pkgs"
 96sudo="sudo"
95 97
96while [ $# -gt 0 ]; do 98while [ $# -gt 0 ]; do
97 case "$1" in 99 case "$1" in
98 -S) setsdir=$2; shift ;; 100 -S) setsdir=$2; shift ;;
 101 -c) custom=$2; shift ;;
99 -h) h=$2; shift ;; 102 -h) h=$2; shift ;;
100 -s) size=$2; shift ;; 103 -s) size=$2; shift ;;
101 -x) set -x ;; 104 -x) set -x ;;
102 *) break ;; 105 *) break ;;
103 esac 106 esac
104 shift 107 shift
105done 108done
106 109
107if [ $# -gt 0 ]; then 110if [ $# -gt 0 ]; then
108 # take the next argument as being the image name 111 # take the next argument as being the image name
109 image="$1" 112 image="$1"
110 shift 113 shift
111fi 114fi
112 115
113total=0 116total=0
114for s in ${sets}; do 117for s in ${sets}; do
115 total=$(expr ${total} + $(sizeone ${setsdir}/${s}.tgz)) 118 total=$(expr ${total} + $(sizeone ${setsdir}/${s}.tgz))
116done 119done
117total=$(expr \( ${total} / 1000000 \) + ${overhead}) 120# calculate size of custom files
 121custsize=0
 122if [ -d "${custom}" ]; then
 123 custsize=$(ls -lR "${custom}" | awk 'NF == 9 { tot += $5 } END { print tot }')
 124fi
 125total=$(expr \( \( ${total} + ${custsize} \) / 1000000 \) + ${overhead})
118if [ $size -eq 0 ]; then 126if [ $size -eq 0 ]; then
119 # auto-size the pkgs fs 127 # auto-size the pkgs fs
120 size=${total} 128 size=${total}
121else 129else
122 # check that we've been given enough space 130 # check that we've been given enough space
123 if [ ${total} -gt ${size} ]; then 131 if [ ${total} -gt ${size} ]; then
124 echo "File system size given as ${size} MB, but it needs ${total} MB" >&2 132 echo "File system size given as ${size} MB, but it needs ${total} MB" >&2
125 exit 1 133 exit 1
126 fi 134 fi
127fi 135fi
128 136
129echo "${bar} making a new ${size} MB image in ${image} ${bar}" 137echo "${bar} making a new ${size} MB image in ${image} ${bar}"
130dd if=/dev/zero of=${image} bs=1m count=${size} 138dd if=/dev/zero of=${image} bs=1m count=${size}
131 139
132vnddev=$(next_avail vnd) 140vnddev=$(next_avail vnd)
133echo "${bar} mounting image via vnd ${vnddev} ${bar}" 141echo "${bar} mounting image via vnd ${vnddev} ${bar}"
134sudo vnconfig ${vnddev} ${image} 142${sudo} vnconfig ${vnddev} ${image}
135sudo newfs /dev/r${vnddev}a 143${sudo} newfs /dev/r${vnddev}a
136sudo mount /dev/${vnddev}a /mnt 144${sudo} mount /dev/${vnddev}a /mnt
137 145
138echo "${bar} installing sets ${bar}" 146echo "${bar} installing sets ${bar}"
139(cd /mnt && 147(cd /mnt &&
140 for s in ${sets}; do 148 for s in ${sets}; do
141 echo ${s} 149 echo ${s}
142 sudo tar xpzf ${setsdir}/${s}.tgz 150 ${sudo} tar xpzf ${setsdir}/${s}.tgz
143 done 151 done
144) 152)
145 153
146echo "${bar} performing customisations ${bar}" 154echo "${bar} performing customisations ${bar}"
147sudo rm -f /mnt/etc/motd 155${sudo} rm -f /mnt/etc/motd
148 156
149tmp=/tmp/usermode.$$ 157tmp=/tmp/usermode.$$
150cat > ${tmp} << EOF 158cat > ${tmp} << EOF
151# NetBSD/usermode /etc/fstab 159# NetBSD/usermode /etc/fstab
152/dev/ld0a / ffs ro 1 1 160/dev/ld0a / ffs ro 1 1
153/dev/ld1a /pkgs ffs ro 1 2 161/dev/ld1a /pkgs ffs ro 1 2
154kernfs /kern kernfs rw 162kernfs /kern kernfs rw
155ptyfs /dev/pts ptyfs rw 163ptyfs /dev/pts ptyfs rw
156procfs /proc procfs rw 164procfs /proc procfs rw
157# mount /root as tmpfs on top of existing dir 165# mount /root as tmpfs on top of existing dir
158tmpfs /root.cow tmpfs rw,-s2M 0 0 166tmpfs /root.cow tmpfs rw,-s2M 0 0
159/root.cow /root union rw,hidden 0 0 167/root.cow /root union rw,hidden 0 0
160# mount /etc as tmpfs on top of existing dir 168# mount /etc as tmpfs on top of existing dir
161tmpfs /etc.cow tmpfs rw,-s12M 0 0 169tmpfs /etc.cow tmpfs rw,-s12M 0 0
162/etc.cow /etc union rw,hidden 0 0 170/etc.cow /etc union rw,hidden 0 0
163# mount /var/run as tmpfs on top of existing dir 171# mount /var/run as tmpfs on top of existing dir
164tmpfs /var.run tmpfs rw,-s1M 0 0 172tmpfs /var.run tmpfs rw,-s1M 0 0
165/var.run /var/run union rw,hidden - - 173/var.run /var/run union rw,hidden - -
166# mount /var/log as tmpfs on top of existing dir 174# mount /var/log as tmpfs on top of existing dir
167tmpfs /var.log tmpfs rw,-s10M 0 0 175tmpfs /var.log tmpfs rw,-s10M 0 0
168/var.log /var/log union rw,hidden - - 176/var.log /var/log union rw,hidden - -
169tmpfs /var/db tmpfs rw,-s8M 0 0 177tmpfs /var/db tmpfs rw,-s8M 0 0
170tmpfs /tmp tmpfs rw,-s32M 0 0 178tmpfs /tmp tmpfs rw,-s32M 0 0
171/dev/cd0a /cdrom cd9660 ro,noauto 179/dev/cd0a /cdrom cd9660 ro,noauto
172EOF 180EOF
173sudo mv ${tmp} /mnt/etc/fstab 181${sudo} mv ${tmp} /mnt/etc/fstab
174 182
175cat > ${tmp} << EOF 183cat > ${tmp} << EOF
176# $NetBSD: mkimage,v 1.1 2012/01/15 02:01:02 agc Exp $ 184# $NetBSD: mkimage,v 1.2 2012/01/20 02:19:47 agc Exp $
177# 185#
178# see rc.conf(5) for more information. 186# see rc.conf(5) for more information.
179# 187#
180# Use program=YES to enable program, NO to disable it. program_flags are 188# Use program=YES to enable program, NO to disable it. program_flags are
181# passed to the program on the command line. 189# passed to the program on the command line.
182# 190#
183 191
184# Load the defaults in from /etc/defaults/rc.conf (if it's readable). 192# Load the defaults in from /etc/defaults/rc.conf (if it's readable).
185# These can be overridden below. 193# These can be overridden below.
186# 194#
187if [ -r /etc/defaults/rc.conf ]; then 195if [ -r /etc/defaults/rc.conf ]; then
188 . /etc/defaults/rc.conf 196 . /etc/defaults/rc.conf
189fi 197fi
@@ -192,42 +200,48 @@ fi @@ -192,42 +200,48 @@ fi
192# 200#
193rc_configured=YES 201rc_configured=YES
194 202
195# make sure we have the right rw filesystem at boot 203# make sure we have the right rw filesystem at boot
196critical_filesystems_local="/var/db /var.run /var/run /var.log /var/log /etc.cow /etc /root.cow /root" 204critical_filesystems_local="/var/db /var.run /var/run /var.log /var/log /etc.cow /etc /root.cow /root"
197 205
198# Add local overrides below 206# Add local overrides below
199# 207#
200dhcpcd=YES 208dhcpcd=YES
201sshd=YES 209sshd=YES
202 210
203hostname=${h} 211hostname=${h}
204EOF 212EOF
205sudo mv ${tmp} /mnt/etc/rc.conf 213${sudo} mv ${tmp} /mnt/etc/rc.conf
206 214
207echo "${bar} making extra directories ${bar}" 215echo "${bar} making extra directories ${bar}"
208for d in ${usermodedirs}; do 216for d in ${usermodedirs}; do
209 sudo mkdir -p /mnt/${d} 217 ${sudo} mkdir -p /mnt/${d}
210done 218done
211for d in ${specialdirs}; do 219for d in ${specialdirs}; do
212 sudo mkdir -p /mnt/${d} 220 ${sudo} mkdir -p /mnt/${d}
213done 221done
214 222
215echo "${bar} customising /var/tmp ${bar}" 223echo "${bar} customising /var/tmp ${bar}"
216sudo rm -rf /mnt/var/tmp 224${sudo} rm -rf /mnt/var/tmp
217(cd /mnt/var && sudo ln -s /tmp tmp) 225(cd /mnt/var && ${sudo} ln -s /tmp tmp)
218 226
219# package-related stuff 227# package-related stuff
220(cat /mnt/etc/csh.cshrc;echo "setenv PKG_DBDIR /usr/pkg/.dbdir") > ${tmp} 228(cat /mnt/etc/csh.cshrc;echo "setenv PKG_DBDIR /usr/pkg/.dbdir") > ${tmp}
221sudo mv ${tmp} /mnt/etc/csh.cshrc 229${sudo} mv ${tmp} /mnt/etc/csh.cshrc
222(cat /mnt/etc/profile;echo "export PKG_DBDIR=/usr/pkg/.dbdir") > ${tmp} 230(cat /mnt/etc/profile;echo "export PKG_DBDIR=/usr/pkg/.dbdir") > ${tmp}
223sudo mv ${tmp} /mnt/etc/profile 231${sudo} mv ${tmp} /mnt/etc/profile
224(echo "PKG_DBDIR=/usr/pkg/.dbdir") > ${tmp} 232(echo "PKG_DBDIR=/usr/pkg/.dbdir") > ${tmp}
225sudo mv ${tmp} /mnt/etc/mk.conf 233${sudo} mv ${tmp} /mnt/etc/mk.conf
226(cd /mnt/usr && sudo ln -s /pkgs/usr/pkg pkg) 234(cd /mnt/usr && ${sudo} ln -s /pkgs/usr/pkg pkg)
 235
 236# last, customisation stage
 237if [ -d ${custom} ]; then
 238 echo "${bar} user customisations from files in ${custom} ${bar}"
 239 (cd ${custom} && ${sudo} pax -rwpe . /mnt)
 240fi
227 241
228df /mnt 242df /mnt
229 243
230sudo umount /mnt 244${sudo} umount /mnt
231sudo vnconfig -u ${vnddev} 245${sudo} vnconfig -u ${vnddev}
232 246
233exit 0 247exit 0