ovirt 0.5.0 → 0.6.0
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 +4 -4
- data/.rspec +0 -1
- data/README.md +1 -1
- data/lib/ovirt/api.rb +3 -4
- data/lib/ovirt/base.rb +47 -44
- data/lib/ovirt/cluster.rb +1 -1
- data/lib/ovirt/data_center.rb +1 -1
- data/lib/ovirt/event.rb +424 -424
- data/lib/ovirt/exception.rb +2 -2
- data/lib/ovirt/inventory.rb +7 -7
- data/lib/ovirt/logging.rb +5 -0
- data/lib/ovirt/null_logger.rb +11 -0
- data/lib/ovirt/service.rb +35 -45
- data/lib/ovirt/snapshot.rb +2 -2
- data/lib/ovirt/statistic.rb +4 -5
- data/lib/ovirt/storage_domain.rb +1 -1
- data/lib/ovirt/template.rb +28 -31
- data/lib/ovirt/user.rb +1 -1
- data/lib/ovirt/version.rb +1 -1
- data/lib/ovirt/vm.rb +18 -24
- data/lib/ovirt.rb +12 -0
- data/spec/base_spec.rb +7 -9
- data/spec/event_spec.rb +3 -13
- data/spec/factories/template.rb +37 -0
- data/spec/factories/vm.rb +1 -3
- data/spec/service_spec.rb +22 -23
- data/spec/spec_helper.rb +89 -9
- data/spec/template_spec.rb +23 -54
- data/spec/vm_spec.rb +47 -49
- metadata +9 -5
    
        data/lib/ovirt/exception.rb
    CHANGED
    
    | @@ -4,11 +4,11 @@ module Ovirt | |
| 4 4 |  | 
| 5 5 | 
             
              # Existence
         | 
| 6 6 | 
             
              class TemplateAlreadyExists < Error; end
         | 
| 7 | 
            -
              class VmAlreadyExists | 
| 7 | 
            +
              class VmAlreadyExists < Error; end
         | 
| 8 8 |  | 
| 9 9 | 
             
              # Power State
         | 
| 10 10 | 
             
              class VmAlreadyRunning < Error; end
         | 
| 11 | 
            -
              class VmIsNotRunning | 
| 11 | 
            +
              class VmIsNotRunning < Error; end
         | 
| 12 12 | 
             
              class VmNotReadyToBoot < Error; end
         | 
| 13 13 |  | 
| 14 14 | 
             
              class UsageError < Error; end
         | 
    
        data/lib/ovirt/inventory.rb
    CHANGED
    
    | @@ -2,7 +2,7 @@ module Ovirt | |
| 2 2 | 
             
              class Inventory
         | 
| 3 3 | 
             
                attr_accessor :service
         | 
| 4 4 |  | 
| 5 | 
            -
                def initialize(options={})
         | 
| 5 | 
            +
                def initialize(options = {})
         | 
| 6 6 | 
             
                  @service = Service.new(options)
         | 
| 7 7 | 
             
                end
         | 
| 8 8 |  | 
| @@ -78,9 +78,9 @@ module Ovirt | |
| 78 78 |  | 
| 79 79 | 
             
                def get_vm(path)
         | 
| 80 80 | 
             
                  vm_guid = ::File.basename(path, '.*')
         | 
| 81 | 
            -
                  vm | 
| 82 | 
            -
                  vm | 
| 83 | 
            -
                   | 
| 81 | 
            +
                  vm      = get_resource_by_ems_ref("/api/vms/#{vm_guid}") rescue nil
         | 
| 82 | 
            +
                  vm      = get_resource_by_ems_ref("/api/templates/#{vm_guid}") if vm.blank?
         | 
| 83 | 
            +
                  vm
         | 
| 84 84 | 
             
                end
         | 
| 85 85 |  | 
| 86 86 | 
             
                def get_resource_by_ems_ref(uri_suffix, element_name = nil)
         | 
| @@ -131,16 +131,16 @@ module Ovirt | |
| 131 131 | 
             
                # > secondary_item_jobs({:vm, => [v1, v2]})
         | 
| 132 132 | 
             
                #  => [[v1, :disks], [v1, :snapshots], [v1, :nics], [v2, :disks], [v2, :snapshots], [v2, :nics]]
         | 
| 133 133 | 
             
                def secondary_item_jobs(primary_items)
         | 
| 134 | 
            -
                  SECONDARY_ITEMS. | 
| 134 | 
            +
                  SECONDARY_ITEMS.flat_map do |key, methods|
         | 
| 135 135 | 
             
                    primary_items[key].product(methods)
         | 
| 136 | 
            -
                  end | 
| 136 | 
            +
                  end
         | 
| 137 137 | 
             
                end
         | 
| 138 138 |  | 
| 139 139 | 
             
                def collect_primary_items
         | 
| 140 140 | 
             
                  jobs = primary_item_jobs
         | 
| 141 141 |  | 
| 142 142 | 
             
                  results = collect_in_parallel(jobs) do |_, method|
         | 
| 143 | 
            -
                     | 
| 143 | 
            +
                    send(method)
         | 
| 144 144 | 
             
                  end
         | 
| 145 145 |  | 
| 146 146 | 
             
                  jobs.zip(results).each_with_object({}) do |((key, _), result), hash|
         | 
    
        data/lib/ovirt/service.rb
    CHANGED
    
    | @@ -2,6 +2,8 @@ require 'nokogiri' | |
| 2 2 |  | 
| 3 3 | 
             
            module Ovirt
         | 
| 4 4 | 
             
              class Service
         | 
| 5 | 
            +
                include Logging
         | 
