diff --git a/include/Nebula.h b/include/Nebula.h index 1048358887..ef6575cff6 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -228,12 +228,12 @@ public: static string version() { - return "OpenNebula 3.1.0"; + return "OpenNebula 3.1.80"; }; static string db_version() { - return "3.1.0"; + return "3.1.80"; } void start(); diff --git a/install.sh b/install.sh index 6fb7f2bcfe..3d4e4e933d 100755 --- a/install.sh +++ b/install.sh @@ -746,6 +746,7 @@ ONEDB_MIGRATOR_FILES="src/onedb/2.0_to_2.9.80.rb \ src/onedb/2.9.85_to_2.9.90.rb \ src/onedb/2.9.90_to_3.0.0.rb \ src/onedb/3.0.0_to_3.1.0.rb \ + src/onedb/3.1.0_to_3.1.80.rb \ src/onedb/onedb.rb \ src/onedb/onedb_backend.rb" @@ -958,6 +959,7 @@ OCCI_ETC_TEMPLATE_FILES="src/cloud/occi/etc/templates/common.erb \ src/cloud/occi/etc/templates/custom.erb \ src/cloud/occi/etc/templates/small.erb \ src/cloud/occi/etc/templates/medium.erb \ + src/cloud/occi/etc/templates/network.erb \ src/cloud/occi/etc/templates/large.erb" #----------------------------------------------------------------------------- @@ -1111,6 +1113,9 @@ SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \ src/sunstone/public/images/panel_short.png \ src/sunstone/public/images/pbar.gif \ src/sunstone/public/images/Refresh-icon.png \ + src/sunstone/public/images/red_bullet.png \ + src/sunstone/public/images/yellow_bullet.png \ + src/sunstone/public/images/green_bullet.png \ src/sunstone/public/images/vnc_off.png \ src/sunstone/public/images/vnc_on.png" diff --git a/share/install_gems/install_gems b/share/install_gems/install_gems index d0c44fc7db..3b85b5069c 100755 --- a/share/install_gems/install_gems +++ b/share/install_gems/install_gems @@ -2,16 +2,17 @@ require 'pp' -PACKAGES=%w{optional sunstone quota cloud ozones_client ozones_server - ozones_server_mysql ozones_server_sqlite} - -DEFAULT=%w{optional sunstone quota cloud ozones_server acct} +DEFAULT=%w{optional sunstone quota cloud ozones_server acct auth_ldap} if defined?(RUBY_VERSION) && RUBY_VERSION>="1.8.7" SQLITE='sqlite3' # xmlparser gem is not compatible with ruby 1.9 OPTIONAL=%w{nokogiri} + + if RUBY_VERSION=='1.8.7' + OPTIONAL << 'xmlparser' + end else SQLITE='sqlite3-ruby --version 1.2.0' OPTIONAL=%w{nokogiri xmlparser} @@ -21,7 +22,7 @@ GROUPS={ :optional => OPTIONAL, :quota => [SQLITE, 'sequel'], :sunstone => ['json', 'rack', 'sinatra', 'thin', 'sequel', SQLITE], - :cloud => %w{amazon-ec2 rack sinatra thin uuid curb}, + :cloud => %w{amazon-ec2 rack sinatra thin uuidtools curb}, :ozones_client => %w{json}, :ozones_server => %w{json data_mapper dm-sqlite-adapter dm-mysql-adapter}+[ SQLITE, 'mysql' @@ -30,9 +31,12 @@ GROUPS={ :ozones_server_mysql => %w{json data_mapper dm-mysql-adapter mysql}, :acct => ['sequel', SQLITE, 'mysql'], :acct_sqlite => ['sequel', SQLITE], - :acct_mysql => ['sequel', 'mysql'] + :acct_mysql => ['sequel', 'mysql'], + :auth_ldap => 'net-ldap' } +PACKAGES=GROUPS.keys + DISTRIBUTIONS={ :debian => { :id => ['Ubuntu', 'Debian'], @@ -82,6 +86,15 @@ class String end end +def installed_gems + text=`gem list --no-versions --no-details` + if $?.exitstatus!=0 + nil + else + text.split(/\s+/) + end +end + def try_library(name, error_message) begin require name.to_s @@ -107,12 +120,14 @@ def help puts puts "If no parameters are specified then this list will be used:" puts DEFAULT.join(' ') + puts + puts "Use --check parameter to search for non installed libraries." end def get_gems(packages) packages.map do |package| GROUPS[package.to_sym] - end.flatten.uniq + end.flatten.uniq-installed_gems end def detect_distro @@ -191,6 +206,88 @@ def install_dependencies(gems, distro) end end +def run_command(cmd) + puts cmd + system cmd + #system "true" + + if $?!=0 + puts "Error executing #{cmd}" + exit(-1) + end +end + +def install_gems(packages) + gems_list=get_gems(packages) + + if gems_list.empty? + puts "Gems already installed" + exit(0) + end + + dist=detect_distro + + install_dependencies(gems_list, dist) + + packages_string=gems_list.join(' ') + + prefix="" + + if dist && dist.last[:gem_env] + prefix=dist.last[:gem_env].collect do |name, value| + "#{name}=\"#{value}\"" + end.join(' ')+' ' + end + + command_string = "#{prefix}gem install --no-ri --no-rdoc" + + install_warning(packages) + + simple_gems=gems_list.select {|g| !(g.match(/\s/)) } + if simple_gems and !simple_gems.empty? + cmd=command_string+" " << simple_gems.join(' ') + run_command(cmd) + end + + special_gems=gems_list.select {|g| g.match(/\s/) } + special_gems.each do |gem| + cmd=command_string+" "<0 - packages=ARGV +if params.length>0 + packages=params else packages=DEFAULT end -gems_list=get_gems(packages) -dist=detect_distro - -install_dependencies(gems_list, dist) - -packages_string=gems_list.join(' ') - -prefix="" - -if dist && dist.last[:gem_env] - prefix=dist.last[:gem_env].collect do |name, value| - "#{name}=\"#{value}\"" - end.join(' ')+' ' +case command +when 'help' + help + exit(0) +when 'check' + check_gems(packages) +when 'install' + install_gems(packages) end -command_string = "#{prefix}gem install --no-ri --no-rdoc" -install_warning(packages) -gems_list.each do |gem| - cmd=command_string+" "< @token_expiration_time - EXPIRE_MARGIN @token_expiration_time = time_now + EXPIRE_DELTA - update_userpool_cache end @token_expiration_time diff --git a/src/cloud/common/CloudClient.rb b/src/cloud/common/CloudClient.rb index 176471419b..562888917d 100644 --- a/src/cloud/common/CloudClient.rb +++ b/src/cloud/common/CloudClient.rb @@ -173,7 +173,7 @@ module CloudCLI def version_text version=< +<% if @vnet_info['SIZE'] != nil %> +NETWORK_SIZE = <%= @vnet_info['SIZE']%> +<% end %> + +<% if @vnet_info['DESCRIPTION'] != nil %> +DESCRIPTION = "<%= @vnet_info['DESCRIPTION'] %>" +<% end %> + +<% if @vnet_info['PUBLIC'] != nil %> +PUBLIC = "<%= @vnet_info['PUBLIC'] %>" +<% end %> + +#BRIDGE = NAME_OF_DEFAULT_BRIDGE +#PHYDEV = NAME_OF_PHYSICAL_DEVICE +#VLAN = YES|NO diff --git a/src/cloud/occi/lib/ImageOCCI.rb b/src/cloud/occi/lib/ImageOCCI.rb index cd573554c3..50a12133f5 100755 --- a/src/cloud/occi/lib/ImageOCCI.rb +++ b/src/cloud/occi/lib/ImageOCCI.rb @@ -30,7 +30,7 @@ class ImageOCCI < Image <%= self['TEMPLATE/DESCRIPTION'] %> <% end %> <%= self['SIZE'] %> - <% if self['FSTYPE'] != nil %> + <% if self['FSTYPE'] != nil and !self['FSTYPE'].empty? %> <%= self['FSTYPE'] %> <% end %> <%= self['PUBLIC'] == "0" ? "NO" : "YES"%> diff --git a/src/cloud/occi/lib/OCCIServer.rb b/src/cloud/occi/lib/OCCIServer.rb index 613ecd5333..0b5d26e5d2 100755 --- a/src/cloud/occi/lib/OCCIServer.rb +++ b/src/cloud/occi/lib/OCCIServer.rb @@ -40,6 +40,9 @@ require 'pp' COLLECTIONS = ["compute", "instance_type", "network", "storage"] +# FLAG that will filter the elements retrieved from the Pools +POOL_FILTER = Pool::INFO_GROUP + class OCCIServer < CloudServer # Server initializer # config_file:: _String_ path of the config file @@ -109,21 +112,14 @@ class OCCIServer < CloudServer # [return] _String_,_Integer_ Pool Representation or error, status code def get_computes(request) # --- Get User's VMs --- - user_flag = -1 - vmpool = VirtualMachinePoolOCCI.new( @client, - user_flag) + POOL_FILTER) # --- Prepare XML Response --- rc = vmpool.info - if OpenNebula.is_error?(rc) - if rc.message.match("Error getting") - return rc, 404 - else - return rc, 500 - end + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end return to_occi_xml(vmpool, 200) @@ -136,21 +132,14 @@ class OCCIServer < CloudServer # => status code def get_networks(request) # --- Get User's VNETs --- - user_flag = -1 - network_pool = VirtualNetworkPoolOCCI.new( @client, - user_flag) + POOL_FILTER) # --- Prepare XML Response --- rc = network_pool.info - if OpenNebula.is_error?(rc) - if rc.message.match("Error getting") - return rc, 404 - else - return rc, 500 - end + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end return to_occi_xml(network_pool, 200) @@ -162,21 +151,14 @@ class OCCIServer < CloudServer # status code def get_storages(request) # --- Get User's Images --- - user_flag = -1 - image_pool = ImagePoolOCCI.new( @client, - user_flag) + POOL_FILTER) # --- Prepare XML Response --- rc = image_pool.info - if OpenNebula.is_error?(rc) - if rc.message.match("Error getting") - return rc, 404 - else - return rc, 500 - end + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end return to_occi_xml(image_pool, 200) @@ -192,7 +174,6 @@ class OCCIServer < CloudServer # --- Prepare XML Response --- rc = user_pool.info - if OpenNebula.is_error?(rc) return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end @@ -227,7 +208,9 @@ class OCCIServer < CloudServer return template, 500 if OpenNebula.is_error?(template) rc = vm.allocate(template) - return rc, 500 if OpenNebula.is_error?(rc) + if OpenNebula.is_error?(rc) + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] + end # --- Prepare XML Response --- vm.info @@ -246,13 +229,8 @@ class OCCIServer < CloudServer # --- Prepare XML Response --- rc = vm.info - if OpenNebula.is_error?(rc) - if rc.message.match("Error getting") - return rc, 404 - else - return rc, 500 - end + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end return to_occi_xml(vm, 200) @@ -269,12 +247,11 @@ class OCCIServer < CloudServer VirtualMachine.build_xml(params[:id]), @client) - rc = vm.info - return rc, 404 if OpenNebula::is_error?(rc) - # --- Finalize the VM --- result = vm.finalize - return result, 500 if OpenNebula::is_error?(result) + if OpenNebula.is_error?(result) + return result, CloudServer::HTTP_ERROR_CODE[result.errno] + end return "", 204 end @@ -317,14 +294,16 @@ class OCCIServer < CloudServer VirtualNetwork.build_xml, @client, request.body, - @config[:bridge]) + @config[:template_location]) # --- Generate the template and Allocate the new Instance --- template = network.to_one_template return template, 500 if OpenNebula.is_error?(template) rc = network.allocate(template) - return rc, 500 if OpenNebula.is_error?(rc) + if OpenNebula.is_error?(rc) + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] + end # --- Prepare XML Response --- network.info @@ -342,13 +321,8 @@ class OCCIServer < CloudServer # --- Prepare XML Response --- rc = network.info - if OpenNebula.is_error?(rc) - if rc.message.match("Error getting") - return rc, 404 - else - return rc, 500 - end + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end return to_occi_xml(network, 200) @@ -363,12 +337,11 @@ class OCCIServer < CloudServer VirtualNetwork.build_xml(params[:id]), @client) - rc = network.info - return rc, 404 if OpenNebula::is_error?(rc) - # --- Delete the VNET --- rc = network.delete - return rc, 500 if OpenNebula::is_error?(rc) + if OpenNebula.is_error?(rc) + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] + end return "", 204 end @@ -385,15 +358,15 @@ class OCCIServer < CloudServer VirtualNetwork.build_xml(params[:id]), @client) - rc = vnet.info - return rc, 400 if OpenNebula.is_error?(rc) - + rc = nil if vnet_info['PUBLIC'] == 'YES' rc = vnet.publish - return rc, 400 if OpenNebula.is_error?(rc) elsif vnet_info['PUBLIC'] == 'NO' rc = vnet.unpublish - return rc, 400 if OpenNebula.is_error?(rc) + end + + if OpenNebula.is_error?(rc) + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end # --- Prepare XML Response --- @@ -432,7 +405,9 @@ class OCCIServer < CloudServer return template, 500 if OpenNebula.is_error?(template) rc = image.allocate(template) - return rc, 500 if OpenNebula.is_error?(rc) + if OpenNebula.is_error?(rc) + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] + end # --- Prepare XML Response --- image.info @@ -450,13 +425,8 @@ class OCCIServer < CloudServer @client) rc = image.info - if OpenNebula.is_error?(rc) - if rc.message.match("Error getting") - return rc, 404 - else - return rc, 500 - end + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end # --- Prepare XML Response --- @@ -473,12 +443,11 @@ class OCCIServer < CloudServer Image.build_xml(params[:id]), @client) - rc = image.info - return rc, 404 if OpenNebula::is_error?(rc) - # --- Delete the Image --- rc = image.delete - return rc, 500 if OpenNebula::is_error?(rc) + if OpenNebula.is_error?(rc) + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] + end return "", 204 end @@ -495,24 +464,22 @@ class OCCIServer < CloudServer Image.build_xml(params[:id]), @client) - rc = image.info - return rc, 400 if OpenNebula.is_error?(rc) - + rc = nil if image_info['PERSISTENT'] && image_info['PUBLIC'] error_msg = "It is not allowed more than one change per request" return OpenNebula::Error.new(error_msg), 400 elsif image_info['PERSISTENT'] == 'YES' rc = image.persistent - return rc, 400 if OpenNebula.is_error?(rc) elsif image_info['PERSISTENT'] == 'NO' rc = image.nonpersistent - return rc, 400 if OpenNebula.is_error?(rc) elsif image_info['PUBLIC'] == 'YES' rc = image.publish - return rc, 400 if OpenNebula.is_error?(rc) elsif image_info['PUBLIC'] == 'NO' rc = image.unpublish - return rc, 400 if OpenNebula.is_error?(rc) + end + + if OpenNebula.is_error?(rc) + return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end # --- Prepare XML Response --- @@ -532,7 +499,6 @@ class OCCIServer < CloudServer # --- Prepare XML Response --- rc = user.info - if OpenNebula.is_error?(rc) return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end diff --git a/src/cloud/occi/lib/VirtualMachineOCCI.rb b/src/cloud/occi/lib/VirtualMachineOCCI.rb index 73274ba9b0..f05f194920 100755 --- a/src/cloud/occi/lib/VirtualMachineOCCI.rb +++ b/src/cloud/occi/lib/VirtualMachineOCCI.rb @@ -100,11 +100,11 @@ class VirtualMachineOCCI < VirtualMachine def to_one_template() if @vm_info == nil error_msg = "Missing COMPUTE section in the XML body" - return OpenNebula::Error.new(error_msg), 400 + return OpenNebula::Error.new(error_msg) end if @template == nil - return OpenNebula::Error.new("Bad instance type"), 500 + return OpenNebula::Error.new("Bad instance type") end begin diff --git a/src/cloud/occi/lib/VirtualNetworkOCCI.rb b/src/cloud/occi/lib/VirtualNetworkOCCI.rb index eeb7194c92..f996b967d2 100755 --- a/src/cloud/occi/lib/VirtualNetworkOCCI.rb +++ b/src/cloud/occi/lib/VirtualNetworkOCCI.rb @@ -15,6 +15,7 @@ #--------------------------------------------------------------------------- # require 'OpenNebula' +require 'ipaddr' include OpenNebula @@ -26,35 +27,23 @@ class VirtualNetworkOCCI < VirtualNetwork <% if self['TEMPLATE/DESCRIPTION'] != nil %> <%= self['TEMPLATE/DESCRIPTION'] %> <% end %> -
<%= self['TEMPLATE/NETWORK_ADDRESS'] %>
- <% if self['TEMPLATE/NETWORK_SIZE'] %> - <%= self['TEMPLATE/NETWORK_SIZE'] %> + <% if network_address != nil %> +
<%= network_address %>
<% end %> + <% if network_size != nil %> + <%= network_size %> + <% end %> + <%= self['TOTAL_LEASES'] %> <%= self['PUBLIC'] == "0" ? "NO" : "YES"%> } - ONE_NETWORK = %q{ - NAME = "<%= @vnet_info['NAME'] %>" - TYPE = RANGED - <% if @vnet_info['DESCRIPTION'] != nil %> - DESCRIPTION = "<%= @vnet_info['DESCRIPTION'] %>" - <% end %> - <% if @vnet_info['PUBLIC'] != nil %> - PUBLIC = "<%= @vnet_info['PUBLIC'] %>" - <% end %> - <% if @bridge %> - BRIDGE = <%= @bridge %> - <% end %> - NETWORK_ADDRESS = <%= @vnet_info['ADDRESS'] %> - NETWORK_SIZE = <%= @vnet_info['SIZE']%> - }.gsub(/^ /, '') - # Class constructor - def initialize(xml, client, xml_info=nil, bridge=nil) + # + def initialize(xml, client, xml_info=nil, base=nil) super(xml, client) - @bridge = bridge @vnet_info = nil + @common_template = base + '/network.erb' if base if xml_info != nil xmldoc = XMLElement.build_xml(xml_info, 'NETWORK') @@ -64,6 +53,18 @@ class VirtualNetworkOCCI < VirtualNetwork # Creates the OCCI representation of a Virtual Network def to_occi(base_url) + network_address = nil + network_size = nil + + if self['RANGE/IP_START'] + network_address = self['RANGE/IP_START'] + + ip_start = IPAddr.new(network_address, Socket::AF_INET) + ip_end = IPAddr.new(self['RANGE/IP_END'], Socket::AF_INET) + + network_size = ip_end.to_i - ip_start.to_i + end + begin occi = ERB.new(OCCI_NETWORK) occi_text = occi.result(binding) @@ -78,11 +79,16 @@ class VirtualNetworkOCCI < VirtualNetwork def to_one_template() if @vnet_info == nil error_msg = "Missing NETWORK section in the XML body" - error = OpenNebula::Error.new(error_msg) + return OpenNebula::Error.new(error_msg), 400 + end + + begin + template = ERB.new(File.read(@common_template)).result(binding) + rescue Exception => e + error = OpenNebula::Error.new(e.message) return error end - one = ERB.new(ONE_NETWORK) - return one.result(binding) + return template end end diff --git a/src/onedb/3.1.0_to_3.1.80.rb b/src/onedb/3.1.0_to_3.1.80.rb new file mode 100644 index 0000000000..5644157197 --- /dev/null +++ b/src/onedb/3.1.0_to_3.1.80.rb @@ -0,0 +1,215 @@ +# -------------------------------------------------------------------------- * +# Copyright 2002-2011, 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 'digest/sha1' +require "rexml/document" +include REXML +require 'ipaddr' + +module Migrator + def db_version + "3.1.80" + end + + def one_version + "OpenNebula 3.1.80" + end + + def up + puts " > Networking isolation hooks have been moved to Host drivers.\n"<< + " If you were using a networking hook, enter its name, or press enter\n"<< + " to use the default dummy vn_mad driver.\n\n" + + vn_mad = "" + + while !( ["802.1Q", "dummy", "ebtables", "ovswitch"].include?(vn_mad) ) do + print " Driver name (802.1Q, dummy, ebtables, ovswitch): " + vn_mad = gets.chomp + vn_mad = "dummy" if vn_mad.empty? + end + + # 0 = all, 1 = none, 2 = interactive + vlan_option = 1 + + if ( vn_mad == "ebtables" || vn_mad == "ovswitch" ) + puts + puts " > A new attribute, VLAN = YES/NO will be added to each VNET.\n"<< + " For driver '#{vn_mad}', please choose if you want to isolate all networks (all),\n"<< + " none (none), or be asked individually for each VNET (interactive)\n" + + vlan = "" + while !( ["all", "none", "interactive"].include?(vlan) ) do + print " Isolate VNETs (all, none, interactive): " + vlan = gets.chomp + end + + case vlan + when "all" + vlan_option = 0 + when "none" + vlan_option = 1 + when "interactive" + vlan_option = 2 + end + end + + # New VN_MAD element for hosts + + @db.run "ALTER TABLE host_pool RENAME TO old_host_pool;" + @db.run "CREATE TABLE host_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, state INTEGER, last_mon_time INTEGER, UNIQUE(name));" + + @db.fetch("SELECT * FROM old_host_pool") do |row| + doc = Document.new(row[:body]) + + vn_mad_elem = doc.root.add_element("VN_MAD") + vn_mad_elem.text = vn_mad + + @db[:host_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :state => row[:state], + :last_mon_time => row[:last_mon_time]) + end + + @db.run "DROP TABLE old_host_pool;" + + # New VLAN and RANGE for vnets + + @db.run "ALTER TABLE network_pool RENAME TO old_network_pool;" + @db.run "CREATE TABLE network_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, public INTEGER, UNIQUE(name,uid));" + + @db.fetch("SELECT * FROM old_network_pool") do |row| + doc = Document.new(row[:body]) + + type = "" + doc.root.each_element("TYPE") { |e| + type = e.text + } + + if type == "0" # RANGED + range_elem = doc.root.add_element("RANGE") + ip_start_elem = range_elem.add_element("IP_START") + ip_end_elem = range_elem.add_element("IP_END") + + net_address = "" + doc.root.each_element("TEMPLATE/NETWORK_ADDRESS") { |e| + net_address = e.text + } + + net_valid = false + while !net_valid do + begin + net_address = IPAddr.new(net_address, Socket::AF_INET) + net_valid = true + rescue ArgumentError + puts + puts " > Error processing VNET ##{row[:oid]} '#{row[:name]}'\n"<< + " This network address is invalid: '#{net_address}'\n" + print " Please enter a valid network address: " + net_address = gets.chomp + end + end + + + st_size = "" + doc.root.each_element("TEMPLATE/NETWORK_SIZE") { |e| + st_size = e.text + } + + if ( st_size == "C" || st_size == "c" ) + host_bits = 8 + elsif ( st_size == "B" || st_size == "b" ) + host_bits = 16 + elsif ( st_size == "A" || st_size == "a" ) + host_bits = 24 + else + size = st_size.to_i + host_bits = (Math.log(size+2)/Math.log(2)).ceil + end + + net_mask = 0xFFFFFFFF << host_bits + + net_address = net_address.to_i & net_mask + + ip_start_elem.text = IPAddr.new((net_address + 1), Socket::AF_INET).to_s + ip_end_elem.text = IPAddr.new((net_address + (1 << host_bits) - 2), Socket::AF_INET).to_s + end + + phydev_present = false + doc.root.each_element("PHYDEV") { |e| + phydev_present = true + } + + vlan_elem = doc.root.add_element("VLAN") + + if phydev_present + vlan_elem.text = "1" + else + case vlan_option + when 0 + vlan_elem.text = "1" + when 1 + vlan_elem.text = "0" + when 2 + vlan = "" + while !( ["y", "n"].include?(vlan) ) do + print " > Isolate VNET ##{row[:oid]} '#{row[:name]}'? (y/n) : " + vlan = gets.chomp + end + + if ( vlan == "y" ) + vlan_elem.text = "1" + else + vlan_elem.text = "0" + end + end + end + + @db[:network_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :uid => row[:uid], + :gid => row[:gid], + :public => row[:public]) + end + + @db.run "DROP TABLE old_network_pool;" + + # Add empty HISTORY_RECORDS element to VMs without any records + @db.run "ALTER TABLE vm_pool RENAME TO old_vm_pool;" + @db.run "CREATE TABLE vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, last_poll INTEGER, state INTEGER, lcm_state INTEGER);" + @db.run "INSERT INTO vm_pool SELECT * FROM old_vm_pool;" + + @db.fetch("SELECT * FROM old_vm_pool") do |row| + doc = Document.new(row[:body]) + + found = false + doc.root.each_element("HISTORY_RECORDS") { |e| + found = true + } + + if !found + doc.root.add_element("HISTORY_RECORDS") + end + end + + @db.run "DROP TABLE old_vm_pool;" + + + return true + end +end diff --git a/src/ozones/Server/templates/index.html b/src/ozones/Server/templates/index.html index bcfd3b310c..09b1677e83 100644 --- a/src/ozones/Server/templates/index.html +++ b/src/ozones/Server/templates/index.html @@ -59,7 +59,7 @@ diff --git a/src/sunstone/views/index.erb b/src/sunstone/views/index.erb index 9140aafa6e..a6f1938409 100644 --- a/src/sunstone/views/index.erb +++ b/src/sunstone/views/index.erb @@ -67,7 +67,7 @@ diff --git a/src/vm/History.cc b/src/vm/History.cc index f2a52ccb3c..a14edc9646 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -301,7 +301,7 @@ int History::rebuild_attributes() rc += xpath(stime , "/HISTORY/STIME", 0); rc += xpath(etime , "/HISTORY/ETIME", 0); rc += xpath(vmm_mad_name , "/HISTORY/VMMMAD", "not_found"); - rc += xpath(vnm_mad_name , "/HISTORY/VNMMAD", "not_found"); + xpath(vnm_mad_name , "/HISTORY/VNMMAD", "dummy"); rc += xpath(tm_mad_name , "/HISTORY/TMMAD", "not_found"); rc += xpath(prolog_stime , "/HISTORY/PSTIME", 0); rc += xpath(prolog_etime , "/HISTORY/PETIME", 0); diff --git a/src/vm/vm_var_syntax.cc b/src/vm/vm_var_syntax.cc index 6a75d06320..a8b665169b 100644 --- a/src/vm/vm_var_syntax.cc +++ b/src/vm/vm_var_syntax.cc @@ -146,7 +146,6 @@ void get_image_attribute(VirtualMachine * vm, ImagePool * ipool = nd.get_ipool(); Image * img; int iid = -1; - string iid_str; int num; vector attrs; @@ -154,7 +153,7 @@ void get_image_attribute(VirtualMachine * vm, attr_value.clear(); - if (img_name.empty() || img_name != "IMAGE_ID") + if ( img_name.empty() || (img_name!="IMAGE" && img_name!="IMAGE_ID") ) { return; } @@ -174,11 +173,10 @@ void get_image_attribute(VirtualMachine * vm, continue; } - iid_str = disk->vector_value("IMAGE_ID"); - - if ( iid_str == img_value ) + if ( disk->vector_value(img_name.c_str()) == img_value ) { - istringstream iss(img_value); + string iid_str = disk->vector_value("IMAGE_ID"); + istringstream iss(iid_str); iss >> iid; @@ -232,7 +230,6 @@ void get_network_attribute(VirtualMachine * vm, VirtualNetworkPool * vnpool = nd.get_vnpool(); VirtualNetwork * vn; int vnet_id = -1; - string vnet_id_str; int num; vector attrs; @@ -240,7 +237,7 @@ void get_network_attribute(VirtualMachine * vm, attr_value.clear(); - if (net_name.empty() || net_name != "NETWORK_ID") + if ( net_name.empty() || (net_name!="NETWORK" && net_name!="NETWORK_ID") ) { return; } @@ -260,11 +257,10 @@ void get_network_attribute(VirtualMachine * vm, continue; } - vnet_id_str = net->vector_value("NETWORK_ID"); - - if ( vnet_id_str == net_value ) + if ( net->vector_value(net_name.c_str()) == net_value ) { - istringstream iss(net_value); + string vnet_id_str = net->vector_value("NETWORK_ID"); + istringstream iss(vnet_id_str); iss >> vnet_id; @@ -460,7 +456,7 @@ void insert_vector(VirtualMachine * vm, /* Line 268 of yacc.c */ -#line 464 "vm_var_syntax.cc" +#line 460 "vm_var_syntax.cc" /* Enabling traces. */ #ifndef YYDEBUG @@ -506,7 +502,7 @@ typedef union YYSTYPE { /* Line 293 of yacc.c */ -#line 408 "vm_var_syntax.y" +#line 404 "vm_var_syntax.y" char * val_str; int val_int; @@ -515,7 +511,7 @@ typedef union YYSTYPE /* Line 293 of yacc.c */ -#line 519 "vm_var_syntax.cc" +#line 515 "vm_var_syntax.cc" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -540,7 +536,7 @@ typedef struct YYLTYPE /* Line 343 of yacc.c */ -#line 544 "vm_var_syntax.cc" +#line 540 "vm_var_syntax.cc" #ifdef short # undef short @@ -830,7 +826,7 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 432, 432, 433, 436, 440, 453, 468 + 0, 428, 428, 429, 432, 436, 449, 464 }; #endif @@ -1831,7 +1827,7 @@ yyreduce: case 4: /* Line 1806 of yacc.c */ -#line 437 "vm_var_syntax.y" +#line 433 "vm_var_syntax.y" { (*parsed) << (yyvsp[(1) - (1)].val_str); } @@ -1840,7 +1836,7 @@ yyreduce: case 5: /* Line 1806 of yacc.c */ -#line 441 "vm_var_syntax.y" +#line 437 "vm_var_syntax.y" { string name((yyvsp[(1) - (2)].val_str)); @@ -1858,7 +1854,7 @@ yyreduce: case 6: /* Line 1806 of yacc.c */ -#line 454 "vm_var_syntax.y" +#line 450 "vm_var_syntax.y" { string name((yyvsp[(1) - (5)].val_str)); string vname((yyvsp[(3) - (5)].val_str)); @@ -1878,7 +1874,7 @@ yyreduce: case 7: /* Line 1806 of yacc.c */ -#line 469 "vm_var_syntax.y" +#line 465 "vm_var_syntax.y" { string name((yyvsp[(1) - (9)].val_str)); string vname((yyvsp[(3) - (9)].val_str)); @@ -1901,7 +1897,7 @@ yyreduce: /* Line 1806 of yacc.c */ -#line 1905 "vm_var_syntax.cc" +#line 1901 "vm_var_syntax.cc" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -2139,7 +2135,7 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 487 "vm_var_syntax.y" +#line 483 "vm_var_syntax.y" extern "C" void vm_var__error( diff --git a/src/vm/vm_var_syntax.h b/src/vm/vm_var_syntax.h index d40f8d1d51..337bb45d68 100644 --- a/src/vm/vm_var_syntax.h +++ b/src/vm/vm_var_syntax.h @@ -56,7 +56,7 @@ typedef union YYSTYPE { /* Line 2068 of yacc.c */ -#line 408 "vm_var_syntax.y" +#line 404 "vm_var_syntax.y" char * val_str; int val_int; diff --git a/src/vm/vm_var_syntax.y b/src/vm/vm_var_syntax.y index bd75e41a02..027dade20e 100644 --- a/src/vm/vm_var_syntax.y +++ b/src/vm/vm_var_syntax.y @@ -85,7 +85,6 @@ void get_image_attribute(VirtualMachine * vm, ImagePool * ipool = nd.get_ipool(); Image * img; int iid = -1; - string iid_str; int num; vector attrs; @@ -93,7 +92,7 @@ void get_image_attribute(VirtualMachine * vm, attr_value.clear(); - if (img_name.empty() || img_name != "IMAGE_ID") + if ( img_name.empty() || (img_name!="IMAGE" && img_name!="IMAGE_ID") ) { return; } @@ -113,11 +112,10 @@ void get_image_attribute(VirtualMachine * vm, continue; } - iid_str = disk->vector_value("IMAGE_ID"); - - if ( iid_str == img_value ) + if ( disk->vector_value(img_name.c_str()) == img_value ) { - istringstream iss(img_value); + string iid_str = disk->vector_value("IMAGE_ID"); + istringstream iss(iid_str); iss >> iid; @@ -171,7 +169,6 @@ void get_network_attribute(VirtualMachine * vm, VirtualNetworkPool * vnpool = nd.get_vnpool(); VirtualNetwork * vn; int vnet_id = -1; - string vnet_id_str; int num; vector attrs; @@ -179,7 +176,7 @@ void get_network_attribute(VirtualMachine * vm, attr_value.clear(); - if (net_name.empty() || net_name != "NETWORK_ID") + if ( net_name.empty() || (net_name!="NETWORK" && net_name!="NETWORK_ID") ) { return; } @@ -199,11 +196,10 @@ void get_network_attribute(VirtualMachine * vm, continue; } - vnet_id_str = net->vector_value("NETWORK_ID"); - - if ( vnet_id_str == net_value ) + if ( net->vector_value(net_name.c_str()) == net_value ) { - istringstream iss(net_value); + string vnet_id_str = net->vector_value("NETWORK_ID"); + istringstream iss(vnet_id_str); iss >> vnet_id; diff --git a/src/vmm_mad/exec/one_vmm_exec.rb b/src/vmm_mad/exec/one_vmm_exec.rb index b16867ee56..324542ac89 100755 --- a/src/vmm_mad/exec/one_vmm_exec.rb +++ b/src/vmm_mad/exec/one_vmm_exec.rb @@ -115,7 +115,7 @@ class VmmAction # Executes a set of steps. If one step fails any recover action is performed # and the step execution breaks. # @param [Array] array of steps to be executed - # @return [String, Hash] "SUCCESS/FAILURE" for the step set, and + # @return [String, Hash] "SUCCESS/FAILURE" for the step set, and # information associated to each step (by :_info). In case of # failure information is also in [:failed_info] def execute_steps(steps) @@ -124,7 +124,7 @@ class VmmAction steps.each do |step| # Execute Step case step[:driver] - when :vmm + when :vmm if step[:destination] host = @data[:dest_host] ssh = @ssh_dst @@ -134,7 +134,7 @@ class VmmAction end result, info = @vmm.do_action(get_parameters(step[:parameters]), - @id, + @id, host, step[:action], :ssh_stream => ssh, @@ -147,26 +147,27 @@ class VmmAction vnm = @vnm_src end - result, info = vnm.do_action(@id, step[:action]) + result, info = vnm.do_action(@id, step[:action], + :parameters => get_parameters(step[:parameters])) else result = DriverExecHelper.const_get(:RESULT)[:failure] info = "No driver in #{step[:action]}" end - # Save the step info + # Save the step info @data["#{step[:action]}_info".to_sym] = info # Roll back steps, store failed info and break steps - if DriverExecHelper.failed?(result) + if DriverExecHelper.failed?(result) execute_steps(@data[:fail_actions]) if @data[:fail_actions] @data[:failed_info] = info - @vmm.log(@id, + @vmm.log(@id, "Failed to execute #{DRIVER_NAMES[step[:driver]]} " \ "operation: #{step[:action]}.") break else - @vmm.log(@id, + @vmm.log(@id, "Sussecfully execute #{DRIVER_NAMES[step[:driver]]} " \ "operation: #{step[:action]}.") end @@ -217,7 +218,7 @@ class ExecDriver < VirtualMachineDriver @options={ :threaded => true }.merge!(options) - + super("vmm/#{hypervisor}", @options) @hypervisor = hypervisor @@ -273,15 +274,16 @@ class ExecDriver < VirtualMachineDriver }, # Boot the Virtual Machine { - :driver => :vmm, - :action => :deploy, - :parameters => [dfile, :host], - :stdin => domain - }, + :driver => :vmm, + :action => :deploy, + :parameters => [dfile, :host], + :stdin => domain, + }, # Execute post-boot networking setup { :driver => :vnm, :action => :post, + :parameters => [:deploy_info], :fail_actions => [ { :driver => :vmm, @@ -492,5 +494,3 @@ exec_driver = ExecDriver.new(hypervisor, :local_actions => local_actions) exec_driver.start_driver - - diff --git a/src/vnm_mad/one_vnm.rb b/src/vnm_mad/one_vnm.rb index aba0339611..30c886e97a 100644 --- a/src/vnm_mad/one_vnm.rb +++ b/src/vnm_mad/one_vnm.rb @@ -44,12 +44,17 @@ class VirtualNetworkDriver # @param [String, Symbol] aname name of the action # @param [Hash] ops extra options for the command # @option ops [String] :stdin text to be writen to stdin + # @option ops [String] :parameters additional parameters for vnm action def do_action(id, aname, ops = {}) options={ - :stdin => nil, + :stdin => nil, + :parameters => nil }.merge(ops) - cmd = action_command_line(aname, @vm_encoded) + cmd_params = "#{@vm_encoded}" + cmd_params << " #{options[:parameters]}" if options[:parameters] + + cmd = action_command_line(aname, cmd_params) if action_is_local?(aname) execution = LocalCommand.run(cmd, log_method(id)) @@ -67,4 +72,4 @@ class VirtualNetworkDriver result, info = get_info_from_execution(execution) end -end \ No newline at end of file +end diff --git a/src/vnm_mad/remotes/802.1Q/HostManaged.rb b/src/vnm_mad/remotes/802.1Q/HostManaged.rb index 47a65a3cce..67547840fc 100644 --- a/src/vnm_mad/remotes/802.1Q/HostManaged.rb +++ b/src/vnm_mad/remotes/802.1Q/HostManaged.rb @@ -17,8 +17,10 @@ require 'OpenNebulaNetwork' class OpenNebulaHM < OpenNebulaNetwork - def initialize(vm, hypervisor = nil) - super(vm,hypervisor) + XPATH_FILTER = "TEMPLATE/NIC[VLAN='YES']" + + def initialize(vm, deploy_id = nil, hypervisor = nil) + super(vm,XPATH_FILTER,deploy_id,hypervisor) @bridges = get_interfaces end @@ -64,7 +66,8 @@ class OpenNebulaHM < OpenNebulaNetwork def device_exists?(dev, vlan=nil) dev = "#{dev}.#{vlan}" if vlan - OpenNebula.exec_and_log("#{COMMANDS[:ip]} link show #{dev}") + `#{COMMANDS[:ip]} link show #{dev}` + $?.exitstatus == 0 end def create_dev_vlan(dev, vlan) diff --git a/src/vnm_mad/remotes/802.1Q/post b/src/vnm_mad/remotes/802.1Q/post index 6458772e86..7b0afd182e 100755 --- a/src/vnm_mad/remotes/802.1Q/post +++ b/src/vnm_mad/remotes/802.1Q/post @@ -22,6 +22,9 @@ $: << File.join(File.dirname(__FILE__), "..") require 'OpenNebulaNetwork' require 'Firewall' -fw = OpenNebulaFirewall.from_base64(ARGV[0]) +template64 = ARGV[0] +deploy_id = ARGV[1] + +fw = OpenNebulaFirewall.from_base64(template64, deploy_id) fw.activate diff --git a/src/vnm_mad/remotes/Firewall.rb b/src/vnm_mad/remotes/Firewall.rb index 2cc4f98eca..76f00bf09e 100644 --- a/src/vnm_mad/remotes/Firewall.rb +++ b/src/vnm_mad/remotes/Firewall.rb @@ -15,9 +15,13 @@ #--------------------------------------------------------------------------- # class OpenNebulaFirewall < OpenNebulaNetwork - def initialize(vm, hypervisor = nil) - super(vm,hypervisor) + XPATH_FILTER = "TEMPLATE/NIC[ICMP|WHITE_PORTS_TCP|WHITE_PORTS_UDP|" << + "BLACK_PORTS_TCP|BLACK_PORTS_UDP]" + + def initialize(vm, deploy_id = nil, hypervisor = nil) + super(vm,XPATH_FILTER,deploy_id,hypervisor) end + def activate vm_id = @vm['ID'] process do |nic| diff --git a/src/vnm_mad/remotes/OpenNebulaNetwork.rb b/src/vnm_mad/remotes/OpenNebulaNetwork.rb index a944adeb8d..c4ed9f8a23 100644 --- a/src/vnm_mad/remotes/OpenNebulaNetwork.rb +++ b/src/vnm_mad/remotes/OpenNebulaNetwork.rb @@ -43,16 +43,20 @@ COMMANDS = { } class VM - attr_accessor :nics, :vm_info + attr_accessor :nics, :vm_info, :deploy_id - def initialize(vm_root, hypervisor) - @vm_root = vm_root - @hypervisor = hypervisor - @vm_info = Hash.new + def initialize(vm_root, xpath_filter, deploy_id, hypervisor) + @vm_root = vm_root + @xpath_filter = xpath_filter + @deploy_id = deploy_id + @hypervisor = hypervisor + @vm_info = Hash.new + + @deploy_id = nil if deploy_id == "-" nics = Nics.new(@hypervisor) - @vm_root.elements.each("TEMPLATE/NIC[VLAN='YES']") do |nic_element| + @vm_root.elements.each(@xpath_filter) do |nic_element| nic = nics.new_nic nic_element.elements.each('*') do |nic_attribute| @@ -91,19 +95,19 @@ end class OpenNebulaNetwork attr_reader :hypervisor, :vm - def self.from_base64(vm_64, hypervisor=nil) + def self.from_base64(vm_64, deploy_id = nil, hypervisor = nil) vm_xml = Base64::decode64(vm_64) - self.new(vm_xml, hypervisor) + self.new(vm_xml, deploy_id, hypervisor) end - def initialize(vm_tpl, hypervisor=nil) + def initialize(vm_tpl, xpath_filter, deploy_id = nil, hypervisor = nil) if !hypervisor @hypervisor = detect_hypervisor else @hypervisor = hypervisor end - - @vm = VM.new(REXML::Document.new(vm_tpl).root, @hypervisor) + + @vm = VM.new(REXML::Document.new(vm_tpl).root, xpath_filter, deploy_id, @hypervisor) end def process(&block) diff --git a/src/vnm_mad/remotes/OpenNebulaNic.rb b/src/vnm_mad/remotes/OpenNebulaNic.rb index 84214bd154..176d41246e 100644 --- a/src/vnm_mad/remotes/OpenNebulaNic.rb +++ b/src/vnm_mad/remotes/OpenNebulaNic.rb @@ -39,7 +39,11 @@ class NicKVM < Hash end def get_info(vm) - deploy_id = vm['DEPLOY_ID'] + if vm.deploy_id + deploy_id = vm.deploy_id + else + deploy_id = vm['DEPLOY_ID'] + end if deploy_id and vm.vm_info[:dumpxml].nil? vm.vm_info[:dumpxml] = `#{COMMANDS[:virsh]} dumpxml #{deploy_id} \ diff --git a/src/vnm_mad/remotes/ebtables/Ebtables.rb b/src/vnm_mad/remotes/ebtables/Ebtables.rb index c22ad69340..b76d0cad19 100644 --- a/src/vnm_mad/remotes/ebtables/Ebtables.rb +++ b/src/vnm_mad/remotes/ebtables/Ebtables.rb @@ -17,8 +17,10 @@ require 'OpenNebulaNetwork' class EbtablesVLAN < OpenNebulaNetwork - def initialize(vm, hypervisor = nil) - super(vm,hypervisor) + XPATH_FILTER = "TEMPLATE/NIC[VLAN='YES']" + + def initialize(vm, deploy_id = nil, hypervisor = nil) + super(vm,XPATH_FILTER,deploy_id,hypervisor) end def ebtables(rule) diff --git a/src/vnm_mad/remotes/ebtables/post b/src/vnm_mad/remotes/ebtables/post index a862a9aaa9..9e31babff5 100755 --- a/src/vnm_mad/remotes/ebtables/post +++ b/src/vnm_mad/remotes/ebtables/post @@ -22,10 +22,13 @@ $: << File.join(File.dirname(__FILE__), "..") require 'Ebtables' require 'Firewall' -onevlan = EbtablesVLAN.from_base64(ARGV[0]) +template64 = ARGV[0] +deploy_id = ARGV[1] + +onevlan = EbtablesVLAN.from_base64(template64, deploy_id) onevlan.activate -fw = OpenNebulaFirewall.from_base64(ARGV[0]) +fw = OpenNebulaFirewall.from_base64(template64, deploy_id) fw.activate diff --git a/src/vnm_mad/remotes/fw/post b/src/vnm_mad/remotes/fw/post index 6458772e86..7b0afd182e 100755 --- a/src/vnm_mad/remotes/fw/post +++ b/src/vnm_mad/remotes/fw/post @@ -22,6 +22,9 @@ $: << File.join(File.dirname(__FILE__), "..") require 'OpenNebulaNetwork' require 'Firewall' -fw = OpenNebulaFirewall.from_base64(ARGV[0]) +template64 = ARGV[0] +deploy_id = ARGV[1] + +fw = OpenNebulaFirewall.from_base64(template64, deploy_id) fw.activate diff --git a/src/vnm_mad/remotes/ovswitch/OpenvSwitch.rb b/src/vnm_mad/remotes/ovswitch/OpenvSwitch.rb index 9716d99f8a..8471f66a30 100644 --- a/src/vnm_mad/remotes/ovswitch/OpenvSwitch.rb +++ b/src/vnm_mad/remotes/ovswitch/OpenvSwitch.rb @@ -17,8 +17,10 @@ require 'OpenNebulaNetwork' class OpenvSwitchVLAN < OpenNebulaNetwork - def initialize(vm, hypervisor = nil) - super(vm,hypervisor) + XPATH_FILTER = "TEMPLATE/NIC[VLAN='YES']" + + def initialize(vm, deploy_id = nil, hypervisor = nil) + super(vm,XPATH_FILTER,deploy_id,hypervisor) end def activate diff --git a/src/vnm_mad/remotes/ovswitch/post b/src/vnm_mad/remotes/ovswitch/post index 520d74a455..ceb0a0fc41 100755 --- a/src/vnm_mad/remotes/ovswitch/post +++ b/src/vnm_mad/remotes/ovswitch/post @@ -22,11 +22,13 @@ $: << File.join(File.dirname(__FILE__), "..") require 'OpenvSwitch' require 'Firewall' +template64 = ARGV[0] +deploy_id = ARGV[1] -onevlan = OpenvSwitchVLAN.from_base64(ARGV[0]) +onevlan = OpenvSwitchVLAN.from_base64(template64, deploy_id) onevlan.activate -fw = OpenNebulaFirewall.from_base64(ARGV[0]) +fw = OpenNebulaFirewall.from_base64(template64, deploy_id) fw.activate diff --git a/src/vnm_mad/remotes/test/OpenNebulaNetwork_spec.rb b/src/vnm_mad/remotes/test/OpenNebulaNetwork_spec.rb index c06453ffb0..f451b53c3e 100644 --- a/src/vnm_mad/remotes/test/OpenNebulaNetwork_spec.rb +++ b/src/vnm_mad/remotes/test/OpenNebulaNetwork_spec.rb @@ -1,10 +1,10 @@ #!/usr/bin/env ruby -$: << File.dirname(__FILE__) + '/..' -$: << File.dirname(__FILE__) + '/../ebtables' -$: << File.dirname(__FILE__) + '/../802.1Q' -$: << File.dirname(__FILE__) + '/../ovswitch' -$: << File.dirname(__FILE__) + '/../../../mad/ruby' +$: << File.dirname(__FILE__) + '/..' +$: << File.dirname(__FILE__) + '/../ebtables' +$: << File.dirname(__FILE__) + '/../802.1Q' +$: << File.dirname(__FILE__) + '/../ovswitch' +$: << File.dirname(__FILE__) + '/../../../mad/ruby' $: << './' $: << File.dirname(__FILE__) $: << File.join(File.dirname(__FILE__), '..') @@ -43,7 +43,7 @@ describe 'networking' do $capture_commands = { /virsh.*dumpxml/ => OUTPUT[:virsh_dumpxml] } - onevlan = OpenNebulaNetwork.new(OUTPUT[:onevm_show],"kvm") + onevlan = OpenNebulaNetwork.new(OUTPUT[:onevm_show],"TEMPLATE/NIC",nil,"kvm") nics_expected = [{:bridge=>"br0", :ip=>"172.16.0.100", :mac=>"02:00:ac:10:00:64", @@ -76,7 +76,7 @@ describe 'ebtables' do /virsh.*dumpxml/ => OUTPUT[:virsh_dumpxml], /ebtables/ => nil } - onevlan = EbtablesVLAN.new(OUTPUT[:onevm_show],"kvm") + onevlan = EbtablesVLAN.new(OUTPUT[:onevm_show],nil,"kvm") onevlan.activate ebtables_cmds = [ "sudo /sbin/ebtables -A FORWARD -s ! 02:00:ac:10:00:00/ff:ff:ff:ff:ff:00 -o vnet0 -j DROP", @@ -98,7 +98,7 @@ describe 'openvswitch' do /virsh.*dumpxml/ => OUTPUT[:virsh_dumpxml], /ovs-vsctl/ => nil } - onevlan = OpenvSwitchVLAN.new(OUTPUT[:onevm_show],"kvm") + onevlan = OpenvSwitchVLAN.new(OUTPUT[:onevm_show],nil,"kvm") onevlan.activate openvswitch_tags = [ "sudo /usr/local/bin/ovs-vsctl set Port vnet0 tag=2", @@ -117,7 +117,7 @@ describe 'openvswitch' do /brctl show/ => OUTPUT[:brctl_show], /ovs-vsctl/ => nil } - onevlan = OpenvSwitchVLAN.new(OUTPUT[:onevm_show_vlan_id_kvm],"kvm") + onevlan = OpenvSwitchVLAN.new(OUTPUT[:onevm_show_vlan_id_kvm],nil,"kvm") onevlan.activate onevlan_rules = ["sudo /usr/local/bin/ovs-vsctl set Port vnet0 tag=6", @@ -159,36 +159,37 @@ end describe 'host-managed' do it "tag tun/tap devices with vlans in kvm" do $capture_commands = { - /virsh.*dumpxml/ => OUTPUT[:virsh_dumpxml_phydev], + /virsh.*dumpxml/ => nil, /brctl show/ => OUTPUT[:brctl_show], - /brctl add/ => nil, + /brctl add/ => nil, /vconfig/ => nil, - /ip link/ => nil + /ip link set/ => nil, + /ip link show/ => [nil,255] } - hm = OpenNebulaHM.new(OUTPUT[:onevm_show_phydev_kvm],"kvm") + hm = OpenNebulaHM.new(OUTPUT[:onevm_show_phydev_kvm],nil,"kvm") hm.activate hm_activate_rules = ["sudo /sbin/brctl addbr onebr6", "sudo /sbin/ip link set onebr6 up", - "sudo /sbin/ip link show eth0.8", "sudo /sbin/vconfig add eth0 8", "sudo /sbin/ip link set eth0.8 up", "sudo /sbin/brctl addif onebr6 eth0.8"] - hm_activate_rules.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd| - $collector[:backtick].include?(cmd).should == true + hm_activate_rules.each do |cmd| + $collector[:backtick].grep(Regexp.new("^"+cmd)).length.should >= 1 end end it "force VLAN_ID for vlans in kvm" do $capture_commands = { - /virsh.*dumpxml/ => OUTPUT[:virsh_dumpxml_vlan_id], + /virsh.*dumpxml/ => nil, /brctl show/ => OUTPUT[:brctl_show], /brctl add/ => nil, /vconfig/ => nil, - /ip link/ => nil + /ip link set/ => nil, + /ip link show/ => [nil,255] } - hm = OpenNebulaHM.new(OUTPUT[:onevm_show_vlan_id_kvm],"kvm") + hm = OpenNebulaHM.new(OUTPUT[:onevm_show_vlan_id_kvm],nil,"kvm") hm.activate hm_vlan_id = ["sudo /sbin/brctl addbr onebr10", @@ -204,8 +205,36 @@ describe 'host-managed' do "sudo /sbin/ip link set eth0.51 up", "sudo /sbin/brctl addif specialbr eth0.51"] - hm_vlan_id.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd| - $collector[:backtick].include?(cmd).should == true + hm_vlan_id.each do |cmd| + $collector[:backtick].grep(Regexp.new("^"+cmd)).length.should >= 1 + end + end + + it "ignore interfaces that don't have vlan=yes" do + $capture_commands = { + /virsh.*dumpxml/ => nil, + /brctl show/ => OUTPUT[:brctl_show], + /brctl add/ => nil, + /vconfig/ => nil, + /ip link set/ => nil, + /ip link show/ => [nil,255] + } + + + + hm = OpenNebulaHM.new(OUTPUT[:onevm_show_mixed],nil,"kvm") + hm.activate + + hm_vlan_tag = [ "sudo /sbin/brctl show", + "sudo /sbin/brctl addbr onebr1", + "sudo /sbin/ip link set onebr1 up", + "sudo /sbin/ip link show eth0.50", + "sudo /sbin/vconfig add eth0 50", + "sudo /sbin/ip link set eth0.50 up", + "sudo /sbin/brctl addif onebr1 eth0.50" ] + + hm_vlan_tag.each do |cmd| + $collector[:backtick].grep(Regexp.new("^"+cmd)).length.should >= 1 end end end diff --git a/src/vnm_mad/remotes/test/SystemMock.rb b/src/vnm_mad/remotes/test/SystemMock.rb index 6e83e85411..e1447a4ff3 100644 --- a/src/vnm_mad/remotes/test/SystemMock.rb +++ b/src/vnm_mad/remotes/test/SystemMock.rb @@ -2,9 +2,16 @@ module SystemMock def execute_cmd(cmd) if $capture_commands - $capture_commands.each do |regex, output| + $capture_commands.each do |regex, params| + code = nil + if params.instance_of? Array + output, code = params + else + output = params + end + code ||= 0 if cmd.match(regex) - Kernel.send(:`,":;exit 0") + Kernel.send(:`,":;exit #{code}") return output end end diff --git a/src/vnm_mad/remotes/test/output/onevm_show_mixed b/src/vnm_mad/remotes/test/output/onevm_show_mixed new file mode 100644 index 0000000000..a45abbf003 --- /dev/null +++ b/src/vnm_mad/remotes/test/output/onevm_show_mixed @@ -0,0 +1,81 @@ + + 12 + 0 + 0 + oneadmin + oneadmin + ttylinux + 1323096916 + 3 + 3 + 1323096908 + 0 + one-12 + 0 + 0 + 0 + 0 + + + + 0 + localhost + /var/lib/one/ + 1 + 1323096914 + 0 + vmm_kvm + 802.1Q + tm_shared + 1323096914 + 1323096914 + 1323096914 + 0 + 0 + 0 + 0 + + + diff --git a/src/vnm_mad/remotes/test/output/onevm_show_xen b/src/vnm_mad/remotes/test/output/onevm_show_xen index 9f0685ad44..4952762493 100644 --- a/src/vnm_mad/remotes/test/output/onevm_show_xen +++ b/src/vnm_mad/remotes/test/output/onevm_show_xen @@ -34,7 +34,7 @@ - +