deltacloud-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfoj...@redhat.com
Subject [PATCH core] RHEV-M: Switched to rbovirt gem
Date Wed, 08 Feb 2012 11:26:45 GMT
From: Michal Fojtik <mfojtik@redhat.com>


Signed-off-by: Michal fojtik <mfojtik@redhat.com>
---
 .../lib/deltacloud/drivers/rhevm/rhevm_client.rb   |  521 --------------------
 .../lib/deltacloud/drivers/rhevm/rhevm_driver.rb   |   41 +-
 2 files changed, 13 insertions(+), 549 deletions(-)
 delete mode 100644 server/lib/deltacloud/drivers/rhevm/rhevm_client.rb

diff --git a/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb b/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb
deleted file mode 100644
index 5a75143..0000000
--- a/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb
+++ /dev/null
@@ -1,521 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-
-require 'rubygems'
-require 'restclient'
-require 'nokogiri'
-require 'digest/md5'
-require 'json'
-
-module RHEVM
-
-  # NOTE: Injected file will be available in floppy drive inside
-  #       the instance. (Be sure you 'modprobe floppy' on Linux)
-  FILEINJECT_PATH = "deltacloud-user-data.txt"
-
-  def self.client(url)
-    RestClient::Resource.new(url)
-  end
-
-  class BackendVersionUnsupportedException < StandardError; end
-  class RHEVMBackendException < StandardError
-    def initialize(message)
-      @message = message
-      super
-    end
-
-    def message
-      @message
-    end
-  end
-
-  class Client
-
-    attr_reader :credentials, :api_entrypoint, :datacenter_id
-
-    def initialize(username, password, api_entrypoint, datacenter_id=nil)
-      @credentials = { :username => username, :password => password }
-      @datacenter_id = datacenter_id
-      @api_entrypoint = api_entrypoint
-    end
-
-    def vms(opts={})
-      headers = {
-        :accept => "application/xml; detail=disks; detail=nics; detail=hosts"
-      }
-      headers.merge!(auth_header)
-      if opts[:id]
-        vm = Client::parse_response(RHEVM::client(@api_entrypoint)["/vms/%s" % opts[:id]].get(headers)).root
-        return [] unless current_datacenter.cluster_ids.include?((vm/'cluster').first[:id])
-        [ RHEVM::VM::new(self, vm)]
-      else
-        Client::parse_response(RHEVM::client(@api_entrypoint)["/vms"].get(headers)).xpath('/vms/vm').collect
do |vm|
-          next unless current_datacenter.cluster_ids.include?((vm/'cluster').first[:id])
-          RHEVM::VM::new(self, vm)
-        end.compact
-      end
-    end
-
-    def vm_action(id, action, headers={})
-      headers.merge!(auth_header)
-      headers.merge!({:accept => 'application/xml'})
-      vm = vms(:id => id)
-      raise RHEVMBackendException::new("Requested VM not found in datacenter #{self.current_datacenter.id}")
if vm.empty?
-      if action==:delete
-        RHEVM::client(@api_entrypoint)["/vms/%s" % id].delete(headers)
-      else
-        headers.merge!({ :content_type => 'application/xml' })
-        begin
-          client_response = RHEVM::client(@api_entrypoint)["/vms/%s/%s" % [id, action]].post('<action/>',
headers)
-        rescue
-          if $!.is_a?(RestClient::BadRequest)
-            fault = (Nokogiri::XML($!.http_body)/'//fault/detail')
-            fault = fault.text.gsub(/\[|\]/, '') if fault
-          end
-          fault ||= $!.message
-          raise RHEVMBackendException::new(fault)
-        end
-        xml_response = Client::parse_response(client_response)
-
-        return false if (xml_response/'action/status').first.text.strip.upcase!="COMPLETE"
-      end
-      return true
-    end
-
-    def api_version?(major)
-      headers = {
-        :content_type => 'application/xml',
-        :accept => 'application/xml'
-      }
-      headers.merge!(auth_header)
-      result_xml = Nokogiri::XML(RHEVM::client(@api_entrypoint)["/"].get(headers))
-      if (result_xml/'api/system_version').empty?
-        (result_xml/'/api/product_info/version').first[:major].strip == major
-      else
-        (result_xml/'/api/system_version').first[:major].strip == major
-      end
-    end
-
-    def cluster_version?(cluster_id, major)
-      headers = {
-        :content_type => 'application/xml',
-        :accept => 'application/xml'
-      }
-      headers.merge!(auth_header)
-      result_xml = Nokogiri::XML(RHEVM::client(@api_entrypoint)["/clusters/%s" % cluster_id].get(headers))
-      (result_xml/'/cluster/version').first[:major].strip == major
-    end
-
-    def capability?(name)
-      headers = {
-        :content_type => 'application/xml',
-        :accept => 'application/xml'
-      }
-      headers.merge!(auth_header)
-      result_xml = Nokogiri::XML(RHEVM::client(@api_entrypoint)["/capabilities"].get(headers))
-      !(result_xml/"/capabilities/version/custom_properties/custom_property[@name='#{name}']").empty?
-    end
-
-    def create_vm(template_id, opts={})
-      opts ||= {}
-      templ = template(template_id)
-      raise RHEVMBackendException::new("Requested VM not found in datacenter #{self.current_datacenter.id}")
unless templ
-      builder = Nokogiri::XML::Builder.new do
-        vm {
-          name opts[:name] || "i-#{Time.now.to_i}"
-          template_(:id => template_id)
-          cluster_(:id => opts[:realm_id].nil? ? templ.cluster.id : opts[:realm_id])
-          type_ opts[:hwp_id] || 'desktop'
-          memory opts[:hwp_memory] ? (opts[:hwp_memory].to_i*1024*1024).to_s : (512*1024*1024).to_s
-          cpu {
-            topology( :cores => (opts[:hwp_cpu] || '1'), :sockets => '1' )
-          }
-          if opts[:user_data] and not opts[:user_data].empty?
-            if api_version?('3') and cluster_version?((opts[:realm_id] || clusters.first.id),
'3')
-              raise "Required VDSM hook 'floppyinject' not supported by RHEV-M" unless capability?(:floppyinject)
-              custom_properties {
-                custom_property({
-                  :name => "floppyinject",
-                  :value => "#{RHEVM::FILEINJECT_PATH}:#{opts[:user_data]}",
-                  :regexp => "^([^:]+):(.*)$"})
-              }
-            else
-              raise BackendVersionUnsupportedException.new
-            end
-          end
-        }
-      end
-      headers = opts[:headers] || {}
-      headers.merge!({
-        :content_type => 'application/xml',
-        :accept => 'application/xml',
-      })
-      templates = templates(:id => template_id)
-      raise RHEVMBackendException::new("Requested VM not found in datacenter #{self.current_datacenter.id}")
if templates.empty?
-      headers.merge!(auth_header)
-      begin
-        vm = RHEVM::client(@api_entrypoint)["/vms"].post(Nokogiri::XML(builder.to_xml).root.to_s,
headers)
-      rescue
-        if $!.respond_to?(:http_body)
-          fault = (Nokogiri::XML($!.http_body)/'/fault/detail').first
-          fault = fault.text.gsub(/\[|\]/, '') if fault
-        end
-        fault ||= $!.message
-        raise RHEVMBackendException::new(fault)
-      end
-      RHEVM::VM::new(self, Nokogiri::XML(vm).root)
-    end
-
-    def create_template(vm_id, opts={})
-      opts ||= {}
-      builder = Nokogiri::XML::Builder.new do
-        template_ {
-          name opts[:name]
-          description opts[:description]
-          vm(:id => vm_id)
-        }
-      end
-      headers = opts[:headers] || {}
-      headers.merge!({
-        :content_type => 'application/xml',
-        :accept => 'application/xml',
-      })
-      headers.merge!(auth_header)
-      template = RHEVM::client(@api_entrypoint)["/templates"].post(Nokogiri::XML(builder.to_xml).root.to_s,
headers)
-      RHEVM::Template::new(self, Nokogiri::XML(template).root)
-    end
-
-    def destroy_template(id, headers={})
-      headers.merge!({
-        :content_type => 'application/xml',
-        :accept => 'application/xml',
-      })
-      tmpl = template(id)
-      raise RHEVMBackendException::new("Requested VM not found in datacenter #{self.current_datacenter.id}")
unless tmpl
-      headers.merge!(auth_header)
-      RHEVM::client(@api_entrypoint)["/templates/%s" % id].delete(headers)
-      return true
-    end
-
-    def templates(opts={})
-      headers = {
-        :accept => "application/xml"
-      }
-      headers.merge!(auth_header)
-      rhevm_templates = RHEVM::client(@api_entrypoint)["/templates"].get(headers)
-      Client::parse_response(rhevm_templates).xpath('/templates/template').collect do |t|
-        next unless current_datacenter.cluster_ids.include?((t/'cluster').first[:id])
-        RHEVM::Template::new(self, t)
-      end.compact
-    end
-
-    def template(template_id)
-      headers = {
-        :accept => "application/xml"
-      }
-      headers.merge!(auth_header)
-      rhevm_template = RHEVM::client(@api_entrypoint)["/templates/%s" % template_id].get(headers)
-      RHEVM::Template::new(self, Client::parse_response(rhevm_template).root)
-    end
-
-    def datacenters(opts={})
-      headers = {
-        :accept => "application/xml"
-      }
-      headers.merge!(auth_header)
-      rhevm_datacenters = RHEVM::client(@api_entrypoint)["/datacenters"].get(headers)
-      Client::parse_response(rhevm_datacenters).xpath('/data_centers/data_center').collect
do |dc|
-        RHEVM::DataCenter::new(self, dc)
-      end
-    end
-
-    def clusters
-      current_datacenter.clusters
-    end
-
-    def cluster(cluster_id)
-      current_datacenter.cluster(cluster_id)
-    end
-
-    def current_datacenter
-      @current_datacenter ||= self.datacenter_id ? datacenter(self.datacenter_id) : datacenters.first
-    end
-
-    def datacenter(datacenter_id)
-      headers = {
-        :accept => "application/xml"
-      }
-      headers.merge!(auth_header)
-      rhevm_datacenter = RHEVM::client(@api_entrypoint)["/datacenters/%s" % datacenter_id].get(headers)
-      RHEVM::DataCenter::new(self, Client::parse_response(rhevm_datacenter).root)
-    end
-
-    def hosts(opts={})
-      headers = {
-        :accept => "application/xml"
-      }
-      headers.merge!(auth_header)
-      if opts[:id]
-        vm = Client::parse_response(RHEVM::client(@api_entrypoint)["/hosts/%s" % opts[:id]].get(headers)).root
-        [ RHEVM::Host::new(self, vm)]
-      else
-        Client::parse_response(RHEVM::client(@api_entrypoint)["/hosts"].get(headers)).xpath('/hosts/host').collect
do |vm|
-          RHEVM::Host::new(self, vm)
-        end
-      end
-    end
-
-    def storagedomains(opts={})
-      headers = {
-        :accept => "application/xml"
-      }
-      headers.merge!(auth_header)
-      if opts[:id]
-        vm = Client::parse_response(RHEVM::client(@api_entrypoint)["/storagedomains/%s" %
opts[:id]].get(headers)).root
-        [ RHEVM::StorageDomain::new(self, vm)]
-      else
-        Client::parse_response(RHEVM::client(@api_entrypoint)["/storagedomains"].get(headers)).xpath('/storage_domains/storage_domain').collect
do |vm|
-          RHEVM::StorageDomain::new(self, vm)
-        end
-      end
-    end
-
-    def auth_header
-      # As RDOC says this is the function for strict_encode64:
-      encoded_credentials = ["#{@credentials[:username]}:#{@credentials[:password]}"].pack("m0").gsub(/\n/,'')
-      { :authorization => "Basic " + encoded_credentials }
-    end
-
-    def base_url
-      url = URI.parse(@api_entrypoint)
-      "#{url.scheme}://#{url.host}:#{url.port}"
-    end
-
-    def self.parse_response(response)
-      Nokogiri::XML(response)
-    end
-
-    def has_datacenter?(vm)
-      value=!(vm/'data_center').empty?
-      value
-    end
-  end
-
-  class BaseObject
-    attr_accessor :id, :href, :name
-    attr_reader :client
-
-    def initialize(client, id, href, name)
-      @id, @href, @name = id, href, name
-      @client = client
-      self
-    end
-  end
-
-  class Link
-    attr_accessor :id, :href, :client
-
-    def initialize(client, id, href)
-      @id, @href = id, href
-      @client = client
-    end
-
-    def follow
-      xml = Client::parse_response(RHEVM::client(@client.base_url)[@href].get(@client.auth_header))
-      object_class = ::RHEVM.const_get(xml.root.name.camelize)
-      object_class.new(@client, (xml.root))
-    end
-
-  end
-
-  class VM < BaseObject
-    attr_reader :description, :status, :memory, :profile, :display, :host, :cluster, :template,
:macs
-    attr_reader :storage, :cores, :username, :creation_time
-    attr_reader :ip, :vnc
-
-    def initialize(client, xml)
-      super(client, xml[:id], xml[:href], (xml/'name').first.text)
-      @username = client.credentials[:username]
-      parse_xml_attributes!(xml)
-      self
-    end
-
-    private
-
-    def parse_xml_attributes!(xml)
-      @description = ((xml/'description').first.text rescue '')
-      @status = (xml/'status').first.text
-      @memory = (xml/'memory').first.text
-      @profile = (xml/'type').first.text
-      @template = Link::new(@client, (xml/'template').first[:id], (xml/'template').first[:href])
-      @host = Link::new(@client, (xml/'host').first[:id], (xml/'host').first[:href]) rescue
nil
-      @cluster = Link::new(@client, (xml/'cluster').first[:id], (xml/'cluster').first[:href])
-      @display = {
-        :type => (xml/'display/type').first.text,
-        :address => ((xml/'display/address').first.text rescue nil),
-        :port => ((xml/'display/port').first.text rescue nil),
-        :monitors => (xml/'display/monitors').first.text
-      }
-      @cores = ((xml/'cpu/topology').first[:cores] rescue nil)
-      @storage = ((xml/'disks/disk/size').first.text rescue nil)
-      @macs = (xml/'nics/nic/mac').collect { |mac| mac[:address] }
-      @creation_time = (xml/'creation_time').text
-      @ip = ((xml/'guest_info/ips/ip').first[:address] rescue nil)
-      @vnc = {
-        :address => ((xml/'display/address').first.text rescue "127.0.0.1"),
-        :port => ((xml/'display/port').first.text rescue "5890")
-      } unless @ip
-    end
-
-  end
-
-  class Template < BaseObject
-    attr_reader :description, :status, :cluster
-
-    def initialize(client, xml)
-      super(client, xml[:id], xml[:href], (xml/'name').first.text)
-      parse_xml_attributes!(xml)
-      self
-    end
-
-    private
-
-    def parse_xml_attributes!(xml)
-      @description = ((xml/'description').first.text rescue nil)
-      @status = (xml/'status').first.text
-      @cluster = Link::new(@client, (xml/'cluster').first[:id], (xml/'cluster').first[:href])
-    end
-  end
-
-  class Cluster < BaseObject
-    attr_reader :description, :datacenter, :version
-
-    def initialize(client, xml)
-      super(client, xml[:id], xml[:href], (xml/'name').first.text)
-      parse_xml_attributes!(xml)
-      self
-    end
-
-    private
-
-    def parse_xml_attributes!(xml)
-      @description = ((xml/'description').first.text rescue nil)
-      @version =((xml/'version').first[:major].strip rescue nil)
-      unless (xml/'data_center').empty?
-        @datacenter = Link::new(@client, (xml/'data_center').first[:id], (xml/'data_center').first[:href])
-      end
-    end
-
-  end
-
-  class DataCenter < BaseObject
-    attr_reader :description, :status
-
-    def initialize(client, xml)
-      super(client, xml[:id], xml[:href], (xml/'name').first.text)
-      parse_xml_attributes!(xml)
-      self
-    end
-
-    def clusters
-      headers = {
-        :accept => "application/xml; detail=datacenters"
-      }
-      headers.merge!(client.auth_header)
-      clusters_list = RHEVM::client(client.api_entrypoint)["/clusters"].get(headers)
-      cluster_arr = Client::parse_response(clusters_list).xpath('/clusters/cluster')
-      clusters_arr = []
-      cluster_arr.each do |cluster|
-        cluster = RHEVM::Cluster.new(self.client, cluster)
-        clusters_arr << cluster if cluster.datacenter && cluster.datacenter.id
== client.datacenter_id
-      end
-      clusters_arr
-    end
-
-    def cluster(cluster_id)
-      headers = {
-        :accept => "application/xml; detail=datacenters"
-      }
-      headers.merge!(client.auth_header)
-      cluster_xml = RHEVM::client(client.api_entrypoint)["/clusters/%s" % cluster_id].get(headers)
-      cluster = RHEVM::Cluster.new(self.client, cluster_xml)
-      if cluster.datacenter && cluster.datacenter.id == client.datacenter_id
-        cluster
-      else
-        nil
-      end
-    end
-
-    def cluster_ids
-      @cluster_ids ||= clusters.collect { |c| c.id }
-    end
-
-    private
-
-    def parse_xml_attributes!(xml)
-      @description = ((xml/'description').first.text rescue nil)
-      @status = (xml/'status').first.text
-    end
-  end
-
-  class Host < BaseObject
-    attr_reader :description, :status, :cluster
-
-    def initialize(client, xml)
-      super(client, xml[:id], xml[:href], (xml/'name').first.text)
-      parse_xml_attributes!(xml)
-      self
-    end
-
-    private
-
-    def parse_xml_attributes!(xml)
-      @description = ((xml/'description').first.text rescue nil)
-      @status = (xml/'status').first.text
-      @clister = Link::new(@client, (xml/'cluster').first[:id], (xml/'cluster').first[:href])
-    end
-  end
-
-  class StorageDomain < BaseObject
-    attr_reader :available, :used, :kind, :address, :path
-
-    def initialize(client, xml)
-      super(client, xml[:id], xml[:href], (xml/'name').first.text)
-      parse_xml_attributes!(xml)
-      self
-    end
-
-    private
-
-    def parse_xml_attributes!(xml)
-      @available = (xml/'available').first.text
-      @used = (xml/'used').first.text
-      @kind = (xml/'storage/type').first.text
-      @address = ((xml/'storage/address').first.text rescue nil)
-      @path = ((xml/'storage/path').first.text rescue nil)
-    end
-  end
-
-end
-
-class String
-  unless method_defined?(:camelize)
-    # Camelize converts strings to UpperCamelCase
-    def camelize
-      self.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
-    end
-  end
-end
diff --git a/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb b/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb
index a66b9c6..f804870 100644
--- a/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb
+++ b/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb
@@ -14,18 +14,8 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-# Minihowto: Setting up this driver
-#
-# 1. Setup RHEV-M server
-# 2. Setup RHEV-M API (git://git.fedorahosted.org/rhevm-api.git - follow README)
-# 3. Set URL to API using shell variable (or HTTP header, see comment on provider_url)
-#    export API_PROVIDER="https://x.x.x.x/rhevm-api-powershell"
-# 4. Start Deltacloud using: deltacloudd -i rhevm
-# 5. Use RHEV-M credentials + append Windows Domain
-#    like: admin@rhevm.example.com
-
 require 'deltacloud/base_driver'
