Class: RbVmomi::VIM::VirtualMachine

Inherits:
Object
  • Object
show all
Defined in:
lib/vmonkey/vim/VirtualMachine.rb

Instance Method Summary collapse

Instance Method Details

#_clone_params(vm_name, dest, opts) ⇒ Object



250
251
252
253
254
255
256
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 250

def _clone_params(vm_name, dest, opts)
  {
    name: vm_name,
    folder: dest.vm_folder,
    spec: _clone_spec(dest, opts)
  }
end

#_clone_spec(dest, opts) ⇒ Object



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 258

def _clone_spec(dest, opts)
  opts[:config] ||= {}

  clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(
    location: RbVmomi::VIM.VirtualMachineRelocateSpec({
      pool: dest.vm_pool,
      datastore: opts[:datastore]
      }),
    powerOn: false,
    template: false
  )

  device_change = opts[:deviceChange] || Array.new
  clone_spec.config = RbVmomi::VIM.VirtualMachineConfigSpec(deviceChange: device_change)

  clone_spec.customization = monkey.customization_spec(opts[:customization_spec])
  clone_spec.config.annotation = opts[:config][:annotation]
  clone_spec.config.numCPUs = opts[:config][:num_cpus]
  clone_spec.config.memoryMB = opts[:config][:memory_mb]
  clone_spec.config.files = opts[:config][:files]

  clone_spec
end

#annotationObject



30
31
32
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 30

def annotation
  config.annotation
end

#annotation=(value) ⇒ Object



34
35
36
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 34

def annotation=(value)
  ReconfigVM_Task(spec: RbVmomi::VIM.VirtualMachineConfigSpec(annotation: value)).wait_for_completion
end

#clone_to(path, opts = {}) ⇒ Object



10
11
12
13
14
15
16
17
18
19
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 10

def clone_to(path, opts = {})
  dest = monkey.get(path.parent)
  unless dest.is_a? RbVmomi::VIM::Folder or dest.is_a? RbVmomi::VIM::VirtualApp
    raise "Cannot clone_to [#{path.parent}] - destination must specify a Folder or VirtualApp"
  end

  params = _clone_params(path.basename, dest, opts)

  self.CloneVM_Task(params).wait_for_completion
end

#clone_to!(path) ⇒ Object



21
22
23
24
25
26
27
28
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 21

def clone_to!(path)
  dest_vm = monkey.vm(path)
  dest_vm.destroy if dest_vm

  monkey.folder('/').mk_folder(path.parent) unless path.parent.to_s.empty?

  clone_to(path)
end

#destroyObject



5
6
7
8
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 5

def destroy
  self.PowerOffVM_Task.wait_for_completion unless runtime.powerState == 'poweredOff'
  self.Destroy_Task.wait_for_completion
end

#find_property(name) ⇒ Object



180
181
182
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 180

def find_property(name)
  config.vAppConfig.property.find { |p| p.props[:id] == name.to_s  }
end

#guest_ipObject

backported from rbvmomi 1.8 for rbvmomi 1.5 support



71
72
73
74
75
76
77
78
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 71

def guest_ip
  g = self.guest
  if g.ipAddress && (g.toolsStatus == "toolsOk" || g.toolsStatus == "toolsOld")
    g.ipAddress
  else
    nil
  end
end

#killObject



156
157
158
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 156

def kill
  PowerOffVM_Task().wait_for_completion unless runtime.powerState == 'poweredOff'
end

#move_to(path) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 53

def move_to(path)
  monkey.vm(path) && raise("VirtualMachine already exists. [#{path}]")
  rename = name != path.basename

  to_folder = monkey.folder! path.parent
  reparent = parent != to_folder

  if reparent
    Rename_Task(newName: "#{path.basename}-tmp").wait_for_completion if rename
    to_folder.MoveIntoFolder_Task(list: [self]).wait_for_completion
    Rename_Task(newName: path.basename).wait_for_completion if rename
  else
    Rename_Task(newName: path.basename).wait_for_completion
  end
end

#move_to!(path) ⇒ Object



81
82
83
84
85
86
87
88
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 81

def move_to!(path)
  dest_vm = monkey.vm(path)
  dest_vm.destroy if dest_vm

  monkey.folder('/').mk_folder(path.parent) unless path.parent.to_s.empty?

  move_to(path)
end

#network=(network_name) ⇒ Object

def network

nics = self.config.hardware.device.select{ |d| d.is_a? RbVmomi::VIM.VirtualEthernetCard.class }
nics.first.backing.deviceName if nics.first

end



237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 237

def network=(network_name)
  nics = self.config.hardware.device.select{ |d| d.is_a? RbVmomi::VIM.VirtualEthernetCard.class }
  nics.each do |nic|
    unless nic[:backing][:deviceName] == network_name
      nic[:backing] = RbVmomi::VIM.VirtualEthernetCardNetworkBackingInfo(deviceName: network_name)
      change_spec = RbVmomi::VIM.VirtualMachineConfigSpec( deviceChange: [
        RbVmomi::VIM.VirtualDeviceConfigSpec(device: nic, operation: 'edit')
        ])
      self.ReconfigVM_Task(spec: change_spec).wait_for_completion
    end
  end
end

#port_ready?(port, timeout = 5) ⇒ Boolean

Returns:

  • (Boolean)


90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 90

def port_ready?(port, timeout = 5)
  ip = guest_ip or return false


  ## modified from http://spin.atomicobject.com/2013/09/30/socket-connection-timeout-ruby/
  addr = Socket.getaddrinfo(ip, nil)
  sockaddr = Socket.pack_sockaddr_in(port, addr[0][3])

  Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0).tap do |socket|
    socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)

    begin
      # Initiate the socket connection in the background. If it doesn't fail
      # immediately it will raise an IO::WaitWritable (Errno::EINPROGRESS)
      # indicating the connection is in progress.
      socket.connect_nonblock(sockaddr)

    rescue IO::WaitWritable
      # IO.select will block until the socket is writable or the timeout
      # is exceeded - whichever comes first.
      if IO.select(nil, [socket], nil, timeout)
        begin
          # Verify there is now a good connection
          socket.connect_nonblock(sockaddr)
        rescue Errno::EISCONN
          # Good news everybody, the socket is connected!
          return true
        rescue Errno::ETIMEDOUT, Errno::EPERM, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH
          return false
        rescue
          # An unexpected exception was raised - the connection is no good.
          raise
        end
      else
        # IO.select returns nil when the socket is not ready before timeout
        # seconds have elapsed
        return false
      end
    ensure
      socket.close
    end

    return true
  end
end

#property(*args) ⇒ Object



38
39
40
41
42
43
44
45
46
47
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 38

def property(*args)
  case args.size
  when 1
    read_property(*args)
  when 2, 3
    set_property(*args)
  else
    raise ArgumentError.new("wrong number of arguments (#{args.size} for 1, 2 or 3)")
  end
end

#property!(name) ⇒ Object



49
50
51
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 49

def property!(name)
  read_property(name) || raise("vApp Property not found. [#{name}]")
end

#read_property(name) ⇒ Object



184
185
186
187
188
189
190
191
192
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 184

def read_property(name)
  p = find_property(name)
  value = nil
  unless p.nil?
    value = p[:value]
    value = p[:defaultValue] if value.empty?
  end
  value
end

#ready?Boolean

Returns:

  • (Boolean)


176
177
178
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 176

def ready?
  ! guest_ip.nil?
end

#set_property(name, value, opts = {}) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 194

def set_property(name, value, opts={})
  opts = {
      type: 'string',
      userConfigurable: true
    }.merge opts

  if config.vAppConfig && config.vAppConfig.property
    existing_property = find_property(name)
  end

  if existing_property
    operation = 'edit'
    property_key = existing_property.props[:key]
  else
    operation = 'add'
    property_key = name.object_id
  end

  value = value.join(',') if value.is_a?(Array)

  vm_config_spec = RbVmomi::VIM.VirtualMachineConfigSpec(
    vAppConfig: RbVmomi::VIM.VmConfigSpec(
      property: [
        RbVmomi::VIM.VAppPropertySpec(
          operation: operation,
          info: opts.merge({
            key: property_key,
            id: name.to_s,
            value: value.to_s
            }))]))

  if config.vAppConfig.nil? || config.vAppConfig.ovfEnvironmentTransport.empty?
    vm_config_spec[:vAppConfig][:ovfEnvironmentTransport] = ['com.vmware.guestInfo']
  end

  ReconfigVM_Task( spec: vm_config_spec ).wait_for_completion
end

#startObject



168
169
170
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 168

def start
  PowerOnVM_Task().wait_for_completion unless runtime.powerState == 'poweredOn'
end

#started?Boolean

Returns:

  • (Boolean)


172
173
174
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 172

def started?
  runtime.powerState == 'poweredOn'
end

#stopObject



160
161
162
163
164
165
166
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 160

def stop
  return if runtime.powerState == 'poweredOff'
  ShutdownGuest()
  sleep 2 until runtime.powerState == 'poweredOff'
rescue
  PowerOffVM_Task().wait_for_completion unless runtime.powerState == 'poweredOff'
end

#wait_for(max = 300, interval = 2, &block) ⇒ Object



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 136

def wait_for(max=300, interval=2, &block)
  elapsed = 0
  start = Time.now

  until (result = yield) || (elapsed > max)
    sleep interval
    elapsed = Time.now - start
  end

  unless result
    raise "Waited #{max} seconds, giving up."
  end

  true
end

#wait_for_port(port) ⇒ Object



152
153
154
# File 'lib/vmonkey/vim/VirtualMachine.rb', line 152

def wait_for_port(port)
  wait_for { port_ready?(port) }
end