blob: e9d906f221c92aeed6ed631bbe071479e789d24d [file] [log] [blame]
# 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::Service::Machine < CIMI::Service::Base
metadata :realm,
:constraints => lambda { |c|
c.driver.realms(c.credentials).map { |r| r.id }
}
metadata :machine_image, :type => 'URI'
def self.find(id, context)
instances = []
if id == :all
instances = context.driver.instances(context.credentials)
instances.map { |instance| from_instance(instance, context) }.compact
else
instance = context.driver.instance(context.credentials, :id => id)
raise CIMI::Model::NotFound unless instance
from_instance(instance, context)
end
end
def perform(action, &block)
begin
op = action.operation
op = :reboot if op == :restart
if context.driver.send(:"#{op}_instance", context.credentials, ref_id(id))
block.callback :success
else
raise "Operation #{op} failed to execute on given Machine #{ref_id(id)}"
end
rescue => e
raise
block.callback :failure, e.message
end
end
def self.delete!(id, context)
context.driver.destroy_instance(context.credentials, id)
new(context, :values => { :id => id }).destroy
end
#returns the newly attach machine_volume
def self.attach_volume(volume, location, context)
context.driver.attach_storage_volume(context.credentials,
{:id=>volume, :instance_id=>context.params[:id], :device=>location})
CIMI::Service::MachineVolume.find(context.params[:id], context, volume)
end
#returns the machine_volume_collection for the given machine
def self.detach_volume(volume, location, context)
context.driver.detach_storage_volume(context.credentials,
{:id=>volume, :instance_id=>context.params[:id], :device=>location})
CIMI::Service::MachineVolume.collection_for_instance(context.params[:id], context)
end
def self.from_instance(instance, context)
cpu = memory = (instance.instance_profile.id == "opaque")? "n/a" : nil
machine_conf = CIMI::Service::MachineConfiguration.find(instance.instance_profile.name, context)
machine_spec = {
:name => instance.name,
:created => instance.launch_time.nil? ? Time.now.xmlschema : Time.parse(instance.launch_time.to_s).xmlschema,
:description => "No description set for Machine #{instance.name}",
:id => context.machine_url(instance.id),
:state => convert_instance_state(instance.state),
:cpu => cpu || convert_instance_cpu(instance.instance_profile, context),
:memory => memory || convert_instance_memory(instance.instance_profile, context),
:disks => { :href => context.machine_url(instance.id)+"/disks"},
:volumes => { :href=>context.machine_url(instance.id)+"/volumes"},
:operations => convert_instance_actions(instance, context)
}
if context.expand? :disks
machine_spec[:disks] = CIMI::Service::Disk.find(instance, machine_conf, context, :all)
end
if context.expand? :volumes
machine_spec[:volumes] = CIMI::Service::MachineVolume.find(instance.id, context, :all)
end
machine_spec[:realm] = instance.realm_id if instance.realm_id
machine_spec[:machine_image] = { :href => context.machine_image_url(instance.image_id) } if instance.image_id
self.new(context, :values => machine_spec)
end
# FIXME: This will convert 'RUNNING' state to 'STARTED'
# which is defined in CIMI (p65)
#
def self.convert_instance_state(state)
case state
when "RUNNING" then "STARTED"
when "PENDING" then "CREATING" #aruba only exception... could be "STARTING" here
else state
end
end
def self.convert_instance_cpu(profile, context)
cpu_override = profile.overrides.find { |p, v| p == :cpu }
if cpu_override.nil?
CIMI::Service::MachineConfiguration.find(profile.id, context).cpu
else
cpu_override[1]
end
end
def self.convert_instance_memory(profile, context)
machine_conf = CIMI::Service::MachineConfiguration.find(profile.name, context)
memory_override = profile.overrides.find { |p, v| p == :memory }
memory_override.nil? ? machine_conf.memory.to_i : context.to_kibibyte(memory_override[1].to_i,"MB")
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, context)
actions = instance.actions.collect do |action|
action = :restart if action == :reboot
name = action
name = :delete if action == :destroy # In CIMI destroy operation become delete
{ :href => context.send(:"#{action}_machine_url", instance.id), :rel => "http://schemas.dmtf.org/cimi/1/action/#{name}" }
end
actions << { :href => context.send(:"machine_images_url"), :rel => "http://schemas.dmtf.org/cimi/1/action/capture" } if instance.can_create_image?
actions
end
def self.convert_storage_volumes(instance, context)
instance.storage_volumes ||= [] #deal with nilpointers
instance.storage_volumes.map{|vol| {:href=>context.volume_url(vol.keys.first),
:initial_location=>vol.values.first} }
end
end