Resize a Hard Disk for a Virtual Machine
The repository below resizes the vagrant box automatically, and I prefer this way.
https://github.com/SydOps/vagrant-box-resize
Here are the manual tasks with my updates and fork from christopher-hopper/vm-resize-hard-disk.md. But one issue is, after I manually resize, I found I can't use packer to re-baker vagrant box again.
Our Virtual Machines are provisioned using Vagrant from a Linux base box to run using VirutalBox. If the Hard Disk space runs out and you cannot remove files to free-up space, you can resize the Hard Disk using some VirtualBox and Linux commands.
The following steps assume you've got a set-up like mine, where:
provisioning/boxes/mybox
HOME
path is the same as your Windows %USERPROFILE%
(see How do I change my Cygwin HOME folder after installation)~/VirtualBox\ VMs/
Stop the virtual machine using Vagrant.
# cd provisioning/boxes/mybox
# vagrant halt
Locate the VirtuaBox VM and the HDD attached to its SATA Controller. In this instance we're assuming the VM is located in the default location and is named mybox_default_1382400620
.
# cd ~/VirtualBox\ VMs/mybox_default_1382400620
# vboxmanage list vms |awk -F \" 'END{print $2}'
# VBoxManage showvminfo mybox_default_1382400620 | grep ".vmdk"
The showvminfo
command should show you the location on the file-system of the HDD of type VMDK along with the name of the Controller it is attached to - it will look something like this:
SATA Controller (0, 0): C:\Users\user.name\VirtualBox VMs\mybox_default_1382400620\box-disk1.vmdk (UUID: 2f79610e-6c06-46d5-becb-448386ea40ec)
clone the VMDK type disk to a VDI type disk so it can be resized.
# cd ~/VirtualBox\ VMs/mybox_default_1382400620
# VBoxManage clonehd "box-disk1.vmdk" "clone-disk1.vdi" --format vdi
NOTE: We do this because VMDK type disks cannot be resized by VirtualBox. It has the added benefit of allowing us to keep our original disk backed-up during the resize operation.
NOTE: Give the full path for vmdk file, so in this sample, the command should be updated as below
VBoxManage clonehd " ~/VirtualBox\ VMs/mybox_default_1382400620/box-disk1.vmdk" "clone-disk1.vdi" --format vdi
NOTE: Otherwise, you will get errors:
VBoxManage: error: Cannot register the hard disk 'xxxxxxxxxx.vmdk' {3b16a523-1637-45fe-ae4f-0b6c78736ba5} because a hard disk 'xxxxxxxxx.vmdk' with UUID {3b16a523-1637-45fe-ae4f-0b6c78736ba5} already exists
VBoxManage: error: Details: code NS_ERROR_INVALID_ARG (0x80070057), component VirtualBox, interface IVirtualBox, callee nsISupports
VBoxManage: error: Context: "OpenMedium(Bstr(pszFilenameOrUuid).raw(), enmDevType, enmAccessMode, fForceNewUuidOnOpen, pMedium.asOutParam())" at line 178 of file VBoxManageDisk.cpp
Find out how big the disk is currently, to determine how large to make it when resized. The information will show the current size and the Format variant. If Dynamic Allocation was used to create the disk, the Format variant will be "dynamic default".
# VboxManage showhdinfo "clone-disk1.vdi" |grep Capacity
Resize the cloned disk to give it more space. The size argument below is given in Megabytes (1024 Bytes = 1 Megabyte). Because this disk was created using dynamic allocation I'm going to resize it to 30GB.
# VBoxManage modifyhd "clone-disk1.vdi" --resize 30720
# VboxManage showhdinfo "clone-disk1.vdi"|grep Capacity
Capacity: 30720 MBytes
_NOTE: reduce from 1TB to 30GB to save the time when run resize2fs
NOTE: If the disk was created using dynamic allocation (see previous step) then the physical size of the disk will not need to match its logical size - meaning you can create a very large logical disk that will increase in physical size only as space is used.
Find out the name of the SATA Storage Controller to attach the newly resized disk to.
# VBoxManage showvminfo mybox_default_1382400620 | grep "Storage"
Attach the newly resized disk to the SATA Controller of the Virtual Machine.
# VBoxManage storageattach mybox_default_1382400620 --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium clone-disk1.vdi
or (IDE Controller)
# VBoxManage storageattach mybox_default_1382400620 --storagectl "IDE Controller" --port 0 --device 0 --type hdd --medium clone-disk1.vdi
Reboot the Virtual Machine using Vagrant.
# cd provisioning/boxes/mybox
# vagrant up
Open a command-line shell as root on the Virtual Machine via ssh.
# vagrant ssh
# sudo su -
Find the name of the logical volume mapping the file-system is on (ie. /dev/mapper/VolGroupOS-lv_root
).
# df
Find the name of the physical volume (or device) that all the partitions are created on (ie. /dev/sda
).
# fdisk -l
Create a new primary partition for use as a Linux LVM
# fdisk /dev/sda
p
to print the partition table to identify the number of partitions. By default there are two - sda1
and sda2
.n
to create a new primary partition.p
for primary.3
for the partition number, depending the output of the partition table print.t
to change the system's partition ID3
to select the newly creation partition8e
to change the Hex Code of the partition for Linux LVM
w
to write the changes to the partition table.Reboot the machine, then ssh back in when it is up again and switch to the root user once more.
# reboot
# vagrant ssh
# sudo su -
Create a new physical volume using the new primary partition just created.
# pvcreate /dev/sda3
Find out the name of the Volume Group that the Logical Volume mapping belongs to (ie. VolGroupOS
).
# vgdisplay
_NOTE: if you get " No volume groups found", run vgscan
or pvscan
Extend the Volume Group to use the newly created physical volume.
# vgextend VolGroupOS /dev/sda3
Extend the logical volume to use more of the Volume Group size now available to it. You can either tell it to use all the space available on the Volume Group: (check by ls /dev/mapper
)
# lvextend -l +100%FREE /dev/mapper/VolGroupOS-lv_root
Or, if you want to control the growth of the Disk, extend it to add a set amount of space in Megabytes, Gigabytes or Terabytes:
# lvextend -L+20G /dev/mapper/VolGroupOS-lv_root
Resize the file-system to use up the space made available in the Logical Volume
# resize2fs /dev/mapper/VolGroupOS-lv_root
Verfiy that there is now more space available
# df -h
A restart of the VM using vagrant may be a good idea here, to ensure that all services are running correctly now that there is more space available. Exit the root user, exit the vagrant user and ssh session, then tell vagrant to restart the machine.
# exit
# exit
# vagrant reload --provision
Finally, don't forget to package it
cd provisioning/boxes/mybox
vagrant package