From d245b263554872cc3341e039c15ab4a2404a26b5 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Mon, 18 Oct 2010 18:44:19 +0200 Subject: [PATCH] Add CONTEXT section to OCCI --- src/cloud/occi/etc/templates/common.erb | 42 ++++++++++++ src/cloud/occi/etc/templates/large.erb | 28 +------- src/cloud/occi/etc/templates/medium.erb | 28 +------- src/cloud/occi/etc/templates/small.erb | 28 +------- src/cloud/occi/lib/VirtualMachineOCCI.rb | 49 ++++++++------ src/oca/ruby/OpenNebula/XMLUtils.rb | 83 +++++++++++++++--------- 6 files changed, 127 insertions(+), 131 deletions(-) create mode 100644 src/cloud/occi/etc/templates/common.erb diff --git a/src/cloud/occi/etc/templates/common.erb b/src/cloud/occi/etc/templates/common.erb new file mode 100644 index 0000000000..0a2756e5b3 --- /dev/null +++ b/src/cloud/occi/etc/templates/common.erb @@ -0,0 +1,42 @@ +# +# This template is processed by the OCCI Server to include specific data for the +# instance, you should not need to modify the <% ... %> compounds. +# You can add common attributes for your cloud templates (e.g. OS) +# + +NAME = "<%= @vm_info['NAME'] %>" + +<% @vm_info.each('DISK') do |disk| %> + <% if disk.attr('STORAGE','href') %> + DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %> + ] + <% end %> +<% end %> + +<% @vm_info.each('NIC') do |nic| %> + <% if nic.attr('NETWORK','href') %> + NIC = [ NETWORK_ID = <%= nic.attr('NETWORK','href').split('/').last %> + <% if nic['IP'] %> + ,IP = <%= nic['IP'] %> + <% end %> + ] + <% end %> +<% end %> + +<% if @vm_info.has_elements?('CONTEXT') %> + CONTEXT = [ + <% first = true %> + <% @vm_info.each('CONTEXT/*') do |cont| %> + <% if cont.text %> + <% if first %> + <%= cont.name %> = "<%= cont.text %>" + <% first = false %> + <% else %> + ,<%= cont.name %> = "<%= cont.text %>" + <% end %> + <% end %> + <% end %> + ] +<% end %> + +INSTANCE_TYPE = <%= @vm_info['INSTANCE_TYPE']%> \ No newline at end of file diff --git a/src/cloud/occi/etc/templates/large.erb b/src/cloud/occi/etc/templates/large.erb index cc1cc7a98f..0af7a6ce14 100644 --- a/src/cloud/occi/etc/templates/large.erb +++ b/src/cloud/occi/etc/templates/large.erb @@ -1,34 +1,8 @@ # # Virtual Machine Template generated for large instance types. Adjust this # by setting the desired capacity (CPU,MEMORY) or adding specific -# attributes for your cloud (e.g. OS). You should not need to change the DISK -# and NIC sections +# attributes for your cloud (e.g. OS). # CPU = 8 MEMORY = 8192 - -NAME = "<%= @vm_info['NAME'] %>" - -<% if @vm_info['DISK'] %> - <% @vm_info.each('DISK') do |disk| %> - <% if disk['STORAGE'] && disk.attr('STORAGE','href') %> - DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %> - ] - <% end %> - <% end %> -<% end %> - -<% if @vm_info['NIC'] %> - <% @vm_info.each('NIC') do |nic| %> - <% if nic['NETWORK'] && nic.attr('NETWORK','href') %> - NIC = [ NETWORK_ID = <%= nic.attr('NETWORK','href').split('/').last %> - <% if nic['IP'] %> - ,IP = <%= nic['IP'] %> - <% end %> - ] - <% end %> - <% end %> -<% end %> - -INSTANCE_TYPE = <%= @vm_info['INSTANCE_TYPE']%> \ No newline at end of file diff --git a/src/cloud/occi/etc/templates/medium.erb b/src/cloud/occi/etc/templates/medium.erb index 074f5d31fd..873a0a3d19 100644 --- a/src/cloud/occi/etc/templates/medium.erb +++ b/src/cloud/occi/etc/templates/medium.erb @@ -1,35 +1,9 @@ # # Virtual Machine Template generated for medium instance types. Adjust this # by setting the desired capacity (CPU,MEMORY) or adding specific -# attributes for your cloud (e.g. OS). You should not need to change the DISK -# and NIC sections +# attributes for your cloud (e.g. OS). # CPU = 4 MEMORY = 4096 -NAME = "<%= @vm_info['NAME'] %>" - -<% if @vm_info['DISK'] %> - <% @vm_info.each('DISK') do |disk| %> - <% if disk['STORAGE'] && disk.attr('STORAGE','href') %> - DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %> - ] - <% end %> - <% end %> -<% end %> - -<% if @vm_info['NIC'] %> - <% @vm_info.each('NIC') do |nic| %> - <% if nic['NETWORK'] && nic.attr('NETWORK','href') %> - NIC = [ NETWORK_ID = <%= nic.attr('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/etc/templates/small.erb b/src/cloud/occi/etc/templates/small.erb index 65f8100f86..7320831643 100644 --- a/src/cloud/occi/etc/templates/small.erb +++ b/src/cloud/occi/etc/templates/small.erb @@ -1,35 +1,9 @@ # # Virtual Machine Template generated for small instance types. Adjust this # by setting the desired capacity (CPU,MEMORY) or adding specific -# attributes for your cloud (e.g. OS). You should not need to change the DISK -# and NIC sections +# attributes for your cloud (e.g. OS). # CPU = 1 MEMORY = 1024 -NAME = "<%= @vm_info['NAME'] %>" - -<% if @vm_info['DISK'] %> - <% @vm_info.each('DISK') do |disk| %> - <% if disk['STORAGE'] && disk.attr('STORAGE','href') %> - DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %> - ] - <% end %> - <% end %> -<% end %> - -<% if @vm_info['NIC'] %> - <% @vm_info.each('NIC') do |nic| %> - <% if nic['NETWORK'] && nic.attr('NETWORK','href') %> - NIC = [ NETWORK_ID = <%= nic.attr('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/VirtualMachineOCCI.rb b/src/cloud/occi/lib/VirtualMachineOCCI.rb index 1568f9ea7c..c72c645525 100755 --- a/src/cloud/occi/lib/VirtualMachineOCCI.rb +++ b/src/cloud/occi/lib/VirtualMachineOCCI.rb @@ -27,17 +27,14 @@ class VirtualMachineOCCI < VirtualMachine <%= self['TEMPLATE/INSTANCE_TYPE'] %> <% end %> <%= self.state_str %> - <% if self['TEMPLATE/DISK'] %> - <% self.each('TEMPLATE/DISK') do |disk| %> + <% self.each('TEMPLATE/DISK') do |disk| %> <%= disk['TYPE'] %> <%= disk['TARGET'] %> - <% end %> <% end %> - <% if self['TEMPLATE/NIC'] %> - <% self.each('TEMPLATE/NIC') do |nic| %> + <% self.each('TEMPLATE/NIC') do |nic| %> <% if nic['IP'] %> @@ -47,32 +44,41 @@ class VirtualMachineOCCI < VirtualMachine <%= nic['MAC'] %> <% end %> + <% end %> + <% if self['TEMPLATE/CONTEXT'] %> + + <% self.each('TEMPLATE/CONTEXT/*') do |cont| %> + <% if cont.text %> + <<%= cont.name %>><%= cont.text %>> <% end %> <% end %> + + <% end %> } - + # Class constructor - def initialize(xml, client, xml_info = nil, types=nil, base=nil) + def initialize(xml, client, xml_info=nil, types=nil, base=nil) super(xml, client) @vm_info = nil @template = nil - + @common_template = base + '/common.erb' if base + if xml_info != nil xmldoc = XMLElement.build_xml(xml_info, 'COMPUTE') @vm_info = XMLElement.new(xmldoc) if xmldoc != nil end - + if @vm_info != nil itype = @vm_info['INSTANCE_TYPE'] - + if itype != nil and types[itype] != nil @template = base + "/#{types[itype]['TEMPLATE']}" end end - + end - + def mk_action(action_str) case action_str.downcase when "stopped" @@ -92,31 +98,31 @@ class VirtualMachineOCCI < VirtualMachine error = OpenNebula::Error.new(error_msg) return error end - + return rc end - + def to_one_template() if @vm_info == nil error_msg = "Missing COMPUTE section in the XML body" return OpenNebula::Error.new(error_msg), 400 end - + if @template == nil return OpenNebula::Error.new("Bad instance type"), 500 end - + begin - template = ERB.new(File.read(@template)) - template_text = template.result(binding) + template = ERB.new(File.read(@common_template)).result(binding) + template << ERB.new(File.read(@template)).result(binding) rescue Exception => e error = OpenNebula::Error.new(e.message) return error end - - return template_text + + return template end - + # Creates the VMI representation of a Virtual Machine def to_occi(base_url) begin @@ -127,6 +133,7 @@ class VirtualMachineOCCI < VirtualMachine return error end + return occi_vm_text.gsub(/\n\s*/,'') end end diff --git a/src/oca/ruby/OpenNebula/XMLUtils.rb b/src/oca/ruby/OpenNebula/XMLUtils.rb index 4ff16187e2..1e56092273 100644 --- a/src/oca/ruby/OpenNebula/XMLUtils.rb +++ b/src/oca/ruby/OpenNebula/XMLUtils.rb @@ -1,26 +1,25 @@ module OpenNebula - + begin require 'nokogiri' NOKOGIRI=true rescue LoadError NOKOGIRI=false end - - + ########################################################################### # The XMLElement class provides an abstraction of the underlying # XML parser engine. It provides XML-related methods for the Pool and # PoolElement classes ########################################################################### class XMLElement - + # xml:: _opaque xml object_ an xml object as returned by build_xml def initialize(xml=nil) @xml = xml end - + # Initialize a XML document for the element # xml:: _String_ the XML document of the object # root_element:: _String_ Base xml element @@ -37,7 +36,7 @@ module OpenNebula end end end - + # Builds a XML document # xml:: _String_ the XML document of the object # root_element:: _String_ Base xml element @@ -48,7 +47,7 @@ module OpenNebula else doc = REXML::Document.new(xml).root end - + return doc end # Extract an element from the XML description of the PoolElement. @@ -60,43 +59,43 @@ module OpenNebula def [](key) if NOKOGIRI element=@xml.xpath(key.to_s) - + if element.size == 0 return nil end else element=@xml.elements[key.to_s] end - + if element element.text end end - + # Gets an attribute from an elemenT # key:: _String_ xpath for the element # name:: _String_ name of the attribute def attr(key,name) value = nil - + if NOKOGIRI element=@xml.xpath(key.to_s.upcase) if element.size == 0 return nil end - + attribute = element.attr(name) - + value = attribute.text if attribute != nil else element=@xml.elements[key.to_s.upcase] - + value = element.attributes[name] if element != nil end - + return value end - + # Iterates over every Element in the XPath and calls the block with a # a XMLElement # block:: _Block_ @@ -111,11 +110,39 @@ module OpenNebula } end end - + + def name + @xml.name + end + + def text + if NOKOGIRI + @xml.content + else + @xml.text + end + end + + def has_elements?(xpath_str) + if NOKOGIRI + element = @xml.xpath(xpath_str.to_s.upcase) + if element && element.children.size > 0 + return true + end + else + element = @xml.elements[xpath_str.to_s] + if element + return element.has_elements? + end + end + + return false + end + def template_str(indent=true) template_like_str('TEMPLATE', indent) end - + def template_like_str(root_element, indent=true) if NOKOGIRI xml_template=@xml.xpath(root_element).to_s @@ -123,7 +150,7 @@ module OpenNebula else rexml=@xml.elements[root_element] end - + if indent ind_enter="\n" ind_tab=' ' @@ -131,13 +158,13 @@ module OpenNebula ind_enter='' ind_tab=' ' end - + str=rexml.collect {|n| if n.class==REXML::Element str_line="" if n.has_elements? str_line << n.name << "=[" << ind_enter - + str_line << n.collect {|n2| if n2 && n2.class==REXML::Element str = ind_tab + n2.name + "=" @@ -152,10 +179,10 @@ module OpenNebula str_line end }.compact.join("\n") - + str end - + def to_xml(pretty=false) if NOKOGIRI @xml.to_xml @@ -170,17 +197,17 @@ module OpenNebula end end end - + ########################################################################### # The XMLUtilsPool module provides an abstraction of the underlying # XML parser engine. It provides XML-related methods for the Pools ########################################################################### class XMLPool < XMLElement - + def initialize(xml=nil) super(xml) end - + #Executes the given block for each element of the Pool #block:: _Block_ def each_element(block) @@ -197,7 +224,5 @@ module OpenNebula end end end - + end - -