Class: VSphereCloud::Resources::VM

Inherits:
Object
  • Object
show all
Includes:
VSphereCloud::RetryBlock, VimSdk
Defined in:
lib/cloud/vsphere/resources/vm.rb

Constant Summary

Constants included from VimSdk

VimSdk::BASE_VERSION, VimSdk::DYNAMIC_TYPES, VimSdk::SOAP_BODY_END, VimSdk::SOAP_BODY_START, VimSdk::SOAP_BODY_TAG, VimSdk::SOAP_END, VimSdk::SOAP_ENVELOPE_END, VimSdk::SOAP_ENVELOPE_START, VimSdk::SOAP_ENVELOPE_TAG, VimSdk::SOAP_FAULT_TAG, VimSdk::SOAP_HEADER_END, VimSdk::SOAP_HEADER_START, VimSdk::SOAP_HEADER_TAG, VimSdk::SOAP_NAMESPACE_MAP, VimSdk::SOAP_START, VimSdk::VERSION1, VimSdk::XMLNS_SOAPENC, VimSdk::XMLNS_SOAPENV, VimSdk::XMLNS_VMODL_BASE, VimSdk::XMLNS_XSD, VimSdk::XMLNS_XSI, VimSdk::XML_ENCODING, VimSdk::XML_HEADER

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from VSphereCloud::RetryBlock

#retry_block, #retry_with_timeout

Constructor Details

#initialize(cid, mob, client, logger) ⇒ VM

Returns a new instance of VM.



9
10
11
12
13
14
# File 'lib/cloud/vsphere/resources/vm.rb', line 9

def initialize(cid, mob, client, logger)
  @client = client
  @mob = mob
  @cid = cid
  @logger = logger
end

Instance Attribute Details

#cidObject (readonly)

Returns the value of attribute cid.



7
8
9
# File 'lib/cloud/vsphere/resources/vm.rb', line 7

def cid
  @cid
end

#mobObject (readonly)

Returns the value of attribute mob.



7
8
9
# File 'lib/cloud/vsphere/resources/vm.rb', line 7

def mob
  @mob
end

Instance Method Details

#accessible_datastoresObject



25
26
27
28
29
30
# File 'lib/cloud/vsphere/resources/vm.rb', line 25

def accessible_datastores
  host_properties['datastore'].map do |store|
    ds = cloud_searcher.get_properties(store, Vim::Datastore, 'info', ensure_all: true)
    ds['info'].name
  end
end

#cdromObject



48
49
50
# File 'lib/cloud/vsphere/resources/vm.rb', line 48

def cdrom
  devices.find { |device| device.kind_of?(Vim::Vm::Device::VirtualCdrom) }
end

#clusterObject



20
21
22
23
# File 'lib/cloud/vsphere/resources/vm.rb', line 20

def cluster
  cluster = cloud_searcher.get_properties(host_properties['parent'], Vim::ClusterComputeResource, 'name', ensure_all: true)
  cluster['name']
end

#datacenterObject



32
33
34
# File 'lib/cloud/vsphere/resources/vm.rb', line 32

def datacenter
  @client.find_parent(@mob, Vim::Datacenter)
end

#deleteObject



137
138
139
# File 'lib/cloud/vsphere/resources/vm.rb', line 137

def delete
  retry_block { @client.delete_vm(@mob) }
end

#devicesObject



40
41
42
# File 'lib/cloud/vsphere/resources/vm.rb', line 40

def devices
  properties['config.hardware.device']
end

#disk_by_cid(disk_cid) ⇒ Object



122
123
124
125
126
127
# File 'lib/cloud/vsphere/resources/vm.rb', line 122

def disk_by_cid(disk_cid)
  devices.find do |d|
    d.kind_of?(Vim::Vm::Device::VirtualDisk) &&
      d.backing.file_name.end_with?("/#{disk_cid}.vmdk")
  end
end

#fix_device_unit_numbers(device_changes) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/cloud/vsphere/resources/vm.rb', line 67

def fix_device_unit_numbers(device_changes)
  controllers_available_unit_numbers = Hash.new { |h,k| h[k] = (0..15).to_a }
  devices.each do |device|
    if device.controller_key
      available_unit_numbers = controllers_available_unit_numbers[device.controller_key]
      available_unit_numbers.delete(device.unit_number)
    end
  end

  device_changes.each do |device_change|
    device = device_change.device
    if device.controller_key && device.unit_number.nil?
      available_unit_numbers = controllers_available_unit_numbers[device.controller_key]
      raise "No available unit numbers for device: #{device.inspect}" if available_unit_numbers.empty?
      device.unit_number = available_unit_numbers.shift
    end
  end
end

#inspectObject



16
17
18
# File 'lib/cloud/vsphere/resources/vm.rb', line 16

def inspect
  "<VM: #{@mob} / #{@cid}>"
end

#nicsObject



44
45
46
# File 'lib/cloud/vsphere/resources/vm.rb', line 44

def nics
  devices.select { |device| device.kind_of?(Vim::Vm::Device::VirtualEthernetCard) }
end

#pci_controllerObject



63
64
65
# File 'lib/cloud/vsphere/resources/vm.rb', line 63

def pci_controller
  devices.find { |device| device.kind_of?(Vim::Vm::Device::VirtualPCIController) }
end

#persistent_disksObject



56
57
58
59
60
61
# File 'lib/cloud/vsphere/resources/vm.rb', line 56

def persistent_disks
 devices.select do |device|
    device.kind_of?(Vim::Vm::Device::VirtualDisk) &&
      device.backing.disk_mode == Vim::Vm::Device::VirtualDiskOption::DiskMode::INDEPENDENT_PERSISTENT
  end
end

#power_offObject



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/cloud/vsphere/resources/vm.rb', line 102

def power_off
  retry_block do
    question = properties['runtime.question']
    if question
      choices = question.choice
      @logger.info("VM is blocked on a question: #{question.text}, " +
        "providing default answer: #{choices.choice_info[choices.default_index].label}")
      @client.answer_vm(@mob, question.id, choices.choice_info[choices.default_index].key)
      power_state = cloud_searcher.get_property(@mob, Vim::VirtualMachine, 'runtime.powerState')
    else
      power_state = properties['runtime.powerState']
    end

    if power_state != Vim::VirtualMachine::PowerState::POWERED_OFF
      @logger.info("Powering off vm: #{@cid}")
      @client.power_off_vm(@mob)
    end
  end
end

#power_onObject



133
134
135
# File 'lib/cloud/vsphere/resources/vm.rb', line 133

def power_on
  @client.power_on_vm(datacenter, @mob)
end

#powered_on?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/cloud/vsphere/resources/vm.rb', line 36

def powered_on?
  power_state == Vim::VirtualMachine::PowerState::POWERED_ON
end

#rebootObject



129
130
131
# File 'lib/cloud/vsphere/resources/vm.rb', line 129

def reboot
  @mob.reboot_guest
end

#reloadObject



141
142
143
144
# File 'lib/cloud/vsphere/resources/vm.rb', line 141

def reload
  @properties = nil
  @host_properties = nil
end

#shutdownObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/cloud/vsphere/resources/vm.rb', line 86

def shutdown
  @logger.debug('Waiting for the VM to shutdown')
  begin
    begin
      @mob.shutdown_guest
    rescue => e
      @logger.debug("Ignoring possible race condition when a VM has powered off by the time we ask it to shutdown: #{e.inspect}")
    end

    wait_until_off(60)
  rescue VSphereCloud::Cloud::TimeoutException
    @logger.debug('The guest did not shutdown in time, requesting it to power off')
    @client.power_off_vm(@mob)
  end
end

#system_diskObject



52
53
54
# File 'lib/cloud/vsphere/resources/vm.rb', line 52

def system_disk
  devices.find { |device| device.kind_of?(Vim::Vm::Device::VirtualDisk) }
end

#wait_until_off(timeout) ⇒ Object



146
147
148
149
150
151
152
153
154
# File 'lib/cloud/vsphere/resources/vm.rb', line 146

def wait_until_off(timeout)
  started = Time.now
  loop do
    power_state = cloud_searcher.get_property(@mob, Vim::VirtualMachine, 'runtime.powerState')
    break if power_state == Vim::VirtualMachine::PowerState::POWERED_OFF
    raise VSphereCloud::Cloud::TimeoutException if Time.now - started > timeout
    sleep(1.0)
  end
end