Skip to content

Instantly share code, notes, and snippets.

@dryleaf
Forked from AugustoCiuffoletti/UbuntuMini.md
Created December 8, 2022 09:27
Show Gist options
  • Save dryleaf/2c74314c13238c495dc42dcf02c6eb52 to your computer and use it in GitHub Desktop.
Save dryleaf/2c74314c13238c495dc42dcf02c6eb52 to your computer and use it in GitHub Desktop.
A script to produce a minimal Ubuntu image for VirtualBox (without the mini.iso)

Living without the Ubuntu mini.iso (in VirtualBox)

The mini.iso for the Ubuntu distribution is legacy since version 20.04LTS (Focal Fossa). This is a bad news for those (like me) that formerly used this distribution to produce lightweight virtual machines for development, teaching, testing, etc. A distribution of the mini.iso for Ubuntu 20.04 is indeed still available here, but there is no guarantee that its availability will continue after Focal Fossa. An askubuntu post on the topic (there are several) is here.

So I decided to find a way to do without the mini.iso, and I wrote this script that takes to the ''tasksel'' step starting from a cloud image in the ubuntu repository. You have many options here about the image format to use: I refer to the .ova file that you find in focal/current. Using a mix of VBOxMangage commands and the cloud-init tools you obtain a tasksel dialog to proceed with you customization. Surprise, it is faster than the procedure based on the mini.iso.

Customizing the script

Customization is carried out by editing the bash variables on top of the script. Namely:

  • VMimage the location of the OVA image
  • VMname the name of your VM (as in the VirtualBox dashboard)
  • VMhostname the hostname
  • VMusername the name of the initial user
  • VMtimezone the timezone (if you do not touch this line it will be the same as your host machine)
  • VMlocale the localization (if you do not touch this line it will be the same as your host machine)
  • VMkeyboard the console keyboard (if you do not touch this line it will be the same as your host machine)

If you do not touch at all you obtain a customizable running VM.

How it works

Jump to the next section if in hurry. This one is mainly written for those that want to adapt it.

The first part of the script creates a vm-config.sh file that will be later uploaded to the running VM and, there, executed to configure it. We will describe its function later.

Next the Virtual Machine is created: download the .ova, create the VM, configure networking, and prepare the drives.

The following step creates the cloud-init configuration files (user-data and meta-data): they will be used by the cloud-init support inside the VM (remember, it is created from a cloud image) to configure it from the inside. In the two files you find the name of the host, the name of the (unique) user, and its RSA public key for authentication. The files are packaged in a .iso file (a virtual DVD) that is attached to the VM, and threfore available to cloud-init.

At this point the script launches the VM, and waits for your prompt to start the successive steps. This is extremely in-elegant: any suggestion is welcome.

When the VM is up and running you hit return and the installation proceeds uploading the configuration script prepared in the very first step, and lauching it execution. It perform a fix in the /etc/hosts file, asks for the password of the unique user (see the $VMusername variable), performs the localization, and updates the software packages, installing a bundle of packages excluded from cloud images and the tasksel tool, which is immediately launched

How to use the script

Preconditions: you have a Linux box with VirtualBox installed and at least an RSA public key available in $HOME/.ssh (if not, then it is time to generate it!).

Launch VirtualBox, next create a directory and download the script. Check if the variables fit your case, next launch it with

$ ./UbuntuMini.sh

After less than one minute (30" on my Lenovo Legion Laptop) a Virtual Terminal appears showing the boot sequence on the VM. Stay on the terminal from which you launched the script, and press return only when the Virtual Terminal shows the login screen.

You will be asked to confirm the connection to the VM (type yes) and, after a few seconds, to set the password for the user (twice).

After a few minutes (four on my laptop) of unattended operation you are presented with the tasksel dialog. Here you can select (up/down arrows and the space key to select) the bundles you want to install. Highlight the <ok> using the TAB key when finished. The installation will proceed, unattended. When finished, the control returns to the host computer. It is advisable to restart the VM before using it.

You can connect with the VM also using ssh password-less from a host terminal:

$ ssh -p 2222 user@localhost

replacing user with the username you indicated in the configuration step.

I have tried a few desktop installations, that are a valuable test since they need that the display manager and the rest are correctly installed, and they work fine. As a lightweight customizable desktop installation I suggest the Xubuntu minimal desktop, available from tasksel.

Enjoy :-)

