opennebula 6.2.0 → 6.3.80.pre

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 62addc3c6ca7a2d64f362b69e78d5249a8c580ca
4
- data.tar.gz: 753aea24a283602fad7c6e7171164a8c6af9ee00
2
+ SHA256:
3
+ metadata.gz: cbf5d10fd120f0a5f41abc59d743f38b1080002271e2ecbb131463a0e145cfba
4
+ data.tar.gz: e3de025f53033170cea9ca52871dd4c0c2ef417d8ca0637b861fe9f495b9d011
5
5
  SHA512:
6
- metadata.gz: afd9480704e6bfce7e708729ef75ad7457ce713b0e85b235b23373e94867b40713aef2a032b191d52f3567b2ca8de4a361e5baaf757228aa131eb32ceda2b12e
7
- data.tar.gz: 0b319949a9cfad08f13f6ecd1040b28d5edaf1a11c46f5fadbd0ea3ee90af97f239a48fa85809789eec9805cb269ad44f9f72c63b5809e6fea8e273acda7f1c5
6
+ metadata.gz: d02e4f443085e4e797b09252a9583c7b59255335abcc51a3a50b0f4f82d2007ab17f7fc13df49bfc7214dd92ba68bc07f4282c019807a3237af1cb0675bf07b1
7
+ data.tar.gz: 86fede32beb5965879433a8808237d17765da216125ef7b312649f6b6707a337fe3783c7cde67aa90cc9feef413c73d69817ff5cb7cee0dec42b3a91f3b5abb9
@@ -51,7 +51,7 @@ end
51
51
  module CloudClient
52
52
 
53
53
  # OpenNebula version
54
- VERSION = '6.2.0'
54
+ VERSION = '6.3.80'
55
55
 
56
56
  # #########################################################################
57
57
  # Default location for the authentication file
data/lib/datacenter.rb CHANGED
@@ -131,7 +131,10 @@ module VCenterDriver
131
131
 
132
132
  # Setting host import name and
133
133
  # replace spaces and weird characters
134
- cluster_name = (ccr['name']).to_s.tr(' ', '_')
134
+ cluster_name = ccr['name'].to_s.tr(' ', '_')
135
+ cluster_name = VCenterDriver::VcImporter.sanitize(
136
+ cluster_name
137
+ )
135
138
  cluster_name =
136
139
  VCenterDriver::VIHelper
137
140
  .one_name(
@@ -159,11 +162,28 @@ module VCenterDriver
159
162
  host_objects
160
163
  end
161
164
 
162
- def get_unimported_datastores(dpool, vcenter_instance_name, hpool)
165
+ # rubocop:disable Style/GlobalVars
166
+ def get_unimported_datastores(dpool, vcenter_instance_name, hpool, args)
163
167
  import_id = 0
164
168
  ds_objects = {}
165
169
  vcenter_uuid = vcenter_instance_uuid
166
170
 
171
+ # Selected host in OpenNebula
172
+ if $conf.nil?
173
+ one_client = OpenNebula::Client.new
174
+ else
175
+ one_client = OpenNebula::Client.new(
176
+ nil,
177
+ $conf[:one_xmlrpc]
178
+ )
179
+ end
180
+ one_host = OpenNebula::Host.new_with_id(args[:host], one_client)
181
+
182
+ rc = one_host.info
183
+ raise rc.message if OpenNebula.is_error? rc
184
+
185
+ cluster_id = one_host['CLUSTER_ID'].to_i
186
+
167
187
  # Get datacenters
168
188
  fetch! if @items.empty?
169
189
 
@@ -185,7 +205,10 @@ module VCenterDriver
185
205
  'summary.freeSpace'
186
206
  )
187
207
 
188
- ds_name = name.to_s
208
+ ds_name = VCenterDriver::VcImporter.sanitize(
209
+ name.to_s
210
+ )
211
+
189
212
  ds_total_mb = ((capacity.to_i / 1024) / 1024)
190
213
  ds_free_mb = ((free_space.to_i / 1024) / 1024)
191
214
  ds_ref = ds['_ref']
@@ -363,8 +386,15 @@ module VCenterDriver
363
386
  end
364
387
  end
365
388
 
389
+ ds_objects.keys.each do |key|
390
+ unless ds_objects[key][:cluster].include? cluster_id
391
+ ds_objects.delete key
392
+ end
393
+ end
394
+
366
395
  { vcenter_instance_name => ds_objects }
367
396
  end
397
+ # rubocop:enable Style/GlobalVars
368
398
 
369
399
  def get_unimported_templates(vi_client, tpool)
370
400
  template_objects = {}
data/lib/datastore.rb CHANGED
@@ -561,7 +561,7 @@ module VCenterDriver
561
561
  rescue StandardError => e
562
562
  message = "Could not find file. Reason: \"#{e.message}\"."
563
563
  if VCenterDriver::CONFIG[:debug_information]
564
- message += ' ' + e.backtrace
564
+ message += ' ' + e.backtrace.to_s
565
565
  end
566
566
  raise message
567
567
  end
@@ -881,7 +881,7 @@ module VCenterDriver
881
881
  @one_class = OpenNebula::Datastore
882
882
  end
883
883
 
884
- def get_list(_args = {})
884
+ def get_list(args = {})
885
885
  dc_folder = VCenterDriver::DatacenterFolder.new(@vi_client)
886
886
 
887
887
  # one pool creation
@@ -908,7 +908,8 @@ module VCenterDriver
908
908
  .get_unimported_datastores(
909
909
  dpool,
910
910
  @vi_client.vc_name,
911
- hpool
911
+ hpool,
912
+ args
912
913
  )
913
914
  @list = rs
914
915
  end
@@ -948,7 +949,11 @@ module VCenterDriver
948
949
  clusters = opts['selected_clusters'].each.map(&:to_i)
949
950
  end
950
951
 
951
- res = { :id => [], :name => selected[:simple_name] }
952
+ name = VCenterDriver::VcImporter.sanitize(
953
+ selected[:simple_name]
954
+ )
955
+
956
+ res = { :id => [], :name => name }
952
957
  @info[:rollback] = []
953
958
  pair.each do |ds|
954
959
  create(ds[:one]) do |one_object, id|
@@ -1011,7 +1016,9 @@ module VCenterDriver
1011
1016
  message = 'Error creating the OpenNebula resource'
1012
1017
  info = selected[:one]
1013
1018
  dsid = selected[:dsid].to_i
1014
- name = selected[:name]
1019
+ name = VCenterDriver::VcImporter.sanitize(
1020
+ selected[:name]
1021
+ )
1015
1022
 
1016
1023
  rc = resource.allocate(info, dsid, false)
1017
1024
  VCenterDriver::VIHelper.check_error(rc, message)
data/lib/file_helper.rb CHANGED
@@ -98,7 +98,7 @@ module VCenterDriver
98
98
  end
99
99
 
100
100
  def self.get_type(file)
101
- type = `file -b --mime-type #{file}`
101
+ type = `file -P bytes=256 -b --mime-type #{file}`
102
102
  if $?.exitstatus != 0 # rubocop:disable Style/SpecialGlobalVars
103
103
  STDERR.puts "Can not read file #{file}"
104
104
  exit(-1)
data/lib/host.rb CHANGED
@@ -712,7 +712,7 @@ module VCenterDriver
712
712
 
713
713
  # Only take care of VMs, not templates
714
714
  if !hashed_properties['config.template']
715
- vms[r.obj._ref] = hashed_properties
715
+ vms[r.obj._ref + '_' + vc_uuid] = hashed_properties
716
716
  vm_objects << r.obj
717
717
  end
718
718
  end
@@ -802,7 +802,8 @@ module VCenterDriver
802
802
  found_vm =
803
803
  host_vms
804
804
  .select do |vm|
805
- vm['DEPLOY_ID'].eql? vm_ref
805
+ vm['DEPLOY_ID'] == vm_ref ||
806
+ vm['DEPLOY_ID'] == VIHelper.get_deploy_id(vm_ref)
806
807
  end.first
807
808
  id = found_vm['ID'] if found_vm
808
809
 
@@ -55,8 +55,12 @@ module OpenNebula
55
55
  @one_pool = nil
56
56
 
57
57
  if @client
58
- info = Nokogiri::XML(@client.call('user.info', -1))
59
- @user_id = Integer(info.xpath('/USER/ID').text)
58
+ rc = @client.call('user.info', -1)
59
+
60
+ unless OpenNebula.is_error?(rc)
61
+ info = Nokogiri::XML(rc)
62
+ @user_id = Integer(info.xpath('/USER/ID').text)
63
+ end
60
64
  end
61
65
 
62
66
  super('DOCUMENT_POOL', 'DOCUMENT', @client)
@@ -315,6 +315,12 @@ module OpenNebula
315
315
  end
316
316
  else
317
317
  IMMUTABLE_ATTRS.each do |attr|
318
+ # Allows updating the template without
319
+ # specifying the immutable attributes
320
+ if template[attr].nil?
321
+ template[attr] = @body[attr]
322
+ end
323
+
318
324
  next if template[attr] == @body[attr]
319
325
 
320
326
  return [false, "service_template/#{attr}"]
@@ -14,7 +14,6 @@
14
14
  # limitations under the License. #
15
15
  #--------------------------------------------------------------------------- #
16
16
 
17
-
18
17
  require 'opennebula/pool_element'
19
18
  require 'base64'
20
19
  require 'yaml'
@@ -217,10 +216,12 @@ module OpenNebula
217
216
  # Imports a wild VM from the host and puts it in running state
218
217
  #
219
218
  # @param name [String] Name of the VM to import
219
+ # @param ipv4 [Array] Array with IP4s to set
220
+ # @param ipv6 [Array] Array with IP6s to set
220
221
  #
221
222
  # @return [nil, OpenNebula::Error] nil in case of success, Error
222
223
  # otherwise
223
- def import_wild(name)
224
+ def import_wild(name, ipv4 = nil, ipv6 = nil)
224
225
  vms = importable_wilds.select {|vm| vm['VM_NAME'] == name }
225
226
 
226
227
  if vms.length == 0
@@ -247,8 +248,15 @@ module OpenNebula
247
248
  vi_client = VCenterDriver::VIClient.new_from_host(self["ID"])
248
249
  importer = VCenterDriver::VmmImporter.new(@client, vi_client)
249
250
 
250
- return importer.import({wild: wild, template: template,
251
- one_item: vm, host: self['ID']})
251
+ return importer.import(
252
+ { :wild => wild,
253
+ :template => template,
254
+ :one_item => vm,
255
+ :host => self['ID'],
256
+ :ipv4 => ipv4,
257
+ :ipv6 => ipv6
258
+ }
259
+ )
252
260
  else
253
261
  rc = vm.allocate(template)
254
262
 
@@ -15,7 +15,9 @@
15
15
  # ---------------------------------------------------------------------------- #
16
16
 
17
17
  require 'rubygems'
18
- require 'opennebula'
18
+ require 'opennebula/xml_utils'
19
+ require 'opennebula/client'
20
+ require 'opennebula/group_pool'
19
21
  require 'net/ldap'
20
22
  require 'yaml'
21
23
 
@@ -185,9 +185,23 @@ module OpenNebula::MarketPlaceAppExt
185
185
  #---------------------------------------------------------------
186
186
  # Created an associated VMTemplate if needed
187
187
  #---------------------------------------------------------------
188
- if (self['TEMPLATE/VMTEMPLATE64'].nil? && !is_vcenter) ||
189
- options[:notemplate] ||
190
- options[:template] == -1
188
+ if is_vcenter &&
189
+ !options[:notemplate] &&
190
+ (!options[:template] || options[:template] == -1)
191
+ tmpl = create_vcenter_template(ds, options, image)
192
+
193
+ if OpenNebula.is_error?(tmpl)
194
+ rc_info[:vmtemplate] = [tmpl]
195
+ else
196
+ rc_info[:vmtemplate] = [tmpl.id]
197
+ end
198
+
199
+ return rc_info
200
+ end
201
+
202
+ if self['TEMPLATE/VMTEMPLATE64'].nil? ||
203
+ options[:notemplate] ||
204
+ options[:template] == -1
191
205
  return rc_info
192
206
  end
193
207
 
@@ -286,33 +300,128 @@ module OpenNebula::MarketPlaceAppExt
286
300
  rc
287
301
  end
288
302
 
289
- def update_options_with_template(options, _validate = false)
290
- vcenterrc_path =
291
- "#{VAR_LOCATION}/remotes/etc/vmm/vcenter/vcenterrc"
303
+ # Create a VM template in vCenter in order to use it when
304
+ # deploying an app from the marketplace
305
+ #
306
+ # @param ds [OpenNebula::Datastore] Datastore information
307
+ # @param options [Hash] Export options
308
+ # @param image [OpenNebula::Image] Image information
309
+ def create_vcenter_template(ds, options, image = nil)
310
+ ret = {}
311
+ keys = %w[VCENTER_TEMPLATE_REF
312
+ VCENTER_CCR_REF
313
+ VCENTER_INSTANCE_ID]
314
+
315
+ if ds['//VCENTER_TEMPLATE_REF']
316
+ keys.each do |key|
317
+ ret[key] = ds["//#{key}"]
318
+ end
319
+ else
320
+ require 'vcenter_driver'
292
321
 
293
- if File.file?(vcenterrc_path)
294
- config_vcenter = YAML.load_file(vcenterrc_path)
322
+ # Get vi client for current datastore
323
+ vi_client = VCenterDriver::VIClient.new_from_datastore(
324
+ ds.id
325
+ )
295
326
 
296
- if config_vcenter.key?(:default_template)
297
- options[:template] =
298
- config_vcenter[:default_template]
327
+ # Get datastore object
328
+ ds_ref = ds['//VCENTER_DS_REF']
329
+ datastore = VCenterDriver::Datastore.new_from_ref(
330
+ ds_ref,
331
+ vi_client
332
+ )
299
333
 
300
- options
301
- else
302
- raise "Couldn't find default_template " \
303
- 'configuration in vcenterrc conf ' \
304
- 'file. Please use the --template ' \
305
- 'file to define a VM Template ID if ' \
306
- 'needed or add default_template to' \
307
- ' vcenterrc conf file'
334
+ # Get resource pool
335
+ host_ref = datastore['host'].first.key.parent._ref
336
+ vi_client.ccr_ref = host_ref
337
+
338
+ host = VCenterDriver::ClusterComputeResource.new_from_ref(
339
+ host_ref,
340
+ vi_client
341
+ )
342
+
343
+ rp = host.resource_pools.first
344
+
345
+ # Get vCentrer instance ID
346
+ uuid = vi_client.vim.serviceContent.about.instanceUuid
347
+
348
+ # Create VM folder it not exists
349
+ dc = datastore.obtain_dc.item
350
+ vm_folder = dc.find_folder('one_default_template')
351
+
352
+ if vm_folder.nil?
353
+ dc.vmFolder.CreateFolder(
354
+ :name => 'one_default_template'
355
+ )
356
+ vm_folder = dc.find_folder('one_default_template')
357
+ end
358
+
359
+ # Define default VM config
360
+ vm_cfg = { :name => "one_app_template-#{ds.id}",
361
+ :guestId => 'otherGuest',
362
+ :numCPUs => 1,
363
+ :memoryMB => 128,
364
+ :files => {
365
+ :vmPathName => "[#{datastore.item.name}]"
366
+ } }
367
+
368
+ # Create the VM
369
+ vm = vm_folder.CreateVM_Task(
370
+ :config => vm_cfg,
371
+ :pool => rp
372
+ ).wait_for_completion
373
+
374
+ # Create the VM template
375
+ vm.MarkAsTemplate
376
+
377
+ ret['VCENTER_TEMPLATE_REF'] = vm._ref
378
+ ret['VCENTER_CCR_REF'] = host_ref
379
+ ret['VCENTER_INSTANCE_ID'] = uuid
380
+
381
+ ret.each do |key, value|
382
+ ds.update("#{key}=\"#{value}\"", true)
308
383
  end
384
+ end
385
+
386
+ tmpl = <<-EOT
387
+ NAME = "#{options[:vmtemplate_name] || options[:name]}"
388
+ CPU = "1"
389
+ VCPU = "1"
390
+ MEMORY = "128"
391
+ HYPERVISOR = "vcenter"
392
+ EOT
393
+
394
+ tmpl << "DISK = [ IMAGE_ID = \"#{image.id}\" ]" if image
395
+
396
+ ret.each do |key, value|
397
+ tmpl << "#{key}=\"#{value}\"\n"
398
+ end
399
+
400
+ vmtpl = Template.new(Template.build_xml, @client)
401
+
402
+ rc = vmtpl.allocate(tmpl)
403
+
404
+ if OpenNebula.is_error?(rc)
405
+ rc
309
406
  else
310
- raise "Couldn't find vcenterrc conf file. " \
311
- ' Please use the --template file to define' \
312
- ' a VM Template ID if needed.'
407
+ Template.new_with_id(vmtpl.id, @client)
313
408
  end
314
409
  end
315
410
 
411
+ def update_options_with_template(options)
412
+ path = "#{VAR_LOCATION}/remotes/etc/vmm/vcenter/vcenterrc"
413
+
414
+ return options unless File.file?(path)
415
+
416
+ config = YAML.load_file(path)
417
+
418
+ return options unless config.key?(:default_template)
419
+
420
+ options[:template] = config[:default_template]
421
+
422
+ options
423
+ end
424
+
316
425
  # Creates a VM template based on the APPTEMPLATE64 attribute
317
426
  # @param [Hash] options
318
427
  # :export_name [String] name of the vm template
@@ -334,19 +443,19 @@ module OpenNebula::MarketPlaceAppExt
334
443
  options = update_options_with_template(options)
335
444
  end
336
445
 
337
- template_id = options[:template]
338
-
339
- if template_id < 0
340
- return
341
- end
446
+ if !options[:template] || options[:template] == -1
447
+ vmtpl = create_vcenter_template(ds, options)
448
+ else
449
+ template_id = options[:template]
450
+ template = Template.new_with_id(template_id, @client)
342
451
 
343
- template = Template.new_with_id(template_id, @client)
452
+ vmtpl_id = template.clone(
453
+ options[:vmtemplate_name] || options[:name]
454
+ )
344
455
 
345
- vmtpl_id = template.clone(
346
- options[:vmtemplate_name] || options[:name]
347
- )
456
+ vmtpl = Template.new_with_id(vmtpl_id, @client)
457
+ end
348
458
 
349
- vmtpl = Template.new_with_id(vmtpl_id, @client)
350
459
  rc = vmtpl.info
351
460
  else
352
461
  # ----------------------------------------------------------
@@ -461,7 +570,7 @@ module OpenNebula::MarketPlaceAppExt
461
570
  def export_recursive(xpath, options)
462
571
  # Get marketplace apps pool to find roles apps
463
572
  pool = OpenNebula::MarketPlaceAppPool.new(@client)
464
- rc = pool.info
573
+ rc = pool.info_all
465
574
 
466
575
  return rc if OpenNebula.is_error?(rc)
467
576
 
@@ -319,10 +319,21 @@ module Service
319
319
 
320
320
  class Client
321
321
  def initialize(opts={})
322
+ endpoint = '/.one/oneflow_endpoint'
322
323
  @username = opts[:username] || ENV['ONEFLOW_USER']
323
324
  @password = opts[:password] || ENV['ONEFLOW_PASSWORD']
324
325
 
325
- url = opts[:url] || ENV['ONEFLOW_URL'] || 'http://localhost:2474'
326
+ if opts[:url]
327
+ url = opts[:url]
328
+ elsif ENV['ONEFLOW_URL']
329
+ url = ENV['ONEFLOW_URL']
330
+ elsif ENV['HOME'] && File.exists?(ENV['HOME'] + endpoint)
331
+ url = File.read(ENV['HOME'] + endpoint).strip
332
+ elsif File.exists?('/var/lib/one/.one/oneflow_endpoint')
333
+ url = File.read('/var/lib/one/.one/oneflow_endpoint').strip
334
+ else
335
+ url = 'http://localhost:2474'
336
+ end
326
337
 
327
338
  if @username.nil? && @password.nil?
328
339
  if ENV["ONE_AUTH"] and !ENV["ONE_AUTH"].empty? and File.file?(ENV["ONE_AUTH"])
@@ -89,8 +89,8 @@ module OpenNebula
89
89
  #######################################################################
90
90
 
91
91
  # Retrieves the information of the given User.
92
- def info()
93
- super(USER_METHODS[:info], 'USER')
92
+ def info(decrypt = false)
93
+ super(USER_METHODS[:info], 'USER', decrypt)
94
94
  end
95
95
 
96
96
  alias_method :info!, :info
@@ -54,7 +54,9 @@ module OpenNebula
54
54
  :unlock => "vm.unlock",
55
55
  :schedadd => "vm.schedadd",
56
56
  :scheddelete => "vm.scheddelete",
57
- :schedupdate => "vm.schedupdate"
57
+ :schedupdate => "vm.schedupdate",
58
+ :attachsg => "vm.attachsg",
59
+ :detachsg => "vm.detachsg"
58
60
  }
59
61
 
60
62
  VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED
@@ -460,6 +462,25 @@ module OpenNebula
460
462
  return call(VM_METHODS[:detachnic], @pe_id, nic_id)
461
463
  end
462
464
 
465
+ # Attaches a Security Groupt to a running VM
466
+ #
467
+ # @param nic_id [Integer] Id of the NIC, where to attach SG
468
+ # @param sg_id [Integer] Id of the SG to be attached
469
+ # @return [nil, OpenNebula::Error] nil in case of success, Error
470
+ # otherwise
471
+ def sg_attach(nic_id, sg_id)
472
+ return call(VM_METHODS[:attachsg], @pe_id, nic_id, sg_id)
473
+ end
474
+
475
+ # Detaches a Security Group from a running VM
476
+ #
477
+ # @param sg_id [Integer] Id of the SG to be detached
478
+ # @return [nil, OpenNebula::Error] nil in case of success, Error
479
+ # otherwise
480
+ def sg_detach(nic_id, sg_id)
481
+ return call(VM_METHODS[:detachsg], @pe_id, nic_id, sg_id)
482
+ end
483
+
463
484
  # Sets the re-scheduling flag for the VM
464
485
  def resched
465
486
  action('resched')
@@ -94,6 +94,35 @@ module OpenNebula::VirtualMachineExt
94
94
  raise rc.message if OpenNebula.is_error?(rc)
95
95
  end
96
96
 
97
+ # --------------------------------------------------------------
98
+ # Ask if source VM is linked clone
99
+ # --------------------------------------------------------------
100
+ use_linked_clones = self['USER_TEMPLATE/VCENTER_LINKED_CLONES']
101
+
102
+ if use_linked_clones && use_linked_clones.downcase == 'yes'
103
+ # Delay the require until it is strictly needed
104
+ # This way we can avoid the vcenter driver dependency
105
+ # in no vCenter deployments
106
+ require 'vcenter_driver'
107
+
108
+ deploy_id = self['DEPLOY_ID']
109
+ vm_id = self['ID']
110
+ host_id = self['HISTORY_RECORDS/HISTORY[last()]/HID']
111
+ vi_client = VCenterDriver::VIClient.new_from_host(host_id)
112
+
113
+ vm = VCenterDriver::VirtualMachine.new(
114
+ vi_client,
115
+ deploy_id,
116
+ vm_id
117
+ )
118
+
119
+ error, vm_template_ref = vm.save_as_linked_clones(name)
120
+
121
+ raise error unless error.nil?
122
+
123
+ return vm_template_ref
124
+ end
125
+
97
126
  # --------------------------------------------------------------
98
127
  # Clone the source template
99
128
  # --------------------------------------------------------------
@@ -271,7 +300,7 @@ module OpenNebula::VirtualMachineExt
271
300
 
272
301
  raise rc.message if OpenNebula.is_error?(rc)
273
302
 
274
- binfo.merge!(backup_info) do |key, old_val, new_val|
303
+ binfo.merge!(backup_info) do |_key, old_val, new_val|
275
304
  new_val.nil? ? old_val : new_val
276
305
  end
277
306
 
@@ -472,7 +501,7 @@ module OpenNebula::VirtualMachineExt
472
501
  end
473
502
 
474
503
  binfo[:apps].each do |id|
475
- logger.info "Deleting applicance #{id}" if logger
504
+ logger.info "Deleting appliance #{id}" if logger
476
505
 
477
506
  papp = OpenNebula::MarketPlaceApp.new_with_id(id, @client)
478
507
 
@@ -450,6 +450,10 @@ module OpenNebula
450
450
  private
451
451
 
452
452
  def build_accounting(filter_flag, options, &block)
453
+
454
+ options[:start_time] = -1 if options[:start_time].nil?
455
+ options[:end_time] = -1 if options[:end_time].nil?
456
+
453
457
  xml_str = @client.call(VM_POOL_METHODS[:accounting],
454
458
  filter_flag,
455
459
  options[:start_time],
data/lib/opennebula.rb CHANGED
@@ -77,5 +77,5 @@ require 'opennebula/flow'
77
77
  module OpenNebula
78
78
 
79
79
  # OpenNebula version
80
- VERSION = '6.2.0'
80
+ VERSION = '6.3.80'
81
81
  end
@@ -28,6 +28,11 @@ module OpenNebula
28
28
  log_function("INFO", message)
29
29
  end
30
30
 
31
+ # Logs an info message
32
+ def self.log_warning(message)
33
+ log_function('WARNING', message)
34
+ end
35
+
31
36
  # Logs an error message
32
37
  def self.log_error(message)
33
38
  log_function("ERROR", message)