diff --git a/src/cloud/common/CloudServer.rb b/src/cloud/common/CloudServer.rb
index a76a6a5040..74b2d62985 100755
--- a/src/cloud/common/CloudServer.rb
+++ b/src/cloud/common/CloudServer.rb
@@ -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
diff --git a/src/cloud/occi/bin/occi-storage b/src/cloud/occi/bin/occi-storage
index 3e6e2dbf0d..93b6436d3f 100755
--- a/src/cloud/occi/bin/occi-storage
+++ b/src/cloud/occi/bin/occi-storage
@@ -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."
diff --git a/src/cloud/occi/etc/templates/large.erb b/src/cloud/occi/etc/templates/large.erb
index b88a916363..cbc429b343 100644
--- a/src/cloud/occi/etc/templates/large.erb
+++ b/src/cloud/occi/etc/templates/large.erb
@@ -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']%>
diff --git a/src/cloud/occi/lib/ImageOCCI.rb b/src/cloud/occi/lib/ImageOCCI.rb
index 781423a5c9..acee97b1eb 100755
--- a/src/cloud/occi/lib/ImageOCCI.rb
+++ b/src/cloud/occi/lib/ImageOCCI.rb
@@ -15,24 +15,82 @@
#--------------------------------------------------------------------------- #
require 'OpenNebula'
-require 'erb'
include OpenNebula
-module ImageOCCI
+class ImageOCCI < Image
OCCI_IMAGE = %q{
- <%= self.id %>
- <%= name %>
- <%= ((size/1024)/1024).to_s %>
- <%= description %>
+ <%= self.id.to_s %>
+ <%= self.name %>
+ <% if template['TYPE'] %>
+ <%= template['TYPE'] %>
+ <% end %>
+ <% if template['DESCRIPTION'] %>
+ <%= template['DESCRIPTION'] %>
+ <% end %>
+ <% if size %>
+ <%= size %>
+ <% end %>
}
+ 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
diff --git a/src/cloud/occi/lib/ImagePoolOCCI.rb b/src/cloud/occi/lib/ImagePoolOCCI.rb
index 596c139575..ebc73dd0b3 100755
--- a/src/cloud/occi/lib/ImagePoolOCCI.rb
+++ b/src/cloud/occi/lib/ImagePoolOCCI.rb
@@ -16,25 +16,35 @@
require 'OpenNebula'
-
include OpenNebula
-class ImagePoolOCCI
+class ImagePoolOCCI < ImagePool
OCCI_IMAGE_POOL = %q{
- <%
- for image in @images do %>
- <%
- end %>
-
+
+ <% if pool_hash['IMAGE_POOL'] && pool_hash['IMAGE_POOL']['IMAGE'] %>
+ <% imagelist=[pool_hash['IMAGE_POOL']['IMAGE']].flatten %>
+ <% imagelist.each{ |image| %>
+
+ <% } %>
+ <% end %>
+
}
-
- 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
diff --git a/src/cloud/occi/lib/OCCIClient.rb b/src/cloud/occi/lib/OCCIClient.rb
index ab94afe059..25e29edc74 100755
--- a/src/cloud/occi/lib/OCCIClient.rb
+++ b/src/cloud/occi/lib/OCCIClient.rb
@@ -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
diff --git a/src/cloud/occi/lib/OCCIServer.rb b/src/cloud/occi/lib/OCCIServer.rb
index 4e46eef40c..8b10e079fc 100755
--- a/src/cloud/occi/lib/OCCIServer.rb
+++ b/src/cloud/occi/lib/OCCIServer.rb
@@ -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
diff --git a/src/cloud/occi/lib/VirtualMachineOCCI.rb b/src/cloud/occi/lib/VirtualMachineOCCI.rb
index 3b0923de50..1f9954cab6 100755
--- a/src/cloud/occi/lib/VirtualMachineOCCI.rb
+++ b/src/cloud/occi/lib/VirtualMachineOCCI.rb
@@ -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{
- <%= id.to_s%>
- <%= self['NAME']%>
- <%= state_str %>
- <% if template['DISK']!=nil
- %><%
- template['DISK'].each do |disk|
- next if !disk
- case disk['TYPE']
- when "swap"%>
- <% when "fs" %>
- <%
- else %>
- <%
- end
- end %>
-
- <% end
- if template['NIC']
- %><%
- template['NIC'].each do |nic|
- next if !nic %>
- ip="<%= nic['IP']%>"<% end %>/><%
- end
- %>
- <%
- end
- if template['INSTANCE_TYPE'] %>
- <%=template['INSTANCE_TYPE']%><%
- end %>
+ <%= self.id.to_s%>
+ <%= self.name%>
+ <% if template['INSTANCE_TYPE'] %>
+ <%= template['INSTANCE_TYPE'] %>
+ <% end %>
+ <%= self.state_str %>
+ <% if template['DISK'] %>
+ <% template['DISK'].each do |disk| %>
+
+
+ <%= disk['NAME'] %>
+ <%= disk['TYPE'] %>
+ <%= disk['TARGET'] %>
+ <% if disk['CLONE'] %>
+
+ <% end %>
+ <% if disk['SAVE_AS'] %>
+ <%= disk['SAVE_AS'] %>
+ <% end %>
+
+ <% end %>
+ <% end %>
+ <% if template['NIC'] %>
+ <% template['NIC'].each do |nic| %>
+
+
+ <% if nic['IP'] %>
+ <%= nic['IP'] %>
+ <% end %>
+
+ <% end %>
+ <% end %>
}
+ # 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
diff --git a/src/cloud/occi/lib/VirtualMachinePoolOCCI.rb b/src/cloud/occi/lib/VirtualMachinePoolOCCI.rb
index 2488f491b1..40f2910a0d 100755
--- a/src/cloud/occi/lib/VirtualMachinePoolOCCI.rb
+++ b/src/cloud/occi/lib/VirtualMachinePoolOCCI.rb
@@ -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{
- <%
- if pool_hash['VM_POOL'] != nil
- vmlist=[pool_hash['VM_POOL']['VM']].flatten
- vmlist.each{|vm| %>
- <%
- }
- end %>
-
+
+ <% if pool_hash['VM_POOL'] && pool_hash['VM_POOL']['VM'] %>
+ <% vmlist=[pool_hash['VM_POOL']['VM']].flatten %>
+ <% vmlist.each{ |vm| %>
+
+ <% } %>
+ <% end %>
+
}
# 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
diff --git a/src/cloud/occi/lib/VirtualNetworkOCCI.rb b/src/cloud/occi/lib/VirtualNetworkOCCI.rb
index 7da7094b14..b2a46e415b 100755
--- a/src/cloud/occi/lib/VirtualNetworkOCCI.rb
+++ b/src/cloud/occi/lib/VirtualNetworkOCCI.rb
@@ -15,38 +15,64 @@
#--------------------------------------------------------------------------- #
require 'OpenNebula'
-require 'erb'
include OpenNebula
class VirtualNetworkOCCI < VirtualNetwork
OCCI_NETWORK = %q{
- <%= vn_hash['VNET']['ID'].strip %>
- <%= vn_hash['VNET']['NAME'].strip %>
- <%= vn_hash['VNET']['TEMPLATE']['NETWORK_ADDRESS'].strip %>
- <%= vn_hash['VNET']['TEMPLATE']['NETWORK_SIZE'].strip %>
+ <%= self.id.to_s %>
+ <%= self.name %>
+ <%= template['NETWORK_ADDRESS'] %>
+ <% if template['NETWORK_SIZE'] %>
+ <%= template['NETWORK_SIZE'] %>
+ <% end %>
}
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
diff --git a/src/cloud/occi/lib/VirtualNetworkPoolOCCI.rb b/src/cloud/occi/lib/VirtualNetworkPoolOCCI.rb
index 3f640e100a..da1941271a 100755
--- a/src/cloud/occi/lib/VirtualNetworkPoolOCCI.rb
+++ b/src/cloud/occi/lib/VirtualNetworkPoolOCCI.rb
@@ -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{
- <%
- if network_pool_hash['VNET_POOL'] != nil
- vnlist=[network_pool_hash['VNET_POOL']['VNET']].flatten
- vnlist.each{|network|%>
- <%
- }
- end %>
-
+
+ <% if pool_hash['VNET_POOL'] && pool_hash['VNET_POOL']['VNET'] %>
+ <% vnlist=[pool_hash['VNET_POOL']['VNET']].flatten %>
+ <% vnlist.each{ |vn| %>
+
+ <% } %>
+ <% end %>
+
}
- # 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
\ No newline at end of file
diff --git a/src/cloud/occi/lib/occi-server.rb b/src/cloud/occi/lib/occi-server.rb
index f42af095fa..81da9ce723 100755
--- a/src/cloud/occi/lib/occi-server.rb
+++ b/src/cloud/occi/lib/occi-server.rb
@@ -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
diff --git a/src/oca/ruby/OpenNebula/XMLUtils.rb b/src/oca/ruby/OpenNebula/XMLUtils.rb
index 6ee470d0f3..a0dfe43539 100644
--- a/src/oca/ruby/OpenNebula/XMLUtils.rb
+++ b/src/oca/ruby/OpenNebula/XMLUtils.rb
@@ -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