1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-22 18:50:08 +03:00

feature #200 Changed OCCI XML Representation

This commit is contained in:
Daniel Molina 2010-07-15 17:04:37 +02:00 committed by Ruben S. Montero
parent bb4a02d539
commit c0149a5bb1
13 changed files with 661 additions and 417 deletions

View File

@ -14,7 +14,6 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
require 'repo_manager'
require 'Configuration'
require 'OpenNebula'
require 'pp'
@ -55,11 +54,6 @@ class CloudServer
@instance_types[@config[:vm_type]['NAME']]=@config[:vm_type]
end
# --- Start a Repository Manager ---
@rm = RepoManager.new(@config[:database])
Image.image_dir = @config[:image_dir]
# --- Start an OpenNebula Session ---
@one_client = Client.new()
@ -124,6 +118,31 @@ class CloudServer
return user
end
def xml_to_hash(xml)
begin
hash = Crack::XML.parse(xml)
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error
end
return hash
end
def get_template_path(instance_type_name)
if instance_type_name.nil?
instance_type=@instance_types.first
end
instance_type=@instance_types[instance_type_name]
if !instance_type
error = OpenNebula::Error.new("Bad instance type")
return error
end
return @config[:template_location]+"/#{instance_type['TEMPLATE']}"
end
###########################################################################
# Repository Methods
@ -134,18 +153,58 @@ class CloudServer
# path:: _String_ path of the tmp file
# metadata:: Additional metadata for the file
# [return] _Image_ Newly created image object
def add_image(uid, file, metadata={})
image = @rm.add(uid,file.path,metadata)
file.unlink
def add_image(image, file=nil)
if file
if file[:tempfile]
file_path = file[:tempfile].path
else
error_msg = "Image not present, aborting."
error = OpenNebula::Error.new(error_msg)
return error
end
if !File.exists?(file_path)
error_msg = "Image file could not be found, aborting."
error = OpenNebula::Error.new(error_msg)
return error
end
end
template = image.to_one_template
return image
rc = image.allocate(template)
if OpenNebula.is_error?(rc)
return rc
end
# Copy the Image file
image.info
template=image.to_hash
template=template['IMAGE']['TEMPLATE']
if file_path
rc = image.copy(file_path, image['SOURCE'])
file[:tempfile].unlink
elsif template['SIZE'] and template['FSTYPE']
rc = image.mk_datablock(
template['SIZE'],
template['FSTYPE'],
image['SOURCE'])
end
if OpenNebula.is_error?(rc)
image.delete
return rc
end
return nil
end
# Gets an image from the repository
# image_id:: _Integer_ Image identifier
# [return] _Image_ Image object
def get_image(image_id)
return @rm.get(image_id)
return nil
end
end

View File