-require 'deltacloud/drivers/rhevm/rhevm_client'
+require 'rbovirt'
 
 module Deltacloud
   module Drivers
@@ -187,23 +177,18 @@ class RHEVMDriver < Deltacloud::BaseDriver
   def create_instance(credentials, image_id, opts={})
     client = new_client(credentials)
     params = {}
-    name = opts[:name]
-    if not name
-      name = Time.now.to_i.to_s
-    end
-    if name.length > USER_NAME_MAX
-      raise "Parameter name must be #{USER_NAME_MAX} characters or less"
+    if opts[:name]
+      raise "Parameter name must be #{USER_NAME_MAX} characters or less" if opts[:name].length
> USER_NAME_MAX
     end
     safely do
-      params[:name] = name
-      params[:realm_id] = opts[:realm_id] if opts[:realm_id]
+      params[:name] = opts[:name]
+      params[:template] = opts[:image_id]
+      params[:cluster] = opts[:realm_id] if opts[:realm_id]
       params[:hwp_id] = opts[:hwp_id] if opts[:hwp_id]
-      params[:hwp_memory] = opts[:hwp_memory] if opts[:hwp_memory]
-      params[:hwp_cpu] = opts[:hwp_cpu] if opts[:hwp_cpu]
-      if opts[:user_data]
-        params[:user_data] = opts[:user_data].gsub(/\n/,'')
-      end
-      convert_instance(client, client.create_vm(image_id, params))
+      params[:memory] = (opts[:hwp_memory] * 1024 * 1024) if opts[:hwp_memory]
+      params[:cores] = opts[:hwp_cpu] if opts[:hwp_cpu]
+      params[:user_data] = opts[:user_data].gsub(/\n/,'') if opts[:user_data]
+      convert_instance(client, client.create_vm(params))
     end
   end
 
