You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by ma...@redhat.com on 2012/06/11 12:09:55 UTC

[PATCH 1/2] Adds buckets/blobs collection to openstack driver

From: marios <ma...@redhat.com>


Signed-off-by: marios <ma...@redhat.com>
---
 .../drivers/openstack/openstack_driver.rb          |  116 ++++++++++++++++++--
 1 files changed, 104 insertions(+), 12 deletions(-)

diff --git a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
index 7c5125c..91624f5 100644
--- a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
+++ b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
@@ -179,49 +179,116 @@ module Deltacloud
         end
 
         def buckets(credentials, opts={})
-
+          os = new_client(credentials, :buckets)
+          buckets = []
+          safely do
+            if opts[:id]
+              buckets << convert_bucket(os.container(opts[:id]))
+            else
+              os.containers.each{|bucket_name| buckets << convert_bucket(os.container(bucket_name))}
+            end
+          end
+          buckets
         end
 
         def create_bucket(credentials, name, opts={})
-
+          os = new_client(credentials, :buckets)
+          bucket = nil
+          safely do
+            bucket = os.create_container(name)
+          end
+          convert_bucket(bucket)
         end
 
         def delete_bucket(credentials, name, opts={})
-
+          os = new_client(credentials, :buckets)
+          safely do
+            os.delete_container(name)
+          end
         end
 
         def blobs(credentials, opts={})
-
+          os = new_client(credentials, :buckets)
+          blobs = []
+          safely do
+            bucket = os.container(opts['bucket'])
+            if(opts[:id])
+              blobs << convert_blob(bucket.object(opts[:id]), opts['bucket'])
+            else
+              bucket.objects_detail.each{|blob| blobs << convert_blob(blob, opts['bucket'])}
+            end
+          end
+          blobs
         end
 
         def blob_data(credentials, bucket, blob, opts={})
-
+          os = new_client(credentials, :buckets)
+          safely do
+            os.container(bucket).object(blob).data_stream do |chunk|
+              yield chunk
+            end
+          end
         end
 
         def create_blob(credentials, bucket, blob, data, opts={})
-
+          os = new_client(credentials, :buckets)
+          safely do
+            BlobHelper.rename_metadata_headers(opts, "X-Object-Meta-")
+            os_blob = os.container(bucket).create_object(blob, {:content_type=> data[:type], :metadata=>opts}, data[:tempfile])
+            convert_blob(os_blob, bucket)
+          end
         end
 
         def delete_blob(credentials, bucket, blob, opts={})
-
+          os = new_client(credentials, :buckets)
+          safely do
+            os.container(bucket).delete_object(blob)
+          end
         end
 
         def blob_metadata(credentials, opts={})
-
+          os = new_client(credentials, :buckets)
+          safely do
+            os.container(opts['bucket']).object(opts[:id]).metadata
+          end
         end
 
         def update_blob_metadata(credentials, opts={})
-
+          os = new_client(credentials, :buckets)
+          safely do
+            BlobHelper.rename_metadata_headers(opts["meta_hash"], "")
+            blob = os.container(opts['bucket']).object(opts[:id])
+            blob.set_metadata(opts['meta_hash'])
+          end
         end
 
+        #params: {:user,:password,:bucket,:blob,:content_type,:content_length,:metadata}
         def blob_stream_connection(params)
-
+          tokens = params[:user].split("+")
+          user_name, tenant_name = tokens.first, tokens.last
+          #need a client for the auth_token and endpoints
+          os = OpenStack::Connection.create(:username => user_name, :api_key => params[:password], :authtenant => tenant_name, :auth_url => api_provider, :service_type => "object-store")
+          http = Net::HTTP.new(os.connection.service_host, os.connection.service_port)
+          http.use_ssl = true
+          http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+          path = os.connection.service_path + URI.encode("/#{params[:bucket]}/#{params[:blob]}")
+          request = Net::HTTP::Put.new(path)
+          request['X-Auth-Token'] = os.connection.authtoken
+          request['X-Storage-Token'] = os.connection.authtoken
+          request['Connection'] = "Keep-Alive"
+          request['Content-Type'] = params[:content_type]
+          request['Content-Length'] = params[:content_length]
+          request['Expect'] = "100-continue"
+          metadata = params[:metadata] || {}
+          BlobHelper::rename_metadata_headers(metadata, 'X-Object-Meta-')
+          metadata.each{|k,v| request[k] = v}
+          return http, request
         end
 
 private
 
         #for v2 authentication credentials.name == "username+tenant_name"
-        def new_client(credentials, buckets=false)
+        def new_client(credentials, type = :compute)
           tokens = credentials.user.split("+")
           if (tokens.size != 2 && api_v2)
             raise ValidationFailure.new(Exception.new("Error: expected \"username+tenantname\" as username, you provided: #{credentials.user}"))
@@ -229,7 +296,15 @@ private
             user_name, tenant_name = tokens.first, tokens.last
           end
           safely do
-              OpenStack::Connection.create(:username => user_name, :api_key => credentials.password, :authtenant => tenant_name, :auth_url => api_provider)
+              case type
+                when :compute
+                  OpenStack::Connection.create(:username => user_name, :api_key => credentials.password, :authtenant => tenant_name, :auth_url => api_provider)
+                when :buckets
+                  OpenStack::Connection.create(:username => user_name, :api_key => credentials.password, :authtenant => tenant_name, :auth_url => api_provider, :service_type => "object-store")
+                else
+                  raise ValidationFailure.new(Exception.new("Error: tried to initialise Openstack connection using" +
+                    " an unknown service_type: #{type}"))
+              end
           end
         end
 
@@ -319,6 +394,23 @@ private
           end
         end
 
+        def convert_bucket(bucket)
+          Bucket.new({ :id => bucket.name,
+                       :name => bucket.name,
+                       :size => bucket.count,
+                       :blob_list => bucket.objects })
+        end
+
+        def convert_blob(blob, bucket_name)
+          op, blob_meta = (blob.class == Hash)? [:fetch, {}] : [:send, blob.metadata]
+          Blob.new({   :id => blob.send(op, :name),
+                       :bucket => bucket_name,
+                       :content_length => blob.send(op, :bytes),
+                       :content_type => blob.send(op, :content_type),
+                       :last_modified => blob.send(op, :last_modified),
+                       :user_metadata => blob_meta })
+        end
+
         #IN: path1='server_path1'. content1='contents1', path2='server_path2', content2='contents2' etc
         #OUT:{local_path=>server_path, local_path1=>server_path2 etc}
         def extract_personality(opts)
-- 
1.7.6.5


Re: [PATCH 2/2] Fixes for blob streaming support - bugs/nits brought over with modular deltacloud

Posted by Ronelle Landy <rl...@redhat.com>.
QE ACK ... works for ec2 provider

Applied patch over deltacloud git commit a6876a9675847af85ba0290c081479903fbb8367.

Test output below (using curl for demo):

