Class: Deltacloud::Drivers::Vsphere::VsphereDriver
- Inherits:
-
BaseDriver
- Object
- BaseDriver
- Deltacloud::Drivers::Vsphere::VsphereDriver
- Includes:
- Deltacloud::Drivers::VSphere::Helper, VSphere::FileManager
- Defined in:
- lib/deltacloud/drivers/vsphere/vsphere_driver.rb
Constant Summary
Constants inherited from BaseDriver
BaseDriver::MEMBER_SHOW_METHODS, BaseDriver::STATE_MACHINE_OPTS
Constants included from Deltacloud
Instance Method Summary collapse
- #create_image(credentials, opts = {}) ⇒ Object
- #create_instance(credentials, image_id, opts = {}) ⇒ Object
-
#destroy_instance(credentials, instance_id) ⇒ Object
(also: #destroy_image)
Destroy an instance, given its id.
-
#hardware_profiles(credentials, opts = {}) ⇒ Object
There is just one hardware profile where memory is measured using maximum memory available on ESX for virtual machines and CPU using maximum free CPU cores in ESX.
-
#images(credentials, opts = {}) ⇒ Object
Images are virtual machines with ‘template’ flag set to be true.
-
#instances(credentials, opts = {}) ⇒ Object
List all running instances, across all datacenters.
-
#realms(credentials, opts = {}) ⇒ Object
List all datacenters managed by the vSphere or vCenter entrypoint.
-
#reboot_instance(credentials, id) ⇒ Object
Reboot an instance, given its id.
-
#start_instance(credentials, id) ⇒ Object
Start an instance, given its id.
-
#stop_instance(credentials, id) ⇒ Object
Stop an instance, given its id.
Methods included from Deltacloud::Drivers::VSphere::Helper
#extract_architecture, #find_datastore, #find_resource_pool, #find_vm, #list_datastores, #list_virtual_machines, #load_serialized_instance, #map_task_to_instance, #stored_tasks
Methods inherited from BaseDriver
#address, #api_provider, #blob, #bucket, #catched_exceptions_list, #configured_providers, constraints, define_hardware_profile, define_instance_states, driver_name, feature, features, #filter_hardware_profiles, #filter_on, #find_hardware_profile, #firewall, #hardware_profile, hardware_profiles, #has_capability?, #has_feature?, has_feature?, #image, #instance, #instance_actions_for, instance_state_machine, #instance_state_machine, #key, #name, #realm, #storage_snapshot, #storage_volume, #supported_collections, #valid_credentials?
Methods included from Deltacloud
[], config, configure, connect, database, default_frontend, drivers, enabled_frontends, frontend_required?, frontends, generate_routes, initialize_database, need_database?, new, require_frontend!
Methods included from CollectionMethods
#collection_exists?, #collection_names, #collections
Methods included from Exceptions
exception_from_status, exceptions, included, logger, #safely
Instance Method Details
#create_image(credentials, opts = {}) ⇒ Object
116 117 118 119 120 121 |
# File 'lib/deltacloud/drivers/vsphere/vsphere_driver.rb', line 116 def create_image(credentials, opts={}) safely do find_vm(credentials, opts[:id])[:instance].MarkAsTemplate end image(credentials, :id => opts[:id]) end |
#create_instance(credentials, image_id, opts = {}) ⇒ Object
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 |
# File 'lib/deltacloud/drivers/vsphere/vsphere_driver.rb', line 212 def create_instance(credentials, image_id, opts={}) safely do if opts[:hwp_cpu] raise "Invalid CPU value. Must be in integer format" unless valid_cpu_value?(opts[:hwp_cpu]) end vm = find_vm(credentials, image_id) raise "ERROR: Could not find the image in given datacenter" unless vm[:instance] # New instance need valid resource pool and datastore to be placed. # For this reason, realm_id **needs** to be set. if opts and opts[:realm_id] resourcePool = find_resource_pool(credentials, opts[:realm_id]) datastore = find_datastore(credentials, opts[:realm_id]) else resourcePool = find_resource_pool(credentials, vm[:datastore]) datastore = find_datastore(credentials, vm[:datastore]) end relocate = { :pool => resourcePool, :datastore => datastore } relocateSpec = RbVmomi::VIM.VirtualMachineRelocateSpec(relocate) # Set extra configuration for VM, like template_id raise "ERROR: Memory must be multiple of 4" unless valid_memory_value?(opts[:hwp_memory]) machine_config = { :memoryMB => opts[:hwp_memory], :numCPUs => opts[:hwp_cpu], :extraConfig => [ { :key => 'template_id', :value => image_id }, ] } if (opts[:user_data] and not opts[:user_data].empty?) and (opts[:user_iso] and not opts[:user_iso].empty?) raise "ERROR: You cannot use user_data and user_iso features together" end # If user wants to inject data into instance he need to submit a Base64 # encoded gzipped ISO image. # This image will be uplaoded to the Datastore given in 'realm_id' # parameter and them attached to instance. if opts[:user_data] and not opts[:user_data].empty? device = vm[:instance].config.hardware.device.select { |hw| hw.class == RbVmomi::VIM::VirtualCdrom }.first if device VSphere::FileManager::user_data!(datastore, opts[:user_data], "#{opts[:name]}.iso") machine_config[:extraConfig] << { :key => 'user_data_file', :value => "#{opts[:name]}.iso" } device.connectable.startConnected = true device.backing = RbVmomi::VIM.VirtualCdromIsoBackingInfo(:fileName => "[#{opts[:realm_id] || vm[:datastore]}] "+ "/#{VSphere::FileManager::DIRECTORY_PATH}/#{opts[:name]}.iso") machine_config.merge!({ :deviceChange => [{ :operation => :edit, :device => device }] }) else raise "Failed to inject data to device because there is no CD-ROM drive defined in given template" end end if opts[:user_iso] and not opts[:user_iso].empty? device = vm[:instance].config.hardware.device.select { |hw| hw.class == RbVmomi::VIM::VirtualCdrom }.first if device VSphere::FileManager::store_iso!(datastore, opts[:user_iso], "#{opts[:name]}.iso") machine_config[:extraConfig] << { :key => 'user_iso_file', :value => "#{opts[:name]}.iso" } device.connectable.startConnected = true device.backing = RbVmomi::VIM.VirtualCdromIsoBackingInfo(:fileName => "[#{opts[:realm_id] || vm[:datastore]}] "+ "/#{VSphere::FileManager::DIRECTORY_PATH}/#{opts[:name]}.iso") machine_config.merge!({ :deviceChange => [{ :operation => :edit, :device => device }] }) else raise "Failed to inject data to device because there is no CD-ROM drive defined in given template" end end spec = RbVmomi::VIM.VirtualMachineCloneSpec( :location => relocateSpec, :powerOn => true, :template => false, :config => RbVmomi::VIM.VirtualMachineConfigSpec(machine_config) ) instance_profile = InstanceProfile::new('default', :hwp_memory => opts[:hwp_memory], :hwp_cpu => opts[:hwp_cpu]) task = vm[:instance].CloneVM_Task(:folder => vm[:instance].parent, :name => opts[:name] || "inst#{Time.now.to_i}", :spec => spec) new_instance = Instance::new( :id => opts[:name], :name => opts[:name], :description => opts[:name], :owner_id => credentials.user, :image_id => opts[:image_id], :realm_id => opts[:realm_id] || vm[:datastore], :state => 'PENDING', :public_addresses => [], :private_addresses => [], :instance_profile => instance_profile, :actions => instance_actions_for( 'PENDING' ), :create_image => false ) # This will 'serialize' instance to YAML file and map it to the task. # Ussualy it takes like 2-3 minutes (depending on storage size) to # complete instance cloning process. map_task_to_instance(datastore, task.info.key, new_instance) end end |
#destroy_instance(credentials, instance_id) ⇒ Object Also known as: destroy_image
Destroy an instance, given its id. Note that this will destroy all instance data.
If there is user-data dile asocciated with instance, remove this file as well.
335 336 337 338 339 340 |
# File 'lib/deltacloud/drivers/vsphere/vsphere_driver.rb', line 335 def destroy_instance(credentials, instance_id) vm = find_vm(credentials, instance_id) user_file = vm[:instance].config[:extraConfig].select { |k| k.key == 'user_iso_file' }.first VSphere::FileManager::delete_iso!(vm[:instance].send(:datastore).first, user_file.value) if user_file vm[:instance].Destroy_Task.wait_for_completion end |
#hardware_profiles(credentials, opts = {}) ⇒ Object
There is just one hardware profile where memory is measured using maximum memory available on ESX for virtual machines and CPU using maximum free CPU cores in ESX.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/deltacloud/drivers/vsphere/vsphere_driver.rb', line 41 def hardware_profiles(credentials, opts={}) vsphere = new_client(credentials) safely do service = vsphere.serviceInstance.content max_memory, max_cpu_cores = [], [] # # Note: Memory is being hardcoded now to range 512MB to 2GB # JIRA: DTACLOUD-123 # service.rootFolder.childEntity.grep(RbVmomi::VIM::Datacenter).each do |dc| # max_memory << dc.hostFolder.childEntity.first.summary.effectiveMemory max_cpu_cores << dc.hostFolder.childEntity.first.summary.numCpuCores end [Deltacloud::HardwareProfile::new('default') do cpu (1..max_cpu_cores.min) memory (512..2048) architecture ['x86_64', 'i386'] end] end end |
#images(credentials, opts = {}) ⇒ Object
Images are virtual machines with ‘template’ flag set to be true. Thus we’re getting them using find_vm and list_virtual_machines
76 77 78 79 80 81 82 83 84 85 86 87 88 89 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 |
# File 'lib/deltacloud/drivers/vsphere/vsphere_driver.rb', line 76 def images(credentials, opts={}) img_arr = [] profiles = hardware_profiles(credentials) # Skip traversing through all instances in all datacenters when ID # attribute is set safely do if opts[:id] template_vms = [ find_vm(credentials, opts[:id]) ].select { |vm| vm[:instance] }.compact else template_vms = list_virtual_machines(credentials).select { |vm| vm[:instance] && vm[:instance].summary.config[:template] } end img_arr = template_vms.collect do |image_hash| image = image_hash[:instance] config = image.summary.config # Preload all properties to save multiple SOAP calls to vSphere properties = { :name => config[:name], :full_name => config[:guestFullName] } image_state = convert_state(:image, image.summary.runtime[:powerState]) # This will determine image architecture using image description. # Ussualy description include '64-bit' or '32-bit'. In case you used # some weird template/OS it will fallback to 64 bit image_architecture = extract_architecture(properties[:full_name]) || 'x86_64' Image.new( :id => properties[:name], :name => properties[:name], :architecture => image_architecture, :owner_id => credentials.user, :description => properties[:full_name], :state => image_state, :creation_time => image.storage[:timestamp], :hardware_profiles => profiles ) end end img_arr = filter_on( img_arr, :architecture, opts ) img_arr.sort_by{|e| [e.owner_id, e.name]} end |
#instances(credentials, opts = {}) ⇒ Object
List all running instances, across all datacenters. DeltaCloud API does not yet support filtering instances by realm.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/deltacloud/drivers/vsphere/vsphere_driver.rb', line 141 def instances(credentials, opts={}) inst_arr, machine_vms, pending_vms = [], [], [] safely do # Using find_vm is a way faster than listing all virtual machines if opts[:id] list_vms = [ find_vm(credentials, opts[:id]) ].compact else list_vms = list_virtual_machines(credentials) end # Split machines to the 'real' one and PENDING one. machine_vms = list_vms.select { |vm| vm[:instance] && !vm[:instance].summary.config[:template] } pending_vms = list_vms.select { |vm| vm[:stored_instance] }.collect { |vm| vm[:stored_instance]} end safely do inst_arr = machine_vms.collect do |vm_hash| # Since all calls to vm are threaten as SOAP calls, reduce them using # local variable. vm, realm_id = vm_hash[:instance], vm_hash[:datastore] config = vm.summary.config next if not config # Template (image_id) is beeing stored as 'extraConfig' parameter in # instance. template_id = vm.config[:extraConfig].select { |k| k.key == 'template_id' } template_id = template_id.first.value unless template_id.empty? properties = { :memory => config[:memorySizeMB], :cpus => config[:numCpu], :storage => vm.summary.storage[:unshared], :name => config[:name], :full_name => config[:guestFullName], } instance_state = convert_state(:instance, vm.summary.runtime[:powerState]) instance_profile = InstanceProfile::new('default', :hwp_cpu => properties[:cpus], :hwp_memory => properties[:memory], :hwp_storage => properties[:storage]) # We're getting IP address from 'vmware guest tools'. # If guest tools are not installed, we return list of MAC addresses # assigned to this instance. public_addresses = vm.macs.values.collect { |mac_address| InstanceAddress.new(mac_address, :type => :mac) } if !vm.guest[:net].empty? and ip_address = vm.guest[:net].first[:ipAddress].first public_addresses += [InstanceAddress.new(ip_address)] end Instance.new( :id => properties[:name], :name => properties[:name], :owner_id => credentials.user, :image_id => template_id.empty? ? nil : template_id, :description => properties[:full_name], :realm_id => realm_id, :state => instance_state, :public_addresses => public_addresses, :private_addresses => [], :instance_profile => instance_profile, :actions => instance_actions_for( instance_state ), :launch_time => vm.runtime.props[:bootTime], :create_image => true ) end end inst_arr.compact! # Append 'temporary' instances to real instances. # 'Temporary' or 'stored' instance are used to speed up instance creation # process by serializing instances to datastore and map instance to task. # inst_arr += pending_vms filter_on( inst_arr, :state, opts ) end |
#realms(credentials, opts = {}) ⇒ Object
List all datacenters managed by the vSphere or vCenter entrypoint.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/deltacloud/drivers/vsphere/vsphere_driver.rb', line 124 def realms(credentials, opts={}) vsphere = new_client(credentials) safely do if opts and opts[:id] datastore = find_datastore(credentials, opts[:id]) [convert_realm(datastore)] else rootFolder = vsphere.serviceInstance.content.rootFolder rootFolder.childEntity.grep(RbVmomi::VIM::Datacenter).collect do |dc| dc.datastoreFolder.childEntity.collect { |ds| convert_realm(ds) } end.flatten end end end |
#reboot_instance(credentials, id) ⇒ Object
Reboot an instance, given its id.
316 317 318 |
# File 'lib/deltacloud/drivers/vsphere/vsphere_driver.rb', line 316 def reboot_instance(credentials, id) find_vm(credentials, id)[:instance].RebootGuest end |
#start_instance(credentials, id) ⇒ Object
Start an instance, given its id.
321 322 323 |
# File 'lib/deltacloud/drivers/vsphere/vsphere_driver.rb', line 321 def start_instance(credentials, id) find_vm(credentials, id)[:instance].PowerOnVM_Task end |
#stop_instance(credentials, id) ⇒ Object
Stop an instance, given its id.
326 327 328 |
# File 'lib/deltacloud/drivers/vsphere/vsphere_driver.rb', line 326 def stop_instance(credentials, id) find_vm(credentials, id)[:instance].PowerOffVM_Task end |