rbovirt 0.1.0 → 0.1.1
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/CHANGES.rdoc +22 -0
- data/lib/client/host_api.rb +10 -4
- data/lib/client/instance_type_api.rb +20 -0
- data/lib/client/operating_system_api.rb +10 -0
- data/lib/client/vm_api.rb +29 -1
- data/lib/ovirt/instance_type.rb +73 -0
- data/lib/ovirt/operating_system.rb +11 -0
- data/lib/ovirt/template.rb +5 -4
- data/lib/ovirt/template_version.rb +2 -2
- data/lib/ovirt/version.rb +1 -1
- data/lib/ovirt/vm.rb +73 -21
- data/lib/rbovirt.rb +42 -25
- data/spec/integration/api_spec.rb +41 -0
- data/spec/integration/instance_type_spec.rb +16 -0
- data/spec/integration/vm_crud_spec.rb +124 -0
- data/spec/unit/vm_spec.rb +44 -0
- metadata +11 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 58cb5fab7fdfa1f4dce04d45532618c7415c8be5
         | 
| 4 | 
            +
              data.tar.gz: ad23cc3fa62db7186b4bf14ae198f5d7e95c74bb
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 22b5ba8ada4d36d8ece11c9be5520188385c6978c80bdee0640b5fe898b559af46a6dd450d4e0b4195e36e3603d027722dc0197fff191c47e01cf789b3d6dde8
         | 
| 7 | 
            +
              data.tar.gz: 47ba3a1763257b788c3bba4eb5596be1dbed85e36345f4f6a4c7ffaaca9cf97cd96024412020fbcb620f95412c1dd3e85f77e210a0e531f9115645d9c87e0c95
         | 
    
        data/CHANGES.rdoc
    CHANGED
    
    | @@ -6,6 +6,28 @@ _rbovirt_ project. | |
| 6 6 | 
             
            Note that this list of changes was added with the 0.0.30 release,
         | 
| 7 7 | 
             
            previous releases aren't described here.
         | 
| 8 8 |  | 
| 9 | 
            +
            == 0.1.1
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            New features:
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            * Support operating systems
         | 
| 14 | 
            +
            * Added missing brackets for template display
         | 
| 15 | 
            +
            * Support for using the persistent-auth
         | 
| 16 | 
            +
            * Add instance types support.
         | 
| 17 | 
            +
            * Fixes Blank template display
         | 
| 18 | 
            +
            * Added support for VMS search options max/pages
         | 
| 19 | 
            +
            * Handle template's disk
         | 
| 20 | 
            +
            * Fix cloud init for OVirt >= 3.5
         | 
| 21 | 
            +
            * Set storage domain for template when provided.
         | 
| 22 | 
            +
            * Include disks in VM XML.
         | 
| 23 | 
            +
            * Make comment of vm or template editable
         | 
| 24 | 
            +
            * Adding override_iptables parameter to reinstall_host
         | 
| 25 | 
            +
            * Implement stricter checks of nicsdef content
         | 
| 26 | 
            +
            * Implement cloud-init for multiple nics
         | 
| 27 | 
            +
            * Fix broken OVIRT::Template#volumes
         | 
| 28 | 
            +
            * Fix for cloudinit so nokogiri correctly processes the files section
         | 
| 29 | 
            +
            * Add option to set description on VM create.
         | 
| 30 | 
            +
             | 
| 9 31 | 
             
            == 0.1.0 / 2015-05-07
         | 
| 10 32 |  | 
| 11 33 | 
             
            New features:
         | 
    
        data/lib/client/host_api.rb
    CHANGED
    
    | @@ -17,11 +17,17 @@ module OVIRT | |
| 17 17 | 
             
                    http_post("/hosts/%s/approve" % host_id, "<action></action>")
         | 
| 18 18 | 
             
                end
         | 
| 19 19 |  | 
| 20 | 
            -
                def reinstall_host(host_id, opts={})
         | 
| 20 | 
            +
                def reinstall_host(host_id, override_iptables=False, opts={})
         | 
| 21 21 | 
             
                    http_post("/hosts/%s/install" % host_id,
         | 
| 22 | 
            -
                              "<action | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 22 | 
            +
                              "<action>
         | 
| 23 | 
            +
                                <ssh>
         | 
| 24 | 
            +
                                 <authentication_method>PublicKey</authentication_method>
         | 
| 25 | 
            +
                                </ssh>
         | 
| 26 | 
            +
                                <host>
         | 
| 27 | 
            +
                                 <override_iptables>" + override_iptables + "</override_iptables>
         | 
| 28 | 
            +
                                </host>
         | 
| 29 | 
            +
                               </action>"
         | 
| 30 | 
            +
                             )
         | 
| 25 31 | 
             
                end
         | 
| 26 32 | 
             
              end
         | 
| 27 33 | 
             
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            module OVIRT
         | 
| 2 | 
            +
              class Client
         | 
| 3 | 
            +
                def instance_type(instance_type_id)
         | 
| 4 | 
            +
                    begin
         | 
| 5 | 
            +
                      instance_type = http_get("/instancetypes/%s" % instance_type_id)
         | 
| 6 | 
            +
                      OVIRT::InstanceType::new(self, instance_type.root)
         | 
| 7 | 
            +
                    rescue
         | 
| 8 | 
            +
                      handle_fault $!
         | 
| 9 | 
            +
                    end
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  def instance_types(opts={})
         | 
| 13 | 
            +
                    search = opts[:search] ||""
         | 
| 14 | 
            +
                    instance_types = http_get("/instancetypes?search=%s" % CGI.escape(search))
         | 
| 15 | 
            +
                    instance_types.xpath('/instance_types/instance_type').collect do |it|
         | 
| 16 | 
            +
                      OVIRT::InstanceType::new(self, it)
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
    
        data/lib/client/vm_api.rb
    CHANGED
    
    | @@ -6,7 +6,11 @@ module OVIRT | |
| 6 6 | 
             
                end
         | 
| 7 7 |  | 
| 8 8 | 
             
                def vms(opts={})
         | 
| 9 | 
            -
                   | 
| 9 | 
            +
                  if opts[:without_details]
         | 
| 10 | 
            +
                    headers = {:accept => "application/xml"}
         | 
| 11 | 
            +
                  else
         | 
| 12 | 
            +
                    headers = {:accept => "application/xml; detail=disks; detail=nics; detail=hosts"}
         | 
| 13 | 
            +
                  end
         | 
| 10 14 | 
             
                  path = "/vms"
         | 
| 11 15 | 
             
                  path += search_url(opts) unless filtered_api
         | 
| 12 16 | 
             
                  http_get(path, headers).xpath('/vms/vm').collect do |vm|
         | 
| @@ -14,6 +18,21 @@ module OVIRT | |
| 14 18 | 
             
                  end
         | 
| 15 19 | 
             
                end
         | 
| 16 20 |  | 
| 21 | 
            +
                def process_vm_opts(opts)
         | 
| 22 | 
            +
                  if (opts[:template] or opts[:template_name]) and (opts[:storagedomain] or opts[:storagedomain_name])
         | 
| 23 | 
            +
                    template_id = opts[:template] || templates.select{|t| t.name == opts[:template_name]}.first.id
         | 
| 24 | 
            +
                    template_disks = template_volumes(template_id)
         | 
| 25 | 
            +
                    storagedomain_id = opts[:storagedomain] || storagedomains.select{|s| s.name == opts[:storagedomain_name]}.first.id
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    # Make sure the 'clone' option is set if any of the disks defined by
         | 
| 28 | 
            +
                    # the template is stored on a different storage domain than requested
         | 
| 29 | 
            +
                    opts[:clone] = true unless opts[:clone] == true || template_disks.empty? || template_disks.all? { |d| d.storage_domain == storagedomain_id }
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    # Create disks map
         | 
| 32 | 
            +
                    opts[:disks] = template_disks.collect { |d| {:id => d.id, :storagedomain => storagedomain_id} }
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 17 36 | 
             
                def create_vm(opts)
         | 
