opennebula 5.1.80.beta1 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/cloud/CloudClient.rb +8 -2
- data/lib/opennebula.rb +1 -1
- data/lib/opennebula/group.rb +2 -10
- data/lib/opennebula/oneflow_client.rb +1 -1
- data/lib/opennebula/pool.rb +9 -4
- data/lib/opennebula/user.rb +11 -2
- data/lib/vcenter_driver.rb +306 -60
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 40bbc901923acb487fd5b753dda85f8677985cdb
|
4
|
+
data.tar.gz: dd3421af744f7a1e25f6c940507297e80b595fe6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2db7146a955358e97698af1f8207623da99d1c4a9b8204380d3483bd9ffacc962b6d4c0d5d5d55dc5a0a49b2602ee2a1a05e021203a02285653aef50c1eaef51
|
7
|
+
data.tar.gz: b0818115d8aebc25f332cdf4585d2bbbd1d9e50f742122442d5aef6d4a61ff9d5211943600a53479e0bbc75e836db1147fd7a4b964286a297658b8ea38e4a077
|
data/lib/cloud/CloudClient.rb
CHANGED
@@ -50,12 +50,17 @@ end
|
|
50
50
|
module CloudClient
|
51
51
|
|
52
52
|
# OpenNebula version
|
53
|
-
VERSION = '5.
|
53
|
+
VERSION = '5.2.0'
|
54
54
|
|
55
55
|
# #########################################################################
|
56
56
|
# Default location for the authentication file
|
57
57
|
# #########################################################################
|
58
|
-
|
58
|
+
|
59
|
+
if ENV["HOME"]
|
60
|
+
DEFAULT_AUTH_FILE = ENV["HOME"]+"/.one/one_auth"
|
61
|
+
else
|
62
|
+
DEFAULT_AUTH_FILE = "/var/lib/one/.one/one_auth"
|
63
|
+
end
|
59
64
|
|
60
65
|
# #########################################################################
|
61
66
|
# Gets authorization credentials from ONE_AUTH or default
|
@@ -63,6 +68,7 @@ module CloudClient
|
|
63
68
|
#
|
64
69
|
# Raises an error if authorization is not found
|
65
70
|
# #########################################################################
|
71
|
+
|
66
72
|
def self.get_one_auth
|
67
73
|
if ENV["ONE_AUTH"] and !ENV["ONE_AUTH"].empty? and
|
68
74
|
File.file?(ENV["ONE_AUTH"])
|
data/lib/opennebula.rb
CHANGED
data/lib/opennebula/group.rb
CHANGED
@@ -331,9 +331,9 @@ module OpenNebula
|
|
331
331
|
@client)
|
332
332
|
|
333
333
|
if udriver
|
334
|
-
rc = group_admin.allocate(uadmin, upasswd, udriver)
|
334
|
+
rc = group_admin.allocate(uadmin, upasswd, udriver, [self.id])
|
335
335
|
else
|
336
|
-
rc = group_admin.allocate(uadmin, upasswd)
|
336
|
+
rc = group_admin.allocate(uadmin, upasswd, nil, [self.id])
|
337
337
|
end
|
338
338
|
|
339
339
|
if OpenNebula.is_error?(rc)
|
@@ -341,14 +341,6 @@ module OpenNebula
|
|
341
341
|
end
|
342
342
|
end
|
343
343
|
|
344
|
-
# Set admin user groups to self
|
345
|
-
rc = group_admin.chgrp(self.id)
|
346
|
-
|
347
|
-
if OpenNebula.is_error?(rc)
|
348
|
-
group_admin.delete
|
349
|
-
return rc
|
350
|
-
end
|
351
|
-
|
352
344
|
rc = self.add_admin(group_admin.id)
|
353
345
|
|
354
346
|
if OpenNebula.is_error?(rc)
|
data/lib/opennebula/pool.rb
CHANGED
@@ -62,19 +62,23 @@ module OpenNebula
|
|
62
62
|
alias_method :info!, :info
|
63
63
|
|
64
64
|
def info_all(xml_method, *args)
|
65
|
-
return xmlrpc_info(xml_method,INFO_ALL
|
65
|
+
return xmlrpc_info(xml_method, INFO_ALL, -1, -1, *args)
|
66
66
|
end
|
67
67
|
|
68
68
|
def info_mine(xml_method, *args)
|
69
|
-
return xmlrpc_info(xml_method,INFO_MINE
|
69
|
+
return xmlrpc_info(xml_method, INFO_MINE, -1, -1, *args)
|
70
70
|
end
|
71
71
|
|
72
72
|
def info_group(xml_method, *args)
|
73
|
-
return xmlrpc_info(xml_method,INFO_GROUP
|
73
|
+
return xmlrpc_info(xml_method, INFO_GROUP, -1, -1, *args)
|
74
|
+
end
|
75
|
+
|
76
|
+
def info_primary_group(xml_method, *args)
|
77
|
+
return xmlrpc_info(xml_method, INFO_PRIMARY_GROUP, -1, -1, *args)
|
74
78
|
end
|
75
79
|
|
76
80
|
def info_filter(xml_method, who, start_id, end_id, *args)
|
77
|
-
return xmlrpc_info(xml_method,who, start_id, end_id, *args)
|
81
|
+
return xmlrpc_info(xml_method, who, start_id, end_id, *args)
|
78
82
|
end
|
79
83
|
|
80
84
|
# Retrieves the monitoring data for all the Objects in the pool
|
@@ -144,6 +148,7 @@ module OpenNebula
|
|
144
148
|
INFO_GROUP = -1
|
145
149
|
INFO_ALL = -2
|
146
150
|
INFO_MINE = -3
|
151
|
+
INFO_PRIMARY_GROUP = -4
|
147
152
|
|
148
153
|
# Iterates over every PoolElement in the Pool and calls the block with a
|
149
154
|
# a PoolElement obtained calling the factory method
|
data/lib/opennebula/user.rb
CHANGED
@@ -98,8 +98,17 @@ module OpenNebula
|
|
98
98
|
# +username+ Name of the new user.
|
99
99
|
#
|
100
100
|
# +password+ Password for the new user
|
101
|
-
|
102
|
-
|
101
|
+
# @param username Username for the new user.
|
102
|
+
# @param password Password for the new user
|
103
|
+
# @param driver Auth driver for the new user.
|
104
|
+
# @param gids Group IDs. The first ID will be used as the main group.
|
105
|
+
# This array can be empty, in which case the default group will be used.
|
106
|
+
#
|
107
|
+
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
108
|
+
# otherwise
|
109
|
+
def allocate(username, password, driver=nil, gids=[])
|
110
|
+
driver = CORE_AUTH if driver.nil?
|
111
|
+
super(USER_METHODS[:allocate], username, password, driver, gids)
|
103
112
|
end
|
104
113
|
|
105
114
|
# Replaces the template contents
|
data/lib/vcenter_driver.rb
CHANGED
@@ -144,6 +144,7 @@ class VIClient
|
|
144
144
|
v.propSet.each{ |dynprop|
|
145
145
|
obj[dynprop.name] = dynprop.val
|
146
146
|
}
|
147
|
+
obj[:ref] = k._ref
|
147
148
|
objects << OpenStruct.new(obj)
|
148
149
|
end
|
149
150
|
}
|
@@ -151,7 +152,7 @@ class VIClient
|
|
151
152
|
end
|
152
153
|
|
153
154
|
############################################################################
|
154
|
-
#
|
155
|
+
# Initialize the VIClient, and creates an OpenNebula client. The parameters
|
155
156
|
# are obtained from the associated OpenNebula host
|
156
157
|
# @param hid [Integer] The OpenNebula host id with VCenter attributes
|
157
158
|
############################################################################
|
@@ -301,6 +302,37 @@ class VIClient
|
|
301
302
|
baseEntity
|
302
303
|
end
|
303
304
|
|
305
|
+
########################################################################
|
306
|
+
# Searches the associated vmFolder of the DataCenter for the current
|
307
|
+
# connection. Returns a RbVmomi::VIM::VirtualMachine or nil if not found
|
308
|
+
#
|
309
|
+
# Searches by moref, name, uuid and then iterates over all VMs
|
310
|
+
#
|
311
|
+
# @param uuid [String] the UUID of the VM or VM Template
|
312
|
+
# @param ref [String] VMware moref
|
313
|
+
# @param name [String] VM name in vCenter
|
314
|
+
########################################################################
|
315
|
+
def find_vm_fast(uuid, ref = nil, name = nil)
|
316
|
+
if ref
|
317
|
+
# It can raise ManagedObjectNotFound
|
318
|
+
begin
|
319
|
+
vm = RbVmomi::VIM::VirtualMachine.new(@dc._connection, ref)
|
320
|
+
return vm if vm.config && vm.config.uuid == uuid
|
321
|
+
rescue => e
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
if name
|
326
|
+
begin
|
327
|
+
vm = @dc.vmFolder.find(name)
|
328
|
+
return vm if vm.config && vm.config.uuid == uuid
|
329
|
+
rescue
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
return find_vm_template(uuid)
|
334
|
+
end
|
335
|
+
|
304
336
|
########################################################################
|
305
337
|
# Searches the associated vmFolder of the DataCenter for the current
|
306
338
|
# connection. Returns a RbVmomi::VIM::VirtualMachine or nil if not found
|
@@ -310,11 +342,7 @@ class VIClient
|
|
310
342
|
version = @vim.serviceContent.about.version
|
311
343
|
|
312
344
|
found_vm = nil
|
313
|
-
|
314
|
-
if version.split(".").first.to_i >= 6
|
315
|
-
found_vm = @dc.vmFolder.findByUuid(uuid, RbVmomi::VIM::VirtualMachine, @dc)
|
316
|
-
end
|
317
|
-
|
345
|
+
found_vm = @dc.vmFolder.findByUuid(uuid, RbVmomi::VIM::VirtualMachine, @dc)
|
318
346
|
return found_vm if found_vm
|
319
347
|
|
320
348
|
vms = VIClient.get_entities(@dc.vmFolder, 'VirtualMachine')
|
@@ -352,6 +380,15 @@ class VIClient
|
|
352
380
|
########################################################################
|
353
381
|
def get_datastore(ds_name)
|
354
382
|
datastores = VIClient.get_entities(@dc.datastoreFolder, 'Datastore')
|
383
|
+
|
384
|
+
storage_pods = VIClient.get_entities(@dc.datastoreFolder, 'StoragePod')
|
385
|
+
storage_pods.each { |sp|
|
386
|
+
storage_pod_datastores = VIClient.get_entities(sp, 'Datastore')
|
387
|
+
if not storage_pod_datastores.empty?
|
388
|
+
datastores.concat(storage_pod_datastores)
|
389
|
+
end
|
390
|
+
}
|
391
|
+
|
355
392
|
ds = datastores.select{|ds| ds.name == ds_name}[0]
|
356
393
|
end
|
357
394
|
|
@@ -430,13 +467,15 @@ class VIClient
|
|
430
467
|
ds = ds_cache[t.datastore[0].to_s]
|
431
468
|
|
432
469
|
one_tmp << {
|
433
|
-
:name
|
434
|
-
:uuid
|
435
|
-
:host
|
436
|
-
:one
|
437
|
-
:ds
|
438
|
-
:default_ds
|
439
|
-
:rp
|
470
|
+
:name => "#{vi_tmp.vm.name} - #{host.cluster_name}",
|
471
|
+
:uuid => vi_tmp.vm.config.uuid,
|
472
|
+
:host => host.cluster_name,
|
473
|
+
:one => vi_tmp.to_one(host),
|
474
|
+
:ds => vi_tmp.to_one_ds(host, ds.name),
|
475
|
+
:default_ds => ds.name,
|
476
|
+
:rp => vi_tmp.to_one_rp(host),
|
477
|
+
:vcenter_ref => vi_tmp.vm._ref,
|
478
|
+
:vcenter_name => vi_tmp.vm.name
|
440
479
|
}
|
441
480
|
end
|
442
481
|
}
|
@@ -513,7 +552,6 @@ class VIClient
|
|
513
552
|
"VN_MAD = \"dummy\"\n" \
|
514
553
|
"VCENTER_TYPE = \"Distributed Port Group\""
|
515
554
|
|
516
|
-
|
517
555
|
default_pc = n.config.defaultPortConfig
|
518
556
|
|
519
557
|
has_vlan = false
|
@@ -540,7 +578,7 @@ class VIClient
|
|
540
578
|
end
|
541
579
|
|
542
580
|
if !vlan_str.empty?
|
543
|
-
vnet_template << "
|
581
|
+
vnet_template << "VLAN_TAGGED_ID=#{vlan_str}\n"
|
544
582
|
end
|
545
583
|
|
546
584
|
one_net = {:name => net_name,
|
@@ -591,6 +629,15 @@ class VIClient
|
|
591
629
|
datacenters.each { |dc|
|
592
630
|
one_tmp = []
|
593
631
|
datastores = VIClient.get_entities(dc.datastoreFolder, 'Datastore')
|
632
|
+
|
633
|
+
storage_pods = VIClient.get_entities(dc.datastoreFolder, 'StoragePod')
|
634
|
+
storage_pods.each { |sp|
|
635
|
+
storage_pod_datastores = VIClient.get_entities(sp, 'Datastore')
|
636
|
+
if not storage_pod_datastores.empty?
|
637
|
+
datastores.concat(storage_pod_datastores)
|
638
|
+
end
|
639
|
+
}
|
640
|
+
|
594
641
|
datastores.each { |ds|
|
595
642
|
next if !ds.is_a? RbVmomi::VIM::Datastore
|
596
643
|
# Find the Cluster from which to access this ds
|
@@ -654,6 +701,15 @@ class VIClient
|
|
654
701
|
|
655
702
|
# Find datastore within datacenter
|
656
703
|
datastores = VIClient.get_entities(dc.datastoreFolder, 'Datastore')
|
704
|
+
|
705
|
+
storage_pods = VIClient.get_entities(dc.datastoreFolder, 'StoragePod')
|
706
|
+
storage_pods.each { |sp|
|
707
|
+
storage_pod_datastores = VIClient.get_entities(sp, 'Datastore')
|
708
|
+
if not storage_pod_datastores.empty?
|
709
|
+
datastores.concat(storage_pod_datastores)
|
710
|
+
end
|
711
|
+
}
|
712
|
+
|
657
713
|
ds = datastores.select{|ds| ds.name == ds_name}[0]
|
658
714
|
next if !ds
|
659
715
|
|
@@ -981,10 +1037,20 @@ class VCenterCachedHost
|
|
981
1037
|
while !datacenter.is_a? RbVmomi::VIM::Datacenter
|
982
1038
|
datacenter = datacenter.parent
|
983
1039
|
end
|
984
|
-
|
1040
|
+
|
985
1041
|
datastores=VIClient.get_entities(
|
986
1042
|
datacenter.datastoreFolder,
|
987
1043
|
'Datastore')
|
1044
|
+
|
1045
|
+
storage_pods = VIClient.get_entities(datacenter.datastoreFolder,
|
1046
|
+
'StoragePod')
|
1047
|
+
storage_pods.each { |sp|
|
1048
|
+
storage_pod_datastores = VIClient.get_entities(sp, 'Datastore')
|
1049
|
+
if not storage_pod_datastores.empty?
|
1050
|
+
datastores.concat(storage_pod_datastores)
|
1051
|
+
end
|
1052
|
+
}
|
1053
|
+
|
988
1054
|
datastores.each { |ds|
|
989
1055
|
@attributes['ds_list'] += ds.name + ","
|
990
1056
|
}
|
@@ -1290,7 +1356,7 @@ class VCenterHost < ::OpenNebula::Host
|
|
1290
1356
|
val[:key]=="opennebula.vm.running"}
|
1291
1357
|
if running_flag.size > 0 and running_flag[0]
|
1292
1358
|
running_flag = running_flag[0][:value]
|
1293
|
-
end
|
1359
|
+
end
|
1294
1360
|
|
1295
1361
|
next if running_flag == "no"
|
1296
1362
|
|
@@ -1345,6 +1411,17 @@ class VCenterHost < ::OpenNebula::Host
|
|
1345
1411
|
|
1346
1412
|
datastores = VIClient.get_entities(client.dc.datastoreFolder,
|
1347
1413
|
'Datastore')
|
1414
|
+
|
1415
|
+
storage_pods = VIClient.get_entities(client.dc.datastoreFolder,
|
1416
|
+
'StoragePod')
|
1417
|
+
|
1418
|
+
storage_pods.each { |sp|
|
1419
|
+
storage_pod_datastores = VIClient.get_entities(sp, 'Datastore')
|
1420
|
+
if not storage_pod_datastores.empty?
|
1421
|
+
datastores.concat(storage_pod_datastores)
|
1422
|
+
end
|
1423
|
+
}
|
1424
|
+
|
1348
1425
|
datastores.each { |ds|
|
1349
1426
|
str_info += "VCENTER_DATASTORE=\"#{ds.name}\"\n"
|
1350
1427
|
}
|
@@ -1383,13 +1460,16 @@ class VCenterVm
|
|
1383
1460
|
# Deploys a VM
|
1384
1461
|
# @xml_text XML representation of the VM
|
1385
1462
|
############################################################################
|
1386
|
-
def self.deploy(xml_text, lcm_state, deploy_id, hostname, datastore = nil
|
1463
|
+
def self.deploy(xml_text, lcm_state, deploy_id, hostname, datastore = nil,
|
1464
|
+
ops = {})
|
1387
1465
|
if lcm_state == "BOOT" || lcm_state == "BOOT_FAILURE"
|
1388
|
-
return clone_vm(xml_text, hostname, datastore)
|
1466
|
+
return clone_vm(xml_text, hostname, datastore, ops)
|
1389
1467
|
else
|
1390
1468
|
hid = VIClient::translate_hostname(hostname)
|
1391
1469
|
connection = VIClient.new(hid)
|
1392
|
-
vm = connection.
|
1470
|
+
vm = connection.find_vm_fast(deploy_id,
|
1471
|
+
ops[:ref],
|
1472
|
+
ops[:name])
|
1393
1473
|
xml = REXML::Document.new xml_text
|
1394
1474
|
|
1395
1475
|
reconfigure_vm(vm, xml, false, hostname)
|
@@ -1428,8 +1508,8 @@ class VCenterVm
|
|
1428
1508
|
detach_attached_disks(vm, disks, hostname) if disks
|
1429
1509
|
end
|
1430
1510
|
|
1431
|
-
# If the VM was instantiated to persistent, convert the VM to
|
1432
|
-
# vCenter VM Template and update the OpenNebula new
|
1511
|
+
# If the VM was instantiated to persistent, convert the VM to
|
1512
|
+
# vCenter VM Template and update the OpenNebula new
|
1433
1513
|
# VM Template to point to the new vCenter VM Template
|
1434
1514
|
if !to_template.nil?
|
1435
1515
|
vm.MarkAsTemplate
|
@@ -1537,18 +1617,28 @@ class VCenterVm
|
|
1537
1617
|
case lcm_state
|
1538
1618
|
when "SHUTDOWN"
|
1539
1619
|
begin
|
1540
|
-
vm.ShutdownGuest
|
1620
|
+
vm.ShutdownGuest
|
1621
|
+
counter = 60*10 # 10 minutes
|
1622
|
+
while counter > 0
|
1623
|
+
break if vm.runtime.powerState == "poweredOff"
|
1624
|
+
counter -= 1
|
1625
|
+
sleep 1
|
1626
|
+
end
|
1541
1627
|
rescue
|
1542
1628
|
end
|
1543
|
-
|
1629
|
+
|
1630
|
+
if vm.runtime.powerState != "poweredOff"
|
1631
|
+
vm.PowerOffVM_Task.wait_for_completion
|
1632
|
+
end
|
1633
|
+
|
1544
1634
|
if keep_disks
|
1545
1635
|
detach_all_disks(vm)
|
1546
1636
|
else
|
1547
1637
|
detach_attached_disks(vm, disks, hostname) if disks
|
1548
1638
|
end
|
1549
1639
|
|
1550
|
-
# If the VM was instantiated to persistent, convert the VM to
|
1551
|
-
# vCenter VM Template and update the OpenNebula new
|
1640
|
+
# If the VM was instantiated to persistent, convert the VM to
|
1641
|
+
# vCenter VM Template and update the OpenNebula new
|
1552
1642
|
# VM Template to point to the new vCenter VM Template
|
1553
1643
|
if !to_template.nil?
|
1554
1644
|
vm.MarkAsTemplate
|
@@ -1576,10 +1666,19 @@ class VCenterVm
|
|
1576
1666
|
|
1577
1667
|
when "SHUTDOWN_POWEROFF", "SHUTDOWN_UNDEPLOY"
|
1578
1668
|
begin
|
1579
|
-
vm.ShutdownGuest
|
1669
|
+
vm.ShutdownGuest
|
1670
|
+
counter = 60*10 # 10 minutes
|
1671
|
+
while counter > 0
|
1672
|
+
break if vm.runtime.powerState == "poweredOff"
|
1673
|
+
counter -= 1
|
1674
|
+
sleep 1
|
1675
|
+
end
|
1580
1676
|
rescue
|
1581
1677
|
end
|
1582
|
-
|
1678
|
+
|
1679
|
+
if vm.runtime.powerState != "poweredOff"
|
1680
|
+
vm.PowerOffVM_Task.wait_for_completion
|
1681
|
+
end
|
1583
1682
|
end
|
1584
1683
|
end
|
1585
1684
|
|
@@ -1793,6 +1892,73 @@ class VCenterVm
|
|
1793
1892
|
end if @vm.guest.net
|
1794
1893
|
|
1795
1894
|
@guest_ip_addresses = guest_ip_addresses.join(',')
|
1895
|
+
|
1896
|
+
# Network metrics - Realtime retrieved by perfManager
|
1897
|
+
pm = @client.vim.serviceInstance.content.perfManager
|
1898
|
+
|
1899
|
+
provider = pm.provider_summary [@vm].first
|
1900
|
+
refresh_rate = provider.refreshRate
|
1901
|
+
|
1902
|
+
vmid = -1
|
1903
|
+
extraconfig_vmid = @vm.config.extraConfig.select{|val|
|
1904
|
+
val[:key]=="opennebula.vm.id"}
|
1905
|
+
if extraconfig_vmid.size > 0 and extraconfig_vmid[0]
|
1906
|
+
vmid = extraconfig_vmid[0][:value].to_i
|
1907
|
+
end
|
1908
|
+
|
1909
|
+
if vmid < 0
|
1910
|
+
@nettx = 0
|
1911
|
+
@netrx = 0
|
1912
|
+
id_not_found = "Could not retrieve VM ID from extra configuration for "\
|
1913
|
+
"vCenter's VM UUID #{@vm.config.uuid}"
|
1914
|
+
else
|
1915
|
+
one_vm = OpenNebula::VirtualMachine.new_with_id(vmid, OpenNebula::Client.new)
|
1916
|
+
one_vm.info
|
1917
|
+
stats = []
|
1918
|
+
|
1919
|
+
if(one_vm["LAST_POLL"] && one_vm["LAST_POLL"].to_i != 0 )
|
1920
|
+
#Real time data stores max 1 hour. 1 minute has 3 samples
|
1921
|
+
interval = (Time.now.to_i - one_vm["LAST_POLL"].to_i)
|
1922
|
+
|
1923
|
+
#If last poll was more than hour ago get 3 minutes,
|
1924
|
+
#else calculate how many samples since last poll
|
1925
|
+
samples = interval > 3600 ? 9 : interval / refresh_rate
|
1926
|
+
max_samples = samples > 0 ? samples : 1
|
1927
|
+
|
1928
|
+
stats = pm.retrieve_stats(
|
1929
|
+
[@vm],
|
1930
|
+
['net.transmitted','net.bytesRx','net.bytesTx','net.received'],
|
1931
|
+
{interval:refresh_rate, max_samples: max_samples}
|
1932
|
+
)
|
1933
|
+
else
|
1934
|
+
# First poll, get at least latest 3 minutes = 9 samples
|
1935
|
+
stats = pm.retrieve_stats(
|
1936
|
+
[@vm],
|
1937
|
+
['net.transmitted','net.bytesRx'],
|
1938
|
+
{interval:refresh_rate, max_samples: 9}
|
1939
|
+
)
|
1940
|
+
end
|
1941
|
+
|
1942
|
+
if stats.empty? || stats.first[1][:metrics].empty?
|
1943
|
+
@nettx = 0
|
1944
|
+
@netrx = 0
|
1945
|
+
else
|
1946
|
+
metrics = stats.first[1][:metrics]
|
1947
|
+
|
1948
|
+
nettx_kbpersec = 0
|
1949
|
+
metrics['net.transmitted'].each { |sample|
|
1950
|
+
nettx_kbpersec += sample
|
1951
|
+
}
|
1952
|
+
|
1953
|
+
netrx_kbpersec = 0
|
1954
|
+
metrics['net.bytesRx'].each { |sample|
|
1955
|
+
netrx_kbpersec += sample
|
1956
|
+
}
|
1957
|
+
|
1958
|
+
@nettx = (nettx_kbpersec * 1024 * refresh_rate).to_i
|
1959
|
+
@netrx = (netrx_kbpersec * 1024 * refresh_rate).to_i
|
1960
|
+
end
|
1961
|
+
end
|
1796
1962
|
end
|
1797
1963
|
|
1798
1964
|
########################################################################
|
@@ -1835,6 +2001,8 @@ class VCenterVm
|
|
1835
2001
|
"PUBLIC_CLOUD = [\n"\
|
1836
2002
|
" TYPE =\"vcenter\",\n"\
|
1837
2003
|
" VM_TEMPLATE =\"#{@vm.config.uuid}\",\n"\
|
2004
|
+
" VCENTER_REF =\"#{@vm.ref}\",\n"\
|
2005
|
+
" VCENTER_NAME=\"#{@vm.name}\",\n"\
|
1838
2006
|
" HOST =\"#{cluster_name}\"\n"\
|
1839
2007
|
"]\n"\
|
1840
2008
|
"GRAPHICS = [\n"\
|
@@ -2015,7 +2183,7 @@ private
|
|
2015
2183
|
########################################################################
|
2016
2184
|
# Returns the spec to reconfig a VM and add a NIC
|
2017
2185
|
########################################################################
|
2018
|
-
def self.calculate_addnic_spec(vm, mac, bridge, model)
|
2186
|
+
def self.calculate_addnic_spec(vm, mac, bridge, model, limit=nil, rsrv=nil)
|
2019
2187
|
model = model.nil? ? nil : model.downcase
|
2020
2188
|
network = vm.runtime.host.network.select{|n| n.name==bridge}
|
2021
2189
|
backing = nil
|
@@ -2065,24 +2233,40 @@ private
|
|
2065
2233
|
:port => port)
|
2066
2234
|
end
|
2067
2235
|
|
2068
|
-
|
2069
|
-
|
2070
|
-
|
2071
|
-
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2236
|
+
card_spec = {
|
2237
|
+
:key => 0,
|
2238
|
+
:deviceInfo => {
|
2239
|
+
:label => "net" + card_num.to_s,
|
2240
|
+
:summary => bridge
|
2241
|
+
},
|
2242
|
+
:backing => backing,
|
2243
|
+
:addressType => mac ? 'manual' : 'generated',
|
2244
|
+
:macAddress => mac
|
2245
|
+
}
|
2246
|
+
|
2247
|
+
if (limit or rsrv) and (limit > 0)
|
2248
|
+
ra_spec = Hash.new
|
2249
|
+
rsrv = limit if rsrv > limit
|
2250
|
+
ra_spec[:limit] = limit if limit
|
2251
|
+
ra_spec[:reservation] = rsrv if rsrv
|
2252
|
+
ra_spec[:share] = RbVmomi::VIM.SharesInfo({
|
2253
|
+
:level => RbVmomi::VIM.SharesLevel("normal"),
|
2254
|
+
:shares => 0
|
2255
|
+
})
|
2256
|
+
card_spec[:resourceAllocation] =
|
2257
|
+
RbVmomi::VIM.VirtualEthernetCardResourceAllocation(ra_spec)
|
2258
|
+
end
|
2259
|
+
|
2260
|
+
return {
|
2261
|
+
:operation => :add,
|
2262
|
+
:device => nic_card.new(card_spec)
|
2079
2263
|
}
|
2080
2264
|
end
|
2081
2265
|
|
2082
2266
|
########################################################################
|
2083
2267
|
# Clone a vCenter VM Template and leaves it powered on
|
2084
2268
|
########################################################################
|
2085
|
-
def self.clone_vm(xml_text, hostname, datastore)
|
2269
|
+
def self.clone_vm(xml_text, hostname, datastore, ops = {})
|
2086
2270
|
|
2087
2271
|
host_id = VCenterDriver::VIClient.translate_hostname(hostname)
|
2088
2272
|
|
@@ -2144,7 +2328,7 @@ private
|
|
2144
2328
|
raise "Cannot find host id in deployment file history." if hid.nil?
|
2145
2329
|
|
2146
2330
|
connection = VIClient.new(hid)
|
2147
|
-
vc_template = connection.
|
2331
|
+
vc_template = connection.find_vm_fast(uuid, ops[:ref], ops[:name])
|
2148
2332
|
|
2149
2333
|
# Find out requested and available resource pool
|
2150
2334
|
|
@@ -2179,6 +2363,16 @@ private
|
|
2179
2363
|
if datastore
|
2180
2364
|
datastores = VIClient.get_entities(connection.dc.datastoreFolder,
|
2181
2365
|
'Datastore')
|
2366
|
+
|
2367
|
+
storage_pods = VIClient.get_entities(connection.dc.datastoreFolder,
|
2368
|
+
'StoragePod')
|
2369
|
+
storage_pods.each { |sp|
|
2370
|
+
storage_pod_datastores = VIClient.get_entities(sp, 'Datastore')
|
2371
|
+
if not storage_pod_datastores.empty?
|
2372
|
+
datastores.concat(storage_pod_datastores)
|
2373
|
+
end
|
2374
|
+
}
|
2375
|
+
|
2182
2376
|
ds = datastores.select{|ds| ds.name == datastore}[0]
|
2183
2377
|
raise "Cannot find datastore #{datastore}" if !ds
|
2184
2378
|
end
|
@@ -2410,7 +2604,24 @@ private
|
|
2410
2604
|
mac = nic.elements["MAC"].text
|
2411
2605
|
bridge = nic.elements["BRIDGE"].text
|
2412
2606
|
model = nic.elements["MODEL"] ? nic.elements["MODEL"].text : nil
|
2413
|
-
|
2607
|
+
limit_in = nic.elements["INBOUND_PEAK_BW"] ? nic.elements["INBOUND_PEAK_BW"].text : ""
|
2608
|
+
limit_out = nic.elements["OUTBOUND_PEAK_BW"] ? nic.elements["OUTBOUND_PEAK_BW"].text : ""
|
2609
|
+
limit = nil
|
2610
|
+
if !limit_in.empty? or !limit_out.empty?
|
2611
|
+
limit=([limit_in.to_i, limit_out.to_i].min / 1024) * 8
|
2612
|
+
end
|
2613
|
+
rsrv_in = nic.elements["INBOUND_AVG_BW"] ? nic.elements["INBOUND_AVG_BW"].text : ""
|
2614
|
+
rsrv_out = nic.elements["OUTBOUND_AVG_BW"] ? nic.elements["OUTBOUND_AVG_BW"].text : ""
|
2615
|
+
rsrv = nil
|
2616
|
+
if !rsrv_in.empty? or !rsrv_out.empty?
|
2617
|
+
rsrv=([rsrv_in.to_i, rsrv_out.to_i].min / 1024) * 8
|
2618
|
+
end
|
2619
|
+
nic_array << calculate_addnic_spec(vm,
|
2620
|
+
mac,
|
2621
|
+
bridge,
|
2622
|
+
model,
|
2623
|
+
limit,
|
2624
|
+
rsrv)
|
2414
2625
|
}
|
2415
2626
|
|
2416
2627
|
device_change += nic_array
|
@@ -2421,7 +2632,7 @@ private
|
|
2421
2632
|
disks = xml.root.get_elements("/VM/TEMPLATE/DISK")
|
2422
2633
|
disk_spec = {}
|
2423
2634
|
|
2424
|
-
# If the VM is not new, avoid
|
2635
|
+
# If the VM is not new, avoid reading DISKS
|
2425
2636
|
if !newvm
|
2426
2637
|
vm.config.hardware.device.select { |d|
|
2427
2638
|
if is_disk?(d)
|
@@ -2490,6 +2701,16 @@ private
|
|
2490
2701
|
# Find datastore within datacenter
|
2491
2702
|
datastores = VIClient.get_entities(connection.dc.datastoreFolder,
|
2492
2703
|
'Datastore')
|
2704
|
+
|
2705
|
+
storage_pods = VIClient.get_entities(connection.dc.datastoreFolder,
|
2706
|
+
'StoragePod')
|
2707
|
+
storage_pods.each { |sp|
|
2708
|
+
storage_pod_datastores = VIClient.get_entities(sp, 'Datastore')
|
2709
|
+
if not storage_pod_datastores.empty?
|
2710
|
+
datastores.concat(storage_pod_datastores)
|
2711
|
+
end
|
2712
|
+
}
|
2713
|
+
|
2493
2714
|
ds = datastores.select{|ds| ds.name == ds_name}[0]
|
2494
2715
|
|
2495
2716
|
controller, new_number = find_free_controller(vm)
|
@@ -2500,22 +2721,48 @@ private
|
|
2500
2721
|
:fileName => "[#{ds_name}] #{img_name}"
|
2501
2722
|
)
|
2502
2723
|
|
2503
|
-
cd = vm.config.hardware.device.select {|hw|
|
2724
|
+
cd = vm.config.hardware.device.select {|hw|
|
2504
2725
|
hw.class == RbVmomi::VIM::VirtualCdrom}.first
|
2505
|
-
|
2506
|
-
|
2507
|
-
|
2508
|
-
|
2509
|
-
|
2510
|
-
|
2511
|
-
|
2512
|
-
|
2513
|
-
|
2514
|
-
|
2515
|
-
|
2516
|
-
|
2517
|
-
|
2518
|
-
|
2726
|
+
|
2727
|
+
# If no CDROM drive present, we need to add it
|
2728
|
+
if !cd
|
2729
|
+
controller, new_unit_number = find_free_controller(vm)
|
2730
|
+
cdrom_drive_spec = RbVmomi::VIM.VirtualMachineConfigSpec(
|
2731
|
+
:deviceChange => [{
|
2732
|
+
:operation => :add,
|
2733
|
+
:device => RbVmomi::VIM::VirtualCdrom(
|
2734
|
+
:backing => vmdk_backing,
|
2735
|
+
:key => -1,
|
2736
|
+
:controllerKey => 15000,
|
2737
|
+
:unitNumber => 0,
|
2738
|
+
:connectable => RbVmomi::VIM::VirtualDeviceConnectInfo(
|
2739
|
+
:startConnected => true,
|
2740
|
+
:connected => true,
|
2741
|
+
:allowGuestControl => true
|
2742
|
+
)
|
2743
|
+
)}]
|
2744
|
+
)
|
2745
|
+
|
2746
|
+
vm.ReconfigVM_Task(:spec =>
|
2747
|
+
cdrom_drive_spec).wait_for_completion
|
2748
|
+
|
2749
|
+
return
|
2750
|
+
else
|
2751
|
+
device = RbVmomi::VIM::VirtualCdrom(
|
2752
|
+
backing: vmdk_backing,
|
2753
|
+
key: cd.key,
|
2754
|
+
controllerKey: cd.controllerKey,
|
2755
|
+
connectable: RbVmomi::VIM::VirtualDeviceConnectInfo(
|
2756
|
+
startConnected: true,
|
2757
|
+
connected: true,
|
2758
|
+
allowGuestControl: true
|
2759
|
+
)
|
2760
|
+
)
|
2761
|
+
device_config_spec = RbVmomi::VIM::VirtualDeviceConfigSpec(
|
2762
|
+
:device => device,
|
2763
|
+
:operation => RbVmomi::VIM::VirtualDeviceConfigSpecOperation('edit')
|
2764
|
+
)
|
2765
|
+
end
|
2519
2766
|
else
|
2520
2767
|
vmdk_backing = RbVmomi::VIM::VirtualDiskFlatVer2BackingInfo(
|
2521
2768
|
:datastore => ds,
|
@@ -2639,7 +2886,6 @@ private
|
|
2639
2886
|
|
2640
2887
|
############################################################################
|
2641
2888
|
# Detach a specific disk from a VM
|
2642
|
-
# Attach disk to a VM
|
2643
2889
|
# @params hostname[String] vcenter cluster name in opennebula as host
|
2644
2890
|
# @params deploy_id[String] deploy id of the vm
|
2645
2891
|
# @params ds_name[String] name of the datastore
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opennebula
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OpenNebula
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -134,9 +134,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
134
134
|
version: '0'
|
135
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
|
-
- - "
|
137
|
+
- - ">="
|
138
138
|
- !ruby/object:Gem::Version
|
139
|
-
version:
|
139
|
+
version: '0'
|
140
140
|
requirements: []
|
141
141
|
rubyforge_project:
|
142
142
|
rubygems_version: 2.5.1
|