Ubuntu Autoinstall

Source ISO

First, download an Ubuntu ISO, and mount it so it can be accessed.

mkdir /mnt/iso
mount -o ro,loop ubuntu-14.04.4-server-amd64.iso /mnt/iso

Documentation

The ISO itself includes the documentation for setting up an automatic install, so you can view it directly if you want. In this case, I'm using elinks as my text browser.

elinks /mnt/iso/doc/install/manual/en/apb.html

Alternatively, if you want to use a GUI browser (firefox, etc), you could open it directly by with this URL: file:///mnt/iso/doc/install/manual/en/apb.html

Target ISO

Copy the contents to the directory of the new ISO you'll be making. Use rsync to recursively copy the files, and include the symlinks.

rsync -rl /mnt/iso/ autoinstall/

The permissions in the new directory are going to be read and execute only, so they need to be updated before any changes can be made. Use the default permissions for files:

find autoinstall/ -type f -print0 | xargs -0 chmod 0644
find autoinstall/ -type d -print0 | xargs -0 chmod 0755

Bootloader

There's two ways to boot the ISO – as a regular CD, using ISOLINUX, or chainloaded through another bootloader, using the GRUB2 configuration. An example of using the ISOLINUX install would be to run it in VirtualBox. An example of using GRUB2 would be using pygrub through XEN.

If you're not using Xen, then just use the default bootloader ISOLINUX.

ISOLINUX

First, add a menu entry for the automated install. Edit autoinstall/isolinux/txt.cfg. Here we use the default Ubuntu Server entry, and make two changes: append file entry changes the location of the preseed file, and adds auto.

Add this directly below the default install:

label autoinstall
  menu label ^Autoinstall Ubuntu Server
  kernel /install/vmlinuz
  append file=/cdrom/preseed/autoinstall.seed vga=788 initrd=/install/initrd.gz quiet auto=true --

Set the default language you want the install to use. See autoinstall/isolinux/langcode for the shortnames. To default to English:

echo en > autoinstall/isolinux/lang
GRUB2

For GRUB, add a new boot entry in autoinstall/boot/grub/grub.cfg, using autoinstall.seed and setting the locale.

menuentry "Automated Install Ubuntu Server" {
        set gfxpayload=keep
        linux   /install/vmlinuz file=/cdrom/preseed/autoinstall.seed locale=en_US --
        initrd  /install/initrd.gz
}

Build ISO

When everything's done, create the ISO using mkisofs:

mkisofs \
        -D \
        -r \
        -V "UBUNTU_AUTOINSTALL" \
        -cache-inodes \
        -J \
        -l \
        -b isolinux/isolinux.bin \
        -c isolinux/boot.cat \
        -input-charset utf-8 \
        -no-emul-boot \
        -boot-load-size 4 \
        -boot-info-table \
        -o autoinstall.iso \
        autoinstall/

Preseed File

Here's the preseed file I use to create an Ubuntu autoinstall ISO.

I had problems with using GRUB2 when booting this installed filesystem, so it uses legacy GRUB instead.

If you use this, note that this will remove everything on the HDD without asking.

  • Sets timezone to America/Denver
  • Default user is ubuntu with password ubuntu
  • Deletes all existing partitions, LVM settings, RAID arrays
  • Creates one partition, with ext4 as the filesystem - no LVM
  • Installs recommended packages, SSH server
  • Installs tmux
  • Eject the CD at the end
  • Powers off the machine after install

Save the contents of this file goes to autoinstall/preseed/autoinstall.seed

# Ubuntu Automated Install Preseed

# Only ask really important questions
d-i debconf/priority string critical

# Unmount partitions that may already be partitioned
d-i preseed/early_command string umount /media || true

# Set locale
d-i debian-installer/language string en
d-i debian-installer/country string US
d-i debian-installer/locale string en_US.UTF-8
d-i localechooser/supported-locales en_US.UTF-8

# Keyboard
d-i console-setup/ask_detect boolean false
d-i keyboard-configuration/layoutcode string us

# Timezone
d-i clock-setup/utc boolean true
d-i time/zone string America/Denver

# Network configuration
d-i netcfg/enable boolean false
d-i netcfg/get_hostname string localhost
d-i netcfg/get_domain string localdomain

# User accounts
d-i passwd/user-fullname string Ubuntu User
d-i passwd/username string ubuntu
d-i passwd/user-password password ubuntu
d-i passwd/user-password-again password ubuntu
d-i user-setup/allow-password-weak boolean true
d-i user-setup/encrypt-home boolean false

# Partitioning

# not setting the disk string, it will use the only available one
# d-i partman-auto/disk string /dev/sda 

# Remove any existing LVM or RAID partitions
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-md/device_remove_md boolean true

# Do not use LVM or encrypted partition
d-i partman-auto/method string regular

# Install everything on one partition
d-i partman-auto/choose_recipe select atomic

# Use ext4 as filesystem
d-i partman/default_filesystem string ext4
# Automatically partition without confirmation
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

# Install recommended packages
d-i pkgsel/install-recommends true

# Install standard Ubuntu types
d-i tasksel tasksel/first multiselect ubuntu-server, standard, openssh-server

# Additional packages to install
d-i pkgsel/include string tmux

# Don't upgrade packages after install
d-i pkgsel/upgrade select none

# Set policy for applying updates
d-i pkgsel/update-policy select none

# Skip updating locate database
d-i pkgsel/updatedb boolean true

# Install bootloader
# Use legacy GRUB
d-i grub-installer/grub2_instead_of_grub_legacy boolean false
d-i grub-installer/only_debian boolean true

# Force writing the bootloader to MBR
d-i grub-installer/with_other_os boolean true

# Avoid that last message about the install being complete.
d-i finish-install/reboot_in_progress note

# Eject CD
d-i cdrom-detect/eject boolean true

# Poweroff when finished
d-i debian-installer/exit/poweroff boolean true

If you make any changes, just rebuild the ISO again using mkisofs, and reload it.