Skip to content

Instantly share code, notes, and snippets.

@dazza-codes
Created September 27, 2015 08:24
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save dazza-codes/f8974d361d3683c3f05c to your computer and use it in GitHub Desktop.
Save dazza-codes/f8974d361d3683c3f05c to your computer and use it in GitHub Desktop.
Utilities to add an independent data disk to virtualbox vms using vagrant
# -*- mode: ruby -*-
# vi: set ft=ruby :
VM_NAME ||= ENV['VM_NAME'] || "ubuntu1404-dev"
HOME = ENV['HOME']
DATA_DISK_PATH = "#{HOME}/VirtualDisks"
FileUtils.mkdir_p DATA_DISK_PATH
DATA_DISK_FILE = "#{DATA_DISK_PATH}/data_disk.vmdk"
DATA_DISK_FORMAT = 'VMDK'
DATA_DISK_SIZE = 500 * 1024
def vbox_manage?
@vbox_manage ||= ! `which VBoxManage`.chomp.empty?
end
def vm_boxes
boxes = {}
if vbox_manage?
vms = `VBoxManage list vms`
vms.split("\n").each do |vm|
x = vm.split
k = x[0].gsub('"','') # vm name
v = x[1].gsub(/[{}]/,'') # vm UUID
boxes[k] = v
end
end
boxes
end
def vm_exists?
vm_boxes[VM_NAME] ? true : false
end
def vm_info
vm_exists? ? `VBoxManage showvminfo #{VM_NAME}` : ''
end
def vm_uuid
vm_boxes[VM_NAME]
end
def vm_state
case vm_exists?
when true
vm_state = vm_info.split("\n").select {|f| f =~ /^State:/}.first || ''
vm_state.split[1]
when false
''
end
end
def vm_running?
vm_state == "running"
end
def vm_start
case vm_exists?
when true
cmd = "VBoxManage startvm #{VM_NAME}"
vm_running? ? true : system(cmd)
when false
false
end
end
def vm_stop
case vm_exists?
when true
cmd = "VBoxManage controlvm #{VM_NAME} poweroff"
vm_running? ? system(cmd) : true
when false
# it is 'stopped' if it doesn't exist, but
# this return value is the status of this operation.
false
end
end
# Try to identify the data disk UUID;
# this can be done whether the vm exists or not.
def data_disk_uuid
@data_disk_uuid ||= begin
data_disk_uuid = nil
if vbox_manage? && data_disk_created?
hdds = `VBoxManage list hdds`.split("\n\n")
hd = hdds.select {|d| d =~ /#{DATA_DISK_FILE}/ }
if hd.length == 1
fields = hd.first.split("\n")
uuid = fields.select {|f| f =~ /^UUID:/ }.first
data_disk_uuid = uuid.split[1]
end
end
data_disk_uuid
end
end
# Is the data disk attached to the vm?
def data_disk_attached?
vm_info =~ /#{DATA_DISK_FILE}/ ? true : false
end
# Try to attach data disk, if necessary
def data_disk_attach
data_disk_create
if vm_exists? && ! data_disk_attached?
vm_stop
cmd = [
'VBoxManage storageattach ' + vm_uuid,
'--storagectl "SATA Controller"',
'--port 1',
'--device 0',
'--type hdd',
'--medium ', DATA_DISK_FILE
].join(' ')
if system(cmd)
puts 'Attached virtual data disk:'
puts "File: #{DATA_DISK_FILE}"
puts "UUID: #{data_disk_uuid}"
end
end
end
# Try to detach data disk
def data_disk_detach
vm_stop
if vm_exists? && data_disk_attached?
cmd = [
'VBoxManage storageattach ' + vm_uuid,
'--storagectl "SATA Controller"',
'--port 1',
'--device 0',
'--type hdd',
'--medium none'
].join(' ')
if system(cmd) && ! data_disk_attached?
puts 'Detached virtual data disk:'
puts "File: #{DATA_DISK_FILE}"
end
end
! data_disk_attached?
end
# Does the data disk exist?
def data_disk_created?
File.exist?(DATA_DISK_FILE)
end
# Try to identify the data disk UUID
def data_disk_create
if ! data_disk_created? && vbox_manage?
cmd = [
'VBoxManage createhd',
'--filename ' + DATA_DISK_FILE,
'--format ' + DATA_DISK_FORMAT,
'--size ' + DATA_DISK_SIZE.to_s
].join(' ')
if system(cmd) && data_disk_created?
puts 'Created virtual data disk:'
puts "File: #{DATA_DISK_FILE}"
puts "UUID: #{data_disk_uuid}"
puts "SIZE: #{DATA_DISK_SIZE}"
end
end
data_disk_created?
end
#!/bin/bash
# partition the data disk
disks=$(ls /dev/sd?)
for d in $disks; do
partition_count=$(ls $d* | wc -l)
if [ $partition_count -eq 1 ]; then
# confirm that no device UUID exists for this disk
dev_count=$(sudo blkid | grep -c "$d")
if [ $dev_count -eq 0 ]; then
echo "partition disk $d"
sudo parted $d mklabel msdos
sudo parted -a optimal $d mkpart primary ext4 0% 100%
dev="${d}1"
echo "format $dev"
sudo mkfs.ext4 -L DATA $dev
fi
fi
done
disks=$(ls /dev/sdb)
for d in $disks; do
partition_count=$(ls $d* | wc -l)
if [ $partition_count -eq 2 ]; then
dev="${d}1"
dev_uuid=$(sudo blkid $dev | sed -e 's/.*UUID="//g' -e 's/".*//g')
fstab_count=$(grep -c "$dev_uuid" /etc/fstab)
if [ $fstab_count -eq 0 ]; then
echo "mount $dev to /data"
sudo mkdir -p /data
echo "UUID=$dev_uuid /data ext4 defaults 0 0" | cat /etc/fstab - > /tmp/fstab.tmp
sudo mv /tmp/fstab.tmp /etc/fstab
sudo mount /data
fi
fi
done
# -*- mode: ruby -*-
# vi: set ft=ruby :
# This vagrant script relies on
# vagrant plugin install vagrant-triggers
VM_NAME = "vbox-dev"
VM_CPUS = 1
VM_MEMORY = 2 * 1024 # in MB
require_relative 'data_disk'
Vagrant.configure(2) do |config|
# Every Vagrant development environment requires a box. You can search for
# boxes at https://atlas.hashicorp.com/search. This one is an Ubuntu LTS.
config.vm.box = "boxcutter/ubuntu1404-desktop"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# View the documentation for the provider you are using for more
# information on available options; e.g.
# https://docs.vagrantup.com/v2/virtualbox/configuration.html
# http://www.virtualbox.org/manual/ch08.html
config.vm.provider "virtualbox" do |v|
v.gui = true
v.name = VM_NAME
v.cpus = VM_CPUS
v.memory = VM_MEMORY # MB
end
# Triggers, depends on:
# vagrant plugin install vagrant-triggers
config.trigger.before :up do
data_disk_attach
end
config.trigger.before :destroy do
data_disk_detach
end
config.vm.provision "shell", path: 'data_disk_setup.sh'
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment