opennebula 6.4.2 → 6.5.90.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/CommandManager.rb +9 -6
- data/lib/OpenNebulaDriver.rb +1 -1
- data/lib/VirtualMachineDriver.rb +27 -13
- data/lib/cloud/CloudClient.rb +1 -1
- data/lib/datastore.rb +13 -0
- data/lib/file_helper.rb +1 -1
- data/lib/models/role.rb +46 -0
- data/lib/opennebula/datastore.rb +3 -2
- data/lib/opennebula/image.rb +32 -22
- data/lib/opennebula/ldap_auth.rb +1 -1
- data/lib/opennebula/virtual_machine.rb +30 -2
- data/lib/opennebula/virtual_machine_ext.rb +0 -206
- data/lib/opennebula/virtual_network.rb +32 -3
- data/lib/opennebula.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f734e466405bed6ee99e84f442bbc112c1a23c68429c645ded3229960210f5a4
|
4
|
+
data.tar.gz: 3dbb527542e8511a470806802c64325294bba4d81fa0ccdeee6aeb4c3d2ec614
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '091f3cc8bd459ae3d9f555d69ca68e205992a0ad56edf6860ee916656a5b40e35e27dde7d8832ede3d31df9a37d16cc9c456e043f9b28bfdf27b9c7e2560811a'
|
7
|
+
data.tar.gz: 594aba3bb33a77eef46cd30e8f6de24cb3139d88bbaec2991c20e4ec4889a399c3f46ba9957911340abba2c3138e6e6a7e2e3f943ec05a0cb8eeaf03ff991b0e
|
data/lib/CommandManager.rb
CHANGED
@@ -212,19 +212,22 @@ end
|
|
212
212
|
# Executes commands in a remote machine ussing ssh. See documentation
|
213
213
|
# for GenericCommand
|
214
214
|
class SSHCommand < GenericCommand
|
215
|
-
|
215
|
+
|
216
|
+
attr_accessor :host, :ssh_opts
|
216
217
|
|
217
218
|
# Creates a command and runs it
|
218
|
-
def self.run(command, host, logger=nil, stdin=nil, timeout=nil)
|
219
|
-
cmd=self.new(command, host, logger, stdin, timeout)
|
219
|
+
def self.run(command, host, logger=nil, stdin=nil, timeout=nil, ssh_opts='')
|
220
|
+
cmd=self.new(command, host, logger, stdin, timeout, ssh_opts)
|
220
221
|
cmd.run
|
221
222
|
cmd
|
222
223
|
end
|
223
224
|
|
224
225
|
# This one takes another parameter. +host+ is the machine
|
225
226
|
# where the command is going to be executed
|
226
|
-
def initialize(command, host, logger=nil, stdin=nil, timeout=nil)
|
227
|
+
def initialize(command, host, logger=nil, stdin=nil, timeout=nil, ssh_opts='')
|
227
228
|
@host=host
|
229
|
+
@ssh_opts = ssh_opts
|
230
|
+
|
228
231
|
super(command, logger, stdin, timeout)
|
229
232
|
end
|
230
233
|
|
@@ -232,10 +235,10 @@ private
|
|
232
235
|
|
233
236
|
def execute
|
234
237
|
if @stdin
|
235
|
-
capture3_timeout("ssh #{@host} #{@command}",
|
238
|
+
capture3_timeout("ssh #{@ssh_opts} #{@host} #{@command}",
|
236
239
|
:pgroup => true, :stdin_data => @stdin)
|
237
240
|
else
|
238
|
-
capture3_timeout("ssh -n #{@host} #{@command}",
|
241
|
+
capture3_timeout("ssh -n #{@ssh_opts} #{@host} #{@command}",
|
239
242
|
:pgroup => true)
|
240
243
|
end
|
241
244
|
end
|
data/lib/OpenNebulaDriver.rb
CHANGED
@@ -108,7 +108,7 @@ class OpenNebulaDriver < ActionManager
|
|
108
108
|
@timeout)
|
109
109
|
elsif options[:ssh_stream]
|
110
110
|
if options[:stdin]
|
111
|
-
cmdin = "cat << EOT | #{command}"
|
111
|
+
cmdin = "cat << 'EOT' | #{command}"
|
112
112
|
stdin = "#{options[:stdin]}\nEOT\n"
|
113
113
|
else
|
114
114
|
cmdin = command
|
data/lib/VirtualMachineDriver.rb
CHANGED
@@ -53,7 +53,9 @@ class VirtualMachineDriver < OpenNebulaDriver
|
|
53
53
|
:resize_disk => "RESIZEDISK",
|
54
54
|
:update_sg => "UPDATESG",
|
55
55
|
:update_conf => "UPDATECONF",
|
56
|
-
:resize => "RESIZE"
|
56
|
+
:resize => "RESIZE",
|
57
|
+
:backup => "BACKUP",
|
58
|
+
:update_nic => "UPDATENIC"
|
57
59
|
}
|
58
60
|
|
59
61
|
POLL_ATTRIBUTE = OpenNebula::VirtualMachine::Driver::POLL_ATTRIBUTE
|
@@ -76,23 +78,23 @@ class VirtualMachineDriver < OpenNebulaDriver
|
|
76
78
|
|
77
79
|
super(directory, @options)
|
78
80
|
|
79
|
-
@hosts
|
80
|
-
|
81
|
-
register_action(ACTION[:deploy].to_sym,
|
82
|
-
register_action(ACTION[:shutdown].to_sym,
|
83
|
-
register_action(ACTION[:reboot].to_sym,
|
84
|
-
register_action(ACTION[:reset].to_sym,
|
85
|
-
register_action(ACTION[:cancel].to_sym,
|
86
|
-
register_action(ACTION[:save].to_sym,
|
87
|
-
register_action(ACTION[:restore].to_sym,
|
88
|
-
register_action(ACTION[:migrate].to_sym,
|
89
|
-
register_action(ACTION[:poll].to_sym,
|
81
|
+
@hosts = Array.new
|
82
|
+
|
83
|
+
register_action(ACTION[:deploy].to_sym, method("deploy"))
|
84
|
+
register_action(ACTION[:shutdown].to_sym, method("shutdown"))
|
85
|
+
register_action(ACTION[:reboot].to_sym, method("reboot"))
|
86
|
+
register_action(ACTION[:reset].to_sym, method("reset"))
|
87
|
+
register_action(ACTION[:cancel].to_sym, method("cancel"))
|
88
|
+
register_action(ACTION[:save].to_sym, method("save"))
|
89
|
+
register_action(ACTION[:restore].to_sym, method("restore"))
|
90
|
+
register_action(ACTION[:migrate].to_sym, method("migrate"))
|
91
|
+
register_action(ACTION[:poll].to_sym, method("poll"))
|
90
92
|
register_action(ACTION[:attach_disk].to_sym, method("attach_disk"))
|
91
93
|
register_action(ACTION[:detach_disk].to_sym, method("detach_disk"))
|
92
94
|
register_action(ACTION[:snapshot_create].to_sym, method("snapshot_create"))
|
93
95
|
register_action(ACTION[:snapshot_revert].to_sym, method("snapshot_revert"))
|
94
96
|
register_action(ACTION[:snapshot_delete].to_sym, method("snapshot_delete"))
|
95
|
-
register_action(ACTION[:cleanup].to_sym,
|
97
|
+
register_action(ACTION[:cleanup].to_sym, method("cleanup"))
|
96
98
|
register_action(ACTION[:attach_nic].to_sym, method("attach_nic"))
|
97
99
|
register_action(ACTION[:detach_nic].to_sym, method("detach_nic"))
|
98
100
|
register_action(ACTION[:disk_snapshot_create].to_sym, method("disk_snapshot_create"))
|
@@ -100,6 +102,8 @@ class VirtualMachineDriver < OpenNebulaDriver
|
|
100
102
|
register_action(ACTION[:update_sg].to_sym, method("update_sg"))
|
101
103
|
register_action(ACTION[:update_conf].to_sym, method("update_conf"))
|
102
104
|
register_action(ACTION[:resize].to_sym, method("resize"))
|
105
|
+
register_action(ACTION[:backup].to_sym, method("backup"))
|
106
|
+
register_action(ACTION[:update_nic].to_sym, method("update_nic"))
|
103
107
|
end
|
104
108
|
|
105
109
|
# Decodes the encoded XML driver message received from the core
|
@@ -234,6 +238,16 @@ class VirtualMachineDriver < OpenNebulaDriver
|
|
234
238
|
send_message(ACTION[:resize],RESULT[:failure],id,error)
|
235
239
|
end
|
236
240
|
|
241
|
+
def backup(id, drv_message)
|
242
|
+
error = "Action not implemented by driver #{self.class}"
|
243
|
+
send_message(ACTION[:backup],RESULT[:failure],id,error)
|
244
|
+
end
|
245
|
+
|
246
|
+
def update_nic(id, drv_message)
|
247
|
+
error = "Action not implemented by driver #{self.class}"
|
248
|
+
send_message(ACTION[:update_nic],RESULT[:failure],id,error)
|
249
|
+
end
|
250
|
+
|
237
251
|
private
|
238
252
|
|
239
253
|
# Interface to handle the pending events from the ActionManager Interface
|
data/lib/cloud/CloudClient.rb
CHANGED
data/lib/datastore.rb
CHANGED
@@ -14,6 +14,19 @@
|
|
14
14
|
# limitations under the License. #
|
15
15
|
#--------------------------------------------------------------------------- #
|
16
16
|
|
17
|
+
# Ruby 3.x+ deprecated URI.escape, however rbvmomi still relies on it
|
18
|
+
|
19
|
+
if RUBY_VERSION.split('.')[0].to_i >= 3
|
20
|
+
# Monkey patch the escape functionality
|
21
|
+
module URI
|
22
|
+
|
23
|
+
def self.escape(url)
|
24
|
+
URI::Parser.new.escape url
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
17
30
|
##############################################################################
|
18
31
|
# Module VCenterDriver
|
19
32
|
##############################################################################
|
data/lib/file_helper.rb
CHANGED
data/lib/models/role.rb
CHANGED
@@ -455,6 +455,9 @@ module OpenNebula
|
|
455
455
|
extra_template << "\nSERVICE_ID = #{@service.id}"
|
456
456
|
extra_template << "\nROLE_NAME = \"#{@body['name']}\""
|
457
457
|
|
458
|
+
# Evaluate attributes with parent roles
|
459
|
+
evaluate(extra_template)
|
460
|
+
|
458
461
|
n_nodes.times do
|
459
462
|
vm_name = @@vm_name_template
|
460
463
|
.gsub('$SERVICE_ID', @service.id.to_s)
|
@@ -1168,6 +1171,49 @@ module OpenNebula
|
|
1168
1171
|
new_cardinality
|
1169
1172
|
end
|
1170
1173
|
|
1174
|
+
# Evaluate rules that references to parent roles
|
1175
|
+
#
|
1176
|
+
# @param template [String] Role template with $ to replace
|
1177
|
+
def evaluate(template)
|
1178
|
+
client = service.client
|
1179
|
+
|
1180
|
+
template.scan(/\$\{(.*?)\}/).flatten.each do |value|
|
1181
|
+
s_value = value.split('.') # 0 -> parent, 1..N -> XPATH
|
1182
|
+
|
1183
|
+
# If parent not found, instead of error, replace it by blank
|
1184
|
+
unless parents.include?(s_value[0])
|
1185
|
+
template.gsub!("${#{value}}", '')
|
1186
|
+
next
|
1187
|
+
end
|
1188
|
+
|
1189
|
+
found = false
|
1190
|
+
p_nodes = service.roles[s_value[0]].nodes
|
1191
|
+
xpath = "//#{s_value[1..-1].join('/').upcase}"
|
1192
|
+
|
1193
|
+
# Iterate over parent nodes to find the XPATH on their template
|
1194
|
+
p_nodes.each do |node|
|
1195
|
+
id = node['deploy_id']
|
1196
|
+
vm = OpenNebula::VirtualMachine.new_with_id(id, client)
|
1197
|
+
|
1198
|
+
# If error continue searching in other nodes
|
1199
|
+
next if OpenNebula.is_error?(vm.info)
|
1200
|
+
|
1201
|
+
next unless vm[xpath]
|
1202
|
+
|
1203
|
+
template.gsub!("${#{value}}", vm[xpath])
|
1204
|
+
|
1205
|
+
# If found, continue with next expression
|
1206
|
+
found = true
|
1207
|
+
break
|
1208
|
+
end
|
1209
|
+
|
1210
|
+
next if found
|
1211
|
+
|
1212
|
+
# If value not found, replace it by blank to avoid issues
|
1213
|
+
template.gsub!("${#{value}}", '')
|
1214
|
+
end
|
1215
|
+
end
|
1216
|
+
|
1171
1217
|
end
|
1172
1218
|
|
1173
1219
|
end
|
data/lib/opennebula/datastore.rb
CHANGED
@@ -34,12 +34,13 @@ module OpenNebula
|
|
34
34
|
:enable => "datastore.enable"
|
35
35
|
}
|
36
36
|
|
37
|
-
DATASTORE_TYPES=%w{IMAGE SYSTEM FILE}
|
37
|
+
DATASTORE_TYPES=%w{IMAGE SYSTEM FILE BACKUP}
|
38
38
|
|
39
39
|
SHORT_DATASTORE_TYPES = {
|
40
40
|
"IMAGE" => "img",
|
41
41
|
"SYSTEM"=> "sys",
|
42
|
-
"FILE" => "fil"
|
42
|
+
"FILE" => "fil",
|
43
|
+
"BACKUP"=> "bck"
|
43
44
|
}
|
44
45
|
|
45
46
|
DATASTORE_STATES=%w{READY DISABLED}
|
data/lib/opennebula/image.rb
CHANGED
@@ -26,20 +26,21 @@ module OpenNebula
|
|
26
26
|
#######################################################################
|
27
27
|
|
28
28
|
IMAGE_METHODS = {
|
29
|
-
:info
|
30
|
-
:allocate
|
31
|
-
:update
|
32
|
-
:enable
|
33
|
-
:persistent
|
34
|
-
:delete
|
35
|
-
:chown
|
36
|
-
:chmod
|
37
|
-
:chtype
|
38
|
-
:clone
|
39
|
-
:rename
|
40
|
-
:snapshotdelete
|
41
|
-
:snapshotrevert
|
42
|
-
:snapshotflatten=> "image.snapshotflatten",
|
29
|
+
:info => "image.info",
|
30
|
+
:allocate => "image.allocate",
|
31
|
+
:update => "image.update",
|
32
|
+
:enable => "image.enable",
|
33
|
+
:persistent => "image.persistent",
|
34
|
+
:delete => "image.delete",
|
35
|
+
:chown => "image.chown",
|
36
|
+
:chmod => "image.chmod",
|
37
|
+
:chtype => "image.chtype",
|
38
|
+
:clone => "image.clone",
|
39
|
+
:rename => "image.rename",
|
40
|
+
:snapshotdelete => "image.snapshotdelete",
|
41
|
+
:snapshotrevert => "image.snapshotrevert",
|
42
|
+
:snapshotflatten => "image.snapshotflatten",
|
43
|
+
:restore => "image.restore",
|
43
44
|
:lock => "image.lock",
|
44
45
|
:unlock => "image.unlock"
|
45
46
|
}
|
@@ -61,7 +62,7 @@ module OpenNebula
|
|
61
62
|
"LOCKED_USED_PERS" => "lock"
|
62
63
|
}
|
63
64
|
|
64
|
-
IMAGE_TYPES=%w{OS CDROM DATABLOCK KERNEL RAMDISK CONTEXT}
|
65
|
+
IMAGE_TYPES=%w{OS CDROM DATABLOCK KERNEL RAMDISK CONTEXT BACKUP}
|
65
66
|
|
66
67
|
SHORT_IMAGE_TYPES={
|
67
68
|
"OS" => "OS",
|
@@ -69,7 +70,8 @@ module OpenNebula
|
|
69
70
|
"DATABLOCK" => "DB",
|
70
71
|
"KERNEL" => "KL",
|
71
72
|
"RAMDISK" => "RD",
|
72
|
-
"CONTEXT" => "CX"
|
73
|
+
"CONTEXT" => "CX",
|
74
|
+
"BACKUP" => "BK"
|
73
75
|
}
|
74
76
|
|
75
77
|
DISK_TYPES=%w{FILE CD_ROM BLOCK RBD}
|
@@ -163,8 +165,8 @@ module OpenNebula
|
|
163
165
|
end
|
164
166
|
|
165
167
|
# Deletes the Image
|
166
|
-
def delete()
|
167
|
-
|
168
|
+
def delete(force=false)
|
169
|
+
call(IMAGE_METHODS[:delete], @pe_id, force)
|
168
170
|
end
|
169
171
|
|
170
172
|
# Changes the owner/group
|
@@ -229,7 +231,7 @@ module OpenNebula
|
|
229
231
|
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
230
232
|
# otherwise
|
231
233
|
def rename(name)
|
232
|
-
|
234
|
+
call(IMAGE_METHODS[:rename], @pe_id, name)
|
233
235
|
end
|
234
236
|
|
235
237
|
# Deletes Image from snapshot
|
@@ -238,7 +240,7 @@ module OpenNebula
|
|
238
240
|
#
|
239
241
|
# @return [nil, OpenNebula::Error] nil in case of success or Error
|
240
242
|
def snapshot_delete(snap_id)
|
241
|
-
|
243
|
+
call(IMAGE_METHODS[:snapshotdelete], @pe_id, snap_id)
|
242
244
|
end
|
243
245
|
|
244
246
|
# Reverts Image state to a previous snapshot
|
@@ -247,7 +249,7 @@ module OpenNebula
|
|
247
249
|
#
|
248
250
|
# @return [nil, OpenNebula::Error] nil in case of success or Error
|
249
251
|
def snapshot_revert(snap_id)
|
250
|
-
|
252
|
+
call(IMAGE_METHODS[:snapshotrevert], @pe_id, snap_id)
|
251
253
|
end
|
252
254
|
|
253
255
|
# Flattens an image snapshot
|
@@ -256,7 +258,15 @@ module OpenNebula
|
|
256
258
|
#
|
257
259
|
# @return [nil, OpenNebula::Error] nil in case of success or Error
|
258
260
|
def snapshot_flatten(snap_id)
|
259
|
-
|
261
|
+
call(IMAGE_METHODS[:snapshotflatten], @pe_id, snap_id)
|
262
|
+
end
|
263
|
+
|
264
|
+
# Restore the VM backup stored by the image
|
265
|
+
#
|
266
|
+
# @param dst_id [Integer] Datastore destination ID
|
267
|
+
# @param restore_opts [String] Template with additional restore options
|
268
|
+
def restore(dst_id, restore_opts)
|
269
|
+
@client.call(IMAGE_METHODS[:restore], @pe_id, dst_id, restore_opts)
|
260
270
|
end
|
261
271
|
|
262
272
|
#######################################################################
|
data/lib/opennebula/ldap_auth.rb
CHANGED
@@ -213,7 +213,7 @@ class OpenNebula::LdapAuth
|
|
213
213
|
groups = []
|
214
214
|
ldap_groups.each do |group|
|
215
215
|
if (g = in_hash_ignore_case?(@mapping, group))
|
216
|
-
if ldap_groups.any? {
|
216
|
+
if !@options[:group_admin_group_dn].nil? and ldap_groups.any? {
|
217
217
|
|s| s.casecmp(@options[:group_admin_group_dn])==0
|
218
218
|
}
|
219
219
|
groups << "*#{@mapping[g]}"
|
@@ -56,7 +56,9 @@ module OpenNebula
|
|
56
56
|
:scheddelete => "vm.scheddelete",
|
57
57
|
:schedupdate => "vm.schedupdate",
|
58
58
|
:attachsg => "vm.attachsg",
|
59
|
-
:detachsg => "vm.detachsg"
|
59
|
+
:detachsg => "vm.detachsg",
|
60
|
+
:backup => "vm.backup",
|
61
|
+
:updatenic => "vm.updatenic"
|
60
62
|
}
|
61
63
|
|
62
64
|
VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED
|
@@ -132,6 +134,8 @@ module OpenNebula
|
|
132
134
|
HOTPLUG_RESIZE
|
133
135
|
HOTPLUG_SAVEAS_UNDEPLOYED
|
134
136
|
HOTPLUG_SAVEAS_STOPPED
|
137
|
+
BACKUP
|
138
|
+
BACKUP_POWEROFF
|
135
139
|
}
|
136
140
|
|
137
141
|
SHORT_VM_STATES={
|
@@ -216,7 +220,9 @@ module OpenNebula
|
|
216
220
|
"HOTPLUG_NIC_POWEROFF" => "hotp",
|
217
221
|
"HOTPLUG_RESIZE" => "hotp",
|
218
222
|
"HOTPLUG_SAVEAS_UNDEPLOYED" => "hotp",
|
219
|
-
"HOTPLUG_SAVEAS_STOPPED" => "hotp"
|
223
|
+
"HOTPLUG_SAVEAS_STOPPED" => "hotp",
|
224
|
+
"BACKUP" => "back",
|
225
|
+
"BACKUP_POWEROFF" => "back",
|
220
226
|
}
|
221
227
|
|
222
228
|
HISTORY_ACTION=%w{none migrate live-migrate shutdown shutdown-hard
|
@@ -228,6 +234,7 @@ module OpenNebula
|
|
228
234
|
snapshot-resize snapshot-delete snapshot-revert disk-saveas
|
229
235
|
disk-snapshot-revert recover retry monitor disk-snapshot-rename
|
230
236
|
alias-attach alias-detach poweroff-migrate poweroff-hard-migrate
|
237
|
+
backup nic-update
|
231
238
|
}
|
232
239
|
|
233
240
|
EXTERNAL_IP_ATTRS = [
|
@@ -462,6 +469,18 @@ module OpenNebula
|
|
462
469
|
return call(VM_METHODS[:detachnic], @pe_id, nic_id)
|
463
470
|
end
|
464
471
|
|
472
|
+
# Updates a NIC for a running VM
|
473
|
+
#
|
474
|
+
# @param nic_id [Integer] Id of the NIC to be updated
|
475
|
+
# @param nic_template [String] Template with updated attributes
|
476
|
+
# @param append [true|false] True to append new attributes instead of
|
477
|
+
# replace the whole template
|
478
|
+
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
479
|
+
# otherwise
|
480
|
+
def nic_update(nic_id, nic_template, append = false)
|
481
|
+
return call(VM_METHODS[:updatenic], @pe_id, nic_id, nic_template, append ? 1 : 0)
|
482
|
+
end
|
483
|
+
|
465
484
|
# Attaches a Security Groupt to a running VM
|
466
485
|
#
|
467
486
|
# @param nic_id [Integer] Id of the NIC, where to attach SG
|
@@ -779,6 +798,15 @@ module OpenNebula
|
|
779
798
|
sched_template)
|
780
799
|
end
|
781
800
|
|
801
|
+
# Generate a backup for the VM (backup config must be set)
|
802
|
+
#
|
803
|
+
# @param ds_id [Integer] Id of the datastore to save the backup
|
804
|
+
# @return [Integer, OpenNebula::Error] ID of the resulting BACKUP image
|
805
|
+
# in case of success, Error otherwise.
|
806
|
+
def backup(ds_id, reset = false)
|
807
|
+
return @client.call(VM_METHODS[:backup], @pe_id, ds_id, reset)
|
808
|
+
end
|
809
|
+
|
782
810
|
########################################################################
|
783
811
|
# Helpers to get VirtualMachine information
|
784
812
|
########################################################################
|
@@ -286,160 +286,6 @@ module OpenNebula::VirtualMachineExt
|
|
286
286
|
raise
|
287
287
|
end
|
288
288
|
|
289
|
-
#-------------------------------------------------------------------
|
290
|
-
# Backups a VM. TODO Add final description
|
291
|
-
# @param keep [Bool]
|
292
|
-
# @param logger[Logger]
|
293
|
-
# @param binfo[Hash] Oneshot
|
294
|
-
#-------------------------------------------------------------------
|
295
|
-
def backup(keep = false, logger = nil, binfo = nil)
|
296
|
-
# --------------------------------------------------------------
|
297
|
-
# Check backup consistency
|
298
|
-
# --------------------------------------------------------------
|
299
|
-
rc = info
|
300
|
-
|
301
|
-
raise rc.message if OpenNebula.is_error?(rc)
|
302
|
-
|
303
|
-
binfo.merge!(backup_info) do |_key, old_val, new_val|
|
304
|
-
new_val.nil? ? old_val : new_val
|
305
|
-
end
|
306
|
-
|
307
|
-
raise 'No backup information' if binfo.nil?
|
308
|
-
|
309
|
-
raise 'No frequency defined' unless valid?(binfo[:freq])
|
310
|
-
|
311
|
-
raise 'No marketplace defined' unless valid?(binfo[:market])
|
312
|
-
|
313
|
-
return if Time.now.to_i - binfo[:last].to_i < binfo[:freq].to_i
|
314
|
-
|
315
|
-
# --------------------------------------------------------------
|
316
|
-
# Save VM as new template
|
317
|
-
# --------------------------------------------------------------
|
318
|
-
logger.info 'Saving VM as template' if logger
|
319
|
-
|
320
|
-
tid = save_as_template(
|
321
|
-
binfo[:name], '', :poweroff => true, :logger => logger
|
322
|
-
)
|
323
|
-
|
324
|
-
tmp = OpenNebula::Template.new_with_id(tid, @client)
|
325
|
-
rc = tmp.info
|
326
|
-
|
327
|
-
raise rc.message if OpenNebula.is_error?(rc)
|
328
|
-
|
329
|
-
# --------------------------------------------------------------
|
330
|
-
# Import template into Marketplace & update VM info
|
331
|
-
# --------------------------------------------------------------
|
332
|
-
logger.info "Importing template #{tmp.id} to marketplace "\
|
333
|
-
"#{binfo[:market]}" if logger
|
334
|
-
|
335
|
-
tmp.extend(OpenNebula::TemplateExt)
|
336
|
-
|
337
|
-
rc, ids = tmp.mp_import(binfo[:market], true, binfo[:name],
|
338
|
-
:wait => true, :logger => logger)
|
339
|
-
|
340
|
-
raise rc.message if OpenNebula.is_error?(rc)
|
341
|
-
|
342
|
-
logger.info "Imported app ids: #{ids.join(',')}" if logger
|
343
|
-
|
344
|
-
rc = update(backup_attr(binfo, ids), true)
|
345
|
-
|
346
|
-
if OpenNebula.is_error?(rc)
|
347
|
-
raise 'Could not update the backup reference: ' \
|
348
|
-
" #{rc.message}. New backup ids are #{ids.join(',')}."
|
349
|
-
end
|
350
|
-
|
351
|
-
# --------------------------------------------------------------
|
352
|
-
# Cleanup
|
353
|
-
# --------------------------------------------------------------
|
354
|
-
backup_cleanup(keep, logger, binfo, tmp)
|
355
|
-
rescue Error, StandardError => e
|
356
|
-
backup_cleanup(keep, logger, binfo, tmp)
|
357
|
-
|
358
|
-
logger.fatal(e.inspect) if logger
|
359
|
-
|
360
|
-
raise
|
361
|
-
end
|
362
|
-
|
363
|
-
#-------------------------------------------------------------------
|
364
|
-
# Restores VM information from previous backup
|
365
|
-
#
|
366
|
-
# @param datastore [Integer] Datastore ID to import app backup
|
367
|
-
# @param logger [Logger] Logger instance to print debug info
|
368
|
-
#
|
369
|
-
# @return [Integer] VM ID
|
370
|
-
#-------------------------------------------------------------------
|
371
|
-
def restore(datastore, logger = nil)
|
372
|
-
rc = info
|
373
|
-
|
374
|
-
if OpenNebula.is_error?(rc)
|
375
|
-
raise "Error getting VM: #{rc.message}"
|
376
|
-
end
|
377
|
-
|
378
|
-
logger.info 'Reading backup information' if logger
|
379
|
-
|
380
|
-
backup_ids = backup_info[:apps]
|
381
|
-
|
382
|
-
# highest (=last) of the app ids is the template id
|
383
|
-
app_id = backup_ids.last
|
384
|
-
|
385
|
-
app = OpenNebula::MarketPlaceApp.new_with_id(app_id, @client)
|
386
|
-
rc = app.info
|
387
|
-
|
388
|
-
if OpenNebula.is_error?(rc)
|
389
|
-
raise "Can not find appliance #{app_id}: #{rc.message}."
|
390
|
-
end
|
391
|
-
|
392
|
-
if logger
|
393
|
-
logger.info "Restoring VM #{self['ID']} from " \
|
394
|
-
"saved appliance #{app_id}"
|
395
|
-
end
|
396
|
-
|
397
|
-
app.extend(OpenNebula::MarketPlaceAppExt)
|
398
|
-
|
399
|
-
exp = app.export(:dsid => Integer(datastore),
|
400
|
-
:name => "#{self['NAME']} - RESTORED")
|
401
|
-
|
402
|
-
if OpenNebula.is_error?(exp)
|
403
|
-
raise "Can not restore app: #{exp.message}."
|
404
|
-
end
|
405
|
-
|
406
|
-
# Check possible errors when exporting apps
|
407
|
-
exp[:image].each do |image|
|
408
|
-
next unless OpenNebula.is_error?(image)
|
409
|
-
|
410
|
-
raise "Error restoring image: #{image.message}."
|
411
|
-
end
|
412
|
-
|
413
|
-
template = exp[:vmtemplate].first
|
414
|
-
|
415
|
-
if OpenNebula.is_error?(template)
|
416
|
-
raise "Error restoring template: #{template.message}."
|
417
|
-
end
|
418
|
-
|
419
|
-
if logger
|
420
|
-
logger.info(
|
421
|
-
"Backup restored, VM template: #{exp[:vmtemplate]}, " \
|
422
|
-
"images: #{exp[:image]}"
|
423
|
-
)
|
424
|
-
|
425
|
-
logger.info(
|
426
|
-
"Instantiating the template #{exp[:vmtemplate]}"
|
427
|
-
)
|
428
|
-
end
|
429
|
-
|
430
|
-
tmpl = OpenNebula::Template.new_with_id(template, @client)
|
431
|
-
rc = tmpl.instantiate
|
432
|
-
|
433
|
-
if OpenNebula.is_error?(rc)
|
434
|
-
raise "Can not instantiate the template: #{rc.message}."
|
435
|
-
end
|
436
|
-
|
437
|
-
rc
|
438
|
-
rescue Error, StandardError => e
|
439
|
-
logger.fatal(e.inspect) if logger
|
440
|
-
raise
|
441
|
-
end
|
442
|
-
|
443
289
|
####################################################################
|
444
290
|
# Private extended interface
|
445
291
|
####################################################################
|
@@ -457,58 +303,6 @@ module OpenNebula::VirtualMachineExt
|
|
457
303
|
!att.nil?
|
458
304
|
end
|
459
305
|
|
460
|
-
#-------------------------------------------------------------------
|
461
|
-
# Get backup information from the VM
|
462
|
-
#-------------------------------------------------------------------
|
463
|
-
def backup_info
|
464
|
-
base = '//USER_TEMPLATE/BACKUP'
|
465
|
-
binfo = {}
|
466
|
-
|
467
|
-
app_ids = self["#{base}/MARKETPLACE_APP_IDS"] || ''
|
468
|
-
|
469
|
-
binfo[:name] = "#{self['NAME']} - BACKUP " \
|
470
|
-
" - #{Time.now.strftime('%Y%m%d_%k%M')}"
|
471
|
-
|
472
|
-
binfo[:freq] = self["#{base}/FREQUENCY_SECONDS"]
|
473
|
-
binfo[:last] = self["#{base}/LAST_BACKUP_TIME"]
|
474
|
-
binfo[:market] = Integer(self["#{base}/MARKETPLACE_ID"])
|
475
|
-
binfo[:apps] = app_ids.split(',')
|
476
|
-
|
477
|
-
binfo
|
478
|
-
rescue StandardError
|
479
|
-
binfo
|
480
|
-
end
|
481
|
-
|
482
|
-
#-------------------------------------------------------------------
|
483
|
-
# Generate backup information string
|
484
|
-
#-------------------------------------------------------------------
|
485
|
-
def backup_attr(binfo, ids)
|
486
|
-
'BACKUP=[' \
|
487
|
-
" MARKETPLACE_APP_IDS = \"#{ids.join(',')}\"," \
|
488
|
-
" FREQUENCY_SECONDS = \"#{binfo[:freq]}\"," \
|
489
|
-
" LAST_BACKUP_TIME = \"#{Time.now.to_i}\"," \
|
490
|
-
" MARKETPLACE_ID = \"#{binfo[:market]}\" ]"
|
491
|
-
end
|
492
|
-
|
493
|
-
#-------------------------------------------------------------------
|
494
|
-
# Cleanup backup leftovers in case of failure
|
495
|
-
#-------------------------------------------------------------------
|
496
|
-
def backup_cleanup(keep, logger, binfo, template)
|
497
|
-
if template
|
498
|
-
logger.info "Deleting template #{template.id}" if logger
|
499
|
-
|
500
|
-
template.delete(true)
|
501
|
-
end
|
502
|
-
|
503
|
-
binfo[:apps].each do |id|
|
504
|
-
logger.info "Deleting appliance #{id}" if logger
|
505
|
-
|
506
|
-
papp = OpenNebula::MarketPlaceApp.new_with_id(id, @client)
|
507
|
-
|
508
|
-
papp.delete
|
509
|
-
end if !keep && binfo[:apps]
|
510
|
-
end
|
511
|
-
|
512
306
|
end
|
513
307
|
end
|
514
308
|
|
@@ -44,7 +44,7 @@ module OpenNebula
|
|
44
44
|
:recover => "vn.recover"
|
45
45
|
}
|
46
46
|
|
47
|
-
VN_STATES=%w{INIT READY LOCK_CREATE LOCK_DELETE DONE ERROR}
|
47
|
+
VN_STATES=%w{INIT READY LOCK_CREATE LOCK_DELETE DONE ERROR UPDATE_FAILURE}
|
48
48
|
|
49
49
|
SHORT_VN_STATES={
|
50
50
|
"INIT" => "init",
|
@@ -52,7 +52,8 @@ module OpenNebula
|
|
52
52
|
"LOCK_CREATE" => "lock",
|
53
53
|
"LOCK_DELETE" => "lock",
|
54
54
|
"DONE" => "done",
|
55
|
-
"ERROR" => "err"
|
55
|
+
"ERROR" => "err",
|
56
|
+
"UPDATE_FAILURE"=> "fail"
|
56
57
|
}
|
57
58
|
|
58
59
|
# Creates a VirtualNetwork description with just its identifier
|
@@ -326,7 +327,7 @@ module OpenNebula
|
|
326
327
|
# Recovers an stuck Virtual Network
|
327
328
|
#
|
328
329
|
# @param result [Integer] Recover with failure (0), success (1),
|
329
|
-
# delete (2)
|
330
|
+
# delete (2), retry (3)
|
330
331
|
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
331
332
|
# otherwise
|
332
333
|
def recover(result)
|
@@ -377,6 +378,34 @@ module OpenNebula
|
|
377
378
|
SHORT_VN_STATES[state_str]
|
378
379
|
end
|
379
380
|
|
381
|
+
# Returns three arrays with the numeric VM IDs for VMs updated,
|
382
|
+
# outdated (include updating) and error
|
383
|
+
def vm_ids
|
384
|
+
updated = Array.new
|
385
|
+
|
386
|
+
self.each('UPDATED_VMS/ID') do |id|
|
387
|
+
updated << id.text.to_i
|
388
|
+
end
|
389
|
+
|
390
|
+
outdated = Array.new
|
391
|
+
|
392
|
+
self.each('OUTDATED_VMS/ID') do |id|
|
393
|
+
outdated << id.text.to_i
|
394
|
+
end
|
395
|
+
|
396
|
+
self.each('UPDATING_VMS/ID') do |id|
|
397
|
+
outdated << id.text.to_i
|
398
|
+
end
|
399
|
+
|
400
|
+
error = Array.new
|
401
|
+
|
402
|
+
self.each('ERROR_VMS/ID') do |id|
|
403
|
+
error << id.text.to_i
|
404
|
+
end
|
405
|
+
|
406
|
+
[updated, outdated, error]
|
407
|
+
end
|
408
|
+
|
380
409
|
private
|
381
410
|
def set_publish(published)
|
382
411
|
group_u = published ? 1 : 0
|
data/lib/opennebula.rb
CHANGED
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: 6.
|
4
|
+
version: 6.5.90.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OpenNebula
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -255,9 +255,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
255
255
|
version: '0'
|
256
256
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
257
257
|
requirements:
|
258
|
-
- - "
|
258
|
+
- - ">"
|
259
259
|
- !ruby/object:Gem::Version
|
260
|
-
version:
|
260
|
+
version: 1.3.1
|
261
261
|
requirements: []
|
262
262
|
rubygems_version: 3.1.2
|
263
263
|
signing_key:
|