Project

General

Profile

Download (70.9 KB) Statistics
| Branch: | Tag: | Revision:
1
#!/bin/sh
2
#
3
# builder_common.sh
4
#
5
# Copyright (c) 2004-2015 Electric Sheep Fencing, LLC
6
# Copyright (C) 2014 Ermal Luçi
7
# All rights reserved.
8
#
9
# NanoBSD portions of the code
10
# Copyright (c) 2005 Poul-Henning Kamp.
11
# and copied from nanobsd.sh
12
# All rights reserved.
13
#
14
# FreeSBIE portions of the code
15
# Copyright (c) 2005 Dario Freni
16
# and copied from FreeSBIE project
17
# All rights reserved.
18
#
19
# Redistribution and use in source and binary forms, with or without
20
# modification, are permitted provided that the following conditions
21
# are met:
22
#
23
# 1. Redistributions of source code must retain the above copyright
24
#    notice, this list of conditions and the following disclaimer.
25
#
26
# 2. Redistributions in binary form must reproduce the above copyright
27
#    notice, this list of conditions and the following disclaimer in the
28
#    documentation and/or other materials provided with the distribution.
29
#
30
# THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
31
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
34
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
41
# OF THE POSSIBILITY OF SUCH DAMAGE.
42
# Redistribution and use in source and binary forms, with or without
43
# modification, are permitted provided that the following conditions are met:
44
#
45

    
46
if [ -n "${IMAGES_FINAL_DIR}" -a "${IMAGES_FINAL_DIR}" != "/" ]; then
47
	mkdir -p ${IMAGES_FINAL_DIR}
48
else
49
	echo "IMAGES_FINAL_DIR is not defined"
50
	print_error_pfS
