Skip to content

Instantly share code, notes, and snippets.

@DonRichards
Forked from ogero/expand_disk.py
Last active February 4, 2020 16:07
Show Gist options
  • Save DonRichards/6dc6c81ae9fc22cba8d7a57b90ab1509 to your computer and use it in GitHub Desktop.
Save DonRichards/6dc6c81ae9fc22cba8d7a57b90ab1509 to your computer and use it in GitHub Desktop.
Python script to expand VirtualBox VMDK disk (created to expand vagrant boxes using VB provider) for Islandora 8 VM
import subprocess,re,os,random,string,sys,fileinput
from sys import platform as _platform
from time import sleep
# VirtualBox disk resize tool is forked from
# Author: Geronimo Onativia ([email protected])
# Some ideas taken from
# https://github.com/mitchellh/vagrant/issues/2339#issuecomment-230839878
# http://stackoverflow.com/a/31177761/13116
DEFAULT_DISK = "ubuntu-bionic-18.04-cloudimg.vmdk"
DEFAULT_VM_NAME = "Islandora 8 Ansible"
DEFAULT_RESIZED_MARK = "_resized"
DEFAULT_DISK_SIZE_MB = 12288
RND = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(5))
def run_command(command):
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
# Read stdout from subprocess until the buffer is empty !
for line in iter(p.stdout.readline, b''):
if line: # Don't print blank lines
yield line
# This ensures the process has completed, AND sets the 'returncode' attr
while p.poll() is None:
sleep(.1) #Don't waste CPU-cycles
# Empty STDERR buffer
err = p.stderr.read()
if p.returncode != 0:
# The run_command() function is responsible for logging STDERR
print "Error: " + err
def touch(fname, times=None):
with open(fname, 'a'):
os.utime(fname, times)
def find_in_file(filename, pattern):
p = re.compile(pattern)
for i, line in enumerate(open(filename)):
for match in re.finditer(pattern, line):
return match.groups()[0]
return ""
print "Beware that your VM must have a name set via Vagrantfile."
vm_name = raw_input('Enter name given to vm [Islandora 8 Ansible]: ')
if not vm_name:
vm_name = DEFAULT_VM_NAME
disk_size = raw_input("Enter new disk size in MB ["+str(DEFAULT_DISK_SIZE_MB)+"]: ")
if not disk_size:
disk_size = DEFAULT_DISK_SIZE_MB
if _platform == "linux" or _platform == "linux2" or _platform == "darwin":
vb_machine_folder_cmd='VBoxManage list systemproperties | grep "Default machine folder"'
elif _platform == "win32":
vb_machine_folder_cmd='VBoxManage list systemproperties | findstr "Default\\ machine\\ folder"'
output = subprocess.check_output(vb_machine_folder_cmd, shell=True)
vb_machines_folder = re.split(':\s+', output)[1].strip()
vb_machine_resized = os.path.join(vb_machines_folder, vm_name+DEFAULT_RESIZED_MARK)
vb_machine_folder = os.path.join(vb_machines_folder, vm_name)
vb_machine_disk = os.path.join(vb_machine_folder, DEFAULT_DISK)
vb_machine_vbox = os.path.join(vb_machine_folder, vm_name+".vbox")
if os.path.isdir(vb_machine_folder):
if os.path.exists(vb_machine_disk):
old_disk_size=os.stat(vb_machine_disk).st_size
if old_disk_size<(float(disk_size)*1000*1000*0.99) and not os.path.exists(vb_machine_resized):
print "Resize needed as size is " + str(int(old_disk_size/float(1000*1000)))+"MB < "+str(disk_size)+"MB"
tmp1 = os.path.join(vb_machine_folder, RND+"_tmp1")
tmp2 = os.path.join(vb_machine_folder, RND+"_tmp2")
uuid = find_in_file(vb_machine_vbox,"HardDisk uuid=\"{([\w-]+)}\"")
print "Got current disk UUID "+uuid
command = "VBoxManage clonemedium disk \"" + vb_machine_disk + "\" \"" + tmp1 + "\" --format vdi"
print ">"+command
for line in run_command(command):
print line
command = "VBoxManage modifyhd \"" + tmp1 + "\" --resize "+str(disk_size)
print ">"+command
for line in run_command(command):
print line
command = "VBoxManage clonemedium disk \"" + tmp1 + "\" \"" + tmp2 + "\" --format vmdk"
print ">"+command
for line in run_command(command):
print line
if os.path.exists(tmp2) and os.path.exists(tmp1):
os.remove(tmp1)
os.remove(vb_machine_disk)
os.rename(tmp2,vb_machine_disk)
print "Re-setting UUID for the new disk"
command = "VBoxManage internalcommands sethduuid \"" + vb_machine_disk + "\" "+uuid
print ">"+command
for line in run_command(command):
print line
touch(vb_machine_resized)
print "VMDK Expanded Successfully!!"
print "Now run this commands to allow sda1 to take new available space:"
print "vagrant up --no-provision"
print "vagrant ssh --command \"sudo resize2fs /dev/sda1\""
print "vagrant provision"
else:
print "Failed to expand to "+str(disk_size)+" the disk "+vb_machine_disk
if os.path.exists(tmp2):
os.remove(tmp2)
if os.path.exists(tmp1):
os.remove(tmp1)
else:
print "Resize not needed as size is " + str(int(old_disk_size/float(1000*1000)))+"MB > "+str(disk_size)+"MB or file "+vm_name+DEFAULT_RESIZED_MARK+" already exists at "+vb_machines_folder
else:
print "Not a file! > "+vb_machine_disk
else:
print "Not a dir! > "+vb_machine_folder
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment