Growing the disk in a vagrant basebox #
2017-03-31
I love using vagrant when making big changes to my puppet code. It allows you to really easily start with a blank slate for each iteration. It gives me a reasonable amount of certainty that should^H^H^H when one my instances blow up, a single puppet pass will do everything needed to generate a new one.
So, today, I’m happily working away on a major restructure of some puppet code when I run into this error.
Error: Execution of '/usr/local/sbin/pkg install -qy javaservicewrapper' returned 3: pkg: Not enough space in /var/cache/pkg, needed 467 KiB available -100 KiB
Ah crap, I’ve run out of space in the vagrant instance. This basebox only has a 4GB root.
$ df -h
Filesystem Size Used Avail Capacity Mounted on
/dev/ada0p2 3.7G 3.4G -1.5M 100% /
I need to make a new basebox with more space. One option is to just create a brand new basebox from scratch. But, instead, I decide to try and resize the disk in this existing basebox.
First of all, I created a minimal Vagrantfile. I just want to spin up a new VM
based on my existing basebox image as a starting point so I run vagrant up
with this Vagrantfile.
Once the instance comes up, I stop it with the virtualbox cli. Note, the VM that the Vagrantfile created is called ‘basebox’.
$ VBoxManage controlvm basebox acpipowerbutton
Lets see how the disk look first.
$ VBoxManage showvminfo basebox | grep IDE
Storage Controller Name (0): IDE
IDE (0, 0): /home/chrskly/VirtualBox VMs/basebox/box-disk1.vmdk (UUID: ab38bc49-9e84-4635-9035-188038496198)
IDE (1, 0): Empty
The disk I want to resize is a vmdk. The virtualbox cli can’t resize vmdk images so we have to convert it to a vdi, grow it, then convert it back to a vmdk.
$ cd ~/VirtualBox\ VMs/basebox/
$ VBoxManage clonehd box-disk1.vmdk box-disk1.vdi --format vdi
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Clone medium created in format 'vdi'. UUID: c2eb30af-96b3-4224-b26f-232d9e382589
$ VBoxManage modifyhd box-disk1.vdi --resize 32768
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
$ VBoxManage clonehd box-disk1.vdi box-disk1-32gb.vmdk --format vmdk
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Clone medium created in format 'vmdk'. UUID: f8760621-d8bb-441f-a394-7509e26e5986
Now we have a clone of our disk image, only it’s 32GB instead of 4GB. We need to attach this disk to our VM.
$ VBoxManage storageattach basebox --storagectl "IDE" --device 0 --port 0 --type hdd --medium /home/chrskly/VirtualBox\ VMs/basebox/box-disk1-32gb.vmdk
$ VBoxManage showvminfo basebox | grep IDE
Storage Controller Name (0): IDE
IDE (0, 0): /home/chrskly/VirtualBox VMs/basebox/box-disk1-32gb.vmdk (UUID: f8760621-d8bb-441f-a394-7509e26e5986)
IDE (1, 0): Empty
Note that there is no detach command for vbox storage. To replace a disk, you attach the new disk to old device/port address. This kicks off the old disk.
Now I want to boot the instance into single user mode to resize the filesystem. Because I’m lazy and don’t want to walk into the next room, turn on a monitor and type a few commands there, I set up serial console access to the VM. First, I had a look at the serial port config for the VM.
$ VBoxManage showvminfo basebox | grep -i uart
UART 1: disabled
UART 2: disabled
UART 3: disabled
UART 4: disabled
The serial port is not enabled. We need to enable it.
$ VBoxManage modifyvm basebox --uart1 0x3F8 4
$ VBoxManage modifyvm basebox --uartmode1 server /tmp/basebox.raw
0x3F8 + IRQ4 is COM1. You can get more info on this in the virtualbox docs here: https://www.virtualbox.org/manual/ch08.html#vboxmanage-modifyvm-other https://www.virtualbox.org/manual/ch03.html#serialports
We then use socat to create a pty and connect to it with screen.
socat UNIX-CONNECT:/tmp/basebox.raw PTY,link=/tmp/basebox.pty &
screen /tmp/basebox.pty
When you boot your VM, you should now see console output in your screen session.
You may need to set console="comconsole"
in your /boot/loader.conf
in
your VM.
Press 2 for single user.
Now lets grow the disk from the OS-es perspective. We have a swap partition here that we need to delete temporarily while we grow the root partition.
# gpart show
=> 34 8388541 ada0 GPT (32G) [CORRUPT]
34 1024 1 freebsd-boot (512K)
1058 7965696 2 freebsd-ufs (3.8G)
7966754 419840 3 freebsd-swap (205M)
8386594 1981 - free - (991K)
# gpart recover ada0
ada0 recovered
# gpart show
=> 34 67108797 ada0 GPT (32G)
34 1024 1 freebsd-boot (512K)
1058 7965696 2 freebsd-ufs (3.8G)
7966754 419840 3 freebsd-swap (205M)
8386594 58722237 - free - (28G)
# gpart delete -i 3 ada0
ada0p3 deleted
# gpart show
=> 34 67108797 ada0 GPT (32G)
34 1024 1 freebsd-boot (512K)
1058 7965696 2 freebsd-ufs (3.8G)
7966754 59142077 - free - (28G)
# gpart resize -i 2 -s 31g ada0
ada0p2 resized
# gpart add -t freebsd-swap ada0
ada0p3 added
# gpart show
=> 34 67108797 ada0 GPT (32G)
34 1024 1 freebsd-boot (512K)
1058 65011712 2 freebsd-ufs (31G)
65012770 2096061 3 freebsd-swap (1.0G)
# growfs /dev/ada0p2
It's strongly recommended to make a backup before growing the file system.
OK to grow filesystem on /dev/ada0p2, mounted on /, from 3.8GB to 31GB? [Yes/No] yes
super-block backups (for fsck_ffs -b #) at:
8975872, 10258112, 11540352, 12822592, 14104832, 15387072, 16669312, 17951552,
19233792, 20516032, 21798272, 23080512, 24362752, 25644992, 26927232,
28209472, 29491712, 30773952, 32056192, 33338432, 34620672, 35902912,
37185152, 38467392, 39749632, 41031872, 42314112, 43596352, 44878592,
46160832, 47443072, 48725312, 50007552, 51289792, 52572032, 53854272,
55136512, 56418752, 57700992, 58983232, 60265472, 61547712, 62829952, 64112192
Time to reboot.
# reboot
Mar 31 22:59:27 init: single user shell terminated.
Waiting (max 60 seconds) for system process `vnlru' to stop...done
Waiting (max 60 seconds) for system process `bufdaemon' to stop...done
Waiting (max 60 seconds) for system process `syncer' to stop...
Syncing disks, vnodes remaining...0 0 0 0 0 0 0 0 0 0 done
All buffers synced.
Uptime: 56m7s
$ vagrant ssh
Last login: Fri Mar 31 22:02:36 2017 from 10.0.2.2
FreeBSD 10.3-RELEASE-p11 (GENERIC) #0: Mon Oct 24 18:49:24 UTC 2016
$ df -h
Filesystem Size Used Avail Capacity Mounted on
/dev/ada0p2 30G 2.5G 25G 9% /
devfs 1.0K 1.0K 0B 100% /dev
fdescfs 1.0K 1.0K 0B 100% /dev/fd
Excellent! We can now package our VM to make a new basebox and I can get back to my puppet code.
$ vagrant package basebox
==> basebox: Attempting graceful shutdown of VM...
==> basebox: Clearing any previously set forwarded ports...
==> basebox: Exporting VM...
==> basebox: Compressing package to: /home/chrskly/Code/basebox/package.box