Revision e6a57b0f src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb

View differences:

src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb
24 24
        VIClient.get_entities(@item, "VirtualMachine").each do |item|
25 25
            if item.config.template
26 26
                item_name = item._ref
27
                @items[item_name.to_sym] = VirtualMachine.new(item)
27
                @items[item_name.to_sym] = Template.new(item)
28 28
            end
29 29
        end
30 30
    end
......
44 44
    end
45 45
end # class VirtualMachineFolder
46 46

  
47
class VirtualMachine
48
    VM_PREFIX_DEFAULT = "one-$i-"
49

  
50
    POLL_ATTRIBUTE    = OpenNebula::VirtualMachine::Driver::POLL_ATTRIBUTE
51
    VM_STATE          = OpenNebula::VirtualMachine::Driver::VM_STATE
52

  
53
    VM_SHUTDOWN_TIMEOUT = 600 #10 minutes til poweroff hard
47
class Template
54 48

  
55 49
    attr_accessor :item
56 50

  
......
77 71
        end
78 72
    end
79 73

  
74
    def get_dc
75
        item = @item
76

  
77
        while !item.instance_of? RbVmomi::VIM::Datacenter
78
            item = item.parent
79
            if item.nil?
80
                raise "Could not find the parent Datacenter"
81
            end
82
        end
83

  
84
        Datacenter.new(item)
85
    end
86

  
87
    def delete_template
88
        @item.Destroy_Task.wait_for_completion
89
    end
90

  
91
    def get_vcenter_instance_uuid
92
        @vi_client.vim.serviceContent.about.instanceUuid rescue nil
93
    end
94

  
95
    def create_template_copy(template_name)
96
        error = nil
97
        template_ref = nil
98

  
99
        template_name = "one-#{self['name']}" if template_name.empty?
100

  
101
        relocate_spec_params = {}
102
        relocate_spec_params[:pool] = get_rp
103
        relocate_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(relocate_spec_params)
104

  
105
        clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec({
106
            :location => relocate_spec,
107
            :powerOn  => false,
108
            :template => false
109
        })
110

  
111
        template = nil
112
        begin
113
            template = @item.CloneVM_Task(:folder => @item.parent,
114
                                          :name   => template_name,
115
                                          :spec   => clone_spec).wait_for_completion
116
            template_ref = template._ref
117
        rescue Exception => e
118
            if !e.message.start_with?('DuplicateName')
119
                error = "Could not create the template clone. Reason: #{e.message}"
120
                return error, nil
121
            end
122

  
123
            dc = get_dc
124
            vm_folder = dc.vm_folder
125
            vm_folder.fetch!
126
            vm = vm_folder.items
127
                    .select{|k,v| v.item.name == template_name}
128
                    .values.first.item rescue nil
129

  
130
            if vm
131
                begin
132
                    vm.Destroy_Task.wait_for_completion
133
                    template = @item.CloneVM_Task(:folder => @item.parent,
134
                                                  :name   => template_name,
135
                                                  :spec   => clone_spec).wait_for_completion
136
                    template_ref = template._ref
137
                rescue
138
                    error = "Could not delete the existing template, please remove it manually from vCenter. Reason: #{e.message}"
139
                end
140
            else
141
                error = "Could not create the template clone. Reason: #{e.message}"
142
            end
143
        end
144

  
145
        return error, template_ref
146
    end
147

  
148
    # Linked Clone over existing template
149
    def create_delta_disks
150

  
151
        begin
152
            disks = @item['config.hardware.device'].grep(RbVmomi::VIM::VirtualDisk)
153
            disk_without_snapshots = disks.select { |x| x.backing.parent.nil? }
154
        rescue
155
            error = "Cannot extract existing disks on template."
156
            use_linked_clones = false
157
            return error, use_linked_clones
158
        end
159

  
160
        if !disk_without_snapshots.empty?
161

  
162
            begin
163
                if self['config.template']
164
                    @item.MarkAsVirtualMachine(:pool => get_rp, :host => self['runtime.host'])
165
                end
166
            rescue Exception => e
167
                @item.MarkAsTemplate()
168
                error = "Cannot mark the template as a VirtualMachine. Not using linked clones. Reason: #{e.message}/#{e.backtrace}"
169
                use_linked_clones = false
170
                return error, use_linked_clones
171
            end
172

  
173
            begin
174
                spec = {}
175
                spec[:deviceChange] = []
176

  
177
                disk_without_snapshots.each do |disk|
178
                    remove_disk_spec = { :operation => :remove, :device => disk }
179
                    spec[:deviceChange] << remove_disk_spec
180

  
181
                    add_disk_spec = { :operation => :add,
182
                                    :fileOperation => :create,
183
                                    :device => disk.dup.tap { |x|
184
                                            x.backing = x.backing.dup
185
                                            x.backing.fileName = "[#{disk.backing.datastore.name}]"
186
                                            x.backing.parent = disk.backing
187
                                    }
188
                    }
189
                    spec[:deviceChange] << add_disk_spec
190
                end
191

  
192
                @item.ReconfigVM_Task(:spec => spec).wait_for_completion if !spec[:deviceChange].empty?
193
            rescue Exception => e
194
                error = "Cannot create the delta disks on top of the template. Reason: #{e.message}."
195
                use_linked_clones = false
196
                return error, use_linked_clones
197
            end
198

  
199
            begin
200
                @item.MarkAsTemplate()
201
            rescue
202
                error = "Cannot mark the VirtualMachine as a template. Not using linked clones."
203
                use_linked_clones = false
204
                return error, use_linked_clones
205
            end
206

  
207
            error = nil
208
            use_linked_clones = true
209
            return error, use_linked_clones
210
        else
211
            # Template already has delta disks
212
            error = nil
213
            use_linked_clones = true
214
            return error, use_linked_clones
215
        end
216
    end
217

  
218
    def import_vcenter_disks(vc_uuid, dpool, ipool)
219
        disk_info = ""
220
        error = ""
221

  
222
        begin
223
            lock #Lock import operation, to avoid concurrent creation of images
224

  
225
            ccr_ref = self["runtime.host.parent._ref"]
226

  
227
            #Get disks and info required
228
            vc_disks = get_vcenter_disks
229

  
230
            # Track allocated images
231
            allocated_images = []
232

  
233
            vc_disks.each do |disk|
234
                datastore_found = VCenterDriver::Storage.get_one_image_ds_by_ref_and_ccr(disk[:datastore]._ref,
235
                                                                                        ccr_ref,
236
                                                                                        vc_uuid,
237
                                                                                        dpool)
238
                if datastore_found.nil?
239
                    error = "\n    ERROR: datastore #{disk[:datastore].name}: has to be imported first as an image datastore!\n"
240

  
241
                    #Rollback delete disk images
242
                    allocated_images.each do |i|
243
                        i.delete
