incubator-deltacloud-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michal Fojtik <mfoj...@redhat.com>
Subject Re: [PATCH core] Drivers now declare the capabilities they provide by implementing methods for each collection.
Date Fri, 10 Dec 2010 13:04:45 GMT
On 03/12/10 11:44 -0500, tcrawley@redhat.com wrote:
>From: Tobias Crawley <tcrawley@redhat.com>
>
>This patch makes the with_capability feature in rabbit actually work - before
>this, all drivers would appear to provide most capabilities, since the check
>was a simple respond_to?, and most capabilities were defined in the base_driver,
>and overridden by the drivers. With this change, those empty definitions are
>removed from the base_driver.
>
>The next step is to expose the available capabilities with the entry_points.
>I've started on that, but it introduces top level api changes, so I'll send
>a separate message to the list for discussion.

Works perfecly, applied cleanely on latest master. 
Our test suites are perfectly happy with that as well.
This is a great addition to API Tobi, thanks for this work.

ACK && push.

   -- Michal

>
>Toby
>
>---
> server/lib/deltacloud/backend_capability.rb      |   16 +++-
> server/lib/deltacloud/base_driver/base_driver.rb |  135 ++++++++++------------
> server/lib/deltacloud/base_driver/features.rb    |    6 +
> server/lib/deltacloud/drivers/ec2/ec2_driver.rb  |    4 -
> 4 files changed, 83 insertions(+), 78 deletions(-)
>
>diff --git a/server/lib/deltacloud/backend_capability.rb b/server/lib/deltacloud/backend_capability.rb
>index bec8714..5594550 100644
>--- a/server/lib/deltacloud/backend_capability.rb
>+++ b/server/lib/deltacloud/backend_capability.rb
>@@ -2,6 +2,7 @@ module Deltacloud::BackendCapability
>
>   class Failure < StandardError
>     attr_reader :capability
>+
>     def initialize(capability, msg='')
>       super(msg)
>       @capability = capability
>@@ -9,13 +10,26 @@ module Deltacloud::BackendCapability
>   end
>
>   attr_reader :capability
>+
>   def with_capability(capability)
>     @capability = capability
>   end
>
>+  def has_capability?(backend)
>+    !capability or backend.has_capability?(capability)
>+  end
>+
>   def check_capability(backend)
>-    if capability and !backend.respond_to?(capability)
>+    if !has_capability?(backend)
>       raise Failure.new(capability, "#{capability} capability not supported by backend
#{backend.class.name}")
>     end
>   end
>+
>+  module Helpers
>+    def operations_for_collection(collection)
>+      collections[collection].operations.values.select { |op| op.has_capability?(driver)
}
>+    end
>+  end
>+
>+  helpers Helpers
> end
>diff --git a/server/lib/deltacloud/base_driver/base_driver.rb b/server/lib/deltacloud/base_driver/base_driver.rb
>index 4419359..7815eb4 100644
>--- a/server/lib/deltacloud/base_driver/base_driver.rb
>+++ b/server/lib/deltacloud/base_driver/base_driver.rb
>@@ -42,7 +42,7 @@ module Deltacloud
>   end
>
>   class BaseDriver
>-
>+
>     def self.define_hardware_profile(name,&block)
>       @hardware_profiles ||= []
>       hw_profile = @hardware_profiles.find{|e| e.name == name}
>@@ -126,100 +126,90 @@ module Deltacloud
>       actions
>     end
>
>+    ## Capabilities
>+    # The rabbit dsl supports declaring a capability that is required
>+    # in the backend driver for the call to succeed. A driver can
>+    # provide a capability by implementing the method with the same
>+    # name as the capability. Below is a list of the capabilities as
>+    # the expected method signatures.
>+    #
>+    # Following the capability list are the resource member show
>+    # methods. They each require that the corresponding collection
>+    # method be defined
>+    #
>+    # TODO: standardize all of these to the same signature (credentials, opts)
>+    #
>+    # def realms(credentials, opts=nil)
>+    #
>+    # def images(credentials, ops)
>+    #
>+    # def instances(credentials, ops)
>+    # def create_instance(credentials, image_id, opts)
>+    # def start_instance(credentials, id)
>+    # def stop_instance(credentials, id)
>+    # def reboot_instance(credentials, id)
>+    #
>+    # def storage_volumes(credentials, ops)
>+    #
>+    # def storage_snapshots(credentials, ops)
>+    #
>+    # def buckets(credentials, opts = nil)
>+    # def create_bucket(credentials, name, opts=nil)
>+    # def delete_bucket(credentials, name, opts=nil)
>+    #
>+    # def blobs(credentials, opts = nil)
>+    # def blob_data(credentials, bucket_id, blob_id, opts)
>+    # def create_blob(credentials, bucket_id, blob_id, blob_data, opts=nil)
>+    # def delete_blob(credentials, bucket_id, blob_id, opts=nil)
>+    #
>+    # def keys(credentials, opts)
>+    # def create_key(credentials, opts)
>+    # def destroy_key(credentials, opts)
>+
>     def realm(credentials, opts)
>-      realms = realms(credentials, opts)
>-      return realms.first unless realms.empty?
>-      nil
>-    end
>-
>-    def realms(credentials, opts=nil)
>-      []
>+      realms = realms(credentials, opts).first if has_capability?(:realms)
>     end
>
>     def image(credentials, opts)
>-      images = images(credentials, opts)
>-      return images.first unless images.empty?
>-      nil
>-    end
>-
>-    def images(credentials, ops)
>-      []
>+      images(credentials, opts).first if has_capability?(:images)
>     end
>
>     def instance(credentials, opts)
>-      instances = instances(credentials, opts)
>-      return instances.first unless instances.empty?
>-      nil
>-    end
>-
>-    def instances(credentials, ops)
>-      []
>-    end
>-
>-    def create_instance(credentials, image_id, opts)
>-    end
>-    def start_instance(credentials, id)
>-    end
>-    def stop_instance(credentials, id)
>-    end
>-    def reboot_instance(credentials, id)
>+      instances(credentials, opts).first if has_capability?(:instances)
>     end
>
>     def storage_volume(credentials, opts)
>-      volumes = storage_volumes(credentials, opts)
>-      return volumes.first unless volumes.empty?
>-      nil
>-    end
>-
>-    def storage_volumes(credentials, ops)
>-      []
>+      storage_volumes(credentials, opts).first if has_capability?(:storage_volumes)
>     end
>
>     def storage_snapshot(credentials, opts)
>-      snapshots = storage_snapshots(credentials, opts)
>-      return snapshots.first unless snapshots.empty?
>-      nil
>-    end
>-
>-    def storage_snapshots(credentials, ops)
>-      []
>-    end
>-
>-    def buckets(credentials, opts = nil)
>-      #list of buckets belonging to account
>-      []
>+      storage_snapshots(credentials, opts).first if has_capability?(:storage_snapshots)
>     end
>
>     def bucket(credentials, opts = nil)
>-    #list of objects within bucket
>-      list = buckets(credentials, opts)
>-      return list.first unless list.empty?
>-      nil
>-    end
>-
>-    def create_bucket(credentials, name, opts=nil)
>-    end
>-
>-    def delete_bucket(credentials, name, opts=nil)
>+      #list of objects within bucket
>+      buckets(credentials, opts).first if has_capability?(:buckets)
>     end
>-
>-    def blobs(credentials, opts = nil)
>-      []
>-    end
>-
>+
>     def blob(credentials, opts = nil)
>-       list = blobs(credentials, opts)
>-       return list.first unless list.empty?
>+      blobs(credentials, opts).first if has_capability?(:blobs)
>     end
>
>-    def blob_data(credentials, bucket_id, blob_id, opts)
>+    def key(credentials, opts=nil)
>+      keys(credentials, opts).first if has_capability?(:keys)
>     end
>
>-    def create_blob(credentials, bucket_id, blob_id, blob_data, opts=nil)
>-    end
>+    MEMBER_SHOW_METHODS =
>+      [ :realm, :image, :instance, :storage_volume, :bucket, :blob, :key ]
>
>-    def delete_blob(credentials, bucket_id, blob_id, opts=nil)
>+    def has_capability?(capability)
>+      if MEMBER_SHOW_METHODS.include?(capability.to_sym)
>+        has_capability?(capability.to_s.pluralize)
>+      else
>+        respond_to?(capability)
>+      end
>     end
>+
>
>     def filter_on(collection, attribute, opts)
>       return collection if opts.nil?
>@@ -237,8 +227,7 @@ module Deltacloud
>     end
>
>     def has_collection?(collection)
>-      return true if self.supported_collections.include?(collection)
>-      return false
>+      supported_collections.include?(collection)
>     end
>
>     def catched_exceptions_list
>diff --git a/server/lib/deltacloud/base_driver/features.rb b/server/lib/deltacloud/base_driver/features.rb
>index de055de..f20f635 100644
>--- a/server/lib/deltacloud/base_driver/features.rb
>+++ b/server/lib/deltacloud/base_driver/features.rb
>@@ -117,6 +117,12 @@ module Deltacloud
>       self.class.features[collection] || []
>     end
>
>+    def features_for_operation(collection, operation)
>+      features(collection).select do |f|
>+        f.operations.detect { |o| o.name == operation }
>+      end
>+    end
>+
>     #
>     # Declaration of optional features
>     #
>diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
>index d38f8f7..9fc0726 100644
>--- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
>+++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
>@@ -284,10 +284,6 @@ class EC2Driver < Deltacloud::BaseDriver
>     snapshots
>   end
>
>-  def key(credentials, opts=nil)
>-    keys(credentials, opts).first
>-  end
>-
>   def keys(credentials, opts=nil)
>     ec2 = new_client( credentials )
>     opts[:key_name] = opts[:id] if opts and opts[:id]
>--
>1.7.3.2
>

-- 
--------------------------------------------------------
Michal Fojtik, mfojtik@redhat.com
Deltacloud API: http://deltacloud.org
--------------------------------------------------------

Mime
View raw message