| 18 37 | 
             
                  cluster_major_ver, cluster_minor_ver = cluster_version(self.cluster_id)
         | 
| 19 38 |  | 
| @@ -32,6 +51,9 @@ module OVIRT | |
| 32 51 | 
             
                      raise BackendVersionUnsupportedException.new
         | 
| 33 52 | 
             
                    end
         | 
| 34 53 | 
             
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  process_vm_opts(opts)
         | 
| 56 | 
            +
             | 
| 35 57 | 
             
                  opts[:cluster_name] ||= clusters.first.name unless opts[:cluster]
         | 
| 36 58 | 
             
                  OVIRT::VM::new(self, http_post("/vms",OVIRT::VM.to_xml(opts)).root)
         | 
| 37 59 | 
             
                end
         | 
| @@ -122,6 +144,12 @@ module OVIRT | |
| 122 144 | 
             
                end
         | 
| 123 145 |  | 
| 124 146 | 
             
                def vm_start_with_cloudinit(id, opts={})
         | 
| 147 | 
            +
                  # Get the api and cluster version on which the VM is provisioned.
         | 
| 148 | 
            +
                  # This is required for VM::cloudinit.
         | 
| 149 | 
            +
                  opts.merge!(
         | 
| 150 | 
            +
                    :cluster_version => cluster_version(vm(id).cluster.id),
         | 
| 151 | 
            +
                    :api_version => api_version.split('.').map(&:to_i)
         | 
| 152 | 
            +
                  )
         | 
| 125 153 | 
             
                  xml = OVIRT::VM.cloudinit(opts)
         | 
| 126 154 | 
             
                  xml_response = http_post("/vms/%s/%s" % [id, 'start'], xml, {} )
         | 
| 127 155 | 
             
                  return (xml_response/'action/status').first.text.strip.upcase=="COMPLETE"
         | 
| @@ -0,0 +1,73 @@ | |
| 1 | 
            +
            module OVIRT
         | 
| 2 | 
            +
              # Instance types are added to oVirt 3.5 and have been updated in oVirt 3.6
         | 
| 3 | 
            +
              class InstanceType < BaseObject
         | 
| 4 | 
            +
                # Common attributes to all oVirt version supported at this time
         | 
| 5 | 
            +
                attr_reader :name, :description, :memory, :cores, :os, :creation_time
         | 
| 6 | 
            +
                attr_reader :ha, :ha_priority, :display, :usb, :migration_downtime
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                # oVirt 3.5 attributes
         | 
| 9 | 
            +
                attr_reader :type, :status, :cpu_shares, :boot_menu, :origin, :stateless
         | 
| 10 | 
            +
                attr_reader :delete_protected, :sso, :timezone
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                # oVirt 3.6 attributes
         | 
| 13 | 
            +
                attr_reader :migration, :io_threads, :memory_guaranteed
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def initialize(client, xml)
         | 
| 16 | 
            +
                  super(client, xml[:id], xml[:href], (xml/'name').first.text)
         | 
| 17 | 
            +
                  parse_xml_attributes!(xml)
         | 
| 18 | 
            +
                  self
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                private
         | 
| 22 | 
            +
                def parse_xml_attributes!(xml)
         | 
| 23 | 
            +
                  # Common attributes
         | 
| 24 | 
            +
                  @description = ((xml/'description').first.text rescue '')
         | 
| 25 | 
            +
                  @memory = (xml/'memory').first.text
         | 
| 26 | 
            +
                  @cores = ((xml/'cpu/topology').first[:cores].to_i * (xml/'cpu/topology').first[:sockets].to_i rescue nil)
         | 
| 27 | 
            +
                  @os = {
         | 
| 28 | 
            +
                      :type => (xml/'os').first[:type],
         | 
| 29 | 
            +
                      :boot => (xml/'os/boot').collect {|boot| boot[:dev] }
         | 
| 30 | 
            +
                  }
         | 
| 31 | 
            +
                  @creation_time = (xml/'creation_time').text
         | 
| 32 | 
            +
                  @ha = parse_bool((xml/'high_availability/enabled').first.text)
         | 
| 33 | 
            +
                  @ha_priority = ((xml/'high_availability/priority').first.text rescue nil)
         | 
| 34 | 
            +
                  @display = {
         | 
| 35 | 
            +
                    :type => (xml/'display/type').first.text,
         | 
| 36 | 
            +
                    :monitors => (xml/'display/monitors').first.text,
         | 
| 37 | 
            +
                    :single_qxl_pci => parse_bool((xml/'display/single_qxl_pci').first.text),
         | 
| 38 | 
            +
                    :smartcard_enabled => parse_bool((xml/'display/smartcard_enabled').first.text),
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  }
         | 
| 41 | 
            +
                  @usb = parse_bool((xml/'usb/enabled').first.text)
         | 
| 42 | 
            +
                  @migration_downtime = ((xml/'migration_downtime').first.text)
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  # oVirt 3.5 attributes
         | 
| 45 | 
            +
                  @type = ((xml/'type').first.text rescue nil)
         | 
| 46 | 
            +
                  @status = ((xml/'status').first.text rescue nil)
         | 
| 47 | 
            +
                  @cpu_shares = (((xml/'cpu_shares').first.text) rescue nil)
         | 
| 48 | 
            +
                  potential_bool = ((xml/'bios/boot_menu/enabled').first.text rescue nil)
         | 
| 49 | 
            +
                  @boot_menu = potential_bool.nil? ? nil : parse_bool(potential_bool)
         | 
| 50 | 
            +
                  @origin = ((xml/'origin').text rescue nil)
         | 
| 51 | 
            +
                  potential_bool = ((xml/'stateless').first.text rescue nil)
         | 
| 52 | 
            +
                  @stateless = potential_bool.nil? ? nil : parse_bool(potential_bool)
         | 
| 53 | 
            +
                  potential_bool = ((xml/'delete_protected').first.text rescue nil)
         | 
| 54 | 
            +
                  @delete_protected = potential_bool.nil? ? nil : parse_bool(potential_bool)
         | 
| 55 | 
            +
                  #@sso = ((xml/'sso/methods').first.text rescue nil)
         | 
| 56 | 
            +
                  @timezone = ((xml/'timezone').first.text rescue nil)
         | 
| 57 | 
            +
                  potential_bool = ((xml/'display/allow_override').first.text rescue nil)
         | 
| 58 | 
            +
                  @display[:allow_override] = potential_bool.nil? ? nil : parse_bool(potential_bool)
         | 
| 59 | 
            +
                  potential_bool = ((xml/'display/file_transfer_enabled').first.text rescue nil)
         | 
| 60 | 
            +
                  @display[:file_transfer_enabled] = potential_bool.nil? ? nil : parse_bool(potential_bool)
         | 
| 61 | 
            +
                  potential_bool = ((xml/'display/copy_paste_enabled').first.text rescue nil)
         | 
| 62 | 
            +
                  @display[:copy_paste_enabled] = potential_bool.nil? ? nil : parse_bool(potential_bool)
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  # oVirt 3.6 attributes
         | 
| 65 | 
            +
                  @migration = {
         | 
| 66 | 
            +
                    :auto_converge => ((xml/'migration/auto_converge').first.text rescue nil),
         | 
| 67 | 
            +
                    :compressed => ((xml/'migration/compressed').first.text rescue nil)
         | 
| 68 | 
            +
                  }
         | 
| 69 | 
            +
                  @io_threads = ((xml/'io/threads').first.text rescue nil)
         | 
| 70 | 
            +
                  @memory_guaranteed = ((xml/'memory_policy/guaranteed').first.text rescue nil)
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
            end
         | 
    
        data/lib/ovirt/template.rb
    CHANGED
    
    | @@ -1,6 +1,7 @@ | |
| 1 1 | 
             
            module OVIRT
         | 
| 2 2 | 
             
              class Template < BaseObject
         | 
| 3 | 
            -
                attr_reader :description, : | 