244
                    end
245

  
246
                    break
247
                end
248

  
249
                image_import = VCenterDriver::Datastore.get_image_import_template(disk[:datastore].name,
250
                                                                                disk[:path],
251
                                                                                disk[:type], ipool)
252
                #Image is already in the datastore
253
                if image_import[:one]
254
                    # This is the disk info
255
                    disk_info << "DISK=[\n"
256
                    disk_info << "IMAGE_ID=\"#{image_import[:one]["ID"]}\",\n"
257
                    disk_info << "OPENNEBULA_MANAGED=\"NO\"\n"
258
                    disk_info << "]\n"
259
                elsif !image_import[:template].empty?
260
                    # Then the image is created as it's not in the datastore
261
                    one_i = VCenterDriver::VIHelper.new_one_item(OpenNebula::Image)
262

  
263
                    allocated_images << one_i
264

  
265
                    rc = one_i.allocate(image_import[:template], datastore_found['ID'].to_i)
266

  
267
                    if ::OpenNebula.is_error?(rc)
268
                        error = "    Error creating disk from template: #{rc.message}. Cannot import the template\n"
269

  
270
                        #Rollback delete disk images
271
                        allocated_images.each do |i|
272
                            i.delete
273
                        end
274

  
275
                        break
276
                    end
277

  
278
                    #Add info for One template
279
                    one_i.info
280
                    disk_info << "DISK=[\n"
281
                    disk_info << "IMAGE_ID=\"#{one_i["ID"]}\",\n"
282
                    disk_info << "IMAGE_UNAME=\"#{one_i["UNAME"]}\",\n"
283
                    disk_info << "OPENNEBULA_MANAGED=\"NO\"\n"
284
                    disk_info << "]\n"
285
                end
286
            end
287

  
288
        rescue Exception => e
289
            error = "There was an error trying to create an image for disk in vcenter template. Reason: #{e.message}"
290
        ensure
291
            unlock
292
        end
293

  
294
        return error, disk_info
295
    end
296

  
297
    def import_vcenter_nics(vc_uuid, npool)
298
        nic_info = ""
299
        error = ""
300

  
301
        begin
302
            lock #Lock import operation, to avoid concurrent creation of images
303

  
304
            ccr_ref  = self["runtime.host.parent._ref"]
305
            ccr_name = self["runtime.host.parent.name"]
306

  
307
            #Get disks and info required
308
            vc_nics = get_vcenter_nics
309

  
310
            # Track allocated networks
311
            allocated_networks = []
312

  
313
            vc_nics.each do |nic|
314

  
315
                network_found = VCenterDriver::Network.get_one_vnet_ds_by_ref_and_ccr(nic[:net_ref],
316
                                                                                    ccr_ref,
317
                                                                                    vc_uuid,
318
                                                                                    npool)
319
                #Network is already in the datastore
320
                if network_found
321
                    # This is the existing nic info
322
                    nic_info << "NIC=[\n"
323
                    nic_info << "NETWORK_ID=\"#{network_found["ID"]}\",\n"
324
                    nic_info << "OPENNEBULA_MANAGED=\"NO\"\n"
325
                    nic_info << "]\n"
326
                else
327
                    # Then the network has to be created as it's not in OpenNebula
328
                    one_vn = VCenterDriver::VIHelper.new_one_item(OpenNebula::VirtualNetwork)
329

  
330
                    allocated_networks << one_vn
331

  
332
                    one_vnet = VCenterDriver::Network.to_one_template(nic[:net_name],
333
                                                                    nic[:net_ref],
334
                                                                    nic[:pg_type],
335
                                                                    ccr_ref,
336
                                                                    ccr_name,
337
                                                                    vc_uuid)
338

  
339
                    # By default add an ethernet range to network size 255
340
                    ar_str = ""
341
                    ar_str << "AR=[\n"
342
                    ar_str << "TYPE=\"ETHER\",\n"
343
                    ar_str << "SIZE=\"255\"\n"
344
                    ar_str << "]\n"
345
                    one_vnet[:one] << ar_str
346

  
347
                    rc = one_vn.allocate(one_vnet[:one])
348

  
349
                    if ::OpenNebula.is_error?(rc)
350
                        error = "    Error creating virtual network from template: #{rc.message}. Cannot import the template\n"
351

  
352
                        #Rollback, delete virtual networks
353
                        allocated_networks.each do |n|
354
                            n.delete
355
                        end
356

  
357
                        break
358
                    end
359

  
360
                    #Add info for One template
361
                    one_vn.info
362
                    nic_info << "NIC=[\n"
363
                    nic_info << "NETWORK_ID=\"#{one_vn["ID"]}\",\n"
364
                    nic_info << "OPENNEBULA_MANAGED=\"NO\"\n"
365
                    nic_info << "]\n"
366
                end
367
            end
368

  
369
        rescue Exception => e
370
            error = "There was an error trying to create a virtual network for network in vcenter template. Reason: #{e.message}"
371
        ensure
372
            unlock
373
        end
374

  
375
        return error, nic_info
376
    end
377

  
378
    def get_vcenter_disks
379

  
380
        disks = []
381
        @item["config.hardware.device"].each do |device|
382
            disk = {}
383
            if is_disk_or_iso?(device)
384
                disk[:device]    = device
385
                disk[:datastore] = device.backing.datastore
386
                disk[:path]      = device.backing.fileName
387
                disk[:path_wo_ds]= disk[:path].sub(/^\[(.*?)\] /, "")
388
                disk[:type]      = is_disk?(device) ? "OS" : "CDROM"
389
                disks << disk
390
            end
391
        end
392

  
393
        return disks
394
    end
395

  
396
    def get_vcenter_nics
397
        nics = []
398
        @item["config.hardware.device"].each do |device|
399
            nic = {}
400
            if is_nic?(device)
401
                nic[:net_name]  = device.backing.network.name
402
                nic[:net_ref]   = device.backing.network._ref
403
                nic[:pg_type]   = VCenterDriver::Network.get_network_type(device)
404
                nics << nic
405
            end
406
        end
407
        return nics
408
    end
409

  
410
    #  Checks if a RbVmomi::VIM::VirtualDevice is a disk or a cdrom
411
    def is_disk_or_cdrom?(device)
412
        is_disk  = !(device.class.ancestors.index(RbVmomi::VIM::VirtualDisk)).nil?
413
        is_cdrom = !(device.class.ancestors.index(RbVmomi::VIM::VirtualCdrom)).nil?
414
        is_disk || is_cdrom
415
    end
416

  
417
    #  Checks if a RbVmomi::VIM::VirtualDevice is a disk or an iso file
418
    def is_disk_or_iso?(device)
419
        is_disk  = !(device.class.ancestors.index(RbVmomi::VIM::VirtualDisk)).nil?
