Skip to content

Commit

Permalink
Add support for reconfigure cdrom
Browse files Browse the repository at this point in the history
  • Loading branch information
agrare committed Apr 30, 2018
1 parent b14b2f3 commit b0bb49d
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 12 deletions.
2 changes: 1 addition & 1 deletion app/models/manageiq/providers/vmware/infra_manager/vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ class ManageIQ::Providers::Vmware::InfraManager::Vm < ManageIQ::Providers::Infra

supports :reconfigure_disks
supports :reconfigure_network_adapters

supports :reconfigure_disksize
supports :reconfigure_cdroms

def add_miq_alarm
raise "VM has no EMS, unable to add alarm" unless ext_management_system
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,19 @@ def build_config_spec(options)
set_spec_option(vmcs, :memoryMB, options[:vm_memory], :to_i)
set_spec_option(vmcs, :numCPUs, options[:number_of_cpus], :to_i)

if options[:disk_remove] || options[:disk_add] || options[:disk_resize] || options[:network_adapter_add] || options[:network_adapter_remove]
if options_requiring_connection.any? { |key| options.key?(key) }
with_provider_object do |vim_obj|
hardware = vim_obj.getHardware

remove_disks(vim_obj, vmcs, hardware, options[:disk_remove]) if options[:disk_remove]
resize_disks(vim_obj, vmcs, hardware, options[:disk_resize]) if options[:disk_resize]
add_disks(vim_obj, vmcs, hardware, options[:disk_add]) if options[:disk_add]
remove_network_adapters(vim_obj, vmcs, options[:network_adapter_remove]) if options[:network_adapter_remove]
add_network_adapters(vmcs, options[:network_adapter_add]) if options[:network_adapter_add]

remove_network_adapters(vim_obj, vmcs, hardware, options[:network_adapter_remove]) if options[:network_adapter_remove]
add_network_adapters(vim_obj, vmcs, hardware, options[:network_adapter_add]) if options[:network_adapter_add]

connect_cdroms(vim_obj, vmcs, hardware, options[:cdrom_connect]) if options[:cdrom_connect]
disconnect_cdroms(vim_obj, vmcs, hardware, options[:cdrom_disconnect]) if options[:cdrom_disconnect]
end
end
end
Expand Down Expand Up @@ -151,18 +155,26 @@ def add_disks(vim_obj, vmcs, hardware, disks)
end
end

def remove_network_adapters(vim_obj, vmcs, network_adapters)
def remove_network_adapters(vim_obj, vmcs, hardware, network_adapters)
network_adapters.each do |n|
remove_network_adapter_config_spec(vim_obj, vmcs, n)
remove_network_adapter_config_spec(vim_obj, vmcs, hardware, n)
end
end

def add_network_adapters(vmcs, network_adapters)
def add_network_adapters(vim_obj, vmcs, hardware, network_adapters)
network_adapters.each do |n|
add_network_adapter_config_spec(vmcs, n)
add_network_adapter_config_spec(vim_obj, vmcs, hardware, n)
end
end

def connect_cdroms(vim_obj, vmcs, hardware, cdroms)
cdroms.each { |cdrom| connect_cdrom_config_spec(vim_obj, vmcs, hardware, cdrom) }
end

def disconnect_cdroms(vim_obj, vmcs, hardware, cdroms)
cdroms.each { |cdrom| disconnect_cdrom_config_spec(vim_obj, vmcs, hardware, cdrom) }
end

def scsi_controller_units(controller_key)
[*0..6, *8..15].each.collect do |unit_number|
[controller_key, unit_number]
Expand Down Expand Up @@ -260,7 +272,7 @@ def add_disk_config_spec(vmcs, options)
end
end

def add_network_adapter_config_spec(vmcs, options)
def add_network_adapter_config_spec(_vim, vmcs, _hardware, options)
add_device_config_spec(vmcs, VirtualDeviceConfigSpecOperation::Add) do |vdcs|
vdcs.device = VimHash.new("VirtualVmxnet3") do |dev|
dev.key = next_device_idx # negative integer as temporary key
Expand Down Expand Up @@ -332,10 +344,10 @@ def resize_disk_config_spec(vim_obj, vmcs, hardware, options)
end
end

def remove_network_adapter_config_spec(vim_obj, vmcs, options)
def remove_network_adapter_config_spec(vim_obj, vmcs, hardware, options)
raise "remove_network_adapter_config_spec: network_adapter name is required." unless options[:network][:name]
network_adapter_label = options[:network][:name]
controller_key, key, unit_number = vim_obj.send(:getDeviceKeysByLabel, network_adapter_label)
controller_key, key, unit_number = vim_obj.send(:getDeviceKeysByLabel, network_adapter_label, hardware)
add_device_config_spec(vmcs, VirtualDeviceConfigSpecOperation::Remove) do |vdcs|
vdcs.device = VimHash.new("VirtualEthernetCard") do |dev|
dev.key = key
Expand All @@ -345,6 +357,40 @@ def remove_network_adapter_config_spec(vim_obj, vmcs, options)
end
end

def connect_cdrom_config_spec(vim_obj, vmcs, hardware, cdrom)
device = vim_obj.send(:getDeviceByLabel, cdrom[:device_name], hardware)
raise "connect_cdrom_config_spec: no virtual device associated with: #{cdrom[:device_name]}" unless device

datastore_ref = HostStorage.find_by(:storage_id => cdrom[:storage_id], :host_id => host.id).try(:ems_ref)
raise "connect_cdrom_config_spec: could not find datastore reference for storage ID [#{cdrom[:storage_id]}] and host ID [#{host.id}]" unless datastore_ref

