You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltacloud.apache.org by mf...@apache.org on 2011/09/08 11:14:04 UTC

svn commit: r1166580 - in /incubator/deltacloud/trunk/server/lib/deltacloud/drivers/rhevm: rhevm_client.rb rhevm_driver.rb

Author: mfojtik
Date: Thu Sep  8 09:14:03 2011
New Revision: 1166580

URL: http://svn.apache.org/viewvc?rev=1166580&view=rev
Log:
RHEVM: Added user-data injection support based on fileinject VDSM hook

Modified:
    incubator/deltacloud/trunk/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb
    incubator/deltacloud/trunk/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb

Modified: incubator/deltacloud/trunk/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb?rev=1166580&r1=1166579&r2=1166580&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb (original)
+++ incubator/deltacloud/trunk/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb Thu Sep  8 09:14:03 2011
@@ -23,10 +23,27 @@ require 'json'
 
 module RHEVM
 
+  #
+  # NOTE: Change this if you want to use Windows machine to (/c/something)
+  #
+  FILEINJECT_PATH = "/tmp/deltacloud.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
@@ -66,6 +83,32 @@ module RHEVM
       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))
+      (result_xml/'/api/system_version').first[:major].strip == major
+    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 escape_user_data(data)
+      # Replace " with ' to keep quotes in XML attribute safe
+      data.gsub!(/"/, "'")
+      data
+    end
+
     def create_vm(template_id, opts={})
       opts ||= {}
       builder = Nokogiri::XML::Builder.new do
@@ -78,6 +121,30 @@ module RHEVM
           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')
+              #
+              # Clone is necessary to keep provisioning same as original template
+              # https://bugzilla.redhat.com/show_bug.cgi?id=733695
+              #
+              disks {
+                clone_ "true"
+              }
+              custom_properties {
+                #
+                # FIXME: 'regexp' parameter is just a temporary workaround. This
+                # is a reported and verified bug and should be fixed in next
+                # RHEV-M release.
+                #
+                custom_property({
+                  :name => "fileinject",
+                  :value => "#{RHEVM::FILEINJECT_PATH}:#{escape_user_data(Base64.decode64(opts[:user_data]))}",
+                  :regexp => "^.*:.*$"})
+              }
+            else
+              raise BackendVersionUnsupportedException.new
+            end
+          end
         }
       end
       headers = opts[:headers] || {}
@@ -86,7 +153,16 @@ module RHEVM
         :accept => 'application/xml',
       })
       headers.merge!(auth_header)
-      vm = RHEVM::client(@api_entrypoint)["/vms"].post(Nokogiri::XML(builder.to_xml).root.to_s, headers)
+      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
 

Modified: incubator/deltacloud/trunk/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb?rev=1166580&r1=1166579&r2=1166580&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb (original)
+++ incubator/deltacloud/trunk/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb Thu Sep  8 09:14:03 2011
@@ -37,6 +37,8 @@ class RHEVMDriver < Deltacloud::BaseDriv
     constraint :max_length, 50
   end
 
+  feature :instances, :user_data
+
   USER_NAME_MAX = feature(:instances, :user_name).constraints[:max_length]
 
   # FIXME: These values are just for ilustration
@@ -192,6 +194,11 @@ class RHEVMDriver < Deltacloud::BaseDriv
       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]
+        # NOTE: Injected data will be Base64 encoded to pass through XML
+        # attribute. You *need* to decode this file using a script inside guest.
+        params[:user_data] = opts[:user_data].gsub(/\n/,'')
+      end
       convert_instance(client, client.create_vm(image_id, params))
     end
   end