incubator-deltacloud-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfoj...@redhat.com
Subject [PATCH core] RHEVM: Added user-data injection support based on fileinject VDSM hook
Date Mon, 29 Aug 2011 08:34:07 GMT
From: Michal Fojtik <mfojtik@redhat.com>


Signed-off-by: Michal fojtik <mfojtik@redhat.com>
---
 .../lib/deltacloud/drivers/rhevm/rhevm_client.rb   |   78 +++++++++++++++++++-
 .../lib/deltacloud/drivers/rhevm/rhevm_driver.rb   |    7 ++
 2 files changed, 84 insertions(+), 1 deletions(-)

diff --git a/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb b/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb
index 26bf471..ca8e3d9 100644
--- a/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb
+++ b/server/lib/deltacloud/drivers/rhevm/rhevm_client.rb
@@ -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
 
diff --git a/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb b/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb
index d402bc8..93ba4a5 100644
--- a/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb
+++ b/server/lib/deltacloud/drivers/rhevm/rhevm_driver.rb
@@ -37,6 +37,8 @@ class RHEVMDriver < Deltacloud::BaseDriver
     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::BaseDriver
       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
-- 
1.7.4.1


Mime
View raw message