#!/bin/bash #set -x set -e # [ X`whoami` = X'root' ] || { echo "You must be root to run this script."; exit 1; } [ -n "$BINARIES_DIR" ] || { echo "BINARIES_DIR variable should be defined."; exit 1; } ########################### # VARIABLES ########################### STAMP=`date +%Y%m%d%H%M%S` SCRIPT=`readlink -f "$0"` SCRIPTDIR=`dirname "${SCRIPT}"` SOLO=${SCRIPTDIR}/solo SYNC=${SCRIPTDIR}/sync REPO=${SCRIPTDIR}/.. GNUPG=${REPO}/gnupg STAGE=${SCRIPTDIR}/stage RELEASE=precise VERSION=12.04 ORIGISO=$BINARIES_DIR/ubuntu-12.04-server-amd64.iso NEWISONAME=nailgun-ubuntu-${VERSION}-amd64 [ -z ${NEWISODIR} ] && NEWISODIR=/var/tmp MIRROR="http://ru.archive.ubuntu.com/ubuntu" REQDEB=`cat ${REPO}/requirements-deb.txt | grep -v "^\s*$" | grep -v "^\s*#"` BASEDIR=/var/tmp/build_iso ORIG=${BASEDIR}/orig NEW=${BASEDIR}/new EXTRAS=${BASEDIR}/extras KEYRING=${BASEDIR}/keyring INDICES=${BASEDIR}/indices TMPGNUPG=${BASEDIR}/gnupg GPGKEYID=F8AF89DD GPGKEYNAME="Mirantis Product" GPGKEYEMAIL="" GPGKEY="${GPGKEYNAME} ${GPGKEYEMAIL}" GPGPASSWDFILE=${TMPGNUPG}/keyphrase ARCHITECTURES="i386 amd64" SECTIONS="main restricted universe multiverse" [ -z ${BOOTSTRAP_KERNEL_URL} ] && \ BOOTSTRAP_KERNEL_URL='http://mc0n1-srt.srt.mirantis.net/bootstrap-linux.last' [ -z ${BOOTSTRAP_INITRD_URL} ] && \ BOOTSTRAP_INITRD_URL='http://mc0n1-srt.srt.mirantis.net/bootstrap-initrd.gz.last' BOOTSTRAPDIR=${BASEDIR}/bootstrap EGGSDIR=${BASEDIR}/eggs GEMSDIR=${BASEDIR}/gems ########################### # CLEANING ########################### echo "Cleaning ..." if (mount | grep -q ${ORIG}); then echo "Umounting ${ORIG} ..." fusermount -u ${ORIG} fi echo "Removing ${BASEDIR} ..." rm -rf ${BASEDIR} echo "Removing ${ORIG} ..." rm -rf ${ORIG} echo "Removing ${NEW} ..." rm -rf ${NEW} echo "Removing ${INDICES} ..." rm -rf ${INDICES} #echo "Removing ${EXTRAS} ..." #rm -rf ${EXTRAS} echo "Removing ${TMPGNUPG} ..." rm -rf ${TMPGNUPG} echo "Removing ${KEYRING} ..." rm -rf ${KEYRING} ########################### # STAGING ########################### mkdir -p ${ORIG} mkdir -p ${NEW} echo "Mounting original iso image ..." fuseiso ${ORIGISO} ${ORIG} echo "Syncing original iso to new iso ..." rsync -a ${ORIG}/ ${NEW} chmod -R u+w ${NEW} echo "Syncing stage directory to new iso ..." rsync -a ${STAGE}/ ${NEW} ########################### # DOWNLOADING INDICES ########################### echo "Downloading indices ..." mkdir -p ${INDICES} # for s in ${SECTIONS}; do # wget -qO- ${MIRROR}/indices/override.${RELEASE}.${s}.debian-installer > \ # ${INDICES}/override.${RELEASE}.${s}.debian-installer # # wget -qO- ${MIRROR}/indices/override.${RELEASE}.${s} > \ # ${INDICES}/override.${RELEASE}.${s} # # wget -qO- ${MIRROR}/indices/override.${RELEASE}.extra.${s} > \ # ${INDICES}/override.${RELEASE}.extra.${s} # done cp $BINARIES_DIR/ubuntu/precise/indices/* ${INDICES} ########################### # REORGANIZE POOL ########################### echo "Reorganizing pool ..." ( cd ${NEW}/pool find -type f \( -name "*.deb" -o -name "*.udeb" \) | while read debfile; do debbase=`basename ${debfile}` packname=`echo ${debbase} | awk -F_ '{print $1}'` section=`grep "^${packname}\s" ${INDICES}/* | \ grep -v extra | head -1 | awk -F: '{print $1}' | \ awk -F. '{print $3}'` test -z ${section} && section=main mkdir -p ${NEW}/pools/${RELEASE}/${section} mv ${debfile} ${NEW}/pools/${RELEASE}/${section} done ) rm -fr ${NEW}/pool ########################### # DOWNLOADING REQUIRED DEBS ########################### mkdir -p ${EXTRAS}/state touch ${EXTRAS}/state/status mkdir -p ${EXTRAS}/archives mkdir -p ${EXTRAS}/cache mkdir -p ${EXTRAS}/etc/preferences.d mkdir -p ${EXTRAS}/etc/apt.conf.d cat > ${EXTRAS}/etc/sources.list < ${EXTRAS}/etc/preferences.d/opscode < ${EXTRAS}/etc/apt.conf < ${NEW}/dists/${RELEASE}/${s}/binary-${a}/Release < ${BASEDIR}/extraoverride.pl <) { chomp; next if /^ /; if (/^\$/ && defined(\$task)) { print "\$package Task \$task\n"; undef \$package; undef \$task; } (\$key, \$value) = split /: /, \$_, 2; if (\$key eq 'Package') { \$package = \$value; } if (\$key eq 'Task') { \$task = \$value; } } EOF chmod +x ${BASEDIR}/extraoverride.pl gunzip -c ${NEW}/dists/${RELEASE}/main/binary-amd64/Packages.gz | \ ${BASEDIR}/extraoverride.pl >> \ ${INDICES}/override.${RELEASE}.extra.main for s in ${SECTIONS}; do for a in ${ARCHITECTURES}; do for t in deb udeb; do echo "Scanning section=${s} arch=${a} type=${t} ..." if [ X${t} = Xudeb ]; then di="/debian-installer" diover=".debian-installer" else di="" diover="" fi [ -r ${INDICES}/override.${RELEASE}.${s}${diover} ] && \ override=${INDICES}/override.${RELEASE}.${s}${diover} || \ unset override [ -r ${INDICES}/override.${RELEASE}.extra.${s} ] && \ extraoverride="-e ${INDICES}/override.${RELEASE}.extra.${s}" || \ unset extraoverride mkdir -p ${NEW}/pools/${RELEASE}/${s} ( cd ${NEW} && dpkg-scanpackages -m -a${a} -t${t} ${extraoverride} \ pools/${RELEASE}/${s} \ ${override} > \ ${NEW}/dists/${RELEASE}/${s}${di}/binary-${a}/Packages ) gzip -c ${NEW}/dists/${RELEASE}/${s}${di}/binary-${a}/Packages > \ ${NEW}/dists/${RELEASE}/${s}${di}/binary-${a}/Packages.gz done done done echo "Creating main Release file in cdrom repo" cat > ${BASEDIR}/release.conf < \ ${NEW}/dists/${RELEASE}/Release echo "Signing main Release file in cdrom repo ..." GNUPGHOME=${TMPGNUPG} gpg --yes --no-tty --default-key ${GPGKEYID} \ --passphrase-file ${GPGPASSWDFILE} --output ${NEW}/dists/${RELEASE}/Release.gpg \ -ba ${NEW}/dists/${RELEASE}/Release ########################### # DOWNLOADING BOOTSTRAP ########################### echo "Downloading bootstrap kernel and miniroot ..." echo "BOOTSTRAP_KERNEL_URL=${BOOTSTRAP_KERNEL_URL}" echo "BOOTSTRAP_INITRD_URL=${BOOTSTRAP_INITRD_URL}" mkdir -p ${BOOTSTRAPDIR} # wget -qO- ${BOOTSTRAP_KERNEL_URL} > ${BOOTSTRAPDIR}/linux # wget -qO- ${BOOTSTRAP_INITRD_URL} > ${BOOTSTRAPDIR}/initrd.gz cp $BINARIES_DIR/bootstrap/linux $BOOTSTRAPDIR/ cp $BINARIES_DIR/bootstrap/initrd.gz $BOOTSTRAPDIR/initrd.gz ########################### # DOWNLOADING PYTHON EGGS ########################### echo "Downloading python eggs ..." # FIXME: # It is very ugly to just copy directory with eggs into disk # It is nice to have beautiful way to download eggs with there dependencies mkdir -p ${EGGSDIR} rsync -av $BINARIES_DIR/eggs/ ${EGGSDIR} ########################### # DOWNLOADING RUBY GEMS ########################### echo "Downloading ruby gems ..." # FIXME: # It is very ugly to just copy directory with gems into disk # It is nice to have beautiful way to download gems with there dependencies mkdir -p ${GEMSDIR} rsync -av $BINARIES_DIR/gems/ ${GEMSDIR} ########################### # INJECT EXTRA FILES ########################### echo "Injecting files ..." echo ">>> Injecting late script ..." mkdir -p ${NEW}/bin cat > ${NEW}/bin/late < /target/etc/apt/sources.list.d/local.list # gnupg cp -r /cdrom/gnupg /target/root/.gnupg chown -R root:root /target/root/.gnupg chmod 700 /target/root/.gnupg chmod 600 /target/root/.gnupg/* # bootstrap mkdir -p /target/var/lib/mirror/bootstrap cp /cdrom/bootstrap/linux /target/var/lib/mirror/bootstrap/linux cp /cdrom/bootstrap/initrd.gz /target/var/lib/mirror/bootstrap/initrd.gz mkdir -p /target/root/.ssh chmod 700 /target/root/.ssh cp /cdrom/bootstrap/bootstrap.rsa /target/root/.ssh/bootstrap.rsa chmod 600 /target/root/.ssh/bootstrap.rsa # nailgun mkdir -p /target/opt cp -r /cdrom/nailgun /target/opt #system cp -r /cdrom/sync/* /target/ in-target update-rc.d chef-client disable # eggs cp -r /cdrom/eggs /target/var/lib/mirror # gems cp -r /cdrom/gems /target/var/lib/mirror EOF chmod +x ${NEW}/bin/late echo ">>> Syncing system ..." mkdir -p ${NEW}/sync rsync -rltp ${SYNC}/ ${NEW}/sync echo ">>> Injecting repo indices ..." mkdir -p ${NEW}/indices cp -r ${INDICES}/* ${NEW}/indices echo ">>> Injecting gnupg ..." mkdir ${NEW}/gnupg cp -r ${REPO}/gnupg ${NEW}/gnupg echo ">>> Injecting bootstrap files ..." mkdir -p ${NEW}/bootstrap cp ${BOOTSTRAPDIR}/linux ${NEW}/bootstrap/linux cp ${BOOTSTRAPDIR}/initrd.gz ${NEW}/bootstrap/initrd.gz cp ${REPO}/bootstrap/ssh/id_rsa ${NEW}/bootstrap/bootstrap.rsa echo ">>> Injecting nailgun webapp ..." cp -r ${REPO}/nailgun ${NEW} echo ">>> Injecting cookbooks ..." cp -r ${REPO}/cookbooks ${NEW}/nailgun echo ">>> Injecting scripts ..." mkdir -p ${NEW}/nailgun/bin cp ${REPO}/bin/create_release ${NEW}/nailgun/bin/create_release echo ">>> Injecting solo auxiliary files ..." mkdir -p ${NEW}/nailgun/solo cp ${SOLO}/solo.json ${NEW}/nailgun/solo/solo.json cp ${SOLO}/solo.rb ${NEW}/nailgun/solo/solo.rb echo ">>> Injecting eggs ..." mkdir -p ${NEW}/eggs rsync -av ${EGGSDIR}/ ${NEW}/eggs echo ">>> Injecting gems ..." mkdir -p ${NEW}/gems rsync -av ${GEMSDIR}/ ${NEW}/gems ########################### # MAKE NEW ISO ########################### echo "Calculating md5sums ..." rm ${NEW}/md5sum.txt ( cd ${NEW}/ && \ find . -type f -print0 | \ xargs -0 md5sum | \ grep -v "boot.cat" | \ grep -v "md5sum.txt" > md5sum.txt ) ISONAME_W_STAMP="${NEWISONAME}.${STAMP}.iso" echo "Building iso image ..." mkisofs -r -V "Mirantis Nailgun" \ -cache-inodes \ -J -l -b isolinux/isolinux.bin \ -c isolinux/boot.cat -no-emul-boot \ -boot-load-size 4 -boot-info-table \ -o ${NEWISODIR}/${ISONAME_W_STAMP} ${NEW}/ rm -f ${NEWISODIR}/${NEWISONAME}.last.iso ( cd ${NEWISODIR} ln -s ${NEWISONAME}.${STAMP}.iso ${NEWISONAME}.last.iso ) echo "ISO image ${ISONAME_W_STAMP} has been successfully built."