| 3 | 
            +
                attr_reader :description, :status, :cluster, :creation_time, :os, :storage, :display, :profile, :memory, :version
         | 
| 4 | 
            +
                attr_accessor :comment
         | 
| 4 5 |  | 
| 5 6 | 
             
                def initialize(client, xml)
         | 
| 6 7 | 
             
                  super(client, xml[:id], xml[:href], (xml/'name').first.text)
         | 
| @@ -25,7 +26,7 @@ module OVIRT | |
| 25 26 | 
             
                end
         | 
| 26 27 |  | 
| 27 28 | 
             
                def volumes
         | 
| 28 | 
            -
                  @volumes ||= @client. | 
| 29 | 
            +
                  @volumes ||= @client.template_volumes(id)
         | 
| 29 30 | 
             
                end
         | 
| 30 31 |  | 
| 31 32 | 
             
                private
         | 
| @@ -38,8 +39,8 @@ module OVIRT | |
| 38 39 | 
             
                  @profile = (xml/'type').first.text
         | 
| 39 40 | 
             
                  @cluster = Link::new(@client, (xml/'cluster').first[:id], (xml/'cluster').first[:href])
         | 
| 40 41 | 
             
                  @display = {
         | 
| 41 | 
            -
                    :type => (xml/'display/type').first.text,
         | 
| 42 | 
            -
                    :monitors => (xml/'display/monitors').first.text
         | 
| 42 | 
            +
                    :type => ((xml/'display/type').first.text rescue ''),
         | 
| 43 | 
            +
                    :monitors => ((xml/'display/monitors').first.text rescue 0)
         | 
| 43 44 | 
             
                  }
         | 
| 44 45 | 
             
                  @cores = ((xml/'cpu/topology').first[:cores].to_i * (xml/'cpu/topology').first[:sockets].to_i rescue nil)
         | 
| 45 46 | 
             
                  @storage = ((xml/'disks/disk/size').first.text rescue nil)
         | 
| @@ -8,7 +8,7 @@ module OVIRT | |
| 8 8 | 
             
                def parse_xml_attributes(xml)
         | 
| 9 9 | 
             
                  @base_template = (xml/"base_template").first[:id]
         | 
| 10 10 | 
             
                  @version_number = (xml/"version_number").first.text
         | 
| 11 | 
            -
                  @version_name = (xml/"version_name").first.text
         | 
| 11 | 
            +
                  @version_name = ((xml/"version_name").first.text rescue nil)
         | 
| 12 12 | 
             
                end
         | 
| 13 13 | 
             
              end
         | 
| 14 | 
            -
            end
         | 
| 14 | 
            +
            end
         | 
    
        data/lib/ovirt/version.rb
    CHANGED
    
    
    
        data/lib/ovirt/vm.rb
    CHANGED
    
    | @@ -4,9 +4,9 @@ module OVIRT | |
| 4 4 | 
             
                FILEINJECT_PATH = "user-data.txt"
         | 
| 5 5 |  | 
| 6 6 | 
             
              class VM < BaseObject
         | 
| 7 | 
            -
                attr_reader :description, : | 
| 7 | 
            +
                attr_reader :description, :status, :memory, :profile, :display, :host, :cluster, :template
         | 
| 8 8 | 
             
                attr_reader :storage, :cores, :creation_time, :os, :ha, :ha_priority, :ips, :vnc, :quota, :clone
         | 
| 9 | 
            -
                attr_accessor :interfaces, :volumes
         | 
| 9 | 
            +
                attr_accessor :comment, :interfaces, :volumes
         | 
| 10 10 |  | 
| 11 11 | 
             
                def initialize(client, xml)
         | 
| 12 12 | 
             
                  super(client, xml[:id], xml[:href], (xml/'name').first.text)
         | 
| @@ -50,6 +50,7 @@ module OVIRT | |
| 50 50 | 
             
                  builder = Nokogiri::XML::Builder.new do
         | 