@@ -224,7 +209,7 @@ class RHEVMDriver < Deltacloud::BaseDriver
   def new_client(credentials)
     url, datacenter = api_provider.split(';')
     safely do
-      ::RHEVM::Client.new(credentials.user, credentials.password, url, datacenter)
+      OVIRT::Client.new(credentials.user, credentials.password, url, datacenter)
     end
   end
 
@@ -260,7 +245,7 @@ class RHEVMDriver < Deltacloud::BaseDriver
     end
     # If IP retrieval failed, fallback to VNC and MAC address
     if public_addresses.empty?
-      public_addresses = inst.macs.collect { |mac_address| InstanceAddress.new(mac_address,
:type => :mac) }
+      public_addresses = inst.interfaces.map { |interface| InstanceAddress.new(interface.mac,
:type => :mac) }
     end
     if inst.vnc
       public_addresses << InstanceAddress.new(inst.vnc[:address], :port => inst.vnc[:port],
:type => :vnc)
@@ -271,7 +256,7 @@ class RHEVMDriver < Deltacloud::BaseDriver
       :state => state,
       :image_id => inst.template.id,
       :realm_id => inst.cluster.id,
-      :owner_id => inst.username,
+      :owner_id => client.credentials[:username],
       :launch_time => inst.creation_time,
       :instance_profile => profile,
       :hardware_profile_id => profile.id,
-- 
1.7.8.2


Mime
View raw message