Index: user/gjb/thermite-v2/thermite.sh =================================================================== --- user/gjb/thermite-v2/thermite.sh (nonexistent) +++ user/gjb/thermite-v2/thermite.sh (revision 295686) @@ -0,0 +1,554 @@ +#!/bin/sh +#- +# Copyright (c) 2013-2015 The FreeBSD Foundation +# Copyright (c) 2012, 2013 Glen Barber +# All rights reserved. +# +# Portions of this software were developed by Glen Barber +# under sponsorship from the FreeBSD Foundation. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# Thermite is a pyrotechnic composition of shell script and zfs. +# When executed, it generates a significant amount of heat. +# Wrapper script for release.sh to automate mass release builds. +# +# $FreeBSD$ +# + +usage() { + echo "$(basename ${0}) -c /path/to/configuration/file" + exit 1 +} + +info() { + out="${@}" + printf "$(date +%Y%m%d-%H:%M:%S)\tINFO:\t${out}\n" >/dev/stdout + unset out +} + +verbose() { + if [ -z ${debug} ] || [ ${debug} -eq 0 ]; then + return 0 + fi + out="${@}" + printf "$(date +%Y%m%d-%H:%M:%S)\tDEBUG:\t${out}\n" >/dev/stdout + unset out +} + +runcmd() { + verbose "${rev} ${arch} ${kernel} ${type}" + eval "$@" +} + +loop_revs() { + verbose "loop_revs() start" + for rev in ${revs}; do + verbose "loop_revs() arguments: $@" + eval runcmd "$@" + done + unset rev + verbose "loop_revs() stop" +} + +loop_archs() { + verbose "loop_archs() start" + for arch in ${archs}; do + verbose "loop_archs() arguments: $@" + eval runcmd "$@" + done + unset arch + verbose "loop_archs() stop" +} + +loop_kernels() { + verbose "loop_kernels() start" + for kernel in ${kernels}; do + verbose "loop_kernels() arguments: $@" + eval runcmd "$@" + done + unset kernel + verbose "loop_kernel() stop" +} + +loop_types() { + verbose "loop_types() start" + for type in ${types}; do + verbose "loop_types() arguments: $@" + eval runcmd "$@" + done + unset type + verbose "loop_types() stop" +} + +runall() { + verbose "runall() start" + verbose "runall() arguments: $@" + eval loop_revs loop_archs loop_kernels loop_types "$@" + verbose "runall() stop" +} + +check_use_zfs() { + if [ -z ${use_zfs} ]; then + return 1 + fi + if [ ! -c /dev/zfs ]; then + return 1 + fi + return 0 +} + +truncate_logs() { + source_config || return 0 + echo > ${logdir}/${rev}-${arch}-${kernel}-${type}.log + return 0 +} + +source_config() { + local configfile + configfile="${scriptdir}/${rev}-${arch}-${kernel}-${type}.conf" + if [ ! -e "${configfile}" ]; then + return 1 + fi + . "${configfile}" + return 0 +} + +zfs_mount_tree() { + source_config || return 0 + _tree=${1} + [ -z ${_tree} ] && return 0 + seed_src= + case ${_tree} in + src) + seed_src=1 + ;; + doc) + [ ! -z ${NODOC} ] && return 0 + ;; + ports) + [ ! -z ${NOPORTS} ] && return 0 + ;; + *) + info "Unknown source tree type: ${_tree}" + return 0 + ;; + esac + _clone="${zfs_parent}/${rev}-${_tree}-${type}" + _mount="/${zfs_mount}/${rev}-${arch}-${kernel}-${type}" + _target="${zfs_parent}/${rev}-${arch}-${kernel}-${type}-${_tree}" + info "Cloning ${_clone}@clone to ${_target}" + zfs clone -p -o mountpoint=${_mount}/usr/${_tree} \ + ${_clone}@clone ${_target} + if [ ! -z ${seed_src} ]; then + # Only create chroot seeds for x86. + if [ "${arch}" = "amd64" ] || [ "${arch}" = "i386" ]; then + _seedmount=${chroots}/${rev}/${arch}/${type} + _seedtarget="${zfs_parent}/${rev}-${arch}-${type}-chroot" + zfs clone -p -o mountpoint=${_seedmount} \ + ${_clone}@clone ${_seedtarget} + fi + fi + unset _clone _mount _target _tree _seedmount _seedtarget +} + +zfs_create_tree() { + source_config || return 0 + _tree=${1} + [ -z ${_tree} ] && return 0 + [ ! -z $(eval echo \${zfs_${_tree}_seed_${rev}_${type}}) ] && return 0 + case ${_tree} in + src) + _svnsrc="${SVNROOT}/${SRCBRANCH}" + ;; + doc) + [ ! -z ${NODOC} ] && return 0 + _svnsrc="${SVNROOT}/${DOCBRANCH}" + ;; + ports) + [ ! -z ${NOPORTS} ] && return 0 + _svnsrc="${SVNROOT}/${PORTBRANCH}" + ;; + *) + info "Unknown source tree type: ${_tree}" + return 0 + ;; + esac + _clone="${zfs_parent}/${rev}-${_tree}-${type}" + _mount="/${zfs_mount}/${rev}-${_tree}-${type}" + info "Creating ${_clone}" + zfs create -o atime=off -o mountpoint=${_mount} ${_clone} + info "Source checkout ${_svnsrc} to ${_mount}" + svn co -q ${_svnsrc} ${_mount} + info "Creating ZFS snapshot ${_clone}@clone" + zfs snapshot ${_clone}@clone + eval zfs_${_tree}_seed_${rev}_${type}=1 + unset _clone _mount _tree _svnsrc +} + +zfs_bootstrap() { + [ -z ${use_zfs} ] && return 0 + runall zfs_create_tree src + runall zfs_create_tree ports + runall zfs_create_tree doc + runall zfs_mount_tree src + runall zfs_mount_tree ports + runall zfs_mount_tree doc + zfs_bootstrap_done=1 +} + +prebuild_setup() { + info "Creating ${logdir}" + mkdir -p ${logdir} + info "Creating ${srcdir}" + mkdir -p ${srcdir} + info "Creating ${chroots}" + mkdir -p ${chroots} + info "Checking out src/release to ${srcdir}" + svn co -q --force svn://svn.freebsd.org/base/${releasesrc}/release \ + ${srcdir} + info "Reverting any changes to ${srcdir}" + svn revert -R ${srcdir} +} + +# Email log output when a stage has completed +send_logmail() { + [ -z "${emailgoesto}" ] && return 0 + [ -z "${emailsentfrom}" ] && return 0 + local _body + local _subject + _subject="${2}" + _body="$(tail -n 50 ${1})" + + printf "From: ${emailsentfrom}\nTo: ${emailgoesto}\nSubject: ${_subject}\n\n${_body}\n\n" \ + | /usr/sbin/sendmail -oi -f ${emailsentfrom} ${emailgoesto} + return 0 +} + +# Stage builds for ftp propagation. +ftp_stage() { + _build="${rev}-${arch}-${kernel}-${type}" + _conf="${scriptdir}/${_build}.conf" + source_config || return 0 + [ -z "${EVERYTHINGISFINE}" ] && return 0 + + load_stage_env + info "Staging for ftp: ${_build}" + [ ! -z "${EMBEDDEDBUILD}" ] && export EMBEDDEDBUILD + [ ! -z "${BOARDNAME}" ] && export BOARDNAME + [ ! -z "${BUILDSVNREV}" ] && export SVNREVISION=${BUILDSVNREV} + [ ! -z "${BUILDDATE}" ] && export BUILDDATE + [ -z "${SVNREVISION}" -a -e "${scriptdir}/svnrev_src" ] && \ + export SVNREVISION="$(cat ${scriptdir}/svnrev_src)" + [ -z "${BUILDDATE}" -a -e "${scriptdir}/builddate" ] && \ + export BUILDDATE="$(cat ${scriptdir}/builddate)" + chroot ${CHROOTDIR} make -C /usr/src/release \ + -f Makefile.mirrors \ + TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ + KERNCONF=${KERNEL} WITH_VMIMAGES=${WITH_VMIMAGES} \ + WITH_DVD=${WITH_DVD} \ + ftp-stage >> ${logdir}/${_build}.log 2>&1 + + if [ -z "${ftpdir}" ]; then + info "FTP directory (ftpdir) not set." + info "Refusing to rsync(1) to the stage area." + return 0 + fi + + case ${type} in + release) + _type="releases" + ;; + *) + _type="snapshots" + ;; + esac + + mkdir -p "${ftpdir}/${_type}" + rsync -avH ${CHROOTDIR}/R/ftp-stage/${_type}/* \ + ${ftpdir}/${_type}/ >> ${logdir}/${_build}.log 2>&1 + unset BOARDNAME BUILDDATE EMBEDDEDBUILD SVNREVISION WITH_VMIMAGES + return 0 +} + +# Run the release builds. +build_release() { + _build="${rev}-${arch}-${kernel}-${type}" + _conf="${scriptdir}/${_build}.conf" + source_config || return 0 + info "Building release: ${_build}" + set >> ${logdir}/${_build}.log + env -i __BUILDCONFDIR="${__BUILDCONFDIR}" \ + /bin/sh ${srcdir}/release.sh -c ${_conf} \ + >> ${logdir}/${_build}.log 2>&1 + + ftp_stage + ls -1 ${CHROOTDIR}/R/* >> ${logdir}/${_build}.log + send_logmail ${logdir}/${_build}.log ${_build} + unset _build _conf +} + +# Upload AWS EC2 AMI images. +upload_ec2_ami() { + _build="${rev}-${arch}-${kernel}-${type}" + _conf="${scriptdir}/${_build}.conf" + source_config || return 0 + case ${arch} in + amd64) + ;; + *) + return 0 + ;; + esac + info "Uploading EC2 AMI image for build: ${_build}" + if [ ! -e "${CHROOTDIR}/${AWSKEYFILE}" ]; then + cp -p ${AWSKEYFILE} ${CHROOTDIR}/${AWSKEYFILE} + if [ $? -ne 0 ]; then + info "Amazon EC2 key file not found." + return 0 + fi + fi + if [ -z "${AWSREGION}" -o -z "${AWSBUCKET}" -o -z "${AWSKEYFILE}" ]; then + return 0 + fi + mount -t devfs devfs ${CHROOTDIR}/dev + chroot ${CHROOTDIR} make -C /usr/src/release \ + AWSREGION=${AWSREGION} \ + AWSBUCKET=${AWSBUCKET} \ + AWSKEYFILE=${AWSKEYFILE} \ + EC2PUBLIC=${EC2PUBLIC} ec2ami \ + >> ${logdir}/${_build}.ec2.log 2>&1 + unset _build _conf AWSREGION AWSBUCKET AWSKEYFILE EC2PUBLIC + umount ${CHROOTDIR}/dev + return 0 +} # upload_ec2_ami() + +# Upload Microsoft Azure virtual machine images. +upload_azure_image() { + _build="${rev}-${arch}-${kernel}-${type}" + _conf="${scriptdir}/${_build}.conf" + source_config || return 0 + case ${arch} in + amd64) + ;; + *) + return 0 + ;; + esac + if [ -z "${AZURE_UPLOAD_CONF}" ]; then + return 0 + fi + info "Uploading Azure virutal machine image for build: ${_build}" + if [ ! -e "${CHROOTDIR}/${AZURE_UPLOAD_CONF}" ]; then + cp -p ${AZURE_UPLOAD_CONF} ${CHROOTDIR}/${AZURE_UPLOAD_CONF} + if [ $? -ne 0 ]; then + info "Azure key file not found." + return 0 + fi + fi + mount -t devfs devfs ${CHROOTDIR}/dev + chroot ${CHROOTDIR} make -C /usr/src/release \ + AZURE_UPLOAD_CONF=${AZURE_UPLOAD_CONF} \ + azure-upload \ + >> ${logdir}/${_build}.azure.log 2>&1 + unset _build _conf AZURE_UPLOAD_CONF + umount ${CHROOTDIR}/dev + return 0 +} # upload_azure_image() + +# Upload Vagrant virtual machine images. +upload_vagrant_image() { + _build="${rev}-${arch}-${kernel}-${type}" + _conf="${scriptdir}/${_build}.conf" + source_config || return 0 + case ${arch} in + amd64) + ;; + *) + return 0 + ;; + esac + if [ -z "${VAGRANT_UPLOAD_CONF}" ]; then + return 0 + fi + info "Uploading Vagrant virutal machine image for build: ${_build}" + if [ ! -e "${CHROOTDIR}/${VAGRANT_UPLOAD_CONF}" ]; then + cp -p ${VAGRANT_UPLOAD_CONF} \ + ${CHROOTDIR}/${VAGRANT_UPLOAD_CONF} + if [ $? -ne 0 ]; then + info "Vagrant key file not found." + return 0 + fi + fi + mount -t devfs devfs ${CHROOTDIR}/dev + chroot ${CHROOTDIR} make -C /usr/src/release \ + VAGRANT_UPLOAD_CONF=${VAGRANT_UPLOAD_CONF} \ + vagrant-upload \ + >> ${logdir}/${_build}.vagrant.log 2>&1 + unset _build _conf VAGRANT_UPLOAD_CONF + umount ${CHROOTDIR}/dev + return 0 +} # upload_vagrant_image() + +# Upload Google Compute Engine virtual machine images. +upload_gce_image() { + _build="${rev}-${arch}-${kernel}-${type}" + _conf="${scriptdir}/${_build}.conf" + source_config || return 0 + case ${arch} in + amd64) + ;; + *) + return 0 + ;; + esac + if [ -z "${GCE_LOGIN_SKIP}" -o -z "${GCE_BUCKET}" ]; then + return 0 + fi + info "Uploading GCE virutal machine image for build: ${_build}" + if [ ! -d "${CHROOTDIR}/${GCE_CONFIG_DIR}" ]; then + if [ ! -e "${GCE_CONFIG_PKG}" ]; then + echo "Cannot locate config tarball." + return 0 + fi + mkdir -p ${CHROOTDIR}/${GCE_CONFIG_LOC} + tar -xzf ${GCE_CONFIG_PKG} -C ${CHROOTDIR}/${GCE_CONFIG_LOC} + fi + mount -t devfs devfs ${CHROOTDIR}/dev + chroot ${CHROOTDIR} make -C /usr/src/release \ + GCE_BUCKET=${GCE_BUCKET} \ + GCE_LOGIN_SKIP=1 \ + gce-upload \ + >> ${logdir}/${_build}.gce 2>&1 + unset _build _conf GCE_BUCKET GCE_CONFIG_DIR GCE_CONFIG_PKG + unset GCE_CONFIG_LOC GCE_LOGIN_SKIP + umount ${CHROOTDIR}/dev + return 0 +} # upload_gce_image() + +# Install amd64/i386 "seed" chroots for all branches being built. +install_chroots() { + source_config || return 0 + if [ ${rev} -le 8 ]; then + info "This script does not support rev=${rev}" + return 0 + fi + case ${arch} in + i386) + _chrootarch="i386" + ;; + *) + _chrootarch="amd64" + ;; + esac + _build="${rev}-${arch}-${kernel}-${type}" + _dest="${__WRKDIR_PREFIX}/${_build}" + _srcdir="${chroots}/${rev}/${_chrootarch}/${type}" + _objdir="${chroots}/${rev}-obj/${_chrootarch}/${type}" + info "Creating ${_dest}" + mkdir -p "${_dest}" + info "Installing ${_dest}" + env MAKEOBJDIRPREFIX=${_objdir} \ + make -C ${_srcdir} \ + __MAKE_CONF=/dev/null SRCCONF=/dev/null \ + TARGET=${_chrootarch} TARGET_ARCH=${_chrootarch} \ + DESTDIR=${_dest} \ + installworld distribution >> \ + ${logdir}/${_build}.log 2>&1 + unset _build _dest _objdir _srcdir +} + +# Build amd64/i386 "seed" chroots for all branches being built. +build_chroots() { + source_config || return 0 + if [ ${rev} -le 9 ]; then + info "This script does not support rev ${rev}" + return 0 + fi + case ${arch} in + i386) + _chrootarch="i386" + ;; + *) + _chrootarch="amd64" + ;; + esac + [ ! -z $(eval echo \${chroot_${_chrootarch}_build_${rev}_${type}}) ] && return 0 + _build="${rev}-${_chrootarch}-${type}" + _srcdir="${chroots}/${rev}/${_chrootarch}/${type}" + _objdir="${chroots}/${rev}-obj/${_chrootarch}/${type}" + mkdir -p "${_srcdir}" + # Source the build configuration file to get + # the SRCBRANCH to use + if [ -z ${zfs_bootstrap_done} ]; then + # Skip svn checkout, the trees are there. + info "SVN checkout ${SRCBRANCH} for ${_chrootarch} ${type}" + svn co -q ${SVNROOT}/${SRCBRANCH} \ + ${_srcdir} \ + >> ${logdir}/${_build}.log 2>&1 + fi + info "Building ${_srcdir} world" + env MAKEOBJDIRPREFIX=${_objdir} \ + make -C ${_srcdir} ${WORLD_FLAGS} \ + __MAKE_CONF=/dev/null SRCCONF=/dev/null \ + TARGET=${_chrootarch} TARGET_ARCH=${_chrootarch} \ + buildworld >> \ + ${logdir}/${_build}.log 2>&1 + eval chroot_${_chrootarch}_build_${rev}_${type}=1 + unset _build _dest _objdir _srcdir +} + +main() { + releasesrc="head" + export __BUILDCONFDIR="$(dirname $(realpath ${0}))" + + while getopts "c:d" opt; do + case ${opt} in + c) + CONF=${OPTARG} + [ -e ${CONF} ] && . $(realpath ${CONF}) + ;; + d) + debug=1 + ;; + \?) + usage + ;; + esac + done + shift $(($OPTIND - 1)) + [ -z ${CONF} ] && usage + zfs_bootstrap_done= + prebuild_setup + runall truncate_logs + zfs_bootstrap + runall build_chroots + runall install_chroots + runall build_release + runall upload_ec2_ami + runall upload_azure_image + runall upload_gce_image + runall upload_vagrant_image +} + +main "$@" + Property changes on: user/gjb/thermite-v2/thermite.sh ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: user/gjb/thermite-v2/master.conf =================================================================== --- user/gjb/thermite-v2/master.conf (nonexistent) +++ user/gjb/thermite-v2/master.conf (revision 295686) @@ -0,0 +1,59 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +# Thermite is a pyrotechnic composition of shell script and zfs. +# When executed, it generates a significant amount of heat. +# This is its configuration file. + +use_zfs=1 +emailgoesto= +emailsentfrom= +scriptdir="$(dirname $(realpath ${0}))" +srcdir="${scriptdir}/../release" +logdir="${scriptdir}/../logs" +chroots="${scriptdir}/../chroots" + +releasesrc="head" +heads="11" +stables= + +revs="${heads} ${stables}" +archs="amd64 i386 powerpc powerpc64 sparc64 armv6 aarch64" +types="snap" + +x86_kernels="GENERIC" +armv6_kernels="BEAGLEBONE CUBOX-HUMMINGBOARD GUMSTIX RPI-B RPI2 PANDABOARD WANDBOARD" + +kernels="${x86_kernels} GENERIC64 ${armv6_kernels}" + +ftpdir="/snap/ftp" + +zfs_root="zroot" +zfs_mount="releng" +zfs_parent="${zfs_root}/${zfs_mount}" + +__WRKDIR_PREFIX="/releng" + +BUILDSVNREV="rHEAD" +BUILDDATE="$(date +%Y%m%d)" +SVNROOT="svn://svn.FreeBSD.org/" + +KERNEL="GENERIC" +WORLD_FLAGS="-j $(( $(( $(sysctl -n hw.ncpu) + 1 )) / 2 ))" +KERNEL_FLAGS="-j $(( $(( $(sysctl -n hw.ncpu) + 1 )) / 2 ))" + +CHROOTBUILD_SKIP=1 +SRC_UPDATE_SKIP=1 +PORTS_UPDATE_SKIP=1 +DOC_UPDATE_SKIP=1 + +unset BOARDNAME +unset EMBEDDEDBUILD +unset EMBEDDEDPORTS +unset EMBEDDED_TARGET +unset EMBEDDED_TARGET_ARCH + +## Before uncommenting this, be *really* sure you know what it does. +#export EVERYTHINGISFINE=1 Property changes on: user/gjb/thermite-v2/master.conf ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: user/gjb/thermite-v2/mk-vmimage.sh =================================================================== --- user/gjb/thermite-v2/mk-vmimage.sh (nonexistent) +++ user/gjb/thermite-v2/mk-vmimage.sh (revision 295686) @@ -0,0 +1,246 @@ +#!/bin/sh +#- +# Copyright (c) 2013, 2014 The FreeBSD Foundation +# Copyright (c) 2012, 2013 Glen Barber +# All rights reserved. +# +# Portions of this software were developed by Glen Barber +# under sponsorship from the FreeBSD Foundation. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# Script to create the VM images available on ftp.FreeBSD.org. +# +# $FreeBSD$ +# + +PATH="/bin:/sbin:/usr/bin:/usr/sbin" +export PATH + +usage () { + echo "$(basename ${0}) -c /path/to/release.conf" + exit 1 +} + +check_prereq () { + rc=0 + case ${VM_TARGET_ARCH} in + i386|amd64) + # Ok to create vm image + ;; + *) + rc=1 + ;; + esac + case ${KERNEL} in + GENERIC) + ;; + *) + rc=1 + ;; + esac + + return ${rc} +} + +create_etc() { + chroot ${CHROOTDIR} /usr/bin/newaliases + echo "# Custom /etc/fstab for FreeBSD VM images" \ + > ${CHROOTDIR}/vmimage/mnt/etc/fstab + echo "/dev/gpt/rootfs / ufs rw 2 2" \ + >> ${CHROOTDIR}/vmimage/mnt/etc/fstab + echo "/dev/gpt/swapfs none swap sw 0 0" \ + >> ${CHROOTDIR}/vmimage/mnt/etc/fstab + sync + while ! umount ${CHROOTDIR}/vmimage/mnt; do + sleep 1 + done +} + +create_vmimage_qemu() { + # mkimg(1) supports the formats being created. + [ ! -z "${no_qemu}" ] && return 0 + diskformats="qcow2" + if [ ! -x /usr/local/bin/qemu-img ]; then + echo "qemu-img not found, skipping qcow2 format." + return 0 + fi + + if [ ! -x /usr/bin/mkimg ]; then + # No mkimg(1) here, so use qemu-img for them all. + diskformats="${diskformats} vpc vmdk" + fi + + if [ -e "${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk" ]; then + rm -f "${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk" + fi + mkdir -p ${CHROOTDIR}/vmimage ${CHROOTDIR}/vmimage/mnt + touch ${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk + truncate -s 20G ${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk + mddev=$(mdconfig -a -t vnode -f ${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk) + + gpart create -s gpt /dev/${mddev} + gpart add -t freebsd-boot -a 1m -s 512k -l bootfs /dev/${mddev} + gpart add -t freebsd-swap -a 1m -s 1G -l swapfs /dev/${mddev} + gpart add -t freebsd-ufs -a 1m -l rootfs /dev/${mddev} + gpart bootcode -b ${CHROOTDIR}/boot/pmbr \ + -p ${CHROOTDIR}/boot/gptboot -i 1 /dev/${mddev} + newfs -j -L rootfs /dev/${mddev}p3 + mount /dev/${mddev}p3 ${CHROOTDIR}/vmimage/mnt + + # Errors here are ok, 'set -e' is re-enabled below again. + set +e + mount -t devfs devfs ${CHROOTDIR}/dev + chroot ${CHROOTDIR} make -s -C /usr/src DESTDIR=/vmimage/mnt \ + installworld installkernel distribution + set -e + while ! umount ${CHROOTDIR}/dev; do + sleep 1 + done + create_etc + + for f in ${diskformats}; do + _f=${f} + case ${_f} in + vpc) + _f=vhd + ;; + *) + ;; + esac + /usr/local/bin/qemu-img convert \ + -O ${f} ${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk \ + ${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.${_f} + xz ${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.${_f} + done + mdconfig -d -u ${mddev} + rm ${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk + return 0 +} + +create_vmimage_mkimg() { + no_qemu= + diskformats="vmdk vhdf raw" + + if [ ! -x /usr/bin/mkimg ]; then + return 0 + fi + + mkimg_version=$(/usr/bin/mkimg --version 2>/dev/null | awk '{print $2}') + + if [ ! -z "${mkimg_version}" ]; then + diskformats="${diskformats} qcow2" + no_qemu=1 + fi + + if [ ! -d ${CHROOTDIR}/R/ftp ]; then + echo "Error: Cannot find the ftp/*.txz files." + exit 1 + fi + + dists="base kernel games" + if [ -e ${CHROOTDIR}/R/ftp/lib32.txz ]; then + dists="${dists} lib32" + fi + + if [ -e "${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk" ]; then + rm -f "${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk" + fi + mkdir -p ${CHROOTDIR}/vmimage ${CHROOTDIR}/vmimage/mnt + touch ${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk + truncate -s 20G ${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk + mddev=$(mdconfig -a -t vnode -f ${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk) + + newfs -j -L rootfs /dev/${mddev} + mount /dev/${mddev} ${CHROOTDIR}/vmimage/mnt + + for d in ${dists}; do + tar -xf ${CHROOTDIR}/R/ftp/${d}.txz -C ${CHROOTDIR}/vmimage/mnt + done + create_etc + mdconfig -d -u ${mddev} + + for f in ${diskformats}; do + case ${f} in + vhdf) + _f=vhd + ;; + *) + _f=${f} + ;; + esac + /usr/bin/mkimg -f ${f} \ + -s gpt -b ${CHROOTDIR}/boot/pmbr \ + -p freebsd-boot/bootfs:=${CHROOTDIR}/boot/gptboot \ + -p freebsd-swap/swapfs::1G \ + -p freebsd-ufs/rootfs:=${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk \ + -o ${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.${_f} + xz ${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.${_f} + done + mdconfig -d -u ${mddev} + rm -f "${CHROOTDIR}/vmimage/${VM_IMAGE_NAME}.rawdisk" + return 0 +} + +main() { + while getopts c: opt; do + case ${opt} in + c) + VM_CONFIG="${OPTARG}" + ;; + \?) + usage + ;; + esac + done + + # Force use of configuration file + if [ "X${VM_CONFIG}" = "X" ]; then + usage + fi + if [ ! -e "${VM_CONFIG}" ]; then + echo "ERROR: Configuration file not found" + exit 1 + fi + . ${VM_CONFIG} + + VM_TARGET_ARCH=$(echo ${__CONFIG_NAME} | cut -f 2 -d -) + + # Use the build environment to get the branch revision (i.e., 10.0) + # and branch (i.e., -CURRENT, -STABLE) for the vm image name. + VM_IMAGE_REVISION=$(make -C ${CHROOTDIR}/usr/src/release -V REVISION) + VM_IMAGE_BRANCH=$(make -C ${CHROOTDIR}/usr/src/release -V BRANCH) + VM_IMAGE_NAME="${VM_IMAGE_REVISION}-${VM_IMAGE_BRANCH}" + VM_IMAGE_NAME="$(uname -s)-${VM_IMAGE_NAME}-${VM_TARGET_ARCH}" + + check_prereq || exit 0 + + create_vmimage_mkimg + create_vmimage_qemu + + cd ${CHROOTDIR}/vmimage + sha256 FreeBSD*.xz > CHECKSUM.SHA256 + md5 FreeBSD*.xz > CHECKSUM.MD5 + +} + +main "$@" Property changes on: user/gjb/thermite-v2/mk-vmimage.sh ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: user/gjb/thermite-v2/11-amd64-GENERIC-snap.conf =================================================================== --- user/gjb/thermite-v2/11-amd64-GENERIC-snap.conf (nonexistent) +++ user/gjb/thermite-v2/11-amd64-GENERIC-snap.conf (revision 295686) @@ -0,0 +1,27 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +# Sample configuration file for building a head/ snapshot using +# thermite.sh. + +CHROOTDIR="/scratch/11-amd64-GENERIC-snap" +CHROOTBUILD_SKIP=1 +SVNROOT="svn://svn.FreeBSD.org/" +SRCBRANCH="base/head@${_SVNREV}" +DOCBRANCH="doc/head@rHEAD" +PORTBRANCH="ports/head@rHEAD" +WORLD_FLAGS="-j10" +KERNEL_FLAGS="-j8" +KERNEL="GENERIC" +TARGET="amd64" +TARGET_ARCH="amd64" +NODOC=1 +NOPORTS=1 + +# svn revision to build. Do not include leading 'r'. +_SVNREV="262657" +# Date the build was started. +DATE="20140301" + Property changes on: user/gjb/thermite-v2/11-amd64-GENERIC-snap.conf ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property