| 51 51 | 
             
                    vm{
         | 
| 52 52 | 
             
                      name_ opts[:name] || "i-#{Time.now.to_i}"
         | 
| 53 | 
            +
                      description_ opts[:description] || ""
         | 
| 53 54 | 
             
                      if opts[:comment]
         | 
| 54 55 | 
             
                        comment_ opts[:comment]
         | 
| 55 56 | 
             
                      end
         | 
| @@ -79,18 +80,23 @@ module OVIRT | |
| 79 80 | 
             
                      end
         | 
| 80 81 | 
             
                      # os element must not be sent when template is present (RHBZ 1104235)
         | 
| 81 82 | 
             
                      if opts[:template].nil? || opts[:template].empty?
         | 
| 82 | 
            -
                        os | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 83 | 
            +
                        os_opts = opts[:os] ? opts[:os].dup : {}
         | 
| 84 | 
            +
                        os_opts[:type] ||= opts[:os_type] || 'unassigned'
         | 
| 85 | 
            +
                        os_opts[:boot] ||= [opts.fetch(:boot_dev1, 'network'), opts.fetch(:boot_dev2, 'hd')]
         | 
| 86 | 
            +
                        os_opts[:kernel] ||= opts[:os_kernel]
         | 
| 87 | 
            +
                        os_opts[:initrd] ||= opts[:os_initrd]
         | 
| 88 | 
            +
                        os_opts[:cmdline] ||= opts[:os_cmdline]
         | 
| 89 | 
            +
                        if opts[:first_boot_dev]
         | 
| 90 | 
            +
                          os_opts[:boot] = os_opts[:boot].sort_by.with_index do |device, index|
         | 
| 91 | 
            +
                            device == opts[:first_boot_dev] ? -1 : index
         | 
| 89 92 | 
             
                          end
         | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 92 | 
            -
                           | 
| 93 | 
            -
             | 
| 93 | 
            +
                        end
         | 
| 94 | 
            +
                        os(:type => os_opts[:type]) do
         | 
| 95 | 
            +
                          os_opts[:boot].each { |device| boot(:dev => device) }
         | 
| 96 | 
            +
                          kernel os_opts[:kernel]
         | 
| 97 | 
            +
                          initrd os_opts[:initrd]
         | 
| 98 | 
            +
                          cmdline os_opts[:cmdline]
         | 
| 99 | 
            +
                        end
         | 
| 94 100 | 
             
                      end
         | 
| 95 101 | 
             
                      if !opts[:ha].nil? || !opts[:ha_priority].nil?
         | 
| 96 102 | 
             
                        high_availability_{
         | 
| @@ -98,7 +104,16 @@ module OVIRT | |
| 98 104 | 
             
                          priority_(opts[:ha_priority]) unless opts[:ha_priority].nil?
         | 
| 99 105 | 
             
                        }
         | 
| 100 106 | 
             
                      end
         | 
| 101 | 
            -
                      disks_ { | 
| 107 | 
            +
                      disks_ {
         | 
| 108 | 
            +
                        clone_(opts[:clone]) if opts[:clone]
         | 
| 109 | 
            +
                        if opts[:disks]
         | 
| 110 | 
            +
                          opts[:disks].each do |d|
         | 
| 111 | 
            +
                            disk(:id => d[:id]) {
         | 
| 112 | 
            +
                              storage_domains { storage_domain(:id => d[:storagedomain]) }
         | 
| 113 | 
            +
                            }
         | 
| 114 | 
            +
                          end
         | 
| 115 | 
            +
                        end
         | 
| 116 | 
            +
                      }
         | 
| 102 117 | 
             
                      display_{
         | 
| 103 118 | 
             
                        type_(opts[:display][:type])
         | 
| 104 119 | 
             
                      } if opts[:display]
         | 
| @@ -136,11 +151,14 @@ module OVIRT | |
| 136 151 | 
             
                  gateway             = opts[:gateway]
         | 
| 137 152 | 
             
                  domain              = opts[:domain]
         | 
| 138 153 | 
             
                  nicname             = opts[:nicname]
         | 
| 154 | 
            +
                  nicsdef             = opts[:nicsdef]
         | 
| 139 155 | 
             
                  user                = opts[:user] || 'root'
         | 
| 140 156 | 
             
                  password            = opts[:password]
         | 
| 141 157 | 
             
                  ssh_authorized_keys = opts[:ssh_authorized_keys]
         | 
| 142 158 | 
             
                  fileslist           = opts[:files]
         | 
| 143 159 | 
             
                  runcmd              = opts[:runcmd]
         | 
| 160 | 
            +
                  cluster_major, cluster_minor = opts[:cluster_version]
         | 
| 161 | 
            +
                  api_major,api_minor, api_build, api_revision = opts[:api_version]
         | 
| 144 162 | 
             
                  extracmd            = nil 
         | 
| 145 163 | 
             
                  unless opts[:phone_home].nil?
         | 
| 146 164 | 
             
                    phone_home = \
         | 
| @@ -164,6 +182,23 @@ module OVIRT | |
| 164 182 | 
             
                  end
         | 
| 165 183 | 
             
                  builder   = Nokogiri::XML::Builder.new do
         | 
| 166 184 | 
             
                    action {
         | 
| 185 | 
            +
                      # An API has changed in version 3.5.5. Make sure
         | 
| 186 | 
            +
                      # <use_cloud_init>true</use_cloud_init> is used only if the endpoint
         | 
| 187 | 
            +
                      # if of that version or higher and the cluster the VM is provisioned
         | 
| 188 | 
            +
                      # to is of version 3.5 or higher.
         | 
| 189 | 
            +
                      # NOTE: RHEV-m/OVirt versions prior to 3.6.0 contain a bug
         | 
| 190 | 
            +
                      # (https://bugzilla.redhat.com/show_bug.cgi?id=1206068) which causes
         | 
| 191 | 
            +
                      # that build and revision parameters ov API version are set to 0.
         | 
| 192 | 
            +
                      # This may have an impact on conditional inclusion of <use_cloud_init>
         | 
| 193 | 
            +
                      # and thus leaving the guest unconfigured.
         | 
| 194 | 
            +
                      # You can either upgrade to RHEV-m/OVirt 3.6+ or work this around by
         | 
| 195 | 
            +
                      # manually forcing the ovirt engine to report an appropriate version:
         | 
| 196 | 
            +
                      # % rhevm-config -s VdcVersion=<major>.<minor>.<build>.<revision>
         | 
| 197 | 
            +
                      # % service ovirt-engine restart
         | 
| 198 | 
            +
                      # Please replace the placeholders with appropriate values. 
         | 
| 199 | 
            +
                      if api_major > 3 || (api_major == 3 && api_minor > 5) || (api_major == 3 && api_minor == 5 && api_build >= 5)
         | 
| 200 | 
            +
                        use_cloud_init true if cluster_major > 3 || (cluster_major == 3 && cluster_minor >= 5)
         | 
| 201 | 
            +
                      end
         | 
| 167 202 | 
             
                      vm {
         | 
| 168 203 | 
             
                        initialization {
         | 
| 169 204 | 
             
                          unless runcmd.nil?
         | 
| @@ -194,18 +229,35 @@ module OVIRT | |
| 194 229 | 
             
                                }
         | 
| 195 230 | 
             
                              }
         | 
| 196 231 | 
             
                            end
         | 
| 197 | 
            -
                            network_configuration { | 
| 198 | 
            -
                               | 
| 232 | 
            +
                            network_configuration {
         | 
| 233 | 
            +
                              if !nicname.nil?
         | 
| 199 234 | 
             
                                nics {
         | 
| 200 235 | 
             
                                  nic {
         | 
| 201 | 
            -
             | 
| 236 | 
            +
                                    name_ nicname
         | 
| 202 237 | 
             
                                    unless ip.nil? || netmask.nil? || gateway.nil?
         | 
| 203 238 | 
             
                                      network { ip(:'address'=> ip , :'netmask'=> netmask, :'gateway'=> gateway ) }
         | 
| 204 239 | 
             
                                      boot_protocol 'STATIC'
         | 
| 205 240 | 
             
                                      on_boot 'true'
         | 
| 206 241 | 
             
                                    end 
         | 
| 207 242 | 
             
                                  }
         | 
| 208 | 
            -
                                } | 
| 243 | 
            +
                                }
         | 
| 244 | 
            +
                              elsif nicsdef.is_a?(Array) && !nicsdef.empty? && nicsdef.all? { |n| n.is_a?(Hash) }
         | 
| 245 | 
            +
                                nics {
         | 
| 246 | 
            +
                                  nicsdef.each do |n|
         | 
| 247 | 
            +
                                    nic {
         | 
| 248 | 
            +
                                      name_(n[:nicname])
         | 
| 249 | 
            +
                                      boot_protocol_(n[:boot_protocol] || 'NONE') # Defaults to NONE boot proto
         | 
| 250 | 
            +
                                      on_boot_(n[:on_boot] || 'true') # Defaults to 'true'
         | 
| 251 | 
            +
                                      unless n[:ip].nil? || n[:netmask].nil?
         | 
| 252 | 
            +
                                        network_ {
         | 
| 253 | 
            +
                                          n[:gateway].nil? ?
         | 
| 254 | 
            +
                                          ip_(:address => n[:ip], :netmask => n[:netmask]) :
         | 
| 255 | 
            +
                                          ip_(:address => n[:ip], :netmask => n[:netmask], :gateway => n[:gateway])
         | 
| 256 | 
            +
                                        }
         | 
| 257 | 
            +
                                      end
         | 
| 258 | 
            +
                                    }
         | 
| 259 | 
            +
                                  end
         | 
| 260 | 
            +
                                }
         | 
| 209 261 | 
             
                              end
         | 
| 210 262 | 
             
                              dns { 
         | 
| 211 263 | 
             
                                unless dns.nil? 
         | 
| @@ -223,7 +275,7 @@ module OVIRT | |
| 223 275 | 
             
                          regenerate_ssh_keys 'true'
         | 
| 224 276 | 
             
                          files {
         | 
| 225 277 | 
             
                            unless extracmd.nil?
         | 
| 226 | 
            -
                               | 
| 278 | 
            +
                              file_ {
         | 
| 227 279 | 
             
                                name_   'ignored'
         | 
| 228 280 | 
             
                                content extracmd
         | 
| 229 281 | 
             
                                type    'PLAINTEXT'
         | 
| @@ -259,12 +311,12 @@ module OVIRT | |
| 259 311 | 
             
                  @host = Link::new(@client, (xml/'host').first[:id], (xml/'host').first[:href]) rescue nil
         | 
| 260 312 | 
             
                  @cluster = Link::new(@client, (xml/'cluster').first[:id], (xml/'cluster').first[:href])
         | 
| 261 313 | 
             
                  @display = {
         | 
| 262 | 
            -
                    :type => (xml/'display/type').first.text,
         | 
| 314 | 
            +
                    :type => ((xml/'display/type').first.text rescue ''),
         | 
| 263 315 | 
             
                    :address => ((xml/'display/address').first.text rescue nil),
         | 
| 264 316 | 
             
                    :port => ((xml/'display/port').first.text rescue nil),
         | 
| 265 317 | 
             
                    :secure_port => ((xml/'display/secure_port').first.text rescue nil),
         | 
| 266 318 | 
             
                    :subject => ((xml/'display/certificate/subject').first.text rescue nil),
         | 
| 267 | 
            -
                    :monitors => (xml/'display/monitors').first.text
         | 
| 319 | 
            +
                    :monitors => ((xml/'display/monitors').first.text rescue 0)
         | 
| 268 320 | 
             
                  }
         | 
| 269 321 | 
             
                  @cores = ((xml/'cpu/topology').first[:cores].to_i * (xml/'cpu/topology').first[:sockets].to_i rescue nil)
         | 
| 270 322 | 
             
                  @storage = ((xml/'disks/disk/size').first.text rescue nil)
         | 
    
        data/lib/rbovirt.rb
    CHANGED
    
    | @@ -12,7 +12,9 @@ require "ovirt/interface" | |
| 12 12 | 
             
            require "ovirt/network"
         | 
| 13 13 | 
             
            require "ovirt/quota"
         | 
| 14 14 | 
             
            require "ovirt/affinity_group"
         | 
| 15 | 
            +
            require "ovirt/instance_type"
         | 
| 15 16 | 
             
            require "ovirt/version"
         | 
| 17 | 
            +
            require "ovirt/operating_system"
         | 
| 16 18 |  | 
| 17 19 | 
             
            require "client/vm_api"
         | 
| 18 20 | 
             
            require "client/template_api"
         | 
| @@ -24,6 +26,8 @@ require "client/quota_api" | |
| 24 26 | 
             
            require "client/disk_api"
         | 
| 25 27 | 
             
            require "client/affinity_group_api"
         | 
| 26 28 | 
             
            require "client/disk_profile_api"
         | 
| 29 | 
            +
            require "client/instance_type_api"
         | 
| 30 | 
            +
            require "client/operating_system_api"
         | 
| 27 31 |  | 
| 28 32 | 
             
            require "nokogiri"
         | 
| 29 33 | 
             
            require "rest_client"
         | 
| @@ -45,7 +49,7 @@ module OVIRT | |
| 45 49 |  | 
| 46 50 | 
             
              class Client
         | 
| 47 51 |  | 
| 48 | 
            -
                attr_reader :credentials, :api_entrypoint, :datacenter_id, :cluster_id, :filtered_api, :ca_cert_file, :ca_cert_store, :ca_no_verify
         | 
| 52 | 
            +
                attr_reader :credentials, :api_entrypoint, :datacenter_id, :cluster_id, :filtered_api, :ca_cert_file, :ca_cert_store, :ca_no_verify, :persistent_auth, :jsessionid
         | 
| 49 53 |  | 
| 50 54 | 
             
                # Construct a new ovirt client class.
         | 
| 51 55 | 
             
                # mandatory parameters
         | 
| @@ -67,20 +71,26 @@ module OVIRT | |
| 67 71 | 
             
                               :cluster_id => backward_compatibility_cluster,
         | 
| 68 72 | 
             
                               :filtered_api => backward_compatibility_filtered}
         | 
| 69 73 | 
             
                  end
         | 
| 70 | 
            -
                  @api_entrypoint | 
| 71 | 
            -
                  @credentials | 
| 72 | 
            -
                  @datacenter_id | 
| 73 | 
            -
                  @cluster_id | 
| 74 | 
            -
                  @filtered_api | 
| 75 | 
            -
                  @ca_cert_file | 
| 76 | 
            -
                  @ca_cert_store | 
| 77 | 
            -
                  @ca_no_verify | 
| 74 | 
            +
                  @api_entrypoint  = api_entrypoint
         | 
| 75 | 
            +
                  @credentials     = { :username => username, :password => password }
         | 
| 76 | 
            +
                  @datacenter_id   = options[:datacenter_id]
         | 
| 77 | 
            +
                  @cluster_id      = options[:cluster_id]
         | 
| 78 | 
            +
                  @filtered_api    = options[:filtered_api]
         | 
| 79 | 
            +
                  @ca_cert_file    = options[:ca_cert_file]
         | 
| 80 | 
            +
                  @ca_cert_store   = options[:ca_cert_store]
         | 
| 81 | 
            +
                  @ca_no_verify    = options[:ca_no_verify]
         | 
| 82 | 
            +
                  @persistent_auth = options[:persistent_auth]
         | 
| 83 | 
            +
                  @jsessionid      = options[:jsessionid]
         | 
| 78 84 | 
             
                end
         | 
| 79 85 |  | 
| 80 86 | 
             
                def api_version
         | 
| 81 87 | 
             
                  return @api_version unless @api_version.nil?
         | 
| 82 88 | 
             
                  xml = http_get("/")/'/api/product_info/version'
         | 
| 83 | 
            -
                   | 
| 89 | 
            +
                  major = (xml/'version').first[:major]
         | 
| 90 | 
            +
                  minor = (xml/'version').first[:minor]
         | 
| 91 | 
            +
                  build = (xml/'version').first[:build]
         | 
| 92 | 
            +
                  revision = (xml/'version').first[:revision]
         | 
| 93 | 
            +
                  @api_version = "#{major}.#{minor}.#{build}.#{revision}"
         | 
| 84 94 | 
             
                end
         | 
| 85 95 |  | 
| 86 96 | 
             
                def api_version?(major, minor=nil)
         | 
| @@ -93,9 +103,13 @@ module OVIRT | |
| 93 103 | 
             
                end
         | 
| 94 104 |  | 
| 95 105 | 
             
                private
         | 
| 106 | 
            +
             | 
| 96 107 | 
             
                def search_url opts
         | 
| 97 | 
            -
                  search = opts[:search] ||  | 
| 98 | 
            -
                  " | 
| 108 | 
            +
                  search = opts[:search] || ''
         | 
| 109 | 
            +
                  search += " datacenter=\"%s\"" % current_datacenter.name
         | 
| 110 | 
            +
                  search += " page #{opts[:page]}" if opts[:page]
         | 
| 111 | 
            +
                  max = opts[:max] ? ";max=#{opts[:max]}" : ''
         | 
| 112 | 
            +
                  "#{max}?search=#{CGI.escape(search)}"
         | 
| 99 113 | 
             
                end
         | 
| 100 114 |  | 
| 101 115 | 
             
                def current_datacenter
         | 
| @@ -108,9 +122,7 @@ module OVIRT | |
| 108 122 |  | 
| 109 123 | 
             
                def http_get(suburl, headers={})
         | 
| 110 124 | 
             
                  begin
         | 
| 111 | 
            -
                     | 
| 112 | 
            -
                    puts "#{res}\n" if ENV['RBOVIRT_LOG_RESPONSE']
         | 
| 113 | 
            -
                    Nokogiri::XML(res)
         | 
| 125 | 
            +
                    handle_success(rest_client(suburl).get(http_headers(headers)))
         | 
| 114 126 | 
             
                  rescue
         | 
| 115 127 | 
             
                    handle_fault $!
         | 
| 116 128 | 
             
                  end
         | 
| @@ -118,9 +130,7 @@ module OVIRT | |
| 118 130 |  | 
| 119 131 | 
             
                def http_post(suburl, body, headers={})
         | 
| 120 132 | 
             
                  begin
         | 
| 121 | 
            -
                     | 
| 122 | 
            -
                    puts "#{res}\n" if ENV['RBOVIRT_LOG_RESPONSE']
         | 
| 123 | 
            -
                    Nokogiri::XML(res)
         | 
| 133 | 
            +
                    handle_success(rest_client(suburl).post(body, http_headers(headers)))
         | 
| 124 134 | 
             
                  rescue
         | 
| 125 135 | 
             
                    handle_fault $!
         | 
| 126 136 | 
             
                  end
         | 
| @@ -128,9 +138,7 @@ module OVIRT | |
| 128 138 |  | 
| 129 139 | 
             
                def http_put(suburl, body, headers={})
         | 
| 130 140 | 
             
                  begin
         | 
| 131 | 
            -
                     | 
| 132 | 
            -
                    puts "#{res}\n" if ENV['RBOVIRT_LOG_RESPONSE']
         | 
| 133 | 
            -
                    Nokogiri::XML(res)
         | 
| 141 | 
            +
                    handle_success(rest_client(suburl).put(body, http_headers(headers)))
         | 
| 134 142 | 
             
                  rescue
         | 
| 135 143 | 
             
                    handle_fault $!
         | 
| 136 144 | 
             
                  end
         | 
| @@ -140,9 +148,7 @@ module OVIRT | |
| 140 148 | 
             
                  begin
         | 
| 141 149 | 
             
                    headers = body ? http_headers(headers) :
         | 
| 142 150 | 
             
                      {:accept => 'application/xml'}.merge(auth_header).merge(filter_header)
         | 
| 143 | 
            -
                     | 
| 144 | 
            -
                    puts "#{res}\n" if ENV['RBOVIRT_LOG_RESPONSE']
         | 
| 145 | 
            -
                    Nokogiri::XML(res)
         | 
| 151 | 
            +
                    handle_success(rest_client(suburl).delete_with_payload(body, headers))
         | 
| 146 152 | 
             
                  rescue
         | 
| 147 153 | 
             
                    handle_fault $!
         | 
| 148 154 | 
             
                  end
         | 
| @@ -151,7 +157,12 @@ module OVIRT | |
| 151 157 | 
             
                def auth_header
         | 
| 152 158 | 
             
                  # This is the method for strict_encode64:
         | 
| 153 159 | 
             
                  encoded_credentials = ["#{@credentials[:username]}:#{@credentials[:password]}"].pack("m0").gsub(/\n/,'')
         | 
| 154 | 
            -
                  { :authorization => "Basic " + encoded_credentials }
         | 
| 160 | 
            +
                  headers = { :authorization => "Basic " + encoded_credentials }
         | 
| 161 | 
            +
                  if persistent_auth
         | 
| 162 | 
            +
                    headers[:prefer] = 'persistent-auth'
         | 
| 163 | 
            +
                    headers[:cookie] = "JSESSIONID=#{jsessionid}" if jsessionid
         | 
| 164 | 
            +
                  end
         | 
| 165 | 
            +
                  headers
         | 
| 155 166 | 
             
                end
         | 
| 156 167 |  | 
| 157 168 | 
             
                def rest_client(suburl)
         | 
| @@ -189,6 +200,12 @@ module OVIRT | |
| 189 200 | 
             
                  }).merge(headers)
         | 
| 190 201 | 
             
                end
         | 
| 191 202 |  | 
| 203 | 
            +
                def handle_success(response)
         | 
| 204 | 
            +
                  puts "#{response}\n" if ENV['RBOVIRT_LOG_RESPONSE']
         | 
| 205 | 
            +
                  @jsessionid ||= response.cookies['JSESSIONID']
         | 
| 206 | 
            +
                  Nokogiri::XML(response)
         | 
| 207 | 
            +
                end
         | 
| 208 | 
            +
             | 
| 192 209 | 
             
                def handle_fault(f)
         | 
| 193 210 | 
             
                  if f.is_a?(RestClient::BadRequest) || f.is_a?(RestClient::Conflict)
         | 
| 194 211 | 
             
                    fault = (Nokogiri::XML(f.http_body)/'//fault/detail')
         | 
| @@ -58,6 +58,28 @@ describe OVIRT, "Https authentication" do | |
| 58 58 | 
             
              end
         | 
| 59 59 | 
             
            end
         | 
| 60 60 |  | 
| 61 | 
            +
            describe OVIRT, "Persistent authentication" do
         | 
| 62 | 
            +
              context 'use persistent authentication' do
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                it "test_request_with_persistent_authentication" do
         | 
| 65 | 
            +
                  user, password, url, datacenter = endpoint
         | 
| 66 | 
            +
                  cert = ca_cert(url)
         | 
| 67 | 
            +
                  store = OpenSSL::X509::Store.new().add_cert(
         | 
| 68 | 
            +
                          OpenSSL::X509::Certificate.new(cert))
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  client = ::OVIRT::Client.new(user, password, url, {:ca_cert_store => store, :persistent_auth => true})
         | 
| 71 | 
            +
                  client.api_version.class.should eql(String)
         | 
| 72 | 
            +
                  client.persistent_auth.should eql(true)
         | 
| 73 | 
            +
                  client.jsessionid.should_not be_nil
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  # When performing a new request the jsessionid should remain the same
         | 
| 76 | 
            +
                  orig_jsession_id = client.jsessionid
         | 
| 77 | 
            +
                  client.datacenters.class.should eql(Array)
         | 
| 78 | 
            +
                  client.jsessionid.should eql(orig_jsession_id)
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
            end
         | 
| 82 | 
            +
             | 
| 61 83 | 
             
            describe OVIRT, "Admin API" do
         | 
| 62 84 |  | 
| 63 85 | 
             
              before(:all) do
         | 
| @@ -97,3 +119,22 @@ describe OVIRT, "User API" do | |
| 97 119 | 
             
              end
         | 
| 98 120 |  | 
| 99 121 | 
             
            end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
            describe OVIRT, "Operating systems API" do
         | 
| 124 | 
            +
             | 
| 125 | 
            +
              before(:all) do
         | 
| 126 | 
            +
                setup_client
         | 
| 127 | 
            +
              end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
              context 'basic user api and listing' do
         | 
| 130 | 
            +
                it "exposes supported operating systems" do
         | 
| 131 | 
            +
                  oses = @client.operating_systems
         | 
| 132 | 
            +
                  oses.should_not be_empty
         | 
| 133 | 
            +
                  os = oses.first
         | 
| 134 | 
            +
                  os.id.should_not be_empty
         | 
| 135 | 
            +
                  os.name.should_not be_empty
         | 
| 136 | 
            +
                  os.description.should_not be_empty
         | 
| 137 | 
            +
                end
         | 
| 138 | 
            +
              end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require "#{File.dirname(__FILE__)}/../spec_helper"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "Basic Instance type life cycle" do
         | 
| 4 | 
            +
              before(:all) do
         | 
| 5 | 
            +
                setup_client
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              it "test_should_return_instance_types" do
         | 
| 9 | 
            +
                @client.instance_types
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              it "test_should_return_an_instance_type" do
         | 
| 13 | 
            +
                @instance_type = @client.instance_types.first
         | 
| 14 | 
            +
                @client.instance_type(@instance_type.id).id.should eql(@instance_type.id)
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -51,6 +51,8 @@ shared_examples_for "Basic VM Life cycle" do | |
| 51 51 | 
             
              end
         | 
| 52 52 |  | 
| 53 53 | 
             
              it "test_should_set_vm_ticket" do
         | 
| 54 | 
            +
                while @client.vm(@vm.id).status.strip != 'down' do
         | 
| 55 | 
            +
                end
         | 
| 54 56 | 
             
                @client.vm_action(@vm.id, :start)
         | 
| 55 57 | 
             
                while !@client.vm(@vm.id).running? do
         | 
| 56 58 | 
             
                end
         | 
| @@ -117,6 +119,7 @@ shared_examples_for "VM Life cycle without template" do | |
| 117 119 | 
             
              end
         | 
| 118 120 | 
             
            end
         | 
| 119 121 |  | 
| 122 | 
            +
             | 
| 120 123 | 
             
            describe "Admin API VM Life cycle" do
         | 
| 121 124 |  | 
| 122 125 | 
             
              before(:all) do
         | 
| @@ -149,3 +152,124 @@ describe "User API VM Life cycle" do | |
| 149 152 | 
             
                it_behaves_like "Basic VM Life cycle"
         | 
| 150 153 | 
             
              end
         | 
| 151 154 | 
             
            end
         | 
| 155 | 
            +
             | 
| 156 | 
            +
            describe "VM API support functions" do
         | 
| 157 | 
            +
             | 
| 158 | 
            +
              before(:all) do
         | 
| 159 | 
            +
                setup_client
         | 
| 160 | 
            +
                if @client.templates.empty?
         | 
| 161 | 
            +
                  name = 'vm-'+Time.now.to_i.to_s
         | 
| 162 | 
            +
                  @cluster = @client.clusters.select{|c| c.name == cluster_name}.first.id
         | 
| 163 | 
            +
                  vm = @client.create_vm(:name => name, :cluster => @cluster)
         | 
| 164 | 
            +
                  @client.add_volume(vm.id)
         | 
| 165 | 
            +
                  @client.add_interface(vm.id, :network_name => network_name)
         | 
| 166 | 
            +
                  while !@client.vm(vm.id).ready? do
         | 
| 167 | 
            +
                  end
         | 
| 168 | 
            +
                  @client.create_template(:vm => vm.id, :name => "template-#{name}", :description => "test_template", :comment => "test_template")
         | 
| 169 | 
            +
                end
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                @template_name = @config['template'] || @client.templates.first.name
         | 
| 172 | 
            +
                @template = @client.templates.find { |t| t.name == @template_name }.id
         | 
| 173 | 
            +
                @template_disks = @client.template_volumes(@template)
         | 
| 174 | 
            +
                @storagedomain = @client.storagedomains.first.id
         | 
| 175 | 
            +
                @storagedomain_name = @client.storagedomains.first.name
         | 
| 176 | 
            +
              end
         | 
| 177 | 
            +
             | 
| 178 | 
            +
              context 'options processing' do
         | 
| 179 | 
            +
                it "should process template option into disk decriptions" do
         | 
| 180 | 
            +
                  t_id = @template
         | 
| 181 | 
            +
                  opts = {:template => t_id}
         | 
| 182 | 
            +
                  t_name = opts[:template_name]
         | 
| 183 | 
            +
                  @client.process_vm_opts(opts)
         | 
| 184 | 
            +
                  opts[:template].should eql(t_id)
         | 
| 185 | 
            +
                  opts[:template_name].should eql(t_name)
         | 
| 186 | 
            +
                end
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                it "should process template_name option into disk decriptions" do
         | 
| 189 | 
            +
                  t_name = @template_name
         | 
| 190 | 
            +
                  opts = {:template_name => t_name}
         | 
| 191 | 
            +
                  t_id = opts[:template]
         | 
| 192 | 
            +
                  @client.process_vm_opts(opts)
         | 
| 193 | 
            +
                  opts[:template].should eql(t_id)
         | 
| 194 | 
            +
                  opts[:template_name].should eql(t_name)
         | 
| 195 | 
            +
                end
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                it "should process template and storagedomain options into disk decriptions" do
         | 
| 198 | 
            +
                  t_id = @template
         | 
| 199 | 
            +
                  s_id = @storagedomain
         | 
| 200 | 
            +
                  opts = {:template => t_id,
         | 
| 201 | 
            +
                          :storagedomain => s_id}
         | 
| 202 | 
            +
                  t_name = opts[:template_name]
         | 
| 203 | 
            +
                  s_name = opts[:storagedomain_name]
         | 
| 204 | 
            +
                  @client.process_vm_opts(opts)
         | 
| 205 | 
            +
                  opts[:disks].length.should eql(@template_disks.length)
         | 
| 206 | 
            +
                  unless @template_disks.empty?
         | 
| 207 | 
            +
                    opts[:disks].first[:id].should_not be_nil
         | 
| 208 | 
            +
                    opts[:disks].first[:storagedomain].should eql(s_id)
         | 
| 209 | 
            +
                  end
         | 
| 210 | 
            +
                  opts[:template].should eql(t_id)
         | 
| 211 | 
            +
                  opts[:template_name].should eql(t_name)
         | 
| 212 | 
            +
                  opts[:storagedomain].should eql(s_id)
         | 
| 213 | 
            +
                  opts[:storagedomain_name].should eql(s_name)
         | 
| 214 | 
            +
                end
         | 
| 215 | 
            +
             | 
| 216 | 
            +
                it "should process template_name and storagedomain options into disk decriptions" do
         | 
| 217 | 
            +
                  t_name = @template_name
         | 
| 218 | 
            +
                  s_id = @storagedomain
         | 
| 219 | 
            +
                  opts = {:template_name => t_name,
         | 
| 220 | 
            +
                          :storagedomain => s_id}
         | 
| 221 | 
            +
                  t_id = opts[:template]
         | 
| 222 | 
            +
                  s_name = opts[:storagedomain_name]
         | 
| 223 | 
            +
                  @client.process_vm_opts(opts)
         | 
| 224 | 
            +
                  opts[:disks].length.should eql(@template_disks.length)
         | 
| 225 | 
            +
                  unless @template_disks.empty?
         | 
| 226 | 
            +
                    opts[:disks].first[:id].should_not be_nil
         | 
| 227 | 
            +
                    opts[:disks].first[:storagedomain].should eql(s_id)
         | 
| 228 | 
            +
                  end
         | 
| 229 | 
            +
                  opts[:template].should eql(t_id)
         | 
| 230 | 
            +
                  opts[:template_name].should eql(t_name)
         | 
| 231 | 
            +
                  opts[:storagedomain].should eql(s_id)
         | 
| 232 | 
            +
                  opts[:storagedomain_name].should eql(s_name)
         | 
| 233 | 
            +
                end
         | 
| 234 | 
            +
             | 
| 235 | 
            +
                it "should process template and storagedomain_name options into disk decriptions" do
         | 
| 236 | 
            +
                  t_id = @template
         | 
| 237 | 
            +
                  s_name = @storagedomain_name
         | 
| 238 | 
            +
                  opts = {:template => t_id,
         | 
| 239 | 
            +
                          :storagedomain_name => s_name}
         | 
| 240 | 
            +
                  t_name = opts[:template_name]
         | 
| 241 | 
            +
                  s_id = opts[:storagedomain_id]
         | 
| 242 | 
            +
                  @client.process_vm_opts(opts)
         | 
| 243 | 
            +
                  opts[:disks].length.should eql(@template_disks.length)
         | 
| 244 | 
            +
                  unless @template_disks.empty?
         | 
| 245 | 
            +
                    opts[:disks].first[:id].should_not be_nil
         | 
| 246 | 
            +
                    opts[:disks].first[:storagedomain].should eql(@storagedomain)
         | 
| 247 | 
            +
                  end
         | 
| 248 | 
            +
                  opts[:template].should eql(t_id)
         | 
| 249 | 
            +
                  opts[:template_name].should eql(t_name)
         | 
| 250 | 
            +
                  opts[:storagedomain].should eql(s_id)
         | 
| 251 | 
            +
                  opts[:storagedomain_name].should eql(s_name)
         | 
| 252 | 
            +
                end
         | 
| 253 | 
            +
             | 
| 254 | 
            +
                it "should process template_name and storagedomain_name options into disk decriptions" do
         | 
| 255 | 
            +
                  t_name = @template_name
         | 
| 256 | 
            +
                  s_name = @storagedomain_name
         | 
| 257 | 
            +
                  opts = {:template_name => t_name,
         | 
| 258 | 
            +
                          :storagedomain_name => s_name}
         | 
| 259 | 
            +
                  t_id = opts[:template]
         | 
| 260 | 
            +
                  s_id = opts[:storagedomain]
         | 
| 261 | 
            +
                  @client.process_vm_opts(opts)
         | 
| 262 | 
            +
                  opts[:disks].length.should eql(@template_disks.length)
         | 
| 263 | 
            +
                  unless @template_disks.empty?
         | 
| 264 | 
            +
                    opts[:disks].first[:id].should_not be_nil
         | 
| 265 | 
            +
                    opts[:disks].first[:storagedomain].should eql(@storagedomain)
         | 
| 266 | 
            +
                  end
         | 
| 267 | 
            +
                  opts[:template].should eql(t_id)
         | 
| 268 | 
            +
                  opts[:template_name].should eql(t_name)
         | 
| 269 | 
            +
                  opts[:storagedomain].should eql(s_id)
         | 
| 270 | 
            +
                  opts[:storagedomain_name].should eql(s_name)
         | 
| 271 | 
            +
                end
         | 
| 272 | 
            +
             | 
| 273 | 
            +
              end
         | 
| 274 | 
            +
            end
         | 
| 275 | 
            +
             | 
    
        data/spec/unit/vm_spec.rb
    CHANGED
    
    | @@ -232,6 +232,50 @@ END_HEREDOC | |
| 232 232 | 
             
                  xml.nil?.should eql(false)
         | 
| 233 233 | 
             
                end
         | 
| 234 234 |  | 
| 235 | 
            +
                it "create vm xml without description" do
         | 
| 236 | 
            +
                  opts = {
         | 
| 237 | 
            +
                      :cluster_name =>'cluster',
         | 
| 238 | 
            +
                      :template_name =>'template',
         | 
| 239 | 
            +
                  }
         | 
| 240 | 
            +
                  xml = OVIRT::VM.to_xml(opts)
         | 
| 241 | 
            +
                  xml.nil?.should eql(false)
         | 
| 242 | 
            +
                  Nokogiri::XML(xml).xpath("//description").length.should eql(1)
         | 
| 243 | 
            +
                  Nokogiri::XML(xml).xpath("//description")[0].children.length.should eql(0)
         | 
| 244 | 
            +
                end
         | 
| 245 | 
            +
             | 
| 246 | 
            +
                it "create vm xml with description" do
         | 
| 247 | 
            +
                  opts = {
         | 
| 248 | 
            +
                      :cluster_name =>'cluster',
         | 
| 249 | 
            +
                      :template_name =>'template',
         | 
| 250 | 
            +
                      :description => 'a description',
         | 
| 251 | 
            +
                  }
         | 
| 252 | 
            +
                  xml = OVIRT::VM.to_xml(opts)
         | 
| 253 | 
            +
                  xml.nil?.should eql(false)
         | 
| 254 | 
            +
                  Nokogiri::XML(xml).xpath("//description").length.should eql(1)
         | 
| 255 | 
            +
                  Nokogiri::XML(xml).xpath("//description")[0].children.length.should eql(1)
         | 
| 256 | 
            +
                  Nokogiri::XML(xml).xpath("//description")[0].children[0].text?.should eql(true)
         | 
| 257 | 
            +
                  Nokogiri::XML(xml).xpath("//description")[0].content.should eql("a description")
         | 
| 258 | 
            +
                end
         | 
| 259 | 
            +
             | 
| 260 | 
            +
                it "create vm xml with disks" do
         | 
| 261 | 
            +
                  disk = "00000000-0000-0000-0000-000000000000"
         | 
| 262 | 
            +
                  storagedomain = "00000000-0000-0000-0000-000000000001"
         | 
| 263 | 
            +
                  disks = [{:id => disk, :storagedomain => storagedomain}]
         | 
| 264 | 
            +
                  opts = {
         | 
| 265 | 
            +
                      :cluster_name => 'cluster',
         | 
| 266 | 
            +
                      :disks => disks,
         | 
| 267 | 
            +
                  }
         | 
| 268 | 
            +
                  xml = OVIRT::VM.to_xml(opts)
         | 
| 269 | 
            +
                  puts xml
         | 
| 270 | 
            +
                  xml.nil?.should eql(false)
         | 
| 271 | 
            +
                  Nokogiri::XML(xml).xpath("//disks").length.should eql(1)
         | 
| 272 | 
            +
                  Nokogiri::XML(xml).xpath("//disks")[0].element_children.length.should eql(1)
         | 
| 273 | 
            +
                  Nokogiri::XML(xml).xpath("//disks/disk[contains(@id,'#{disk}')]").length.should eql(1)
         | 
| 274 | 
            +
                  Nokogiri::XML(xml).xpath("//disks/disk/storage_domains").length.should eql(1)
         | 
| 275 | 
            +
                  Nokogiri::XML(xml).xpath("//disks/disk/storage_domains")[0].element_children.length.should eql(1)
         | 
| 276 | 
            +
                  Nokogiri::XML(xml).xpath("//disks/disk/storage_domains/storage_domain[contains(@id,'#{storagedomain}')]").length.should eql(1)
         | 
| 277 | 
            +
                end
         | 
| 278 | 
            +
             | 
| 235 279 | 
             
                it "should be running" do
         | 
| 236 280 | 
             
                  vm = OVIRT::VM.new(nil, Nokogiri::XML(@xml).xpath('/').first)
         | 
| 237 281 | 
             
                  vm.running?.should eql(true)
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rbovirt
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.1. | 
| 4 | 
            +
              version: 0.1.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Amos Benari
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2016-04-25 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: nokogiri
         | 
| @@ -80,8 +80,7 @@ dependencies: | |
| 80 80 | 
             
                - - ">="
         | 
| 81 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 82 | 
             
                    version: '0'
         | 
| 83 | 
            -
            description:  | 
| 84 | 
            -
                  A Ruby client for oVirt REST API
         | 
| 83 | 
            +
            description: "    A Ruby client for oVirt REST API\n"
         | 
| 85 84 | 
             
            email:
         | 
| 86 85 | 
             
            - abenari@redhat.com
         | 
| 87 86 | 
             
            executables: []
         | 
| @@ -103,6 +102,8 @@ files: | |
| 103 102 | 
             
            - lib/client/disk_api.rb
         | 
| 104 103 | 
             
            - lib/client/disk_profile_api.rb
         | 
| 105 104 | 
             
            - lib/client/host_api.rb
         | 
| 105 | 
            +
            - lib/client/instance_type_api.rb
         | 
| 106 | 
            +
            - lib/client/operating_system_api.rb
         | 
| 106 107 | 
             
            - lib/client/quota_api.rb
         | 
| 107 108 | 
             
            - lib/client/storage_domain_api.rb
         | 
| 108 109 | 
             
            - lib/client/template_api.rb
         | 
| @@ -113,8 +114,10 @@ files: | |
| 113 114 | 
             
            - lib/ovirt/datacenter.rb
         | 
| 114 115 | 
             
            - lib/ovirt/disk_profile.rb
         | 
| 115 116 | 
             
            - lib/ovirt/host.rb
         | 
| 117 | 
            +
            - lib/ovirt/instance_type.rb
         | 
| 116 118 | 
             
            - lib/ovirt/interface.rb
         | 
| 117 119 | 
             
            - lib/ovirt/network.rb
         | 
| 120 | 
            +
            - lib/ovirt/operating_system.rb
         | 
| 118 121 | 
             
            - lib/ovirt/quota.rb
         | 
| 119 122 | 
             
            - lib/ovirt/storage_domain.rb
         | 
| 120 123 | 
             
            - lib/ovirt/template.rb
         | 
| @@ -127,6 +130,7 @@ files: | |
| 127 130 | 
             
            - rbovirt.gemspec
         | 
| 128 131 | 
             
            - spec/endpoint.yml.example
         | 
| 129 132 | 
             
            - spec/integration/api_spec.rb
         | 
| 133 | 
            +
            - spec/integration/instance_type_spec.rb
         | 
| 130 134 | 
             
            - spec/integration/vm_crud_spec.rb
         | 
| 131 135 | 
             
            - spec/spec_helper.rb
         | 
| 132 136 | 
             
            - spec/unit/client_spec.rb
         | 
| @@ -157,14 +161,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 157 161 | 
             
                  version: '0'
         | 
| 158 162 | 
             
            requirements: []
         | 
| 159 163 | 
             
            rubyforge_project: 
         | 
| 160 | 
            -
            rubygems_version: 2. | 
| 164 | 
            +
            rubygems_version: 2.0.14
         | 
| 161 165 | 
             
            signing_key: 
         | 
| 162 166 | 
             
            specification_version: 4
         | 
| 163 167 | 
             
            summary: A Ruby client for oVirt REST API
         | 
| 164 168 | 
             
            test_files:
         | 
| 165 169 | 
             
            - spec/endpoint.yml.example
         | 
| 166 170 | 
             
            - spec/integration/api_spec.rb
         | 
| 171 | 
            +
            - spec/integration/instance_type_spec.rb
         | 
| 167 172 | 
             
            - spec/integration/vm_crud_spec.rb
         | 
| 168 173 | 
             
            - spec/spec_helper.rb
         | 
| 169 174 | 
             
            - spec/unit/client_spec.rb
         | 
| 170 175 | 
             
            - spec/unit/vm_spec.rb
         | 
| 176 | 
            +
            has_rdoc: 
         |