420
        is_iso = device.backing.is_a? RbVmomi::VIM::VirtualCdromIsoBackingInfo
421
        is_disk || is_iso
422
    end
423

  
424
    #  Checks if a RbVmomi::VIM::VirtualDevice is a disk
425
    def is_disk?(device)
426
        !(device.class.ancestors.index(RbVmomi::VIM::VirtualDisk)).nil?
427
    end
428

  
429
    #  Checks if a RbVmomi::VIM::VirtualDevice is a network interface
430
    def is_nic?(device)
431
        !device.class.ancestors.index(RbVmomi::VIM::VirtualEthernetCard).nil?
432
    end
433

  
434
    # @return RbVmomi::VIM::ResourcePool, first resource pool in cluster
435
    def get_rp
436
        self['runtime.host.parent.resourcePool']
437
    end
438

  
439
    def to_one_template(template, cluster_ref, cluster_name, has_nics_and_disks, rp, rp_list, vcenter_uuid, vcenter_instance_name, dc_name)
440

  
441
        template_ref  = template['_ref']
442
        template_name = template["name"]
443

  
444
        one_tmp = {}
445
        one_tmp[:name]                  = "[#{vcenter_instance_name} - #{dc_name}] #{template_name} - #{cluster_name}"
446
        one_tmp[:template_name]         = template_name
447
        one_tmp[:vcenter_ccr_ref]       = cluster_ref
448
        one_tmp[:vcenter_ref]           = template_ref
449
        one_tmp[:vcenter_instance_uuid] = vcenter_uuid
450
        one_tmp[:cluster_name]          = cluster_name
451
        one_tmp[:rp]                    = rp
452
        one_tmp[:rp_list]               = rp_list
453
        one_tmp[:template]              = template
454
        one_tmp[:import_disks_and_nics] = has_nics_and_disks
455

  
456
        one_tmp[:one]                   = to_one(true, vcenter_uuid, cluster_ref, cluster_name, vcenter_instance_name, dc_name)
457
        return one_tmp
458
    end
459

  
460
    def vm_to_one(vm_name)
461

  
462
        str = "NAME   = \"#{vm_name}\"\n"\
463
              "CPU    = \"#{@vm_info["config.hardware.numCPU"]}\"\n"\
464
              "vCPU   = \"#{@vm_info["config.hardware.numCPU"]}\"\n"\
465
              "MEMORY = \"#{@vm_info["config.hardware.memoryMB"]}\"\n"\
466
              "HYPERVISOR = \"vcenter\"\n"\
467
              "SCHED_REQUIREMENTS=\"ID=\\\"#{@vm_info["host_id"]}\\\"\"\n"\
468
              "CONTEXT = [\n"\
469
              "    NETWORK = \"YES\",\n"\
470
              "    SSH_PUBLIC_KEY = \"$USER[SSH_PUBLIC_KEY]\"\n"\
471
              "]\n"\
472
              "VCENTER_INSTANCE_ID =\"#{@vm_info["vc_uuid"]}\"\n"
473

  
474
        str << "IMPORT_VM_ID =\"#{self["_ref"]}\"\n"
475
        str << "IMPORT_STATE =\"#{@state}\"\n"
476

  
477
        vnc_port = nil
478
        keymap = nil
479

  
480
        @vm_info["config.extraConfig"].select do |xtra|
481
            if xtra[:key].downcase=="remotedisplay.vnc.port"
482
                vnc_port = xtra[:value]
483
            end
484

  
485
            if xtra[:key].downcase=="remotedisplay.vnc.keymap"
486
                keymap = xtra[:value]
487
            end
488
        end
489

  
490
        if !@vm_info["config.extraConfig"].empty?
491
            str << "GRAPHICS = [\n"\
492
                   "  TYPE     =\"vnc\",\n"
493
            str << "  PORT     =\"#{vnc_port}\",\n" if vnc_port
494
            str << "  KEYMAP   =\"#{keymap}\",\n" if keymap
495
            str << "  LISTEN   =\"0.0.0.0\"\n"
496
            str << "]\n"
497
        end
498

  
499
        if !@vm_info["config.annotation"] || @vm_info["config.annotation"].empty?
500
            str << "DESCRIPTION = \"vCenter Template imported by OpenNebula" \
501
                " from Cluster #{@vm_info["cluster_name"]}\"\n"
502
        else
503
            notes = @vm_info["config.annotation"].gsub("\\", "\\\\").gsub("\"", "\\\"")
504
            str << "DESCRIPTION = \"#{notes}\"\n"
505
        end
506

  
507
        case @vm_info["guest.guestFullName"]
508
            when /CentOS/i
509
                str << "LOGO=images/logos/centos.png\n"
510
            when /Debian/i
511
                str << "LOGO=images/logos/debian.png\n"
512
            when /Red Hat/i
513
                str << "LOGO=images/logos/redhat.png\n"
514
            when /Ubuntu/i
515
                str << "LOGO=images/logos/ubuntu.png\n"
516
            when /Windows XP/i
517
                str << "LOGO=images/logos/windowsxp.png\n"
518
            when /Windows/i
519
                str << "LOGO=images/logos/windows8.png\n"
520
            when /Linux/i
521
                str << "LOGO=images/logos/linux.png\n"
522
        end
523

  
524
        return str
525
    end
526

  
527
    def to_one(template=false, vc_uuid=nil, ccr_ref=nil, ccr_name=nil, vcenter_instance_name, dc_name)
528

  
529
        if !ccr_ref && !ccr_name
530
            cluster  = @item["runtime.host"].parent
531
            ccr_name = cluster.name
532
            ccr_ref  = cluster._ref
533
        end
534

  
535
        vc_uuid  = self["_connection.serviceContent.about.instanceUuid"] if !vc_uuid
536

  
537
        # Get info of the host where the VM/template is located
538
        host_id = nil
539
        one_host = VCenterDriver::VIHelper.find_by_ref(OpenNebula::HostPool,
540
                                                       "TEMPLATE/VCENTER_CCR_REF",
541
                                                       ccr_ref,
542
                                                       vc_uuid)
543

  
544
        num_cpu, memory, extraconfig, annotation, guest_fullname = @item.collect("config.hardware.numCPU","config.hardware.memoryMB","config.extraConfig","config.annotation","guest.guestFullName")
545
        host_id = one_host["ID"] if one_host
546

  
547
        name = ""
548
        if template
549
            name << "[#{vcenter_instance_name} - #{dc_name}] #{self["name"]} - #{ccr_name.tr(" ", "_")}"
550
        else
551
            name << "#{self["name"]} - #{ccr_name.tr(" ", "_")}"
552
        end
553

  
554
        str = "NAME   = \"#{name}\"\n"\
555
              "CPU    = \"#{num_cpu}\"\n"\
556
              "vCPU   = \"#{num_cpu}\"\n"\
