opennebula 5.13.80.pre → 6.0.0.2
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 +1 -1
- data/lib/datacenter.rb +69 -34
- data/lib/datastore.rb +2 -2
- data/lib/distributed_firewall.rb +17 -4
- data/lib/network.rb +74 -4
- data/lib/nsx_client.rb +17 -4
- data/lib/nsx_constants.rb +18 -5
- data/lib/nsx_driver.rb +15 -2
- data/lib/nsx_rule.rb +17 -4
- data/lib/nsxt_client.rb +17 -4
- data/lib/nsxv_client.rb +17 -4
- data/lib/opennebula.rb +1 -1
- data/lib/opennebula/client.rb +9 -1
- data/lib/opennebula/flow/service_template.rb +37 -1
- data/lib/opennebula/image.rb +2 -0
- data/lib/opennebula/marketplaceapp_ext.rb +77 -13
- data/lib/opennebula/pool.rb +2 -0
- data/lib/opennebula/template_ext.rb +19 -2
- data/lib/opennebula/virtual_machine.rb +2 -0
- data/lib/opennebula/virtual_machine_ext.rb +35 -17
- data/lib/opennebula/wait_ext.rb +120 -85
- data/lib/scripts_common.rb +3 -0
- data/lib/vcenter_driver.rb +13 -2
- data/lib/vcenter_importer.rb +2 -2
- data/lib/vi_helper.rb +2 -1
- data/lib/virtual_machine.rb +50 -12
- data/lib/vm_template.rb +17 -16
- data/lib/vmm_importer.rb +8 -0
- metadata +6 -6
data/lib/opennebula/wait_ext.rb
CHANGED
@@ -14,19 +14,117 @@
|
|
14
14
|
# limitations under the License. #
|
15
15
|
#--------------------------------------------------------------------------- #
|
16
16
|
|
17
|
-
require 'ffi-rzmq'
|
18
17
|
|
19
18
|
require 'opennebula/host'
|
20
19
|
require 'opennebula/image'
|
21
20
|
require 'opennebula/virtual_machine'
|
22
21
|
|
22
|
+
module OpenNebula::WaitExtEvent
|
23
|
+
def wait_event(ctx, event, timeout)
|
24
|
+
subscriber = ctx.socket(ZMQ::SUB)
|
25
|
+
|
26
|
+
# Create subscriber
|
27
|
+
key = ''
|
28
|
+
content = ''
|
29
|
+
|
30
|
+
subscriber.setsockopt(ZMQ::RCVTIMEO, timeout * 1000)
|
31
|
+
subscriber.setsockopt(ZMQ::SUBSCRIBE, event)
|
32
|
+
subscriber.connect(@client.one_zmq)
|
33
|
+
|
34
|
+
rc = subscriber.recv_string(key)
|
35
|
+
rc = subscriber.recv_string(content) if rc != -1
|
36
|
+
|
37
|
+
return if ZMQ::Util.errno == ZMQ::EAGAIN || rc == -1
|
38
|
+
|
39
|
+
content
|
40
|
+
ensure
|
41
|
+
subscriber.setsockopt(ZMQ::UNSUBSCRIBE, event)
|
42
|
+
subscriber.close
|
43
|
+
end
|
44
|
+
|
45
|
+
def wait2(sstr1, sstr2, timeout = 60, cycles = -1)
|
46
|
+
wfun = OpenNebula::WaitExt::WAIT[self.class]
|
47
|
+
|
48
|
+
# Start with a timeout of 2 seconds, to wait until the first
|
49
|
+
# info.
|
50
|
+
#
|
51
|
+
# The timeout is increased later, to avoid multiple info calls.
|
52
|
+
c_timeout = 2
|
53
|
+
recvs = 0
|
54
|
+
in_state = false
|
55
|
+
|
56
|
+
# Subscribe with timeout seconds
|
57
|
+
#
|
58
|
+
# Subscribe string:
|
59
|
+
#
|
60
|
+
# EVENT STATE element_name/state_str//self.ID
|
61
|
+
#
|
62
|
+
# - element_name: is the element name to find in the message
|
63
|
+
# - self.ID: returns element ID to find in the message
|
64
|
+
ctx = ZMQ::Context.new(1)
|
65
|
+
|
66
|
+
until in_state || (cycles != -1 && recvs >= cycles)
|
67
|
+
content = wait_event(ctx,
|
68
|
+
wfun[:event].call(self, sstr1, sstr2),
|
69
|
+
c_timeout)
|
70
|
+
|
71
|
+
if content && !content.empty?
|
72
|
+
in_state = wfun[:in_state_e].call(sstr1, sstr2, content)
|
73
|
+
|
74
|
+
break if in_state
|
75
|
+
end
|
76
|
+
|
77
|
+
c_timeout *= 10
|
78
|
+
c_timeout = timeout if c_timeout > timeout
|
79
|
+
|
80
|
+
rco = info
|
81
|
+
|
82
|
+
return false if OpenNebula.is_error?(rco)
|
83
|
+
|
84
|
+
in_state = wfun[:in_state].call(self, sstr1, sstr2)
|
85
|
+
|
86
|
+
recvs += 1
|
87
|
+
end
|
88
|
+
|
89
|
+
in_state
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
module OpenNebula::WaitExtPolling
|
95
|
+
def wait2(sstr1, sstr2, timeout = 60, cycles = -1)
|
96
|
+
wfun = OpenNebula::WaitExt::WAIT[self.class]
|
97
|
+
|
98
|
+
stime = 5
|
99
|
+
recvs = 0
|
100
|
+
cycles = timeout / stime
|
101
|
+
in_state = false
|
102
|
+
|
103
|
+
loop do
|
104
|
+
rco = info
|
105
|
+
|
106
|
+
return false if OpenNebula.is_error?(rco)
|
107
|
+
|
108
|
+
in_state = wfun[:in_state].call(self, sstr1, sstr2)
|
109
|
+
|
110
|
+
recvs += 1
|
111
|
+
|
112
|
+
break if in_state || recvs >= cycles
|
113
|
+
|
114
|
+
sleep stime
|
115
|
+
end
|
116
|
+
|
117
|
+
in_state
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
23
122
|
# Module to decorate Wait classes with the following methods:
|
24
123
|
# - Wait
|
25
124
|
#
|
26
125
|
# rubocop:disable Style/ClassAndModuleChildren
|
27
126
|
module OpenNebula::WaitExt
|
28
|
-
|
29
|
-
# Wait classes and the name published in ZMQ
|
127
|
+
# Wait classes and the name published in ZMQ/STATE
|
30
128
|
WAIT = {
|
31
129
|
OpenNebula::Host => {
|
32
130
|
:event => lambda {|o, s1, _s2|
|
@@ -78,7 +176,7 @@ module OpenNebula::WaitExt
|
|
78
176
|
},
|
79
177
|
|
80
178
|
:in_state => lambda {|o, s1, s2|
|
81
|
-
|
179
|
+
obj_s1 = Integer(o['STATE'])
|
82
180
|
inx_s1 = OpenNebula::VirtualMachine::VM_STATE.index(s1)
|
83
181
|
|
84
182
|
obj_s2 = Integer(o['LCM_STATE'])
|
@@ -105,93 +203,30 @@ module OpenNebula::WaitExt
|
|
105
203
|
wait?(obj)
|
106
204
|
|
107
205
|
class << obj
|
206
|
+
begin
|
207
|
+
require 'ffi-rzmq'
|
108
208
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
# @param timeout [Integer] Number of seconds to timeout event recv
|
114
|
-
# @param cycles [Integer] Number of recv cycles. After each one
|
115
|
-
# object status is checked in OpenNebula.
|
116
|
-
# Use -1 (default) to wait forever.
|
117
|
-
def wait(state_str, timeout = 60, cycles = -1)
|
118
|
-
wait2(state_str, '', timeout, cycles)
|
119
|
-
end
|
120
|
-
|
121
|
-
def wait_event(ctx, event, timeout)
|
122
|
-
subscriber = ctx.socket(ZMQ::SUB)
|
123
|
-
|
124
|
-
# Create subscriber
|
125
|
-
key = ''
|
126
|
-
content = ''
|
127
|
-
|
128
|
-
subscriber.setsockopt(ZMQ::RCVTIMEO, timeout * 1000)
|
129
|
-
subscriber.setsockopt(ZMQ::SUBSCRIBE, event)
|
130
|
-
subscriber.connect('tcp://localhost:2101')
|
131
|
-
|
132
|
-
rc = subscriber.recv_string(key)
|
133
|
-
rc = subscriber.recv_string(content) if rc != -1
|
134
|
-
|
135
|
-
return if ZMQ::Util.errno == ZMQ::EAGAIN || rc == -1
|
136
|
-
|
137
|
-
content
|
138
|
-
ensure
|
139
|
-
subscriber.setsockopt(ZMQ::UNSUBSCRIBE, event)
|
140
|
-
subscriber.close
|
141
|
-
end
|
142
|
-
|
143
|
-
def wait2(sstr1, sstr2, timeout = 60, cycles = -1)
|
144
|
-
wfun = WAIT[self.class]
|
145
|
-
|
146
|
-
# Start with a timeout of 2 seconds, to wait until the first
|
147
|
-
# info.
|
148
|
-
#
|
149
|
-
# The timeout is increased later, to avoid multiple info calls.
|
150
|
-
c_timeout = 2
|
151
|
-
recvs = 0
|
152
|
-
in_state = false
|
153
|
-
|
154
|
-
# Subscribe with timeout seconds
|
155
|
-
#
|
156
|
-
# Subscribe string:
|
157
|
-
#
|
158
|
-
# EVENT STATE element_name/state_str//self.ID
|
159
|
-
#
|
160
|
-
# - element_name: is the element name to find in the message
|
161
|
-
# - self.ID: returns element ID to find in the message
|
162
|
-
ctx = ZMQ::Context.new(1)
|
163
|
-
|
164
|
-
until in_state || (cycles != -1 && recvs >= cycles)
|
165
|
-
content = wait_event(ctx,
|
166
|
-
wfun[:event].call(self, sstr1, sstr2),
|
167
|
-
c_timeout)
|
168
|
-
|
169
|
-
if content && !content.empty?
|
170
|
-
in_state = wfun[:in_state_e].call(sstr1, sstr2, content)
|
171
|
-
|
172
|
-
break if in_state
|
173
|
-
end
|
174
|
-
|
175
|
-
c_timeout *= 10
|
176
|
-
c_timeout = timeout if c_timeout > timeout
|
177
|
-
|
178
|
-
rco = info
|
179
|
-
|
180
|
-
return false if OpenNebula.is_error?(rco)
|
181
|
-
|
182
|
-
in_state = wfun[:in_state].call(self, sstr1, sstr2)
|
183
|
-
|
184
|
-
recvs += 1
|
185
|
-
end
|
186
|
-
|
187
|
-
in_state
|
188
|
-
end
|
189
|
-
|
209
|
+
include OpenNebula::WaitExtEvent
|
210
|
+
rescue LoadError
|
211
|
+
include OpenNebula::WaitExtPolling
|
212
|
+
end
|
190
213
|
end
|
191
214
|
|
192
215
|
super
|
193
216
|
end
|
194
217
|
|
218
|
+
# Wait until the element reaches some specific state
|
219
|
+
# It waits until the state can be found in ZMQ event message
|
220
|
+
#
|
221
|
+
# @param state_str [String] State name to wait
|
222
|
+
# @param timeout [Integer] Number of seconds to timeout event recv
|
223
|
+
# @param cycles [Integer] Number of recv cycles. After each one
|
224
|
+
# object status is checked in OpenNebula.
|
225
|
+
# Use -1 (default) to wait forever.
|
226
|
+
def wait(state_str, timeout = 60, cycles = -1)
|
227
|
+
wait2(state_str, '', timeout, cycles)
|
228
|
+
end
|
229
|
+
|
195
230
|
# Check if object has the method wait or not
|
196
231
|
#
|
197
232
|
# @param obj [Object or Class] Object to check class
|
data/lib/scripts_common.rb
CHANGED
@@ -14,6 +14,8 @@
|
|
14
14
|
# limitations under the License. #
|
15
15
|
#--------------------------------------------------------------------------- #
|
16
16
|
|
17
|
+
require 'shellwords'
|
18
|
+
|
17
19
|
module OpenNebula
|
18
20
|
|
19
21
|
# Generic log function
|
@@ -76,6 +78,7 @@ module OpenNebula
|
|
76
78
|
# If a second parameter is present it is used as the error message when
|
77
79
|
# the command fails
|
78
80
|
def self.exec_and_log(command, message=nil, allowed_return_code=0)
|
81
|
+
command = command.shellsplit.shelljoin # escape
|
79
82
|
output=`#{command} 2>&1 1>/dev/null`
|
80
83
|
code=$?.exitstatus
|
81
84
|
|
data/lib/vcenter_driver.rb
CHANGED
@@ -36,14 +36,25 @@ end
|
|
36
36
|
|
37
37
|
ENV['LANG'] = 'C'
|
38
38
|
|
39
|
+
# %%RUBYGEMS_SETUP_BEGIN%%
|
39
40
|
if File.directory?(GEMS_LOCATION)
|
40
41
|
real_gems_path = File.realpath(GEMS_LOCATION)
|
41
42
|
if !defined?(Gem) || Gem.path != [real_gems_path]
|
42
43
|
$LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
|
43
|
-
|
44
|
-
|
44
|
+
|
45
|
+
# Suppress warnings from Rubygems
|
46
|
+
# https://github.com/OpenNebula/one/issues/5379
|
47
|
+
begin
|
48
|
+
verb = $VERBOSE
|
49
|
+
$VERBOSE = nil
|
50
|
+
require 'rubygems'
|
51
|
+
Gem.use_paths(real_gems_path)
|
52
|
+
ensure
|
53
|
+
$VERBOSE = verb
|
54
|
+
end
|
45
55
|
end
|
46
56
|
end
|
57
|
+
# %%RUBYGEMS_SETUP_END%%
|
47
58
|
|
48
59
|
$LOAD_PATH << LIB_LOCATION + '/ruby/vendors/rbvmomi/lib'
|
49
60
|
$LOAD_PATH << LIB_LOCATION + '/ruby'
|
data/lib/vcenter_importer.rb
CHANGED
@@ -496,9 +496,9 @@ module VCenterDriver
|
|
496
496
|
end
|
497
497
|
|
498
498
|
#
|
499
|
-
# Create and allocate a
|
499
|
+
# Create and allocate a OpenNebula Object.
|
500
500
|
#
|
501
|
-
# @param info [String] Info passed to
|
501
|
+
# @param info [String] Info passed to OpenNebula Core.
|
502
502
|
#
|
503
503
|
# @return [&block] the allocated object through a block.
|
504
504
|
#
|
data/lib/vi_helper.rb
CHANGED
@@ -231,10 +231,11 @@ module VCenterDriver
|
|
231
231
|
@ref_hash[attribute][refkey]
|
232
232
|
end
|
233
233
|
|
234
|
+
require 'addressable'
|
234
235
|
def self.find_image_by(att, the_class, path, ds_id, pool = nil)
|
235
236
|
pool = one_pool(the_class, false) if pool.nil?
|
236
237
|
pool.find do |e|
|
237
|
-
e[att] == path &&
|
238
|
+
e[att] == Addressable::URI.escape(path) &&
|
238
239
|
e['DATASTORE_ID'] == ds_id
|
239
240
|
end
|
240
241
|
end
|
data/lib/virtual_machine.rb
CHANGED
@@ -33,14 +33,27 @@ module VCenterDriver
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
# rubocop: disable all
|
37
|
+
# %%RUBYGEMS_SETUP_BEGIN%%
|
38
|
+
if File.directory?(GEMS_LOCATION)
|
39
|
+
real_gems_path = File.realpath(GEMS_LOCATION)
|
40
|
+
if !defined?(Gem) || Gem.path != [real_gems_path]
|
41
|
+
$LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
|
42
|
+
|
43
|
+
# Suppress warnings from Rubygems
|
44
|
+
# https://github.com/OpenNebula/one/issues/5379
|
45
|
+
begin
|
46
|
+
verb = $VERBOSE
|
47
|
+
$VERBOSE = nil
|
40
48
|
require 'rubygems'
|
41
49
|
Gem.use_paths(real_gems_path)
|
50
|
+
ensure
|
51
|
+
$VERBOSE = verb
|
42
52
|
end
|
43
53
|
end
|
54
|
+
end
|
55
|
+
# %%RUBYGEMS_SETUP_END%%
|
56
|
+
# rubocop: enable all
|
44
57
|
|
45
58
|
$LOAD_PATH << RUBY_LIB_LOCATION
|
46
59
|
|
@@ -1041,7 +1054,8 @@ module VCenterDriver
|
|
1041
1054
|
else
|
1042
1055
|
if snapshots?
|
1043
1056
|
error = 'Disk metadata not present and snapshots exist. ' \
|
1044
|
-
'
|
1057
|
+
'Please remove imported VM with "onevm recover ' \
|
1058
|
+
'--delete-db".'
|
1045
1059
|
raise error
|
1046
1060
|
end
|
1047
1061
|
|
@@ -1961,7 +1975,7 @@ module VCenterDriver
|
|
1961
1975
|
end
|
1962
1976
|
|
1963
1977
|
card_spec = {
|
1964
|
-
:key =>
|
1978
|
+
:key => Time.now.utc.strftime('%Y%m%d%M%S%L').to_i,
|
1965
1979
|
:deviceInfo => {
|
1966
1980
|
:label => 'net' + card_num.to_s,
|
1967
1981
|
:summary => pg_name
|
@@ -2107,7 +2121,7 @@ module VCenterDriver
|
|
2107
2121
|
end
|
2108
2122
|
|
2109
2123
|
card_spec = {
|
2110
|
-
:key =>
|
2124
|
+
:key => Time.now.utc.strftime('%Y%m%d%M%S%L').to_i,
|
2111
2125
|
:deviceInfo => {
|
2112
2126
|
:label => 'net' + card_num.to_s,
|
2113
2127
|
:summary => pg_name
|
@@ -2401,6 +2415,15 @@ module VCenterDriver
|
|
2401
2415
|
|
2402
2416
|
# Attach DISK to VM (hotplug)
|
2403
2417
|
def attach_disk(disk)
|
2418
|
+
# Adding a new disk in newer vSphere versions
|
2419
|
+
# automatically cleans all system snapshots
|
2420
|
+
# https://github.com/OpenNebula/one/issues/5409
|
2421
|
+
if snapshots? or one_snapshots?
|
2422
|
+
error_message = 'Existing sytem snapshots, cannot change disks. '
|
2423
|
+
error_message << 'Please remove all snapshots and try again.'
|
2424
|
+
raise error_message
|
2425
|
+
end
|
2426
|
+
|
2404
2427
|
spec_hash = {}
|
2405
2428
|
device_change = []
|
2406
2429
|
|
@@ -2582,6 +2605,12 @@ module VCenterDriver
|
|
2582
2605
|
def detach_disk(disk)
|
2583
2606
|
return unless disk.exists?
|
2584
2607
|
|
2608
|
+
if snapshots? or one_snapshots?
|
2609
|
+
error_message = 'Existing sytem snapshots, cannot change disks. '
|
2610
|
+
error_message << 'Please remove all snapshots and try again.'
|
2611
|
+
raise error_message
|
2612
|
+
end
|
2613
|
+
|
2585
2614
|
spec_hash = {}
|
2586
2615
|
spec_hash[:extraConfig] = [disk.config(:delete)]
|
2587
2616
|
spec_hash[:deviceChange] = [{
|
@@ -2611,15 +2640,15 @@ module VCenterDriver
|
|
2611
2640
|
# - The disk is managed by OpenNebula
|
2612
2641
|
detachable= !(one_vm['LCM_STATE'].to_i == 11 && !disk.managed?)
|
2613
2642
|
detachable &&= disk.exists?
|
2614
|
-
|
2643
|
+
|
2615
2644
|
return unless detachable
|
2616
2645
|
|
2617
2646
|
detach_disk(disk)
|
2618
2647
|
|
2619
2648
|
# Check if we want to keep the non persistent disk
|
2620
2649
|
keep_non_persistent_disks =
|
2621
|
-
VCenterDriver::CONFIG[:keep_non_persistent_disks]
|
2622
|
-
|
2650
|
+
VCenterDriver::CONFIG[:keep_non_persistent_disks]
|
2651
|
+
|
2623
2652
|
return if keep_non_persistent_disks == true
|
2624
2653
|
|
2625
2654
|
disk.destroy
|
@@ -2816,7 +2845,7 @@ module VCenterDriver
|
|
2816
2845
|
# Convert VM to template in vCenter
|
2817
2846
|
mark_as_template
|
2818
2847
|
|
2819
|
-
# Edit the
|
2848
|
+
# Edit the OpenNebula template
|
2820
2849
|
one_client = OpenNebula::Client.new
|
2821
2850
|
template_id = one_item['TEMPLATE/TEMPLATE_ID']
|
2822
2851
|
new_template = OpenNebula::Template.new_with_id(template_id,
|
@@ -2867,6 +2896,15 @@ module VCenterDriver
|
|
2867
2896
|
self['rootSnapshot'] && !self['rootSnapshot'].empty?
|
2868
2897
|
end
|
2869
2898
|
|
2899
|
+
def one_snapshots?
|
2900
|
+
begin
|
2901
|
+
!one_item['TEMPLATE/SNAPSHOT'].nil?
|
2902
|
+
rescue StandardError
|
2903
|
+
# one_item may not be retrieved if deploy_id hasn't been set
|
2904
|
+
false
|
2905
|
+
end
|
2906
|
+
end
|
2907
|
+
|
2870
2908
|
def instantiated_as_persistent?
|
2871
2909
|
begin
|
2872
2910
|
!one_item['TEMPLATE/CLONING_TEMPLATE_ID'].nil?
|
@@ -3032,7 +3070,7 @@ module VCenterDriver
|
|
3032
3070
|
# Create a snapshot for the VM
|
3033
3071
|
def create_snapshot(snap_id, snap_name)
|
3034
3072
|
memory_dumps = true
|
3035
|
-
memory_dumps = CONFIG[:memory_dumps]
|
3073
|
+
memory_dumps = CONFIG[:memory_dumps] unless CONFIG[:memory_dumps].nil?
|
3036
3074
|
|
3037
3075
|
snapshot_hash = {
|
3038
3076
|
:name => snap_id,
|