@ -82,7 +82,7 @@ require 'occi/OCCIClient'
require 'CloudClient'
require 'getoptlong'
require "rexml/document"
require 'pp'
include CloudCLI
opts = GetoptLong.new(
@ -166,8 +166,14 @@ case ARGV[0].downcase
rc = occi_client.get_image(image_id)
when 'delete'
puts 'Delete not yet implemented'
exit(-1)
image_id = ARGV[1]
if !image_id
puts "#{cmd_name} show: missing storage id parameter"
exit(-1)
end
rc = occi_client.delete_image(image_id)
else
puts "Command #{ARGV[0]} not valid."

View File

@ -1,55 +1,34 @@
NAME = <%= vm_info['NAME']%>
CPU = 8
MEMORY = 8192
OS = [ kernel = /vmlinuz,
initrd = /initrd.img,
root = sda1,
kernel_cmd = "ro xencons=tty console=tty1"]
<% if vm_info['STORAGE']
vm_info['STORAGE'].each do |key, image|
image=[image].flatten
case key
when "SWAP"
image.each do |img|
%>
DISK = [ type = "swap",
size=<%= img['size']%>,
target=<%= img['dev']%> ]
<%
end
when "DISK"
image.each do |img|
%>
DISK = [ type = "disk",
target=<%= img['dev']%>,
source=<%= img['source']%>,
image_id=<%= img['image']%> ]
<%
end
when "FS"
image.each do |img|
%>
DISK = [ type = "fs",
target=<%= img['dev']%>,
size=<%= img['size']%>,
format=<%= @config[:fs_format]||"ext3"%> ]
<% end %>
<% end %>
<% end %>
<% end %>
<% if vm_info['NETWORK'] and vm_info['NETWORK']['NIC'] %>
<% vm_info['NETWORK']['NIC'].each do |nic| %>
NIC = [
<% if nic['ip'] %>
IP=<%= nic['ip'] %>,
<% end %>
NETWORK="<%= nic['network']%>",
NETWORK_ID=<%= nic['network_id'] %>
]
<% end %>
<% end %>
INSTANCE_TYPE = <%= vm_info[:instance_type ]%>
NAME = <%= vm_info['NAME'] %>
<% if vm_info['DISK'] %>
<% vm_info['DISK'].each do |disk| %>
<% if disk['STORAGE'] && disk['STORAGE']['href'] %>
DISK = [ IMAGE_ID = <%= disk['STORAGE']['href'].split('/').last %>
<% if disk['OVERWRITE'] %>
OVERWRITE = yes
<% end %>
<% if disk['SAVE_AS'] %>
SAVE_AS = "<%= disk['SAVE_AS'] %>"
<% end %>
]
<% end %>
<% end %>
<% end %>
<% if vm_info['NIC'] %>
<% vm_info['NIC'].each do |nic| %>
<% if nic['NETWORK'] && nic['NETWORK']['href'] %>
NIC = [ NETWORK_ID = <%= nic['NETWORK']['href'].split('/').last %>,
<% if nic['IP'] %>
IP = <%= nic['IP'] %>
<% end %>
]
<% end %>
<% end %>
<% end %>
INSTANCE_TYPE = <%= vm_info['INSTANCE_TYPE']%>

View File

@ -15,24 +15,82 @@
#--------------------------------------------------------------------------- #
require 'OpenNebula'
require 'erb'
include OpenNebula
module ImageOCCI
class ImageOCCI < Image
OCCI_IMAGE = %q{
<DISK>
<ID><%= self.id %></ID>
<NAME><%= name %></NAME>
<SIZE><%= ((size/1024)/1024).to_s %></SIZE>
<URL><%= description %></URL>
<ID><%= self.id.to_s %></ID>
<NAME><%= self.name %></NAME>
<% if template['TYPE'] %>
<TYPE><%= template['TYPE'] %></TYPE>
<% end %>
<% if template['DESCRIPTION'] %>
<DESCRIPTION><%= template['DESCRIPTION'] %></DESCRIPTION>
<% end %>
<% if size %>
<SIZE><%= size %></SIZE>
<% end %>
</DISK>
}
ONE_IMAGE = %q{
NAME = "<%= image_info['NAME'] %>"
<% if image_info['DESCRIPTION'] %>
DESCRIPTION = "<%= image_info['DESCRIPTION'] %>"
<% end %>
<% if image_info['TYPE'] %>
TYPE = <%= image_info['TYPE'] %>
<% end %>
<% if image_info['FSTYPE'] %>
FSTYPE = <%= image_info['FSTYPE'] %>
<% end %>
<% if image_info['SIZE'] %>
SIZE = <%= image_info['SIZE'] %>
<% end %>
}.gsub(/^ /, '')
# Class constructor
def initialize(image_info, xml, client)
super(xml, client)
@image_info = image_info
end
# Creates the OCCI representation of an Image
def to_occi()
image_hash = self.to_hash
return image_hash, 500 if OpenNebula.is_error?(image_hash)
template = image_hash['IMAGE']['TEMPLATE']
begin
size = File.stat(template['SOURCE']).size if template['SOURCE']
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error
end
occi = ERB.new(OCCI_IMAGE)
return occi.result(binding).gsub(/\n\s*/,'')
end
def to_one_template()
if @image_info['STORAGE']
image_info = @image_info['STORAGE']
if !image_info['NAME']
error_msg = "Missing Image NAME in the XML DISK section"
error = OpenNebula::Error.new(error_msg)
return error
end
else
error_msg = "Missing STORAGE section in the XML body"
error = OpenNebula::Error.new(error_msg)
return error
end
one = ERB.new(ONE_IMAGE)
return one.result(binding)
end
end

View File

@ -16,25 +16,35 @@
require 'OpenNebula'
include OpenNebula
class ImagePoolOCCI
class ImagePoolOCCI < ImagePool
OCCI_IMAGE_POOL = %q{
<STORAGE><%
for image in @images do %>
<DISK href="<%= base_url%>/storage/<%= image[:id] %>"/><%
end %>
</STORAGE>
<STORAGE_COLLECTION>
<% if pool_hash['IMAGE_POOL'] && pool_hash['IMAGE_POOL']['IMAGE'] %>
<% imagelist=[pool_hash['IMAGE_POOL']['IMAGE']].flatten %>
<% imagelist.each{ |image| %>
<STORAGE href="<%= base_url %>/storage/<%= image['ID'] %>"/>
<% } %>
<% end %>
</STORAGE_COLLECTION>
}
def initialize(user_id)
@images=Image.filter(:owner => user_id)
end
# Creates the OCCI representation of a Virtual Machine Pool
def to_occi(base_url)
occi = ERB.new(OCCI_IMAGE_POOL)
return occi.result(binding).gsub(/\n\s*/,'')
pool_hash = self.to_hash
return pool_hash, 500 if OpenNebula.is_error?(pool_hash)
begin
occi = ERB.new(OCCI_IMAGE_POOL)
occi_text = occi.result(binding)
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error
end
return occi_text.gsub(/\n\s*/,'')
end
end

View File

@ -164,7 +164,7 @@ module OCCIClient
xml=File.read(xmlfile)
image_info=Crack::XML.parse(xml)
file_path = image_info['DISK']['URL']
file_path = image_info['STORAGE']['URL']
m=file_path.match(/^\w+:\/\/(.*)$/)
@ -210,7 +210,7 @@ module OCCIClient
end
file.close
pp res
if CloudClient::is_error?(res)
return res
else
@ -370,5 +370,25 @@ module OCCIClient
return res.body
end
end
######################################################################
# :id VM identifier
######################################################################
def delete_image(id)
url = URI.parse(@endpoint+"/storage/" + id.to_s)
req = Net::HTTP::Delete.new(url.path)
req.basic_auth @occiauth[0], @occiauth[1]
res = CloudClient::http_start(url, @timeout) {|http|
http.request(req)
}
if CloudClient::is_error?(res)
return res
else
return res.body
end
end
end
end

View File

@ -31,7 +31,7 @@ require 'VirtualNetworkPoolOCCI'
require 'ImageOCCI'
require 'ImagePoolOCCI'
include ImageOCCI
require 'pp'
##############################################################################
@ -102,153 +102,110 @@ class OCCIServer < CloudServer
# request:: _Hash_ hash containing the data of the request
# [return] _String_,_Integer_ COMPUTE Representation or error, status code
def post_compute(request)
# Get client with user credentials
# --- Get client with user credentials ---
client = get_client(request.env)
# --- Check OCCI XML from POST ---
if request.body
vm_info=Crack::XML.parse(request.body.read)
vm_info = xml_to_hash(request.body.read)
return vm_info, 400 if OpenNebula.is_error?(vm_info)
else
error = OpenNebula::Error.new(
"OCCI XML representation of VM not present")
error_msg = "OCCI XML representation of VM not present"
error = OpenNebula::Error.new(error_msg)
return error, 400
end
vm_info=vm_info['COMPUTE']
disks=vm_info['STORAGE']
disks['DISK']=[disks['DISK']].flatten if disks and disks['DISK']
disks['DISK'].each{|disk|
next if !disk['image']
image = get_image(disk['image'])
if !image
error = OpenNebula::Error.new(
"Invalid image (#{disk['image']}) referred")
return error, 400
end
disk['source']=image.path
} if disks and disks['DISK']
vm_info['STORAGE']=disks
if vm_info['NETWORK'] and vm_info['NETWORK']['NIC']
if vm_info['NETWORK']['NIC'].class==Array
nics=vm_info['NETWORK']['NIC']
else
nics=[vm_info['NETWORK']['NIC']]
end
nics.each{|nic|
next if nic==nil
vn=VirtualNetwork.new(
VirtualNetwork.build_xml(nic['network']),
client)
vn.info
vn_xml=Crack::XML.parse(vn.to_xml)
if !vn_xml['VNET']['NAME']
error = OpenNebula::Error.new(
"Invalid network referred")
return error, 400
end
nic['network_id']=nic['network']
nic['network']=vn_xml['VNET']['NAME'].strip
} if nics
vm_info['NETWORK']['NIC']=nics
# --- Get Template Path ---
if vm_info['COMPUTE']
template_path = get_template_path(
vm_info['COMPUTE']['INSTANCE_TYPE'])
end
instance_type_name=vm_info['INSTANCE_TYPE']
instance_type=@instance_types[instance_type_name]
if !instance_type
error = OpenNebula::Error.new("Bad instance type")
return error, 400
end
vm_info[:instance_type]=instance_type_name
template=ERB.new(File.read(
@config[:template_location]+"/#{instance_type['TEMPLATE']}"))
template_text=template.result(binding)
vm=VirtualMachineOCCI.new(
return template_path, 500 if OpenNebula.is_error?(template_path)
vm_info['TEMPLATE_PATH'] = template_path
# --- Create the new Instance ---
vm = VirtualMachineOCCI.new(
vm_info,
VirtualMachine.build_xml,
client)
response=vm.allocate(template_text)
if OpenNebula.is_error?(response)
return response, 400
else
vm.info
return vm.to_occi(@base_url), 201
end
# --- Generate the template and Allocate the new Instance ---
template = vm.to_one_template
return template, 500 if OpenNebula.is_error?(template)
rc = vm.allocate(template)
return rc, 500 if OpenNebula.is_error?(rc)
# --- Prepare XML Response ---
vm.info
xml_response = vm.to_occi(@base_url)
return xml_response, 500 if OpenNebula.is_error?(xml_response)
return xml_response, 201
end
# Gets the pool representation of COMPUTES
# request:: _Hash_ hash containing the data of the request
# [return] _String_,_Integer_ Pool Representation or error, status code
def get_computes(request)
# Get client with user credentials
# --- Get client with user credentials ---
client = get_client(request.env)
# Just show resources from the user making the request
# --- Get User's VMs ---
user_flag = -1
vmpool = VirtualMachinePoolOCCI.new(client,user_flag)
vmpool.info
# OCCI conversion
begin
compute_xml = vmpool.to_occi(@base_url)
return compute_xml, 200
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error, 500
end
vmpool = VirtualMachinePoolOCCI.new(client, user_flag)
rc = vmpool.info
return rc, 404 if OpenNebula.is_error?(rc)
# --- Prepare XML Response ---
xml_response = vmpool.to_occi(@base_url)
return xml_response, 500 if OpenNebula.is_error?(xml_response)
return xml_response, 201
end
# Post a new network to the NETWORK pool
# request:: _Hash_ hash containing the data of the request
# [return] _String_,_Integer_ Network Representation or error, status code
def post_network(request)
# Get client with user credentials
# --- Get client with user credentials ---
client = get_client(request.env)
# Info retrieval from post params
# --- Check OCCI XML from POST ---
if request.body
network_info=Crack::XML.parse(request.body.read)
network_info = xml_to_hash(request.body.read)
return network_info, 400 if OpenNebula.is_error?(network_info)
else
error_msg = "OCCI XML representation of Virtual Network" +
" not present in the request"
error = OpenNebula::Error.new(error_msg)
return error, 400
error_msg = "OCCI XML representation of VNET not present"
error = OpenNebula::Error.new(error_msg)
return error, 400
end
# Allocate the VirtualNetwork
if network_info['NETWORK']
network_info['NETWORK']['BRIDGE'] = @config[:bridge]
end
# --- Create the new Instance ---
network = VirtualNetworkOCCI.new(
VirtualNetwork.build_xml,
client)
network_info,
VirtualNetwork.build_xml,
client)
begin
vntemplate = network.to_one_template(
network_info['NETWORK'],
@config[:bridge])
rc = network.allocate(vntemplate)
# --- Generate the template and Allocate the new Instance ---
template = network.to_one_template
return template, 500 if OpenNebula.is_error?(template)
if OpenNebula::is_error?(rc)
return rc, 404
end
rc = network.allocate(template)
return rc, 500 if OpenNebula.is_error?(rc)
network.info
network_xml = network.to_occi
return network_xml, 201
rescue Exception => e
error_msg = "Error creating the Virtual Network:" + e.to_s
error_msg = ".Reason:" + rc if rc
error = OpenNebula::Error.new(error_msg)
return error, 500
end
# --- Prepare XML Response ---
network.info
xml_response = network.to_occi
return xml_response, 500 if OpenNebula.is_error?(xml_response)
return xml_response, 201
end
# Gets the pool representation of NETWORKS
@ -256,54 +213,52 @@ class OCCIServer < CloudServer
# [return] _String_,_Integer_ Network pool representation or error,
# => status code
def get_networks(request)
# Get client with user credentials
# --- Get client with user credentials ---
client = get_client(request.env)
# --- Get User's VNETs ---
user_flag = -1
network_pool = VirtualNetworkPoolOCCI.new(client, user_flag)
# Info retrieval
network_pool = VirtualNetworkPoolOCCI.new(client)
network_pool.info
# OCCI conversion
begin
network_pool.to_occi(@base_url)
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error, 500
end
rc = network_pool.info
return rc, 404 if OpenNebula.is_error?(rc)
# --- Prepare XML Response ---
xml_response = network_pool.to_occi(@base_url)
return xml_response, 500 if OpenNebula.is_error?(xml_response)
return xml_response, 201
end
# Post a new image to the STORAGE pool
# request:: _Hash_ hash containing the data of the request
# [return] _String_,_Integer_ Image representation or error, status code
def post_storage(request)
# Info retrieval from post params
# Get client with user credentials
client = get_client(request.env)
# --- Check OCCI XML from POST ---
if request.params['occixml']
image_info=Crack::XML.parse(request.params['occixml'])
image_info = xml_to_hash(request.params['occixml'])
return image_info, 400 if OpenNebula.is_error?(image_info)
else
error_msg = "OCCI XML representation of Image" +
" not present in the request"
error = OpenNebula::Error.new(error_msg)
error = OpenNebula::Error.new(error_msg)
return error, 400
end
# --- Create and Add the new Image ---
image = ImageOCCI.new(image_info, Image.build_xml, client)
if request.params['file']
file=request.params["file"]
else
error_msg = "File not present in the request"
error = OpenNebula::Error.new(error_msg)
return error, 400
end
user = get_user(request.env)
# tmpfile where the file is stored
f_tmp=file[:tempfile]
img=add_image(user[:id], f_tmp, {:name=>image_info['DISK']['NAME'],
:description=>image_info['DISK']['URL']})
img.extend(ImageOCCI)
xml_response = img.to_occi
rc = add_image(image, request.params['file'])
return rc, 500 if OpenNebula.is_error?(rc)
return xml_response, 201
# --- Enable the new Image ---
rc = image.enable
return rc, 500 if OpenNebula.is_error?(rc)
return image.to_occi, 201
end
# Gets the pool representation of STORAGES
@ -311,11 +266,21 @@ class OCCIServer < CloudServer
# [return] _String_,_Integer_ Image pool representation or error,
# status code
def get_storages(request)
# Retrieve images owned by this user
user = get_user(request.env)
image_pool = ImagePoolOCCI.new(user[:id])
return image_pool.to_occi(@base_url), 200
# --- Get client with user credentials ---
client = get_client(request.env)
# --- Get User's Images ---
user_flag = -1
image_pool = ImagePoolOCCI.new(client, user_flag)
result = image_pool.info
return result, 404 if OpenNebula.is_error?(result)
# --- Prepare XML Response ---
xml_response = image_pool.to_occi(@base_url)
return xml_response, 500 if OpenNebula.is_error?(xml_response)
return xml_response, 201
end
###################################################
@ -327,27 +292,23 @@ class OCCIServer < CloudServer
# [return] _String_,_Integer_ COMPUTE representation or error,
# status code
def get_compute(request, params)
# Get client with user credentials
# --- Get client with user credentials ---
client = get_client(request.env)
# --- Get the VM ---
vm = VirtualMachineOCCI.new(
VirtualMachine.build_xml(params[:id]),
client)
nil,
VirtualMachine.build_xml(params[:id]),
client)
result=vm.info
result = vm.info
return result, 404 if OpenNebula::is_error?(result)
if OpenNebula::is_error?(result)
return result, 404
end
begin
return vm.to_occi(@base_url), 200
rescue Exception => e
error_msg = "Error converting COMPUTE resource to OCCI format"
error_msg = "\n Reason: " + e.message
error = OpenNebula::Error.new(error_msg)
return error, 500
end
# --- Prepare XML Response ---
xml_response = vm.to_occi(@base_url)
return xml_response, 500 if OpenNebula.is_error?(xml_response)
return xml_response, 201
end
# Deletes a COMPUTE resource
@ -355,20 +316,20 @@ class OCCIServer < CloudServer
# [return] _String_,_Integer_ Delete confirmation msg or error,
# status code
def delete_compute(request, params)
# Get client with user credentials
# --- Get client with user credentials ---
client = get_client(request.env)
vm = VirtualMachineOCCI.new(
nil,
VirtualMachine.build_xml(params[:id]),
client)
# --- Finalize the VM ---
result = vm.finalize
pp result
return result, 500 if OpenNebula::is_error?(result)
if OpenNebula::is_error?(result)
return result, 500
else
return "", 204
end
return "", 204
end
# Updates a COMPUTE resource
@ -376,53 +337,40 @@ class OCCIServer < CloudServer
# [return] _String_,_Integer_ Update confirmation msg or error,
# status code
def put_compute(request, params)
# Get client with user credentials
# --- Get client with user credentials ---
client = get_client(request.env)
# --- Check OCCI XML from POST ---
if request.body
vm_info=Crack::XML.parse(request.body.read)
vm_info = xml_to_hash(request.body.read)
return vm_info, 400 if OpenNebula.is_error?(vm_info)
else
error_msg = "OCCI XML representation of VM not present"
error = OpenNebula::Error.new(error_msg)
error = OpenNebula::Error.new(error_msg)
return error, 400
end
vm=VirtualMachineOCCI.new(
VirtualMachine.build_xml(params[:id]),
client)
if !vm_info['COMPUTE']['STATE']
error_msg = "State not defined in the OCCI XML"
error = OpenNebula::Error.new(error_msg)
# --- Get the VM and Action on it ---
if vm_info['COMPUTE'] && vm_info['COMPUTE']['STATE']
vm = VirtualMachineOCCI.new(
vm_info,
VirtualMachine.build_xml(params[:id]),
client)
rc = vm.mk_action(vm_info['COMPUTE']['STATE'])
return rc, 400 if OpenNebula.is_error?(rc)
else
error_msg = "State not defined in the OCCI XML"
error = OpenNebula::Error.new(error_msg)
return error, 400
end
case vm_info['COMPUTE']['STATE'].downcase
when "stopped"
rc = vm.stop
when "suspended"
rc = vm.suspend
when "resume"
rc = vm.resume
when "cancel"
rc = vm.cancel
when "shutdown"
rc = vm.shutdown
when "done"
rc = vm.finalize
else
error_msg = "Invalid state"
error = OpenNebula::Error.new(error_msg)
return error, 400
end
if OpenNebula.is_error?(rc)
return rc, 400
else
vm.info
response_text = vm.to_occi(@base_url)
return response_text, 202
end
# --- Prepare XML Response ---
vm.info
xml_response = vm.to_occi(@base_url)
return xml_response, 500 if OpenNebula.is_error?(xml_response)
return xml_response, 202
end
# Retrieves a NETWORK resource
@ -430,25 +378,23 @@ class OCCIServer < CloudServer
# [return] _String_,_Integer_ NETWORK occi representation or error,
# status code
def get_network(request, params)
# Get client with user credentials
# --- Get client with user credentials ---
client = get_client(request.env)
# --- Get the VM ---
vn = VirtualNetworkOCCI.new(
nil,
VirtualNetwork.build_xml(params[:id]),
client)
result = vn.info
return result, 404 if OpenNebula::is_error?(result)
# --- Prepare XML Response ---
xml_response = vn.to_occi
return xml_response, 500 if OpenNebula.is_error?(xml_response)
vn = VirtualNetworkOCCI.new(
VirtualNetwork.build_xml(params[:id]),
client)
result=vn.info
if OpenNebula::is_error?(result)
return result, 404
end
begin
return vn.to_occi, 200
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error, 500
end
return xml_response, 200
end
# Deletes a NETWORK resource
@ -456,20 +402,19 @@ class OCCIServer < CloudServer
# [return] _String_,_Integer_ Delete confirmation msg or error,
# status code
def delete_network(request, params)
# Get client with user credentials
# --- Get client with user credentials ---
client = get_client(request.env)
vn = VirtualNetworkOCCI.new(
nil,
VirtualNetwork.build_xml(params[:id]),
client)
# --- Delete the VNET ---
result = vn.delete
if OpenNebula::is_error?(result)
return result, 500
else
return "", 204
end
return result, 500 if OpenNebula::is_error?(result)
return "", 204
end
# Get a STORAGE resource
@ -477,19 +422,20 @@ class OCCIServer < CloudServer
# [return] _String_,_Integer_ STORAGE occi representation or error,
# status code
def get_storage(request, params)
# Get client with user credentials
# --- Get client with user credentials ---
client = get_client(request.env)
image=get_image(params[:id])
if image
image.extend(ImageOCCI)
return image.to_occi, 200
else
msg="Disk with id = \"" + params[:id] + "\" not found"
error = OpenNebula::Error.new(msg)
return error, 404
end
# --- Get the Image ---
image = ImageOCCI.new(nil, Image.build_xml(params[:id]), client)
result = image.info
return result, 404 if OpenNebula::is_error?(result)
# --- Prepare XML Response ---
xml_response = image.to_occi
return xml_response, 500 if OpenNebula.is_error?(xml_response)
return xml_response, 200
end
# Deletes a STORAGE resource (Not yet implemented)
@ -497,7 +443,15 @@ class OCCIServer < CloudServer
# [return] _String_,_Integer_ Delete confirmation msg or error,
# status code
def delete_storage(request, params)
error = OpenNebula::Error.new("Not yet implemented")
return error, 501
# --- Get client with user credentials ---
client = get_client(request.env)
image = ImageOCCI.new(nil, Image.build_xml(params[:id]), client)
# --- Delete the Image ---
result = image.delete
return result, 500 if OpenNebula::is_error?(result)
return "", 204
end
end