>>  curl -H 'content-type: text/html' -H 'X-Deltacloud-Blobmeta-Name:myblob' -H 'X-Deltacloud-Blobmeta-Version:2.4' -H 'X-Deltacloud-Blobmeta-Author:rlandy' -iv --upload-file "/home/rlandy/Temp/rhel62rhevm.xml" --user "AKIAJCBB265A57CGKR2Q:mRqPo4C566epOauIxO4faFsOdeTyus7oOVdHKgw5" "http://qe-blade-02.idm.lab.bos.redhat.com:3006/api/buckets/bucket-rlandy/newblob?format=xml"
* About to connect() to qe-blade-02.idm.lab.bos.redhat.com port 3006 (#0)
*   Trying 10.16.76.33... Connection refused
* couldn't connect to host
* Closing connection #0
curl: (7) couldn't connect to host
[rlandy@localhost /]$ curl -H 'content-type: text/html' -H 'X-Deltacloud-Blobmeta-Name:myblob' -H 'X-Deltacloud-Blobmeta-Version:2.4' -H 'X-Deltacloud-Blobmeta-Author:rlandy' -iv --upload-file "/home/rlandy/Temp/rhel62rhevm.xml" --user "un:pw" "http://localhost:3008/api/buckets/bucket-rlandy/newblob?format=xml"
* About to connect() to localhost port 3008 (#0)
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 3008 (#0)
* Server auth using Basic with user 'x'
> PUT /api/buckets/bucket-rlandy/newblob?format=xml HTTP/1.1
> Authorization: Basic x==
> User-Agent: curl/7.21.7 (x86_64-redhat-linux-gnu) libcurl/7.21.7 NSS/3.13.1.0 zlib/1.2.5 libidn/1.22 libssh2/1.2.7
> Host: localhost:3008
> Accept: */*
> content-type: text/html
> X-Deltacloud-Blobmeta-Name:myblob
> X-Deltacloud-Blobmeta-Version:2.4
> X-Deltacloud-Blobmeta-Author:rlandy
> Content-Length: 931
> Expect: 100-continue
> 
* Done waiting for 100-continue
* We are completely uploaded and fine
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: Apache-Deltacloud/0.5.0
Server: Apache-Deltacloud/0.5.0
< Cache-Control: max-age=0, private, must-revalidate
Cache-Control: max-age=0, private, must-revalidate
< Content-Length: 645
Content-Length: 645
< Date: Tue, 12 Jun 2012 13:58:55 GMT
Date: Tue, 12 Jun 2012 13:58:55 GMT
< X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; mode=block
< Content-Type: application/xml
Content-Type: application/xml
< X-Frame-Options: sameorigin
X-Frame-Options: sameorigin
< ETag: "x"
ETag: "x"
< Connection: keep-alive
Connection: keep-alive

< 
<?xml version='1.0' encoding='utf-8' ?>
<blob href='http://localhost:3008/api/buckets/bucket-rlandy/newblob' id='newblob'>
  <bucket>bucket-rlandy</bucket>
  <content_length>931</content_length>
  <content_type>text/html</content_type>
  <last_modified></last_modified>
  <user_metadata>
    <entry key='x-amz-meta-name'>
      <![CDATA[myblob]]>
    </entry>
    <entry key='x-amz-meta-version'>
      <![CDATA[2.4]]>
    </entry>
    <entry key='x-amz-meta-author'>
      <![CDATA[rlandy]]>
    </entry>
  </user_metadata>
  <content href='http://localhost:3008/api/buckets/bucket-rlandy/newblob/content' rel='blob_content'></content>
</blob>
* Connection #0 to host localhost left intact
* Closing connection #0




----- Original Message -----
> From: marios@redhat.com
> To: dev@deltacloud.apache.org
> Sent: Monday, June 11, 2012 6:09:56 AM
> Subject: [PATCH 2/2] Fixes for blob streaming support - bugs/nits brought over with modular deltacloud
> 
> From: marios <ma...@redhat.com>
> 
> 
> Signed-off-by: marios <ma...@redhat.com>
> ---
>  server/lib/deltacloud/collections/buckets.rb       |   38
>  +++++++++++++++++++-
>  .../lib/deltacloud/helpers/blob_stream_helper.rb   |    3 +-
>  2 files changed, 38 insertions(+), 3 deletions(-)
> 
> diff --git a/server/lib/deltacloud/collections/buckets.rb
> b/server/lib/deltacloud/collections/buckets.rb
> index 355d4d0..9a8698f 100644
> --- a/server/lib/deltacloud/collections/buckets.rb
> +++ b/server/lib/deltacloud/collections/buckets.rb
> @@ -48,6 +48,40 @@ module Deltacloud::Collections
>        end
>      end
>  
> +    put route_for ("/buckets/:bucket/:blob") do
> +      if(env["BLOB_SUCCESS"]) #ie got a 200ok after putting blob
> +        content_type = env["CONTENT_TYPE"]
> +        content_type ||=  ""
> +        @blob = driver.blob(credentials, {:id => params[:blob],
> +                                          'bucket' =>
> params[:bucket]})
> +        respond_to do |format|
> +          format.xml { haml :"blobs/show" }
> +          format.html { haml :"blobs/show" }
> +          format.json { convert_to_json(:blob, @blob) }
> +        end
> +      elsif(env["BLOB_FAIL"])
> +        report_error(500) #OK?
> +      else # small blobs - < 112kb dont hit the streaming monkey
> patch - use 'normal' create_blob
> +        # also, if running under webrick don't hit the streaming
> patch (Thin specific)
> +        bucket_id = params[:bucket]
> +        blob_id = params[:blob]
> +        temp_file = Tempfile.new("temp_blob_file")
> +        temp_file.write(env['rack.input'].read)
> +        temp_file.flush
> +        content_type = env['CONTENT_TYPE'] || ""
> +        blob_data = {:tempfile => temp_file, :type => content_type}
> +        user_meta =
> BlobHelper::extract_blob_metadata_hash(request.env)
> +        @blob = driver.create_blob(credentials, bucket_id, blob_id,
> blob_data, user_meta)
> +        temp_file.delete
> +        respond_to do |format|
> +          format.xml { haml :"blobs/show" }
> +          format.html { haml :"blobs/show" }
> +          format.json { convert_to_json(:blob, @blob) }
> +        end
> +      end
> +    end
> +
> +
>      collection :buckets do
>  
>        standard_show_operation
> @@ -142,9 +176,11 @@ module Deltacloud::Collections
>            end
>          end
>  
> +require 'ruby-debug'
>          action :stream, :http_method => :put, :with_capability =>
>          :create_blob do
>            description "Stream new blob data into the blob"
>            control do
> +debugger
>              if(env["BLOB_SUCCESS"]) #ie got a 200ok after putting
>              blob
>                content_type = env["CONTENT_TYPE"]
>                content_type ||=  ""
> @@ -201,7 +237,7 @@ module Deltacloud::Collections
>            control do
>              meta_hash =
>              BlobHelper::extract_blob_metadata_hash(request.env)
>              success = driver.update_blob_metadata(credentials,
>              {'bucket'=>params[:id], :id =>params[:blob_id],
>              'meta_hash' => meta_hash})
> -            if(success)
> +           if(success)
>                meta_hash.each do |k,v|
>                  headers["X-Deltacloud-Blobmeta-#{k}"] = v
>                end
> diff --git a/server/lib/deltacloud/helpers/blob_stream_helper.rb
> b/server/lib/deltacloud/helpers/blob_stream_helper.rb
> index 08cafe2..8567543 100644
> --- a/server/lib/deltacloud/helpers/blob_stream_helper.rb
> +++ b/server/lib/deltacloud/helpers/blob_stream_helper.rb
> @@ -149,7 +149,6 @@ require 'base64'
>  class BlobStreamIO
>  
>    attr_accessor :size, :provider, :sock
> -
>    def initialize(request)
>      @client_request = request
>      @size = 0
> @@ -159,7 +158,7 @@ class BlobStreamIO
>      #deal with blob_metadata: (X-Deltacloud-Blobmeta-name: value)
>      user_meta = BlobHelper::extract_blob_metadata_hash(request.env)
>      @content_length = request.env['CONTENT_LENGTH']
> -    @http, provider_request =
> driver.blob_stream_connection({:user=>user,
> +    @http, provider_request =
> Deltacloud::API.driver.blob_stream_connection({:user=>user,
>         :password=>password, :bucket=>bucket, :blob=>blob,
>         :metadata=> user_meta,
>         :content_type=>content_type, :content_length=>@content_length
>         })
>      @content_length = @content_length.to_i #for comparison of size
>      in '<< (data)'
> --
> 1.7.6.5
> 
> 

[PATCH 2/2] Fixes for blob streaming support - bugs/nits brought over with modular deltacloud

Posted by ma...@redhat.com.
From: marios <ma...@redhat.com>


Signed-off-by: marios <ma...@redhat.com>
---
 server/lib/deltacloud/collections/buckets.rb       |   38 +++++++++++++++++++-
 .../lib/deltacloud/helpers/blob_stream_helper.rb   |    3 +-
 2 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/server/lib/deltacloud/collections/buckets.rb b/server/lib/deltacloud/collections/buckets.rb
index 355d4d0..9a8698f 100644
--- a/server/lib/deltacloud/collections/buckets.rb
+++ b/server/lib/deltacloud/collections/buckets.rb
@@ -48,6 +48,40 @@ module Deltacloud::Collections
       end
     end
 
+    put route_for ("/buckets/:bucket/:blob") do
+      if(env["BLOB_SUCCESS"]) #ie got a 200ok after putting blob
+        content_type = env["CONTENT_TYPE"]
+        content_type ||=  ""
+        @blob = driver.blob(credentials, {:id => params[:blob],
+                                          'bucket' => params[:bucket]})
+        respond_to do |format|
+          format.xml { haml :"blobs/show" }
+          format.html { haml :"blobs/show" }
+          format.json { convert_to_json(:blob, @blob) }
+        end
+      elsif(env["BLOB_FAIL"])
+        report_error(500) #OK?
+      else # small blobs - < 112kb dont hit the streaming monkey patch - use 'normal' create_blob
+        # also, if running under webrick don't hit the streaming patch (Thin specific)
+        bucket_id = params[:bucket]
+        blob_id = params[:blob]
+        temp_file = Tempfile.new("temp_blob_file")
+        temp_file.write(env['rack.input'].read)
+        temp_file.flush
+        content_type = env['CONTENT_TYPE'] || ""
+        blob_data = {:tempfile => temp_file, :type => content_type}
+        user_meta = BlobHelper::extract_blob_metadata_hash(request.env)
+        @blob = driver.create_blob(credentials, bucket_id, blob_id, blob_data, user_meta)
+        temp_file.delete
+        respond_to do |format|
+          format.xml { haml :"blobs/show" }
+          format.html { haml :"blobs/show" }
+          format.json { convert_to_json(:blob, @blob) }
+        end
+      end
+    end
+
+
     collection :buckets do
 
       standard_show_operation
@@ -142,9 +176,11 @@ module Deltacloud::Collections
           end
         end
 
+require 'ruby-debug'
         action :stream, :http_method => :put, :with_capability => :create_blob do
           description "Stream new blob data into the blob"
           control do
+debugger
             if(env["BLOB_SUCCESS"]) #ie got a 200ok after putting blob
               content_type = env["CONTENT_TYPE"]
               content_type ||=  ""
@@ -201,7 +237,7 @@ module Deltacloud::Collections
           control do
             meta_hash = BlobHelper::extract_blob_metadata_hash(request.env)
             success = driver.update_blob_metadata(credentials, {'bucket'=>params[:id], :id =>params[:blob_id], 'meta_hash' => meta_hash})
-            if(success)
+           if(success)
               meta_hash.each do |k,v|
                 headers["X-Deltacloud-Blobmeta-#{k}"] = v
               end
diff --git a/server/lib/deltacloud/helpers/blob_stream_helper.rb b/server/lib/deltacloud/helpers/blob_stream_helper.rb
index 08cafe2..8567543 100644
--- a/server/lib/deltacloud/helpers/blob_stream_helper.rb
+++ b/server/lib/deltacloud/helpers/blob_stream_helper.rb
@@ -149,7 +149,6 @@ require 'base64'
 class BlobStreamIO
 
   attr_accessor :size, :provider, :sock
-
   def initialize(request)
     @client_request = request
     @size = 0
@@ -159,7 +158,7 @@ class BlobStreamIO
     #deal with blob_metadata: (X-Deltacloud-Blobmeta-name: value)
     user_meta = BlobHelper::extract_blob_metadata_hash(request.env)
     @content_length = request.env['CONTENT_LENGTH']
-    @http, provider_request = driver.blob_stream_connection({:user=>user,
+    @http, provider_request = Deltacloud::API.driver.blob_stream_connection({:user=>user,
        :password=>password, :bucket=>bucket, :blob=>blob, :metadata=> user_meta,
        :content_type=>content_type, :content_length=>@content_length })
     @content_length = @content_length.to_i #for comparison of size in '<< (data)'
-- 
1.7.6.5


Re: [PATCH 1/2] Adds buckets/blobs collection to openstack driver

Posted by Michal Fojtik <mf...@redhat.com>.
On 06/11/12, marios@redhat.com wrote:

ACK.

  -- Michal

> From: marios <ma...@redhat.com>
> 
> 
> Signed-off-by: marios <ma...@redhat.com>
> ---
>  .../drivers/openstack/openstack_driver.rb          |  116 ++++++++++++++++++--
>  1 files changed, 104 insertions(+), 12 deletions(-)
> 
> diff --git a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
> index 7c5125c..91624f5 100644
> --- a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
> +++ b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
> @@ -179,49 +179,116 @@ module Deltacloud
>          end
>  
>          def buckets(credentials, opts={})
> -
> +          os = new_client(credentials, :buckets)
> +          buckets = []
> +          safely do
> +            if opts[:id]
> +              buckets << convert_bucket(os.container(opts[:id]))
> +            else
> +              os.containers.each{|bucket_name| buckets << convert_bucket(os.container(bucket_name))}
> +            end
> +          end
> +          buckets
>          end
>  
>          def create_bucket(credentials, name, opts={})
> -
> +          os = new_client(credentials, :buckets)
> +          bucket = nil
> +          safely do
> +            bucket = os.create_container(name)
> +          end
> +          convert_bucket(bucket)
>          end
>  
>          def delete_bucket(credentials, name, opts={})
> -
> +          os = new_client(credentials, :buckets)
> +          safely do
> +            os.delete_container(name)
> +          end
>          end
>  
>          def blobs(credentials, opts={})
> -
> +          os = new_client(credentials, :buckets)
> +          blobs = []
> +          safely do
> +            bucket = os.container(opts['bucket'])
> +            if(opts[:id])
> +              blobs << convert_blob(bucket.object(opts[:id]), opts['bucket'])
> +            else
> +              bucket.objects_detail.each{|blob| blobs << convert_blob(blob, opts['bucket'])}
> +            end
> +          end
> +          blobs
>          end
>  
>          def blob_data(credentials, bucket, blob, opts={})
> -
> +          os = new_client(credentials, :buckets)
> +          safely do
> +            os.container(bucket).object(blob).data_stream do |chunk|
> +              yield chunk
> +            end
> +          end
>          end
>  
>          def create_blob(credentials, bucket, blob, data, opts={})
> -
> +          os = new_client(credentials, :buckets)
> +          safely do
> +            BlobHelper.rename_metadata_headers(opts, "X-Object-Meta-")
> +            os_blob = os.container(bucket).create_object(blob, {:content_type=> data[:type], :metadata=>opts}, data[:tempfile])
> +            convert_blob(os_blob, bucket)
> +          end
>          end
>  
>          def delete_blob(credentials, bucket, blob, opts={})
> -
> +          os = new_client(credentials, :buckets)
> +          safely do
> +            os.container(bucket).delete_object(blob)
> +          end
>          end
>  
>          def blob_metadata(credentials, opts={})
> -
> +          os = new_client(credentials, :buckets)
> +          safely do
> +            os.container(opts['bucket']).object(opts[:id]).metadata
> +          end
>          end
>  
>          def update_blob_metadata(credentials, opts={})
> -
> +          os = new_client(credentials, :buckets)
> +          safely do
> +            BlobHelper.rename_metadata_headers(opts["meta_hash"], "")
> +            blob = os.container(opts['bucket']).object(opts[:id])
> +            blob.set_metadata(opts['meta_hash'])
> +          end
>          end
>  
> +        #params: {:user,:password,:bucket,:blob,:content_type,:content_length,:metadata}
>          def blob_stream_connection(params)
> -
> +          tokens = params[:user].split("+")
> +          user_name, tenant_name = tokens.first, tokens.last
> +          #need a client for the auth_token and endpoints
> +          os = OpenStack::Connection.create(:username => user_name, :api_key => params[:password], :authtenant => tenant_name, :auth_url => api_provider, :service_type => "object-store")
> +          http = Net::HTTP.new(os.connection.service_host, os.connection.service_port)
> +          http.use_ssl = true
> +          http.verify_mode = OpenSSL::SSL::VERIFY_NONE
> +          path = os.connection.service_path + URI.encode("/#{params[:bucket]}/#{params[:blob]}")
> +          request = Net::HTTP::Put.new(path)
> +          request['X-Auth-Token'] = os.connection.authtoken
> +          request['X-Storage-Token'] = os.connection.authtoken
> +          request['Connection'] = "Keep-Alive"
> +          request['Content-Type'] = params[:content_type]
> +          request['Content-Length'] = params[:content_length]
> +          request['Expect'] = "100-continue"
> +          metadata = params[:metadata] || {}
> +          BlobHelper::rename_metadata_headers(metadata, 'X-Object-Meta-')
> +          metadata.each{|k,v| request[k] = v}
> +          return http, request
>          end
>  
>  private
>  
>          #for v2 authentication credentials.name == "username+tenant_name"
> -        def new_client(credentials, buckets=false)
> +        def new_client(credentials, type = :compute)
>            tokens = credentials.user.split("+")
>            if (tokens.size != 2 && api_v2)
>              raise ValidationFailure.new(Exception.new("Error: expected \"username+tenantname\" as username, you provided: #{credentials.user}"))
> @@ -229,7 +296,15 @@ private
>              user_name, tenant_name = tokens.first, tokens.last
>            end
>            safely do
> -              OpenStack::Connection.create(:username => user_name, :api_key => credentials.password, :authtenant => tenant_name, :auth_url => api_provider)
> +              case type
> +                when :compute
> +                  OpenStack::Connection.create(:username => user_name, :api_key => credentials.password, :authtenant => tenant_name, :auth_url => api_provider)
> +                when :buckets
> +                  OpenStack::Connection.create(:username => user_name, :api_key => credentials.password, :authtenant => tenant_name, :auth_url => api_provider, :service_type => "object-store")
> +                else
> +                  raise ValidationFailure.new(Exception.new("Error: tried to initialise Openstack connection using" +
> +                    " an unknown service_type: #{type}"))
> +              end
>            end
>          end
>  
> @@ -319,6 +394,23 @@ private
>            end
>          end
>  
> +        def convert_bucket(bucket)
> +          Bucket.new({ :id => bucket.name,
> +                       :name => bucket.name,
> +                       :size => bucket.count,
> +                       :blob_list => bucket.objects })
> +        end
> +
> +        def convert_blob(blob, bucket_name)
> +          op, blob_meta = (blob.class == Hash)? [:fetch, {}] : [:send, blob.metadata]
> +          Blob.new({   :id => blob.send(op, :name),
> +                       :bucket => bucket_name,
> +                       :content_length => blob.send(op, :bytes),
> +                       :content_type => blob.send(op, :content_type),
> +                       :last_modified => blob.send(op, :last_modified),
> +                       :user_metadata => blob_meta })
> +        end
> +
>          #IN: path1='server_path1'. content1='contents1', path2='server_path2', content2='contents2' etc
>          #OUT:{local_path=>server_path, local_path1=>server_path2 etc}
>          def extract_personality(opts)
> -- 
> 1.7.6.5
> 

-- 
Michal Fojtik
Sr. Software Engineer, Deltacloud API (http://deltacloud.org)