How to automatically resize virtual box disk with vagrant

Kan Rangsan
4 min readJul 28, 2019

--

Background

I’m using vagrant on Windows with virtual box and CentOS 7 image. The vagrant box image I didn’t build it myself but get from people’s image here. The size of OS disk depends on its image. It’s configured at the the time when the image is created. I want in increase root partition from 10GB to 20GB. This guide won’t fit you if you build image yourself.

[root@node06 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 9.8G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 9.3G 0 part
├─centos-root 253:0 0 8.3G 0 lvm /
└─centos-swap 253:1 0 1000M 0 lvm [SWAP]

Test it

Let’s do it manually first. Test with hand then automate later. First we need to install the vagrant plugin that manage disk resizing by running> vagrant plugin install vagrant-disksize . Then set the disk size you wan in Vagrant file. For example

Vagrant.configure(2) do |config|
config.vm.box = "centos/7"
config.disksize.size = '20GB'
end

Run vagrant up . You’ll see the output as below. That means physical disk has been resized to 20GB.

Later, you need to resize partition table and file system which the command might be different depends on your environment (OS, file system ,etc…).

The image I use, mount root partition as LVM with xfs type. Below steps are how I extend root partition with parted command. Later I’ll use these steps in vagrant file to auto extend root mount point when run vagrant up.

  1. Check the physical disk size. Now it’s 20GB.
[root@node06 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 9.3G 0 part
├─centos-root 253:0 0 8.3G 0 lvm /
└─centos-swap 253:1 0 1000M 0 lvm [SWAP]

2. Change partition table using parted. Require version 3.1.29 above for a resize option.

### Check free size
$ sudo parted /dev/sda print free
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
32.3kB 1049kB 1016kB Free Space
1 1049kB 525MB 524MB primary xfs boot
2 525MB 10.5GB 9960MB primary lvm
10.5GB 21.5GB 11.0GB Free Space
### Resize to 100%
$ sudo parted /dev/sda resizepart 2 100%
### Check again
$ sudo parted /dev/sda print free
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
32.3kB 1049kB 1016kB Free Space
1 1049kB 525MB 524MB primary xfs boot
2 525MB 21.5GB 20.9GB primary lvm

3. Extend physical volume. You’ll see volume group has free PE.

$ sudo pvdisplay
--- Physical volume ---
PV Name /dev/sda2
VG Name centos
PV Size 9.28 GiB / not usable 3.00 MiB
Allocatable yes
PE Size 4.00 MiB
Total PE 2374
Free PE 10
Allocated PE 2364
$ sudo pvresize /dev/sda2
Physical volume "/dev/sda2" changed
1 physical volume(s) resized / 0 physical volume(s) not resized

$ sudo pvdisplay
--- Physical volume ---
PV Name /dev/sda2
VG Name centos
PV Size 19.51 GiB / not usable 2.00 MiB
Allocatable yes
PE Size 4.00 MiB
Total PE 4994
Free PE 2630
Allocated PE 2364
$ sudo vgdisplay
--- Volume group ---
VG Name centos
...
...
VG Size 19.51 GiB
PE Size 4.00 MiB
Total PE 4994
Alloc PE / Size 2364 / 9.23 GiB
Free PE / Size 2630 / 10.27 GiB

4. Extend logical group.

$ sudo lvdisplay
--- Logical volume ---
LV Path /dev/centos/root
LV Name root
VG Name centos
...
LV Size 8.26 GiB
Current LE 2114
...
$ sudo lvextend -l +100%FREE /dev/centos/root
Size of logical volume centos/root changed from 8.26 GiB (2114 extents) to 18.53 GiB (4744 extents).
Logical volume root successfully resized.

5. Resize root file system online. Now root mount point have the new size.

$ sudo xfs_growfs /dev/centos/root$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 19.5G 0 part
├─centos-root 253:0 0 18.5G 0 lvm /
└─centos-swap 253:1 0 1000M 0 lvm [SWAP]

Automate Part

Put all previous steps to Vagrant file. For me, I use the script inline method. Run vagrant up, have a cup of coffee then check the result. :)

Vagrant.configure(2) do |config|  common = <<-SCRIPT
sudo parted /dev/sda resizepart 2 100%
sudo pvresize /dev/sda2
sudo lvextend -l +100%FREE /dev/centos/root
sudo xfs_growfs /dev/centos/root
SCRIPT
config.vm.define "node01" do |node1|
node1.vm.hostname = "node01"
node1.vm.network "private_network", ip: "192.168.56.121"
config.vm.provision :shell, :inline => common
end
end

--

--