Created
May 28, 2018 09:17
-
-
Save mkjaer/cd4a1fa72fa3224a4651982b86b5d487 to your computer and use it in GitHub Desktop.
Create unattended Ubuntu ISO
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
cd $(dirname "${0}") | |
UBUNTU_VERSION=${UBUNTU_VERSION:=16.04.3} | |
INSTALL_HOSTNAME=${INSTALL_HOSTNAME:=ubuntu} | |
USERNAME=${USERNAME:=username} | |
PASSWORD=${PASSWORD:=password} | |
SEED_FILE=${SEED_FILE:=lvm.seed} | |
TIMEZONE=${TIMEZONE:=$(cat /etc/timezone)} | |
DOWNLOAD_FILE="ubuntu-$UBUNTU_VERSION-server-amd64.iso" | |
DOWNLOAD_LOCATION="http://releases.ubuntu.com/$UBUNTU_VERSION/" | |
NEW_ISO_NAME="ubuntu-$UBUNTU_VERSION-server-amd64-unattended.iso" | |
SCRIPT_PATH="${PWD}" | |
TMP="${PWD}/tmp" # Working folder | |
# Only run as root | |
if [ $(whoami) != "root" ]; then | |
echo "This script can only be run as root..." | |
exit 1 | |
fi | |
# Download the iso file if it doesn't already exist | |
if [[ ! -f $TMP/$DOWNLOAD_FILE ]]; then | |
echo -n "Downloading $DOWNLOAD_FILE: " | |
wget "$DOWNLOAD_LOCATION$DOWNLOAD_FILE" --directory-prefix=$TMP | |
if [[ $? -ne 0 ]]; then | |
echo "Error: Failed to download ISO: $DOWNLOAD_LOCATION$DOWNLOAD_FILE" | |
echo "You can download it manually and move it to $TMP/$DOWNLOAD_FILE" | |
exit 1 | |
fi | |
fi | |
# Copy seed file | |
echo -n "Copying $SEED_FILE: " | |
if [[ ! -f $SCRIPT_PATH/$SEED_FILE ]]; then | |
echo "No seed file ($SEED_FILE) found. Aborting..." | |
exit 1 | |
fi | |
cp $SCRIPT_PATH/$SEED_FILE $TMP/ | |
# install required packages | |
if [ -z $(which mkpasswd) ] || [ -z $(which mkisofs) ] || [ -z $(which isohybrid) ]; then | |
echo "Installing required packages..." | |
apt-get -y update > /dev/null 2>&1 | |
apt-get -y install whois genisoimage syslinux > /dev/null | |
#16.04 | |
if [ $(fgrep "16.04" /etc/os-release) ]; then | |
apt-get -y install syslinux-utils > /dev/null | |
fi | |
fi | |
# Create working folders | |
echo "Creating working folders..." | |
mkdir -p $TMP/iso_org $TMP/iso_new | |
# Mount the image | |
if [[ -z $(grep $TMP/iso_org /proc/mounts) ]]; then | |
echo "Mounting original iso file..." | |
mount -o loop $TMP/$DOWNLOAD_FILE $TMP/iso_org | |
fi | |
# Copy the iso contents to the working directory | |
cp -rT $TMP/iso_org $TMP/iso_new > /dev/null 2>&1 | |
# Boot without waiting for user input | |
sed -i -r 's/timeout\s+[0-9]+/timeout 1/g' $TMP/iso_new/isolinux/isolinux.cfg | |
# Copy the seed file to the iso | |
cp -rT $TMP/$SEED_FILE $TMP/iso_new/preseed/$SEED_FILE | |
# Copy debian packages to be installed later | |
if [[ -d "packages" ]]; then | |
echo "Creating $TMP/iso_new/pool/extras/ and copying $(ls packages | wc -l) files/folders..." | |
mkdir -p $TMP/iso_new/pool/extras/ | |
cp -R packages/ $TMP/iso_new/pool/extras/ | |
else | |
echo "No packages folder found so nothing extra added..." | |
fi | |
# Generate a password hash for the seed file | |
PWHASH=$(echo $PASSWORD | mkpasswd -s -m sha-512) | |
# Update the seed file with our input | |
sed -i "s@{{username}}@$USERNAME@g" $TMP/iso_new/preseed/$SEED_FILE | |
sed -i "s@{{pwhash}}@$PWHASH@g" $TMP/iso_new/preseed/$SEED_FILE | |
sed -i "s@{{hostname}}@$INSTALL_HOSTNAME@g" $TMP/iso_new/preseed/$SEED_FILE | |
sed -i "s@{{timezone}}@$TIMEZONE@g" $TMP/iso_new/preseed/$SEED_FILE | |
# Calculate checksum for seed file | |
SEED_CHECKSUM=$(md5sum $TMP/iso_new/preseed/$SEED_FILE) | |
# Add the autoinstall option to the menu | |
sed -i "/label install/ilabel autoinstall\n\ | |
menu label ^Autoinstall Ubuntu Server\n\ | |
kernel /install/vmlinuz\n\ | |
append file=/cdrom/preseed/ubuntu-server.seed initrd=/install/initrd.gz pcie_aspm=off auto=true priority=high preseed/file=/cdrom/preseed/$SEED_FILE preseed/file/checksum=$SEED_CHECKSUM --" $TMP/iso_new/isolinux/txt.cfg | |
echo "Creating the new iso..." | |
cd $TMP/iso_new | |
mkisofs -D -r -V "UNATTENDED_UBUNTU" -cache-inodes -J -l -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o $TMP/$NEW_ISO_NAME . > /dev/null 2>&1 | |
# Make iso bootable (for dd'ing to USB stick) | |
isohybrid $TMP/$NEW_ISO_NAME | |
# Cleanup | |
umount $TMP/iso_org | |
rm -rf $TMP/iso_new $TMP/iso_org $TMP/$SEED_FILE | |
mkdir -p $SCRIPT_PATH/target | |
mv $TMP/*-unattended.iso $SCRIPT_PATH/target/ | |
echo | |
echo "Finished the new iso (target/$NEW_ISO_NAME) created using $SEED_FILE" | |
echo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# regional setting | |
d-i debian-installer/language string en_US:en | |
d-i debian-installer/country string US | |
d-i debian-installer/locale string en_US | |
d-i localechooser/supported-locales multiselect en_US.UTF-8 | |
d-i pkgsel/install-language-support boolean true | |
# Verbose output and no boot splash screen | |
d-i debian-installer/quiet boolean false | |
d-i debian-installer/splash boolean false | |
# force unmount any old disk | |
d-i preseed/early_command string umount /media || true | |
# Install hwe kernel | |
d-i base-installer/kernel/altmeta string hwe-16.04 | |
# Use the following option to add additional boot parameters for the installed system | |
# cgroup_enable=memory swapaccount=1 is for https://docs.docker.com/engine/installation/linux/linux-postinstall/ | |
d-i debian-installer/add-kernel-opts string vga=normal nomodeset cgroup_enable=memory swapaccount=1 pcie_aspm=off transparent_hugepage=never | |
# keyboard selection | |
d-i console-setup/ask_detect boolean false | |
d-i keyboard-configuration/modelcode string pc105 | |
d-i keyboard-configuration/layoutcode string us | |
d-i keyboard-configuration/variantcode string intl | |
d-i keyboard-configuration/xkb-keymap select us(intl) | |
d-i debconf/language string en_US:en | |
# network settings | |
d-i netcfg/enable boolean true | |
d-i netcfg/choose_interface select auto | |
d-i netcfg/dhcp_timeout string 5 | |
d-i netcfg/get_hostname string {{hostname}} | |
d-i netcfg/get_domain string {{hostname}} | |
# mirror settings | |
d-i apt-setup/no_mirror boolean true | |
#d-i mirror/country string manual | |
#d-i mirror/http/hostname string archive.ubuntu.com | |
#d-i mirror/http/directory string /ubuntu | |
d-i mirror/http/proxy string | |
# clock and timezone settings | |
d-i time/zone string {{timezone}} | |
d-i clock-setup/utc boolean true | |
d-i clock-setup/ntp boolean false | |
# user account setup | |
d-i passwd/root-login boolean false | |
# Root password, encrypted | |
d-i passwd/root-password-crypted password {{pwhash}} | |
d-i passwd/root-password-crypted password {{pwhash}} | |
d-i passwd/make-user boolean true | |
d-i passwd/user-fullname string {{username}} | |
d-i passwd/username string {{username}} | |
d-i passwd/user-password-crypted password {{pwhash}} | |
d-i passwd/user-uid string | |
d-i user-setup/allow-password-weak boolean false | |
d-i passwd/user-default-groups string adm cdrom dialout lpadmin plugdev sambashare | |
d-i user-setup/encrypt-home boolean false | |
# configure apt | |
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 | |
tasksel tasksel/first multiselect Basic Ubuntu server, openssh-server | |
d-i pkgsel/upgrade select none | |
d-i pkgsel/update-policy select none | |
d-i pkgsel/updatedb boolean false | |
# disk partitioning | |
d-i partman/confirm_write_new_label boolean true | |
d-i partman/choose_partition select finish | |
d-i partman/confirm_nooverwrite boolean true | |
d-i partman/confirm boolean true | |
d-i partman-auto/purge_lvm_from_device boolean true | |
d-i partman-lvm/device_remove_lvm boolean true | |
d-i partman-lvm/confirm boolean true | |
d-i partman-lvm/confirm_nooverwrite boolean true | |
#d-i partman-auto-lvm/no_boot boolean true | |
d-i partman-md/device_remove_md boolean true | |
d-i partman-md/confirm boolean true | |
d-i partman-md/confirm_nooverwrite boolean true | |
d-i partman-auto/method string lvm | |
d-i partman-auto-lvm/guided_size string max | |
d-i partman-partitioning/confirm_write_new_label boolean true | |
d-i partman-basicfilesystems/no_swap boolean false | |
d-i partman/default_filesystem string ext4 | |
d-i partman-auto/choose_recipe select preseedrecipe | |
d-i partman-auto-lvm/new_vg_name string ubuntu-x64-templ | |
d-i partman-auto/expert_recipe string \ | |
preseedrecipe :: \ | |
512 600 512 ext3 \ | |
$primary{ } $bootable{ } \ | |
method{ format } format{ } \ | |
use_filesystem{ } filesystem{ ext3 } \ | |
mountpoint{ /boot } \ | |
. \ | |
6144 6146 -1 ext4 method{ lvm } $lvmok{ } \ | |
lv_name{ whatever } format{ } \ | |
use_filesystem{ } filesystem{ ext4 } \ | |
mountpoint{ / } \ | |
. | |
# grub boot loader | |
d-i grub-installer/only_debian boolean true | |
d-i grub-installer/with_other_os boolean true | |
# finish installation | |
d-i finish-install/reboot_in_progress note | |
d-i finish-install/keep-consoles boolean false | |
d-i cdrom-detect/eject boolean true | |
d-i debian-installer/exit/halt boolean false | |
d-i debian-installer/exit/poweroff boolean false | |
d-i preseed/late_command string cp -a /cdrom/pool/extras/packages/changeip.sh /target/usr/local/bin/changeip; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment