Class: LeaseTool

Inherits:
Object
  • Object
show all
Defined in:
lib/rbvmomi/utils/leases.rb

Overview

A class to manage VM leases

This class uses YAML encoded VM annotations (config.annotation) to manage a lease system. It helps add such lease info onto new and existing VMs and to find VMs that have expired leases or that are about to have expired leases. The calling code can use those to generate emails with about-to-expire notifications, suspend, power off or destroy VMs that have exceeded their lease, etc.

Instance Method Summary collapse

Instance Method Details

#current_timeTime

Retrieve the current time as used by the lease tool.

Returns:

  • (Time)

    Current time as used by the lease tool



37
38
39
40
# File 'lib/rbvmomi/utils/leases.rb', line 37

def current_time
  # XXX: Should swith to time provided by VC
  Time.now
end

#filter_expired_vms(vms, vmprops, opts = {}) ⇒ Array

Filter the list of passed in Virtul Machines and find the one that are expired. A time offset can be used to identify VMs that will expire at a certain point in the future. If a VM doesn’t have a lease, it is treated as never expiring.

Parameters:

  • vms (Array)

    List of VIM::VirtualMachine instances, may or may not have leases

  • vmprops (Hash)

    Hash of VIM::VirtualMachine instances to their properties

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :time_delta (int)

    Time delta (seconds) to be added to current time

Returns:

  • (Array)

    List of expired VMs



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/rbvmomi/utils/leases.rb', line 129

def filter_expired_vms vms, vmprops, opts = {}
  time_delta = opts[:time_delta] || 0
  time = current_time + time_delta
  
  out = vms.map do |vm|
    props = vmprops[vm]
    next unless annotation = props['config.annotation']
    note = YAML.load annotation
    next unless note.is_a?(Hash) && lease = note['lease']
    next unless time > lease
    time_to_expiration = ((lease - time) + time_delta)
    [vm, time_to_expiration]
  end.compact
  out = Hash[out]
  out
end

#find_leaseless_vms(vms, vmprops) ⇒ Array

Filter the list of passed in Virtual Machines and find the ones that currently do not have a lease.

Parameters:

  • vms (Array)

    List of VIM::VirtualMachine instances, may or may not have leases

  • vmprops (Hash)

    Hash of VIM::VirtualMachine instances to their properties

Returns:

  • (Array)

    List of leaseless VMs



110
111
112
113
114
115
116
117
118
119
# File 'lib/rbvmomi/utils/leases.rb', line 110

def find_leaseless_vms vms, vmprops
  vms.reject do |vm|
    props = vmprops[vm]
    annotation = props['config.annotation']
    if annotation
      note = YAML.load annotation
      note.is_a?(Hash) && note['lease']
    end
  end
end

#get_vms_props(vms) ⇒ Hash

Fetch all VM properties that the LeaseTool needs on all VMs passed in.

Parameters:

  • vms (Array)

    List of VIM::VirtualMachine instances

Returns:

  • (Hash)

    Hash of VMs as keys and their properties as values



26
27
28
29
30
31
32
33
# File 'lib/rbvmomi/utils/leases.rb', line 26

def get_vms_props vms
  out = {}
  if vms.length > 0
    pc = vms.first._connection.serviceContent.propertyCollector
    out = pc.collectMultiple(vms, 'name', 'config.annotation')
  end
  out
end

#set_lease_in_vm_config(vmconfig, lease_minutes) ⇒ Hash

Helper function that sets the lease info in a passed in VM config. If there is no annotation, it is added. If there is an annotation, it is updated to include the lease info. Note that if the annotation isn’t YAML, it is overwritten.

Parameters:

  • vmconfig (Hash)

    Virtual Machine config spec

  • lease_minutes (int)

    Time to lease expiration from now in minutes

Returns:

  • (Hash)

    Updated Virtual Machine config spec



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/rbvmomi/utils/leases.rb', line 49

def set_lease_in_vm_config vmconfig, lease_minutes
  annotation = vmconfig[:annotation]
  annotation ||= ""
  note = YAML.load annotation
  if !note.is_a?(Hash)
    note = {}
  end
  lease = current_time + lease_minutes * 60
  note['lease'] = lease
  vmconfig[:annotation] = YAML.dump(note)
  vmconfig
end

#set_lease_on_leaseless_vms(vms, vmprops, opts = {}) ⇒ Array

Issue ReconfigVM_Task to set the lease on all VMs that currently do not have a lease. All VM reconfigurations are done in parallel and the function waits for all of them to complete

Parameters:

  • vms (Array)

    List of VIM::VirtualMachine instances, may or may not have leases

  • vmprops (Hash)

    Hash of VIM::VirtualMachine instances to their properties

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :lease_minutes (int)

    Time to lease expiration from now in minutes

Returns:

  • (Array)

    List of previously leaseless VMs that now have a lease



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/rbvmomi/utils/leases.rb', line 87

def set_lease_on_leaseless_vms vms, vmprops, opts = {}
  lease_minutes = opts[:lease_minutes]
  if !lease_minutes
    raise "Expected lease_minutes to be specified"
  end
  vms = find_leaseless_vms vms, vmprops
  if vms.length > 0
    tasks = vms.map do |vm|
      annotation = vmprops[vm]['config.annotation']
      task = set_lease_on_vm_task(vm, lease_minutes, annotation)
      task
    end
    si = vms.first._connection.serviceInstance
    si.wait_for_multiple_tasks [], tasks
  end
  vms
end

#set_lease_on_vm_task(vm, lease_minutes, annotation = nil) ⇒ VIM::Task

Issue ReconfigVM_Task on the VM to update the lease. User can pass in current annotation, but if not, it is retrieved on demand. A task is returned, i.e. function doesn’t wait for completion.

Parameters:

  • vm (VIM::VirtualMachine)

    Virtual Machine instance

  • lease_minutes (int)

    Time to lease expiration from now in minutes

  • annotation (String) (defaults to: nil)

    ‘config.annotation’ property of the VM. Optional.

Returns:

  • (VIM::Task)

    VM reconfiguration task



69
70
71
72
73
74
75
76
77
78
# File 'lib/rbvmomi/utils/leases.rb', line 69

def set_lease_on_vm_task vm, lease_minutes, annotation = nil
  if !annotation
    annotation = vm.collect 'config.annotation' 
  end
  vmconfig = {:annotation => annotation}
  vmconfig = set_lease_in_vm_config vmconfig, lease_minutes
  # XXX: It may be a good idea to cite the VM version here to avoid
  #      concurrent writes to the annotation stepping on each others toes
  vm.ReconfigVM_Task(:spec => vmconfig)
end

#vms_props_listArray

Lists of VM properties the LeaseTool needs to do its job. Can be used to construct larger property collector calls that retrieve more info than just one subsystem needs.

Returns:

  • (Array)

    List of property names



19
20
21
# File 'lib/rbvmomi/utils/leases.rb', line 19

def vms_props_list 
  ['name', 'config.annotation']
end