51
fi
52

    
53
lc() {
54
	echo "${1}" | tr '[[:upper:]]' '[[:lower:]]'
55
}
56

    
57
git_last_commit() {
58
	export CURRENT_COMMIT=$(git -C ${BUILDER_ROOT} log -1 --format='%H')
59
	export CURRENT_AUTHOR=$(git -C ${BUILDER_ROOT} log -1 --format='%an')
60
	echo ">>> Last known commit $CURRENT_AUTHOR - $CURRENT_COMMIT"
61
	echo "$CURRENT_COMMIT" > $SCRATCHDIR/build_commit_info.txt
62
}
63

    
64
# Create core pkg repository
65
core_pkg_create_repo() {
66
	if [ ! -d "${CORE_PKG_PATH}/All" ]; then
67
		return
68
	fi
69

    
70
	echo -n ">>> Creating core packages repository... "
71
	if pkg repo -q "${CORE_PKG_PATH}"; then
72
		echo "Done!"
73
	else
74
		echo "Failed!"
75
		print_error_pfS
76
	fi
77
}
78

    
79
# Create core pkg (base, kernel)
80
core_pkg_create() {
81
	local _template="${1}"
82
	local _flavor="${2}"
83
	local _version="${3}"
84
	local _root="${4}"
85

    
86
	[ -d "${CORE_PKG_TMP}" ] \
87
		&& rm -rf ${CORE_PKG_TMP}
88

    
89
	local _templates_path=${BUILDER_TOOLS}/templates/core_pkg/${_template}
90
	local _template_metadir=${_templates_path}/metadir
91
	local _metadir=${CORE_PKG_TMP}/${_template}_metadir
92

    
93
	if [ ! -d ${_template_metadir} ]; then
94
		echo "ERROR: Template dir not found for pkg ${_template}"
95
		exit
96
	fi
97

    
98
	mkdir -p ${CORE_PKG_TMP}
99

    
100
	cp -r ${_template_metadir} ${_metadir}
101

    
102
	local _manifest=${_metadir}/+MANIFEST
103
	local _plist=${CORE_PKG_TMP}/${_template}_plist
104
	local _exclude_plist=${CORE_PKG_TMP}/${_template}_exclude_plist
105

    
106
	if [ -f "${_templates_path}/pkg-plist" ]; then
107
		cp ${_templates_path}/pkg-plist ${_plist}
108
	else
109
		(cd ${_root} && find . -type f -or -type l | sed 's,^.,,' | sort -u) > ${_plist}
110
	fi
111

    
112
	if [ -f "${_templates_path}/exclude_plist" ]; then
113
		cp ${_templates_path}/exclude_plist ${_exclude_plist}
114
	else
115
		touch ${_exclude_plist}
116
	fi
117

    
118
	sed \
119
		-i '' \
120
		-e "s,%%PRODUCT_NAME%%,${PRODUCT_NAME},g" \
121
		-e "s,%%PRODUCT_URL%%,${PRODUCT_URL},g" \
122
		-e "s,%%FLAVOR%%,${_flavor},g" \
123
		-e "s,%%VERSION%%,${_version},g" \
124
		${_metadir}/* \
125
		${_plist} \
126
		${exclude_plist}
127

    
128
	if [ -f "${_exclude_plist}" ]; then
129
		sort -u ${_exclude_plist} > ${_plist}.exclude
130
		mv ${_plist} ${_plist}.tmp
131
		comm -23 ${_plist}.tmp ${_plist}.exclude > ${_plist}
132
		rm -f ${_plist}.tmp ${plist}.exclude
133
	fi
134

    
135
	mkdir -p ${CORE_PKG_PATH}/All
136
	if ! pkg create -o ${CORE_PKG_PATH}/All -p ${_plist} -r ${_root} -m ${_metadir}; then
137
		echo ">>> ERROR: Error building package ${_template} ${_flavor}"
138
		print_error_pfS
139
	fi
140
}
141

    
142
# This routine will output that something went wrong
143
print_error_pfS() {
144
	echo
145
	echo "####################################"
146
	echo "Something went wrong, check errors!" >&2
147
	echo "####################################"
148
	echo
149
	echo "NOTE: a lot of times you can run './build.sh --clean-builder' to resolve."
150
	echo
151
	if [ "$1" != "" ]; then
152
		echo $1
153
	fi
154
	[ -n "${LOGFILE}" -a -f "${LOGFILE}" ] && \
155
		echo "Log saved on ${LOGFILE}" && \
156
		tail -n20 ${LOGFILE} >&2
157
	echo
158
	kill $$
159
	exit 1
160
}
161

    
162
prestage_on_ram_setup() {
163
	[ -d "${STAGE_CHROOT_DIR}" ] \
164
		|| mkdir -p ${STAGE_CHROOT_DIR}
165
	[ -d "${FINAL_CHROOT_DIR}" ] \
166
		|| mkdir -p ${FINAL_CHROOT_DIR}
167

    
168
	_AVAIL_MEM=$(($(sysctl -n hw.usermem) / 1024 / 1024))
169
	if [ $_AVAIL_MEM -lt 2000 ]; then
170
		echo ">>> Builder has less than 2GiB RAM skipping memory disks"
171
		return
172
	else
173
		echo "######################################################################################"
174
		echo
175
		echo ">>> Builder has more than 2GiB RAM enabling memory disks"
176
		echo ">>> WARNING: Remember to remove these memory disks by running $0 --disable-memorydisks"
177
		echo
178
		echo "######################################################################################"
179
	fi
180

    
181
	if df /dev/ufs/prestagebacking >/dev/null 2>&1; then
182
		echo ">>> Detected preexisting memory disk enabled for ${STAGE_CHROOT_DIR}."
183
	else
184
		mdconfig -a -t swap -u 10001 -s ${MEMORYDISK_SIZE}
185
		newfs -L prestagebacking -U /dev/md10001
186
		mount /dev/ufs/prestagebacking ${STAGE_CHROOT_DIR}
187
	fi
188

    
189
	if df /dev/ufs/finalstagebacking >/dev/null 2>&1; then
190
		echo ">>> Detected preexisting memory disk enabled for ${FINAL_CHROOT_DIR}."
191
	else
192
		mdconfig -a -t swap -u 10002 -s ${MEMORYDISK_SIZE}
193
		newfs -L finalstagebacking -U /dev/md10002
194
		mount /dev/ufs/finalstagebacking ${FINAL_CHROOT_DIR}
195
	fi
196
}
197

    
198
prestage_on_ram_cleanup() {
199
	if [ -c /dev/md10001 ]; then
200
		if [ -d ${STAGE_CHROOT_DIR} ]; then
201
			umount ${STAGE_CHROOT_DIR}
202
		fi
203
		mdconfig -d -u 10001
204
	fi
205
	if [ -c /dev/md10002 ]; then
206
		if [ -d ${FINAL_CHROOT_DIR} ]; then
207
			umount ${FINAL_CHROOT_DIR}
208
		fi
209
		mdconfig -d -u 10002
210
	fi
211
}
212

    
213
# This routine will verify that the kernel has been
214
# installed OK to the staging area.
215
ensure_kernel_exists() {
216
	if [ ! -f "$1/boot/kernel/kernel.gz" ]; then
217
		echo ">>> ERROR: Could not locate $1/boot/kernel.gz"
218
		print_error_pfS
219
	fi
220
	KERNEL_SIZE=$(stat -f "%z" $1/boot/kernel/kernel.gz)
221
	if [ "$KERNEL_SIZE" -lt 3500 ]; then
222
		echo ">>> ERROR: Kernel $1/boot/kernel.gz appears to be smaller than it should be: $KERNEL_SIZE"
223
		print_error_pfS
224
	fi
225
}
226

    
227
get_pkg_name() {
228
	echo "${PRODUCT_NAME}-${1}-${CORE_PKG_VERSION}"
229
}
230

    
231
# This routine builds all related kernels
232
build_all_kernels() {
233
	# Set KERNEL_BUILD_PATH if it has not been set
234
	if [ -z "${KERNEL_BUILD_PATH}" ]; then
235
		KERNEL_BUILD_PATH=$SCRATCHDIR/kernels
236
		echo ">>> KERNEL_BUILD_PATH has not been set. Setting to ${KERNEL_BUILD_PATH}!"
237
	fi
238

    
239
	[ -d "${KERNEL_BUILD_PATH}" ] \
240
		&& rm -rf ${KERNEL_BUILD_PATH}
241

    
242
	# Build embedded kernel
243
	for BUILD_KERNEL in $BUILD_KERNELS; do
244
		unset KERNCONF
245
		unset KERNEL_DESTDIR
246
		unset KERNELCONF
247
		unset KERNEL_NAME
248
		export KERNCONF=$BUILD_KERNEL
249
		export KERNEL_DESTDIR="$KERNEL_BUILD_PATH/$BUILD_KERNEL"
250
		export KERNELCONF="${FREEBSD_SRC_DIR}/sys/${TARGET}/conf/$BUILD_KERNEL"
251
		export KERNEL_NAME=${BUILD_KERNEL}
252

    
253
		LOGFILE="${BUILDER_LOGS}/kernel.${KERNCONF}.${TARGET}.log"
254
		echo ">>> Building $BUILD_KERNEL kernel."  | tee -a ${LOGFILE}
255

    
256
		if [ ! -e "${FREEBSD_SRC_DIR}/sys/${TARGET}/conf/${BUILD_KERNEL}" ]; then
257
			echo ">>> ERROR: Could not find $KERNELCONF"
258
			print_error_pfS
259
		fi
260

    
261
		if [ -n "${NO_BUILDKERNEL}" -a -f "${CORE_PKG_PATH}/All/$(get_pkg_name kernel-${KERNEL_NAME}).txz" ]; then
262
			echo ">>> NO_BUILDKERNEL set, skipping build" | tee -a ${LOGFILE}
263
			continue
264
		fi
265

    
266
		export SRC_CONF=${SRC_CONF}
267
		buildkernel
268

    
269
		echo ">>> Staging $BUILD_KERNEL kernel..." | tee -a ${LOGFILE}
270
		installkernel
271

    
272
		ensure_kernel_exists $KERNEL_DESTDIR
273

    
274
		echo -n ">>> Creating pkg of $KERNEL_NAME kernel to staging area..."  | tee -a ${LOGFILE}
275
		core_pkg_create kernel ${KERNEL_NAME} ${CORE_PKG_VERSION} ${KERNEL_DESTDIR}
276

    
277
		rm -rf $KERNEL_DESTDIR 2>&1 1>/dev/null
278

    
279
		echo ".Done" | tee -a ${LOGFILE}
280
	done
281
}
282

    
283
install_default_kernel() {
284
	if [ -z "${1}" ]; then
285
		echo ">>> ERROR: install_default_kernel called without a kernel config name"| tee -a ${LOGFILE}
286
		print_error_pfS
287
	fi
288

    
289
	export KERNEL_NAME="${1}"
290

    
291
	echo -n ">>> Installing kernel to be used by image ${KERNEL_NAME}..." | tee -a ${LOGFILE}
292

    
293
	# Copy kernel package to chroot, otherwise pkg won't find it to install
294
	if ! pkg_chroot_add ${FINAL_CHROOT_DIR} kernel-${KERNEL_NAME}; then
295
		echo ">>> ERROR: Error installing kernel package $(get_pkg_name kernel-${KERNEL_NAME}).txz" | tee -a ${LOGFILE}
296
		print_error_pfS
297
	fi
298

    
299
	# Lock kernel to avoid user end up removing it for any reason
300
	pkg_chroot ${FINAL_CHROOT_DIR} lock -q -y $(get_pkg_name kernel-${KERNEL_NAME})
301

    
302
	if [ ! -f $FINAL_CHROOT_DIR/boot/kernel/kernel.gz ]; then
303
		echo ">>> ERROR: No kernel installed on $FINAL_CHROOT_DIR and the resulting image will be unusable. STOPPING!" | tee -a ${LOGFILE}
304
		print_error_pfS
305
	fi
306
	mkdir -p $FINAL_CHROOT_DIR/pkgs
307
	if [ -z "${2}" -o -n "${INSTALL_EXTRA_KERNELS}" ]; then
308
		cp ${CORE_PKG_PATH}/All/$(get_pkg_name kernel-${KERNEL_NAME}).txz $FINAL_CHROOT_DIR/pkgs
309
		if [ -n "${INSTALL_EXTRA_KERNELS}" ]; then
310
			for _EXTRA_KERNEL in $INSTALL_EXTRA_KERNELS; do
311
				_EXTRA_KERNEL_PATH=${CORE_PKG_PATH}/All/$(get_pkg_name kernel-${_EXTRA_KERNEL}).txz
312
				if [ -f "${_EXTRA_KERNEL_PATH}" ]; then
313
					echo -n ". adding ${_EXTRA_KERNEL_PATH} on image /pkgs folder"
314
					cp ${_EXTRA_KERNEL_PATH} $FINAL_CHROOT_DIR/pkgs
315
				else
316
					echo ">>> ERROR: Requested kernel $(get_pkg_name kernel-${_EXTRA_KERNEL}).txz was not found to be put on image /pkgs folder!"
317
					print_error_pfS
318
				fi
319
			done
320
		fi
321
	fi
322
	echo "Done." | tee -a ${LOGFILE}
323

    
324
	unset KERNEL_NAME
325
}
326

    
327
# Items that need to be fixed up that are
328
# specific to nanobsd builds
329
cust_fixup_nanobsd() {
330
	local _NANO_WITH_VGA="${1}"
331

    
332
	echo ">>> Fixing up NanoBSD Specific items..." | tee -a ${LOGFILE}
333

    
334
	echo "nanobsd" > $FINAL_CHROOT_DIR/etc/platform
335

    
336
	local BOOTCONF=${FINAL_CHROOT_DIR}/boot.config
337
	local LOADERCONF=${FINAL_CHROOT_DIR}/boot/loader.conf
338

    
339
	if [ "${_NANO_WITH_VGA}" = "nanobsd" ]; then
340
		# Tell loader to use serial console early.
341
		echo "-S115200 -h" >> ${BOOTCONF}
342
	fi
343

    
344
	# Remove old console options if present.
345
	[ -f "${LOADERCONF}" ] \
346
		&& sed -i "" -Ee "/(console|boot_multicons|boot_serial|hint.uart)/d" ${LOADERCONF}
347
	# Activate serial console+video console in loader.conf
348
	echo 'autoboot_delay="5"' >> ${LOADERCONF}
349
	echo 'loader_color="NO"' >> ${LOADERCONF}
350
	echo 'beastie_disable="YES"' >> ${LOADERCONF}
351
	echo 'boot_serial="YES"' >> ${LOADERCONF}
352
	echo 'console="comconsole"' >> ${LOADERCONF}
353
	echo 'comconsole_speed="115200"' >> ${LOADERCONF}
354
}
355

    
356
# Creates a full update file
357
create_Full_update_tarball() {
358
	mkdir -p $UPDATESDIR
359

    
360
	customize_stagearea_for_image "fullupdate"
361
	install_default_kernel ${DEFAULT_KERNEL}
362

    
363
	rm -rf ${FINAL_CHROOT_DIR}/cf
364
	rm -rf ${FINAL_CHROOT_DIR}/conf
365
	rm -f ${FINAL_CHROOT_DIR}/etc/rc.conf
366
	rm -f ${FINAL_CHROOT_DIR}/etc/pwd.db 2>/dev/null
367
	rm -f ${FINAL_CHROOT_DIR}/etc/group 2>/dev/null
368
	rm -f ${FINAL_CHROOT_DIR}/etc/spwd.db 2>/dev/null
369
	rm -f ${FINAL_CHROOT_DIR}/etc/passwd 2>/dev/null
370
	rm -f ${FINAL_CHROOT_DIR}/etc/master.passwd 2>/dev/null
371
	rm -f ${FINAL_CHROOT_DIR}/etc/fstab 2>/dev/null
372
	rm -f ${FINAL_CHROOT_DIR}/etc/bogons 2>/dev/null
373
	# Remove loader.conf and friends.  Ticket #560
374
	rm ${FINAL_CHROOT_DIR}/boot/loader.conf 2>/dev/null
375
	rm ${FINAL_CHROOT_DIR}/boot/loader.conf.local 2>/dev/null
376

    
377
	# Old systems will run (pre|post)_upgrade_command from /tmp
378
	if [ -f ${FINAL_CHROOT_DIR}/usr/local/share/${PRODUCT_NAME}/pre_upgrade_command ]; then
379
		cp -p \
380
			${FINAL_CHROOT_DIR}/usr/local/share/${PRODUCT_NAME}/pre_upgrade_command \
381
			${FINAL_CHROOT_DIR}/tmp
382
	fi
383
	if [ -f ${FINAL_CHROOT_DIR}/usr/local/share/${PRODUCT_NAME}/post_upgrade_command ]; then
384
		cp -p \
385
			${FINAL_CHROOT_DIR}/usr/local/share/${PRODUCT_NAME}/post_upgrade_command \
386
			${FINAL_CHROOT_DIR}/tmp
387
	fi
388

    
389
	echo ">>> Creating ${UPDATES_TARBALL_FILENAME} ..." | tee -a ${LOGFILE}
390
	tar --exclude=./dev -czPf ${UPDATES_TARBALL_FILENAME} -C ${FINAL_CHROOT_DIR} .
391
}
392

    
393
# Outputs various set variables aka env
394
print_flags() {
395

    
396
	echo
397
	printf "             Product version: %s\n" $PRODUCT_VERSION
398
	printf "                   Stage DIR: %s\n" $STAGE_CHROOT_DIR
399
	printf "                 Updates dir: %s\n" $UPDATESDIR
400
	printf " Image Preparation Stage DIR: %s\n" $FINAL_CHROOT_DIR
401
	printf "                  Source DIR: %s\n" $FREEBSD_SRC_DIR
402
	printf "          FreeBSD repository: %s\n" $FREEBSD_REPO_BASE
403
	printf "          FreeBSD-src branch: %s\n" $FREEBSD_BRANCH
404
	printf "     FreeBSD original branch: %s\n" $FREEBSD_PARENT_BRANCH
405
	printf "               BUILD_KERNELS: %s\n" $BUILD_KERNELS
406
	printf "           Git Branch or Tag: %s\n" $GIT_REPO_BRANCH_OR_TAG
407
	printf "            MODULES_OVERRIDE: %s\n" $MODULES_OVERRIDE
408
	printf "    VMDK_DISK_CAPACITY_IN_GB: %s\n" $VMDK_DISK_CAPACITY_IN_GB
409
	printf "   OVA_FIRST_PART_SIZE_IN_GB: %s\n" $OVA_FIRST_PART_SIZE_IN_GB
410
	printf "    OVA_SWAP_PART_SIZE_IN_GB: %s\n" $OVA_SWAP_PART_SIZE_IN_GB
411
	printf "                 OVFTEMPLATE: %s\n" $OVFTEMPLATE
412
	printf "                     OVFVMDK: %s\n" $OVFVMDK
413
	printf "                    SRC_CONF: %s\n" $SRC_CONF
414
	printf "                     ISOPATH: %s\n" $ISOPATH
415
	printf "                MEMSTICKPATH: %s\n" $MEMSTICKPATH
416
	printf "    UPDATES_TARBALL_FILENAME: %s\n" $UPDATES_TARBALL_FILENAME
417
if [ -n "$SHOW_ENV" ]; then
418
	for LINE in $(env | egrep -v '(terminal|PASS|NAME|USER|SSH|GROUP|HOST)'); do
419
		echo "SHOW_ENV: $LINE"
420
	done
421
fi
422
	echo
423
}
424

    
425
# This builds FreeBSD (make buildworld)
426
# Imported from FreeSBIE
427
make_world() {
428

    
429
	LOGFILE=${BUILDER_LOGS}/buildworld.${TARGET}
430
	if [ -n "${NO_BUILDWORLD}" ]; then
431
		echo ">>> NO_BUILDWORLD set, skipping build" | tee -a ${LOGFILE}
432
		return
433
	fi
434

    
435
	# Set SRC_CONF variable if it's not already set.
436
	if [ -z "${SRC_CONF}" ]; then
437
		echo ">>> SRC_CONF is unset make sure this is what you want!" | tee -a ${LOGFILE}
438
	else
439
		echo ">>> Setting SRC_CONF to $SRC_CONF" | tee -a ${LOGFILE}
440
	fi
441

    
442
	# Set default parameters
443
	export MAKE_ARGS="${MAKEJ_WORLD} __MAKE_CONF=${MAKE_CONF} SRCCONF=${SRC_CONF} TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH}"
444

    
445
	echo ">>> LOGFILE set to $LOGFILE." | tee -a ${LOGFILE}
446
	makeargs="${MAKE_ARGS}"
447
	echo ">>> Building world for ${TARGET} architecture... (Starting - $(LC_ALL=C date))" | tee -a ${LOGFILE}
448
	echo ">>> Builder is running the command: env LOCAL_ITOOLS=\"${EXTRA_TOOLS}\" script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR} -DNO_CLEAN ${makeargs} buildworld" | tee -a ${LOGFILE}
449
	(env LOCAL_ITOOLS="${EXTRA_TOOLS}" script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR} -DNO_CLEAN ${makeargs} buildworld || print_error_pfS;) | egrep '^>>>' | tee -a ${LOGFILE}
450
	echo ">>> Building world for ${TARGET} architecture... (Finished - $(LC_ALL=C date))" | tee -a ${LOGFILE}
451

    
452
	LOGFILE=${BUILDER_LOGS}/installworld.${TARGET}
453
	echo ">>> LOGFILE set to $LOGFILE." | tee -a ${LOGFILE}
454
	# Create if cleaned up
455
	makeargs="${MAKE_ARGS} DESTDIR=${STAGE_CHROOT_DIR} WITHOUT_TOOLCHAIN=1"
456
	echo ">>> Installing world for ${TARGET} architecture... (Starting - $(LC_ALL=C date))" | tee -a ${LOGFILE}
457
	echo ">>> Builder is running the command: env LOCAL_ITOOLS=\"${EXTRA_TOOLS}\" script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR} ${makeargs} installworld" | tee -a ${LOGFILE}
458
	(env LOCAL_ITOOLS="${EXTRA_TOOLS}" script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR} ${makeargs} installworld || print_error_pfS;) | egrep '^>>>' | tee -a ${LOGFILE}
459
	echo ">>> Installing world for ${TARGET} architecture... (Finished - $(LC_ALL=C date))" | tee -a ${LOGFILE}
460

    
461
	makeargs="${MAKE_ARGS} DESTDIR=${STAGE_CHROOT_DIR}"
462
	echo ">>> Distribution world for ${TARGET} architecture... (Starting - $(LC_ALL=C date))" | tee -a ${LOGFILE}
463
	echo ">>> Builder is running the command: script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR} ${makeargs} distribution " | tee -a ${LOGFILE}
464
	(script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR} ${makeargs} distribution  || print_error_pfS;) | egrep '^>>>' | tee -a ${LOGFILE}
465
	echo ">>> Distribution world for ${TARGET} architecture... (Finished - $(LC_ALL=C date))" | tee -a ${LOGFILE}
466

    
467
	[ -d "${STAGE_CHROOT_DIR}/usr/local/bin" ] \
468
		|| mkdir -p ${STAGE_CHROOT_DIR}/usr/local/bin
469
	makeargs="${MAKE_ARGS} DESTDIR=${STAGE_CHROOT_DIR}"
470
	echo ">>> Building and installing crypto tools and athstats for ${TARGET} architecture... (Starting - $(LC_ALL=C date))" | tee -a ${LOGFILE}
471
	echo ">>> Builder is running the command: script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR}/tools/tools/crypto ${makeargs} clean all install " | tee -a ${LOGFILE}
472
	(script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR}/tools/tools/crypto ${makeargs} clean all install || print_error_pfS;) | egrep '^>>>' | tee -a ${LOGFILE}
473
	echo ">>> Builder is running the command: script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR}/tools/tools/ath/athstats ${makeargs} clean" | tee -a ${LOGFILE}
474
	(script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR}/tools/tools/ath/athstats ${makeargs} clean || print_error_pfS;) | egrep '^>>>' | tee -a ${LOGFILE}
475
	echo ">>> Builder is running the command: script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR}/tools/tools/ath/athstats ${makeargs} all" | tee -a ${LOGFILE}
476
	(script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR}/tools/tools/ath/athstats ${makeargs} all || print_error_pfS;) | egrep '^>>>' | tee -a ${LOGFILE}
477
	echo ">>> Builder is running the command: script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR}/tools/tools/ath/athstats ${makeargs} install" | tee -a ${LOGFILE}
478
	(script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR}/tools/tools/ath/athstats ${makeargs} install || print_error_pfS;) | egrep '^>>>' | tee -a ${LOGFILE}
479
	echo ">>> Building and installing crypto tools and athstats for ${TARGET} architecture... (Finished - $(LC_ALL=C date))" | tee -a ${LOGFILE}
480

    
481
	unset makeargs
482
}
483

    
484
# This routine originated in nanobsd.sh
485
nanobsd_set_flash_details () {
486
	a1=$(echo $1 | tr '[:upper:]' '[:lower:]')
487

    
488
	# Source:
489
	#	SanDisk CompactFlash Memory Card
490
	#	Product Manual
491
	#	Version 10.9
492
	#	Document No. 20-10-00038
493
	#	April 2005
494
	# Table 2-7
495
	# NB: notice math error in SDCFJ-4096-388 line.
496
	#
497
	case "${a1}" in
498
		1024|1024m|1024mb|1g)
499
			NANO_MEDIASIZE=$((997129216/512))
500
			;;
501
		2048|2048m|2048mb|2g)
502
			NANO_MEDIASIZE=$((1989999616/512))
503
			;;
504
		4096|4096m|4096mb|4g)
505
			NANO_MEDIASIZE=$((3989999616/512))
506
			;;
507
		8192|8192m|8192mb|8g)
508
			NANO_MEDIASIZE=$((7989999616/512))
509
			;;
510
		16384|16384m|16384mb|16g)
511
			NANO_MEDIASIZE=$((15989999616/512))
512
			;;
513
		*)
514
			echo "Unknown Flash capacity"
515
			exit 2
516
			;;
517
	esac
518

    
519
	NANO_HEADS=16
520
	NANO_SECTS=63
521

    
522
	echo ">>> [nanoo] $1"
523
	echo ">>> [nanoo] NANO_MEDIASIZE: $NANO_MEDIASIZE"
524
	echo ">>> [nanoo] NANO_HEADS: $NANO_HEADS"
525
	echo ">>> [nanoo] NANO_SECTS: $NANO_SECTS"
526
	echo ">>> [nanoo] NANO_BOOT0CFG: $NANO_BOOT0CFG"
527
}
528

    
529
# This routine originated in nanobsd.sh
530
create_nanobsd_diskimage () {
531
	if [ -z "${1}" ]; then
532
		echo ">>> ERROR: Type of image has not been specified"
533
		print_error_pfS
534
	fi
535
	if [ -z "${2}" ]; then
536
		echo ">>> ERROR: Size of image has not been specified"
537
		print_error_pfS
538
	fi
539

    
540
	if [ "${1}" = "nanobsd" ]; then
541
		# It's serial
542
		export NANO_BOOTLOADER="boot/boot0sio"
543
	elif [ "${1}" = "nanobsd-vga" ]; then
544
		# It's vga
545
		export NANO_BOOTLOADER="boot/boot0"
546
	else
547
		echo ">>> ERROR: Type of image to create unknown"
548
		print_error_pfS
549
	fi
550

    
551
	if [ -z "${2}" ]; then
552
		echo ">>> ERROR: Media size(s) not specified."
553
		print_error_pfS
554
	fi
555

    
556
	if [ -z "${2}" ]; then
557
		echo ">>> ERROR: FLASH_SIZE is not set."
558
		print_error_pfS
559
	fi
560

    
561
	LOGFILE=${BUILDER_LOGS}/${1}.${TARGET}
562
	# Prepare folder to be put in image
563
	customize_stagearea_for_image "${1}"
564
	install_default_kernel ${DEFAULT_KERNEL} "no"
565

    
566
	# Must be run after customize_stagearea_for_image
567
	cust_fixup_nanobsd ${1}
568

    
569
	for _NANO_MEDIASIZE in ${2}; do
570
		if [ -z "${_NANO_MEDIASIZE}" ]; then
571
			continue;
572
		fi
573

    
574
		echo ">>> building NanoBSD(${1}) disk image with size ${_NANO_MEDIASIZE} for platform (${TARGET})..." | tee -a ${LOGFILE}
575
		echo "" > $BUILDER_LOGS/nanobsd_cmds.sh
576

    
577
		IMG="${IMAGES_FINAL_DIR}/${PRODUCT_NAME}-${PRODUCT_VERSION}-${_NANO_MEDIASIZE}-${TARGET}-${1}${TIMESTAMP_SUFFIX}.img"
578
		IMGUPDATE="${IMAGES_FINAL_DIR}/${PRODUCT_NAME}-${PRODUCT_VERSION}-${_NANO_MEDIASIZE}-${TARGET}-${1}-upgrade${TIMESTAMP_SUFFIX}.img"
579

    
580
		nanobsd_set_flash_details ${_NANO_MEDIASIZE}
581

    
582
		# These are defined in FlashDevice and on builder_default.sh
583
		echo $NANO_MEDIASIZE \
584
			$NANO_IMAGES \
585
			$NANO_SECTS \
586
			$NANO_HEADS \
587
			$NANO_CODESIZE \
588
			$NANO_CONFSIZE \
589
			$NANO_DATASIZE |
590
awk '
591
{
592
	printf "# %s\n", $0
593

    
594
	# size of cylinder in sectors
595
	cs = $3 * $4
596

    
597
	# number of full cylinders on media
598
	cyl = int ($1 / cs)
599

    
600
	# output fdisk geometry spec, truncate cyls to 1023
601
	if (cyl <= 1023)
602
		print "g c" cyl " h" $4 " s" $3
603
	else
604
		print "g c" 1023 " h" $4 " s" $3
605

    
606
	if ($7 > 0) {
607
		# size of data partition in full cylinders
608
		dsl = int (($7 + cs - 1) / cs)
609
	} else {
610
		dsl = 0;
611
	}
612

    
613
	# size of config partition in full cylinders
614
	csl = int (($6 + cs - 1) / cs)
615

    
616
	if ($5 == 0) {
617
		# size of image partition(s) in full cylinders
618
		isl = int ((cyl - dsl - csl) / $2)
619
	} else {
620
		isl = int (($5 + cs - 1) / cs)
621
	}
622

    
623
	# First image partition start at second track
624
	print "p 1 165 " $3, isl * cs - $3
625
	c = isl * cs;
626

    
627
	# Second image partition (if any) also starts offset one
628
	# track to keep them identical.
629
	if ($2 > 1) {
630
		print "p 2 165 " $3 + c, isl * cs - $3
631
		c += isl * cs;
632
	}
633

    
634
	# Config partition starts at cylinder boundary.
635
	print "p 3 165 " c, csl * cs
636
	c += csl * cs
637

    
638
	# Data partition (if any) starts at cylinder boundary.
639
	if ($7 > 0) {
640
		print "p 4 165 " c, dsl * cs
641
	} else if ($7 < 0 && $1 > c) {
642
		print "p 4 165 " c, $1 - c
643
	} else if ($1 < c) {
644
		print "Disk space overcommitted by", \
645
		    c - $1, "sectors" > "/dev/stderr"
646
		exit 2
647
	}
648

    
649
	# Force slice 1 to be marked active. This is necessary
650
	# for booting the image from a USB device to work.
651
	print "a 1"
652
}
653
	' > ${IMAGES_FINAL_DIR}/_.fdisk
654

    
655
		MNT=${IMAGES_FINAL_DIR}/_.mnt
656
		mkdir -p ${MNT}
657

    
658
		dd if=/dev/zero of=${IMG} bs=${NANO_SECTS}b \
659
			count=0 seek=$((${NANO_MEDIASIZE}/${NANO_SECTS})) 2>&1 >> ${LOGFILE}
660

    
661
		MD=$(mdconfig -a -t vnode -f ${IMG} -x ${NANO_SECTS} -y ${NANO_HEADS})
662
		trap "mdconfig -d -u ${MD}; return" 1 2 15 EXIT
663

    
664
		fdisk -i -f ${IMAGES_FINAL_DIR}/_.fdisk ${MD} 2>&1 >> ${LOGFILE}
665
		fdisk ${MD} 2>&1 >> ${LOGFILE}
666

    
667
		boot0cfg -B -b ${FINAL_CHROOT_DIR}/${NANO_BOOTLOADER} ${NANO_BOOT0CFG} ${MD} 2>&1 >> ${LOGFILE}
668

    
669
		# Create first image
670
		bsdlabel -m i386 -w -B -b ${FINAL_CHROOT_DIR}/boot/boot ${MD}s1 2>&1 >> ${LOGFILE}
671
		bsdlabel -m i386 ${MD}s1 2>&1 >> ${LOGFILE}
672
		local _label=$(lc ${PRODUCT_NAME})
673
		newfs -L ${_label}0 ${NANO_NEWFS} /dev/${MD}s1a 2>&1 >> ${LOGFILE}
674
		mount /dev/ufs/${_label}0 ${MNT}
675
		if [ $? -ne 0 ]; then
676
			echo ">>> ERROR: Something wrong happened during mount of first slice image creation. STOPPING!" | tee -a ${LOGFILE}
677
			print_error_pfS
678
		fi
679
		# Consider the unmounting as well
680
		trap "umount /dev/ufs/${_label}0; mdconfig -d -u ${MD}; return" 1 2 15 EXIT
681

    
682
		clone_directory_contents ${FINAL_CHROOT_DIR} ${MNT}
683

    
684
		# Set NanoBSD image size
685
		echo "${_NANO_MEDIASIZE}" > ${MNT}/etc/nanosize.txt
686
		rm -f $MNT/cf/conf/* 2>/dev/null
687

    
688
		echo "/dev/ufs/${_label}0 / ufs ro,sync,noatime 1 1" > ${MNT}/etc/fstab
689
		if [ $NANO_CONFSIZE -gt 0 ] ; then
690
			echo "/dev/ufs/cf /cf ufs ro,sync,noatime 1 1" >> ${MNT}/etc/fstab
691
		fi
692

    
693
		umount ${MNT}
694
		# Restore the original trap
695
		trap "mdconfig -d -u ${MD}; return" 1 2 15 EXIT
696

    
697
		# Setting NANO_IMAGES to 1 and NANO_INIT_IMG2 will tell
698
		# NanoBSD to only create one partition.  We default to 2
699
		# partitions in case anything happens to the first the
700
		# operator can boot from the 2nd and should be OK.
701

    
702
		# Before just going to use dd for duplicate think!
703
		# The images are created as sparse so lets take advantage
704
		# of that by just exec some commands.
705
		if [ $NANO_IMAGES -gt 1 -a $NANO_INIT_IMG2 -gt 0 ] ; then
706
			# Duplicate to second image (if present)
707
			echo ">>> Creating NanoBSD second slice by duplicating first slice." | tee -a ${LOGFILE}
708
			# Create second image
709
			dd if=/dev/${MD}s1 of=/dev/${MD}s2 conv=sparse bs=64k 2>&1 >> ${LOGFILE}
710
			tunefs -L ${_label}1 /dev/${MD}s2a 2>&1 >> ${LOGFILE}
711
			mount /dev/ufs/${_label}1 ${MNT}
712
			if [ $? -ne 0 ]; then
713
				echo ">>> ERROR: Something wrong happened during mount of second slice image creation. STOPPING!" | tee -a ${LOGFILE}
714
				print_error_pfS
715
			fi
716
			# Consider the unmounting as well
717
			trap "umount /dev/ufs/${_label}1; mdconfig -d -u ${MD}; return" 1 2 15 EXIT
718

    
719
			echo "/dev/ufs/${_label}1 / ufs ro,sync,noatime 1 1" > ${MNT}/etc/fstab
720
			if [ $NANO_CONFSIZE -gt 0 ] ; then
721
				echo "/dev/ufs/cf /cf ufs ro,sync,noatime 1 1" >> ${MNT}/etc/fstab
722
			fi
723

    
724
			umount ${MNT}
725
			# Restore the trap back
726
			trap "mdconfig -d -u ${MD}; return" 1 2 15 EXIT
727
		fi
728

    
729
		# Create Data slice, if any.
730
		# Note the changing of the variable to NANO_CONFSIZE
731
		# from NANO_DATASIZE.  We also added glabel support
732
		# and populate the Product configuration from the /cf
733
		# directory located in FINAL_CHROOT_DIR
734
		if [ $NANO_CONFSIZE -gt 0 ] ; then
735
			echo ">>> Creating /cf area to hold config.xml"
736
			newfs -L cf ${NANO_NEWFS} /dev/${MD}s3 2>&1 >> ${LOGFILE}
737
			# Mount data partition and copy contents of /cf
738
			# Can be used later to create custom default config.xml while building
739
			mount /dev/ufs/cf ${MNT}
740
			if [ $? -ne 0 ]; then
741
				echo ">>> ERROR: Something wrong happened during mount of cf slice image creation. STOPPING!" | tee -a ${LOGFILE}
742
				print_error_pfS
743
			fi
744
			# Consider the unmounting as well
745
			trap "umount /dev/ufs/cf; mdconfig -d -u ${MD}; return" 1 2 15 EXIT
746

    
747
			clone_directory_contents ${FINAL_CHROOT_DIR}/cf ${MNT}
748

    
749
			umount ${MNT}
750
			# Restore the trap back
751
			trap "mdconfig -d -u ${MD}; return" 1 2 15 EXIT
752
		else
753
			">>> [nanoo] NANO_CONFSIZE is not set. Not adding a /conf partition.. You sure about this??" | tee -a ${LOGFILE}
754
		fi
755

    
756
		echo ">>> [nanoo] Creating NanoBSD upgrade file from first slice..." | tee -a ${LOGFILE}
757
		dd if=/dev/${MD}s1 of=$IMGUPDATE conv=sparse bs=64k 2>&1 >> ${LOGFILE}
758

    
759
		mdconfig -d -u $MD
760
		# Restore default action
761
		trap "-" 1 2 15 EXIT
762

    
763
		# Check each image and ensure that they are over
764
		# 3 megabytes.  If either image is under 20 megabytes
765
		# in size then error out.
766
		IMGSIZE=$(stat -f "%z" ${IMG})
767
		IMGUPDATESIZE=$(stat -f "%z" ${IMGUPDATE})
768
		CHECKSIZE="20040710"
769
		if [ "$IMGSIZE" -lt "$CHECKSIZE" ]; then
770
			echo ">>> ERROR: Something went wrong when building NanoBSD.  The image size is under 20 megabytes!" | tee -a ${LOGFILE}
771
			print_error_pfS
772
		fi
773
		if [ "$IMGUPDATESIZE" -lt "$CHECKSIZE" ]; then
774
			echo ">>> ERROR: Something went wrong when building NanoBSD upgrade image.  The image size is under 20 megabytes!" | tee -a ${LOGFILE}
775
			print_error_pfS
776
		fi
777

    
778
		# Wrap up the show, Johnny
779
		echo ">>> NanoBSD Image completed for size: $_NANO_MEDIASIZE." | tee -a ${LOGFILE}
780

    
781
		gzip -qf $IMG &
782
		_bg_pids="${_bg_pids}${_bg_pids:+ }$!"
783
		gzip -qf $IMGUPDATE &
784
		_bg_pids="${_bg_pids}${_bg_pids:+ }$!"
785
	done
786

    
787
	unset IMG
788
	unset IMGUPDATE
789
	unset IMGUPDATESIZE
790
	unset IMGSIZE
791

    
792
	ls -lah $IMAGES_FINAL_DIR
793
}
794

    
795
# This routine creates a ova image that contains
796
# a ovf and vmdk file. These files can be imported
797
# right into vmware or virtual box.
798
# (and many other emulation platforms)
799
# http://www.vmware.com/pdf/ovf_whitepaper_specification.pdf
800
create_ova_image() {
801
	# XXX create a .ovf php creator that you can pass:
802
	#     1. populatedSize
803
	#     2. license
804
	#     3. product name
805
	#     4. version
806
	#     5. number of network interface cards
807
	#     6. allocationUnits
808
	#     7. capacity
809
	#     8. capacityAllocationUnits
810

    
811
	LOGFILE=${BUILDER_LOGS}/ova.${TARGET}.log
812

    
813
	[ -d "${OVA_TMP}" ] \
814
		&& rm -rf ${OVA_TMP}
815

    
816
	mkdir -p ${OVA_TMP}
817

    
818
	# Prepare folder to be put in image
819
	customize_stagearea_for_image "ova"
820
	install_default_kernel ${DEFAULT_KERNEL} "no"
821

    
822
	# Fill fstab
823
	echo ">>> Installing platform specific items..." | tee -a ${LOGFILE}
824
	echo "/dev/gpt/${PRODUCT_NAME}	/	ufs		rw	0	0" > ${FINAL_CHROOT_DIR}/etc/fstab
825
	echo "/dev/gpt/swap0	none	swap	sw	0	0" >> ${FINAL_CHROOT_DIR}/etc/fstab
826

    
827
	# Create / partition
828
	echo -n ">>> Creating / partition... " | tee -a ${LOGFILE}
829
	makefs \
830
		-B little \
831
		-o label=${PRODUCT_NAME} \
832
		-s ${OVA_FIRST_PART_SIZE_IN_GB}g \
833
		${OVA_TMP}/${OVFUFS} \
834
		${FINAL_CHROOT_DIR} 2>&1 >> ${LOGFILE}
835

    
836
	if [ $? -ne 0 -o ! -f ${OVA_TMP}/${OVFUFS} ]; then
837
		if [ -f ${OVA_TMP}/${OVFUFS} ]; then
838
			rm -f ${OVA_TMP}/${OVFUFS}
839
		fi
840
		echo "Failed!" | tee -a ${LOGFILE}
841
		echo ">>> ERROR: Error creating vmdk / partition. STOPPING!" | tee -a ${LOGFILE}
842
		print_error_pfS
843
	fi
844
	echo "Done!" | tee -a ${LOGFILE}
845

    
846
	# Create raw disk
847
	echo -n ">>> Creating raw disk... " | tee -a ${LOGFILE}
848
	mkimg \
849
		-s gpt \
850
		-f raw \
851
		-b /boot/pmbr \
852
		-p freebsd-boot:=/boot/gptboot \
853
		-p freebsd-ufs/${PRODUCT_NAME}:=${OVA_TMP}/${OVFUFS} \
854
		-p freebsd-swap/swap0::${OVA_SWAP_PART_SIZE} \
855
		-o ${OVA_TMP}/${OVFRAW} 2>&1 >> ${LOGFILE}
856

    
857
	if [ $? -ne 0 -o ! -f ${OVA_TMP}/${OVFRAW} ]; then
858
		if [ -f ${OVA_TMP}/${OVFUFS} ]; then
859
			rm -f ${OVA_TMP}/${OVFUFS}
860
		fi
861
		if [ -f ${OVA_TMP}/${OVFRAW} ]; then
862
			rm -f ${OVA_TMP}/${OVFRAW}
863
		fi
864
		echo "Failed!" | tee -a ${LOGFILE}
865
		echo ">>> ERROR: Error creating temporary vmdk image. STOPPING!" | tee -a ${LOGFILE}
866
		print_error_pfS
867
	fi
868
	echo "Done!" | tee -a ${LOGFILE}
869

    
870
	# We don't need it anymore
871
	rm -f ${OVA_TMP}/${OVFUFS} >/dev/null 2>&1
872

    
873
	# Convert raw to vmdk
874
	echo -n ">>> Creating vmdk disk... " | tee -a ${LOGFILE}
875
	vmdktool -z9 -v ${OVA_TMP}/${OVFVMDK} ${OVA_TMP}/${OVFRAW}
876

    
877
	if [ $? -ne 0 -o ! -f ${OVA_TMP}/${OVFVMDK} ]; then
878
		if [ -f ${OVA_TMP}/${OVFRAW} ]; then
879
			rm -f ${OVA_TMP}/${OVFRAW}
880
		fi
881
		if [ -f ${OVA_TMP}/${OVFVMDK} ]; then
882
			rm -f ${OVA_TMP}/${OVFVMDK}
883
		fi
884
		echo "Failed!" | tee -a ${LOGFILE}
885
		echo ">>> ERROR: Error creating vmdk image. STOPPING!" | tee -a ${LOGFILE}
886
		print_error_pfS
887
	fi
888
	echo "Done!" | tee -a ${LOGFILE}
889

    
890
	rm -f ${OVA_TMP}/i${OVFRAW}
891

    
892
	ova_setup_ovf_template
893

    
894
	echo -n ">>> Writing final ova image... " | tee -a ${LOGFILE}
895
	# Create OVA file for vmware
896
	gtar -C ${OVA_TMP} -cpf ${OVAPATH} ${PRODUCT_NAME}.ovf ${OVFVMDK}
897
	echo "Done!" | tee -a ${LOGFILE}
898
	rm -f ${OVA_TMP}/${OVFVMDK} >/dev/null 2>&1
899

    
900
	echo ">>> OVA created: $(LC_ALL=C date)" | tee -a ${LOGFILE}
901
}
902

    
903
# called from create_ova_image
904
ova_setup_ovf_template() {
905
	if [ ! -f ${OVFTEMPLATE} ]; then
906
		echo ">>> ERROR: OVF template file (${OVFTEMPLATE}) not found."
907
		print_error_pfS
908
	fi
909

    
910
	#  OperatingSystemSection (${PRODUCT_NAME}.ovf)
911
	#  42   FreeBSD 32-Bit
912
	#  78   FreeBSD 64-Bit
913
	if [ "${TARGET}" = "amd64" ]; then
914
		local _os_id="78"
915
		local _os_type="freebsd64Guest"
916
		local _os_descr="FreeBSD 64-Bit"
917
	elif [ "${TARGET}" = "i386" ]; then
918
		local _os_id="42"
919
		local _os_type="freebsdGuest"
920
		local _os_descr="FreeBSD"
921
	else
922
		echo ">>> ERROR: Platform not supported for OVA (${TARGET})"
923
		print_error_pfS
924
	fi
925

    
926
	local POPULATED_SIZE=$(du -d0 -k $FINAL_CHROOT_DIR | cut -f1)
927
	local POPULATED_SIZE_IN_BYTES=$((${POPULATED_SIZE}*1024))
928
	local VMDK_FILE_SIZE=$(stat -f "%z" ${OVA_TMP}/${OVFVMDK})
929

    
930
	sed \
931
		-e "s,%%VMDK_FILE_SIZE%%,${VMDK_FILE_SIZE},g" \
932
		-e "s,%%VMDK_DISK_CAPACITY_IN_GB%%,${VMDK_DISK_CAPACITY_IN_GB},g" \
933
		-e "s,%%POPULATED_SIZE_IN_BYTES%%,${POPULATED_SIZE_IN_BYTES},g" \
934
		-e "s,%%OS_ID%%,${_os_id},g" \
935
		-e "s,%%OS_TYPE%%,${_os_type},g" \
936
		-e "s,%%OS_DESCR%%,${_os_descr},g" \
937
		-e "s,%%PRODUCT_NAME%%,${PRODUCT_NAME},g" \
938
		-e "s,%%PRODUCT_VERSION%%,${PRODUCT_VERSION},g" \
939
		-e "s,%%PRODUCT_URL%%,${PRODUCT_URL},g" \
940
		-e "/^%%PRODUCT_LICENSE%%/r ${BUILDER_ROOT}/license.txt" \
941
		-e "/^%%PRODUCT_LICENSE%%/d" \
942
		${OVFTEMPLATE} > ${OVA_TMP}/${PRODUCT_NAME}.ovf
943
}
944

    
945
# Cleans up previous builds
946
clean_builder() {
947
	# Clean out directories
948
	echo ">>> Cleaning up previous build environment...Please wait!"
949

    
950
	staginareas_clean_each_run
951

    
952
	if [ -d "${STAGE_CHROOT_DIR}" ]; then
953
		BASENAME=$(basename ${STAGE_CHROOT_DIR})
954
		echo -n ">>> Cleaning ${STAGE_CHROOT_DIR} ..."
955
		chflags -R noschg ${STAGE_CHROOT_DIR} 2>&1 >/dev/null
956
		rm -rf ${STAGE_CHROOT_DIR}/* 2>/dev/null
957
		echo "Done."
958
	fi
959

    
960
	if [ -z "${NO_CLEAN_FREEBSD_OBJ}" -a -d "${FREEBSD_SRC_DIR}" ]; then
961
		OBJTREE=$(env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} make -C ${FREEBSD_SRC_DIR} -V OBJTREE)
962
		if [ -d "${OBJTREE}" ]; then
963
			echo -n ">>> Cleaning FreeBSD objects dir staging..."
964
			echo -n "."
965
			chflags -R noschg ${OBJTREE} 2>&1 >/dev/null
966
			echo -n "."
967
			rm -rf ${OBJTREE}/*
968
			echo "Done!"
969
		fi
970
		if [ -d "${KERNEL_BUILD_PATH}" ]; then
971
			echo -n ">>> Cleaning previously built kernel stage area..."
972
			rm -rf $KERNEL_BUILD_PATH/*
973
			echo "Done!"
974
		fi
975
	fi
976
	mkdir -p $KERNEL_BUILD_PATH
977

    
978
	echo -n ">>> Cleaning previously built images..."
979
	rm -rf $IMAGES_FINAL_DIR/*
980
	rm -rf $STAGINGAREA/*
981
	echo "Done!"
982

    
983
	if [ -z "${NO_CLEAN_FREEBSD_SRC}" ]; then
984
		if [ -d "$FREEBSD_SRC_DIR" ]; then
985
			echo -n ">>> Ensuring $FREEBSD_SRC_DIR is clean..."
986
			rm -rf ${FREEBSD_SRC_DIR}
987
			echo "Done!"
988
		fi
989
	fi
990

    
991
	echo -n ">>> Cleaning previous builder logs..."
992
	if [ -d "$BUILDER_LOGS" ]; then
993
		rm -rf ${BUILDER_LOGS}
994
	fi
995
	mkdir -p ${BUILDER_LOGS}
996

    
997
	echo "Done!"
998

    
999
	echo ">>> Cleaning of builder environment has finished."
1000
}
1001

    
1002
clone_directory_contents() {
1003
	if [ ! -d "$1" -o ! -d "$2" ]; then
1004
		if [ -z "${LOGFILE}" ]; then
1005
			echo ">>> ERROR: Argument $1 supplied is not a directory!"
1006
		else
1007
			echo ">>> ERROR: Argument $1 supplied is not a directory!" | tee -a ${LOGFILE}
1008
		fi
1009
		print_error_pfS
1010
	fi
1011
	echo -n ">>> Using TAR to clone $1 to $2 ..."
1012
	tar -C ${1} -c -f - . | tar -C ${2} -x -p -f -
1013
	echo "Done!"
1014
}
1015

    
1016
clone_to_staging_area() {
1017
	# Clone everything to the final staging area
1018
	echo -n ">>> Cloning everything to ${STAGE_CHROOT_DIR} staging area..."
1019
	LOGFILE=${BUILDER_LOGS}/cloning.${TARGET}.log
1020

    
1021
	tar -C ${PRODUCT_SRC} -c -f - . | \
1022
		tar -C ${STAGE_CHROOT_DIR} -x -p -f -
1023

    
1024
	if [ -f ${STAGE_CHROOT_DIR}/etc/master.passwd ]; then
1025
		chroot ${STAGE_CHROOT_DIR} cap_mkdb /etc/master.passwd
1026
		chroot ${STAGE_CHROOT_DIR} pwd_mkdb /etc/master.passwd
1027
	fi
1028
	mkdir -p ${STAGE_CHROOT_DIR}/etc/mtree
1029
	mtree -Pcp ${STAGE_CHROOT_DIR}/var > ${STAGE_CHROOT_DIR}/etc/mtree/var.dist
1030
	mtree -Pcp ${STAGE_CHROOT_DIR}/etc > ${STAGE_CHROOT_DIR}/etc/mtree/etc.dist
1031
	if [ -d ${STAGE_CHROOT_DIR}/usr/local/etc ]; then
1032
		mtree -Pcp ${STAGE_CHROOT_DIR}/usr/local/etc > ${STAGE_CHROOT_DIR}/etc/mtree/localetc.dist
1033
	fi
1034

    
1035
	## Add buildtime and lastcommit information
1036
	# This is used for detecting updates.
1037
	echo "$BUILTDATESTRING" > $STAGE_CHROOT_DIR/etc/version.buildtime
1038
	# Record last commit info if it is available.
1039
	if [ -f $SCRATCHDIR/build_commit_info.txt ]; then
1040
		cp $SCRATCHDIR/build_commit_info.txt $STAGE_CHROOT_DIR/etc/version.lastcommit
1041
	fi
1042

    
1043
	local _exclude_files="${CORE_PKG_TMP}/base_exclude_files"
1044
	sed \
1045
		-e "s,%%PRODUCT_NAME%%,${PRODUCT_NAME},g" \
1046
		-e "s,%%FLAVOR%%,${_flavor},g" \
1047
		-e "s,%%VERSION%%,${_version},g" \
1048
		${BUILDER_TOOLS}/templates/core_pkg/base/exclude_files \
1049
		> ${_exclude_files}
1050

    
1051
	mkdir -p ${STAGE_CHROOT_DIR}/usr/local/share/${PRODUCT_NAME} >/dev/null 2>&1
1052
	mtree \
1053
		-c \
1054
		-k uid,gid,mode,size,flags,sha256digest \
1055
		-p ${STAGE_CHROOT_DIR} \
1056
		-X ${_exclude_files} \
1057
		> ${STAGE_CHROOT_DIR}/usr/local/share/${PRODUCT_NAME}/base.mtree
1058
	tar \
1059
		-C ${STAGE_CHROOT_DIR} \
1060
		-cJf ${STAGE_CHROOT_DIR}/usr/local/share/${PRODUCT_NAME}/base.txz \
1061
		-X ${_exclude_files} \
1062
		.
1063

    
1064
	core_pkg_create base "" ${CORE_PKG_VERSION} ${STAGE_CHROOT_DIR}
1065
	core_pkg_create base-nanobsd "" ${CORE_PKG_VERSION} ${STAGE_CHROOT_DIR}
1066
	core_pkg_create default-config "" ${CORE_PKG_VERSION} ${STAGE_CHROOT_DIR}
1067

    
1068
	local DEFAULTCONF=${STAGE_CHROOT_DIR}/conf.default/config.xml
1069

    
1070
	# Change default interface names to match vmware driver
1071
	sed -i '' -e 's,em0,vmx0,' -e 's,em1,vmx1,' ${DEFAULTCONF}
1072
	core_pkg_create default-config-vmware "" ${CORE_PKG_VERSION} ${STAGE_CHROOT_DIR}
1073

    
1074
	# Restore default values to be used by serial package
1075
	sed -i '' -e 's,vmx0,em0,' -e 's,vmx1,em1,' ${DEFAULTCONF}
1076

    
1077
	# Activate serial console in config.xml
1078
	# If it was there before, clear the setting to be sure we don't add it twice.
1079
	sed -i "" -e "/		<enableserial\/>/d" ${DEFAULTCONF}
1080
	# Enable serial in the config
1081
	sed -i "" -e "s/	<\/system>/		<enableserial\/>\\$(echo -e \\\n)	<\/system>/" ${DEFAULTCONF}
1082

    
1083
	echo force > ${STAGE_CHROOT_DIR}/cf/conf/enableserial_force
1084

    
1085
	core_pkg_create default-config-serial "" ${CORE_PKG_VERSION} ${STAGE_CHROOT_DIR}
1086

    
1087
	rm -f ${STAGE_CHROOT_DIR}/cf/conf/enableserial_force
1088
	rm -f ${STAGE_CHROOT_DIR}/cf/conf/config.xml
1089

    
1090
	# Make sure pkg is present
1091
	pkg_bootstrap ${STAGE_CHROOT_DIR}
1092

    
1093
	echo "Done!"
1094
}
1095

    
1096
create_final_staging_area() {
1097
	if [ -z "${FINAL_CHROOT_DIR}" ]; then
1098
		echo ">>> ERROR: FINAL_CHROOT_DIR is not set, cannot continue!" | tee -a ${LOGFILE}
1099
		print_error_pfS
1100
	fi
1101

    
1102
	if [ -d "${FINAL_CHROOT_DIR}" ]; then
1103
		echo -n ">>> Previous ${FINAL_CHROOT_DIR} detected cleaning up..." | tee -a ${LOGFILE}
1104
		chflags -R noschg ${FINAL_CHROOT_DIR} 2>&1 1>/dev/null
1105
		rm -rf ${FINAL_CHROOT_DIR}/* 2>&1 1>/dev/null
1106
		echo "Done." | tee -a ${LOGFILE}
1107
	fi
1108

    
1109
	echo ">>> Preparing Final image staging area: $(LC_ALL=C date)" 2>&1 | tee -a ${LOGFILE}
1110
	echo ">>> Cloning ${STAGE_CHROOT_DIR} to ${FINAL_CHROOT_DIR}" 2>&1 | tee -a ${LOGFILE}
1111
	clone_directory_contents ${STAGE_CHROOT_DIR} ${FINAL_CHROOT_DIR}
1112

    
1113
	if [ ! -f $FINAL_CHROOT_DIR/sbin/init ]; then
1114
		echo ">>> ERROR: Something went wrong during cloning -- Please verify!" 2>&1 | tee -a ${LOGFILE}
1115
		print_error_pfS
1116
	fi
1117
}
1118

    
1119
customize_stagearea_for_image() {
1120
	# Prepare final stage area
1121
	create_final_staging_area
1122

    
1123
	if [ "${1}" = "nanobsd" -o \
1124
	     "${1}" = "nanobsd-vga" ]; then
1125
		pkg_chroot_add ${FINAL_CHROOT_DIR} base-nanobsd
1126
	else
1127
		pkg_chroot_add ${FINAL_CHROOT_DIR} base
1128
	fi
1129

    
1130
	if [ "${1}" = "iso" -o \
1131
	     "${1}" = "memstick" -o \
1132
	     "${1}" = "memstickserial" -o \
1133
	     "${1}" = "memstickadi" ]; then
1134
		install_bsdinstaller
1135
		mkdir -p ${FINAL_CHROOT_DIR}/pkgs
1136
		cp ${CORE_PKG_PATH}/All/*default-config*.txz ${FINAL_CHROOT_DIR}/pkgs
1137
	fi
1138

    
1139
	if [ "${1}" = "nanobsd" -o \
1140
	     "${1}" = "memstickserial" -o \
1141
	     "${1}" = "memstickadi" ]; then
1142
		pkg_chroot_add ${FINAL_CHROOT_DIR} default-config-serial
1143
	elif [ "${1}" = "ova" ]; then
1144
		pkg_chroot_add ${FINAL_CHROOT_DIR} default-config-vmware
1145
	else
1146
		pkg_chroot_add ${FINAL_CHROOT_DIR} default-config
1147
	fi
1148
}
1149

    
1150
create_distribution_tarball() {
1151
	mkdir -p ${FINAL_CHROOT_DIR}/install
1152

    
1153
	tar -C ${FINAL_CHROOT_DIR} --exclude ./install --exclude ./pkgs -cJf ${FINAL_CHROOT_DIR}/install/${PRODUCT_NAME}.txz .
1154
}
1155

    
1156
create_iso_image() {
1157
	LOGFILE=${BUILDER_LOGS}/isoimage.${TARGET}
1158
	echo ">>> Building bootable ISO image for ${TARGET}" | tee -a ${LOGFILE}
1159
	if [ -z "${DEFAULT_KERNEL}" ]; then
1160
		echo ">>> ERROR: Could not identify DEFAULT_KERNEL to install on image!" | tee -a ${LOGFILE}
1161
		print_error_pfS
1162
	fi
1163

    
1164
	customize_stagearea_for_image "iso"
1165
	install_default_kernel ${DEFAULT_KERNEL}
1166

    
1167
	echo cdrom > $FINAL_CHROOT_DIR/etc/platform
1168

    
1169
	FSLABEL=$(echo ${PRODUCT_NAME} | tr '[:lower:]' '[:upper:]')
1170
	echo "/dev/iso9660/${FSLABEL} / cd9660 ro 0 0" > ${FINAL_CHROOT_DIR}/etc/fstab
1171

    
1172
	# This check is for supporting create memstick/ova images
1173
	echo -n ">>> Running command: script -aq $LOGFILE makefs -t cd9660 -o bootimage=\"i386;${FINAL_CHROOT_DIR}/boot/cdboot \"-o no-emul-boot -o rockridge " | tee -a ${LOGFILE}
1174
	echo "-o label=${FSLABEL} -o publisher=\"${PRODUCT_NAME} project.\" $ISOPATH ${FINAL_CHROOT_DIR}" | tee -a ${LOGFILE}
1175

    
1176
	create_distribution_tarball
1177

    
1178
	# Remove /rescue from iso since cd9660 cannot deal with hardlinks
1179
	rm -rf ${FINAL_CHROOT_DIR}/rescue
1180

    
1181
	makefs -t cd9660 -o bootimage="i386;${FINAL_CHROOT_DIR}/boot/cdboot" -o no-emul-boot -o rockridge \
1182
		-o label=${FSLABEL} -o publisher="${PRODUCT_NAME} project." $ISOPATH ${FINAL_CHROOT_DIR} 2>&1 >> ${LOGFILE}
1183
	if [ $? -ne 0 -o ! -f $ISOPATH ]; then
1184
		if [ -f ${ISOPATH} ]; then
1185
			rm -f $ISOPATH
1186
		fi
1187
		echo ">>> ERROR: Something wrong happened during ISO image creation. STOPPING!" | tee -a ${LOGFILE}
1188
		print_error_pfS
1189
	fi
1190
	gzip -qf $ISOPATH &
1191
	_bg_pids="${_bg_pids}${_bg_pids:+ }$!"
1192

    
1193
	echo ">>> ISO created: $(LC_ALL=C date)" | tee -a ${LOGFILE}
1194
}
1195

    
1196
create_memstick_image() {
1197

    
1198
	LOGFILE=${BUILDER_LOGS}/memstick.${TARGET}
1199
	if [ "${MEMSTICKPATH}" = "" ]; then
1200
		echo ">>> MEMSTICKPATH is empty skipping generation of memstick image!" | tee -a ${LOGFILE}
1201
		return
1202
	fi
1203

    
1204
	if [ ! -d ${FINAL_CHROOT_DIR}/boot ]; then
1205
		customize_stagearea_for_image "memstick"
1206
		install_default_kernel ${DEFAULT_KERNEL}
1207
	fi
1208

    
1209
	echo cdrom > $FINAL_CHROOT_DIR/etc/platform
1210

    
1211
	echo ">>> Creating memstick to ${MEMSTICKPATH}." 2>&1 | tee -a ${LOGFILE}
1212
	echo "/dev/ufs/${PRODUCT_NAME} / ufs ro 0 0" > ${FINAL_CHROOT_DIR}/etc/fstab
1213
	echo "kern.cam.boot_delay=10000" >> ${FINAL_CHROOT_DIR}/boot/loader.conf.local
1214

    
1215
	create_distribution_tarball
1216

    
1217
	makefs -B little -o label=${PRODUCT_NAME} ${MEMSTICKPATH} ${FINAL_CHROOT_DIR}
1218
	if [ $? -ne 0 ]; then
1219
		if [ -f ${MEMSTICKPATH} ]; then
1220
			rm -f $MEMSTICKPATH
1221
		fi
1222
		echo ">>> ERROR: Something wrong happened during MEMSTICK image creation. STOPPING!" | tee -a ${LOGFILE}
1223
		print_error_pfS
1224
	fi
1225
	MD=$(mdconfig -a -t vnode -f $MEMSTICKPATH)
1226
	# Just in case
1227
	trap "mdconfig -d -u ${MD}" 1 2 15 EXIT
1228
	gpart create -s BSD ${MD} 2>&1 >> ${LOGFILE}|
1229
	gpart bootcode -b ${FINAL_CHROOT_DIR}/boot/boot ${MD} 2>&1 >> ${LOGFILE}
1230
	gpart add -t freebsd-ufs ${MD} 2>&1 >> ${LOGFILE}
1231
	trap "-" 1 2 15 EXIT
1232
	mdconfig -d -u ${MD} 2>&1 | tee -a ${LOGFILE}
1233
	gzip -qf $MEMSTICKPATH &
1234
	_bg_pids="${_bg_pids}${_bg_pids:+ }$!"
1235

    
1236
	echo ">>> MEMSTICK created: $(LC_ALL=C date)" | tee -a ${LOGFILE}
1237
}
1238

    
1239
create_memstick_serial_image() {
1240
	LOGFILE=${BUILDER_LOGS}/memstickserial.${TARGET}
1241
	if [ "${MEMSTICKSERIALPATH}" = "" ]; then
1242
		echo ">>> MEMSTICKSERIALPATH is empty skipping generation of memstick image!" | tee -a ${LOGFILE}
1243
		return
1244
	fi
1245

    
1246
	if [ ! -d ${FINAL_CHROOT_DIR}/boot ]; then
1247
		customize_stagearea_for_image "memstickserial"
1248
		install_default_kernel ${DEFAULT_KERNEL}
1249
	fi
1250

    
1251
	echo cdrom > $FINAL_CHROOT_DIR/etc/platform
1252

    
1253
	echo "/dev/ufs/${PRODUCT_NAME} / ufs ro 0 0" > ${FINAL_CHROOT_DIR}/etc/fstab
1254
	echo "kern.cam.boot_delay=10000" >> ${FINAL_CHROOT_DIR}/boot/loader.conf.local
1255

    
1256
	echo ">>> Creating serial memstick to ${MEMSTICKSERIALPATH}." 2>&1 | tee -a ${LOGFILE}
1257

    
1258
	BOOTCONF=${FINAL_CHROOT_DIR}/boot.config
1259
	LOADERCONF=${FINAL_CHROOT_DIR}/boot/loader.conf
1260

    
1261
	echo ">>> Activating serial console..." 2>&1 | tee -a ${LOGFILE}
1262
	# Activate serial console in boot.config
1263
	if [ -f ${BOOTCONF} ]; then
1264
		sed -i "" '/-D$/d' ${BOOTCONF}
1265
	fi
1266
	echo "-S115200 -D" >> ${BOOTCONF}
1267

    
1268
	# Remove old console options if present.
1269
	[ -f "${LOADERCONF}" ] \
1270
		&& sed -i "" -Ee "/(console|boot_multicons|boot_serial)/d" ${LOADERCONF}
1271
	# Activate serial console+video console in loader.conf
1272
	echo 'boot_multicons="YES"' >>  ${LOADERCONF}
1273
	echo 'boot_serial="YES"' >> ${LOADERCONF}
1274
	echo 'console="comconsole,vidconsole"' >> ${LOADERCONF}
1275
	echo 'comconsole_speed="115200"' >> ${LOADERCONF}
1276

    
1277
	create_distribution_tarball
1278

    
1279
	makefs -B little -o label=${PRODUCT_NAME} ${MEMSTICKSERIALPATH} ${FINAL_CHROOT_DIR}
1280
	if [ $? -ne 0 ]; then
1281
		if [ -f ${MEMSTICKSERIALPATH} ]; then
1282
			rm -f $MEMSTICKSERIALPATH
1283
		fi
1284
		echo ">>> ERROR: Something wrong happened during MEMSTICKSERIAL image creation. STOPPING!" | tee -a ${LOGFILE}
1285
		print_error_pfS
1286
	fi
1287
	MD=$(mdconfig -a -t vnode -f $MEMSTICKSERIALPATH)
1288
	# Just in case
1289
	trap "mdconfig -d -u ${MD}" 1 2 15 EXIT
1290
	gpart create -s BSD ${MD} 2>&1 >> ${LOGFILE}
1291
	gpart bootcode -b ${FINAL_CHROOT_DIR}/boot/boot ${MD} 2>&1 >> ${LOGFILE}
1292
	gpart add -t freebsd-ufs ${MD} 2>&1 >> ${LOGFILE}
1293
	trap "-" 1 2 15 EXIT
1294
	mdconfig -d -u ${MD} 2>&1 >> ${LOGFILE}
1295
	gzip -qf $MEMSTICKSERIALPATH &
1296
	_bg_pids="${_bg_pids}${_bg_pids:+ }$!"
1297

    
1298
	echo ">>> MEMSTICKSERIAL created: $(LC_ALL=C date)" | tee -a ${LOGFILE}
1299
}
1300

    
1301
create_memstick_adi_image() {
1302
	LOGFILE=${BUILDER_LOGS}/memstickadi${TARGET}
1303
	if [ "${MEMSTICKADIPATH}" = "" ]; then
1304
		echo ">>> MEMSTICKADIPATH is empty skipping generation of memstick image!" | tee -a ${LOGFILE}
1305
		return
1306
	fi
1307

    
1308
	if [ ! -d ${FINAL_CHROOT_DIR}/boot ]; then
1309
		customize_stagearea_for_image "memstickadi"
1310
		install_default_kernel ${DEFAULT_KERNEL}
1311
	fi
1312

    
1313
	echo cdrom > $FINAL_CHROOT_DIR/etc/platform
1314

    
1315
	echo "/dev/ufs/${PRODUCT_NAME} / ufs ro 0 0" > ${FINAL_CHROOT_DIR}/etc/fstab
1316
	echo "kern.cam.boot_delay=10000" >> ${FINAL_CHROOT_DIR}/boot/loader.conf.local
1317

    
1318
	echo ">>> Creating serial memstick to ${MEMSTICKADIPATH}." 2>&1 | tee -a ${LOGFILE}
1319

    
1320
	BOOTCONF=${FINAL_CHROOT_DIR}/boot.config
1321
	LOADERCONF=${FINAL_CHROOT_DIR}/boot/loader.conf
1322

    
1323
	echo ">>> Activating serial console..." 2>&1 | tee -a ${LOGFILE}
1324
	# Activate serial console in boot.config
1325
	if [ -f ${BOOTCONF} ]; then
1326
		sed -i "" '/-[Dh]$/d' ${BOOTCONF}
1327
	fi
1328
	echo "-S115200 -h" >> ${BOOTCONF}
1329

    
1330
	# Remove old console options if present.
1331
	[ -f "${LOADERCONF}" ] \
1332
		&& sed -i "" -Ee "/(console|boot_multicons|boot_serial|hint.uart)/d" ${LOADERCONF}
1333
	# Activate serial console+video console in loader.conf
1334
	echo 'boot_serial="YES"' >> ${LOADERCONF}
1335
	echo 'console="comconsole"' >> ${LOADERCONF}
1336
	echo 'comconsole_speed="115200"' >> ${LOADERCONF}
1337
	echo 'comconsole_port="0x2F8"' >> ${LOADERCONF}
1338
	echo 'hint.uart.0.flags="0x00"' >> ${LOADERCONF}
1339
	echo 'hint.uart.1.flags="0x10"' >> ${LOADERCONF}
1340

    
1341
	create_distribution_tarball
1342

    
1343
	makefs -B little -o label=${PRODUCT_NAME} ${MEMSTICKADIPATH} ${FINAL_CHROOT_DIR}
1344
	if [ $? -ne 0 ]; then
1345
		if [ -f ${MEMSTICKADIPATH} ]; then
1346
			rm -f $MEMSTICKADIPATH
1347
		fi
1348
		echo ">>> ERROR: Something wrong happened during MEMSTICKADI image creation. STOPPING!" | tee -a ${LOGFILE}
1349
		print_error_pfS
1350
	fi
1351
	MD=$(mdconfig -a -t vnode -f $MEMSTICKADIPATH)
1352
	# Just in case
1353
	trap "mdconfig -d -u ${MD}" 1 2 15 EXIT
1354
	gpart create -s BSD ${MD} 2>&1 >> ${LOGFILE}
1355
	gpart bootcode -b ${FINAL_CHROOT_DIR}/boot/boot ${MD} 2>&1 >> ${LOGFILE}
1356
	gpart add -t freebsd-ufs ${MD} 2>&1 >> ${LOGFILE}
1357
	trap "-" 1 2 15 EXIT
1358
	mdconfig -d -u ${MD} 2>&1 >> ${LOGFILE}
1359
	gzip -qf $MEMSTICKADIPATH &
1360
	_bg_pids="${_bg_pids}${_bg_pids:+ }$!"
1361

    
1362
	echo ">>> MEMSTICKADI created: $(LC_ALL=C date)" | tee -a ${LOGFILE}
1363
}
1364

    
1365
# Create pkg conf on desired place with desired arch/branch
1366
setup_pkg_repo() {
1367
	if [ -z "${4}" ]; then
1368
		return
1369
	fi
1370

    
1371
	local _target="${1}"
1372
	local _arch="${2}"
1373
	local _target_arch="${3}"
1374
	local _branch="${4}"
1375

    
1376
	mkdir -p $(dirname ${_target}) >/dev/null 2>&1
1377

    
1378
	sed \
1379
		-e "s/%%ARCH%%/${_arch}_${_target_arch}/" \
1380
		-e "s/%%GIT_REPO_BRANCH_OR_TAG%%/${_branch}/g" \
1381
		-e "s,%%PKG_REPO_SERVER%%,${PKG_REPO_SERVER},g" \
1382
		-e "s/%%PRODUCT_NAME%%/${PRODUCT_NAME}/g" \
1383
		${FREEBSD_SRC_DIR}/release/pkg_repos/${PRODUCT_NAME}.conf.template \
1384
		> ${_target}
1385
}
1386

    
1387
# This routine ensures any ports / binaries that the builder
1388
# system needs are on disk and ready for execution.
1389
builder_setup() {
1390
	# If Product-builder is already installed, just leave
1391
	if pkg info -e -q ${PRODUCT_NAME}-builder; then
1392
		return
1393
	fi
1394

    
1395
	if [ ! -f /usr/local/etc/pkg/repos/${PRODUCT_NAME}.conf ]; then
1396
		[ -d /usr/local/etc/pkg/repos ] \
1397
			|| mkdir -p /usr/local/etc/pkg/repos
1398

    
1399
		update_freebsd_sources
1400

    
1401
		local _arch=$(uname -m)
1402
		setup_pkg_repo /usr/local/etc/pkg/repos/${PRODUCT_NAME}.conf ${_arch} ${_arch} ${PKG_REPO_CONF_BRANCH}
1403
	fi
1404

    
1405
	pkg install ${PRODUCT_NAME}-builder
1406
}
1407

    
1408
# Updates FreeBSD sources
1409
update_freebsd_sources() {
1410
	if [ "${1}" = "full" ]; then
1411
		local _full=1
1412
		local _clone_params=""
1413
	else
1414
		local _full=0
1415
		local _clone_params="--depth 1 --single-branch"
1416
	fi
1417

    
1418
	if [ ! -d "${FREEBSD_SRC_DIR}" ]; then
1419
		mkdir -p ${FREEBSD_SRC_DIR}
1420
	fi
1421

    
1422
	if [ -n "${NO_BUILDWORLD}" -a -n "${NO_BUILDKERNEL}" ]; then
1423
		echo ">>> NO_BUILDWORLD and NO_BUILDKERNEL set, skipping update of freebsd sources" | tee -a ${LOGFILE}
1424
		return
1425
	fi
1426

    
1427
	echo -n ">>> Obtaining FreeBSD sources ${FREEBSD_BRANCH}..."
1428
	local _FREEBSD_BRANCH=${FREEBSD_BRANCH:-"devel"}
1429
	local _CLONE=1
1430

    
1431
	if [ -d "${FREEBSD_SRC_DIR}/.git" ]; then
1432
		CUR_BRANCH=$(cd ${FREEBSD_SRC_DIR} && git branch | grep '^\*' | cut -d' ' -f2)
1433
		if [ ${_full} -eq 0 -a "${CUR_BRANCH}" = "${_FREEBSD_BRANCH}" ]; then
1434
			_CLONE=0
1435
			( cd ${FREEBSD_SRC_DIR} && git clean -fd; git fetch origin; git reset --hard origin/${_FREEBSD_BRANCH} ) 2>&1 | grep -C3 -i -E 'error|fatal'
1436
		else
1437
			rm -rf ${FREEBSD_SRC_DIR}
1438
		fi
1439
	fi
1440

    
1441
	if [ ${_CLONE} -eq 1 ]; then
1442
		( git clone --branch ${_FREEBSD_BRANCH} ${_clone_params} ${FREEBSD_REPO_BASE} ${FREEBSD_SRC_DIR} ) 2>&1 | grep -C3 -i -E 'error|fatal'
1443
	fi
1444

    
1445
	if [ ! -d "${FREEBSD_SRC_DIR}/.git" ]; then
1446
		echo ">>> ERROR: It was not possible to clone FreeBSD src repo"
1447
		print_error_pfS
1448
	fi
1449

    
1450
	if [ -n "${GIT_FREEBSD_COSHA1}" ]; then
1451
		( cd ${FREEBSD_SRC_DIR} && git checkout ${GIT_FREEBSD_COSHA1} ) 2>&1 | grep -C3 -i -E 'error|fatal'
1452
	fi
1453
	echo "Done!"
1454
}
1455

    
1456
pkg_chroot() {
1457
	local _root="${1}"
1458
	shift
1459

    
1460
	if [ $# -eq 0 ]; then
1461
		return -1
1462
	fi
1463

    
1464
	if [ -z "${_root}" -o "${_root}" = "/" -o ! -d "${_root}" ]; then
1465
		return -1
1466
	fi
1467

    
1468
	mkdir -p \
1469
		${SCRATCHDIR}/pkg_cache \
1470
		${_root}/var/cache/pkg \
1471
		${_root}/dev
1472

    
1473
	/sbin/mount -t nullfs ${SCRATCHDIR}/pkg_cache ${_root}/var/cache/pkg
1474
	/sbin/mount -t devfs devfs ${_root}/dev
1475
	cp -f /etc/resolv.conf ${_root}/etc/resolv.conf
1476
	touch ${BUILDER_LOGS}/install_pkg_install_ports.txt
1477
	script -aq ${BUILDER_LOGS}/install_pkg_install_ports.txt pkg -c ${_root} $@ >/dev/null 2>&1
1478
	rm -f ${_root}/etc/resolv.conf
1479
	/sbin/umount -f ${_root}/dev
1480
	/sbin/umount -f ${_root}/var/cache/pkg
1481
}
1482

    
1483

    
1484
pkg_chroot_add() {
1485
	if [ -z "${1}" -o -z "${2}" ]; then
1486
		return 1
1487
	fi
1488

    
1489
	local _target="${1}"
1490
	local _pkg="$(get_pkg_name ${2}).txz"
1491

    
1492
	if [ ! -d "${_target}" ]; then
1493
		echo ">>> ERROR: Target dir ${_target} not found"
1494
		print_error_pfS
1495
	fi
1496

    
1497
	if [ ! -f ${CORE_PKG_PATH}/All/${_pkg} ]; then
1498
		echo ">>> ERROR: Package ${_pkg} not found"
1499
		print_error_pfS
1500
	fi
1501

    
1502
	cp ${CORE_PKG_PATH}/All/${_pkg} ${_target}
1503
	pkg_chroot ${_target} add /${_pkg}
1504
	rm -f ${_target}/${_pkg}
1505
}
1506

    
1507
pkg_bootstrap() {
1508
	local _root=${1:-"${STAGE_CHROOT_DIR}"}
1509

    
1510
	setup_pkg_repo ${_root}/usr/local/etc/pkg/repos/${PRODUCT_NAME}.conf ${TARGET} ${TARGET_ARCH} ${PKG_REPO_CONF_BRANCH}
1511

    
1512
	pkg_chroot ${_root} bootstrap -f
1513
}
1514

    
1515
# This routine assists with installing various
1516
# freebsd ports files into the pfsenese-fs staging
1517
# area.
1518
install_pkg_install_ports() {
1519
	local MAIN_PKG="${1}"
1520

    
1521
	if [ -z "${MAIN_PKG}" ]; then
1522
		MAIN_PKG=${PRODUCT_NAME}
1523
	fi
1524

    
1525
	echo ">>> Installing pkg repository in chroot (${STAGE_CHROOT_DIR})..."
1526

    
1527
	[ -d ${STAGE_CHROOT_DIR}/var/cache/pkg ] || \
1528
		mkdir -p ${STAGE_CHROOT_DIR}/var/cache/pkg
1529

    
1530
	[ -d ${SCRATCHDIR}/pkg_cache ] || \
1531
		mkdir -p ${SCRATCHDIR}/pkg_cache
1532

    
1533
	echo ">>> Installing built ports (packages) in chroot (${STAGE_CHROOT_DIR})... (starting)"
1534
	pkg_chroot ${STAGE_CHROOT_DIR} install ${MAIN_PKG} ${custom_package_list}
1535
	pkg_chroot ${STAGE_CHROOT_DIR} autoremove
1536
	echo ">>> Installing built ports (packages) in chroot (${STAGE_CHROOT_DIR})... (finshied)"
1537
}
1538

    
1539
install_bsdinstaller() {
1540
	echo ">>> Installing BSDInstaller in chroot (${FINAL_CHROOT_DIR})... (starting)"
1541
	pkg_chroot ${FINAL_CHROOT_DIR} install -f bsdinstaller
1542
	sed -i '' -e "s,%%PRODUCT_NAME%%,${PRODUCT_NAME}," \
1543
		  -e "s,%%PRODUCT_VERSION%%,${PRODUCT_VERSION}," \
1544
		  -e "s,%%ARCH%%,${TARGET}," \
1545
		  ${FINAL_CHROOT_DIR}/usr/local/share/dfuibe_lua/conf/pfSense.lua \
1546
		  ${FINAL_CHROOT_DIR}/usr/local/share/dfuibe_lua/conf/pfSense_rescue.lua
1547
	echo ">>> Installing BSDInstaller in chroot (${FINAL_CHROOT_DIR})... (finished)"
1548
}
1549

    
1550
staginareas_clean_each_run() {
1551
	echo -n ">>> Cleaning build directories: "
1552
	if [ -d "${FINAL_CHROOT_DIR}" ]; then
1553
		BASENAME=$(basename ${FINAL_CHROOT_DIR})
1554
		echo -n "$BASENAME "
1555
		chflags -R noschg ${FINAL_CHROOT_DIR} 2>&1 >/dev/null
1556
		rm -rf ${FINAL_CHROOT_DIR}/* 2>/dev/null
1557
	fi
1558
	echo "Done!"
1559
}
1560

    
1561
# Imported from FreeSBIE
1562
buildkernel() {
1563
	if [ -n "${NO_BUILDKERNEL}" ]; then
1564
		echo ">>> NO_BUILDKERNEL set, skipping build" | tee -a ${LOGFILE}
1565
		return
1566
	fi
1567

    
1568
	if [ -z "${KERNCONF}" ]; then
1569
		echo ">>> ERROR: No kernel configuration defined probably this is not what you want! STOPPING!" | tee -a ${LOGFILE}
1570
		print_error_pfS
1571
	fi
1572

    
1573
	if [ -n "${KERNELCONF}" ]; then
1574
		export KERNCONFDIR=$(dirname ${KERNELCONF})
1575
		export KERNCONF=$(basename ${KERNELCONF})
1576
	fi
1577

    
1578
	SRCCONFBASENAME=$(basename ${SRC_CONF})
1579
	echo ">>> KERNCONFDIR: ${KERNCONFDIR}"
1580
	echo ">>> ARCH:        ${TARGET}"
1581
	echo ">>> SRC_CONF:    ${SRCCONFBASENAME}"
1582

    
1583
	makeargs="${MAKEJ_KERNEL} SRCCONF=${SRC_CONF} __MAKE_CONF=${MAKE_CONF} TARGET_ARCH=${TARGET_ARCH} TARGET=${TARGET}"
1584
	echo ">>> Builder is running the command: script -aq $LOGFILE make -DNO_KERNELCLEAN $makeargs buildkernel KERNCONF=${KERNCONF}" | tee -a $LOGFILE
1585
	(script -q $LOGFILE make -C ${FREEBSD_SRC_DIR} -DNO_KERNELCLEAN $makeargs buildkernel KERNCONF=${KERNCONF} || print_error_pfS;) | egrep '^>>>'
1586
}
1587

    
1588
# Imported from FreeSBIE
1589
installkernel() {
1590
	if [ -z "${KERNCONF}" ]; then
1591
		echo ">>> ERROR: No kernel configuration defined probably this is not what you want! STOPPING!" | tee -a ${LOGFILE}
1592
		print_error_pfS
1593
	fi
1594

    
1595
	if [ -n "${KERNELCONF}" ]; then
1596
		export KERNCONFDIR=$(dirname ${KERNELCONF})
1597
		export KERNCONF=$(basename ${KERNELCONF})
1598
	fi
1599

    
1600
	mkdir -p ${STAGE_CHROOT_DIR}/boot
1601
	makeargs="${MAKEJ_KERNEL} SRCCONF=${SRC_CONF} __MAKE_CONF=${MAKE_CONF} TARGET_ARCH=${TARGET_ARCH} TARGET=${TARGET} DESTDIR=${KERNEL_DESTDIR}"
1602
	echo ">>> Builder is running the command: script -aq $LOGFILE make ${makeargs} installkernel KERNCONF=${KERNCONF}"  | tee -a $LOGFILE
1603
	(script -aq $LOGFILE make -C ${FREEBSD_SRC_DIR} ${makeargs} installkernel KERNCONF=${KERNCONF} || print_error_pfS;) | egrep '^>>>'
1604
	gzip -f9 $KERNEL_DESTDIR/boot/kernel/kernel
1605
}
1606

    
1607
# Launch is ran first to setup a few variables that we need
1608
# Imported from FreeSBIE
1609
launch() {
1610
	if [ "$(id -u)" != "0" ]; then
1611
		echo "Sorry, this must be done as root."
1612
	fi
1613

    
1614
	echo ">>> Operation $0 has started at $(date)"
1615
}
1616

    
1617
finish() {
1618
	echo ">>> Operation $0 has ended at $(date)"
1619
}
1620

    
1621
pkg_repo_rsync() {
1622
	local _repo_path="${1}"
1623

    
1624
	if [ -n "${DO_NOT_UPLOAD}" -o -z "${_repo_path}" -o ! -d "${_repo_path}" ]; then
1625
		return
1626
	fi
1627

    
1628
	if [ -z "${LOGFILE}" ]; then
1629
		local _logfile="/dev/null"
1630
	else
1631
		local _logfile="${LOGFILE}"
1632
	fi
1633

    
1634
	echo -n ">>> Sending updated repository to ${PKG_RSYNC_HOSTNAME}... " | tee -a ${_logfile}
1635
	if script -aq ${_logfile} rsync -ave "ssh -p ${PKG_RSYNC_SSH_PORT}" \
1636
		--timeout=60 --delete-delay ${_repo_path} \
1637
		${PKG_RSYNC_USERNAME}@${PKG_RSYNC_HOSTNAME}:${PKG_RSYNC_DESTDIR} >/dev/null 2>&1
1638
	then
1639
		echo "Done!" | tee -a ${_logfile}
1640
	else
1641
		echo "Failed!" | tee -a ${_logfile}
1642
		echo ">>> ERROR: An error occurred sending repo to remote hostname"
1643
		print_error_pfS
1644
	fi
1645
}
1646

    
1647
poudriere_create_patch() {
1648
	local _jail_patch="${SCRATCHDIR}/poudriere_jail.${GIT_REPO_BRANCH_OR_TAG}.patch"
1649

    
1650
	if [ -z "${FREEBSD_PARENT_BRANCH}" ]; then
1651
		echo ">>> ERROR: FREEBSD_PARENT_BRANCH is not set"
1652
	fi
1653

    
1654
	LOGFILE=${BUILDER_LOGS}/poudriere.log
1655

    
1656
	# Get FreeBSD source and apply patches
1657
	update_freebsd_sources full
1658

    
1659
	[ -f "${_jail_patch}" ] && \
1660
		rm -f "${_jail_patch}"
1661

    
1662
	# Create a big patch with all our changes to use on jail
1663
	( \
1664
		cd ${FREEBSD_SRC_DIR} && \
1665
		git diff $(git merge-base origin/${FREEBSD_PARENT_BRANCH} ${FREEBSD_BRANCH}) > ${_jail_patch}
1666
	) >/dev/null 2>&1
1667

    
1668
	# Check if patch was created
1669
	if [ ! -s "${_jail_patch}" ]; then
1670
		echo ">>> ERROR: Patch does not exist or is empty, aborting..." | tee -a ${LOGFILE}
1671
		print_error_pfS
1672
	fi
1673
}
1674

    
1675
poudriere_possible_archs() {
1676
	local _arch=$(uname -m)
1677
	local _archs="i386.i386"
1678

    
1679
	# IF host is amd64, we'll create both repos, and if possible armv6
1680
	if [ "${_arch}" = "amd64" ]; then
1681
		_archs="amd64.amd64 ${_archs}"
1682

    
1683
		if [ -f /usr/local/bin/qemu-arm-static ]; then
1684
			# Make sure binmiscctl is ok
1685
			/usr/local/etc/rc.d/qemu_user_static forcestart >/dev/null 2>&1
1686

    
1687
			if binmiscctl lookup armv6 >/dev/null 2>&1; then
1688
				_archs="${_archs} arm.armv6"
1689
			fi
1690
		fi
1691
	fi
1692

    
1693
	if [ -n "${ARCH_LIST}" ]; then
1694
		local _found=0
1695
		for _desired_arch in ${ARCH_LIST}; do
1696
			_found=0
1697
			for _possible_arch in ${_archs}; do
1698
				if [ "${_desired_arch}" = "${_possible_arch}" ]; then
1699
					_found=1
1700
					break
1701
				fi
1702
			done
1703
			if [ ${_found} -eq 0 ]; then
1704
				echo ">>> ERROR: Impossible to build for arch: ${_desired_arch}"
1705
				print_error_pfS
1706
			fi
1707
		done
1708
		_archs="${ARCH_LIST}"
1709
	fi
1710

    
1711
	echo ${_archs}
1712
}
1713

    
1714
poudriere_jail_name() {
1715
	local _jail_arch="${1}"
1716

    
1717
	if [ -z "${_jail_arch}" ]; then
1718
		return 1
1719
	fi
1720

    
1721
	# Poudriere doesn't like periods in jail names
1722
	_jail_arch=$(echo "${_jail_arch}" | tr '.' '_')
1723

    
1724
	echo "${PRODUCT_NAME}_${GIT_REPO_BRANCH_OR_TAG}_${_jail_arch}"
1725
}
1726

    
1727
poudriere_create_ports_tree() {
1728
	LOGFILE=${BUILDER_LOGS}/poudriere.log
1729

    
1730
	if ! poudriere ports -l | grep -q -E "^${POUDRIERE_PORTS_NAME}[[:blank:]]"; then
1731
		local _branch=""
1732
		if [ -z "${POUDRIERE_PORTS_GIT_URL}" ]; then
1733
			echo ">>> ERROR: POUDRIERE_PORTS_GIT_URL is not defined"
1734
			print_error_pfS
1735
		fi
1736
		if [ -n "${POUDRIERE_PORTS_GIT_BRANCH}" ]; then
1737
			_branch="-B ${POUDRIERE_PORTS_GIT_BRANCH}"
1738
		fi
1739
		echo -n ">>> Creating poudriere ports tree, it may take some time... " | tee -a ${LOGFILE}
1740
		if ! script -aq ${LOGFILE} poudriere ports -c -p "${POUDRIERE_PORTS_NAME}" -m git ${_branch} >/dev/null 2>&1; then
1741
			echo "" | tee -a ${LOGFILE}
1742
			echo ">>> ERROR: Error creating poudriere ports tree, aborting..." | tee -a ${LOGFILE}
1743
			print_error_pfS
1744
		fi
1745
		echo "Done!" | tee -a ${LOGFILE}
1746
	fi
1747
}
1748

    
1749
poudriere_init() {
1750
	local _error=0
1751
	local _archs=$(poudriere_possible_archs)
1752
	local _jail_patch="${SCRATCHDIR}/poudriere_jail.${GIT_REPO_BRANCH_OR_TAG}.patch"
1753

    
1754
	LOGFILE=${BUILDER_LOGS}/poudriere.log
1755

    
1756
	# Sanity checks
1757
	if [ -z "${ZFS_TANK}" ]; then
1758
		echo ">>> ERROR: \$ZFS_TANK is empty" | tee -a ${LOGFILE}
1759
		error=1
1760
	fi
1761

    
1762
	if [ -z "${ZFS_ROOT}" ]; then
1763
		echo ">>> ERROR: \$ZFS_ROOT is empty" | tee -a ${LOGFILE}
1764
		error=1
1765
	fi
1766

    
1767
	if [ -z "${POUDRIERE_PORTS_NAME}" ]; then
1768
		echo ">>> ERROR: \$POUDRIERE_PORTS_NAME is empty" | tee -a ${LOGFILE}
1769
		error=1
1770
	fi
1771

    
1772
	if [ ${_error} -eq 1 ]; then
1773
		print_error_pfS
1774
	fi
1775

    
1776
	# Check if zpool exists
1777
	if ! zpool list ${ZFS_TANK} >/dev/null 2>&1; then
1778
		echo ">>> ERROR: ZFS tank ${ZFS_TANK} not found, please create it and try again..." | tee -a ${LOGFILE}
1779
		print_error_pfS
1780
	fi
1781

    
1782
	# Check if zfs rootfs exists
1783
	if ! zfs list ${ZFS_TANK}${ZFS_ROOT} >/dev/null 2>&1; then
1784
		echo ">>> ERROR: ZFS filesystem ${ZFS_TANK}${ZFS_ROOT} not found, please create it and try again..." | tee -a ${LOGFILE}
1785
		print_error_pfS
1786
	fi
1787

    
1788
	# Make sure poudriere is installed
1789
	if ! pkg info --quiet poudriere; then
1790
		echo ">>> Installing poudriere..." | tee -a ${LOGFILE}
1791
		if ! pkg install poudriere >/dev/null 2>&1; then
1792
			echo ">>> ERROR: poudriere was not installed, aborting..." | tee -a ${LOGFILE}
1793
			print_error_pfS
1794
		fi
1795
	fi
1796

    
1797
	# Create poudriere.conf
1798
	if [ -z "${POUDRIERE_PORTS_GIT_URL}" ]; then
1799
		echo ">>> ERROR: POUDRIERE_PORTS_GIT_URL is not defined"
1800
		print_error_pfS
1801
	fi
1802
	echo ">>> Creating poudriere.conf" | tee -a ${LOGFILE}
1803
	cat <<EOF >/usr/local/etc/poudriere.conf
1804
ZPOOL=${ZFS_TANK}
1805
ZROOTFS=${ZFS_ROOT}
1806
RESOLV_CONF=/etc/resolv.conf
1807
BASEFS=/usr/local/poudriere
1808
USE_PORTLINT=no
1809
USE_TMPFS=yes
1810
NOLINUX=yes
1811
DISTFILES_CACHE=/usr/ports/distfiles
1812
CHECK_CHANGED_OPTIONS=yes
1813
CHECK_CHANGED_DEPS=yes
1814
ATOMIC_PACKAGE_REPOSITORY=yes
1815
COMMIT_PACKAGES_ON_FAILURE=no
1816
GIT_URL="${POUDRIERE_PORTS_GIT_URL}"
1817
EOF
1818

    
1819
	# Remove old jails
1820
	for jail_arch in ${_archs}; do
1821
		jail_name=$(poudriere_jail_name ${jail_arch})
1822

    
1823
		if poudriere jail -i -j "${jail_name}" >/dev/null 2>&1; then
1824
			echo ">>> Poudriere jail ${jail_name} already exists, deleting it..." | tee -a ${LOGFILE}
1825
			poudriere jail -d -j "${jail_name}" >/dev/null 2>&1
1826
		fi
1827
	done
1828

    
1829
	# Remove old ports tree
1830
	if poudriere ports -l | grep -q -E "^${POUDRIERE_PORTS_NAME}[[:blank:]]"; then
1831
		echo ">>> Poudriere ports tree ${POUDRIERE_PORTS_NAME} already exists, deleting it..." | tee -a ${LOGFILE}
1832
		poudriere ports -d -p "${POUDRIERE_PORTS_NAME}"
1833
	fi
1834

    
1835
	poudriere_create_patch
1836

    
1837
	local native_xtools=""
1838
	# Now we are ready to create jails
1839
	for jail_arch in ${_archs}; do
1840
		jail_name=$(poudriere_jail_name ${jail_arch})
1841

    
1842
		if [ "${jail_arch}" = "arm.armv6" ]; then
1843
			native_xtools="-x"
1844
		else
1845
			native_xtools=""
1846
		fi
1847

    
1848
		echo -n ">>> Creating jail ${jail_name}, it may take some time... " | tee -a ${LOGFILE}
1849
		# XXX: Change -m to git when it's available in poudriere
1850
		if ! script -aq ${LOGFILE} poudriere jail -c -j "${jail_name}" -v ${FREEBSD_PARENT_BRANCH} \
1851
				-a ${jail_arch} -m svn -P ${_jail_patch} ${native_xtools} >/dev/null 2>&1; then
1852
			echo "" | tee -a ${LOGFILE}
1853
			echo ">>> ERROR: Error creating jail ${jail_name}, aborting..." | tee -a ${LOGFILE}
1854
			print_error_pfS
1855
		fi
1856
		echo "Done!" | tee -a ${LOGFILE}
1857
	done
1858

    
1859
	poudriere_create_ports_tree
1860

    
1861
	echo ">>> Poudriere is now configured!" | tee -a ${LOGFILE}
1862
}
1863

    
1864
poudriere_update_jails() {
1865
	local _archs=$(poudriere_possible_archs)
1866
	local _jail_patch="${SCRATCHDIR}/poudriere_jail.${GIT_REPO_BRANCH_OR_TAG}.patch"
1867

    
1868
	LOGFILE=${BUILDER_LOGS}/poudriere.log
1869

    
1870
	poudriere_create_patch
1871

    
1872
	local native_xtools=""
1873
	for jail_arch in ${_archs}; do
1874
		jail_name=$(poudriere_jail_name ${jail_arch})
1875

    
1876
		if ! poudriere jail -i -j "${jail_name}" >/dev/null 2>&1; then
1877
			echo ">>> Poudriere jail ${jail_name} not found, skipping..." | tee -a ${LOGFILE}
1878
			continue
1879
		fi
1880

    
1881
		if [ "${jail_arch}" = "arm.armv6" ]; then
1882
			native_xtools="-x"
1883
		else
1884
			native_xtools=""
1885
		fi
1886

    
1887
		echo -n ">>> Updating jail ${jail_name}, it may take some time... " | tee -a ${LOGFILE}
1888
		if ! script -aq ${LOGFILE} poudriere jail -u -j "${jail_name}" -P ${_jail_patch} ${native_xtools} >/dev/null 2>&1; then
1889
			echo "" | tee -a ${LOGFILE}
1890
			echo ">>> ERROR: Error updating jail ${jail_name}, aborting..." | tee -a ${LOGFILE}
1891
			print_error_pfS
1892
		fi
1893
		echo "Done!" | tee -a ${LOGFILE}
1894
	done
1895
}
1896

    
1897
poudriere_update_ports() {
1898
	LOGFILE=${BUILDER_LOGS}/poudriere.log
1899

    
1900
	# Create ports tree if necessary
1901
	if ! poudriere ports -l | grep -q -E "^${POUDRIERE_PORTS_NAME}[[:blank:]]"; then
1902
		poudriere_create_ports_tree
1903
	else
1904
		echo -n ">>> Reseting local changes on ports tree ${POUDRIERE_PORTS_NAME}... " | tee -a ${LOGFILE}
1905
		script -aq ${LOGFILE} git -C "/usr/local/poudriere/ports/${POUDRIERE_PORTS_NAME}" reset --hard >/dev/null 2>&1
1906
		script -aq ${LOGFILE} git -C "/usr/local/poudriere/ports/${POUDRIERE_PORTS_NAME}" clean -fd >/dev/null 2>&1
1907
		echo "Done!" | tee -a ${LOGFILE}
1908
		echo -n ">>> Updating ports tree ${POUDRIERE_PORTS_NAME}... " | tee -a ${LOGFILE}
1909
		script -aq ${LOGFILE} poudriere ports -u -p "${POUDRIERE_PORTS_NAME}" >/dev/null 2>&1
1910
		echo "Done!" | tee -a ${LOGFILE}
1911
	fi
1912
}
1913

    
1914
poudriere_bulk() {
1915
	local _archs=$(poudriere_possible_archs)
1916

    
1917
	LOGFILE=${BUILDER_LOGS}/poudriere.log
1918

    
1919
	if [ -z "${DO_NOT_UPLOAD}" -a -z "${PKG_RSYNC_HOSTNAME}" ]; then
1920
		echo ">>> ERROR: PKG_RSYNC_HOSTNAME is not set"
1921
		print_error_pfS
1922
	fi
1923

    
1924
	poudriere_create_ports_tree
1925

    
1926
	[ -d /usr/local/etc/poudriere.d ] || \
1927
		mkdir -p /usr/local/etc/poudriere.d
1928

    
1929
	if [ -f "${BUILDER_TOOLS}/conf/pfPorts/make.conf" ]; then
1930
		cp -f "${BUILDER_TOOLS}/conf/pfPorts/make.conf" /usr/local/etc/poudriere.d/${POUDRIERE_PORTS_NAME}-make.conf
1931
	fi
1932

    
1933
	# Change version of pfSense meta ports for snapshots
1934
	if [ -z "${_IS_RELEASE}" ]; then
1935
		for meta_pkg in ${PRODUCT_NAME} ${PRODUCT_NAME}-vmware; do
1936
			local _meta_pkg_version="$(echo "${PRODUCT_VERSION}" | sed 's,DEVELOPMENT,ALPHA,')-${DATESTRING}"
1937
			sed -i '' -e "/^DISTVERSION/ s,^.*,DISTVERSION=	${_meta_pkg_version}," \
1938
				/usr/local/poudriere/ports/${POUDRIERE_PORTS_NAME}/security/${meta_pkg}/Makefile
1939
		done
1940
	fi
1941

    
1942
	for jail_arch in ${_archs}; do
1943
		jail_name=$(poudriere_jail_name ${jail_arch})
1944

    
1945
		if ! poudriere jail -i -j "${jail_name}" >/dev/null 2>&1; then
1946
			echo ">>> Poudriere jail ${jail_name} not found, skipping..." | tee -a ${LOGFILE}
1947
			continue
1948
		fi
1949

    
1950
		if [ -f "${POUDRIERE_BULK}.${jail_arch}" ]; then
1951
			_ref_bulk="${POUDRIERE_BULK}.${jail_arch}"
1952
		else
1953
			_ref_bulk="${POUDRIERE_BULK}"
1954
		fi
1955

    
1956
		_bulk=${SCRATCHDIR}/poudriere_bulk.${GIT_REPO_BRANCH_OR_TAG}
1957
		sed -e "s,%%PRODUCT_NAME%%,${PRODUCT_NAME},g" ${_ref_bulk} > ${_bulk}
1958

    
1959
		if ! poudriere bulk -f ${_bulk} -j ${jail_name} -p ${POUDRIERE_PORTS_NAME}; then
1960
			echo ">>> ERROR: Something went wrong..."
1961
			print_error_pfS
1962
		fi
1963

    
1964
		echo ">>> Cleaning up old packages from repo..."
1965
		if ! poudriere pkgclean -f ${_bulk} -j ${jail_name} -p ${POUDRIERE_PORTS_NAME} -y; then
1966
			echo ">>> ERROR: Something went wrong..."
1967
			print_error_pfS
1968
		fi
1969

    
1970
		# ./ is intentional, it's a rsync trick to make it chdir to directory before send it
1971
		pkg_repo_rsync "/usr/local/poudriere/data/packages/./${jail_name}-${POUDRIERE_PORTS_NAME}"
1972
	done
1973
}
1974

    
1975
# This routine is called to write out to stdout
1976
# a string. The string is appended to $SNAPSHOTSLOGFILE
1977
# and we scp the log file to the builder host if
1978
# needed for the real time logging functions.
1979
snapshots_update_status() {
1980
	if [ -z "${SNAPSHOTS}" -o -z "$1" ]; then
1981
		return
1982
	fi
1983
	echo $1
1984
	echo "`date` -|- $1" >> $SNAPSHOTSLOGFILE
1985
	if [ -z "${DO_NOT_UPLOAD}" -a -n "${RSYNCIP}" ]; then
1986
		LU=`cat $SNAPSHOTSLASTUPDATE`
1987
		CT=`date "+%H%M%S"`
1988
		# Only update every minute
1989
		if [ "$LU" != "$CT" ]; then
1990
			ssh ${RSYNCUSER}@${RSYNCIP} "mkdir -p ${RSYNCLOGS}"
1991
			scp -q $SNAPSHOTSLOGFILE ${RSYNCUSER}@${RSYNCIP}:${RSYNCLOGS}/build.log
1992
			date "+%H%M%S" > $SNAPSHOTSLASTUPDATE
1993
		fi
1994
	fi
1995
}
1996

    
1997
# Copy the current log file to $filename.old on
1998
# the snapshot www server (real time logs)
1999
snapshots_rotate_logfile() {
2000
	if [ -z "${DO_NOT_UPLOAD}" -a -n "${RSYNCIP}" ]; then
2001
		scp -q $SNAPSHOTSLOGFILE ${RSYNCUSER}@${RSYNCIP}:${RSYNCLOGS}/build.log.old
2002
	fi
2003

    
2004
	# Cleanup log file
2005
	rm -f $SNAPSHOTSLOGFILE;    touch $SNAPSHOTSLOGFILE
2006
	rm -f $SNAPSHOTSLASTUPDATE; touch $SNAPSHOTSLASTUPDATE
2007

    
2008
}
2009

    
2010
snapshots_copy_to_staging_nanobsd() {
2011
	for NANOTYPE in nanobsd nanobsd-vga; do
2012
		for FILESIZE in ${1}; do
2013
			FILENAMEFULL="${PRODUCT_NAME}-${PRODUCT_VERSION}-${FILESIZE}-${TARGET}-${NANOTYPE}${TIMESTAMP_SUFFIX}.img.gz"
2014
			FILENAMEUPGRADE="${PRODUCT_NAME}-${PRODUCT_VERSION}-${FILESIZE}-${TARGET}-${NANOTYPE}-upgrade${TIMESTAMP_SUFFIX}.img.gz"
2015
			mkdir -p $STAGINGAREA/nanobsd
2016
			mkdir -p $STAGINGAREA/nanobsdupdates
2017

    
2018
			cp $IMAGES_FINAL_DIR/$FILENAMEFULL $STAGINGAREA/nanobsd/ 2>/dev/null
2019
			cp $IMAGES_FINAL_DIR/$FILENAMEUPGRADE $STAGINGAREA/nanobsdupdates 2>/dev/null
2020

    
2021
			if [ -f $STAGINGAREA/nanobsd/$FILENAMEFULL ]; then
2022
				md5 $STAGINGAREA/nanobsd/$FILENAMEFULL > $STAGINGAREA/nanobsd/$FILENAMEFULL.md5 2>/dev/null
2023
				sha256 $STAGINGAREA/nanobsd/$FILENAMEFULL > $STAGINGAREA/nanobsd/$FILENAMEFULL.sha256 2>/dev/null
2024
			fi
2025
			if [ -f $STAGINGAREA/nanobsdupdates/$FILENAMEUPGRADE ]; then
2026
				md5 $STAGINGAREA/nanobsdupdates/$FILENAMEUPGRADE > $STAGINGAREA/nanobsdupdates/$FILENAMEUPGRADE.md5 2>/dev/null
2027
				sha256 $STAGINGAREA/nanobsdupdates/$FILENAMEUPGRADE > $STAGINGAREA/nanobsdupdates/$FILENAMEUPGRADE.sha256 2>/dev/null
2028
			fi
2029

    
2030
			# Copy NanoBSD auto update:
2031
			if [ -f $STAGINGAREA/nanobsdupdates/$FILENAMEUPGRADE ]; then
2032
				cp $STAGINGAREA/nanobsdupdates/$FILENAMEUPGRADE $STAGINGAREA/latest-${NANOTYPE}-$FILESIZE.img.gz 2>/dev/null
2033
				sha256 $STAGINGAREA/latest-${NANOTYPE}-$FILESIZE.img.gz > $STAGINGAREA/latest-${NANOTYPE}-$FILESIZE.img.gz.sha256 2>/dev/null
2034
				# NOTE: Updates need a file with output similar to date output
2035
				# Use the file generated at start of snapshots_dobuilds() to be consistent on times
2036
				cp $BUILTDATESTRINGFILE $STAGINGAREA/version-${NANOTYPE}-$FILESIZE
2037
			fi
2038
		done
2039
	done
2040
}
2041

    
2042
snapshots_copy_to_staging_iso_updates() {
2043
	# Copy ISOs
2044
	md5 ${ISOPATH}.gz > ${ISOPATH}.md5
2045
	sha256 ${ISOPATH}.gz > ${ISOPATH}.sha256
2046
	cp ${ISOPATH}* $STAGINGAREA/ 2>/dev/null
2047

    
2048
	# Copy memstick items
2049
	md5 ${MEMSTICKPATH}.gz > ${MEMSTICKPATH}.md5
2050
	sha256 ${MEMSTICKPATH}.gz > ${MEMSTICKPATH}.sha256
2051
	cp ${MEMSTICKPATH}* $STAGINGAREA/ 2>/dev/null
2052

    
2053
	md5 ${MEMSTICKSERIALPATH}.gz > ${MEMSTICKSERIALPATH}.md5
2054
	sha256 ${MEMSTICKSERIALPATH}.gz > ${MEMSTICKSERIALPATH}.sha256
2055
	cp ${MEMSTICKSERIALPATH}* $STAGINGAREA/ 2>/dev/null
2056

    
2057
	if [ "${TARGET}" = "amd64" ]; then
2058
		md5 ${MEMSTICKADIPATH}.gz > ${MEMSTICKADIPATH}.md5
2059
		sha256 ${MEMSTICKADIPATH}.gz > ${MEMSTICKADIPATH}.sha256
2060
		cp ${MEMSTICKADIPATH}* $STAGINGAREA/ 2>/dev/null
2061
	fi
2062

    
2063
	md5 ${UPDATES_TARBALL_FILENAME} > ${UPDATES_TARBALL_FILENAME}.md5
2064
	sha256 ${UPDATES_TARBALL_FILENAME} > ${UPDATES_TARBALL_FILENAME}.sha256
2065
	cp ${UPDATES_TARBALL_FILENAME}* $STAGINGAREA/ 2>/dev/null
2066
	# NOTE: Updates need a file with output similar to date output
2067
	# Use the file generated at start of snapshots_dobuilds() to be consistent on times
2068
	if [ -z "${_IS_RELEASE}" ]; then
2069
		cp $BUILTDATESTRINGFILE $STAGINGAREA/version 2>/dev/null
2070
	fi
2071
}
2072

    
2073
snapshots_scp_files() {
2074
	if [ -z "${RSYNC_COPY_ARGUMENTS}" ]; then
2075
		RSYNC_COPY_ARGUMENTS="-ave ssh --timeout=60 --bwlimit=${RSYNCKBYTELIMIT}" #--bwlimit=50
2076
	fi
2077

    
2078
	snapshots_update_status ">>> Copying core pkg repo to ${PKG_RSYNC_HOSTNAME}"
2079
	# Add ./ before last directory, it's rsync trick to make it chdir to parent directory before send
2080
	pkg_repo_rsync $(echo "${CORE_PKG_PATH}" | sed -E 's,/$,,; s,/([^/]*)$,/./\1,')
2081
	snapshots_update_status ">>> Finished copying core pkg repo"
2082

    
2083
	snapshots_update_status ">>> Copying files to ${RSYNCIP}"
2084

    
2085
	# Ensure directory(s) are available
2086
	ssh ${RSYNCUSER}@${RSYNCIP} "mkdir -p ${RSYNCPATH}/livecd_installer"
2087
	ssh ${RSYNCUSER}@${RSYNCIP} "mkdir -p ${RSYNCPATH}/updates"
2088
	ssh ${RSYNCUSER}@${RSYNCIP} "mkdir -p ${RSYNCPATH}/nanobsd"
2089
	if [ -d $STAGINGAREA/virtualization ]; then
2090
		ssh ${RSYNCUSER}@${RSYNCIP} "mkdir -p ${RSYNCPATH}/virtualization"
2091
	fi
2092
	ssh ${RSYNCUSER}@${RSYNCIP} "mkdir -p ${RSYNCPATH}/.updaters"
2093
	# ensure permissions are correct for r+w
2094
	ssh ${RSYNCUSER}@${RSYNCIP} "chmod -R ug+rw ${RSYNCPATH}/."
2095
	rsync $RSYNC_COPY_ARGUMENTS $STAGINGAREA/${PRODUCT_NAME}-*iso* \
2096
		${RSYNCUSER}@${RSYNCIP}:${RSYNCPATH}/livecd_installer/
2097
	rsync $RSYNC_COPY_ARGUMENTS $STAGINGAREA/${PRODUCT_NAME}-memstick* \
2098
		${RSYNCUSER}@${RSYNCIP}:${RSYNCPATH}/livecd_installer/
2099
	rsync $RSYNC_COPY_ARGUMENTS $STAGINGAREA/${PRODUCT_NAME}-*Update* \
2100
		${RSYNCUSER}@${RSYNCIP}:${RSYNCPATH}/updates/
2101
	rsync $RSYNC_COPY_ARGUMENTS $STAGINGAREA/nanobsd/* \
2102
		${RSYNCUSER}@${RSYNCIP}:${RSYNCPATH}/nanobsd/
2103
	rsync $RSYNC_COPY_ARGUMENTS $STAGINGAREA/nanobsdupdates/* \
2104
		${RSYNCUSER}@${RSYNCIP}:${RSYNCPATH}/updates/
2105
	if [ -d $STAGINGAREA/virtualization ]; then
2106
		rsync $RSYNC_COPY_ARGUMENTS $STAGINGAREA/virtualization/* \
2107
			${RSYNCUSER}@${RSYNCIP}:${RSYNCPATH}/virtualization/
2108
	fi
2109

    
2110
	# Rather than copy these twice, use ln to link to the latest one.
2111

    
2112
	ssh ${RSYNCUSER}@${RSYNCIP} "rm -f ${RSYNCPATH}/.updaters/latest.tgz"
2113
	ssh ${RSYNCUSER}@${RSYNCIP} "rm -f ${RSYNCPATH}/.updaters/latest.tgz.sha256"
2114

    
2115
	LATESTFILENAME="`ls $UPDATESDIR/*.tgz | grep Full | grep -v md5 | grep -v sha256 | tail -n1`"
2116
	LATESTFILENAME=`basename ${LATESTFILENAME}`
2117
	ssh ${RSYNCUSER}@${RSYNCIP} "ln -s ${RSYNCPATH}/updates/${LATESTFILENAME} \
2118
		${RSYNCPATH}/.updaters/latest.tgz"
2119
	ssh ${RSYNCUSER}@${RSYNCIP} "ln -s ${RSYNCPATH}/updates/${LATESTFILENAME}.sha256 \
2120
		${RSYNCPATH}/.updaters/latest.tgz.sha256"
2121

    
2122
	for i in ${FLASH_SIZE}
2123
	do
2124
		ssh ${RSYNCUSER}@${RSYNCIP} "rm -f ${RSYNCPATH}/.updaters/latest-nanobsd-${i}.img.gz"
2125
		ssh ${RSYNCUSER}@${RSYNCIP} "rm -f ${RSYNCPATH}/.updaters/latest-nanobsd-${i}.img.gz.sha256"
2126
		ssh ${RSYNCUSER}@${RSYNCIP} "rm -f ${RSYNCPATH}/.updaters/latest-nanobsd-vga-${i}.img.gz"
2127
		ssh ${RSYNCUSER}@${RSYNCIP} "rm -f ${RSYNCPATH}/.updaters/latest-nanobsd-vga-${i}.img.gz.sha256"
2128

    
2129
		FILENAMEUPGRADE="${PRODUCT_NAME}-${PRODUCT_VERSION}-${i}-${TARGET}-nanobsd-upgrade${TIMESTAMP_SUFFIX}.img.gz"
2130
		ssh ${RSYNCUSER}@${RSYNCIP} "ln -s ${RSYNCPATH}/updates/${FILENAMEUPGRADE} \
2131
			${RSYNCPATH}/.updaters/latest-nanobsd-${i}.img.gz"
2132
		ssh ${RSYNCUSER}@${RSYNCIP} "ln -s ${RSYNCPATH}/updates/${FILENAMEUPGRADE}.sha256 \
2133
			${RSYNCPATH}/.updaters/latest-nanobsd-${i}.img.gz.sha256"
2134

    
2135
		FILENAMEUPGRADE="${PRODUCT_NAME}-${PRODUCT_VERSION}-${i}-${TARGET}-nanobsd-vga-upgrade${TIMESTAMP_SUFFIX}.img.gz"
2136
		ssh ${RSYNCUSER}@${RSYNCIP} "ln -s ${RSYNCPATH}/updates/${FILENAMEUPGRADE} \
2137
			${RSYNCPATH}/.updaters/latest-nanobsd-vga-${i}.img.gz"
2138
		ssh ${RSYNCUSER}@${RSYNCIP} "ln -s ${RSYNCPATH}/updates/${FILENAMEUPGRADE}.sha256 \
2139
			${RSYNCPATH}/.updaters/latest-nanobsd-vga-${i}.img.gz.sha256"
2140
	done
2141

    
2142
	rsync $RSYNC_COPY_ARGUMENTS $STAGINGAREA/version* \
2143
		${RSYNCUSER}@${RSYNCIP}:${RSYNCPATH}/.updaters
2144
	snapshots_update_status ">>> Finished copying files."
2145
}
(2-2/3)