opennebula 5.12.13 → 5.13.80.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/ActionManager.rb +1 -1
- data/lib/CommandManager.rb +1 -1
- data/lib/DriverExecHelper.rb +44 -28
- data/lib/OpenNebulaDriver.rb +8 -4
- data/lib/VirtualMachineDriver.rb +9 -2
- data/lib/cloud/CloudClient.rb +3 -3
- data/lib/datacenter.rb +1258 -0
- data/lib/datastore.rb +1025 -0
- data/lib/distributed_firewall.rb +280 -0
- data/lib/file_helper.rb +370 -0
- data/lib/host.rb +1517 -0
- data/lib/logical_port.rb +50 -0
- data/lib/logical_switch.rb +77 -0
- data/lib/memoize.rb +74 -0
- data/lib/models/role.rb +39 -8
- data/lib/models/service.rb +92 -31
- data/lib/models.rb +5 -5
- data/lib/network.rb +635 -0
- data/lib/nsx_client.rb +144 -0
- data/lib/nsx_component.rb +28 -0
- data/lib/nsx_constants.rb +149 -0
- data/lib/nsx_driver.rb +78 -0
- data/lib/nsx_error.rb +77 -0
- data/lib/nsx_rule.rb +193 -0
- data/lib/nsxt_client.rb +176 -0
- data/lib/nsxt_dfw.rb +196 -0
- data/lib/nsxt_logical_port.rb +94 -0
- data/lib/nsxt_rule.rb +188 -0
- data/lib/nsxt_tz.rb +38 -0
- data/lib/nsxv_client.rb +176 -0
- data/lib/nsxv_dfw.rb +202 -0
- data/lib/nsxv_logical_port.rb +107 -0
- data/lib/nsxv_rule.rb +172 -0
- data/lib/nsxv_tz.rb +41 -0
- data/lib/opaque_network.rb +134 -0
- data/lib/opennebula/acl.rb +1 -1
- data/lib/opennebula/acl_pool.rb +1 -1
- data/lib/opennebula/client.rb +1 -1
- data/lib/opennebula/cluster.rb +1 -1
- data/lib/opennebula/cluster_pool.rb +1 -1
- data/lib/opennebula/datastore.rb +1 -1
- data/lib/opennebula/datastore_pool.rb +1 -1
- data/lib/opennebula/document.rb +8 -29
- data/lib/opennebula/document_json.rb +42 -12
- data/lib/opennebula/document_pool.rb +1 -1
- data/lib/opennebula/document_pool_json.rb +1 -1
- data/lib/opennebula/error.rb +4 -1
- data/lib/opennebula/flow/grammar.rb +1195 -0
- data/lib/{models → opennebula/flow}/service_pool.rb +26 -2
- data/lib/{models → opennebula/flow}/service_template.rb +86 -17
- data/lib/opennebula/flow/service_template_ext.rb +84 -0
- data/lib/{models → opennebula/flow}/service_template_pool.rb +1 -1
- data/lib/opennebula/flow/validator.rb +499 -0
- data/lib/opennebula/flow.rb +23 -0
- data/lib/opennebula/group.rb +1 -1
- data/lib/opennebula/group_pool.rb +1 -1
- data/lib/opennebula/hook.rb +5 -12
- data/lib/opennebula/hook_log.rb +1 -1
- data/lib/opennebula/hook_pool.rb +1 -1
- data/lib/opennebula/host.rb +1 -1
- data/lib/opennebula/host_pool.rb +1 -1
- data/lib/opennebula/image.rb +17 -14
- data/lib/opennebula/image_pool.rb +1 -1
- data/lib/opennebula/ldap_auth.rb +1 -1
- data/lib/opennebula/ldap_auth_spec.rb +1 -1
- data/lib/opennebula/lockable_ext.rb +163 -0
- data/lib/opennebula/marketplace.rb +1 -1
- data/lib/opennebula/marketplace_pool.rb +1 -1
- data/lib/opennebula/marketplaceapp.rb +9 -119
- data/lib/opennebula/marketplaceapp_ext.rb +522 -0
- data/lib/opennebula/marketplaceapp_pool.rb +1 -1
- data/lib/opennebula/oneflow_client.rb +4 -3
- data/lib/opennebula/pool.rb +4 -3
- data/lib/opennebula/pool_element.rb +1 -1
- data/lib/opennebula/security_group.rb +1 -1
- data/lib/opennebula/security_group_pool.rb +1 -1
- data/lib/opennebula/server_cipher_auth.rb +1 -1
- data/lib/opennebula/server_x509_auth.rb +1 -1
- data/lib/opennebula/ssh_auth.rb +1 -1
- data/lib/opennebula/system.rb +1 -1
- data/lib/opennebula/template.rb +4 -13
- data/lib/opennebula/template_ext.rb +325 -0
- data/lib/opennebula/template_pool.rb +1 -1
- data/lib/opennebula/user.rb +26 -2
- data/lib/opennebula/user_pool.rb +1 -1
- data/lib/opennebula/utils.rb +1 -1
- data/lib/opennebula/vdc.rb +1 -1
- data/lib/opennebula/vdc_pool.rb +1 -1
- data/lib/opennebula/virtual_machine.rb +25 -207
- data/lib/opennebula/virtual_machine_ext.rb +469 -0
- data/lib/opennebula/virtual_machine_pool.rb +1 -5
- data/lib/opennebula/virtual_network.rb +4 -10
- data/lib/opennebula/virtual_network_pool.rb +1 -1
- data/lib/opennebula/virtual_router.rb +4 -12
- data/lib/opennebula/virtual_router_pool.rb +1 -1
- data/lib/opennebula/vm_group.rb +4 -11
- data/lib/opennebula/vm_group_pool.rb +1 -1
- data/lib/opennebula/vntemplate.rb +4 -13
- data/lib/opennebula/vntemplate_pool.rb +1 -1
- data/lib/opennebula/wait_ext.rb +222 -0
- data/lib/opennebula/x509_auth.rb +1 -1
- data/lib/opennebula/xml_element.rb +1 -1
- data/lib/opennebula/xml_pool.rb +1 -1
- data/lib/opennebula/xml_utils.rb +1 -1
- data/lib/opennebula/zone.rb +1 -1
- data/lib/opennebula/zone_pool.rb +1 -1
- data/lib/opennebula.rb +5 -2
- data/lib/rest_client.rb +201 -0
- data/lib/scripts_common.rb +180 -0
- data/lib/transport_zone.rb +43 -0
- data/lib/vcenter_driver.rb +9 -22
- data/lib/vcenter_importer.rb +616 -0
- data/lib/vi_client.rb +281 -0
- data/lib/vi_helper.rb +312 -0
- data/lib/virtual_machine.rb +3477 -0
- data/lib/virtual_wire.rb +158 -0
- data/lib/vm_device.rb +80 -0
- data/lib/vm_disk.rb +202 -0
- data/lib/vm_folder.rb +69 -0
- data/lib/vm_helper.rb +30 -0
- data/lib/vm_monitor.rb +303 -0
- data/lib/vm_nic.rb +70 -0
- data/lib/vm_template.rb +1961 -0
- data/lib/vmm_importer.rb +121 -0
- metadata +101 -35
@@ -1,5 +1,5 @@
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
2
|
-
# Copyright 2002-
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
3
3
|
# #
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
data/lib/opennebula/ldap_auth.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# ---------------------------------------------------------------------------- #
|
2
|
-
# Copyright 2002-
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
3
3
|
# #
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# ---------------------------------------------------------------------------- #
|
2
|
-
# Copyright 2002-
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
3
3
|
# #
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
3
|
+
# #
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
5
|
+
# not use this file except in compliance with the License. You may obtain #
|
6
|
+
# a copy of the License at #
|
7
|
+
# #
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0 #
|
9
|
+
# #
|
10
|
+
# Unless required by applicable law or agreed to in writing, software #
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
13
|
+
# See the License for the specific language governing permissions and #
|
14
|
+
# limitations under the License. #
|
15
|
+
#--------------------------------------------------------------------------- #
|
16
|
+
|
17
|
+
require 'date'
|
18
|
+
|
19
|
+
require 'opennebula/document'
|
20
|
+
require 'opennebula/hook'
|
21
|
+
require 'opennebula/image'
|
22
|
+
require 'opennebula/marketplaceapp'
|
23
|
+
require 'opennebula/template'
|
24
|
+
require 'opennebula/virtual_machine'
|
25
|
+
require 'opennebula/virtual_network'
|
26
|
+
require 'opennebula/virtual_router'
|
27
|
+
require 'opennebula/vm_group'
|
28
|
+
require 'opennebula/vntemplate'
|
29
|
+
|
30
|
+
# Module to decorate Lockable classes with the following methods:
|
31
|
+
# - Lock
|
32
|
+
# - Unlock
|
33
|
+
# - Synchronize
|
34
|
+
#
|
35
|
+
# rubocop:disable Style/ClassAndModuleChildren
|
36
|
+
module OpenNebula::LockableExt
|
37
|
+
|
38
|
+
# Expire timeout for locking operation
|
39
|
+
LOCK_TIMEOUT = 120
|
40
|
+
|
41
|
+
def self.make_lockable(obj, methods)
|
42
|
+
obj.instance_variable_set(:@lock_method, methods[:lock])
|
43
|
+
obj.instance_variable_set(:@unlock_method, methods[:unlock])
|
44
|
+
|
45
|
+
obj.extend(OpenNebula::LockableExt)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.extend_object(obj)
|
49
|
+
lockable?(obj)
|
50
|
+
|
51
|
+
class << obj
|
52
|
+
|
53
|
+
# Locks the object
|
54
|
+
#
|
55
|
+
# @param level [Integer] Lock level
|
56
|
+
# @param test [Boolean] Check if the object is already locked
|
57
|
+
#
|
58
|
+
# use -> level = 1
|
59
|
+
# manage -> level = 2
|
60
|
+
# admin -> level = 3
|
61
|
+
# all -> level = 4
|
62
|
+
#
|
63
|
+
# @return [Integer, OpenNebula::Error]
|
64
|
+
# - Object ID if the lock was granted
|
65
|
+
# - Error otherwise
|
66
|
+
def lock(level, test = false)
|
67
|
+
return Error.new('ID not defined') unless @pe_id
|
68
|
+
|
69
|
+
@client.call(@lock_method, @pe_id, level, test)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Unlocks this object
|
73
|
+
#
|
74
|
+
# @return [nil, OpenNebula::Error]
|
75
|
+
# - nil in case of success
|
76
|
+
# - Error otherwise
|
77
|
+
def unlock
|
78
|
+
@client.call(@unlock_method, @pe_id)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Executes an operation with lock granted
|
82
|
+
#
|
83
|
+
# @param level [Integer] Lock level
|
84
|
+
#
|
85
|
+
# @return [Operation rc, OpenNebula::Error]
|
86
|
+
# - Operation return code
|
87
|
+
# - Error otherwise
|
88
|
+
def synchronize(level)
|
89
|
+
rc = lock(level, true)
|
90
|
+
|
91
|
+
if OpenNebula.is_error?(rc)
|
92
|
+
# If test check, core returns timestamp when it was locked
|
93
|
+
lock_time = Time.at(Integer(rc.message.split(' ')[1]))
|
94
|
+
c_time = Time.now
|
95
|
+
|
96
|
+
# If the timeout has not yet expired, return error
|
97
|
+
if (c_time - lock_time) < LOCK_TIMEOUT
|
98
|
+
return Error.new('Object is locked')
|
99
|
+
end
|
100
|
+
|
101
|
+
rc = lock(level)
|
102
|
+
|
103
|
+
return rc if OpenNebula.is_error?(rc)
|
104
|
+
end
|
105
|
+
|
106
|
+
ret = yield if block_given?
|
107
|
+
|
108
|
+
unless OpenNebula.is_error?(info)
|
109
|
+
rc = unlock
|
110
|
+
|
111
|
+
return rc if OpenNebula.is_error?(rc)
|
112
|
+
end
|
113
|
+
|
114
|
+
ret
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
super
|
120
|
+
end
|
121
|
+
|
122
|
+
# Check if object is lockable or not
|
123
|
+
#
|
124
|
+
# @param obj [Object or Class] Object to check class
|
125
|
+
def self.lockable?(obj)
|
126
|
+
# Lockable classes
|
127
|
+
lockable = [
|
128
|
+
OpenNebula::Document,
|
129
|
+
OpenNebula::Hook,
|
130
|
+
OpenNebula::Image,
|
131
|
+
OpenNebula::MarketPlaceApp,
|
132
|
+
OpenNebula::Template,
|
133
|
+
OpenNebula::VirtualMachine,
|
134
|
+
OpenNebula::VirtualNetwork,
|
135
|
+
OpenNebula::VirtualRouter,
|
136
|
+
OpenNebula::VMGroup,
|
137
|
+
OpenNebula::VNTemplate
|
138
|
+
]
|
139
|
+
|
140
|
+
# Get obj class to find parents in lockable class
|
141
|
+
# rubocop:disable Style/TernaryParentheses
|
142
|
+
(obj.is_a? Class) ? o_class = obj : o_class = obj.class
|
143
|
+
# rubocop:enable Style/TernaryParentheses
|
144
|
+
|
145
|
+
found = false
|
146
|
+
i_class = o_class
|
147
|
+
|
148
|
+
while i_class
|
149
|
+
if lockable.include?(i_class)
|
150
|
+
found = true
|
151
|
+
break
|
152
|
+
end
|
153
|
+
|
154
|
+
i_class = i_class.superclass
|
155
|
+
end
|
156
|
+
|
157
|
+
return if found
|
158
|
+
|
159
|
+
raise StandardError, "Cannot extend #{o_class} with LockableExt"
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
# rubocop:enable Style/ClassAndModuleChildren
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
2
|
-
# Copyright 2002-
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
3
3
|
# #
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
2
|
-
# Copyright 2002-
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
3
3
|
# #
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
2
|
-
# Copyright 2002-
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
3
3
|
# #
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
@@ -14,6 +14,8 @@
|
|
14
14
|
# limitations under the License. #
|
15
15
|
#--------------------------------------------------------------------------- #
|
16
16
|
|
17
|
+
require 'opennebula/lockable_ext'
|
18
|
+
require 'opennebula/marketplaceapp_ext'
|
17
19
|
require 'opennebula/pool_element'
|
18
20
|
|
19
21
|
module OpenNebula
|
@@ -47,7 +49,10 @@ module OpenNebula
|
|
47
49
|
'DISABLED' => 'dis'
|
48
50
|
}
|
49
51
|
|
50
|
-
MARKETPLACEAPP_TYPES = %w{UNKNOWN
|
52
|
+
MARKETPLACEAPP_TYPES = %w{UNKNOWN
|
53
|
+
IMAGE
|
54
|
+
VMTEMPLATE
|
55
|
+
SERVICE_TEMPLATE}
|
51
56
|
|
52
57
|
SHORT_MARKETPLACEAPP_TYPES = {
|
53
58
|
'UNKNOWN' => 'unk',
|
@@ -75,6 +80,8 @@ module OpenNebula
|
|
75
80
|
|
76
81
|
# Class constructor
|
77
82
|
def initialize(xml, client)
|
83
|
+
LockableExt.make_lockable(self, MARKETPLACEAPP_METHODS)
|
84
|
+
|
78
85
|
super(xml, client)
|
79
86
|
end
|
80
87
|
|
@@ -158,92 +165,6 @@ module OpenNebula
|
|
158
165
|
call(MARKETPLACEAPP_METHODS[:rename], @pe_id, name)
|
159
166
|
end
|
160
167
|
|
161
|
-
# Exports this app to a suitable OpenNebula object
|
162
|
-
# @param appid [Integer] id of the marketplace app
|
163
|
-
# @param options [Hash] to control the export behavior
|
164
|
-
# dsid [Integer] datastore to save images
|
165
|
-
# name [String] of the new object
|
166
|
-
# vmtemplate_name [String] name for the VM Template, if the App has one
|
167
|
-
#
|
168
|
-
# @return [Hash, OpenNebula::Error] with the ID and type of the created
|
169
|
-
# objects. Instead of an ID, the array may contain OpenNebula::Error with
|
170
|
-
# specific object creation errors
|
171
|
-
# { :vm => [ vm ids/OpenNebula::Error ],
|
172
|
-
# :vmtemplate => [ vmtemplates ids/OpenNebula::Error ],
|
173
|
-
# :image => [ vm ids/OpenNebula::Error ] }
|
174
|
-
def export(options = {})
|
175
|
-
rc = info
|
176
|
-
return rc if OpenNebula.is_error?(rc)
|
177
|
-
return Error.new('App is not READY') if state_str != 'READY'
|
178
|
-
|
179
|
-
if options[:dsid].nil? && type_str != 'VMTEMPLATE'
|
180
|
-
return Error.new('Missing datastore id')
|
181
|
-
end
|
182
|
-
|
183
|
-
return Error.new('Missing name to export app') if options[:name].nil?
|
184
|
-
|
185
|
-
if !self['APPTEMPLATE64'].nil?
|
186
|
-
tmpl = Base64.decode64(self['APPTEMPLATE64'])
|
187
|
-
else
|
188
|
-
tmpl = ''
|
189
|
-
end
|
190
|
-
|
191
|
-
name = options[:name] || "marketapp-#{id}"
|
192
|
-
options[:vmtemplate_name] = name unless options[:vmtemplate_name]
|
193
|
-
|
194
|
-
tmpl << "\n"
|
195
|
-
tmpl << 'NAME="' << name << "\"\n"
|
196
|
-
tmpl << 'FROM_APP="' << self['ID'] << "\"\n"
|
197
|
-
tmpl << 'URL_ARGS="' << options[:url_args] << "\"\n" if options[:url_args]
|
198
|
-
|
199
|
-
case type_str
|
200
|
-
when 'IMAGE'
|
201
|
-
image = Image.new(Image.build_xml, @client)
|
202
|
-
rc = image.allocate(tmpl, options[:dsid])
|
203
|
-
|
204
|
-
ds = OpenNebula::Datastore.new_with_id(options[:dsid], @client)
|
205
|
-
|
206
|
-
rc_image = image.info
|
207
|
-
rc_ds = ds.info
|
208
|
-
|
209
|
-
image_error = OpenNebula.is_error?(rc_image)
|
210
|
-
ds_error = OpenNebula.is_error?(rc_ds)
|
211
|
-
|
212
|
-
xpath = 'TEMPLATE/DRIVER'
|
213
|
-
format = self['FORMAT']
|
214
|
-
type = ds[xpath]
|
215
|
-
|
216
|
-
if !image_error && !ds_error
|
217
|
-
if type == 'vcenter' && format == 'qcow2'
|
218
|
-
image.replace('DEV_PREFIX' => 'sd')
|
219
|
-
image.delete_element('TEMPLATE/FORMAT')
|
220
|
-
image.delete_element('TEMPLATE/DRIVER')
|
221
|
-
|
222
|
-
image.update(image.template_like_str("TEMPLATE"))
|
223
|
-
elsif type == 'vcenter' && format != 'iso' && format != 'vmdk'
|
224
|
-
image.replace('FORMAT' => 'vmdk')
|
225
|
-
elsif type && type != 'vcenter' && format == 'vmdk'
|
226
|
-
image.replace('FORMAT' => type)
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
return { :image => [rc] } if OpenNebula.is_error?(rc)
|
231
|
-
|
232
|
-
vmtpl_id = create_vmtemplate(options, image.id)
|
233
|
-
|
234
|
-
return { :image => [image.id], :vmtemplate => [vmtpl_id] }
|
235
|
-
|
236
|
-
when 'VMTEMPLATE'
|
237
|
-
# TODO import all the images associated to a VMTEMPLATE app
|
238
|
-
# current version only support no-image based apps (e.g. hybrid)
|
239
|
-
vmtpl_id = create_vmtemplate(options)
|
240
|
-
|
241
|
-
return { :image => [], :vmtemplate => [vmtpl_id] }
|
242
|
-
else
|
243
|
-
return Error.new("App type #{type_str} not supported")
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
168
|
# Enables this app
|
248
169
|
def enable
|
249
170
|
call(MARKETPLACEAPP_METHODS[:enable], @pe_id, true)
|
@@ -288,37 +209,6 @@ module OpenNebula
|
|
288
209
|
SHORT_MARKETPLACEAPP_STATES[state_str]
|
289
210
|
end
|
290
211
|
|
291
|
-
# Locked a MarketplaceApp
|
292
|
-
def lock(level)
|
293
|
-
call(MARKETPLACEAPP_METHODS[:lock], @pe_id, level)
|
294
|
-
end
|
295
|
-
|
296
|
-
# Unlocked a MarketplaceApp
|
297
|
-
def unlock()
|
298
|
-
call(MARKETPLACEAPP_METHODS[:unlock], @pe_id)
|
299
|
-
end
|
300
|
-
|
301
|
-
private
|
302
|
-
|
303
|
-
# Creates a VM template based on the VMTEMPLATE64 attribute
|
304
|
-
# @return [Integer, OpenNebula::Error] template id or error
|
305
|
-
# TODO this method needs to be extended to support [image_ids]
|
306
|
-
def create_vmtemplate(options, image_id = nil)
|
307
|
-
return -1 if self['TEMPLATE/VMTEMPLATE64'].nil?
|
308
|
-
|
309
|
-
tmpl = Base64.decode64(self['TEMPLATE/VMTEMPLATE64'])
|
310
|
-
|
311
|
-
tmpl << "\nNAME=\"#{options[:vmtemplate_name]}\"\n"
|
312
|
-
tmpl << "DISK=[ IMAGE_ID = #{image_id} ]\n" if image_id
|
313
|
-
|
314
|
-
vmtpl = Template.new(Template.build_xml, @client)
|
315
|
-
rc = vmtpl.allocate(tmpl)
|
316
|
-
|
317
|
-
return rc if OpenNebula.is_error?(rc)
|
318
|
-
|
319
|
-
vmtpl.id
|
320
|
-
end
|
321
|
-
|
322
212
|
end
|
323
213
|
|
324
214
|
end
|