557
              "MEMORY = \"#{memory}\"\n"\
558
              "HYPERVISOR = \"vcenter\"\n"\
559
              "SCHED_REQUIREMENTS=\"ID=\\\"#{host_id}\\\"\"\n"\
560
              "CONTEXT = [\n"\
561
              "    NETWORK = \"YES\",\n"\
562
              "    SSH_PUBLIC_KEY = \"$USER[SSH_PUBLIC_KEY]\"\n"\
563
              "]\n"\
564
              "VCENTER_INSTANCE_ID =\"#{vc_uuid}\"\n"
565

  
566
        if !template
567
            str << "IMPORT_VM_ID =\"#{self["_ref"]}\"\n"
568
            str << "IMPORT_STATE =\"#{@state}\"\n"
569
        end
570

  
571
        if template
572
            str << "VCENTER_TEMPLATE_REF =\"#{self['_ref']}\"\n"
573
            str << "VCENTER_CCR_REF =\"#{ccr_ref}\"\n"
574
        end
575

  
576
        vnc_port = nil
577
        keymap = nil
578

  
579
        if !template
580
            extraconfig.select do |xtra|
581

  
582
                if xtra[:key].downcase=="remotedisplay.vnc.port"
583
                    vnc_port = xtra[:value]
584
                end
585

  
586
                if xtra[:key].downcase=="remotedisplay.vnc.keymap"
587
                    keymap = xtra[:value]
588
                end
589
            end
590
        end
591

  
592
        if !extraconfig.empty?
593
            str << "GRAPHICS = [\n"\
594
                   "  TYPE     =\"vnc\",\n"
595
            str << "  PORT     =\"#{vnc_port}\",\n" if vnc_port
596
            str << "  KEYMAP   =\"#{keymap}\",\n" if keymap
597
            str << "  LISTEN   =\"0.0.0.0\"\n"
598
            str << "]\n"
599
        end
600

  
601
        if annotation.nil? || annotation.empty?
602
            str << "DESCRIPTION = \"vCenter Template imported by OpenNebula" \
603
                " from Cluster #{ccr_name}\"\n"
604
        else
605
            notes = annotation.gsub("\\", "\\\\").gsub("\"", "\\\"")
606
            str << "DESCRIPTION = \"#{notes}\"\n"
607
        end
608

  
609
        case guest_fullname
610
            when /CentOS/i
611
                str << "LOGO=images/logos/centos.png\n"
612
            when /Debian/i
613
                str << "LOGO=images/logos/debian.png\n"
614
            when /Red Hat/i
615
                str << "LOGO=images/logos/redhat.png\n"
616
            when /Ubuntu/i
617
                str << "LOGO=images/logos/ubuntu.png\n"
618
            when /Windows XP/i
619
                str << "LOGO=images/logos/windowsxp.png\n"
620
            when /Windows/i
621
                str << "LOGO=images/logos/windows8.png\n"
622
            when /Linux/i
623
                str << "LOGO=images/logos/linux.png\n"
624
        end
625

  
626
        return str
627
    end
628

  
629
    def self.get_xml_template(template, vcenter_uuid, vi_client, vcenter_instance_name=nil, dc_name=nil, rp_cache={})
630

  
631
        begin
632
            template_ccr  = template['runtime.host.parent']
633
            template_ccr_ref = template_ccr._ref
634
            template_ccr_name =template_ccr.name
635

  
636
            vcenter_instance_name = vi_client.vim.host if !vcenter_instance_name
637

  
638
            if !dc_name
639
                dc = get_dc
640
                dc_name = dc.item.name
641
            end
642
            # Check if template has nics or disks to be imported later
643
            has_nics_and_disks = true
644
            ##template["config.hardware.device"].each do |device|
645
            ##    if VCenterDriver::Storage.is_disk_or_iso?(device) ||
646
            ##    VCenterDriver::Network.is_nic?(device)
647
            ##        has_nics_and_disks = true
648
            ##        break
649
            ##    end
650
            ##end
651

  
652
            #Get resource pools
653

  
654
            if !rp_cache[template_ccr_name]
655
                tmp_cluster = VCenterDriver::ClusterComputeResource.new_from_ref(template_ccr_ref, vi_client)
656
                rp_list = tmp_cluster.get_resource_pool_list
657
                rp = ""
658
                if !rp_list.empty?
659
                    rp_name_list = []
660
                    rp_list.each do |rp_hash|
661
                        rp_name_list << rp_hash[:name]
662
                    end
663
                    rp =  "O|list|Which resource pool you want this VM to run in? "
664
                    rp << "|#{rp_name_list.join(",")}" #List of RP
665
                    rp << "|#{rp_name_list.first}" #Default RP
666
                end
667
                rp_cache[template_ccr_name] = rp
668
            end
669
            rp = rp_cache[template_ccr_name]
670

  
671
            object = template.to_one_template(template,
672
                                            template_ccr_ref,
673
                                            template_ccr_name,
674
                                            has_nics_and_disks,
675
                                            rp,
676
                                            rp_list,
677
                                            vcenter_uuid,
678
                                            vcenter_instance_name,
679
                                            dc_name)
680

  
681
            return object
682

  
683
        rescue
684
            return nil
685
        end
686
    end
687

  
688
    # TODO check with uuid
689
    def self.new_from_ref(ref, vi_client)
690
        self.new(RbVmomi::VIM::VirtualMachine.new(vi_client.vim, ref), vi_client)
691
    end
692

  
693
end
694

  
695
class VirtualMachine < Template
696
    VM_PREFIX_DEFAULT = "one-$i-"
697

  
698
    POLL_ATTRIBUTE    = OpenNebula::VirtualMachine::Driver::POLL_ATTRIBUTE
699
    VM_STATE          = OpenNebula::VirtualMachine::Driver::VM_STATE
700

  
701
    VM_SHUTDOWN_TIMEOUT = 600 #10 minutes til poweroff hard
702

  
703
    attr_accessor :item
704

  
705
    attr_accessor :vm_info
706

  
707
    include Memoize
708

  
709
    def initialize(item=nil, vi_client=nil)
710
        @item = item
711
        @vi_client = vi_client
712
        @locking = true
713
        @vm_info = nil
714
    end
715

  
80 716
    ############################################################################
81 717
    ############################################################################
82 718

  
......
95 731
    # The OpenNebula VM
96 732
    # @return OpenNebula::VirtualMachine or XMLElement
97 733
    def one_item
98
        if @one_item.nil?
734
        if !@one_item
99 735
            vm_id = get_vm_id
100 736

  
101 737
            raise "Unable to find vm_id." if vm_id.nil?
......
471 1107
        vcenter_disks = get_vcenter_disks
472 1108

  
473 1109
        # Create an array with the paths of the disks in vcenter template
474
        template = VCenterDriver::VirtualMachine.new_from_ref(template_ref, vi_client)