| 6 | 
            +
             | 
| 5 7 | 
             
                DEFAULT_OPTIONS  = {}
         | 
| 6 8 | 
             
                REQUIRED_OPTIONS = [:server, :username, :password]
         | 
| 7 9 | 
             
                DEFAULT_PORT_3_0 = 8443
         | 
| @@ -20,16 +22,16 @@ module Ovirt | |
| 20 22 | 
             
                  klass.create_from_xml(self, xml)
         | 
| 21 23 | 
             
                end
         | 
| 22 24 |  | 
| 23 | 
            -
                def initialize(options={})
         | 
| 25 | 
            +
                def initialize(options = {})
         | 
| 24 26 | 
             
                  @options = DEFAULT_OPTIONS.merge(options)
         | 
| 25 27 | 
             
                  parse_domain_name
         | 
| 26 | 
            -
                  REQUIRED_OPTIONS.each { |key| raise "No #{key | 
| 27 | 
            -
                  @password | 
| 28 | 
            +
                  REQUIRED_OPTIONS.each { |key| raise "No #{key} specified" unless @options.key?(key) }
         | 
| 29 | 
            +
                  @password   = @options.delete(:password)
         | 
| 28 30 | 
             
                  @session_id = @options[:session_id]
         | 
| 29 31 | 
             
                end
         | 
| 30 32 |  | 
| 31 33 | 
             
                def inspect # just like the default inspect, but WITHOUT @password
         | 
| 32 | 
            -
                  "#<#{self.class.name}:0x#{( | 
| 34 | 
            +
                  "#<#{self.class.name}:0x#{(object_id << 1).to_s(16).rjust(14, '0')} @options=#{@options.inspect}>"
         | 
| 33 35 | 
             
                end
         | 
| 34 36 |  | 
| 35 37 | 
             
                def api(reload = false)
         | 
| @@ -95,10 +97,10 @@ module Ovirt | |
| 95 97 | 
             
                end
         | 
| 96 98 |  | 
| 97 99 | 
             
                def get_resource_by_ems_ref(uri_suffix, element_name = nil)
         | 
| 98 | 
            -
                  xml | 
| 99 | 
            -
                  doc | 
| 100 | 
            +
                  xml            = resource_get(uri_suffix)
         | 
| 101 | 
            +
                  doc            = Nokogiri::XML(xml)
         | 
| 100 102 | 
             
                  element_name ||= doc.root.name
         | 
| 101 | 
            -
                  klass | 
| 103 | 
            +
                  klass          = self.class.name_to_class(element_name)
         | 
| 102 104 | 
             
                  xml_to_object(klass, doc.root)
         | 
| 103 105 | 
             
                end
         | 
| 104 106 |  | 
| @@ -110,17 +112,16 @@ module Ovirt | |
| 110 112 | 
             
                    doc = Nokogiri::XML(xml)
         | 
| 111 113 | 
             
                  end
         | 
| 112 114 | 
             
                  element_name ||= uri_suffix.singularize
         | 
| 113 | 
            -
                  klass | 
| 115 | 
            +
                  klass          = self.class.name_to_class(element_name)
         | 
| 114 116 |  | 
| 115 117 | 
             
                  xml_path = uri_suffix == 'api' ? element_name : "#{element_name.pluralize}/#{element_name}"
         | 
| 116 | 
            -
                  objects | 
| 118 | 
            +
                  objects  = doc.xpath("//#{xml_path}")
         | 
| 117 119 | 
             
                  objects.collect { |obj| xml_to_object(klass, obj) }
         | 
| 118 120 | 
             
                end
         | 
| 119 121 |  | 
| 120 122 | 
             
                def status(link)
         | 
| 121 123 | 
             
                  response = resource_get(link)
         | 
| 122 | 
            -
             | 
| 123 | 
            -
                  node = Base.xml_to_nokogiri(response)
         | 
| 124 | 
            +
                  node     = Base.xml_to_nokogiri(response)
         | 
| 124 125 | 
             
                  node.xpath('status/state').text
         | 
| 125 126 | 
             
                end
         | 
| 126 127 |  | 
| @@ -137,7 +138,7 @@ module Ovirt | |
| 137 138 |  | 
| 138 139 | 
             
                def self.ovirt?(options)
         | 
| 139 140 | 
             
                  options[:username] = options[:password] = "_unused"
         | 
| 140 | 
            -
                  ! | 
| 141 | 
            +
                  !new(options).engine_ssh_public_key.to_s.blank?
         | 
| 141 142 | 
             
                rescue RestClient::ResourceNotFound
         | 
| 142 143 | 
             
                  false
         | 
| 143 144 | 
             
                end
         | 
| @@ -147,36 +148,36 @@ module Ovirt | |
| 147 148 | 
             
                  RestClient::Resource.new("#{base_uri}/engine.ssh.key.txt", resource_options).get
         | 
| 148 149 | 
             
                end
         | 
| 149 150 |  | 
| 150 | 
            -
                def paginate_resource_get(path = nil, sort_by | 
| 151 | 
            +
                def paginate_resource_get(path = nil, sort_by = :name, direction = :asc)
         | 
| 151 152 | 
             
                  log_header = "#{self.class.name}#paginate_resource_get"
         | 
| 152 | 
            -
                  page | 
| 153 | 
            -
                  full_xml | 
| 153 | 
            +
                  page       = 1
         | 
| 154 | 
            +
                  full_xml   = nil
         | 
| 154 155 | 
             
                  loop do
         | 
| 155 156 | 
             
                    uri = "#{path}?search=sortby%20#{sort_by}%20#{direction}%20page%20#{page}"
         | 
| 156 | 
            -
                    partial_xml_str =  | 
| 157 | 
            +
                    partial_xml_str = resource_get(uri)
         | 
| 157 158 | 
             
                    if full_xml.nil?
         | 
| 158 159 | 
             
                      full_xml = Nokogiri::XML(partial_xml_str)
         | 
| 159 160 | 
             
                    else
         | 
| 160 161 | 
             
                      partial_xml = Nokogiri::XML(partial_xml_str)
         | 
| 161 162 | 
             
                      break if partial_xml.root.children.count == 0
         | 
| 162 | 
            -
                       | 
| 163 | 
            +
                      logger.debug "#{log_header}: Combining resource elements for <#{path}> from page:<#{page}>"
         | 
| 163 164 | 
             
                      full_xml.root << partial_xml.root.children
         | 
| 164 165 | 
             
                    end
         | 
| 165 166 | 
             
                    page += 1
         | 
| 166 167 | 
             
                  end
         | 
| 167 | 
            -
                   | 
| 168 | 
            -
                   | 
| 168 | 
            +
                  logger.debug "#{log_header}: Combined elements for <#{path}>.  Total elements:<#{full_xml.root.children.count}>"
         | 
| 169 | 
            +
                  full_xml
         | 
| 169 170 | 
             
                end
         | 
| 170 171 |  | 
| 171 172 | 
             
                def resource_get(path = nil)
         | 
| 172 173 | 
             
                  resource_verb(path, :get)
         | 
| 173 174 | 
             
                end
         | 
| 174 175 |  | 
| 175 | 
            -
                def resource_put(path, payload, additional_headers={:content_type => :xml, :accept => :xml})
         | 
| 176 | 
            +
                def resource_put(path, payload, additional_headers = {:content_type => :xml, :accept => :xml})
         | 
| 176 177 | 
             
                  resource_verb(path, :put, payload, additional_headers)
         | 
| 177 178 | 
             
                end
         | 
| 178 179 |  | 
| 179 | 
            -
                def resource_post(path, payload, additional_headers={:content_type => :xml, :accept => :xml})
         | 
| 180 | 
            +
                def resource_post(path, payload, additional_headers = {:content_type => :xml, :accept => :xml})
         | 
| 180 181 | 
             
                  resource_verb(path, :post, payload, additional_headers)
         | 
| 181 182 | 
             
                end
         | 
| 182 183 |  | 
| @@ -193,10 +194,9 @@ module Ovirt | |
| 193 194 |  | 
| 194 195 | 
             
                def resource_verb(path, verb, *args)
         | 
| 195 196 | 
             
                  log_header = "#{self.class.name}#resource_#{verb}"
         | 
| 196 | 
            -
             | 
| 197 | 
            -
                   | 
| 198 | 
            -
                   | 
| 199 | 
            -
                  $rhevm_log.debug "#{log_header}: With args: <#{args.inspect}>" if $rhevm_log.try(:debug?)
         | 
| 197 | 
            +
                  resource   = create_resource(path)
         | 
| 198 | 
            +
                  logger.info "#{log_header}: Sending URL: <#{resource.url}>"
         | 
| 199 | 
            +
                  logger.debug "#{log_header}: With args: <#{args.inspect}>"
         | 
| 200 200 | 
             
                  resource.send(verb, *args) do |response, request, result, &block|
         | 
| 201 201 | 
             
                    case response.code
         | 
| 202 202 | 
             
                    when 200
         | 
| @@ -208,7 +208,7 @@ module Ovirt | |
| 208 208 | 
             
                    end
         | 
| 209 209 | 
             
                  end
         | 
| 210 210 | 
             
                rescue RestClient::Unauthorized
         | 
| 211 | 
            -
                  if  | 
| 211 | 
            +
                  if session_id
         | 
| 212 212 | 
             
                    self.session_id = nil
         | 
| 213 213 | 
             
                    retry
         | 
| 214 214 | 
             
                  else
         | 
| @@ -217,22 +217,15 @@ module Ovirt | |
| 217 217 | 
             
                rescue RestClient::ResourceNotFound, Ovirt::Error
         | 
| 218 218 | 
             
                  raise
         | 
| 219 219 | 
             
                rescue Exception => e
         | 
| 220 | 
            -
                   | 
| 221 | 
            -
                  if $rhevm_log.nil?
         | 
| 222 | 
            -
                    puts msg
         | 
| 223 | 
            -
                  else
         | 
| 224 | 
            -
                    $rhevm_log.error msg
         | 
| 225 | 
            -
                  end
         | 
| 220 | 
            +
                  logger.error("#{log_header}: class = #{e.class.name}, message=#{e.message}, URI=#{resource ? resource.url : path}")
         | 
| 226 221 | 
             
                  raise
         | 
| 227 222 | 
             
                end
         | 
| 228 223 |  | 
| 229 224 | 
             
                def parse_normal_response(response, resource)
         | 
| 230 225 | 
             
                  parse_set_cookie_header(response.headers[:set_cookie])
         | 
| 231 | 
            -
                   | 
| 232 | 
            -
             | 
| 233 | 
            -
             | 
| 234 | 
            -
                    $rhevm_log.debug "#{log_header}: Return from URL: <#{resource.url}> Data:#{response}" if $rhevm_log.debug?
         | 
| 235 | 
            -
                  end
         | 
| 226 | 
            +
                  log_header = "#{self.class.name}#parse_normal_response"
         | 
| 227 | 
            +
                  logger.info  "#{log_header}: Return from URL: <#{resource.url}> Data length:#{response.length}"
         | 
| 228 | 
            +
                  logger.debug "#{log_header}: Return from URL: <#{resource.url}> Data:#{response}"
         | 
| 236 229 | 
             
                  response
         | 
| 237 230 | 
             
                end
         | 
| 238 231 |  | 
| @@ -262,11 +255,11 @@ module Ovirt | |
| 262 255 | 
             
                end
         | 
| 263 256 |  | 
| 264 257 | 
             
                def resource_options
         | 
| 265 | 
            -
                  headers = merge_headers( | 
| 258 | 
            +
                  headers = merge_headers('Prefer' => 'persistent-auth')
         | 
| 266 259 | 
             
                  options = {}
         | 
| 267 260 |  | 
| 268 | 
            -
                  if  | 
| 269 | 
            -
                    headers[:cookie]     = "#{SESSION_ID_KEY}=#{ | 
| 261 | 
            +
                  if session_id
         | 
| 262 | 
            +
                    headers[:cookie]     = "#{SESSION_ID_KEY}=#{session_id}"
         | 
| 270 263 | 
             
                  else
         | 
| 271 264 | 
             
                    options[:user]       = fully_qualified_username
         | 
| 272 265 | 
             
                    options[:password]   = password
         | 
| @@ -285,7 +278,7 @@ module Ovirt | |
| 285 278 | 
             
                end
         | 
| 286 279 |  | 
| 287 280 | 
             
                def authorization_header
         | 
| 288 | 
            -
                  @authorization_header ||= { | 
| 281 | 
            +
                  @authorization_header ||= {:authorization => "Basic #{authorization_value}"}
         | 
| 289 282 | 
             
                end
         | 
| 290 283 |  | 
| 291 284 | 
             
                def authorization_value
         | 
| @@ -315,9 +308,7 @@ module Ovirt | |
| 315 308 | 
             
                  @options[:username]
         | 
| 316 309 | 
             
                end
         | 
| 317 310 |  | 
| 318 | 
            -
                 | 
| 319 | 
            -
                  @password
         | 
| 320 | 
            -
                end
         | 
| 311 | 
            +
                attr_reader :password
         | 
| 321 312 |  | 
| 322 313 | 
             
                def domain
         | 
| 323 314 | 
             
                  @options[:domain]
         | 
| @@ -345,6 +336,5 @@ module Ovirt | |
| 345 336 | 
             
                    end
         | 
| 346 337 | 
             
                  end
         | 
| 347 338 | 
             
                end
         | 
| 348 | 
            -
             | 
| 349 339 | 
             
              end
         | 
| 350 340 | 
             
            end
         | 
    
        data/lib/ovirt/snapshot.rb
    CHANGED
    
    | @@ -10,11 +10,11 @@ module Ovirt | |
| 10 10 | 
             
                end
         | 
| 11 11 |  | 
| 12 12 | 
             
                def delete
         | 
| 13 | 
            -
                   | 
| 13 | 
            +
                  destroy
         | 
| 14 14 | 
             
                  while self[:snapshot_status] == "locked" || self[:snapshot_status] == "ok"
         | 
| 15 15 | 
             
                    sleep 2
         | 
| 16 16 | 
             
                    break if (obj = self.class.find_by_href(@service, self[:href])).nil?
         | 
| 17 | 
            -
                     | 
| 17 | 
            +
                    replace(obj)
         | 
| 18 18 | 
             
                  end
         | 
| 19 19 | 
             
                end
         | 
| 20 20 | 
             
              end
         | 
    
        data/lib/ovirt/statistic.rb
    CHANGED
    
    | @@ -3,10 +3,9 @@ module Ovirt | |
| 3 3 | 
             
                self.top_level_strings = [:name, :description, :type, :unit]
         | 
| 4 4 |  | 
| 5 5 | 
             
                def self.parse_node_extended(node, hash)
         | 
| 6 | 
            -
                   | 
| 7 | 
            -
                   | 
| 8 | 
            -
                   | 
| 9 | 
            -
                  values = values_node.xpath('value').collect do |v|
         | 
| 6 | 
            +
                  values_node = node.xpath('values').first
         | 
| 7 | 
            +
                  values_type = values_node['type']
         | 
| 8 | 
            +
                  values      = values_node.xpath('value').collect do |v|
         | 
| 10 9 | 
             
                    datum = v.xpath('datum').text
         | 
| 11 10 | 
             
                    case values_type
         | 
| 12 11 | 
             
                    when 'INTEGER'
         | 
| @@ -18,7 +17,7 @@ module Ovirt | |
| 18 17 | 
             
                    end
         | 
| 19 18 | 
             
                    datum
         | 
| 20 19 | 
             
                  end
         | 
| 21 | 
            -
                  hash[:values] | 
| 20 | 
            +
                  hash[:values] = values
         | 
| 22 21 |  | 
| 23 22 | 
             
                  [:vm, :nic, :disk].each do |type|
         | 
| 24 23 | 
             
                    parent_node = node.xpath(type.to_s).first
         | 
    
        data/lib/ovirt/storage_domain.rb
    CHANGED
    
    | @@ -25,7 +25,7 @@ module Ovirt | |
| 25 25 |  | 
| 26 26 | 
             
                      unless vg_hash.blank?
         | 
| 27 27 | 
             
                        parse_first_node(vg, :logical_unit, vg_hash,
         | 
| 28 | 
            -
             | 
| 28 | 
            +
                                         :node => [:address, :port, :target, :username, :serial, :vendor_id, :product_id, :lun_mapping, :portal, :size, :paths])
         | 
| 29 29 | 
             
                      end
         | 
| 30 30 | 
             
                    end
         | 
| 31 31 | 
             
                  end
         | 
    
        data/lib/ovirt/template.rb
    CHANGED
    
    | @@ -17,7 +17,7 @@ module Ovirt | |
| 17 17 | 
             
                                   :node_to_bool => [:enabled])
         | 
| 18 18 |  | 
| 19 19 | 
             
                  parse_first_node_with_hash(node, 'cpu/topology', hash.store_path(:cpu, :topology, {}),
         | 
| 20 | 
            -
             | 
| 20 | 
            +
                                             :attribute_to_i => [:sockets, :cores])
         | 
| 21 21 |  | 
| 22 22 | 
             
                  parse_first_node(node, :high_availability, hash,
         | 
| 23 23 | 
             
                                   :node_to_bool => [:enabled],
         | 
| @@ -28,7 +28,7 @@ module Ovirt | |
| 28 28 | 
             
                                   :node      => [:kernel, :initrd, :cmdline])
         | 
| 29 29 |  | 
| 30 30 | 
             
                  hash[:os][:boot_order] = boot_order = []
         | 
| 31 | 
            -
                  #Collect boot order
         | 
| 31 | 
            +
                  # Collect boot order
         | 
| 32 32 | 
             
                  node.xpath('os/boot').each do |boot|
         | 
| 33 33 | 
             
                    dev = boot['dev']
         | 
| 34 34 | 
             
                    boot_order << {:dev => dev} unless dev.blank?
         | 
| @@ -41,37 +41,34 @@ module Ovirt | |
| 41 41 | 
             
                end
         | 
| 42 42 |  | 
| 43 43 | 
             
                def os_type
         | 
| 44 | 
            -
                   | 
| 44 | 
            +
                  attributes.fetch_path(:os, :type) || 'unassigned'
         | 
| 45 45 | 
             
                end
         | 
| 46 46 |  | 
| 47 | 
            -
                def getCfg( | 
| 48 | 
            -
                  # | 
| 49 | 
            -
                   | 
| 47 | 
            +
                def getCfg(_snap = nil)
         | 
| 48 | 
            +
                  # TODO: Remove the following MiqException and any others
         | 
| 49 | 
            +
                  raise MiqException::MiqVimError, "Failed to retrieve configuration information for VM" if attributes.nil?
         | 
| 50 50 |  | 
| 51 | 
            -
                   | 
| 52 | 
            -
             | 
| 53 | 
            -
                   | 
| 54 | 
            -
                   | 
| 55 | 
            -
                   | 
| 56 | 
            -
                  cfgHash['memsize'] = cfgProps[:memory] / 1048576  # in MB
         | 
| 57 | 
            -
                  cfgHash['numvcpu'] = cfgProps.fetch_path(:cpu, :sockets)
         | 
| 51 | 
            +
                  cfg_hash = {}
         | 
| 52 | 
            +
                  cfg_hash['displayname'] = attributes[:name]
         | 
| 53 | 
            +
                  cfg_hash['guestos']     = attributes.fetch_path(:os, :type)
         | 
| 54 | 
            +
                  cfg_hash['memsize']     = attributes[:memory] / 1_048_576  # in MB
         | 
| 55 | 
            +
                  cfg_hash['numvcpu']     = attributes.fetch_path(:cpu, :sockets)
         | 
| 58 56 |  | 
| 59 57 | 
             
                  # Collect disk information
         | 
| 60 | 
            -
                   | 
| 61 | 
            -
                   | 
| 58 | 
            +
                  attributes[:disks] = send(:disks, :disk) if self[:disks].nil?
         | 
| 59 | 
            +
                  disks.each_with_index do |disk, idx|
         | 
| 62 60 | 
             
                    storage_domain = disk[:storage_domains].first
         | 
| 63 | 
            -
                    storage_id | 
| 64 | 
            -
                    disk_key | 
| 65 | 
            -
                    file_path | 
| 61 | 
            +
                    storage_id     = storage_domain && storage_domain[:id]
         | 
| 62 | 
            +
                    disk_key       = disk[:image_id].blank? ? :id : :image_id
         | 
| 63 | 
            +
                    file_path      = storage_id && ::File.join('/dev', storage_id, disk[disk_key])
         | 
| 66 64 |  | 
| 67 65 | 
             
                    tag = "scsi0:#{idx}"
         | 
| 68 | 
            -
                     | 
| 69 | 
            -
                     | 
| 70 | 
            -
                     | 
| 71 | 
            -
                     | 
| 72 | 
            -
                    #cfgHash["#{tag}.mode"] = dev['backing']['diskMode']
         | 
| 66 | 
            +
                    cfg_hash["#{tag}.present"]    = "true"
         | 
| 67 | 
            +
                    cfg_hash["#{tag}.devicetype"] = "disk"
         | 
| 68 | 
            +
                    cfg_hash["#{tag}.filename"]   = file_path.to_s
         | 
| 69 | 
            +
                    cfg_hash["#{tag}.format"]     = disk[:format]
         | 
| 73 70 | 
             
                  end
         | 
| 74 | 
            -
                   | 
| 71 | 
            +
                  cfg_hash
         | 
| 75 72 | 
             
                end
         | 
| 76 73 |  | 
| 77 74 | 
             
                REQUIRED_CLONE_PARAMETERS     = [:name, :cluster]
         | 
| @@ -85,9 +82,9 @@ module Ovirt | |
| 85 82 | 
             
                  options[:storage] = Base.object_to_id(options[:storage]) if options[:storage]
         | 
| 86 83 |  | 
| 87 84 | 
             
                  case options[:clone_type]
         | 
| 88 | 
            -
                  when :full | 
| 89 | 
            -
                  when :linked | 
| 90 | 
            -
                  when :skeletal | 
| 85 | 
            +
                  when :full     then clone_to_vm(options)
         | 
| 86 | 
            +
                  when :linked   then clone_to_vm(options)
         | 
| 87 | 
            +
                  when :skeletal then clone_to_vm_via_blank_template(options)
         | 
| 91 88 | 
             
                  end
         | 
| 92 89 | 
             
                end
         | 
| 93 90 |  | 
| @@ -105,7 +102,7 @@ module Ovirt | |
| 105 102 | 
             
                  (CLONE_ATTRIBUTES_WITH_SCALARS + CLONE_ATTRIBUTES_WITH_HASHES).each do |key|
         | 
| 106 103 | 
             
                    options[key] ||= self[key]
         | 
| 107 104 | 
             
                  end
         | 
| 108 | 
            -
                  options[:os_type] ||=  | 
| 105 | 
            +
                  options[:os_type] ||= os_type
         | 
| 109 106 |  | 
| 110 107 | 
             
                  skeleton_options = options.dup
         | 
| 111 108 | 
             
                  skeleton_options[:clone_type] = :linked
         | 
| @@ -116,7 +113,7 @@ module Ovirt | |
| 116 113 | 
             
                end
         | 
| 117 114 |  | 
| 118 115 | 
             
                def create_new_disks_from_template(vm, options)
         | 
| 119 | 
            -
                   | 
| 116 | 
            +
                  disks.each do |disk_object|
         | 
| 120 117 | 
             
                    disk_options            = disk_object.attributes_for_new_disk
         | 
| 121 118 | 
             
                    disk_options[:sparse]   = options[:sparse]  unless options[:sparse].nil?
         | 
| 122 119 | 
             
                    disk_options[:storage]  = options[:storage] unless options[:storage].blank?
         | 
| @@ -155,14 +152,14 @@ module Ovirt | |
| 155 152 | 
             
                        end
         | 
| 156 153 | 
             
                      end
         | 
| 157 154 |  | 
| 158 | 
            -
                      xml.os(:type => options[:os_type] ||  | 
| 155 | 
            +
                      xml.os(:type => options[:os_type] || os_type) do
         | 
| 159 156 | 
             
                        xml.boot(:dev => 'hd')
         | 
| 160 157 | 
             
                      end
         | 
| 161 158 |  | 
| 162 159 | 
             
                      if options[:clone_type] == :full
         | 
| 163 160 | 
             
                        xml.disks do
         | 
| 164 161 | 
             
                          xml.clone_ true
         | 
| 165 | 
            -
                           | 
| 162 | 
            +
                          disks.each do |disk_object|
         | 
| 166 163 | 
             
                            xml.disk(:id => disk_object.attributes[:id]) do
         | 
| 167 164 | 
             
                              xml.sparse options[:sparse] unless options[:sparse].nil?
         | 
| 168 165 | 
             
                              xml.storage_domains { xml.storage_domain(:id => options[:storage]) } if options[:storage]
         | 
    
        data/lib/ovirt/user.rb
    CHANGED
    
    | @@ -5,7 +5,7 @@ module Ovirt | |
| 5 5 |  | 
| 6 6 | 
             
                def self.parse_node_extended(node, hash)
         | 
| 7 7 | 
             
                  groups_node   = node.xpath('groups').first
         | 
| 8 | 
            -
                  hash[:groups] = groups_node.xpath('group').collect | 
| 8 | 
            +
                  hash[:groups] = groups_node.xpath('group').collect(&:text) unless groups_node.nil?
         | 
| 9 9 | 
             
                end
         | 
| 10 10 | 
             
              end
         | 
| 11 11 | 
             
            end
         | 
    
        data/lib/ovirt/version.rb
    CHANGED
    
    
    
        data/lib/ovirt/vm.rb
    CHANGED
    
    | @@ -49,8 +49,7 @@ module Ovirt | |
| 49 49 | 
             
                end
         | 
| 50 50 |  | 
| 51 51 | 
             
                def destroy
         | 
| 52 | 
            -
                  # TODO:
         | 
| 53 | 
            -
                  # 1. If VM was running, wait for it to stop
         | 
| 52 | 
            +
                  # TODO: If VM was running, wait for it to stop
         | 
| 54 53 | 
             
                  begin
         | 
| 55 54 | 
             
                    stop
         | 
| 56 55 | 
             
                  rescue VmIsNotRunning
         | 
| @@ -75,7 +74,7 @@ module Ovirt | |
| 75 74 | 
             
                  #     <state>pending</state>
         | 
| 76 75 | 
             
                  #   </status>
         | 
| 77 76 | 
             
                  # </action>
         | 
| 78 | 
            -
                  doc | 
| 77 | 
            +
                  doc    = Nokogiri::XML(response)
         | 
| 79 78 | 
             
                  action = doc.xpath("//action").first
         | 
| 80 79 | 
             
                  raise Ovirt::Error, "No Action in Response: #{response.inspect}" if action.nil?
         | 
| 81 80 | 
             
                  action['href']
         | 
| @@ -210,10 +209,8 @@ module Ovirt | |
| 210 209 | 
             
                  attach_payload(payload)
         | 
| 211 210 | 
             
                end
         | 
| 212 211 |  | 
| 213 | 
            -
                def detach_payload_3_3( | 
| 214 | 
            -
                  update! | 
| 215 | 
            -
                    xml.payloads
         | 
| 216 | 
            -
                  end
         | 
| 212 | 
            +
                def detach_payload_3_3(_types)
         | 
| 213 | 
            +
                  update!(&:payloads)
         | 
| 217 214 | 
             
                end
         | 
| 218 215 |  | 
| 219 216 | 
             
                # Attaches the +files+ as a floppy drive payload.
         | 
| @@ -237,8 +234,8 @@ module Ovirt | |
| 237 234 | 
             
                    end
         | 
| 238 235 | 
             
                  end
         | 
| 239 236 | 
             
                rescue Ovirt::Error => err
         | 
| 240 | 
            -
                  raise  | 
| 241 | 
            -
                  raise | 
| 237 | 
            +
                  raise VmNotReadyToBoot, [err.message, err] if err.message =~ /disks .+ are locked/
         | 
| 238 | 
            +
                  raise
         | 
| 242 239 | 
             
                end
         | 
| 243 240 |  | 
| 244 241 | 
             
                def boot_from_cdrom(iso_file_name)
         | 
| @@ -255,8 +252,8 @@ module Ovirt | |
| 255 252 | 
             
                    end
         | 
| 256 253 | 
             
                  end
         | 
| 257 254 | 
             
                rescue Ovirt::Error => err
         | 
| 258 | 
            -
                  raise  | 
| 259 | 
            -
                  raise | 
| 255 | 
            +
                  raise VmNotReadyToBoot, [err.message, err] if err.message =~ /disks .+ are locked/
         | 
| 256 | 
            +
                  raise
         | 
| 260 257 | 
             
                end
         | 
| 261 258 |  | 
| 262 259 | 
             
                def self.parse_xml(xml)
         | 
| @@ -267,7 +264,7 @@ module Ovirt | |
| 267 264 | 
             
                                   :node => [:affinity])
         | 
| 268 265 |  | 
| 269 266 | 
             
                  parse_first_node_with_hash(node, 'placement_policy/host', hash[:placement_policy][:host] = {},
         | 
| 270 | 
            -
             | 
| 267 | 
            +
                                             :attribute => [:id])
         | 
| 271 268 |  | 
| 272 269 | 
             
                  parse_first_node(node, :memory_policy, hash,
         | 
| 273 270 | 
             
                                   :node_to_i => [:guaranteed])
         | 
| @@ -323,12 +320,10 @@ module Ovirt | |
| 323 320 | 
             
                      xml.description desc
         | 
| 324 321 | 
             
                    end
         | 
| 325 322 | 
             
                  end
         | 
| 326 | 
            -
                  data | 
| 327 | 
            -
                  path | 
| 328 | 
            -
             | 
| 323 | 
            +
                  data     = builder.doc.root.to_xml
         | 
| 324 | 
            +
                  path     = "#{api_endpoint}/snapshots"
         | 
| 329 325 | 
             
                  response = @service.resource_post(path, data)
         | 
| 330 | 
            -
             | 
| 331 | 
            -
                  snap = Snapshot.create_from_xml(@service, response)
         | 
| 326 | 
            +
                  snap     = Snapshot.create_from_xml(@service, response)
         | 
| 332 327 |  | 
| 333 328 | 
             
                  while snap[:snapshot_status] == "locked"
         | 
| 334 329 | 
             
                    sleep 2
         | 
| @@ -337,16 +332,16 @@ module Ovirt | |
| 337 332 | 
             
                  snap
         | 
| 338 333 | 
             
                end
         | 
| 339 334 |  | 
| 340 | 
            -
                def create_template(options={})
         | 
| 335 | 
            +
                def create_template(options = {})
         | 
| 341 336 | 
             
                  builder = Nokogiri::XML::Builder.new do |xml|
         | 
| 342 337 | 
             
                    xml.template do
         | 
| 343 338 | 
             
                      xml.name options[:name]
         | 
| 344 339 | 
             
                      xml.vm(:id => self[:id])
         | 
| 345 340 | 
             
                    end
         | 
| 346 341 | 
             
                  end
         | 
| 347 | 
            -
                  data | 
| 348 | 
            -
             | 
| 342 | 
            +
                  data     = builder.doc.root.to_xml
         | 
| 349 343 | 
             
                  response = @service.resource_post(:templates, data)
         | 
| 344 | 
            +
             | 
| 350 345 | 
             
                  Template.create_from_xml(@service, response)
         | 
| 351 346 | 
             
                rescue Ovirt::Error => err
         | 
| 352 347 | 
             
                  raise TemplateAlreadyExists, err.message if err.message.include?("Template name already exists")
         | 
| @@ -359,10 +354,9 @@ module Ovirt | |
| 359 354 | 
             
                  ovirt_cloud_init_keys = %w(active_directory_ou authorized_ssh_keys dns_search dns_servers domain host_name input_locale nic_configurations org_name regenerate_ssh_keys root_password system_locale timezone ui_language user_locale user_name)
         | 
| 360 355 |  | 
| 361 356 | 
             
                  require 'yaml'
         | 
| 362 | 
            -
                  raw_content | 
| 363 | 
            -
             | 
| 364 | 
            -
                   | 
| 365 | 
            -
                  custom_script = YAML.dump(raw_content).to_s.sub("---\n", "")
         | 
| 357 | 
            +
                  raw_content          = YAML.load(content)
         | 
| 358 | 
            +
                  hash                 = ovirt_cloud_init_keys.each_with_object({}) { |k, h| h[k] = raw_content.delete(k) }
         | 
| 359 | 
            +
                  custom_script        = YAML.dump(raw_content).to_s.sub("---\n", "")
         | 
| 366 360 | 
             
                  hash[:custom_script] = custom_script unless custom_script.blank?
         | 
| 367 361 | 
             
                  hash.delete_nils
         | 
| 368 362 | 
             
                end
         | 
    
        data/lib/ovirt.rb
    CHANGED
    
    | @@ -2,6 +2,8 @@ require 'active_support/all' | |
| 2 2 | 
             
            require 'more_core_extensions/all'
         | 
| 3 3 |  | 
| 4 4 | 
             
            require 'ovirt/exception'
         | 
| 5 | 
            +
            require 'ovirt/logging'
         | 
| 6 | 
            +
            require 'ovirt/null_logger'
         | 
| 5 7 | 
             
            require 'ovirt/base'
         | 
| 6 8 | 
             
            require 'ovirt/version'
         | 
| 7 9 |  | 
| @@ -32,3 +34,13 @@ require 'ovirt/template' | |
| 32 34 | 
             
            require 'ovirt/user'
         | 
| 33 35 | 
             
            require 'ovirt/vm'
         | 
| 34 36 | 
             
            require 'ovirt/vmpool'
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            module Ovirt
         | 
| 39 | 
            +
              class << self
         | 
| 40 | 
            +
                attr_writer :logger
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              def self.logger
         | 
| 44 | 
            +
                @logger ||= NullLogger.new
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
            end
         | 
    
        data/spec/base_spec.rb
    CHANGED
    
    | @@ -1,19 +1,17 @@ | |
| 1 | 
            -
            require 'spec_helper'
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            describe Ovirt::Base do
         | 
| 4 2 | 
             
              it ".api_endpoint" do
         | 
| 5 | 
            -
                Ovirt::Base.api_endpoint. | 
| 6 | 
            -
                Ovirt::Template.api_endpoint. | 
| 7 | 
            -
                Ovirt::Cluster.api_endpoint. | 
| 8 | 
            -
                Ovirt::Vm.api_endpoint. | 
| 9 | 
            -
                Ovirt::StorageDomain.api_endpoint. | 
| 10 | 
            -
                Ovirt::DataCenter.api_endpoint. | 
| 3 | 
            +
                expect(Ovirt::Base.api_endpoint).to          eq("bases")
         | 
| 4 | 
            +
                expect(Ovirt::Template.api_endpoint).to      eq("templates")
         | 
| 5 | 
            +
                expect(Ovirt::Cluster.api_endpoint).to       eq("clusters")
         | 
| 6 | 
            +
                expect(Ovirt::Vm.api_endpoint).to            eq("vms")
         | 
| 7 | 
            +
                expect(Ovirt::StorageDomain.api_endpoint).to eq("storagedomains")
         | 
| 8 | 
            +
                expect(Ovirt::DataCenter.api_endpoint).to    eq("datacenters")
         | 
| 11 9 | 
             
              end
         | 
| 12 10 |  | 
| 13 11 | 
             
              it ".href_to_guid" do
         | 
| 14 12 | 
             
                guid = "1c92b67c-9d10-4f48-85bd-28ba2fd6d9b3"
         | 
| 15 13 | 
             
                expect(Ovirt::Base.send(:href_to_guid, "/api/clusters/#{guid}")).to eq(guid)
         | 
| 16 14 | 
             
                expect(Ovirt::Base.send(:href_to_guid, guid)).to                    eq(guid)
         | 
| 17 | 
            -
                expect { Ovirt::Base.send(:href_to_guid,  | 
| 15 | 
            +
                expect { Ovirt::Base.send(:href_to_guid, 12_345) }.to               raise_error(ArgumentError)
         | 
| 18 16 | 
             
              end
         | 
| 19 17 | 
             
            end
         | 
    
        data/spec/event_spec.rb
    CHANGED
    
    | @@ -1,26 +1,16 @@ | |
| 1 | 
            -
            require 'spec_helper'
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            describe Ovirt::Event do
         | 
| 4 2 | 
             
              context ".set_event_name" do
         | 
| 5 | 
            -
                before :each do
         | 
| 6 | 
            -
                  @orig_log, $rhevm_log = $rhevm_log, double("logger")
         | 
| 7 | 
            -
                end
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                after :each do
         | 
| 10 | 
            -
                  $rhevm_log = @orig_log
         | 
| 11 | 
            -
                end
         | 
| 12 | 
            -
             | 
| 13 3 | 
             
                it "sets the name corresponding to a valid code" do
         | 
| 14 4 | 
             
                  hash = {:code => 1}
         | 
| 15 5 | 
             
                  described_class.send(:set_event_name, hash)
         | 
| 16 | 
            -
                  hash[:name]. | 
| 6 | 
            +
                  expect(hash[:name]).to eq(Ovirt::Event::EVENT_CODES[1])
         | 
| 17 7 | 
             
                end
         | 
| 18 8 |  | 
| 19 9 | 
             
                it "sets 'UNKNOWN' as the name with an invalid code" do
         | 
| 20 | 
            -
                   | 
| 10 | 
            +
                  expect(Ovirt.logger).to receive(:warn).with("Ovirt::Event.set_event_name Unknown RHEVM event -1: Invalid Code")
         | 
| 21 11 | 
             
                  hash = {:code => -1, :description => "Invalid Code"}
         | 
| 22 12 | 
             
                  described_class.send(:set_event_name, hash)
         | 
| 23 | 
            -
                  hash[:name]. | 
| 13 | 
            +
                  expect(hash[:name]).to eq("UNKNOWN")
         | 
| 24 14 | 
             
                end
         | 
| 25 15 | 
             
              end
         | 
| 26 16 | 
             
            end
         |