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 2011/11/25 18:27:14 UTC

CIMI::Volume creation

Patches 1/2 add the Volume model to server and self find to model itself
Patch 3 adds VolumeConfiguration collection and Volume create route to server

(note, drivers currently supporting Deltacloud::StorageVolume are ec2 and rhevm. I used  EC2 
as reference in implementing this patch series. EC2 has no notion of VolumeCOnfiguration... only
specifies that 'capacity' is between 1 and 1000 GiB. So the 'find' method basically creates
the VolumeConfigurations 'on the fly'.. listing all gives you 1000 of them... needs scrutiny+discussion)

Patch 4 Adds the self find to VolumeConfiguration model
Patch 5 adds the actual create to the Volume model

======================

To create a Volume, with 'deltacloudd --cimi -i ec2' (i.e. ec2 driver with cimi frontend)

with xml body:

curl -X POST --user "user:pass" -H "Content-Type: application/CIMI-VolumeCreate+xml" -d '<VolumeCreate><name> marios_new_volume </name> <description> a new volume </description><volumeTemplate><volumeConfig href="http://localhost:3001/cimi/volume_configurations/2"> </volumeConfig></volumeTemplate></VolumeCreate>' http://localhost:3001//cimi/volumes?format=xml

with json body:

curl -X POST --user "user:pass" -H "Content-Type: application/CIMI-VolumeCreate+json" -d '{"name": "marios_new_volume", "description": "a new volume", "volumeTemplate": { "volumeConfig": {"href":"http://localhost:3001/cimi/volume_configurations/2" }}}' http://localhost:3001//cimi/volumes?format=xml


response:
<Volume xmlns="http://www.dmtf.org/cimi">
  <name>vol-c955f5a4</name>
  <eventlog href="http://eventlogs" />
  <guestInterface></guestInterface>
  <uri>http://localhost:3001/cimi/volumes/vol-c955f5a4</uri>
  <supportsSnapshots>true</supportsSnapshots>
  <capacity quantity="2" units="gibibyte" />
  <description>vol-c955f5a4</description>
  <bootable>false</bootable>
  <created>Fri Nov 25 17:05:14 UTC 2011</created>
</Volume>


marios

[PATCH 3/5] Adds CIMI::Volume create and CIMI::VolumeConfiguration list/show to server.rb

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


Signed-off-by: marios <ma...@redhat.com>
---
 server/lib/cimi/server.rb |   41 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/server/lib/cimi/server.rb b/server/lib/cimi/server.rb
index 85fa2f6..64f3b8c 100644
--- a/server/lib/cimi/server.rb
+++ b/server/lib/cimi/server.rb
@@ -238,4 +238,45 @@ global_collection :volumes do
     end
   end
 
+  operation :create do
+    description "Create a new Volume."
+    control do
+      params.merge!({:content_type => (request.content_type.end_with?("+json") ? :json  : :xml) })
+      #((request.content_type.end_with?("+xml")) ? :xml : report_error(415) ) FIXME
+      new_volume = Volume.create(params, self)
+      respond_to do |format|
+        format.json { new_volume.to_json }
+        format.xml { new_volume.to_xml }
+      end
+    end
+  end
+
+end
+
+global_collection :volume_configurations do
+  description "The Volume Configuration entity represents the set of configuration values needed to create a Volume with certain characteristics. Volume Configurations are created by Providers and MAY, at the Providers discretion, be created by Consumers"
+
+  operation :index do
+    description "Get list all VolumeConfigurations"
+    control do
+      volume_configs = VolumeConfiguration.all(self)
+      respond_to do |format|
+        format.xml { volume_configs.to_xml_cimi_collection(self) }
+        format.json { volume_configs.to_json_cimi_collection(self) }
+      end
+    end
+  end
+
+  operation :show do
+    description "Get a specific VolumeConfiguration"
+    param :id, :required, :string
+    control do
+      volume_config = VolumeConfiguration.find(params[:id], self)
+      respond_to do |format|
+        format.xml { volume_config.to_xml }
+        format.json { volume_config.json }
+      end
+    end
+  end
+
 end
-- 
1.7.6.4


[PATCH 2/5] Adds find&conversion methods to CIMI::Volume model

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


