Skip to content

Instantly share code, notes, and snippets.

@endersonmaia
Forked from aminin/.gitignore
Created January 18, 2013 13:58
Show Gist options
  • Save endersonmaia/4564699 to your computer and use it in GitHub Desktop.
Save endersonmaia/4564699 to your computer and use it in GitHub Desktop.
build/
*.box
*.iso

About

Consider weevee as more common way to create a basebox.

This script will:

  1. download the Ubuntu 12.04 alternate server, 64bit iso
  2. ... do some magic to turn it into a vagrant box file
  3. output package.box

Requirements

  1. Ubuntu 12.04 (amd64) with virtualbox and vagrant installed
  2. 64bit CPU with hardware virtualization feature

Usage

bash build.sh

This should do everything you need. If you don't have mkisofs, install macports, then: sudo port install cdrtools

References

  1. http://blog.ericwhite.ca/articles/2009/11/unattended-debian-lenny-install/
  2. http://cdimage.ubuntu.com/releases/precise/beta-2/
  3. http://www.imdb.com/name/nm1483369/
  4. http://vagrantup.com/docs/base_boxes.html
  5. https://github.com/tigris/vagrant-ubuntu-precise-64
#!/bin/bash
# make sure we have dependencies
hash mkisofs 2>/dev/null || { echo >&2 "ERROR: mkisofs not found. Aborting."; exit 1; }
BOX="ubuntu-12.04-amd64"
FOLDER_BASE=`pwd`
FOLDER_BUILD="${FOLDER_BASE}/build"
FOLDER_VBOX="${FOLDER_BUILD}/vbox"
FOLDER_ISO="${FOLDER_BUILD}/iso"
FOLDER_ISO_TMP="${FOLDER_BUILD}/iso_tmp"
FOLDER_ISO_CUSTOM="${FOLDER_BUILD}/iso/custom"
FOLDER_ISO_INITRD="${FOLDER_BUILD}/iso/initrd"
# let's make sure they exist
mkdir -p "${FOLDER_BUILD}"
mkdir -p "${FOLDER_VBOX}"
mkdir -p "${FOLDER_ISO}"
sudo rm -rf "${FOLDER_ISO_TMP}"
mkdir -p "${FOLDER_ISO_TMP}"
# let's make sure they're empty
echo "Cleaning Custom build directories..."
sudo rm -rf "${FOLDER_ISO_CUSTOM}"
sudo rm -rf "${FOLDER_ISO_INITRD}"
mkdir -p "${FOLDER_ISO_INITRD}"
VBoxManage unregistervm ${BOX} --delete 1>/dev/null 2>/dev/null
MIRROR_URL="http://mirror.yandex.ru/ubuntu-releases/precise/"
ISO_FILENAME="ubuntu-12.04-alternate-amd64.iso"
ISO_URL="${MIRROR_URL}${ISO_FILENAME}"
ISO_MD5="9fcc322536575dda5879c279f0b142d7"
INITRD_FILENAME="${FOLDER_ISO}/initrd.gz"
ISO_MD5SUM_TEMP="${FOLDER_BUILD}/md5sum"
ISO_GUESTADDITIONS="/usr/share/virtualbox/VBoxGuestAdditions.iso"
# download the installation disk if you haven't already or it is corrupted somehow
echo "Downloading ubuntu-12.04-alternate-amd64.iso ..."
cd ${FOLDER_ISO}
if [ ! -e "${ISO_FILENAME}" ]; then
curl --output "${ISO_FILENAME}" -L "${ISO_URL}"
fi
# make sure download is right...
echo "${ISO_MD5} *${ISO_FILENAME}" > $ISO_MD5SUM_TEMP
md5sum --status --check $ISO_MD5SUM_TEMP
if [ $? != 0 ]; then
echo "ERROR: MD5 does not match. Aborting."
exit 1
fi
# customize it
echo "Creating Custom ISO"
echo "Extracting downloaded ISO ..."
sudo mount -t iso9660 -o ro,loop "${ISO_FILENAME}" "${FOLDER_ISO_TMP}"
cp -a ${FOLDER_ISO_TMP} ${FOLDER_ISO_CUSTOM}
sudo umount "${FOLDER_ISO_TMP}"
# backup initrd.gz
echo "Backing up current init.rd ..."
chmod u+w "${FOLDER_ISO_CUSTOM}/install" "${FOLDER_ISO_CUSTOM}/install/initrd.gz"
mv "${FOLDER_ISO_CUSTOM}/install/initrd.gz" "${FOLDER_ISO_CUSTOM}/install/initrd.gz.org"
# stick in our new initrd.gz
echo "Installing new initrd.gz ..."
cd "${FOLDER_ISO_INITRD}"
gunzip -c "${FOLDER_ISO_CUSTOM}/install/initrd.gz.org" | sudo cpio -id
cd "${FOLDER_BASE}"
cp preseed.cfg "${FOLDER_ISO_INITRD}/preseed.cfg"
cd "${FOLDER_ISO_INITRD}"
find . | sudo cpio --create --format='newc' | gzip > "${FOLDER_ISO_CUSTOM}/install/initrd.gz"
# clean up permissions
echo "Cleaning up Permissions ..."
chmod u-w "${FOLDER_ISO_CUSTOM}/install" "${FOLDER_ISO_CUSTOM}/install/initrd.gz" "${FOLDER_ISO_CUSTOM}/install/initrd.gz.org"
# replace isolinux configuration
echo "Replacing isolinux config ..."
cd "${FOLDER_BASE}"
chmod u+w "${FOLDER_ISO_CUSTOM}/isolinux" "${FOLDER_ISO_CUSTOM}/isolinux/isolinux.cfg"
rm "${FOLDER_ISO_CUSTOM}/isolinux/isolinux.cfg"
cp isolinux.cfg "${FOLDER_ISO_CUSTOM}/isolinux/isolinux.cfg"
chmod u+w "${FOLDER_ISO_CUSTOM}/isolinux/isolinux.bin"
# add late_command script
echo "Add late_command script ..."
chmod u+w "${FOLDER_ISO_CUSTOM}"
cp "${FOLDER_BASE}/late_command.sh" "${FOLDER_ISO_CUSTOM}"
echo "Running mkisofs ..."
mkisofs -r -V "Custom Ubuntu Install CD" \
-cache-inodes -quiet \
-J -l -b isolinux/isolinux.bin \
-c isolinux/boot.cat -no-emul-boot \
-boot-load-size 4 -boot-info-table \
-o "${FOLDER_ISO}/custom.iso" "${FOLDER_ISO_CUSTOM}"
# create virtual machine
echo "Creating VM Box..."
VBoxManage createvm \
--name "${BOX}" \
--ostype Ubuntu_64 \
--register \
--basefolder "${FOLDER_VBOX}"
VBoxManage modifyvm "${BOX}" \
--memory 360 \
--boot1 dvd \
--boot2 disk \
--boot3 none \
--boot4 none \
--vram 12 \
--pae off \
--rtcuseutc on
VBoxManage storagectl "${BOX}" \
--name "IDE Controller" \
--add ide \
--controller PIIX4 \
--hostiocache on
VBoxManage storageattach "${BOX}" \
--storagectl "IDE Controller" \
--port 1 \
--device 0 \
--type dvddrive \
--medium "${FOLDER_ISO}/custom.iso"
VBoxManage storagectl "${BOX}" \
--name "SATA Controller" \
--add sata \
--controller IntelAhci \
--sataportcount 1 \
--hostiocache off
VBoxManage createhd \
--filename "${FOLDER_VBOX}/${BOX}/${BOX}.vdi" \
--size 40960
VBoxManage storageattach "${BOX}" \
--storagectl "SATA Controller" \
--port 0 \
--device 0 \
--type hdd \
--medium "${FOLDER_VBOX}/${BOX}/${BOX}.vdi"
VBoxManage startvm "${BOX}"
echo -n "Waiting for installer to finish "
while VBoxManage list runningvms | grep "${BOX}" >/dev/null; do
sleep 20
echo -n "."
done
echo ""
# Forward SSH
VBoxManage modifyvm "${BOX}" \
--natpf1 "guestssh,tcp,,2222,,22"
# Attach guest additions iso
VBoxManage storageattach "${BOX}" \
--storagectl "IDE Controller" \
--port 1 \
--device 0 \
--type dvddrive \
--medium "${ISO_GUESTADDITIONS}"
VBoxManage startvm "${BOX}"
# get private key
curl --output "${FOLDER_BUILD}/id_rsa" "https://raw.github.com/mitchellh/vagrant/master/keys/vagrant"
chmod 600 "${FOLDER_BUILD}/id_rsa"
# install virtualbox guest additions
ssh -i "${FOLDER_BUILD}/id_rsa" -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p 2222 vagrant@127.0.0.1 "sudo mount /dev/cdrom /media/cdrom; sudo sh /media/cdrom/VBoxLinuxAdditions.run; sudo umount /media/cdrom; sudo shutdown -h now"
echo -n "Waiting for machine to shut off "
while VBoxManage list runningvms | grep "${BOX}" >/dev/null; do
sleep 20
echo -n "."
done
echo ""
VBoxManage modifyvm "${BOX}" --natpf1 delete "guestssh"
# Detach guest additions iso
echo "Detach guest additions ..."
VBoxManage storageattach "${BOX}" \
--storagectl "IDE Controller" \
--port 1 \
--device 0 \
--type dvddrive \
--medium emptydrive
echo "Building Vagrant Box ..."
vagrant package --base "${BOX}"
echo "Deleting VM Box ..."
VBoxManage unregistervm --delete ${BOX}
# unattended installation
default unattended
prompt 0
timeout 0
label unattended
kernel /install/vmlinuz
append vga=788 initrd=/install/initrd.gz keyboard-configuration/layoutcode=us quiet --
#!/bin/bash
# passwordless sudo
echo "%sudo ALL=NOPASSWD: ALL" > /etc/sudoers.d/vagrant
# let sudo see rvm path
echo 'Defaults !secure_path' >> /etc/sudoers.d/vagrant
chmod 0440 /etc/sudoers.d/vagrant
# public ssh key for vagrant user
mkdir /home/vagrant/.ssh
wget -O /home/vagrant/.ssh/authorized_keys "https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub"
chmod 755 /home/vagrant/.ssh
chmod 644 /home/vagrant/.ssh/authorized_keys
chown -R vagrant:vagrant /home/vagrant/.ssh
# speed up ssh
echo "UseDNS no" >> /etc/ssh/sshd_config
# Some packages (such as dpkg) imply the admin group exists
addgroup --system admin
usermod -G admin -a vagrant
# Install RVM
curl -L get.rvm.io | bash -s stable
# To enable rvm path configuration via /etc/profile.d/rvm.sh
usermod -G rvm -a vagrant
usermod -G rvm -a root
# rvm path configuration
source /etc/profile.d/rvm.sh
# Install ruby 1.9.3
rvm install 1.9.3
# get chef
gem install chef --no-rdoc --no-ri
# display login promt after boot
sed "s/quiet splash//" /etc/default/grub > /tmp/grub
mv /tmp/grub /etc/default/grub
update-grub
# clean up
apt-get clean
Copyright (C) 2012 Carl Johan Crafoord, Benson Wong
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
### Localization
d-i debian-installer/language string ru
d-i debian-installer/country string RU
d-i debian-installer/locale string ru_RU.UTF-8
# Locale
d-i localechooser/preferred-locale string ru_RU.UTF-8
d-i localechooser/supported-locales ru_RU.UTF-8, en_US.UTF-8
# Keyboard selection.
# Keyboard
d-i localechooser/shortlist select RU
d-i localechooser/shortlist/ru select Российская Федерация
d-i console-setup/ask_detect boolean false
d-i keyboard-configuration/layoutcode string ru
d-i keyboard-configuration/variant select Русская
d-i keyboard-configuration/layout select Русская
d-i keyboard-configuration/toggle select Alt+Shift
# Pick any network interface and go with it
d-i netcfg/get_hostname string vagrant-ubuntu-64
d-i netcfg/get_domain string vagrantup.com
# What's a vagrant?
d-i passwd/user-fullname string
d-i passwd/username string vagrant
d-i passwd/user-password password vagrant
d-i passwd/user-password-again password vagrant
d-i user-setup/allow-password-weak boolean true
d-i user-setup/encrypt-home boolean false
# We've got all the time in the world
d-i time/zone string Australia/Melbourne
d-i clock-setup/utc boolean true
# Need to do something about that disk
d-i partman-auto/method string regular
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
# No proxy, please
d-i mirror/http/proxy string
# Only install the standard system and language packs.
tasksel tasksel/first multiselect
d-i preseed/early_command string . /usr/share/debconf/confmodule; db_get debconf/priority; case $RET in low|medium) db_fset tasksel/first seen false; echo 'tasksel tasksel/first seen false' >>/var/lib/preseed/log ;; esac
d-i pkgsel/language-pack-patterns string
# No language support packages.
d-i pkgsel/install-language-support boolean false
# Individual additional packages to install
# Packages [zlib1g-dev libssl-dev libreadline6-dev libxml2-dev libsqlite3-dev] are for compilling Ruby with RVM
d-i pkgsel/include string build-essential ssh curl git nfs-common zlib1g-dev libssl-dev libreadline6-dev libxml2-dev libsqlite3-dev
# Whether to upgrade packages after debootstrap.
# Allowed values: none, safe-upgrade, full-upgrade
d-i pkgsel/upgrade select safe-upgrade
# Go grub, go!
d-i grub-installer/only_debian boolean true
#For the update
d-i pkgsel/update-policy select none
# Wrapping things up
d-i preseed/late_command string cp /cdrom/late_command.sh /target/tmp/late_command.sh && in-target chmod +x /tmp/late_command.sh && in-target /tmp/late_command.sh
# Shut down, already
d-i finish-install/reboot_in_progress note
d-i debian-installer/exit/poweroff boolean true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment