diff --git a/berta.gemspec b/berta.gemspec index 493b0ed..64e5fe6 100644 --- a/berta.gemspec +++ b/berta.gemspec @@ -29,7 +29,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'chronic_duration', '~> 0.10' s.add_runtime_dependency 'mail', '~> 2.6' - s.add_runtime_dependency 'opennebula', '~> 5.8' + s.add_runtime_dependency 'opennebula', '>= 6.2', '<= 6.4' s.add_runtime_dependency 'settingslogic', '~> 2.0' s.add_runtime_dependency 'thor', '~> 0.19' s.add_runtime_dependency 'tilt', '~> 2.0' diff --git a/lib/berta/entities/expiration.rb b/lib/berta/entities/expiration.rb index 59bafa5..3e9ace3 100644 --- a/lib/berta/entities/expiration.rb +++ b/lib/berta/entities/expiration.rb @@ -9,9 +9,14 @@ class Expiration # @param xml [XMLElement] XML from which to create instance # @return [Berta::Entities::Expiration] Expiration from given xml # @raise [Berta::Errors::Entities::InvalidEntityXMLError] If XMLElement was not in correct format - def self.from_xml(xml) + def self.from_xml(xml, start_time=0) check_xml!(xml) - Berta::Entities::Expiration.new(xml['ID'], xml['TIME'], xml['ACTION']) + time = if xml['TIME'].start_with?('+') + start_time + xml['TIME'].to_i + else + xml['TIME'] + end + Berta::Entities::Expiration.new(xml['ID'], time, xml['ACTION']) end # Raises error if XML element is not in correct format. @@ -37,7 +42,7 @@ def initialize(id, time, action) end # Generate schelude action template that can be used - # in VMS USER_TEMPLATE/SCHED_ACTION + # in VMS TEMPLATE/SCHED_ACTION # # @return [String] Schelude action template def template @@ -45,7 +50,9 @@ def template SCHED_ACTION = [ ID = "#{id}", ACTION = "#{action}", - TIME = "#{time}" + TIME = "#{time}", + END_TYPE = "2", + END_VALUE = "#{time}" ] VM_TEMPLATE end diff --git a/lib/berta/virtual_machine_handler.rb b/lib/berta/virtual_machine_handler.rb index 7ba2cd3..8fc72bd 100644 --- a/lib/berta/virtual_machine_handler.rb +++ b/lib/berta/virtual_machine_handler.rb @@ -18,10 +18,8 @@ def initialize(virtual_machine) # invalid expiration it will be deleted. Other expirations # are kept. def update - exps = remove_invalid(expirations) - exps = add_default_expiration(exps) - return if exps == expirations - update_expirations(exps) + remove_invalid + add_default_expiration rescue Berta::Errors::BackendError => e logger.error "#{e.message} on vm with id #{handle['ID']}" end @@ -71,13 +69,14 @@ def default_expiration end # Returns array of expirations on vm. Expirations are - # classes from USER_TEMPLATE/SCHED_ACTION. + # classes from SCHED_ACTION. # # @return [Array] All expirations on vm def expirations exps = [] - handle.each('USER_TEMPLATE/SCHED_ACTION') \ - { |saxml| exps.push(Berta::Entities::Expiration.from_xml(saxml)) } + start_time = handle.retrieve_elements('STIME').first.to_i + handle.each('TEMPLATE/SCHED_ACTION') \ + { |saxml| exps.push(Berta::Entities::Expiration.from_xml(saxml, start_time)) } exps end @@ -96,35 +95,27 @@ def ==(other) private - def remove_invalid(exps) - valid = exps.select(&:in_expiration_interval?) - if valid.length != exps.length - logger.info "Removing #{exps.length - valid.length} invalid expirations on vm with" \ - "id=#{handle['ID']} usr=#{handle['UNAME']} grp=#{handle['GNAME']}" + def remove_invalid + invalid = expirations.reject(&:in_expiration_interval?) + if invalid + invalid.each do |exp| + logger.info "Removing invalid expirations #{exp.id} on vm with" \ + "id=#{handle['ID']} usr=#{handle['UNAME']} grp=#{handle['GNAME']}" \ + ", expires at #{Time.at(exp.time.to_i)}" + return if Berta::Settings['dry-run'] + handle.sched_action_delete(exp.id) + end end - valid end - def add_default_expiration(exps) + def add_default_expiration unless default_expiration new_default = next_expiration - exps << new_default logger.info "Adding default expiration on vm with id=#{handle['ID']} usr=#{handle['UNAME']} grp=#{handle['GNAME']}"\ ", expires at #{Time.at(new_default.time)}" + return if Berta::Settings['dry-run'] + handle.sched_action_add(new_default.template) end - exps - end - - # Sets array of expirations to vm, rewrites all old ones. - # Receiving empty array wont change anything. - # - # @note This method modifies OpenNebula database - # @param exps [Array] Expirations to use - def update_expirations(exps) - template = exps.inject('') { |temp, exp| temp + exp.template } - return if template == '' - logger.debug template.delete("\n ") - send_update(template) end # Sends data to opennebula service @@ -140,7 +131,7 @@ def send_update(template) # # @return [Numeric] Next sched action id def next_expiration_id - elems = handle.retrieve_elements('USER_TEMPLATE/SCHED_ACTION/ID') + elems = handle.retrieve_elements('TEMPLATE/SCHED_ACTION/ID') return 0 unless elems elems.to_a.max.to_i + 1 end