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 2011/11/29 14:44:53 UTC

[PATCH core 01/10] CIMI: Added methods for accessing Machine entities

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


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/lib/cimi/model/machine.rb |   12 ++++++++++++
 server/lib/cimi/server.rb        |   31 ++++++++-----------------------
 2 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/server/lib/cimi/model/machine.rb b/server/lib/cimi/model/machine.rb
index 932acdf..4ad4732 100644
--- a/server/lib/cimi/model/machine.rb
+++ b/server/lib/cimi/model/machine.rb
@@ -54,4 +54,16 @@ class CIMI::Model::Machine < CIMI::Model::Base
     scalar :rel, :href
   end
 
+  def self.find(id, _self)
+    instances = []
+    if id == :all
+      instances = _self.driver.instances(_self.credentials)
+      instances.map { |instance| from_instance(instance, _self) }.compact
+    else
+      instance = _self.driver.instance(_self.credentials, id)
+      from_instance(instance, _self)
+    end
+  end
+
+
 end
diff --git a/server/lib/cimi/server.rb b/server/lib/cimi/server.rb
index 3b3e7d0..b05fa31 100644
--- a/server/lib/cimi/server.rb
+++ b/server/lib/cimi/server.rb
@@ -159,16 +159,11 @@ global_collection :machines do
   operation :index do
     description "List all machines"
     control do
-      instances = driver.send(:instances, credentials, {})
-      @dmtf_col_items = []
-      if instances
-        instances.map do |instance|
-          new_item = { "name" => instance.name,
-            "href" => machine_url(instance.id) }
-          @dmtf_col_items.insert 0,  new_item
-        end
+      machines = Machine.all(self)
+      respond_to do |format|
+        format.xml { machines.to_xml_cimi_collection(self) }
+        format.json { machines.to_json_cimi_collection(self) }
       end
-      respond_to_collection "machine.col.xml"
     end
   end
 
@@ -177,20 +172,10 @@ global_collection :machines do
     with_capability :instance
     param :id,          :string,    :required
     control do
-      @machine = driver.send(:instance, credentials, { :id => params[:id]} )
-      if @machine
-        #setup the default values for a machine imageion
-        resource_default = get_resource_default "machine"
-        #get the actual values from image
-        resource_value = { "name" => @machine.name,
-          "status" => @machine.state, "uri" => @machine.id,
-          "href" => machine_url(@machine.id) }
-        #mixin actual values get from the specific image
-        @dmtfitem = resource_default["dmtfitem"].merge resource_value
-        show_resource "machines/show", "Machine",
-          {"property" => "properties", "disk" => "disks", "operation" => "operations"}
-      else
-        report_error(404)
+      machine = Machine.find(params[:id], self)
+      respond_to do |format|
+        format.xml { machine.to_xml }
+        format.json { machine.to_json }
       end
     end
   end
-- 
1.7.4.4


[PATCH core 10/10] CIMI: Added delete operation Cucumber scenario for Machine entity and couple other minor fixed there

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


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/tests/cimi/features/machines.feature        |   37 +++++++-----
 .../features/step_definitions/machines_steps.rb    |   59 ++++++++++++++++----
 server/tests/cimi/features/support/env.rb          |    8 +++
 3 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/server/tests/cimi/features/machines.feature b/server/tests/cimi/features/machines.feature
index badf427..08934ad 100644
--- a/server/tests/cimi/features/machines.feature
+++ b/server/tests/cimi/features/machines.feature
@@ -2,7 +2,7 @@ Feature: Managing Machines
   In order to interact with the provider
   We must first be provided a URL to the main entry point (CEP).
 
-  Scenario: Create a New Machine
+  Scenario: Create a New Machine entity
     Given Cloud Entry Point URL is provided
     And client retrieve the Cloud Entry Point
     When client specifies a Machine Image
@@ -14,28 +14,33 @@ Feature: Managing Machines
       | description | sampleMachine1Description |
     Then client should be able to create this Machine
 
-  Scenario: Querying created Machine
+  Scenario: Querying created Machine entity
     Given Cloud Entry Point URL is provided
     And client retrieve the Cloud Entry Point
-    When client query for 'sampleMachine1' Machine entity
-    Then client should verify that this machine exists
-    And client should verify that this Machine has set
-      | name        | sampleMachine1            ||
-      | description | sampleMachine1Description ||
-      | cpu         | 1                         ||
-      | memory      | quantity                  | 1740  |
-      | state       | RUNNING                   ||
+    When client query for created Machine entity
+    Then client should verify that this Machine exists
+    And client should verify that this Machine has been created properly
+      | cpu         | 1                         |
+      | memory      | 1740.8                    |
+      | state       | STARTED                   |
 
-  Scenario: Stopping Machine
+  Scenario: Stopping created Machine entity
     Given Cloud Entry Point URL is provided
     And client retrieve the Cloud Entry Point
-    When client executes stop operation on Machine 'sampleMachine1'
-    Then client should be able to query for 'sampleMachine1' Machine entity
+    When client executes stop operation on created Machine
+    Then client query for created Machine entity
     And client should verify that this machine is stopped
 
-  Scenario: Starting Machine
+  Scenario: Starting created Machine entity
     Given Cloud Entry Point URL is provided
     And client retrieve the Cloud Entry Point
-    When client executes start operation on Machine 'sampleMachine1'
-    Then client should be able to query for 'sampleMachine1' Machine entity
+    When client executes start operation on created Machine
+    Then client query for created Machine entity
     And client should verify that this machine is started
+
+  Scenario: Deleting created Machine entity
+    Given Cloud Entry Point URL is provided
+    And client retrieve the Cloud Entry Point
+    When client executes delete operation on created Machine
+    Then client query for created Machine entity
+    And client should verify that this machine is deleted
diff --git a/server/tests/cimi/features/step_definitions/machines_steps.rb b/server/tests/cimi/features/step_definitions/machines_steps.rb
index d8a6b87..a8b63d0 100644
--- a/server/tests/cimi/features/step_definitions/machines_steps.rb
+++ b/server/tests/cimi/features/step_definitions/machines_steps.rb
@@ -21,9 +21,10 @@ end
 When /^client specifies a new Machine using$/ do |machine|
   @machine_image.should_not be_nil
   @machine_configuration.should_not be_nil