#!/bin/bash
VMimage="https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.ova"
VMname="test"
VMhostname="vb-mini"
VMusername="user"
VMtimezone=`cat /etc/timezone`
VMlocale=`localectl | grep LANG | cut -f2 -d:`
VMkeyboard=`localectl | grep "X11 Layout" | cut -f2 -d:`
VMdir=$HOME"/VirtualBox VMs"
### DO NOT TOUCH AFTER THIS LINE (unless you know what you are doing)
#Prepare vm-config.sh script to be run on the new VM
echo "Prepare vm-config.sh script"
echo "#!/bin/bash" > vm-config.sh
echo "VMhostname=\"$VMhostname\"" >> vm-config.sh
echo "VMusername=\"$VMusername\"" >> vm-config.sh
echo "VMtimezone=\""`cat /etc/timezone`"\"" >> vm-config.sh
echo "VMlocale=\""`localectl | grep LANG | cut -f2 -d:`"\"" >> vm-config.sh
echo "VMkeyboard=\""`localectl | grep "X11 Layout" | cut -f2 -d:`"\"" >> vm-config.sh
cat >> vm-config.sh <<"EOF"
# Define colors
LGREEN='\033[1;32m'
NC='\033[0m' # No Color
echo -e "${LGREEN}*** Now running on $HOSTNAME${NC}"
echo -e "${LGREEN}*** Fixing /etc/hosts${NC}"
if ! grep $VMhostname -q /etc/hosts
then sed -i".bak" "/127\.0\.0\.1/ s/$/ ${VMhostname}/" /etc/hosts
fi
echo -e "${LGREEN}*** Configuring localization for "$HOSTNAME"....${NC}"
timedatectl set-timezone $VMtimezone
localectl set-locale $VMlocale
localectl set-keymap $VMkeyboard
echo -e "${LGREEN}*** Set password for $VMusername on "$HOSTNAME"....${NC}"
passwd $VMusername
echo -e "${LGREEN}*** Updating packages...${NC}"
apt update
apt -y upgrade
echo -e "${LGREEN}*** Installing extra packages...${NC}"
apt -y install linux-modules-extra-$(uname -r) tasksel
echo -e "${LGREEN}*** Installing VirtualBox guest additions...${NC}"
sudo apt -y install virtualbox-guest-additions-iso
sudo mount -o loop /usr/share/virtualbox/VBoxGuestAdditions.iso /media/
sudo /media/VBoxLinuxAdditions.run
echo -e "${LGREEN}*** Bundle package selection (with tasksel)...${NC}"
tasksel
echo -e "${LGREEN}*** Consider rebooting the VM before using${NC}"
EOF
# prepare the tools
sudo apt-get install cloud-image-utils
imgFile=`basename $VMimage`
echo $imgFile
# get the image
if [ ! -e $imgFile ]
then wget $VMimage
fi
VBoxManage import $imgFile --vsys 0 --vmname $VMname
VBoxManage modifyvm $VMname --nic1 nat # Set networking as NAT
VBoxManage modifyvm $VMname --natpf1 ,tcp,,2222,,22 # Enable port forwarding for ssh
VBoxManage storagectl $VMname --name Floppy --remove # Remove floppy driver
# Create the configuration DVD
cat > meta-data <<EOF
instance-id: ubuntu
local-hostname: $VMhostname
EOF
cat > user-data <<EOF
#cloud-config
users:
- name: $VMusername
sudo: ['ALL=(ALL) NOPASSWD:ALL']
shell: /bin/bash
EOF
echo " ssh_authorized_keys: " >> user-data
for f in ~/.ssh/*.pub
do
echo -n " - " >> user-data
cat $f >> user-data
done
# Password initialization not working... why?
#echo -n " passwd: " >> user-data
#cat >> user-data <<"EOF"
#...input from mkpasswd here
#EOF
cloud-localds ciconf.iso user-data meta-data
rm user-data meta-data
# Mount the configuration disk
VBoxManage storageattach $VMname --storagectl IDE --port 0 --device 0 --type dvddrive --medium ciconf.iso
VBoxManage startvm $VMname
echo "Type 'return' on *this* terminal when the login prompt appears on the VM terminal..."
read
ssh-keygen -f "/home/augusto/.ssh/known_hosts" -R "[localhost]:2222"
echo "Transfer the vmconfig.sh script"
scp -P 2222 vm-config.sh user@localhost:/tmp/
echo "Running the script on the VM"
ssh -tt -p 2222 $VMusername@localhost "sudo bash /tmp/vm-config.sh"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment