Skip to content

Instantly share code, notes, and snippets.

@dolph
Last active December 8, 2016 22:48
Show Gist options
  • Save dolph/41266d24b581b85a6202655e96694849 to your computer and use it in GitHub Desktop.
Save dolph/41266d24b581b85a6202655e96694849 to your computer and use it in GitHub Desktop.
Shell script to build a virtualbox VM.
#!/bin/bash
set -e
set -o xtrace
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Create a host only network if one does not exist, so that we can SSH into the
# machine later.
vboxmanage list hostonlyifs | grep vboxnet0 || vboxmanage hostonlyif create
# Delete an existing VM, if one exists.
vboxmanage controlvm ubuntu1604 poweroff hard || true
sleep 1
vboxmanage unregistervm ubuntu1604 --delete || true
# vboxmanage list ostypes
vboxmanage createvm \
--name ubuntu1604 \
--ostype Ubuntu_64 \
--register
vboxmanage modifyvm ubuntu1604 \
--cpus 2 \
--memory 16000
# Create a storage controller to attach hard drives and DVD drives to.
# Available controllers: LsiLogic / LSILogicSAS / BusLogic / IntelAhci / PIIX3
# / PIIX4 / ICH6 / I82078
vboxmanage storagectl ubuntu1604 \
--name SATA \
--add sata \
--controller IntelAhci \
--bootable on
# Create a hard drive for the operating system.
# vboxmanage closemedium disk ubuntu1604 --delete
rm -rf $DIR/ubuntu1604.vdi
vboxmanage createhd --filename ubuntu1604 --size 80000
vboxmanage storageattach ubuntu1604 \
--storagectl SATA \
--port 0 \
--device 0 \
--type hdd \
--medium ubuntu1604.vdi
# Attach a DVD drive.
vboxmanage storageattach ubuntu1604 \
--storagectl SATA \
--port 1 \
--device 0 \
--type dvddrive \
--medium "$DIR/ubuntu-16.04.1-server-amd64-repacked.iso"
# Attach a NAT network to reach the outside world.
vboxmanage modifyvm ubuntu1604 \
--nic1 nat \
--nictype1 82540EM \
--cableconnected1 on
# Attach a host-only network to be able to SSH in.
vboxmanage modifyvm ubuntu1604 \
--nic2 hostonly \
--nictype2 82540EM \
--cableconnected2 on \
--hostonlyadapter2 vboxnet0
# Start the virtual machine.
vboxmanage startvm ubuntu1604
#!/bin/bash
#
# Translate a MAC address fetched from VirtualBox into a IP address
#
if [ $# -lt 1 ]; then
echo -e "\nUsage:\n$0 [virtual machine] \n"
exit 1
fi
# Get a string of the form macaddress1=xxxxxxxxxxx
IFS=$'\n'; for var in $(vboxmanage showvminfo $1 --machinereadable | grep macaddress); do
# Parse out the MAC and convert it to lowercase.
mac=$( echo ${var} | cut -d '=' -f 2- | sed 's/"//g' | tr '[A-Z]' '[a-z]')
# Format the mac address with colons.
mac=$(echo `expr ${mac:0:2}`:`expr ${mac:2:2}`:`expr ${mac:4:2}`:`expr ${mac:6:2}`:`expr ${mac:8:2}`:`expr ${mac:10:2}`)
nmap -sP 192.168.56.0/24 &>/dev/null
# Get known IP, if any.
IFS=$'\n'; for line in $(arp -an); do
IFS=' ' read -a array <<< $line
ip=$(echo "${array[1]}" | tr "(" " " | tr ")" " ")
if [ "$mac" = "${array[3]}" ]; then
echo `echo ${ip} | sed 's/[[:space:]]//g'`
# Yay, we found an IP!
exit 0
fi
done
done
# Couldn't find an IP.
exit 1
# Source: https://help.ubuntu.com/lts/installation-guide/example-preseed.txt
# Language & keyboard configuration, just in case.
d-i debian-installer/locale string en_US
d-i console-setup/ask_detect boolean false
d-i keyboard-configuration/xkb-keymap select us
d-i keyboard-configuration/layoutcode select us
# Connect automatically.
d-i netcfg/choose_interface select auto
d-i netcfg/get_hostname string unassigned-hostname
d-i netcfg/get_domain string unassigned-domain
d-i netcfg/hostname string ubuntu1604
# TODO: test without this.
# Disable that annoying WEP key dialog.
d-i netcfg/wireless_wep string
# Load proprietary firmware.
d-i hw-detect/load_firmware boolean true
# Mirror settings
d-i mirror/country string manual
d-i mirror/http/hostname string pubmirrors.dal.corespace.com
d-i mirror/http/directory string /ubuntu
d-i mirror/http/proxy string
# Only create a root user with password r00tme
d-i passwd/root-login boolean true
d-i passwd/make-user boolean false
d-i passwd/root-password password r00tme
d-i passwd/root-password-again password r00tme
d-i user-setup/allow-password-weak boolean true
d-i user-setup/encrypt-home boolean false
# Timezones.
d-i clock-setup/utc boolean true
d-i time/zone string US/Central
d-i clock-setup/ntp boolean false
# Partitioning.
d-i partman-auto/init_automatically_partition select biggest_free
d-i partman-auto/method string lvm
d-i partman-auto-lvm/guided_size string max
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-md/device_remove_md boolean true
d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman-auto/choose_recipe select atomic
d-i partman/default_filesystem string ext4
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman-md/confirm boolean true
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
# You can choose to install restricted and universe software, or to install
# software from the backports repository.
d-i apt-setup/restricted boolean true
d-i apt-setup/universe boolean true
d-i apt-setup/backports boolean true
d-i apt-setup/services-select multiselect security
d-i apt-setup/security_host string security.ubuntu.com
d-i apt-setup/security_path string /ubuntu
# Package selections.
tasksel tasksel/first multiselect ubuntu-server
d-i pkgsel/include string openssh-server build-essential
# Whether to upgrade packages after debootstrap.
# Allowed values: none, safe-upgrade, full-upgrade
#d-i pkgsel/upgrade select none
# Enable automatic security upgrades.
d-i pkgsel/update-policy select unattended-upgrades
# Disable reporting statistics.
popularity-contest popularity-contest/participate boolean false
# Skip installing a boot loader?
#d-i grub-installer/skip boolean true
#d-i lilo-installer/skip boolean true
d-i grub-installer/only_debian boolean true
# Skip informing the user that install is complete.
d-i finish-install/reboot_in_progress note
# Allow root login via SSH and enable the second ethernet adapter.
# d-i preseed/late_command string \
# in-target sed -i 's/PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config ; in-target sh -c "printf 'auto enp0s8\niface enp0s8 inet dhcp' >> /etc/network/interfaces"
# Shutdown when the install is finished, without rebooting.
d-i debian-installer/exit/poweroff boolean false
# base-config base-config/early_command string in-target printf 'auto enp0s8\niface enp0s8 inet dhcp\n' > /etc/network/interfaces.d/enp0s8
# base-config base-config/late_command string in-target printf 'auto enp0s8\niface enp0s8 inet dhcp\n' > /etc/network/interfaces.d/enp0s8
d-i late_command string \
in-target /usr/bin/printf '\nauto enp0s8\niface enp0s8 inet dhcp\n' > /etc/network/interfaces; \
cp /target/etc/network/interfaces /etc/network/interfaces;
set -e
set -o xtrace
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Pre-emptively clean up from previously failed runs.
sudo umount $DIR/loopdir/ || true
sudo rm -rf $DIR/loopdir/
sudo rm -rf $DIR/unpacked/
sudo rm -rf $DIR/irmod/
# Mount the official ISO as a directory.
sudo mkdir $DIR/loopdir/
sudo mount -o loop ubuntu-16.04.1-server-amd64.iso loopdir
sudo mkdir $DIR/unpacked/
sudo rsync -a -H --exclude=TRANS.TBL $DIR/loopdir/ $DIR/unpacked/
sudo umount $DIR/loopdir/
sudo rm -rf $DIR/loopdir/
# Drop preseed file into place.
sudo cp $DIR/preseed.cfg $DIR/unpacked/preseed/custom.seed
# Modify the boot loader with a fully automatic option.
sudo sh -c "echo 'LABEL customseed
menu label ^Custom seeded installation
kernel /install/vmlinuz
append file=/cdrom/preseed/custom.seed debian-installer/locale=en_US console-setup/layoutcode=en keyboard-configuration/layoutcode=us console-setup/ask_detect=false keyboard-configuration/xkb-keymap=en_US localechooser/translation/warn-light=true localechooser/translation/warn-severe=true initrd=/install/initrd.gz ramdisk_size=16384 root=/dev/ram rw quiet
--
timeout 1' >> $DIR/unpacked/isolinux/isolinux.cfg"
# Set our custom menu item as the default selection.
sudo sed -i 's/^default.*/default customseed/g' $DIR/unpacked/isolinux/isolinux.cfg
# Fix md5sum
cd $DIR/unpacked/
sudo rm md5sum.txt
sudo sh -c 'md5sum `find -follow -type f` > md5sum.txt'
cd $DIR
# Repackage the directory into a new ISO file.
sudo genisoimage \
-o $DIR/ubuntu-16.04.1-server-amd64-repacked.iso \
-r -J -no-emul-boot -boot-load-size 4 \
-boot-info-table \
-b isolinux/isolinux.bin \
-c isolinux/boot.cat $DIR/unpacked/
sudo chown $USER:$USER $DIR/ubuntu-16.04.1-server-amd64-repacked.iso
sudo chmod 664 $DIR/ubuntu-16.04.1-server-amd64-repacked.iso
sudo rm -rf $DIR/unpacked/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment