You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by mf...@redhat.com on 2012/03/20 12:23:46 UTC

[PATCH core 1/4] VSphere: The 'ToolsUnavailable' exception is now reported as backend error

From: Michal Fojtik <mf...@redhat.com>

Previously the ToolsUnavailable exception from VSPhere was
reported as error 500 (Internal Server Error), which isn't correct.
This exception is caused by lack of VMWare tools in machine. These
tools are required for the 'reboot' operation.
The exception is now reported as error 502 (Backend Error).
Appropriate error message is being passed to the client in XML

Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 .../deltacloud/drivers/vsphere/vsphere_driver.rb   |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb b/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
index cbcaa22..fdacc10 100644
--- a/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
+++ b/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
@@ -363,7 +363,7 @@ module Deltacloud::Drivers::VSphere
         status 500
       end
 
-      on /RbVmomi::Fault/ do
+      on /(RbVmomi::Fault|ToolsUnavailable)/ do
         status 502
       end
 
-- 
1.7.9.1


[PATCH core 4/4] Core: Code cleanup in ApplicationHelper

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>

This patch will clean method that are not longer used in
any view or code in server.rb.
Also this patch move the string helper 'truncate_words' to
String core class.

Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/lib/deltacloud/core_ext/string.rb           |    7 ++
 .../lib/deltacloud/helpers/application_helper.rb   |   81 ++++---------------
 server/views/buckets/new.html.haml                 |    4 +-
 server/views/instances/index.html.haml             |    2 +-
 4 files changed, 27 insertions(+), 67 deletions(-)

diff --git a/server/lib/deltacloud/core_ext/string.rb b/server/lib/deltacloud/core_ext/string.rb
index c0dce7b..6c04282 100644
--- a/server/lib/deltacloud/core_ext/string.rb
+++ b/server/lib/deltacloud/core_ext/string.rb
@@ -65,4 +65,11 @@ class String
   def upcase_first
     self[0, 1].upcase + self[1..-1]
   end
+
+  def truncate(length = 10)
+    return self if self.length <= length
+    end_string = "...#{self[(self.length-(length/2))..self.length]}"
+    "#{self[0..(length/2)]}#{end_string}"
+  end
+
 end
diff --git a/server/lib/deltacloud/helpers/application_helper.rb b/server/lib/deltacloud/helpers/application_helper.rb
index bdcbd73..7a0d58b 100644
--- a/server/lib/deltacloud/helpers/application_helper.rb
+++ b/server/lib/deltacloud/helpers/application_helper.rb
@@ -21,25 +21,6 @@ module ApplicationHelper
 
   include Deltacloud
 
-  def bread_crumb
-    s = "<ul class='breadcrumb'><li class='first'><a href='#{settings.root_url}'>&#948</a></li>"
-    url = request.path_info.split('?')  #remove extra query string parameters
-    levels = url[0].split('/') #break up url into different levels
-    levels.each_with_index do |level, index|
-      unless level.blank?
-        next if "/#{level}" == settings.root_url
-        if index == levels.size-1 || (level == levels[levels.size-2] && levels[levels.size-1].to_i > 0)
-          s += "<li class='subsequent'>#{level.gsub(/_/, ' ')}</li>\n" unless level.to_i > 0
-        else
-          link = levels.slice(2, index-1).join("/")
-          s += "<li class='subsequent'><a href=\"#{api_url_for(link)}\">#{level.gsub(/_/, ' ')}</a></li>\n"
-        end
-      end
-    end
-    s+="<li class='docs'>#{link_to_documentation}</li>"
-    s+="</ul>"
-  end
-
   def instance_action_method(action)
     action_method(action, :instances)
   end
@@ -49,7 +30,7 @@ module ApplicationHelper
   end
 
   def driver_has_feature?(feature_name, collection_name = :instances)
-    not driver.features(collection_name).select{ |f| f.name.eql?(feature_name) }.empty?
+    driver.features(collection_name).any? { |f| f.name == feature_name }
   end
 
   def driver_has_auth_features?
@@ -57,15 +38,8 @@ module ApplicationHelper
   end
 
   def driver_auth_feature_name
-    return 'key' if driver_has_feature?(:authentication_key)
-    return 'password' if driver_has_feature?(:authentication_password)
-  end
-
-  def driver_has_bucket_location_feature?
-    driver.features(:buckets).each do |feat|
-      return true if feat.name == :bucket_location
-    end
-    false
+    'key' if driver_has_feature?(:authentication_key)
+    'password' if driver_has_feature?(:authentication_password)
   end
 
   def filter_all(model)
@@ -133,7 +107,11 @@ module ApplicationHelper
       return report_error(405)
     end
 