View File

@ -1,3 +1,19 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
# Licensed 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. #
#--------------------------------------------------------------------------- #
require 'OpenNebula'
include OpenNebula
@ -5,50 +21,111 @@ include OpenNebula
class VirtualMachineOCCI < VirtualMachine
OCCI_VM = %q{
<COMPUTE>
<ID><%= id.to_s%></ID>
<NAME><%= self['NAME']%></NAME>
<STATE><%= state_str %></STATE>
<% if template['DISK']!=nil
%><STORAGE><%
template['DISK'].each do |disk|
next if !disk
case disk['TYPE']
when "swap"%>
<DISK type="swap" size="<%= disk['SIZE']%>" dev="<%= disk['TARGET']%>"/><% when "fs" %>
<DISK type="fs" size="<%= disk['SIZE']%>" format="<%= disk['FORMAT']%>" dev="<%= disk['TARGET']%>"/><%
else %>
<DISK type="disk" href="<%= base_url%>/storage/<%= disk['IMAGE_ID']%>" dev="<%= disk['TARGET']%>"/><%
end
end %>
</STORAGE>
<% end
if template['NIC']
%><NETWORK><%
template['NIC'].each do |nic|
next if !nic %>
<NIC href="<%= base_url%>/network/<%= nic['VNID']%>"<% if nic['IP'] %> ip="<%= nic['IP']%>"<% end %>/><%
end
%>
</NETWORK><%
end
if template['INSTANCE_TYPE'] %>
<INSTANCE_TYPE><%=template['INSTANCE_TYPE']%></INSTANCE_TYPE><%
end %>
<ID><%= self.id.to_s%></ID>
<NAME><%= self.name%></NAME>
<% if template['INSTANCE_TYPE'] %>
<INSTANCE_TYPE><%= template['INSTANCE_TYPE'] %></INSTANCE_TYPE>
<% end %>
<STATE><%= self.state_str %></STATE>
<% if template['DISK'] %>
<% template['DISK'].each do |disk| %>
<DISK>
<STORAGE href="<%= base_url %>/storage/<%= disk['IMAGE_ID'] %>"/>
<NAME><%= disk['NAME'] %></NAME>
<TYPE><%= disk['TYPE'] %></TYPE>
<TARGET><%= disk['TARGET'] %></TARGET>
<% if disk['CLONE'] %>
<OVERWRITE/>
<% end %>
<% if disk['SAVE_AS'] %>
<SAVE_AS><%= disk['SAVE_AS'] %></SAVE_AS>
<% end %>
</DISK>
<% end %>
<% end %>
<% if template['NIC'] %>
<% template['NIC'].each do |nic| %>
<NIC>
<NETWORK href="<%= base_url %>/network/<%= nic['NETWORK_ID'] %>"/>
<% if nic['IP'] %>
<IP><%= nic['IP'] %></IP>
<% end %>
</NIC>
<% end %>
<% end %>
</COMPUTE>
}
# Class constructor
def initialize(vm_info, xml, client)
super(xml, client)
@vm_info = vm_info
end
def mk_action(action_str)
case action_str.downcase
when "stopped"
rc = self.stop
when "suspended"
rc = self.suspend
when "resume"
rc = self.resume
when "cancel"
rc = self.cancel
when "shutdown"
rc = self.shutdown
when "done"
rc = self.finalize
else
error_msg = "Invalid state"
error = OpenNebula::Error.new(error_msg)
return error
end
return rc
end
def to_one_template()
if @vm_info['COMPUTE']
vm_info = @vm_info['COMPUTE']
vm_info['DISK'] = [vm_info['DISK']].flatten if vm_info['DISK']
vm_info['NIC'] = [vm_info['NIC']].flatten if vm_info['NIC']
else
error_msg = "Missing COMPUTE section in the XML body"
error = OpenNebula::Error.new(error_msg)
return error, 400
end
begin
template = ERB.new(File.read(@vm_info['TEMPLATE_PATH']))
template_text = template.result(binding)
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error
end
return template_text
end
# Creates the VMI representation of a Virtual Machine
def to_occi(base_url)
# Let's parse the template
template=self.to_hash
template=template['VM']['TEMPLATE']
vm_hash = self.to_hash
return vm_hash, 500 if OpenNebula.is_error?(vm_hash)
template = vm_hash['VM']['TEMPLATE']
template['DISK']=[template['DISK']].flatten if template['DISK']
template['NIC']=[template['NIC']].flatten if template['NIC']
occi = ERB.new(OCCI_VM)
return occi.result(binding).gsub(/\n\s*/,'')
begin
occi_vm = ERB.new(OCCI_VM)
occi_vm_text = occi_vm.result(binding)
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error
end
return occi_vm_text.gsub(/\n\s*/,'')
end
end

