From: Michal Fojtik <[email protected]>
Signed-off-by: Michal fojtik <[email protected]> --- 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