-    @instance = driver.send(:"#{name}_instance", credentials, params[:id])
+    @benchmark = Benchmark.measure do
+      @instance = driver.send(:"#{name}_instance", credentials, params[:id])
+    end
+
+    headers['X-Backend-Runtime'] = @benchmark.real.to_s
 
     if name == :reboot
       status 202
@@ -180,47 +158,22 @@ module ApplicationHelper
   end
 
   def link_to_format(format)
-    return '' unless request.env['REQUEST_URI']
+    return unless request.env['REQUEST_URI']
     uri = request.env['REQUEST_URI']
     return if uri.include?('format=')
-    if uri.include?('?')
-      uri+="&format=#{format}"
-    else
-      uri+="?format=#{format}"
-    end
-    '<a data-ajax="false" data-icon="grid" href="%s">%s</a>' % [uri, "#{format}".upcase]
-  end
-
-  def link_to_documentation
-    return '' unless request.env['REQUEST_URI']
-    uri = request.env['REQUEST_URI'].dup
-    uri.gsub!(settings.root_url,
-              api_url_for(:docs)) unless uri.include?("docs") #i.e. if already serving under /api/docs, leave it be
-    '<a href="%s">[ Documentation ]</a>' % uri
-  end
-
-  def action_url
-    if [:index].include?(@operation.name)
-      api_url_for("#{@collection.name.to_s}")
-    elsif [:show, :stop, :start, :reboot, :attach, :detach].include?(@operation.name)
-      api_url_for("#{@collection.name.to_s}/:id/#{@operation.name}")
-    elsif [:destroy].include?(@operation.name)
-      api_url_for("#{@collection.name.to_s}/:id")
-    else
-      api_url_for("#{@collection.name}/#{@operation.name}")
+    uri += uri.include?('?') ? "&format=#{format}" : "?format=#{format}"
+    capture_haml do
+      haml_tag :a, :href => uri, :'data-ajax' => 'false', :'data-icon' => 'grid' do
+        haml_concat format.to_s.upcase
+      end
     end
   end
 
   def image_for_state(state)
     state_img = "stopped" if (state!='RUNNING' or state!='PENDING')
-    "<img src='/images/#{state.downcase}.png' title='#{state}'/>"
-  end
-
-  def truncate_words(text, length = 10)
-    return nil unless text
-    return text if text.length<=length
-    end_string = "...#{text[(text.length-(length/2))..text.length]}"
-    "#{text[0..(length/2)]}#{end_string}"
+    capture_haml do
+      haml_tag :img, :src => "/images/#{state}" % state.downcase, :title => state
+    end
   end
 
   # Reverse the entrypoints hash for a driver from drivers.yaml; note that
diff --git a/server/views/buckets/new.html.haml b/server/views/buckets/new.html.haml
index e53b7ea..2abaa96 100644
--- a/server/views/buckets/new.html.haml
+++ b/server/views/buckets/new.html.haml
@@ -1,12 +1,12 @@
 =header "New bucket"
 
 %div{ :'data-role' => :content, :'data-theme' => 'c', :class => 'middle-dialog'}
-  %form{ :action => buckets_url, :method => :post }
+  %form{ :action => buckets_url, :method => :post, :'data-ajax' => 'false' }
     %label
       Bucket Name:
       %input{ :name => 'name', :size => 250}/
       %br
-    -if driver_has_bucket_location_feature?
+    -if driver_has_feature?(:bucket_location, :buckets)
       %p
         %label
           Location: (optional)
diff --git a/server/views/instances/index.html.haml b/server/views/instances/index.html.haml
index dc42a7d..f7efee2 100644
--- a/server/views/instances/index.html.haml
+++ b/server/views/instances/index.html.haml
@@ -8,7 +8,7 @@
       %li
         %a{ :href => instance_url(instance.id), :'data-ajax' => 'false'}
           %img{ :class => 'ui-link-thumb', :src => '/images/machine.png'}
-          %h3=truncate_words(instance.id)
+          %h3=instance.id.to_s.truncate
           %p
             %strong=instance.name
           %p=[instance.owner_id, instance.image_id, instance.hardware_profile].join(', ')
-- 
1.7.9.1


[PATCH core 3/4] Core: Updated unit tests to reflect reboot operation code

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>

Mock unit tests updated to expect 202 code instead of 200.
Also removed non-authenticated routes, which are now under
authentication.

Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/tests/drivers/mock/instance_states_test.rb |    4 ----
 server/tests/drivers/mock/instances_test.rb       |    2 +-
 server/tests/drivers/mock/realms_test.rb          |    4 ----
 3 files changed, 1 insertions(+), 9 deletions(-)

diff --git a/server/tests/drivers/mock/instance_states_test.rb b/server/tests/drivers/mock/instance_states_test.rb
index d145975..905cff3 100644
--- a/server/tests/drivers/mock/instance_states_test.rb
+++ b/server/tests/drivers/mock/instance_states_test.rb
@@ -25,10 +25,6 @@ module DeltacloudUnitTest
       Sinatra::Application
     end
 