Signed-off-by: marios <ma...@redhat.com>
---
 server/lib/cimi/model/volume.rb |   31 ++++++++++++++++++++++++++++++-
 1 files changed, 30 insertions(+), 1 deletions(-)

diff --git a/server/lib/cimi/model/volume.rb b/server/lib/cimi/model/volume.rb
index ed80903..4bdd6ca 100644
--- a/server/lib/cimi/model/volume.rb
+++ b/server/lib/cimi/model/volume.rb
@@ -27,8 +27,37 @@ class CIMI::Model::Volume < CIMI::Model::Base
   array :meters do
     scalar :ref
   end
-  scalar :eventlog
+  href :eventlog
   array :operations do
     scalar :rel, :href
   end
+
+  def self.find(id, _self)
+    volumes = []
+    opts = ( id == :all ) ? {} : { :id => id }
+    volumes = self.driver.storage_volumes(_self.credentials, opts)
+    volumes.collect!{ |volume| from_storage_volume(volume, _self) }
+    return volumes.first unless volumes.length > 1
+    return volumes
+  end
+
+  def self.all(_self); find(:all, _self); end
+
+  private
+
+  def self.from_storage_volume(volume, _self)
+    self.new( { :name => volume.id,
+                :description => volume.id,
+                :created => volume.created,
+                :uri => _self.volume_url(volume.id),
+                :capacity => { :quantity=>volume.capacity, :units=>"gibibyte"  }, #FIXME... units will vary
+                :bootable => "false", #fixme ... will vary... ec2 doesn't expose this
+                :supports_snapshots => "true", #fixme, will vary (true for ec2)
+                :snapshots => [], #fixme...
+                :guest_interface => "",
+                :eventlog => {:href=> "http://eventlogs"},
+                :meters => []
+            } )
+  end
+
 end
-- 
1.7.6.4


[PATCH 4/5] Adds find operation to CIMI::VolumeConfiguration model

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

VolumeConfigurations are created on the fly - none of our cloud providers
supports this model... following ec2 where storage_volumes can be 1..1000 GiB

Signed-off-by: marios <ma...@redhat.com>
---
 server/lib/cimi/model/volume_configuration.rb |   32 +++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/server/lib/cimi/model/volume_configuration.rb b/server/lib/cimi/model/volume_configuration.rb
index 4de0032..7304080 100644
--- a/server/lib/cimi/model/volume_configuration.rb
+++ b/server/lib/cimi/model/volume_configuration.rb
@@ -24,4 +24,36 @@ class CIMI::Model::VolumeConfiguration < CIMI::Model::Base
   array :operations do
     scalar :rel, :href
   end
+
+  def self.find(id, _self)
+    volume_configs = []
+    if id == :all
+      #ec2 ebs volumes can 1gb..1tb
+      (1..1000).each do |size|
+        volume_configs << create(size, _self)
+      end
+    else
+      volume_configs << create(id, _self)
+      return volume_configs.first
+    end
+    return volume_configs
+  end
+
+
+  def self.all(_self); find(:all, _self); end
+
+  private
+
+  def self.create(size, _self)
+    self.new( {
+                :uri => _self.machine_configuration_url(size),
+                :name => size,
+                :description => "volume configuration with #{size} GiB",
+                :created => Time.now.to_s,
+                :capacity => {:quantity=>size, :units=>"gibibytes"},
+                :supports_snapshots => "true",
+                :guest_interface => "NFS"
+            } )
+  end
+
 end
-- 
1.7.6.4


Re: [PATCH 5/5] Adds create operation to CIMI::Volume model

Posted by Michal Fojtik <mf...@redhat.com>.
On Nov 25, 2011, at 6:27 PM, marios@redhat.com wrote:

