Class: ChefMetalVsphere::VsphereProvisioner
- Inherits:
-
ChefMetal::Provisioner
- Object
- ChefMetal::Provisioner
- ChefMetalVsphere::VsphereProvisioner
- Includes:
- Chef::Mixin::ShellOut, Helpers
- Defined in:
- lib/chef_metal_vsphere/vsphere_provisioner.rb
Overview
Provisions machines in vSphere.
Instance Attribute Summary collapse
-
#connect_options ⇒ Object
readonly
Returns the value of attribute connect_options.
Class Method Summary collapse
Instance Method Summary collapse
-
#acquire_machine(action_handler, node) ⇒ Object
Acquire a machine, generally by provisioning it.
-
#connect_to_machine(node) ⇒ Object
Connect to machine without acquiring it.
- #delete_machine(action_handler, node) ⇒ Object
-
#initialize(connect_options) ⇒ VsphereProvisioner
constructor
Create a new Vsphere provisioner.
- #stop_machine(action_handler, node) ⇒ Object
Methods included from Helpers
#dc, #do_vm_clone, #find_customization_spec, #find_folder, #find_pool, #find_vm, #port_ready?, #start_vm, #stop_vm, #vim, #vm_started?, #vm_stopped?
Constructor Details
#initialize(connect_options) ⇒ VsphereProvisioner
Create a new Vsphere provisioner.
## Parameters connect_options - hash of options to be passed to RbVmomi::VIM.connect
:vsphere_host - required - hostname of the vSphere API server
:vsphere_port - optional - port on the vSphere API server (default: 443)
:vshere_path - optional - path on the vSphere API server (default: /sdk)
:vsphere_ssl - optional - true to use ssl in connection to vSphere API server (default: true)
:vsphere_insecure - optional - true to ignore ssl certificate validation errors in connection to vSphere API server (default: false)
:vsphere_user - required - user name to use in connection to vSphere API server
:vsphere_password - required - password to use in connection to vSphere API server
:proxy_host - optional - http proxy host to use in connection to vSphere API server (default: none)
:proxy_port - optional - http proxy port to use in connection to vSphere API server (default: none)
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/chef_metal_vsphere/vsphere_provisioner.rb', line 37 def initialize() = stringify_keys() = { 'vsphere_port' => 443, 'vsphere_ssl' => true, 'vsphere_insecure' => false, 'vsphere_path' => '/sdk' } @connect_options = .merge() = %w( vsphere_host vsphere_user vsphere_password ) = [] .each do |opt| << opt unless @connect_options.has_key?(opt) end unless .empty? raise "missing required options: #{.join(', ')}" end # test vim connection vim || raise("cannot connect to [#{provisioner_url}]") @connect_options end |
Instance Attribute Details
#connect_options ⇒ Object (readonly)
Returns the value of attribute connect_options.
63 64 65 |
# File 'lib/chef_metal_vsphere/vsphere_provisioner.rb', line 63 def @connect_options end |
Class Method Details
.inflate(node) ⇒ Object
18 19 20 21 22 |
# File 'lib/chef_metal_vsphere/vsphere_provisioner.rb', line 18 def self.inflate(node) url = node['normal']['provisioner_output']['provisioner_url'] scheme, provider, id = url.split(':', 3) VsphereProvisioner.new({ :provider => provider }, id) end |
Instance Method Details
#acquire_machine(action_handler, node) ⇒ Object
Acquire a machine, generally by provisioning it. Returns a Machine object pointing at the machine, allowing useful actions like setup, converge, execute, file and directory. The Machine object will have a “node” property which must be saved to the server (if it is any different from the original node object).
## Parameters action_handler - the action_handler object that is calling this method; this
is generally a action_handler, but could be anything that can support the
ChefMetal::ActionHandler interface (i.e., in the case of the test
kitchen metal driver for acquiring and destroying VMs; see the base
class for what needs providing).
node - node object (deserialized json) representing this machine. If
the node has a provisioner_options hash in it, these will be used
instead of options provided by the provisioner. TODO compare and
fail if different?
node will have node['normal']['provisioner_options'] in it with any options.
It is a hash with this format:
-- provisioner_url: vsphere://host:port?ssl=[true|false]&insecure=[true|false]
-- bootstrap_options: hash of options to pass to RbVmomi::VIM::VirtualMachine::CloneTask()
:datacenter
:resource_pool
:cluster
:datastore
:template_name
:template_folder
:vm_folder
:winrm {...} (not yet implemented)
:ssh {...}
Example bootstrap_options for vSphere:
TODO: add other CloneTask params, e.g.: datastore, annotation, resource_pool, ...
'bootstrap_options' => {
'template_name' =>'centos6.small',
'template_folder' =>'Templates',
'vm_folder' => 'MyApp'
}
node['normal']['provisioner_output'] will be populated with information
about the created machine. For vSphere, it is a hash with this
format:
-- provisioner_url: vsphere:host:port?ssl=[true|false]&insecure=[true|false]
-- vm_folder: name of the vSphere folder containing the VM
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/chef_metal_vsphere/vsphere_provisioner.rb', line 111 def acquire_machine(action_handler, node) # Set up the provisioner output = stringify_keys(node['normal']['provisioner_options']) vm_name = node['name'] old_provisioner_output = node['normal']['provisioner_output'] node['normal']['provisioner_output'] = provisioner_output = { 'provisioner_url' => provisioner_url, 'vm_name' => vm_name, 'bootstrap_options' => ['bootstrap_options'] } = node['normal']['provisioner_output']['bootstrap_options'] vm_folder = ['vm_folder'] if ['ssh'] wait_on_port = ['ssh']['port'] raise "Must specify bootstrap_options[:ssh][:port]" if wait_on_port.nil? else raise 'bootstrapping is currently supported for ssh only' # wait_on_port = bootstrap_options['winrm']['port'] end # TODO compare new options to existing and fail if we cannot change it # over (perhaps introduce a boolean that will force a delete and recreate # in such a case) vm = vm_instance(action_handler, node) unless vm_started?(vm, wait_on_port) action_handler.perform_action "Start VM and wait for port #{wait_on_port}" do start_vm(vm, wait_on_port) end end machine = machine_for(node) machine end |
#connect_to_machine(node) ⇒ Object
Connect to machine without acquiring it
152 153 154 |
# File 'lib/chef_metal_vsphere/vsphere_provisioner.rb', line 152 def connect_to_machine(node) machine_for(node) end |
#delete_machine(action_handler, node) ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/chef_metal_vsphere/vsphere_provisioner.rb', line 156 def delete_machine(action_handler, node) if node['normal'] && node['normal']['provisioner_output'] provisioner_output = node['normal']['provisioner_output'] else provisioner_output = {} end vm_name = provisioner_output['vm_name'] || node['name'] vm_folder = provisioner_output['bootstrap_options']['vm_folder'] vm = vm_for(node) unless vm.nil? action_handler.perform_action "Delete VM [#{vm_folder}/#{vm_name}]" do vm.PowerOffVM_Task.wait_for_completion unless vm.runtime.powerState == 'poweredOff' vm.Destroy_Task.wait_for_completion end end end |
#stop_machine(action_handler, node) ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/chef_metal_vsphere/vsphere_provisioner.rb', line 174 def stop_machine(action_handler, node) if node['normal'] && node['normal']['provisioner_output'] provisioner_output = node['normal']['provisioner_output'] else provisioner_output = {} end vm_name = provisioner_output['vm_name'] || node['name'] vm_folder = provisioner_output['bootstrap_options']['vm_folder'] vm = vm_for(node) unless vm_stopped?(vm) action_handler.perform_action "Shutdown guest OS and power off VM [#{vm_folder}/#{vm_name}]" do stop_vm(vm) end end end |