View File

@ -1,26 +1,50 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
# Licensed 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. #
#--------------------------------------------------------------------------- #
require 'OpenNebula'
include OpenNebula
class VirtualMachinePoolOCCI < VirtualMachinePool
OCCI_VM_POOL = %q{
<COMPUTES><%
if pool_hash['VM_POOL'] != nil
vmlist=[pool_hash['VM_POOL']['VM']].flatten
vmlist.each{|vm| %>
<COMPUTE href="<%= base_url %>/compute/<%= vm['ID'].strip %>"/><%
}
end %>
</COMPUTES>
<COMPUTE_COLLECTION>
<% if pool_hash['VM_POOL'] && pool_hash['VM_POOL']['VM'] %>
<% vmlist=[pool_hash['VM_POOL']['VM']].flatten %>
<% vmlist.each{ |vm| %>
<COMPUTE href="<%= base_url %>/compute/<%= vm['ID'] %>"/>
<% } %>
<% end %>
</COMPUTE_COLLECTION>
}
# Creates the OCCI representation of a Virtual Machine Pool
def to_occi(base_url)
pool_hash=to_hash
occi = ERB.new(OCCI_VM_POOL)
return occi.result(binding).gsub(/\n\s*/,'')
pool_hash = self.to_hash
return pool_hash, 500 if OpenNebula.is_error?(pool_hash)
begin
occi = ERB.new(OCCI_VM_POOL)
occi_text = occi.result(binding)
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error
end
return occi_text.gsub(/\n\s*/,'')
end
end

View File

@ -15,38 +15,64 @@
#--------------------------------------------------------------------------- #
require 'OpenNebula'
require 'erb'
include OpenNebula
class VirtualNetworkOCCI < VirtualNetwork
OCCI_NETWORK = %q{
<NETWORK>
<ID><%= vn_hash['VNET']['ID'].strip %></ID>
<NAME><%= vn_hash['VNET']['NAME'].strip %></NAME>
<ADDRESS><%= vn_hash['VNET']['TEMPLATE']['NETWORK_ADDRESS'].strip %></ADDRESS>
<SIZE><%= vn_hash['VNET']['TEMPLATE']['NETWORK_SIZE'].strip %></SIZE>
<ID><%= self.id.to_s %></ID>
<NAME><%= self.name %></NAME>
<ADDRESS><%= template['NETWORK_ADDRESS'] %></ADDRESS>
<% if template['NETWORK_SIZE'] %>
<SIZE><%= template['NETWORK_SIZE'] %></SIZE>
<% end %>
</NETWORK>
}
ONE_NETWORK = %q{
NAME = <%= network_hash['NAME'] %>
NAME = <%= vnet_info['NAME'] %>
TYPE = RANGED
BRIDGE = <%= bridge %>
NETWORK_ADDRESS = <%= network_hash['ADDRESS'] %>
NETWORK_SIZE = <%= network_hash['SIZE'] %>
BRIDGE = <%= vnet_info['BRIDGE'] %>
NETWORK_ADDRESS = <%= vnet_info['ADDRESS'] %>
NETWORK_SIZE = <%= vnet_info['SIZE'] %>
}.gsub(/^ /, '')
# Creates the OCCI representation of a Virtual Network
def to_occi()
vn_hash = to_hash
# Class constructor
def initialize(vnet_info, xml, client)
super(xml, client)
occi = ERB.new(OCCI_NETWORK)
return occi.result(binding).gsub(/\n\s*/,'')
@vnet_info = vnet_info
end
def to_one_template(network_hash, bridge)
one = ERB.new(ONE_NETWORK)
return one.result(binding)
# Creates the OCCI representation of a Virtual Network
def to_occi()
vn_hash = self.to_hash
return vn_hash, 500 if OpenNebula.is_error?(vn_hash)
template = vn_hash['VNET']['TEMPLATE']
begin
occi = ERB.new(OCCI_NETWORK)
occi_text = occi.result(binding)
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error
end
return occi_text.gsub(/\n\s*/,'')
end
def to_one_template()
if @vnet_info['NETWORK']
vnet_info = @vnet_info['NETWORK']
else
error_msg = "Missing STORAGE section in the XML body"
error = OpenNebula::Error.new(error_msg)
return error
end
one = ERB.new(ONE_NETWORK)
return one.result(binding)
end
end