1110
        template = VCenterDriver::Template.new_from_ref(template_ref, vi_client)
475 1111
        template_disks = template.get_vcenter_disks
476 1112
        template_disks_vector = []
477 1113
        template_disks.each_with_index do |d, index|
......
1088 1724
        end
1089 1725
    end
1090 1726

  
1091
    #  Checks if a RbVmomi::VIM::VirtualDevice is a network interface
1092
    def is_nic?(device)
1093
        !device.class.ancestors.index(RbVmomi::VIM::VirtualEthernetCard).nil?
1094
    end
1095

  
1096 1727
    def disks_in_onevm
1097 1728
        onevm_disks_vector = []
1098 1729
        disks = one_item.retrieve_xmlelements("TEMPLATE/DISK")
......
1381 2012
        return nics
1382 2013
    end
1383 2014

  
1384
    def import_vcenter_disks(vc_uuid, dpool, ipool)
1385
        disk_info = ""
1386
        error = ""
1387

  
1388
        begin
1389
            lock #Lock import operation, to avoid concurrent creation of images
1390

  
1391
            ccr_ref = self["runtime.host.parent._ref"]
1392

  
1393
            #Get disks and info required
1394
            vc_disks = get_vcenter_disks
1395

  
1396
            # Track allocated images
1397
            allocated_images = []
1398

  
1399
            vc_disks.each do |disk|
1400

  
1401
                datastore_found = VCenterDriver::Storage.get_one_image_ds_by_ref_and_ccr(disk[:datastore]._ref,
1402
                                                                                        ccr_ref,
1403
                                                                                        vc_uuid,
1404
                                                                                        dpool)
1405
                if datastore_found.nil?
1406
                    error = "    Error datastore #{disk[:datastore].name}: has to be imported first as an image datastore!\n"
1407

  
1408
                    #Rollback delete disk images
1409
                    allocated_images.each do |i|
1410
                        i.delete
1411
                    end
1412

  
1413
                    break
1414
                end
1415

  
1416
                image_import = VCenterDriver::Datastore.get_image_import_template(disk[:datastore].name,
1417
                                                                                disk[:path],
1418
                                                                                disk[:type], ipool)
1419
                #Image is already in the datastore
1420
                if image_import[:one]
1421
                    # This is the disk info
1422
                    disk_info << "DISK=[\n"
1423
                    disk_info << "IMAGE_ID=\"#{image_import[:one]["ID"]}\",\n"
1424
                    disk_info << "OPENNEBULA_MANAGED=\"NO\"\n"
1425
                    disk_info << "]\n"
1426
                elsif !image_import[:template].empty?
1427
                    # Then the image is created as it's not in the datastore
1428
                    one_i = VCenterDriver::VIHelper.new_one_item(OpenNebula::Image)
1429

  
1430
                    allocated_images << one_i
1431

  
1432
                    rc = one_i.allocate(image_import[:template], datastore_found['ID'].to_i)
1433

  
1434
                    if ::OpenNebula.is_error?(rc)
1435
                        error = "    Error creating disk from template: #{rc.message}. Cannot import the template\n"
1436

  
1437
                        #Rollback delete disk images
1438
                        allocated_images.each do |i|
1439
                            i.delete
1440
                        end
1441

  
1442
                        break
1443
                    end
1444

  
1445
                    #Add info for One template
1446
                    one_i.info
1447
                    disk_info << "DISK=[\n"
1448
                    disk_info << "IMAGE_ID=\"#{one_i["ID"]}\",\n"
1449
                    disk_info << "IMAGE_UNAME=\"#{one_i["UNAME"]}\",\n"
1450
                    disk_info << "OPENNEBULA_MANAGED=\"NO\"\n"
1451
                    disk_info << "]\n"
1452
                end
1453
            end
1454

  
1455
        rescue Exception => e
1456
            error = "There was an error trying to create an image for disk in vcenter template. Reason: #{e.message}"
1457
        ensure
1458
            unlock
1459
        end
1460

  
1461
        return error, disk_info
1462
    end
1463

  
1464 2015
    def remove_poweroff_detached_vcenter_nets(networks)
1465 2016
        esx_host = VCenterDriver::ESXHost.new_from_ref(@item.runtime.host._ref, vi_client)
1466 2017
        dc = cluster.get_dc # Get datacenter
......
1518 2069
        end
1519 2070
    end
1520 2071

  
1521
    def import_vcenter_nics(vc_uuid, npool)
1522
        nic_info = ""
1523
        error = ""
1524

  
1525
        begin
1526
            lock #Lock import operation, to avoid concurrent creation of images
1527

  
1528
            ccr_ref  = self["runtime.host.parent._ref"]
1529
            ccr_name = self["runtime.host.parent.name"]
1530

  
1531
            #Get disks and info required
1532
            vc_nics = get_vcenter_nics
1533

  
1534
            # Track allocated networks
1535
            allocated_networks = []
1536

  
1537
            vc_nics.each do |nic|
1538

  
1539
                network_found = VCenterDriver::Network.get_one_vnet_ds_by_ref_and_ccr(nic[:net_ref],
1540
                                                                                    ccr_ref,
1541
                                                                                    vc_uuid,
1542
                                                                                    npool)
1543
                #Network is already in the datastore
1544
                if network_found
1545
                    # This is the existing nic info
1546
                    nic_info << "NIC=[\n"
1547
                    nic_info << "NETWORK_ID=\"#{network_found["ID"]}\",\n"
1548
                    nic_info << "OPENNEBULA_MANAGED=\"NO\"\n"
1549
                    nic_info << "]\n"
1550
                else
1551
                    # Then the network has to be created as it's not in OpenNebula
1552
                    one_vn = VCenterDriver::VIHelper.new_one_item(OpenNebula::VirtualNetwork)
1553

  
1554
                    allocated_networks << one_vn
1555

  
1556
                    one_vnet = VCenterDriver::Network.to_one_template(nic[:net_name],
1557
                                                                    nic[:net_ref],
1558
                                                                    nic[:pg_type],
1559
                                                                    ccr_ref,
1560
                                                                    ccr_name,
1561
                                                                    vc_uuid)
1562

  
1563
                    # By default add an ethernet range to network size 255
1564
                    ar_str = ""
1565
                    ar_str << "AR=[\n"
1566
                    ar_str << "TYPE=\"ETHER\",\n"
1567
                    ar_str << "SIZE=\"255\"\n"
1568
                    ar_str << "]\n"
1569
                    one_vnet[:one] << ar_str
1570

  
1571
                    rc = one_vn.allocate(one_vnet[:one])
1572

  
1573
                    if ::OpenNebula.is_error?(rc)
1574
                        error = "    Error creating virtual network from template: #{rc.message}. Cannot import the template\n"
1575

  
1576
                        #Rollback, delete virtual networks
