#--------------------------------------------------------------------------- # # Copyright 2002-2009, Distributed Systems Architecture Group, Universidad # Complutense de Madrid (dsa-research.org) # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #--------------------------------------------------------------------------- # require 'deltacloud/base_driver' require 'erb' require 'rexml/document' path = File.dirname(__FILE__) $: << path require 'occi_client' module Deltacloud module Drivers module Opennebula class OpennebulaDriver < Deltacloud::BaseDriver ###################################################################### # Hardware profiles ###################################################################### define_hardware_profile 'small' define_hardware_profile 'medium' define_hardware_profile 'large' ###################################################################### # Realms ###################################################################### (REALMS = [ Realm.new( { :id=>'Any id', :name=>'Any name', :limit=>:unlimited, :state=>'Any state', } ), ] ) unless defined?( REALMS ) def realms(credentials, opts=nil) return REALMS if ( opts.nil? ) results = REALMS results = filter_on( results, :id, opts ) results end ###################################################################### # Images ###################################################################### def images(credentials, opts=nil) occi_client = new_client(credentials) images = [] imagesxml = occi_client.get_images storage = REXML::Document.new(imagesxml) storage.root.elements.each do |d| id = d.attributes['href'].split("/").last diskxml = occi_client.get_image(id) images << convert_image(diskxml.to_s(), credentials) end images end ###################################################################### # Instances ###################################################################### define_instance_states do start.to( :pending ) .on( :create ) pending.to( :running ) .automatically running.to( :stopped ) .on( :stop ) stopped.to( :running ) .on( :start ) stopped.to( :finish ) .on( :destroy ) end def instances(credentials, opts=nil) occi_client = new_client(credentials) instances = [] instancesxml = occi_client.get_vms computes = REXML::Document.new(instancesxml) computes.root.elements.each do |d| vm_id = d.attributes['href'].split("/").last computexml = occi_client.get_vm(vm_id) instances << convert_instance(computexml.to_s(), credentials) end instances = filter_on( instances, :id, opts ) instances = filter_on( instances, :state, opts ) instances end def create_instance(credentials, image_id, opts=nil) occi_client = new_client(credentials) hwp_id = opts[:hwp_id] || 'small' instancexml = ERB.new(OCCI_VM).result(binding) instancefile = "|echo '#{instancexml}'" xmlvm = occi_client.post_vms(instancefile) convert_instance(xmlvm.to_s(), credentials) end def start_instance(credentials, id) occi_action(credentials, id, 'RESUME') end def stop_instance(credentials, id) occi_action(credentials, id, 'STOPPED') end def destroy_instance(credentials, id) occi_action(credentials, id, 'DONE') end private def new_client(credentials) OCCIClient::Client.new(nil, credentials.user, credentials.password, false) end def convert_image(diskxml, credentials) disk = REXML::Document.new(diskxml) diskhash = disk.root.elements Image.new( { :id=>diskhash['ID'].text, :name=>diskhash['NAME'].text, :description=>diskhash['NAME'].text, :owner_id=>credentials.user, :architecture=>'Any architecture', } ) end def convert_instance(computexml, credentials) compute = REXML::Document.new(computexml) computehash = compute.root.elements imageid = computehash['STORAGE/DISK[@type="disk"]'].attributes['href'].split("/").last state = (computehash['STATE'].text == "ACTIVE") ? "RUNNING" : "STOPPED" hwp_name = computehash['INSTANCE_TYPE'] || 'small' networks = [] (computehash['NETWORK'].each do |n| networks << n.attributes['ip'] end) unless computehash['NETWORK'].nil? Instance.new( { :id=>computehash['ID'].text, :owner_id=>credentials.user, :name=>computehash['NAME'].text, :image_id=>imageid, :instance_profile=>InstanceProfile.new(hwp_name), :realm_id=>'Any realm', :state=>state, :public_addreses=>networks, :private_addreses=>networks, :actions=> instance_actions_for( state ) } ) end def occi_action(credentials, id, strstate) occi_client = new_client(credentials) actionxml = ERB.new(OCCI_ACTION).result(binding) actionfile = "|echo '#{actionxml}'" xmlvm = occi_client.put_vm(actionfile) convert_instance(xmlvm.to_s(), credentials) end (OCCI_VM = %q{ <%=opts[:name]%> <%= hwp_id %> }.gsub(/^ /, '') ) unless defined?( OCCI_VM ) (OCCI_ACTION = %q{ <%= id %> <%= strstate %> }.gsub(/^ /, '') ) unless defined?( OCCI_ACTION ) end end end end