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:57 UTC

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

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