1577
                        allocated_networks.each do |n|
1578
                            n.delete
1579
                        end
1580

  
1581
                        break
1582
                    end
1583

  
1584
                    #Add info for One template
1585
                    one_vn.info
1586
                    nic_info << "NIC=[\n"
1587
                    nic_info << "NETWORK_ID=\"#{one_vn["ID"]}\",\n"
1588
                    nic_info << "OPENNEBULA_MANAGED=\"NO\"\n"
1589
                    nic_info << "]\n"
1590
                end
1591
            end
1592

  
1593
        rescue Exception => e
1594
            error = "There was an error trying to create a virtual network for network in vcenter template. Reason: #{e.message}"
1595
        ensure
1596
            unlock
1597
        end
1598

  
1599
        return error, nic_info
1600
    end
1601

  
1602
    #  Checks if a RbVmomi::VIM::VirtualDevice is a disk or a cdrom
1603
    def is_disk_or_cdrom?(device)
1604
        is_disk  = !(device.class.ancestors.index(RbVmomi::VIM::VirtualDisk)).nil?
1605
        is_cdrom = !(device.class.ancestors.index(RbVmomi::VIM::VirtualCdrom)).nil?
1606
        is_disk || is_cdrom
1607
    end
1608

  
1609
    #  Checks if a RbVmomi::VIM::VirtualDevice is a disk or an iso file
1610
    def is_disk_or_iso?(device)
1611
        is_disk  = !(device.class.ancestors.index(RbVmomi::VIM::VirtualDisk)).nil?
1612
        is_iso = device.backing.is_a? RbVmomi::VIM::VirtualCdromIsoBackingInfo
1613
        is_disk || is_iso
1614
    end
1615

  
1616
    #  Checks if a RbVmomi::VIM::VirtualDevice is a disk
1617
    def is_disk?(device)
1618
        !(device.class.ancestors.index(RbVmomi::VIM::VirtualDisk)).nil?
1619
    end
1620

  
1621 2072
    def find_free_controller(position=0)
1622 2073
        free_scsi_controllers = []
1623 2074
        scsi_schema           = {}
......
1871 2322
    # monitoring
1872 2323
    ############################################################################
1873 2324

  
1874
    def to_one(template=false)
1875
        cluster  = self["runtime.host.parent.name"]
1876
        ccr_ref  = self["runtime.host.parent._ref"]
1877
        vc_uuid  = self["_connection.serviceContent.about.instanceUuid"]
1878

  
1879
        # Get info of the host where the VM/template is located
1880
        host_id = nil
1881
        one_host = VCenterDriver::VIHelper.find_by_ref(OpenNebula::HostPool,
1882
                                                       "TEMPLATE/VCENTER_CCR_REF",
1883
                                                       ccr_ref,
1884
                                                       vc_uuid)
1885
        host_id = one_host["ID"] if one_host
1886

  
1887
        str = "NAME   = \"#{self["name"]} - #{cluster}\"\n"\
1888
              "CPU    = \"#{@item["config.hardware.numCPU"]}\"\n"\
1889
              "vCPU   = \"#{@item["config.hardware.numCPU"]}\"\n"\
1890
              "MEMORY = \"#{@item["config.hardware.memoryMB"]}\"\n"\
1891
              "HYPERVISOR = \"vcenter\"\n"\
1892
              "SCHED_REQUIREMENTS=\"ID=\\\"#{host_id}\\\"\"\n"\
1893
              "CONTEXT = [\n"\
1894
              "    NETWORK = \"YES\",\n"\
1895
              "    SSH_PUBLIC_KEY = \"$USER[SSH_PUBLIC_KEY]\"\n"\
1896
              "]\n"\
1897
              "VCENTER_INSTANCE_ID =\"#{vc_uuid}\"\n"
1898

  
1899
        if !template
1900
            str << "IMPORT_VM_ID =\"#{self["_ref"]}\"\n"
1901
            str << "IMPORT_STATE =\"#{@state}\"\n"
1902
        end
1903

  
1904
        if template
1905
            str << "VCENTER_TEMPLATE_REF =\"#{self['_ref']}\"\n"
1906
            str << "VCENTER_CCR_REF =\"#{ccr_ref}\"\n"
1907
        end
1908

  
1909
        vnc_port = nil
1910
        keymap = nil
1911

  
1912
        if !template
1913
            @item["config.extraConfig"].select do |xtra|
1914

  
1915
                if xtra[:key].downcase=="remotedisplay.vnc.port"
1916
                    vnc_port = xtra[:value]
1917
                end
1918

  
1919
                if xtra[:key].downcase=="remotedisplay.vnc.keymap"
1920
                    keymap = xtra[:value]
1921
                end
1922
            end
1923
        end
2325
    def monitor(esx_host_cpu, stats)
1924 2326

  
1925
        if @item["config.extraConfig"].size > 0
1926
            str << "GRAPHICS = [\n"\
1927
                   "  TYPE     =\"vnc\",\n"
1928
            str << "  PORT     =\"#{vnc_port}\",\n" if vnc_port
1929
            str << "  KEYMAP   =\"#{keymap}\",\n" if keymap
1930
            str << "  LISTEN   =\"0.0.0.0\"\n"
1931
            str << "]\n"
1932
        end
1933

  
1934
        if @item["config.annotation"].nil? || @item["config.annotation"].empty?
1935
            str << "DESCRIPTION = \"vCenter Template imported by OpenNebula" \
1936
                " from Cluster #{cluster}\"\n"
1937
        else
1938
            notes = @item["config.annotation"].gsub("\\", "\\\\").gsub("\"", "\\\"")
1939
            str << "DESCRIPTION = \"#{notes}\"\n"
1940
        end
1941

  
1942
        case self["guest.guestFullName"]
1943
            when /CentOS/i
1944
                str << "LOGO=images/logos/centos.png\n"
1945
            when /Debian/i
1946
                str << "LOGO=images/logos/debian.png\n"
1947
            when /Red Hat/i
1948
                str << "LOGO=images/logos/redhat.png\n"
1949
            when /Ubuntu/i
1950
                str << "LOGO=images/logos/ubuntu.png\n"
1951
            when /Windows XP/i
1952
                str << "LOGO=images/logos/windowsxp.png\n"
1953
            when /Windows/i
1954
                str << "LOGO=images/logos/windows8.png\n"
1955
            when /Linux/i
1956
                str << "LOGO=images/logos/linux.png\n"
1957
        end
1958

  
1959
        return str
1960
    end
1961

  
1962
    def to_one_template(template, has_nics_and_disks, rp, rp_list, vcenter_uuid)
1963

  
1964
        template_name = template['name']
1965
        template_ref  = template['_ref']
1966
        template_ccr  = template['runtime.host.parent']
1967
        cluster_name  = template['runtime.host.parent.name']
