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 2010/12/10 14:05:27 UTC

svn commit: r1044338 - in /incubator/deltacloud/trunk/server/lib/deltacloud: backend_capability.rb base_driver/base_driver.rb base_driver/features.rb drivers/ec2/ec2_driver.rb

Author: mfojtik
Date: Fri Dec 10 13:05:26 2010
New Revision: 1044338

URL: http://svn.apache.org/viewvc?rev=1044338&view=rev
Log:
Drivers now declare the capabilities they provide by implementing methods for each collection.

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.

Toby

Modified:
    incubator/deltacloud/trunk/server/lib/deltacloud/backend_capability.rb
    incubator/deltacloud/trunk/server/lib/deltacloud/base_driver/base_driver.rb
    incubator/deltacloud/trunk/server/lib/deltacloud/base_driver/features.rb
    incubator/deltacloud/trunk/server/lib/deltacloud/drivers/ec2/ec2_driver.rb

Modified: incubator/deltacloud/trunk/server/lib/deltacloud/backend_capability.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/lib/deltacloud/backend_capability.rb?rev=1044338&r1=1044337&r2=1044338&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/lib/deltacloud/backend_capability.rb (original)
+++ incubator/deltacloud/trunk/server/lib/deltacloud/backend_capability.rb Fri Dec 10 13:05:26 2010
@@ -20,6 +20,7 @@ module Deltacloud::BackendCapability
 
   class Failure < StandardError
     attr_reader :capability
+    
     def initialize(capability, msg='')
       super(msg)
       @capability = capability
@@ -27,13 +28,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

Modified: incubator/deltacloud/trunk/server/lib/deltacloud/base_driver/base_driver.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/lib/deltacloud/base_driver/base_driver.rb?rev=1044338&r1=1044337&r2=1044338&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/lib/deltacloud/base_driver/base_driver.rb (original)
+++ incubator/deltacloud/trunk/server/lib/deltacloud/base_driver/base_driver.rb Fri Dec 10 13:05:26 2010
@@ -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

Modified: incubator/deltacloud/trunk/server/lib/deltacloud/base_driver/features.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/lib/deltacloud/base_driver/features.rb?rev=1044338&r1=1044337&r2=1044338&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/lib/deltacloud/base_driver/features.rb (original)
+++ incubator/deltacloud/trunk/server/lib/deltacloud/base_driver/features.rb Fri Dec 10 13:05:26 2010
@@ -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
     #

Modified: incubator/deltacloud/trunk/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/lib/deltacloud/drivers/ec2/ec2_driver.rb?rev=1044338&r1=1044337&r2=1044338&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/lib/deltacloud/drivers/ec2/ec2_driver.rb (original)
+++ incubator/deltacloud/trunk/server/lib/deltacloud/drivers/ec2/ec2_driver.rb Fri Dec 10 13:05:26 2010
@@ -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]