> From: marios <ma...@redhat.com>
> 
> 
> Signed-off-by: marios <ma...@redhat.com>
> ---
> server/lib/cimi/model/volume.rb |   17 +++++++++++++++++
> 1 files changed, 17 insertions(+), 0 deletions(-)
> 
> diff --git a/server/lib/cimi/model/volume.rb b/server/lib/cimi/model/volume.rb
> index 4bdd6ca..695546d 100644
> --- a/server/lib/cimi/model/volume.rb
> +++ b/server/lib/cimi/model/volume.rb
> @@ -43,6 +43,23 @@ class CIMI::Model::Volume < CIMI::Model::Base
> 
>   def self.all(_self); find(:all, _self); end
> 
> +  def self.create(params, _self)
> +    case params[:content_type]
> +      when :json
> +        json = JSON.parse(_self.request.body.read)
> +        volume_config_id = json["volumeTemplate"]["volumeConfig"]["href"].split("/").last
> +        volume_image_id = (json["volumeTemplate"].has_key?("volumeImage") ? json["volumeTemplate"]["volumeImage"]["href"].split("/").last  : nil)
> +      when :xml
> +        xml = XmlSimple.xml_in(_self.request.body.read)
> +        volume_config_id = xml["volumeTemplate"][0]["volumeConfig"][0]["href"].split("/").last
> +        volume_image_id = (xml["volumeTemplate"][0].has_key?("volumeImage") ? xml["volumeTemplate"][0]["volumeImage"][0]["href"].split("/").last  : nil)
> +    end
> +    volume_config = VolumeConfiguration.find(volume_config_id, _self)
> +    opts = {:capacity=>volume_config.capacity[:quantity], :snapshot_id=>volume_image_id }
> +    storage_volume = self.driver.create_storage_volume(_self.credentials, opts)
> +    from_storage_volume(storage_volume, _self)

I think it would be better to split this method to:

def self.create_from_json(params, _self)
def self.create_from_xml(params, _self)

This two could return an array so:

data, volume_config_id, volume_image_id = create_from_json

def self.create(params, _self)

What do you think?


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


[PATCH 5/5] Adds create operation to CIMI::Volume model

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


Signed-off-by: marios <ma...@redhat.com>
---
 server/lib/cimi/model/volume.rb |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/server/lib/cimi/model/volume.rb b/server/lib/cimi/model/volume.rb
index 4bdd6ca..695546d 100644
--- a/server/lib/cimi/model/volume.rb
+++ b/server/lib/cimi/model/volume.rb
@@ -43,6 +43,23 @@ class CIMI::Model::Volume < CIMI::Model::Base
 
   def self.all(_self); find(:all, _self); end
 
+  def self.create(params, _self)
+    case params[:content_type]
+      when :json
+        json = JSON.parse(_self.request.body.read)
+        volume_config_id = json["volumeTemplate"]["volumeConfig"]["href"].split("/").last
+        volume_image_id = (json["volumeTemplate"].has_key?("volumeImage") ? json["volumeTemplate"]["volumeImage"]["href"].split("/").last  : nil)
+      when :xml
+        xml = XmlSimple.xml_in(_self.request.body.read)
+        volume_config_id = xml["volumeTemplate"][0]["volumeConfig"][0]["href"].split("/").last
+        volume_image_id = (xml["volumeTemplate"][0].has_key?("volumeImage") ? xml["volumeTemplate"][0]["volumeImage"][0]["href"].split("/").last  : nil)
+    end
+    volume_config = VolumeConfiguration.find(volume_config_id, _self)
+    opts = {:capacity=>volume_config.capacity[:quantity], :snapshot_id=>volume_image_id }
+    storage_volume = self.driver.create_storage_volume(_self.credentials, opts)
+    from_storage_volume(storage_volume, _self)
+  end
+
   private
 
   def self.from_storage_volume(volume, _self)
-- 
1.7.6.4


[PATCH 1/5] CIMI::Volume to cimi/server.rb

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


Signed-off-by: marios <ma...@redhat.com>
---
 server/lib/cimi/server.rb |   39 +++++++++++----------------------------
 1 files changed, 11 insertions(+), 28 deletions(-)

diff --git a/server/lib/cimi/server.rb b/server/lib/cimi/server.rb
index 2bd3a39..85fa2f6 100644
--- a/server/lib/cimi/server.rb
+++ b/server/lib/cimi/server.rb
@@ -213,44 +213,27 @@ global_collection :machines do
 end
 
 global_collection :volumes do
-  description 'List all volumes'
+  description "Volume represents storage at either the block or file-system level. Volumes can be attached to Machines. Once attached, Volumes can be accessed by processes on that Machine"
 
   operation :index do
     description "List all volumes"
     control do