1968

  
1969
        one_tmp = {}
1970
        one_tmp[:name]                  = "#{template_name} - #{cluster_name}"
1971
        one_tmp[:template_name]         = template_name
1972
        one_tmp[:vcenter_ccr_ref]       = template_ccr._ref
1973
        one_tmp[:one]                   = to_one(true)
1974
        one_tmp[:vcenter_ref]           = template_ref
1975
        one_tmp[:vcenter_instance_uuid] = vcenter_uuid
1976
        one_tmp[:cluster_name]          = cluster_name
1977
        one_tmp[:rp]                    = rp
1978
        one_tmp[:rp_list]               = rp_list
1979
        one_tmp[:template]              = template
1980
        one_tmp[:import_disks_and_nics] = has_nics_and_disks
1981
        return one_tmp
1982
    end
1983

  
1984
    def monitor
1985 2327
        reset_monitor
1986 2328

  
1987
        @state = state_to_c(self["summary.runtime.powerState"])
2329
        refresh_rate = 20 #20 seconds between samples (realtime)
1988 2330

  
1989
        if @state != VM_STATE[:active]
1990
            reset_monitor
1991
            return
1992
        end
2331
        @state = state_to_c(@vm_info["summary.runtime.powerState"])
1993 2332

  
1994
        cpuMhz = self["runtime.host.summary.hardware.cpuMhz"].to_f
2333
        return if @state != VM_STATE[:active]
1995 2334

  
1996
        @monitor[:used_memory] = self["summary.quickStats.hostMemoryUsage"] * 1024
2335
        cpuMhz =  esx_host_cpu[@vm_info["runtime.host"]._ref]
1997 2336

  
1998
        used_cpu = self["summary.quickStats.overallCpuUsage"].to_f / cpuMhz
2337
        @monitor[:used_memory] = @vm_info["summary.quickStats.hostMemoryUsage"].to_f * 1024
2338

  
2339
        used_cpu = @vm_info["summary.quickStats.overallCpuUsage"].to_f / cpuMhz
1999 2340
        used_cpu = (used_cpu * 100).to_s
2000 2341
        @monitor[:used_cpu]  = sprintf('%.2f', used_cpu).to_s
2001 2342

  
......
2004 2345
        @monitor[:used_cpu]    = 0 if @monitor[:used_cpu].to_i < 0
2005 2346

  
2006 2347
        guest_ip_addresses = []
2007
        self["guest.net"].each do |net|
2348
        @vm_info["guest.net"].each do |net|
2008 2349
            net.ipConfig.ipAddress.each do |ip|
2009 2350
                guest_ip_addresses << ip.ipAddress
2010 2351
            end if net.ipConfig && net.ipConfig.ipAddress
......
2012 2353

  
2013 2354
        @guest_ip_addresses = guest_ip_addresses.join(',')
2014 2355

  
2015
        ########################################################################
2016
        # PerfManager metrics
2017
        ########################################################################
2018
        pm = self['_connection'].serviceInstance.content.perfManager
2019

  
2020
        provider = pm.provider_summary(@item)
2021

  
2022
        refresh_rate = provider.refreshRate
2356
        if stats.key?(@item)
2357
            metrics = stats[@item][:metrics]
2023 2358

  
2024
        if !get_vm_id
2025
            @nettx       = 0
2026
            @netrx       = 0
2027
            @diskrdbytes = 0
2028
            @diskwrbytes = 0
2029
            @diskrdiops  = 0
2030
            @diskwriops  = 0
2031
        else
2032
            stats = []
2033

  
2034
            if (one_item["MONITORING/LAST_MON"] && one_item["MONITORING/LAST_MON"].to_i != 0 )
2035
                #Real time data stores max 1 hour. 1 minute has 3 samples
2036
                interval = (Time.now.to_i - one_item["MONITORING/LAST_MON"].to_i)
2037

  
2038
                #If last poll was more than hour ago get 3 minutes,
2039
                #else calculate how many samples since last poll
2040
                samples =  interval > 3600 ? 9 : (interval / refresh_rate) + 1
2041
                max_samples = samples > 0 ? samples : 1
2042

  
2043
                stats = pm.retrieve_stats(
2044
                    [@item],
2045
                    ['net.transmitted','net.bytesRx','net.bytesTx','net.received',
2046
                    'virtualDisk.numberReadAveraged','virtualDisk.numberWriteAveraged',
2047
                    'virtualDisk.read','virtualDisk.write'],
2048
                    {interval:refresh_rate, max_samples: max_samples}
2049
                )
2050
            else
2051
                # First poll, get at least latest 3 minutes = 9 samples
2052
                stats = pm.retrieve_stats(
2053
                    [@item],
2054
                    ['net.transmitted','net.bytesRx','net.bytesTx','net.received',
2055
                    'virtualDisk.numberReadAveraged','virtualDisk.numberWriteAveraged',
2056
                    'virtualDisk.read','virtualDisk.write'],
2057
                    {interval:refresh_rate, max_samples: 9}
2058
                )
2359
            nettx_kbpersec = 0
2360
            if metrics['net.transmitted']
2361
                metrics['net.transmitted'].each { |sample|
2362
                    nettx_kbpersec += sample
2363
                }
2059 2364
            end
2060 2365

  
2061
            if stats.empty? || stats.first[1][:metrics].empty?
2062
                @nettx = 0
2063
                @netrx = 0
2064
                @diskrdbytes = 0
2065
                @diskwrbytes = 0
2066
                @diskrdiops = 0
2067
                @diskwriops = 0
2068
            else
2069
                metrics = stats.first[1][:metrics]
2070

  
2071
                nettx_kbpersec = 0
2072
                if metrics['net.transmitted']
2073
                    metrics['net.transmitted'].each { |sample|
2074
                        nettx_kbpersec += sample
2075
                    }
2076
                end
2366
            netrx_kbpersec = 0
2367
            if metrics['net.bytesRx']
2368
                metrics['net.bytesRx'].each { |sample|
2369
                    netrx_kbpersec += sample
2370
                }
2371
            end
2077 2372

  
2078
                netrx_kbpersec = 0
2079
                if metrics['net.bytesRx']
2080
                    metrics['net.bytesRx'].each { |sample|
2081
                        netrx_kbpersec += sample
2082
                    }
2083
                end
2373
            read_kbpersec = 0
2374
            if metrics['virtualDisk.read']
2375
                metrics['virtualDisk.read'].each { |sample|
2376
                    read_kbpersec += sample
2377
                }
2378
            end
2084 2379

  
2085
                read_kbpersec = 0
2086
                if metrics['virtualDisk.read']
2087
                    metrics['virtualDisk.read'].each { |sample|
2088
                        read_kbpersec += sample
2089
                    }
2090
                end
2380
            read_iops = 0