+  @new_machine_name = machine.raw[0][1]
   @builder = Nokogiri::XML::Builder.new do |xml|
     xml.Machine(:xmlns => CMWG_NAMESPACE) {
-      xml.name machine.raw[0][1]
+      xml.name @new_machine_name
       xml.description machine.raw[1][1]
       xml.MachineTemplate {
         xml.MachineConfig( :href => @machine_configuration.uri )
@@ -34,23 +35,59 @@ When /^client specifies a new Machine using$/ do |machine|
 end
 
 Then /^client should be able to create this Machine$/ do
-  pending "\nNOTE: There is an inconsistency between Primer and CIMI spec\n" +
-    "The Primer says that client should send just pointners MachineConf and MachineImg\n"+
-    "The CIMI says that full XML need to be provided in order to create a Machine\n\n"
-  @machine = CIMI::Model::Machine.from_xml(@builder.to_xml)
   authorize 'mockuser', 'mockpassword'
-  post '/cimi/machines', @machine
+  header 'Content-Type', 'application/xml'
+  post '/cimi/machines', @builder.to_xml
   last_response.status.should == 201
+  set_new_machine(CIMI::Model::Machine.from_xml(last_response.body))
 end
 
-Then /^client should be able to query this Machine$/ do
-  get "/cimi/machines/%s" % (@new_machine/'')
+Then /^client query for created Machine entity$/ do
+  authorize 'mockuser', 'mockpassword'
+  header 'Content-Type', 'application/xml'
+  get "/cimi/machines/%s" % new_machine.name
+  if @delete_operation
+    last_response.status.should == 404
+  else
+    last_response.status.should == 200
+    @machine = CIMI::Model::Machine.from_xml(last_response.body)
+    @machine.name.should == new_machine.name
+  end
+
 end
 
-When /^client executes (\w+) operation on Machine '(\w+)'$/ do |operation, machine_id|
-  pending # express the regexp above with the code you wish you had
+Then /^client should verify that this Machine has been created properly$/ do |attrs|
+  attrs.rows_hash.each do |key, value|
+    if key == 'memory'
+      @machine.memory['quantity'].to_s.should == value
+    else
+      @machine.send(key.intern).to_s.should == value
+    end
+  end
+end
+
+When /^client executes (\w+) operation on created Machine$/ do |operation|
+  builder = Nokogiri::XML::Builder.new do |xml|
+    xml.Action(:xmlns => CMWG_NAMESPACE) {
+      xml.action "http://www.dmtf.org/cimi/action/#{operation}"
+    }
+  end
+  authorize 'mockuser', 'mockpassword'
+  header 'Content-Type', 'application/xml'
+  if operation == 'delete'
+    delete "/cimi/machines/%s/delete" % new_machine.name
+    last_response.status.should == 200
+    last_response.body.should be_empty
+    @delete_operation = true
+  else
+    post "/cimi/machines/%s/%s" % [new_machine.name, operation], builder.to_xml
+    last_response.status.should == 202
+    last_response.body.should be_empty
+  end
 end
 
 Then /^client should verify that this machine is (\w+)$/ do |status|
-  pending # express the regexp above with the code you wish you had
+  unless @delete_operation
+    @machine.state.should == status.upcase
+  end
 end
diff --git a/server/tests/cimi/features/support/env.rb b/server/tests/cimi/features/support/env.rb
index f55e811..06ff3d6 100644
--- a/server/tests/cimi/features/support/env.rb
+++ b/server/tests/cimi/features/support/env.rb
@@ -16,6 +16,14 @@ def last_xml_response
   Nokogiri::XML(last_response.body)
 end
 
+def new_machine
+  @@new_machine
+end
+
+def set_new_machine(machine)
+  @@new_machine = machine
+end
+
 class String
 
   def to_class_name
-- 
1.7.4.4


[PATCH core 05/10] CIMI: Added Machine actions

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


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/lib/cimi/model/machine.rb |   89 +++++++++++++++++++++++++++++++++++++-
 server/lib/cimi/server.rb        |   71 ++++++++++++++++++++++++++++++
 2 files changed, 159 insertions(+), 1 deletions(-)

diff --git a/server/lib/cimi/model/machine.rb b/server/lib/cimi/model/machine.rb
index 4ad4732..74741e6 100644
--- a/server/lib/cimi/model/machine.rb
+++ b/server/lib/cimi/model/machine.rb
@@ -13,6 +13,8 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
+require 'deltacloud/models/instance_address'
+
 class CIMI::Model::Machine < CIMI::Model::Base
 
   text :state
@@ -60,10 +62,95 @@ class CIMI::Model::Machine < CIMI::Model::Base
       instances = _self.driver.instances(_self.credentials)
       instances.map { |instance| from_instance(instance, _self) }.compact
     else
-      instance = _self.driver.instance(_self.credentials, id)
+      instance = _self.driver.instance(_self.credentials, :id => id)
       from_instance(instance, _self)
     end
   end
 
+  def perform(action, _self, &block)
+    begin
+      if _self.driver.send(:"#{action.name}_instance", _self.credentials, self.name)
+        block.callback :success
+      else
+        raise "Operation failed to execute on given Machine"
+      end
+    rescue => e
+      block.callback :failure, e.message
+    end
+  end
+
+  private
+
+  def self.from_instance(instance, _self)
+    self.new(
+      :name => instance.id,
+      :description => instance.name,
+      :uri => _self.machine_url(instance.id),
+      :state => convert_instance_state(instance.state),
+      :cpu => convert_instance_cpu(instance.instance_profile, _self),
+      :memory => convert_instance_memory(instance.instance_profile, _self),
+      :disks => convert_instance_storage(instance.instance_profile, _self),
+      :network_interfaces => convert_instance_addresses(instance),
+      :operations => convert_instance_actions(instance, _self)
+    )
+  end
+
+  # FIXME: This will convert 'RUNNING' state to 'STARTED'
+  # which is defined in CIMI (p65)
+  #
+  def self.convert_instance_state(state)
+    ('RUNNING' == state) ? 'STARTED' : state
+  end
+
+  def self.convert_instance_cpu(profile, _self)
+    cpu_override = profile.overrides.find { |p, v| p == :cpu }
+    if cpu_override.nil?
+      MachineConfiguration.find(profile.id, _self).cpu
+    else
+      cpu_override[1]
+    end
+  end
+
+  def self.convert_instance_memory(profile, _self)
+    machine_conf = MachineConfiguration.find(profile.name, _self)
+    memory_override = profile.overrides.find { |p, v| p == :memory }
+    {
+      :quantity => memory_override.nil? ? machine_conf.memory[:quantity] : memory_override[1],
+      :units => machine_conf.memory[:units]
+    }
+  end
+
+  def self.convert_instance_storage(profile, _self)
+    machine_conf = MachineConfiguration.find(profile.name, _self)
+    storage_override = profile.overrides.find { |p, v| p == :storage }
+    [
+      { :capacity => { 
+          :quantity => storage_override.nil? ? machine_conf.disks.first[:capacity][:quantity] : storage_override[1],
+          :units => machine_conf.disks.first[:capacity][:units]
+        } 
+      } 
+    ]
+  end
+
+  def self.convert_instance_addresses(instance)
+    (instance.public_addresses + instance.private_addresses).collect do |address|
+      {
+        :hostname => address.is_hostname? ? address : nil,
+        :mac_address => address.is_mac? ? address : nil,
+        :state => 'Active',
+        :protocol => 'IPv4',
+        :address => address.is_ipv4? ? address : nil,
+        :allocation => 'Static'
+      }
+    end
+  end
+
+  def self.convert_instance_actions(instance, _self)
+    instance.actions.collect do |action|
+      action = :delete if action == :destroy  # In CIMI destroy operation become delete
+      action = :restart if action == :reboot  # In CIMI reboot operation become restart
+      { :href => _self.send(:"#{action}_machine_url", instance.id), :rel => "http://www.dmtf.org/cimi/action/#{action}" }
+    end
+  end
 
 end
diff --git a/server/lib/cimi/server.rb b/server/lib/cimi/server.rb
index b05fa31..e6279b9 100644
--- a/server/lib/cimi/server.rb
+++ b/server/lib/cimi/server.rb
@@ -180,6 +180,77 @@ global_collection :machines do
     end
   end
 
+  operation :delete, :method => :post, :member => true do
+    description "Reboot specific machine."
+    param :id,          :string,    :required
+    control do
+      machine = Machine.find(params[:id], self)
+      machine.perform :destroy do |operation|
+        operation.body = request.body.read
+        operation.content_type = params[:content_type]
+        operation.on :success do
+          # We *should* return 202 - Accepted because the 'reboot' operation will not be processed
+          # immediately
+          no_content_with_status 202
+        end
+        operation.on :failure do
+          # error...
+        end
+      end
+    end
+  end
+
+  operation :stop, :method => :post, :member => true do
+    description "Stop specific machine."
+    param :id,          :string,    :required
+    control do
+      machine = Machine.find(params[:id], self)
+      if request.content_type.end_with?("+json")
+        action = Action.from_json(request.body.read)
+      else
+        action = Action.from_xml(request.body.read)
+      end
+      machine.perform(action, self) do |operation|
+        no_content_with_status(202) if operation.success?
+        # Handle errors using operation.failure?
+      end
+    end
+  end
+
+  operation :restart, :method => :post, :member => true do
+    description "Start specific machine."
+    param :id,          :string,    :required
+    control do
+      machine = Machine.find(params[:id], self)
+      if request.content_type.end_with?("+json")
+        action = Action.from_json(request.body.read)
+      else
+        action = Action.from_xml(request.body.read)
+      end
+      machine.perform(action, self) do |operation|
+        no_content_with_status(202) if operation.success?
+        # Handle errors using operation.failure?
+      end
+    end
+  end
+
+  operation :start, :method => :post, :member => true do
+    description "Start specific machine."
+    param :id,          :string,    :required
+    control do
+      machine = Machine.find(params[:id], self)
+      if request.content_type.end_with?("+json")
+        action = Action.from_json(request.body.read)
+      else
+        action = Action.from_xml(request.body.read)
+      end
+      machine.perform(action, self) do |operation|
+        no_content_with_status(202) if operation.success?
+        # Handle errors using operation.failure?
+      end
+    end
+  end
+
 end
 
 global_collection :volumes do
-- 
1.7.4.4


[PATCH core 03/10] CIMI: Added Action model

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


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/lib/cimi/model.rb        |    1 +
 server/lib/cimi/model/action.rb |   24 ++++++++++++++++++++++++
 2 files changed, 25 insertions(+), 0 deletions(-)
 create mode 100644 server/lib/cimi/model/action.rb

diff --git a/server/lib/cimi/model.rb b/server/lib/cimi/model.rb
index 5fee012..acd72ce 100644
--- a/server/lib/cimi/model.rb
+++ b/server/lib/cimi/model.rb
@@ -25,6 +25,7 @@ require 'cimi/model/base'
 require 'cimi/model/machine_template'
 require 'cimi/model/machine_image'
 require 'cimi/model/machine_configuration'
+require 'cimi/model/action'
 require 'cimi/model/machine'
 require 'cimi/model/volume'
 require 'cimi/model/machine_admin'
diff --git a/server/lib/cimi/model/action.rb b/server/lib/cimi/model/action.rb
new file mode 100644
index 0000000..627e673
--- /dev/null
+++ b/server/lib/cimi/model/action.rb
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+class CIMI::Model::Action < CIMI::Model::Base
+
+  text :action
+
+  def name
+    action.split('/').last.intern
+  end
+
+end
-- 
1.7.4.4


[PATCH core 08/10] CIMI: Fixed typo in retrieving single Image in CIMI

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


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/lib/cimi/model/machine_image.rb |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/server/lib/cimi/model/machine_image.rb b/server/lib/cimi/model/machine_image.rb
index 779e21c..97766f0 100644
--- a/server/lib/cimi/model/machine_image.rb
+++ b/server/lib/cimi/model/machine_image.rb
@@ -28,7 +28,7 @@ class CIMI::Model::MachineImage < CIMI::Model::Base
       images = _self.driver.images(_self.credentials)
       images.map { |image| from_image(image, _self) }
     else
-      image = _self.driver.image(_self.credentials, id)
+      image = _self.driver.image(_self.credentials, :id => id)
       from_image(image, _self)
     end
   end
-- 
1.7.4.4


[PATCH core 06/10] CIMI: Added posibility to run all CIMI scenarios at once by invoking 'rake cimi'

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


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/Rakefile |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/server/Rakefile b/server/Rakefile
index 1668474..50ea60a 100644
--- a/server/Rakefile
+++ b/server/Rakefile
@@ -50,6 +50,10 @@ begin
       end
     end
   end
+  Cucumber::Rake::Task.new(:cimi) do |t|
+    t.cucumber_opts = "tests/cimi/features/*.feature --format pretty"
+    t.rcov = false
+  end
   namespace :cimi do
     Cucumber::Rake::Task.new(:machines) do |t|
       t.cucumber_opts = "tests/cimi/features/machines.feature --format pretty"
-- 
1.7.4.4


[PATCH core 02/10] CIMI: Added no_content helper for Machine actions

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


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/lib/cimi/helpers/cimi_helper.rb |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/server/lib/cimi/helpers/cimi_helper.rb b/server/lib/cimi/helpers/cimi_helper.rb
index b55ac3b..f67460b 100644
--- a/server/lib/cimi/helpers/cimi_helper.rb
+++ b/server/lib/cimi/helpers/cimi_helper.rb
@@ -14,8 +14,16 @@
 # under the License.
 
 module CIMIHelper
+
+  def no_content_with_status(code=200)
+    body ''
+    status code
+  end
+
 end
 
+helpers CIMIHelper
+
 class Array
   def to_xml_cimi_collection(_self)
     model_name = first.class.xml_tag_name
-- 
1.7.4.4


[PATCH core 07/10] CIMI: Added standard exception to handle Entity not found errors

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


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/lib/cimi/model/base.rb |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/server/lib/cimi/model/base.rb b/server/lib/cimi/model/base.rb
index 4fa9014..0088b8b 100644
--- a/server/lib/cimi/model/base.rb
+++ b/server/lib/cimi/model/base.rb
@@ -66,6 +66,15 @@ require 'json'
 #   [array(name, opts, &block)]
 #     An array of structured subobjects; the block defines the schema of
 #     the subobjects.
+
+class CIMI::Model::NotFound < StandardError
+  attr_accessor :code
+  def initialize
+    super("Requested Entity Not Found")
+    self.code = 404
+  end
+end
+
 class CIMI::Model::Base
 
   #
-- 
1.7.4.4


Re: [PATCH core 01/10] CIMI: Added methods for accessing Machine entities

Posted by Michal Fojtik <mf...@redhat.com>.
On Nov 29, 2011, at 4:32 PM, marios@redhat.com wrote:

> ACK to the entire patch_nuke

Thanks!

As a bonus I generated all green CIMI Cucumber report:

http://omicron.mifo.sk/cimi_features.html


 -- Michal

> 
> On 29/11/11 15:44, mfojtik@redhat.com wrote:
>> From: Michal Fojtik <mf...@redhat.com>
>> 
>> 
>> Signed-off-by: Michal fojtik <mf...@redhat.com>
>> ---
>> server/lib/cimi/model/machine.rb |   12 ++++++++++++
>> server/lib/cimi/server.rb        |   31 ++++++++-----------------------
>> 2 files changed, 20 insertions(+), 23 deletions(-)
>> 
>> diff --git a/server/lib/cimi/model/machine.rb b/server/lib/cimi/model/machine.rb
>> index 932acdf..4ad4732 100644
>> --- a/server/lib/cimi/model/machine.rb
>> +++ b/server/lib/cimi/model/machine.rb
>> @@ -54,4 +54,16 @@ class CIMI::Model::Machine < CIMI::Model::Base
>>     scalar :rel, :href
>>   end
>> 
>> +  def self.find(id, _self)
>> +    instances = []
>> +    if id == :all
>> +      instances = _self.driver.instances(_self.credentials)
>> +      instances.map { |instance| from_instance(instance, _self) }.compact
>> +    else
>> +      instance = _self.driver.instance(_self.credentials, id)
>> +      from_instance(instance, _self)
>> +    end
>> +  end
>> +
>> +
>> end
>> diff --git a/server/lib/cimi/server.rb b/server/lib/cimi/server.rb
>> index 3b3e7d0..b05fa31 100644
>> --- a/server/lib/cimi/server.rb
>> +++ b/server/lib/cimi/server.rb
>> @@ -159,16 +159,11 @@ global_collection :machines do
>>   operation :index do
>>     description "List all machines"
>>     control do
>> -      instances = driver.send(:instances, credentials, {})
>> -      @dmtf_col_items = []
>> -      if instances
>> -        instances.map do |instance|
>> -          new_item = { "name" => instance.name,
>> -            "href" => machine_url(instance.id) }
>> -          @dmtf_col_items.insert 0,  new_item
>> -        end
>> +      machines = Machine.all(self)
>> +      respond_to do |format|
>> +        format.xml { machines.to_xml_cimi_collection(self) }
>> +        format.json { machines.to_json_cimi_collection(self) }
>>       end
>> -      respond_to_collection "machine.col.xml"
>>     end
>>   end
>> 
>> @@ -177,20 +172,10 @@ global_collection :machines do
>>     with_capability :instance
>>     param :id,          :string,    :required
>>     control do
>> -      @machine = driver.send(:instance, credentials, { :id => params[:id]} )
>> -      if @machine
>> -        #setup the default values for a machine imageion
>> -        resource_default = get_resource_default "machine"
>> -        #get the actual values from image
>> -        resource_value = { "name" => @machine.name,
>> -          "status" => @machine.state, "uri" => @machine.id,
>> -          "href" => machine_url(@machine.id) }
>> -        #mixin actual values get from the specific image
>> -        @dmtfitem = resource_default["dmtfitem"].merge resource_value
>> -        show_resource "machines/show", "Machine",
>> -          {"property" => "properties", "disk" => "disks", "operation" => "operations"}
>> -      else
>> -        report_error(404)
>> +      machine = Machine.find(params[:id], self)
>> +      respond_to do |format|
>> +        format.xml { machine.to_xml }
>> +        format.json { machine.to_json }
>>       end
>>     end
>>   end
> 

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


Re: [PATCH core 01/10] CIMI: Added methods for accessing Machine entities

Posted by "marios@redhat.com" <ma...@redhat.com>.
ACK to the entire patch_nuke

On 29/11/11 15:44, mfojtik@redhat.com wrote:
> From: Michal Fojtik <mf...@redhat.com>
> 
> 
> Signed-off-by: Michal fojtik <mf...@redhat.com>
> ---
>  server/lib/cimi/model/machine.rb |   12 ++++++++++++
>  server/lib/cimi/server.rb        |   31 ++++++++-----------------------
>  2 files changed, 20 insertions(+), 23 deletions(-)
> 
> diff --git a/server/lib/cimi/model/machine.rb b/server/lib/cimi/model/machine.rb
> index 932acdf..4ad4732 100644
> --- a/server/lib/cimi/model/machine.rb
> +++ b/server/lib/cimi/model/machine.rb
> @@ -54,4 +54,16 @@ class CIMI::Model::Machine < CIMI::Model::Base
>      scalar :rel, :href
>    end
>  
> +  def self.find(id, _self)
> +    instances = []
> +    if id == :all
> +      instances = _self.driver.instances(_self.credentials)
> +      instances.map { |instance| from_instance(instance, _self) }.compact
> +    else
> +      instance = _self.driver.instance(_self.credentials, id)
> +      from_instance(instance, _self)
> +    end
> +  end
> +
> +
>  end
> diff --git a/server/lib/cimi/server.rb b/server/lib/cimi/server.rb
> index 3b3e7d0..b05fa31 100644
> --- a/server/lib/cimi/server.rb
> +++ b/server/lib/cimi/server.rb
> @@ -159,16 +159,11 @@ global_collection :machines do
>    operation :index do
>      description "List all machines"
>      control do
> -      instances = driver.send(:instances, credentials, {})
> -      @dmtf_col_items = []
> -      if instances
> -        instances.map do |instance|
> -          new_item = { "name" => instance.name,
> -            "href" => machine_url(instance.id) }
> -          @dmtf_col_items.insert 0,  new_item
> -        end
> +      machines = Machine.all(self)
> +      respond_to do |format|
> +        format.xml { machines.to_xml_cimi_collection(self) }
> +        format.json { machines.to_json_cimi_collection(self) }
>        end
> -      respond_to_collection "machine.col.xml"
>      end
>    end
>  
> @@ -177,20 +172,10 @@ global_collection :machines do
>      with_capability :instance
>      param :id,          :string,    :required
>      control do
> -      @machine = driver.send(:instance, credentials, { :id => params[:id]} )
> -      if @machine
> -        #setup the default values for a machine imageion
> -        resource_default = get_resource_default "machine"
> -        #get the actual values from image
> -        resource_value = { "name" => @machine.name,
> -          "status" => @machine.state, "uri" => @machine.id,
> -          "href" => machine_url(@machine.id) }
> -        #mixin actual values get from the specific image
> -        @dmtfitem = resource_default["dmtfitem"].merge resource_value
> -        show_resource "machines/show", "Machine",
> -          {"property" => "properties", "disk" => "disks", "operation" => "operations"}
> -      else
> -        report_error(404)
> +      machine = Machine.find(params[:id], self)
> +      respond_to do |format|
> +        format.xml { machine.to_xml }
> +        format.json { machine.to_json }
>        end
>      end
>    end


[PATCH core 09/10] CIMI: Added create and destroy operations for Machine entity

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


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/lib/cimi/model/machine.rb |   21 +++++++++++++++++++++
 server/lib/cimi/server.rb        |   33 +++++++++++++++++++--------------
 2 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/server/lib/cimi/model/machine.rb b/server/lib/cimi/model/machine.rb
index 74741e6..19c7f2c 100644
--- a/server/lib/cimi/model/machine.rb
+++ b/server/lib/cimi/model/machine.rb
@@ -63,10 +63,27 @@ class CIMI::Model::Machine < CIMI::Model::Base
       instances.map { |instance| from_instance(instance, _self) }.compact
     else
       instance = _self.driver.instance(_self.credentials, :id => id)
+      raise CIMI::Model::NotFound unless instance
       from_instance(instance, _self)
     end
   end
 
+  def self.create_from_json(body, _self)
+    json = JSON.parse(body)
+    hardware_profile_id = xml['MachineTemplate']['MachineConfig']["href"].split('/').last
+    image_id = xml['MachineTemplate']['MachineImage']["href"].split('/').last
+    instance = _self.create_instance(_self.credentials, image_id, { :hwp_id => hardware_profile_id })
+    from_instance(instance, _self)
+  end
+
+  def self.create_from_xml(body, _self)
+    xml = XmlSimple.xml_in(body)
+    hardware_profile_id = xml['MachineTemplate'][0]['MachineConfig'][0]["href"].split('/').last
+    image_id = xml['MachineTemplate'][0]['MachineImage'][0]["href"].split('/').last
+    instance = _self.driver.create_instance(_self.credentials, image_id, { :hwp_id => hardware_profile_id })
+    from_instance(instance, _self)
+  end
+
   def perform(action, _self, &block)
     begin
       if _self.driver.send(:"#{action.name}_instance", _self.credentials, self.name)
@@ -79,6 +96,10 @@ class CIMI::Model::Machine < CIMI::Model::Base
     end
   end
 
+  def self.delete!(id, _self)
+    _self.driver.destroy_instance(_self.credentials, id)
+  end
+
   private
 
   def self.from_instance(instance, _self)
diff --git a/server/lib/cimi/server.rb b/server/lib/cimi/server.rb
index e6279b9..afee932 100644
--- a/server/lib/cimi/server.rb
+++ b/server/lib/cimi/server.rb
@@ -180,23 +180,28 @@ global_collection :machines do
     end
   end
 
-  operation :delete, :method => :post, :member => true do
+  operation :create do
+    description "Create a new Machine entity."
+    control do
+      if request.content_type.end_with?("+json")
+        new_machine = Machine.create_from_json(request.body.read, self)
+      else
+        new_machine = Machine.create_from_xml(request.body.read, self)
+      end
+      status 201 # Created
+      respond_to do |format|
+        format.json { new_machine.to_json }
+        format.xml { new_machine.to_xml }
+      end
+    end
+  end
+
+  operation :delete, :method => :delete, :member => true do
     description "Reboot specific machine."
     param :id,          :string,    :required
     control do
-      machine = Machine.find(params[:id], self)
-      machine.perform :destroy do |operation|
-        operation.body = request.body.read
-        operation.content_type = params[:content_type]
-        operation.on :success do
-          # We *should* return 202 - Accepted because the 'reboot' operation will not be processed
-          # immediately
-          no_content_with_status 202
-        end
-        operation.on :failure do
-          # error...
-        end
-      end
+      Machine.delete!(params[:id], self)
+      no_content_with_status(200)
     end
   end
 
-- 
1.7.4.4


[PATCH core 04/10] Core: Added callback extension for Proc

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


Signed-off-by: Michal fojtik <mf...@redhat.com>
---
 server/lib/deltacloud/core_ext.rb      |    1 +
 server/lib/deltacloud/core_ext/proc.rb |   27 +++++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 0 deletions(-)
 create mode 100644 server/lib/deltacloud/core_ext/proc.rb

diff --git a/server/lib/deltacloud/core_ext.rb b/server/lib/deltacloud/core_ext.rb
index 042bffc..fedbc18 100644
--- a/server/lib/deltacloud/core_ext.rb
+++ b/server/lib/deltacloud/core_ext.rb
@@ -18,3 +18,4 @@ require 'deltacloud/core_ext/string'
 require 'deltacloud/core_ext/integer'
 require 'deltacloud/core_ext/hash'
 require 'deltacloud/core_ext/array'
+require 'deltacloud/core_ext/proc'
diff --git a/server/lib/deltacloud/core_ext/proc.rb b/server/lib/deltacloud/core_ext/proc.rb
new file mode 100644
index 0000000..3c443ff
--- /dev/null
+++ b/server/lib/deltacloud/core_ext/proc.rb
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+# Original code copied from: http://www.mattsears.com/articles/2011/11/27/ruby-blocks-as-dynamic-callbacks
+# Copyright 2011 Matt Sears.
+class Proc
+  def callback(callable, *args)
+    self === Class.new do
+      method_name = callable.to_sym
+      define_method(method_name) { |&block| block.nil? ? true : block.call(*args) }
+      define_method("#{method_name}?") { true }
+      def method_missing(method_name, *args, &block) false; end
+    end.new
+  end
+end
-- 
1.7.4.4