-      instances = driver.send(:storage_volumes, credentials, {})
-      @dmtf_col_items = []
-      if instances
-        instances.map do |instance|
-          new_item = { "name" => instance.id,
-            "href" => volume_url(instance.id) }
-          @dmtf_col_items.insert 0,  new_item
-        end
+      volumes = Volume.all(self)
+      respond_to do |format|
+        format.xml { volumes.to_xml_cimi_collection(self) }
+        format.json { volumes.to_json_cimi_collection(self) }
       end
-      respond_to_collection "volume.col.xml"
     end
   end
 
   operation :show do
-    description "Show specific machine."
-    with_capability :storage_volume
-    param :id,          :string,    :required
+    description "Show specific Volume."
+    param :id, :string, :required
     control do
-      @volume = driver.send(:storage_volume, credentials, { :id => params[:id]} )
-      if @volume
-        #setup the default values for a machine imageion
-        resource_default = get_resource_default "volume"
-        #get the actual values from image
-        resource_value = { "name" => @volume.id,
-          "status" => @volume.state, "uri" => @volume.id,
-          "href" => volume_url(@volume.id),
-          "capacity" => { "quantity" => @volume.capacity, "units" => "gigabyte"} }
-        #mixin actual values get from the specific image
-        @dmtfitem = resource_default["dmtfitem"].merge resource_value
-        show_resource "volumes/show", "Volume",
-          {"property" => "properties", "operation" => "operations"}
-      else
-        report_error(404)
+      volume = Volume.find(params[:id], self)
+      respond_to do |format|
+        format.xml  { volume.to_xml  }
+        format.json { volume.to_json }
       end
     end
   end
-- 
1.7.6.4


Re: CIMI::Volume creation

Posted by Michal Fojtik <mf...@redhat.com>.
On Nov 25, 2011, at 6:27 PM, marios@redhat.com wrote:

ACK this series. Just one note in 5/5.

  -- Michal

> 
> Patches 1/2 add the Volume model to server and self find to model itself
> Patch 3 adds VolumeConfiguration collection and Volume create route to server
> 
> (note, drivers currently supporting Deltacloud::StorageVolume are ec2 and rhevm. I used  EC2 
> as reference in implementing this patch series. EC2 has no notion of VolumeCOnfiguration... only
> specifies that 'capacity' is between 1 and 1000 GiB. So the 'find' method basically creates
> the VolumeConfigurations 'on the fly'.. listing all gives you 1000 of them... needs scrutiny+discussion)
> 
> Patch 4 Adds the self find to VolumeConfiguration model
> Patch 5 adds the actual create to the Volume model
> 
> ======================
> 
> To create a Volume, with 'deltacloudd --cimi -i ec2' (i.e. ec2 driver with cimi frontend)
> 
> with xml body:
> 
> curl -X POST --user "user:pass" -H "Content-Type: application/CIMI-VolumeCreate+xml" -d '<VolumeCreate><name> marios_new_volume </name> <description> a new volume </description><volumeTemplate><volumeConfig href="http://localhost:3001/cimi/volume_configurations/2"> </volumeConfig></volumeTemplate></VolumeCreate>' http://localhost:3001//cimi/volumes?format=xml
> 
> with json body:
> 
> curl -X POST --user "user:pass" -H "Content-Type: application/CIMI-VolumeCreate+json" -d '{"name": "marios_new_volume", "description": "a new volume", "volumeTemplate": { "volumeConfig": {"href":"http://localhost:3001/cimi/volume_configurations/2" }}}' http://localhost:3001//cimi/volumes?format=xml
> 
> 
> response:
> <Volume xmlns="http://www.dmtf.org/cimi">
>  <name>vol-c955f5a4</name>
>  <eventlog href="http://eventlogs" />
>  <guestInterface></guestInterface>
>  <uri>http://localhost:3001/cimi/volumes/vol-c955f5a4</uri>
>  <supportsSnapshots>true</supportsSnapshots>
>  <capacity quantity="2" units="gibibyte" />
>  <description>vol-c955f5a4</description>
>  <bootable>false</bootable>
>  <created>Fri Nov 25 17:05:14 UTC 2011</created>
> </Volume>
> 
> 
> marios

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