-    def test_it_not_require_authentication
-      require_authentication?('/api/realms').should_not == true
-    end
-
     def test_it_returns_instance_states
       get_auth_url '/api/instance_states', {}
       (last_xml_response/'states/state').length.should > 0
diff --git a/server/tests/drivers/mock/instances_test.rb b/server/tests/drivers/mock/instances_test.rb
index a44ba22..45bb4b8 100644
--- a/server/tests/drivers/mock/instances_test.rb
+++ b/server/tests/drivers/mock/instances_test.rb
@@ -167,7 +167,7 @@ module DeltacloudUnitTest
         reboot_url = (last_xml_response/'actions/link[@rel="reboot"]').first['href']
         reboot_url.should_not == nil
         post_url reboot_url
-        last_response.status.should == 200
+        last_response.status.should == 202
         instance = Nokogiri::XML(last_response.body)
         test_instance_attributes(instance)
         (instance/'state').text.should == 'RUNNING'
diff --git a/server/tests/drivers/mock/realms_test.rb b/server/tests/drivers/mock/realms_test.rb
index 0fa50f4..b0db9e4 100644
--- a/server/tests/drivers/mock/realms_test.rb
+++ b/server/tests/drivers/mock/realms_test.rb
@@ -25,10 +25,6 @@ module DeltacloudUnitTest
       Sinatra::Application
     end
 
-    def test_it_not_require_authentication
-      require_authentication?('/api/realms').should_not == true
-    end
-
     def test_it_returns_realms
       get_auth_url '/api/realms', {}
       (last_xml_response/'realms/realm').length.should > 0
-- 
1.7.9.1


Re: [PATCH core 1/4] VSphere: The 'ToolsUnavailable' exception is now reported as backend error

Posted by "marios@redhat.com" <ma...@redhat.com>.
ack series

On 20/03/12 13:23, mfojtik@redhat.com wrote:
> From: Michal Fojtik <mf...@redhat.com>
> 
> Previously the ToolsUnavailable exception from VSPhere was
> reported as error 500 (Internal Server Error), which isn't correct.
> This exception is caused by lack of VMWare tools in machine. These
> tools are required for the 'reboot' operation.
> The exception is now reported as error 502 (Backend Error).
> Appropriate error message is being passed to the client in XML
> 
> Signed-off-by: Michal fojtik <mf...@redhat.com>
> ---
>  .../deltacloud/drivers/vsphere/vsphere_driver.rb   |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb b/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
> index cbcaa22..fdacc10 100644
> --- a/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
> +++ b/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
> @@ -363,7 +363,7 @@ module Deltacloud::Drivers::VSphere
>          status 500
>        end
>  
> -      on /RbVmomi::Fault/ do
> +      on /(RbVmomi::Fault|ToolsUnavailable)/ do
>          status 502
>        end
>  


[PATCH core 2/4] Core: Report HTTP status 202 after reboot operation (DTACLOUD-162)

Posted by mf...@redhat.com.
From: Michal Fojtik <mf...@redhat.com>

Previously the 'reboot' operation returns various response codes for different
drivers. The code '204' (No Content) was returned for VSphere because the
'reboot' operation does not return full instance object.  However for EC2 it
returns '200' (OK) because in this driver the reboot operation returns full
instance object.

Now all 'reboot' operations in all drivers should return the code 202 (Accepted),
because the operation does not finish and the reboot operation is statefull.
If driver support retrieval of instance object after reboot, the full instance
body is returned, otherwise the Location header will point client to updated
instance.

Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 .../lib/deltacloud/helpers/application_helper.rb   |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/server/lib/deltacloud/helpers/application_helper.rb b/server/lib/deltacloud/helpers/application_helper.rb
index e368103..bdcbd73 100644
--- a/server/lib/deltacloud/helpers/application_helper.rb
+++ b/server/lib/deltacloud/helpers/application_helper.rb
@@ -133,9 +133,13 @@ module ApplicationHelper
       return report_error(405)
     end
 
-    @instance = driver.send(:"#{name}_instance", credentials, params["id"])
+    @instance = driver.send(:"#{name}_instance", credentials, params[:id])
 
-    if name == :destroy or @instance.class!=Instance
+    if name == :reboot
+      status 202
+    end
+
+    if name == :destroy
       respond_to do |format|
         format.xml { return 204 }
         format.json { return 204 }
@@ -143,6 +147,11 @@ module ApplicationHelper
       end
     end
 
+    if @instance.class != Instance
+      response['Location'] = instance_url(params[:id])
+      halt
+    end
+
     respond_to do |format|
       format.xml { haml :"instances/show" }
       format.html { haml :"instances/show" }
-- 
1.7.9.1