add_device_config_spec(vmcs, VirtualDeviceConfigSpecOperation::Edit) do |vdcs|
device.backing = VimHash.new("VirtualCdromIsoBackingInfo") do |backing|
backing.datastore = datastore_ref
backing.fileName = cdrom[:filename]
end

device.connectable.startConnected = true

vdcs.device = device
end
end

def disconnect_cdrom_config_spec(vim_obj, vmcs, hardware, cdrom)
device = vim_obj.send(:getDeviceByLabel, cdrom[:device_name], hardware)
raise "disconnect_cdrom_config_spec: no virtual device associated with: #{cdrom[:device_name]}" unless device

add_device_config_spec(vmcs, VirtualDeviceConfigSpecOperation::Edit) do |vdcs|
device.backing = VimHash.new("VirtualCdromRemoteAtapiBackingInfo") do |backing|
backing.deviceName = ""
end

device.connectable.startConnected = false

vdcs.device = device
end
end

def add_device_config_spec(vmcs, operation)
vmcs_vca = vmcs.deviceChange ||= VimArray.new('ArrayOfVirtualDeviceConfigSpec')
vmcs_vca << VimHash.new('VirtualDeviceConfigSpec') do |vdcs|
Expand Down Expand Up @@ -375,4 +421,8 @@ def next_device_idx
@new_device_idx ||= -100
@new_device_idx -= 1
end

def options_requiring_connection
%i(disk_remove disk_add disk_resize network_adapter_add network_adapter_remove cdrom_connect cdrom_disconnect)
end
end
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
describe ManageIQ::Providers::Vmware::InfraManager::Vm::Reconfigure do
let(:storage) { FactoryGirl.create(:storage_vmware) }
let(:host) do
FactoryGirl.create(:host_vmware_esx).tap do |host|
host.host_storages.create(:storage_id => storage.id, :host_id => host.id, :ems_ref => "datastore-1")
end
end
let(:vm) do
FactoryGirl.create(
:vm_vmware,
:name => 'test_vm',
:raw_power_state => 'poweredOff',
:storage => FactoryGirl.create(:storage, :name => 'storage'),
:hardware => FactoryGirl.create(:hardware, :cpu4x2, :ram1GB, :virtual_hw_version => "07")
:hardware => FactoryGirl.create(:hardware, :cpu4x2, :ram1GB, :virtual_hw_version => "07"),
:host => host,
)
end

Expand Down Expand Up @@ -502,4 +509,94 @@
end
end
end

context "#connect_cdroms" do
let(:vim_obj) { double("MiqVimVm obj") }
let(:vmcs) { VimHash.new("VirtualMachineConfigSpec") }
let(:options) do
[
{
:device_name => "CD/DVD drive 1",
:filename => "[NFS Share] ISO/centos.iso",
:storage_id => storage.id,
}
]
end
let(:subject) { vm.connect_cdroms(vim_obj, vmcs, hardware, options) }

context "with no virtual cdroms" do
let(:hardware) { {"device" => []} }

before do
expect(vim_obj).to receive(:getDeviceByLabel).and_return(nil)
end

it "raises an exception when the cdrom can't be found" do
expect { subject }.to raise_error('connect_cdrom_config_spec: no virtual device associated with: CD/DVD drive 1')
end
end

context "with one virtual cdrom" do
let(:hardware) { {"device" => [virtual_cdrom]} }
let(:virtual_cdrom) do
VimHash.new("VirtualCdrom").tap do |cdrom|
cdrom.backing = VimHash.new("VirtualCdromRemoteAtapiBackingInfo")
cdrom.connectable = VimHash.new("VirtualDeviceConnectInfo")
cdrom.controllerKey = 15000
cdrom.deviceInfo = VimHash.new("Description") do |description|
description.label = "CD/DVD drive 1"
end
cdrom.key = 16000
cdrom.unitNumber = 0
end
end

before do
expect(vim_obj).to receive(:getDeviceByLabel).and_return(virtual_cdrom)
end

it "sets the device backing" do
subject

expect(vmcs.deviceChange.count).to eq(1)

device_change = vmcs.deviceChange.first.device
expect(device_change.backing.xsiType).to eq("VirtualCdromIsoBackingInfo")
expect(device_change.backing.fileName).to eq(options.first[:filename])
end
end
end

context "#disconnect_cdroms" do
let(:vim_obj) { double("MiqVimVm obj") }
let(:vmcs) { VimHash.new("VirtualMachineConfigSpec") }
let(:hardware) { {"device" => [virtual_cdrom]} }
let(:options) { [{:device_name => "CD/DVD drive 1"}] }
let(:subject) { vm.disconnect_cdroms(vim_obj, vmcs, hardware, options) }
let(:virtual_cdrom) do
VimHash.new("VirtualCdrom").tap do |cdrom|
cdrom.backing = VimHash.new("VirtualCdromIsoBackingInfo")
cdrom.connectable = VimHash.new("VirtualDeviceConnectInfo")
cdrom.controllerKey = 15000
cdrom.deviceInfo = VimHash.new("Description") do |description|
description.label = "CD/DVD drive 1"
end
cdrom.key = 16000
cdrom.unitNumber = 0
end
end

before do
expect(vim_obj).to receive(:getDeviceByLabel).and_return(virtual_cdrom)
end

it "sets the device backing" do
subject

expect(vmcs.deviceChange.count).to eq(1)
device_change = vmcs.deviceChange.first.device
expect(device_change.backing.xsiType).to eq("VirtualCdromRemoteAtapiBackingInfo")
expect(device_change.backing.deviceName).to eq("")
end
end
end

0 comments on commit b0bb49d

Please sign in to comment.