2381
            if metrics['virtualDisk.numberReadAveraged']
2382
                metrics['virtualDisk.numberReadAveraged'].each { |sample|
2383
                    read_iops += sample
2384
                }
2385
            end
2091 2386

  
2092
                read_iops = 0
2093
                if metrics['virtualDisk.numberReadAveraged']
2094
                    metrics['virtualDisk.numberReadAveraged'].each { |sample|
2095
                        read_iops += sample
2096
                    }
2097
                end
2387
            write_kbpersec = 0
2388
            if metrics['virtualDisk.write']
2389
                metrics['virtualDisk.write'].each { |sample|
2390
                    write_kbpersec += sample
2391
                }
2392
            end
2098 2393

  
2099
                write_kbpersec = 0
2100
                if metrics['virtualDisk.write']
2101
                    metrics['virtualDisk.write'].each { |sample|
2102
                        write_kbpersec += sample
2103
                    }
2104
                end
2394
            write_iops = 0
2395
            if metrics['virtualDisk.numberWriteAveraged']
2396
                metrics['virtualDisk.numberWriteAveraged'].each { |sample|
2397
                    write_iops += sample
2398
                }
2399
            end
2105 2400

  
2106
                write_iops = 0
2107
                if metrics['virtualDisk.numberWriteAveraged']
2108
                    metrics['virtualDisk.numberWriteAveraged'].each { |sample|
2109
                        write_iops += sample
2110
                    }
2111
                end
2401
            # Accumulate values if present
2402
            previous_nettx = @one_item && @one_item["MONITORING/NETTX"] ? @one_item["MONITORING/NETTX"].to_i : 0
2403
            previous_netrx = @one_item && @one_item["MONITORING/NETRX"] ? @one_item["MONITORING/NETRX"].to_i : 0
2404
            previous_diskrdiops = @one_item && @one_item["MONITORING/DISKRDIOPS"] ? @one_item["MONITORING/DISKRDIOPS"].to_i : 0
2405
            previous_diskwriops = @one_item && @one_item["MONITORING/DISKWRIOPS"] ? @one_item["MONITORING/DISKWRIOPS"].to_i : 0
2406
            previous_diskrdbytes = @one_item && @one_item["MONITORING/DISKRDBYTES"] ? @one_item["MONITORING/DISKRDBYTES"].to_i : 0
2407
            previous_diskwrbytes = @one_item && @one_item["MONITORING/DISKWRBYTES"] ? @one_item["MONITORING/DISKWRBYTES"].to_i : 0
2112 2408

  
2113
                @nettx = (nettx_kbpersec * 1024 * refresh_rate).to_i
2114
                @netrx = (netrx_kbpersec * 1024 * refresh_rate).to_i
2409
            @monitor[:nettx] = previous_nettx + (nettx_kbpersec * 1024 * refresh_rate).to_i
2410
            @monitor[:netrx] = previous_netrx + (netrx_kbpersec * 1024 * refresh_rate).to_i
2115 2411

  
2116
                @diskrdiops = read_iops
2117
                @diskwriops = write_iops
2118
                @diskrdbytes = (read_kbpersec * 1024 * refresh_rate).to_i
2119
                @diskwrbytes = (write_kbpersec * 1024 * refresh_rate).to_i
2120
                @diskwrbytes = (write_kbpersec * 1024 * refresh_rate).to_i
2121
            end
2412
            @monitor[:diskrdiops]  = previous_diskrdiops + read_iops
2413
            @monitor[:diskwriops]  = previous_diskwriops + write_iops
2414
            @monitor[:diskrdbytes] = previous_diskrdbytes + (read_kbpersec * 1024 * refresh_rate).to_i
2415
            @monitor[:diskwrbytes] = previous_diskwrbytes + (write_kbpersec * 1024 * refresh_rate).to_i
2122 2416
        end
2123 2417
    end
2124 2418

  
2419

  
2420

  
2125 2421
    #  Generates a OpenNebula IM Driver valid string with the monitor info
2126 2422
    def info
2127 2423
        return 'STATE=d' if @state == 'd'
2128 2424

  
2129
        guest_ip = self["guest.ipAddress"]
2425
        guest_ip = @vm_info["guest.ipAddress"]
2130 2426

  
2131 2427
        used_cpu    = @monitor[:used_cpu]
2132 2428
        used_memory = @monitor[:used_memory]
......
2137 2433
        diskrdiops  = @monitor[:diskrdiops]
2138 2434
        diskwriops  = @monitor[:diskwriops]
2139 2435

  
2140
        esx_host      = self["runtime.host.name"].to_s
2141
        guest_state   = self["guest.guestState"].to_s
2142
        vmware_tools  = self["guest.toolsRunningStatus"].to_s
2143
        vmtools_ver   = self["guest.toolsVersion"].to_s
2144
        vmtools_verst = self["guest.toolsVersionStatus2"].to_s
2436
        esx_host      = @vm_info["cluster_name"].to_s
2437
        guest_state   = @vm_info["guest.guestState"].to_s
2438
        vmware_tools  = @vm_info["guest.toolsRunningStatus"].to_s
2439
        vmtools_ver   = @vm_info["guest.toolsVersion"].to_s
2440
        vmtools_verst = @vm_info["guest.toolsVersionStatus2"].to_s
2441
        rp_name       = @vm_info["rp_list"].select { |item| item._ref == self["_ref"]}.first[:name] rescue ""
2442
        rp_name       = "Resources" if rp_name.empty?
2145 2443

  
2146 2444
        str_info = ""
2147 2445

  
......
2151 2449
            str_info << "GUEST_IP_ADDRESSES=\"" << @guest_ip_addresses.to_s << "\" "
2152 2450
        end
2153 2451

  
2154
        str_info << "LAST_MON=" << Time.now.to_i.to_s << " "
2155

  
2156 2452
        str_info << "#{POLL_ATTRIBUTE[:state]}="  << @state               << " "
2157 2453
        str_info << "#{POLL_ATTRIBUTE[:cpu]}="    << used_cpu.to_s        << " "
2158 2454
        str_info << "#{POLL_ATTRIBUTE[:memory]}=" << used_memory.to_s     << " "
......
2169 2465
        str_info << "VCENTER_VMWARETOOLS_RUNNING_STATUS=" << vmware_tools    << " "
2170 2466
        str_info << "VCENTER_VMWARETOOLS_VERSION="        << vmtools_ver     << " "
2171 2467
        str_info << "VCENTER_VMWARETOOLS_VERSION_STATUS=" << vmtools_verst   << " "
2172
        str_info << "VCENTER_RESOURCE_POOL=\""            << self["resourcePool"].name << "\" "
2468
        str_info << "VCENTER_RP_NAME=\""                  << rp_name << "\" "
2173 2469
    end
2174 2470

  
2175 2471
    def reset_monitor

Also available in: Unified diff