-
Notifications
You must be signed in to change notification settings - Fork 54
Expand file tree
/
Copy pathmkimg.sh
More file actions
executable file
·369 lines (321 loc) · 9.09 KB
/
Copy pathmkimg.sh
File metadata and controls
executable file
·369 lines (321 loc) · 9.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
#!/bin/sh
set -e
progname=${0##*/}
usage()
{
cat 1>&2 << _USAGE_
Usage: $progname [-s service] [-m megabytes] [-i image] [-x set]
[-k kernel] [-o] [-c URL] [-b]
Create a root image
-s service service name, default "rescue"
-r rootdir hand crafted root directory to use
-m megabytes image size in megabytes, default 10
-i image image name, default rescue-[arch].img
-x sets list of NetBSD sets, default rescue.tgz
-k kernel kernel to copy in the image
-c URL URL to a script to execute as finalizer
-o read-only root filesystem
-b make image BIOS bootable
_USAGE_
exit 1
}
options="s:m:i:r:x:k:c:boh"
[ -f tmp/build* ] && . tmp/build*
. service/common/vars
. service/common/funcs
. service/common/choupi
while getopts "$options" opt
do
case $opt in
s) svc="$OPTARG";;
m) megs="$OPTARG";;
i) img="$OPTARG";;
r) rootdir="$OPTARG";;
x) sets="$OPTARG";;
k) kernel="$OPTARG";;
c) curlsh="$OPTARG";;
b) biosboot=y;;
o) rofs=y;;
h) usage;;
*) usage;;
esac
done
export ARCH PKGVERS
arch=${ARCH:-"amd64"}
svc=${svc:-"rescue"}
megs=${megs:-"20"}
img=${img:-"rescue-${arch}.img"}
sets=${sets:-"rescue.tar.xz"}
rootdir=${rootdir:-}
kernel=${kernel:-}
curlsh=${curlsh:-}
rofs=${rofs:-}
ADDSETS=${ADDSETS:-}
ADDPKGS=${ADDPKGS:-}
SVCIMG=${SVCIMG:-}
OS=$(uname -s)
TAR=tar
FETCH=$(pwd)/scripts/fetch.sh
is_netbsd=
is_buildimg=
is_linux=
is_darwin=
is_openbsd=
is_freebsd=
is_unknown=
case $OS in
NetBSD|smolBSD)
is_netbsd=1
FETCH=ftp
;;
Linux)
is_linux=1
# avoid sets and pkgs untar warnings
TAR=bsdtar
;;
# those 2 will be ported at some point
OpenBSD)
is_openbsd=1
echo "${ERROR} unsupported for now"
exit 1
;;
FreeBSD)
is_freebsd=1
;;
*)
echo "${ERROR} unsupported for now"
exit 1
esac
[ -f "/BUILDIMG" ] && is_buildimg=1
for tool in $TAR # add more if needed
do
if ! command -v $tool >/dev/null; then
echo "$tool missing"
exit 1
fi
done
export TAR FETCH
if [ -z "$is_netbsd" ]; then
if [ -n "$MINIMIZE" ] || [ -f "service/${svc}/NETBSD_ONLY" ]; then
printf "\nThis image must be built on NetBSD!\n"
printf "Use the image builder instead: make SERVICE=$svc build\n"
exit 1
fi
# we're on native NetBSD, disk scan only on build image
elif [ -n "$is_buildimg" ]; then
disks="$(sysctl -n hw.disknames)"
# A secondary disk was passed, record disk that has no wedges
# $imgdev is the image device passed as second disk
if [ "$(echo \"$disks\"|wc -w)" -gt 2 ]; then
for disk in $disks
do
dkctl $disk listwedges 2>&1 | grep -q 'no wedges' && \
imgdev="${disk}"
done
fi
fi
[ -n "$is_linux" ] && u=M || u=m
# inherit from another image
if [ -n "$FROMIMG" ]; then
echo "${ARROW} using ${FROMIMG} as base image"
[ -z "$imgdev" ] && cp images/${FROMIMG} ${img} || \
dd if=images/${FROMIMG} of="${imgdev}" bs=1${u}
else
# only create image if secondary was not passed
[ -z "$imgdev" ] && \
dd if=/dev/zero of=./${img} bs=1${u} count=${megs}
fi
# are we building the builder or a service (secondary drive passed as param)
[ -z "$imgdev" ] && mnt=$(pwd)/mnt || mnt=${DRIVE2}
wedgename="${svc}root"
ffsmountopts="noatime"
if [ -n "$is_linux" ]; then
# no other image than builder image are ext2, don't check for FROMIMG
sgdisk --zap-all ${img} || true
# atribute 59 is "bootme" from /usr/include/sys/disklabel_gpt.h
sgdisk --new=1:0:0 --typecode=1:8300 --change-name=1:"$wedgename" \
--attributes=1:set:59 ${img}
# GitHub actions can't create loopXpY, use an offset
offset=$(sgdisk -i 1 ${img} | awk '/First sector/ {print $3}')
vnd=$(losetup -f --show -o $((offset * 512)) ${img})
mke2fs -O none ${vnd}
mount ${vnd} $mnt
mountfs="ext2fs"
elif [ -n "$is_freebsd" ]; then
[ -z "$imgdev" ] && imgdev="$(mdconfig -a -f $img)"
mountfs="ffs"
if [ -z "$FROMIMG" ]; then
gpart create -s gpt ${imgdev}
gpart add -a 512k -l "$wedgename" -t freebsd-ufs ${imgdev}
mountdev="${imgdev}p1"
newfs -o time -O1 -m0 /dev/${mountdev}
else
mountdev="${imgdev}p1"
fi
mount -o ${ffsmountopts} /dev/${mountdev} $mnt
else # NetBSD
if [ -z "$imgdev" ]; then # no secondary disk, create a vnd
imgdev=$(vndconfig -l|grep -m1 'not'|cut -f1 -d:)
vndconfig $imgdev $img
vnd=$imgdev # for later detach
fi
mountfs="ffs"
getwedge()
{
mountdev=$(dkctl ${1} listwedges|sed -n "s/\(dk.*\):\ ${wedgename}.*/\1/p")
if [ -z "$mountdev" ]; then
echo "${ERROR} no wedge, exiting"
exit 1
fi
echo "$mountdev"
}
if [ -z "$FROMIMG" ]; then
gpt create ${imgdev}
gpt add -a 512k -l "$wedgename" -t ${mountfs} ${imgdev}
gpt set -a bootme -i 1 ${imgdev}
eval $(gpt show ${imgdev}|awk '/NetBSD/ {print "startblk="$1; print "blkcnt="$2}')
mountdev=$(getwedge ${imgdev})
newfs -O1 -m0 /dev/${mountdev}
else
mountdev=$(getwedge ${imgdev})
fi
# sailor shrink is too agressive, journal is lost
[ -z "$MINIMIZE" ] && ffsmountopts="${ffsmountopts},log"
mount -o ${ffsmountopts} /dev/${mountdev} $mnt
fi
[ -f "service/${svc}/sailor.conf" ] && use_sailor=1
# additional packages
for pkg in ${ADDPKGS}; do
# case 1, artefacts created by the builder service
# minimization of the image via sailor is requested
# we need packages cleanly installed via pkgin
if [ -f /tmp/usrpkg.tgz ] && [ -n "$use_sailor" ]; then
echo "${ARROW} unpacking minimal env for sailor"
# needed to re-create packages with pkg_tarup
tar xfp /tmp/usrpkg.tgz -C /
pkgin -y in $ADDPKGS
# exit the loop, packages have been installed cleanly
break
fi
# case 2, no need for recorded, cleanly installed packages
# simply untar them to LOCALBASE
pkg="pkgs/${arch}/${pkg}.tgz"
[ ! -f ${pkg} ] && continue
eval $($TAR xfp $pkg -O +BUILD_INFO|grep ^LOCALBASE)
echo -n "extracting $pkg to ${LOCALBASE}.. "
mkdir -p ${mnt}/${LOCALBASE}
$TAR xfp ${pkg} --exclude='+*' -C ${mnt}/${LOCALBASE} || exit 1
echo done
done
# minimization of the image via sailor is requested
if [ -n "$MINIMIZE" ] && [ -n "$use_sailor" ] && \
[ -d /var/db/pkgin ]; then
echo "${ARROW} minimize image"
rm -rf ${mnt}/var/db/pkg*
cd ${BASEPATH}/sailor
export TERM=vt220
PKG_RCD_SCRIPTS=YES ./sailor.sh build /service/${svc}/sailor.conf
cd ..
# root fs is hand made
elif [ -n "$rootdir" ]; then
$TAR cfp - -C "$rootdir" . | $TAR xfp - -C ${mnt}
# use sets and customizations in services/
else
for s in ${sets} ${ADDSETS}
do
partial=
# we want to extract only part of the archive
if [ "$s" != "${s%:*}" ]; then
partial=".${s#*:}"
s=${s%:*}
fi
# don't prepend sets path if this is a full path
case $s in */*) ;; *) s="sets/${arch}/${s}" ;; esac
echo -n "extracting ${s}.. "
$TAR xfp ${s} -C ${mnt}/ ${partial} || exit 1
echo done
done
fi
# $rootdir can be relative, don't cd mnt yet
for d in sbin bin dev etc/include
do
mkdir -p ${mnt}/$d
done
[ -n "$rofs" ] && mountopt="ro" || mountopt="rw"
if [ "$mountfs" = "ffs" ]; then
mountopt="${mountopt},${ffsmountopts}"
fi
echo "NAME=${wedgename} / $mountfs $mountopt 1 1" > ${mnt}/etc/fstab
rsynclite service/${svc}/etc/ ${mnt}/etc/
rsynclite service/common/ ${mnt}/etc/include/
[ -d service/${svc}/packages ] && \
rsynclite service/${svc}/packages ${mnt}/
[ -n "$kernel" ] && cp -f $kernel ${mnt}/netbsd
# enter the mounted image root
cd $mnt
if [ "$svc" = "rescue" ]; then
for b in init mount_ext2fs
do
ln -s /rescue/$b sbin/
done
ln -s /rescue/sh bin/
fi
# warning, postinst operations are done on the builder
[ -d ../service/${svc}/postinst ] && \
for x in $(set +f; ls ../service/${svc}/postinst/*.sh)
do
# if SVCIMG variable exists, only process its script
if [ -n "$SVCIMG" ]; then
[ "${x##*/}" != "${SVCIMG}.sh" ] && continue
echo "SVCIMG=$SVCIMG" > etc/svc
fi
echo "executing $x"
[ -f $x ] && sh $x
done
# we don't need to hack our way around MAKEDEV on NetBSD / builder
if [ -z "$is_netbsd" ]; then
# newer NetBSD versions use tmpfs for /dev, sailor copies MAKEDEV from /dev
# backup MAKEDEV so imgbuilder rc can copy it
cp dev/MAKEDEV* etc/
# unionfs with ext2 leads to i/o error
# Linux and FreeBSD have different behaviors with -i
sed 's/-o union//g' dev/MAKEDEV >/tmp/MAKEDEV.tmp && \
mv /tmp/MAKEDEV.tmp dev/MAKEDEV && chmod +x dev/MAKEDEV
fi
# record wanted pkgsrc version
echo "PKGVERS=$PKGVERS" > etc/pkgvers
# proceed with caution
[ -n "$curlsh" ] && curl -sSL "$CURLSH" | /bin/sh
[ -n "$MINIMIZE" ] && \
rm -rf var/db/pkgin # wipe pkgin cache and db
# QEMU fw_cfg mountpoint
mkdir -p var/qemufwcfg
if [ -n "$biosboot" ]; then
cp /usr/mdec/boot ${mnt}
cat >${mnt}/boot.cfg<<EOF
timeout=0
consdev=${BIOSCONSOLE}
EOF
fi
disksize=$(du -s ${mnt}|cut -f1)
cd .. # get out mountpoint
umount $mnt
if [ -n "$MINIMIZE" ]; then
addspace=$(( ${MINIMIZE#*+} * 2048 ))
[ $addspace -eq 0 ] && addspace=$((disksize / 10))
disksize=$((disksize + addspace)) # give 10% MB more
echo "${ARROW} resizing image to $((disksize / 2048))MB"
resize_ffs -y -s ${disksize} /dev/${mountdev}
fsck_ffs -c4 -f -y /dev/${mountdev} >/dev/null
echo "$((disksize * 512))" > ${BASEPATH}/tmp/${img##*/}.size
fi
[ -n "$is_freebsd" ] && [ -n "$imgdev" ] && mdconfig -d -u ${imgdev#md}
[ -n "$is_linux" ] && losetup -d $vnd
if [ -n "$is_netbsd" ]; then
if [ -n "$biosboot" ]; then
gpt biosboot -i 1 ${imgdev}
installboot -v /dev/r${mountdev} /usr/mdec/bootxx_ffsv1
fi
[ -n "$vnd" ] && vndconfig -u $vnd
fi
exit 0