Skip to content

Commit

Permalink
Refactor mounting iso to CD-ROM
Browse files Browse the repository at this point in the history
Signed-off-by: Josh Barker <[email protected]>
  • Loading branch information
josh-barker authored and Josh Barker committed Jun 3, 2018
1 parent bd58d73 commit a51d338
Show file tree
Hide file tree
Showing 3 changed files with 215 additions and 25 deletions.
26 changes: 1 addition & 25 deletions lib/chef/provisioning/vsphere_driver/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -689,31 +689,7 @@ def clone_vm(action_handler, bootstrap_options, machine_spec)

vsphere_helper.update_main_disk_size_for(vm, bootstrap_options[:main_disk_size_gb])
vsphere_helper.set_additional_disks_for(vm, bootstrap_options[:datastore], bootstrap_options[:additional_disk_size_gb])

if bootstrap_options[:initial_iso_image]
d_obj = vm.config.hardware.device.select {|hw| hw.class == RbVmomi::VIM::VirtualCdrom}.first
backing = RbVmomi::VIM::VirtualCdromIsoBackingInfo(fileName: bootstrap_options[:initial_iso_image])
task = vm.ReconfigVM_Task(
spec: RbVmomi::VIM.VirtualMachineConfigSpec(
deviceChange: [
operation: :edit,
device: RbVmomi::VIM::VirtualCdrom(
backing: backing,
key: d_obj.key,
controllerKey: d_obj.controllerKey,
connectable: RbVmomi::VIM::VirtualDeviceConnectInfo(
startConnected: true,
connected: true,

allowGuestControl: true
)

)
]
)
)
task.wait_for_completion
end
vsphere_helper.set_initial_iso(vm, bootstrap_options[:initial_iso_file])

vm
end
Expand Down
31 changes: 31 additions & 0 deletions lib/chef/provisioning/vsphere_driver/vsphere_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,37 @@ def set_additional_disks_for(vm, datastore, additional_disk_size_gb)
end
end

# Mounts the an iso on the first virtual CD ROm
#
# @param [Object] vm the VM object.
# @param [Subject] name of the iso file
def set_initial_iso(vm, initial_iso_image)
return unless initial_iso_image

d_obj = vm.config.hardware.device.select { |hw| hw.class == RbVmomi::VIM::VirtualCdrom }.first
backing = RbVmomi::VIM::VirtualCdromIsoBackingInfo(fileName: initial_iso_image)

task = vm.ReconfigVM_Task(
spec: RbVmomi::VIM.VirtualMachineConfigSpec(
deviceChange: [
operation: :edit,
device: RbVmomi::VIM::VirtualCdrom(
backing: backing,
key: d_obj.key,
controllerKey: d_obj.controllerKey,
connectable: RbVmomi::VIM::VirtualDeviceConnectInfo(
startConnected: true,
connected: true,

allowGuestControl: true
)
)
]
)
)
task.wait_for_completion
end

# Updates the main virtual disk for the VM
# This can only add capacity to the main disk, it is not possible to reduce the capacity.
#
Expand Down
183 changes: 183 additions & 0 deletions spec/unit_tests/vsphere_helpers_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
require 'chef/provisioning/vsphere_driver'

describe ChefProvisioningVsphere::VsphereHelper do
let(:subject) do
connection_opts = {
host: 'fake.host.com',
port: 443
}
ChefProvisioningVsphere::VsphereHelper.new(connection_opts, 'fake datacenter')
end
let(:vm) { vm = double('vm') }
let(:task) { double('task', wait_for_completion: true) }

describe '#set_additional_disks_for' do
before do
allow(vm).to receive(:disks).and_return(['root_disk'], ['root_disk', 'first_disk'])
end

context 'when datastore is missing' do
let(:datastore) { nil }
it 'and no extra disks, nothing is raised' do
additional_disk_size_gb = nil
expect { subject.set_additional_disks_for vm, datastore, additional_disk_size_gb }.not_to raise_error
end

it 'and has 1 disk, error is raised' do
additional_disk_size_gb = 1
expect { subject.set_additional_disks_for vm, datastore, additional_disk_size_gb }.to raise_error(RuntimeError)
end

it 'and has multiple disks, error is raised' do
additional_disk_size_gb = [1, 2]
expect { subject.set_additional_disks_for vm, datastore, additional_disk_size_gb }.to raise_error(RuntimeError)
end
end

