#!/bin/bash ## ## makedistro.sh ## ## Made by David Farning ## Login ## ## Started on Sat Jan 9 03:45:30 2010 David Farning ## Last update Wed Feb 10 12:36:31 2010 David Farning ## set -eu function usage() { echo "The script needs 2 parameters: * Action to do: debootstrap|iso|squash|all * Architecture to build: i386|amd64 Usage: $0 debootstrap|iso|squash|source|all|torrent i386|amd64" } function failure() { unmount_directories echo "$@" exit 2 } function unmount_directory() { DIR_TO_UNMOUNT="$1" if mountpoint -q ${DIR_TO_UNMOUNT}; then #FIXME should be able to detect in tmp is mounted echo "Unmounting directory ${DIR_TO_UNMOUNT}..." umount -l ${DIR_TO_UNMOUNT} || failure "Cannot unmount directory ${DIR_TO_UNMOUNT}, error=$?" fi } function unmount_directories() { # check for runs of the script if [ -d ${CHROOT} ] ; then echo "Cleaning up old build tree" for MOUNT in /tmp /lib/modules/*/volatile /proc /sys /dev/pts /var/run ; do unmount_directory ${CHROOT}${MOUNT} done fi } function replace_ssd() { # replace the start-stop-daemon, to make /etc/init.d/ scripts do nothing for a while mv ${CHROOT}/sbin/start-stop-daemon ${CHROOT}/sbin/start-stop-daemon.REAL cat < "$CHROOT/sbin/start-stop-daemon" #!/bin/sh echo echo "Warning: Fake start-stop-daemon called, doing nothing" EOF chmod 755 ${CHROOT}/sbin/start-stop-daemon } function restore_ssd() { # enable /etc/init.d/ scripts mv ${CHROOT}/sbin/start-stop-daemon.REAL ${CHROOT}/sbin/start-stop-daemon } function prepare_chroot() { export LANG=C export LANGUAGE=C mount -t proc proc ${CHROOT}/proc || failure "Failed to mount ${CHROOT}/proc, error=$?" mount -t sysfs sysfs ${CHROOT}/sys || failure "Failed to mount ${CHROOT}/sys, error=$?" mount -t devpts none ${CHROOT}/dev/pts || failure "Failed to mount ${CHROOT}/dev/pts, error=$?" mount -o bind /var/run ${CHROOT}/var/run #mount -o bind /tmp ${CHROOT}/tmp FIXME do we need temp echo "Copying resolv.conf..." cp -f /etc/resolv.conf ${CHROOT}/etc/resolv.conf || failure "Failed to copy resolv.conf to image directory, error=$?" echo "Creating DBUS uuid" #${CCMD} dbus-uuidgen --ensure echo "done" } function in_chroot() { cp usr-chroot.sh ${CHROOT} ${CCMD} ./usr-chroot.sh #rm ${CHROOT}/usr-chroot.sh } function clean_chroot() { unmount_directories echo "Cleaning up apt" ${CCMD} apt-get clean || failure "Failed to run apt-get clean, error=$?" ${CCMD} apt-get autoclean || failure "Failed to run apt-get autoclean, error=$?" echo "Cleaning up temporary directories..." ${CCMD} rm -rf '/tmp/*' '/tmp/.*' '/var/tmp/*' '/var/tmp/.*' #2>/dev/null ${CCMD} rm -rf /var/lib/dbus/machine-id # 2>/dev/null echo "Restoring hosts..." ${CCMD} rm -f ${CHROOT}/etc/hosts || failure "Failed to hosts, error=$?" echo "Restoring resolv.conf..." ${CCMD} rm -f ${CHROOT}/etc/resolv.conf || failure "Failed to remove resolv.conf, error=$?" } function prepare_filesystem_directory() { echo "Preparing directory for filesystem" if [ -e ${CHROOT} ]; then rm -rf ${CHROOT} || failure "Failed to remove directory ${CHROOT}" fi mkdir -p ${CHROOT} } function do_debootstrap() { echo "DATE=${DATE} DIST=${DIST} ARCH=${ARCH} CHROOT=${CHROOT}" unmount_directories rm -rf $CHROOT || exit 1 # debootstrab the base system prepare_filesystem_directory debootstrap --arch=${ARCH} lucid ${CHROOT} ${MIRROR} # replace_ssd prepare_chroot in_chroot clean_chroot # restore_ssd } function prepare_image_directory() { echo "Preparing directory for image" if [ -e ${IMAGE} ]; then rm -rf ${IMAGE} || failure "Failed to remove directory ${IMAGE}" fi mkdir -p ${IMAGE} cp -av ${ISOTEMPLATE}/* ${IMAGE}/ } function pack_squashfs() { prepare_image_directory echo "Updating files lists..." ${CCMD} dpkg-query -W --showformat='${Package} ${Version}\n' > ${IMAGE}/casper/filesystem.manifest || failure "Cannot update filesystem.manifest, error=$?" cp ${IMAGE}/casper/filesystem.manifest ${IMAGE}/casper/filesystem.manifest-desktop sed -i '/ubiquity/d' ${IMAGE}/casper/filesystem.manifest-desktop sed -i '/casper/d' ${IMAGE}/casper/filesystem.manifest-desktop echo "Packing SquashFS image..." if [ -e ${IMAGE}/casper/filesystem.squashfs ]; then rm -f ${IMAGE}/casper/filesystem.squashfs || failure "Cannot remove ${IMAGE}/casper/filesystem.squashfs to make room for created squashfs image, error=$?" fi printf $(du -sx --block-size=1 ${CHROOT} | cut -f1) > ${IMAGE}/casper/filesystem.size mksquashfs ${CHROOT} ${IMAGE}/casper/filesystem.squashfs || failure "Failed to create squashfs image to ${IMAGE}/casper/filesystem.squashfs, error=$?" chmod 644 ${IMAGE}/casper/filesystem.squashfs } function pack_iso(){ #update the kernel image in the master dir cp -v ${CHROOT}/boot/initrd.img* ${IMAGE}/casper/initrd cp -v ${CHROOT}/boot/vmlinuz* ${IMAGE}/casper/vmlinuz echo "Updating md5sums..." pushd ${CHROOT} find . -type f -print0 | xargs -0 md5sum | grep -v "\./md5sum.txt" > md5sum.txt popd mkisofs -o ${ISO} \ -b "isolinux/isolinux.bin" -c "isolinux/boot.cat" \ -no-emul-boot -boot-load-size 4 -boot-info-table \ -cache-inodes -r -J -l \ ${IMAGE} RESULT=$? if [ $RESULT -ne 0 ]; then failure "Failed to pack ISO image, error=${RESULT}" fi } function build_vm(){ VM=${DIST}-${ARCH}-${DATE} VBoxManage createvm --name ${VM} --ostype Ubuntu --register VBoxManage modifyvm ${VM} --memory 2048 VBoxManage modifyvm ${VM} --cpus 3 VBoxManage modifyvm ${VM} --vram 14 VBoxManage modifyvm ${VM} --nic1 nat --acpi on VBoxManage storagectl ${VM} --name ${VM}.ide --add ide --controller PIIX4 VBoxManage createhd --filename ${VM}.vdi --size 5000 --remember VBoxManage storageattach ${VM} --type hdd --storagectl ${VM}.ide --port 0 --device 0 --medium ${VM}.vdi VBoxManage storageattach ${VM} --type dvddrive --storagectl ${VM}.ide --port 1 --device 0 --medium ~/usr/output/${VM}.iso VBoxManage modifyvm ${VM} --boot1 dvd --nic1 nat --acpi on VBoxManage startvm ${VM} while true; do sleep 2 if ! VBoxManage list runningvms | grep -qs "^\"${VM}\""; then break fi done VBoxManage modifyvm ${VM} --memory 512 VBoxManage modifyvm ${VM} --cpus 1 VBoxManage storageattach ${VM} --type dvddrive --storagectl ${VM}.ide --port 1 --device 0 --medium none VBoxManage export ${VM} -o ~/usr/output/${VM}.ovf } function upload_files(){ RELEASE=${DIST}-${ARCH}-${DATE} LOGIN=dfarning@sunjammer.sugarlabs.org for TYPE in iso vmdk ovf mf; do FILE=${RELEASE}.${TYPE} chown dfarning:dfarning ~/usr/output/${FILE} chmod 0777 ~/usr/output/${FILE} rsync --compress --verbose --progress ~/usr/output/${FILE} ${LOGIN}:staging/${FILE} done for TYPE in iso vmdk ovf mf; do FILE=${RELEASE}.${TYPE} ssh ${LOGIN} "cp staging/'${FILE}' public_html/'${FILE}'" ssh ${LOGIN} "ln public_html/'${FILE}' public_html/'${DIST}'-'${ARCH}'-current.'${TYPE}'" done } case $1 in debootstrap|squash|iso|vm|upload|all|debug) ACTION=$1 ;; *) usage exit 1 ;; esac case $2 in i386|amd64) ARCH=$2 ;; *) usage exit 1 ;; esac DATE=$(date +"%Y%m%d") export DEBIAN_FRONTEND=noninteractive MIRROR="http://10.0.02:3142/archive.ubuntu.com/ubuntu" DIST="USR" CHROOT=build/${ARCH}-fs IMAGE=build/${ARCH}-image ISOTEMPLATE=templates/iso ISO=output/${DIST}-${ARCH}-${DATE}.iso LOG=logs/${DIST}-${ARCH}-${DATE}.log CCMD="chroot ${CHROOT}" case $ACTION in debootstrap) COLUMNS=500 do_debootstrap 2>&1 3>&1 0>&1 | COLUMNS=500 tee $LOG ;; squash) COLUMNS=500 pack_squashfs 2>&1 3>&1 0>&1 | COLUMNS=500 tee $LOG ;; iso) COLUMNS=500 pack_iso 2>&1 3>&1 0>&1 | COLUMNS=500 tee $LOG ;; vm) COLUMNS=500 build_vm 2>&1 3>&1 0>&1 | COLUMNS=500 tee $LOG ;; upload) COLUMNS=500 upload_files 2>&1 3>&1 0>&1 | COLUMNS=500 tee $LOG ;; all) COLUMNS=500 do_debootstrap 2>&1 3>&1 0>&1 | COLUMNS=500 tee $LOG COLUMNS=500 pack_squashfs 2>&1 3>&1 0>&1 | COLUMNS=500 tee -a $LOG COLUMNS=500 pack_iso 2>&1 3>&1 0>&1 | COLUMNS=500 tee -a $LOG COLUMNS=500 build_vm 2>&1 3>&1 0>&1 | COLUMNS=500 tee -a $LOG COLUMNS=500 upload_files 2>&1 3>&1 0>&1 | COLUMNS=500 tee -a $LOG ;; debug) do_debootstrap pack_squashfs pack_iso #build_vm #upload_files ;; esac