opennebula 4.90.10.rc1 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,376 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2016, 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
+ require "OpenNebulaDriver"
17
+ require "CommandManager"
18
+ require 'base64'
19
+ require 'rexml/document'
20
+
21
+ # This class provides basic messaging and logging functionality
22
+ # to implement OpenNebula Drivers. A driver is a program that
23
+ # specialize the OpenNebula behavior by interfacing with specific
24
+ # infrastructure functionalities.
25
+ #
26
+ # A Driver inherits this class and only has to provide methods
27
+ # for each action it wants to receive. The method must be associated
28
+ # with the action name through the register_action function
29
+ class VirtualMachineDriver < OpenNebulaDriver
30
+
31
+ # Virtual Machine Driver Protocol constants
32
+ ACTION = {
33
+ :deploy => "DEPLOY",
34
+ :shutdown => "SHUTDOWN",
35
+ :reboot => "REBOOT",
36
+ :reset => "RESET",
37
+ :cancel => "CANCEL",
38
+ :save => "SAVE",
39
+ :restore => "RESTORE",
40
+ :migrate => "MIGRATE",
41
+ :poll => "POLL",
42
+ :log => "LOG",
43
+ :attach_disk => "ATTACHDISK",
44
+ :detach_disk => "DETACHDISK",
45
+ :snapshot_create => "SNAPSHOTCREATE",
46
+ :snapshot_revert => "SNAPSHOTREVERT",
47
+ :snapshot_delete => "SNAPSHOTDELETE",
48
+ :cleanup => "CLEANUP",
49
+ :attach_nic => "ATTACHNIC",
50
+ :detach_nic => "DETACHNIC",
51
+ :disk_snapshot_create => "DISKSNAPSHOTCREATE",
52
+ :update_sg => "UPDATESG"
53
+ }
54
+
55
+ POLL_ATTRIBUTE = {
56
+ :memory => "MEMORY",
57
+ :cpu => "CPU",
58
+ :nettx => "NETTX",
59
+ :netrx => "NETRX",
60
+ :state => "STATE",
61
+ :disk_size => "DISK_SIZE",
62
+ :snapshot_size => "SNAPSHOT_SIZE"
63
+ }
64
+
65
+ VM_STATE = {
66
+ :active => 'a',
67
+ :paused => 'p',
68
+ :error => 'e',
69
+ :deleted => 'd',
70
+ :unknown => '-'
71
+ }
72
+
73
+ HOST_ARG = 1
74
+
75
+ # Register default actions for the protocol.
76
+ #
77
+ # @param [String] directory path inside remotes path where the scripts
78
+ # reside
79
+ # @param [Hash] options options for OpenNebula driver (check the available
80
+ # options in {OpenNebulaDriver#initialize})
81
+ # @option options [Boolean] :threaded (true) enables or disables threads
82
+ def initialize(directory, options={})
83
+ @options={
84
+ :threaded => true,
85
+ :single_host => true
86
+ }.merge!(options)
87
+
88
+ super(directory, @options)
89
+
90
+ @hosts = Array.new
91
+
92
+ register_action(ACTION[:deploy].to_sym, method("deploy"))
93
+ register_action(ACTION[:shutdown].to_sym, method("shutdown"))
94
+ register_action(ACTION[:reboot].to_sym, method("reboot"))
95
+ register_action(ACTION[:reset].to_sym, method("reset"))
96
+ register_action(ACTION[:cancel].to_sym, method("cancel"))
97
+ register_action(ACTION[:save].to_sym, method("save"))
98
+ register_action(ACTION[:restore].to_sym, method("restore"))
99
+ register_action(ACTION[:migrate].to_sym, method("migrate"))
100
+ register_action(ACTION[:poll].to_sym, method("poll"))
101
+ register_action(ACTION[:attach_disk].to_sym, method("attach_disk"))
102
+ register_action(ACTION[:detach_disk].to_sym, method("detach_disk"))
103
+ register_action(ACTION[:snapshot_create].to_sym, method("snapshot_create"))
104
+ register_action(ACTION[:snapshot_revert].to_sym, method("snapshot_revert"))
105
+ register_action(ACTION[:snapshot_delete].to_sym, method("snapshot_delete"))
106
+ register_action(ACTION[:cleanup].to_sym, method("cleanup"))
107
+ register_action(ACTION[:attach_nic].to_sym, method("attach_nic"))
108
+ register_action(ACTION[:detach_nic].to_sym, method("detach_nic"))
109
+ register_action(ACTION[:disk_snapshot_create].to_sym, method("disk_snapshot_create"))
110
+ register_action(ACTION[:update_sg].to_sym, method("update_sg"))
111
+ end
112
+
113
+ # Decodes the encoded XML driver message received from the core
114
+ #
115
+ # @param [String] drv_message the driver message
116
+ # @return [REXML::Element] the root element of the decoded XML message
117
+ def decode(drv_message)
118
+ message = Base64.decode64(drv_message)
119
+ xml_doc = REXML::Document.new(message)
120
+
121
+ xml_doc.root
122
+ end
123
+
124
+ # Execute a command associated to an action and id in a remote host.
125
+ def remotes_action(command, id, host, action, remote_dir, std_in=nil)
126
+ super(command,id,host,ACTION[action],remote_dir,std_in)
127
+ end
128
+
129
+ # Execute a command associated to an action and id on localhost
130
+ def local_action(command, id, action)
131
+ super(command,id,ACTION[action])
132
+ end
133
+
134
+ # Virtual Machine Manager Protocol Actions (generic implementation)
135
+ def deploy(id, drv_message)
136
+ error = "Action not implemented by driver #{self.class}"
137
+ send_message(ACTION[:deploy],RESULT[:failure],id,error)
138
+ end
139
+
140
+ def shutdown(id, drv_message)
141
+ error = "Action not implemented by driver #{self.class}"
142
+ send_message(ACTION[:shutdown],RESULT[:failure],id,error)
143
+ end
144
+
145
+ def reboot(id, drv_message)
146
+ error = "Action not implemented by driver #{self.class}"
147
+ send_message(ACTION[:reboot],RESULT[:failure],id,error)
148
+ end
149
+
150
+ def reset(id, drv_message)
151
+ error = "Action not implemented by driver #{self.class}"
152
+ send_message(ACTION[:reset],RESULT[:failure],id,error)
153
+ end
154
+
155
+ def cancel(id, drv_message)
156
+ error = "Action not implemented by driver #{self.class}"
157
+ send_message(ACTION[:cancel],RESULT[:failure],id,error)
158
+ end
159
+
160
+ def save(id, drv_message)
161
+ error = "Action not implemented by driver #{self.class}"
162
+ send_message(ACTION[:save],RESULT[:failure],id,error)
163
+ end
164
+
165
+ def restore(id, drv_message)
166
+ error = "Action not implemented by driver #{self.class}"
167
+ send_message(ACTION[:restore],RESULT[:failure],id,error)
168
+ end
169
+
170
+ def migrate(id, drv_message)
171
+ error = "Action not implemented by driver #{self.class}"
172
+ send_message(ACTION[:migrate],RESULT[:failure],id,error)
173
+ end
174
+
175
+ def poll(id, drv_message)
176
+ error = "Action not implemented by driver #{self.class}"
177
+ send_message(ACTION[:poll],RESULT[:failure],id,error)
178
+ end
179
+
180
+ def attach_disk(id, drv_message)
181
+ error = "Action not implemented by driver #{self.class}"
182
+ send_message(ACTION[:attach_disk],RESULT[:failure],id,error)
183
+ end
184
+
185
+ def detach_disk(id, drv_message)
186
+ error = "Action not implemented by driver #{self.class}"
187
+ send_message(ACTION[:detach_disk],RESULT[:failure],id,error)
188
+ end
189
+
190
+ def attach_nic(id, drv_message)
191
+ error = "Action not implemented by driver #{self.class}"
192
+ send_message(ACTION[:attach_nic],RESULT[:failure],id,error)
193
+ end
194
+
195
+ def detach_nic(id, drv_message)
196
+ error = "Action not implemented by driver #{self.class}"
197
+ send_message(ACTION[:detach_nic],RESULT[:failure],id,error)
198
+ end
199
+
200
+ def snapshot_create(id, drv_message)
201
+ error = "Action not implemented by driver #{self.class}"
202
+ send_message(ACTION[:snapshot_create],RESULT[:failure],id,error)
203
+ end
204
+
205
+ def snapshot_revert(id, drv_message)
206
+ error = "Action not implemented by driver #{self.class}"
207
+ send_message(ACTION[:snapshot_revert],RESULT[:failure],id,error)
208
+ end
209
+
210
+ def snapshot_delete(id, drv_message)
211
+ error = "Action not implemented by driver #{self.class}"
212
+ send_message(ACTION[:snapshot_delete],RESULT[:failure],id,error)
213
+ end
214
+
215
+ def disk_snapshot_create(id, drv_message)
216
+ error = "Action not implemented by driver #{self.class}"
217
+ send_message(ACTION[:disk_snapshot_create],RESULT[:failure],id,error)
218
+ end
219
+
220
+ def update_sg(id, drv_message)
221
+ error = "Action not implemented by driver #{self.class}"
222
+ send_message(ACTION[:update_sg],RESULT[:failure],id,error)
223
+ end
224
+
225
+ def cleanup(id, drv_message)
226
+ error = "Action not implemented by driver #{self.class}"
227
+ send_message(ACTION[:cleanup],RESULT[:failure],id,error)
228
+ end
229
+
230
+ private
231
+
232
+ # Interface to handle the pending events from the ActionManager Interface
233
+ def delete_running_action(action_id)
234
+ if @options[:single_host]
235
+ delete_running_action_single_host(action_id)
236
+ else
237
+ super(action_id)
238
+ end
239
+ end
240
+
241
+ def delete_running_action_single_host(action_id)
242
+ action=@action_running[action_id]
243
+ if action
244
+ @hosts.delete(action[:host])
245
+ @action_running.delete(action_id)
246
+ end
247
+ end
248
+
249
+ def get_first_runable
250
+ if @options[:single_host]
251
+ get_first_runable_single_host
252
+ else
253
+ super
254
+ end
255
+ end
256
+
257
+ def get_first_runable_single_host
258
+ action_index=nil
259
+ @action_queue.each_with_index do |action, index|
260
+ if !action.keys.include?(:host)
261
+ if action[:args].length == 2
262
+ begin
263
+ xml=decode(action[:args].last)
264
+ host=xml.elements['HOST']
265
+ action[:host]=host.text if host
266
+ rescue
267
+ action[:host]=nil
268
+ end
269
+ else
270
+ action[:host]=nil
271
+ end
272
+ end
273
+
274
+ if action.keys.include?(:host) && action[:host]
275
+ if !@hosts.include?(action[:host])
276
+ action_index=index
277
+ break
278
+ end
279
+ else
280
+ action_index=index
281
+ break
282
+ end
283
+ end
284
+
285
+ return action_index
286
+ end
287
+
288
+ def get_runable_action
289
+ if @options[:single_host]
290
+ get_runable_action_single_host
291
+ else
292
+ super
293
+ end
294
+ end
295
+
296
+ def get_runable_action_single_host
297
+ action_index=get_first_runable
298
+
299
+ if action_index
300
+ action=@action_queue[action_index]
301
+ else
302
+ action=nil
303
+ end
304
+
305
+ if action
306
+ @hosts << action[:host] if action[:host]
307
+ @action_queue.delete_at(action_index)
308
+ end
309
+
310
+ return action
311
+ end
312
+
313
+ def empty_queue
314
+ if @options[:single_host]
315
+ empty_queue_single_host
316
+ else
317
+ super
318
+ end
319
+ end
320
+
321
+ def empty_queue_single_host
322
+ get_first_runable==nil
323
+ end
324
+ end
325
+
326
+ ################################################################
327
+ ################################################################
328
+
329
+ if __FILE__ == $0
330
+
331
+ class TemplateDriver < VirtualMachineDriver
332
+ def initialize
333
+ super('vmm/dummy',
334
+ :concurrency => 15,
335
+ :threaded => true)
336
+ end
337
+
338
+ def deploy(id, host, remote_dfile, not_used)
339
+ #MUST return deploy_id if deployment was successfull
340
+ deploy_id = "-"
341
+ send_message(ACTION[:deploy],RESULT[:success],id,deploy_id)
342
+ end
343
+
344
+ def shutdown(id, host, deploy_id, not_used)
345
+ send_message(ACTION[:shutdown],RESULT[:success],id)
346
+ end
347
+
348
+ def cancel(id, host, deploy_id, not_used)
349
+ send_message(ACTION[:cancel],RESULT[:success],id)
350
+ end
351
+
352
+ def save(id, host, deploy_id, file)
353
+ send_message(ACTION[:save],RESULT[:success],id)
354
+ end
355
+
356
+ def restore(id, host, deploy_id , file)
357
+ send_message(ACTION[:restore],RESULT[:success],id)
358
+ end
359
+
360
+ def migrate(id, host, deploy_id, dest_host)
361
+ send_message(ACTION[:migrate],RESULT[:success],id)
362
+ end
363
+
364
+ def poll(id, host, deploy_id, not_used)
365
+ # monitor_info: string in the form "VAR=VAL VAR=VAL ... VAR=VAL"
366
+ # known VAR are in POLL_ATTRIBUTES. VM states VM_STATES
367
+ monitor_info = "#{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:active]} " \
368
+ "#{POLL_ATTRIBUTE[:nettx]}=12345"
369
+
370
+ send_message(ACTION[:poll],RESULT[:success],id,monitor_info)
371
+ end
372
+ end
373
+
374
+ sd = TemplateDriver.new
375
+ sd.start_driver
376
+ end
@@ -50,7 +50,7 @@ end
50
50
  module CloudClient
51
51
 
52
52
  # OpenNebula version
53
- VERSION = '4.90.10'
53
+ VERSION = '5.0.0'
54
54
 
55
55
  # #########################################################################
56
56
  # Default location for the authentication file
@@ -112,6 +112,7 @@ module OpenNebula
112
112
  DISK_SNAPSHOT_REVERT_SUSPENDED
113
113
  DISK_SNAPSHOT_DELETE_SUSPENDED
114
114
  DISK_SNAPSHOT
115
+ DISK_SNAPSHOT_REVERT
115
116
  DISK_SNAPSHOT_DELETE
116
117
  PROLOG_MIGRATE_UNKNOWN
117
118
  PROLOG_MIGRATE_UNKNOWN_FAILURE
data/lib/opennebula.rb CHANGED
@@ -66,5 +66,5 @@ require 'opennebula/marketplaceapp_pool'
66
66
  module OpenNebula
67
67
 
68
68
  # OpenNebula version
69
- VERSION = '4.90.10'
69
+ VERSION = '5.0.0'
70
70
  end