context 'when datastore is present' do
let(:datastore) { 'some datastore' }
let(:disk_1) do
{
spec: RbVmomi::VIM.VirtualMachineConfigSpec(
deviceChange: [
RbVmomi::VIM::VirtualDeviceConfigSpec(
operation: :add,
fileOperation: :create,
device: RbVmomi::VIM.VirtualDisk(
key: 1,
backing: RbVmomi::VIM.VirtualDiskFlatVer2BackingInfo(
fileName: "[#{datastore}]",
diskMode: 'persistent',
thinProvisioned: true
),
capacityInKB: 1 * 1024 * 1024,
controllerKey: 1000,
unitNumber: 1
)
)
]
)
}
end

let(:disk_2) do
{
spec: RbVmomi::VIM.VirtualMachineConfigSpec(
deviceChange: [
RbVmomi::VIM::VirtualDeviceConfigSpec(
operation: :add,
fileOperation: :create,
device: RbVmomi::VIM.VirtualDisk(
key: 2,
backing: RbVmomi::VIM.VirtualDiskFlatVer2BackingInfo(
fileName: "[#{datastore}]",
diskMode: 'persistent',
thinProvisioned: true
),
capacityInKB: 2 * 1024 * 1024,
controllerKey: 1000,
unitNumber: 2
)
)
]
)
}
end

it 'and no extra disks, nothing is created' do
additional_disk_size_gb = nil
expect(vm).not_to receive(:ReconfigVM_Task)
subject.set_additional_disks_for vm, datastore, additional_disk_size_gb
end

it 'and disk is a string, nothing is created' do
additional_disk_size_gb = ['not a number']
expect(vm).not_to receive(:ReconfigVM_Task)
subject.set_additional_disks_for vm, datastore, additional_disk_size_gb
end

it 'and has 0 GB, nothing is created' do
additional_disk_size_gb = [0]
expect(vm).not_to receive(:ReconfigVM_Task)
subject.set_additional_disks_for vm, datastore, additional_disk_size_gb
end

it 'and has -1 GB, nothing is created' do
additional_disk_size_gb = [-1]
expect(vm).not_to receive(:ReconfigVM_Task)
subject.set_additional_disks_for vm, datastore, additional_disk_size_gb
end

it 'and has 1 x 1 GB, create disk' do
additional_disk_size_gb = 1
expect(vm).to receive(:ReconfigVM_Task).with(disk_1).and_return(task)
subject.set_additional_disks_for vm, datastore, additional_disk_size_gb
end

it 'and has 2 disks, create 2 disks' do
additional_disk_size_gb = [1, 2]

expect(vm).to receive(:ReconfigVM_Task).with(disk_1).and_return(task)
expect(vm).to receive(:ReconfigVM_Task).with(disk_2).and_return(task)
subject.set_additional_disks_for vm, datastore, additional_disk_size_gb
end

it 'and has 3 disks, including 1 of 0 size, create 2 disks' do
additional_disk_size_gb = [0, 1, 2]
expect(vm).to receive(:ReconfigVM_Task).with(disk_1).and_return(task)
expect(vm).to receive(:ReconfigVM_Task).with(disk_2).and_return(task)

subject.set_additional_disks_for vm, datastore, additional_disk_size_gb
end
end
end

describe '#set_initial_iso' do
let(:cd_rom) do
double('cd_rom',
class: RbVmomi::VIM::VirtualCdrom,
key: 'some key',
controllerKey: 'some controller key'
)
end

let(:fake_backing) do
RbVmomi::VIM::VirtualCdromIsoBackingInfo(fileName: 'some_iso.iso')
end

let(:iso_spec) do
{
spec: RbVmomi::VIM.VirtualMachineConfigSpec(
deviceChange: [
operation: :edit,
device: RbVmomi::VIM::VirtualCdrom(
backing: fake_backing,
key: 'some key',
controllerKey: 'some controller key',
connectable: RbVmomi::VIM::VirtualDeviceConnectInfo(
startConnected: true,
connected: true,
allowGuestControl: true
)
)
]
)
}
end

before do
allow(vm).to receive_message_chain(:config, :hardware, :device)
.and_return([cd_rom])
end

it 'does nothing when no iso' do
expect(vm).not_to receive(:ReconfigVM_Task)
subject.set_initial_iso vm, nil
end

it 'sets initial iso' do
expect(vm).to receive(:ReconfigVM_Task).with(iso_spec).and_return(task)
subject.set_initial_iso vm, 'some_iso.iso'
end
end
end

0 comments on commit a51d338

Please sign in to comment.