View File

@ -1,25 +1,49 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
# Licensed 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. #
#--------------------------------------------------------------------------- #
require 'OpenNebula'
include OpenNebula
class VirtualNetworkPoolOCCI < VirtualNetworkPool
OCCI_NETWORK_POOL = %q{
<NETWORKS><%
if network_pool_hash['VNET_POOL'] != nil
vnlist=[network_pool_hash['VNET_POOL']['VNET']].flatten
vnlist.each{|network|%>
<NETWORK href="<%= base_url %>/network/<%= network['ID'].strip
%>"/><%
}
end %>
</NETWORKS>
<NETWORK_COLLECTION>
<% if pool_hash['VNET_POOL'] && pool_hash['VNET_POOL']['VNET'] %>
<% vnlist=[pool_hash['VNET_POOL']['VNET']].flatten %>
<% vnlist.each{ |vn| %>
<NETWORK href="<%= base_url %>/network/<%= vn['ID'] %>"/>
<% } %>
<% end %>
</NETWORK_COLLECTION>
}
# Creates the OCCI representation of a Virtual Network
def to_occi(base_url)
network_pool_hash=to_hash
occi = ERB.new(OCCI_NETWORK_POOL)
return occi.result(binding).gsub(/\n\s*/,'')
# Creates the OCCI representation of a Virtual Machine Pool
def to_occi(base_url)
pool_hash = self.to_hash
return pool_hash, 500 if OpenNebula.is_error?(pool_hash)
begin
occi = ERB.new(OCCI_NETWORK_POOL)
occi_text = occi.result(binding)
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error
end
return occi_text.gsub(/\n\s*/,'')
end
end
end

View File

@ -72,6 +72,8 @@ end
helpers do
def treat_response(result,rc)
if OpenNebula::is_error?(result)
pp 'siiii'
pp rc
halt rc, result.message
end

View File

@ -99,7 +99,12 @@ module OpenNebula
def to_hash
if !@hash && @xml
@hash=Crack::XML.parse(to_xml)
begin
@hash = Crack::XML.parse(to_xml)
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error
end
end
return @hash
end