From 00f8b78f9a2166a2b98968f0ab4b1c8a7f9f90c2 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Tue, 14 Feb 2012 12:09:59 +0100 Subject: [PATCH 01/12] bug #1123: Filter Sunstone monitoring information by user --- src/sunstone/models/SunstoneServer.rb | 9 ++++++--- src/sunstone/sunstone-server.rb | 6 ++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/sunstone/models/SunstoneServer.rb b/src/sunstone/models/SunstoneServer.rb index a8113bcf65..e8222d1670 100644 --- a/src/sunstone/models/SunstoneServer.rb +++ b/src/sunstone/models/SunstoneServer.rb @@ -267,7 +267,7 @@ class SunstoneServer # ############################################################################ - def get_monitoring(id, resource, monitor_resources, gid) + def get_monitoring(id, resource, monitor_resources, opts={}) watch_client = case resource when "vm","VM" OneWatchClient::VmWatchClient.new @@ -278,13 +278,16 @@ class SunstoneServer return [200, error.to_json] end + filter = {} + filter[:uid] = opts[:uid] if opts[:gid]!="0" + columns = monitor_resources.split(',') columns.map!{|e| e.to_sym} if id - rc = watch_client.resource_monitoring(id.to_i, columns) + rc = watch_client.resource_monitoring(id.to_i, columns, filter) else - rc = watch_client.total_monitoring(columns) + rc = watch_client.total_monitoring(columns, filter) end if rc.nil? diff --git a/src/sunstone/sunstone-server.rb b/src/sunstone/sunstone-server.rb index 2ece360837..985ff2338f 100755 --- a/src/sunstone/sunstone-server.rb +++ b/src/sunstone/sunstone-server.rb @@ -243,7 +243,8 @@ get '/:resource/monitor' do nil, params[:resource], params[:monitor_resources], - session[:user_gid]) + :uid => session[:user_id], + :gid => session[:user_gid]) end get '/:resource/:id/monitor' do @@ -251,7 +252,8 @@ get '/:resource/:id/monitor' do params[:id], params[:resource], params[:monitor_resources], - session[:user_gid]) + :uid => session[:user_id], + :gid => session[:user_gid]) end From 10d4412a54dd01c4ca4c39501c1d6b3419173543 Mon Sep 17 00:00:00 2001 From: Patrice LACHANCE Date: Tue, 3 Jan 2012 15:42:10 +0000 Subject: [PATCH 02/12] Added EC2 Regions, Security Groups, VPC ID, Tags and Context management --- src/vmm_mad/ec2/one_vmm_ec2.rb | 188 +++++++++++++++++++++++++++++---- 1 file changed, 166 insertions(+), 22 deletions(-) diff --git a/src/vmm_mad/ec2/one_vmm_ec2.rb b/src/vmm_mad/ec2/one_vmm_ec2.rb index cd7b36b17b..3b851a835e 100755 --- a/src/vmm_mad/ec2/one_vmm_ec2.rb +++ b/src/vmm_mad/ec2/one_vmm_ec2.rb @@ -52,8 +52,8 @@ class EC2Driver < VirtualMachineDriver :terminate => "#{EC2_LOCATION}/bin/ec2-terminate-instances", :describe => "#{EC2_LOCATION}/bin/ec2-describe-instances", :associate => "#{EC2_LOCATION}/bin/ec2-associate-address", - :reboot => "#{EC2_LOCATION}/bin/ec2-reboot-instances", - :authorize => "#{EC2_LOCATION}/bin/ec2-authorize" + :authorize => "#{EC2_LOCATION}/bin/ec2-authorize", + :tags => "#{EC2_LOCATION}/bin/ec2-create-tags" } # EC2 constructor, loads defaults for the EC2Driver @@ -134,11 +134,36 @@ class EC2Driver < VirtualMachineDriver end end - ami = ec2_value(ec2,"AMI") - keypair = ec2_value(ec2,"KEYPAIR") - eip = ec2_value(ec2,"ELASTICIP") - ports = ec2_value(ec2,"AUTHORIZEDPORTS") - type = ec2_value(ec2,"INSTANCETYPE") + aki = ec2_value(ec2,"AKI") + ami = ec2_value(ec2,"AMI") + ports = ec2_value(ec2,"AUTHORIZEDPORTS") + blockmapping = ec2_value(ec2,"BLOCKDEVICEMAPPING") + clienttoken = ec2_value(ec2,"CLIENTTOKEN") + ec2region = host_info("deploy",host,"EC2REGION") + eip = ec2_value(ec2,"ELASTICIP") + type = ec2_value(ec2,"INSTANCETYPE") + keypair = ec2_value(ec2,"KEYPAIR") + licensepool = ec2_value(ec2,"LICENSEPOOL") + clustergroup = ec2_value(ec2,"PLACEMENTGROUP") + privateip = ec2_value(ec2,"PRIVATEIP") + ramdisk = ec2_value(ec2,"RAMDISK") + secgroup = ec2_value(ec2,"SECURITYGROUPS") + subnetid = ec2_value(ec2,"SUBNETID") + tags = ec2_value(ec2,"TAGS") + tenancy = ec2_value(ec2,"TENANCY") + vpcid = ec2_value(ec2,"VPCID") + waitb4eip = ec2_value(ec2,"WAITFORINSTANCE") + ec2context = "" + + # get context data, if any + all_context_elements = xml.root.get_elements("CONTEXT") + context_root = all_context_elements[0] + if context_root + context_ud = ec2_value(context_root,"USERDATA") + context_udf = ec2_value(context_root,"USERDATAFILE") + ec2context << " -d '#{context_ud}'" if context_ud + ec2context << " -f #{context_udf}" if context_udf + end if !ami send_message(ACTION[:deploy],RESULT[:failure],id, @@ -146,9 +171,26 @@ class EC2Driver < VirtualMachineDriver return end - deploy_cmd = "#{EC2[:run]} #{ami}" + deploy_cmd = "#{EC2[:run]} --region #{ec2region} #{ec2context}" + deploy_cmd << " #{ami}" + deploy_cmd << " --kernel #{aki}" if aki + deploy_cmd << " -b #{blockmapping}" if blockmapping + deploy_cmd << " --client-token #{clienttoken}" if clienttoken deploy_cmd << " -k #{keypair}" if keypair + deploy_cmd << " --license-pool #{licensepool}" if licensepool deploy_cmd << " -t #{type}" if type + deploy_cmd << " --ramdisk #{ramdisk}" if ramdisk + deploy_cmd << " --placement-group #{clustergroup}" if clustergroup + if subnetid + deploy_cmd << " -s #{subnetid}" + deploy_cmd << " --private-ip-address #{privateip}" if privateip + deploy_cmd << " --tenancy #{tenancy}" if tenancy + end + if secgroup + for grouptok in secgroup.split(',') + deploy_cmd << " -g #{grouptok}" + end + end deploy_exe = LocalCommand.run(deploy_cmd, log_method(id)) @@ -165,14 +207,69 @@ class EC2Driver < VirtualMachineDriver deploy_id = $1 - if eip - ip_cmd = "#{EC2[:associate]} #{eip} -i #{deploy_id}" - ip_exe = LocalCommand.run(ip_cmd, log_method(id)) + if ports + ports_cmd = "#{EC2[:authorize]} --region #{ec2region} default -p #{ports}" + ports_exe = LocalCommand.run(ports_cmd, log_method(id)) end - if ports - ports_cmd = "#{EC2[:authorize]} default -p #{ports}" - ports_exe = LocalCommand.run(ports_cmd, log_method(id)) + # adding EC2 tags if any are defined in the EC2 section. + # Tags should be defined as a TAG=VAL comma seperated string like + # TAGS="Tag1=Val1, Tag2=Val2, ..." + # + # Notes: + # - If 'Value' starts with a '$', the code will try to resolve it as + # a variable name. For example the special tag 'Name' can be use + # to define the name of the instance visible in the AWS Console + # with the following tag definition + # TAGS="Name=$NAME, tag2=val2, ..." + # + # To resolve the variables, the instance's deployment.0 file + # is parsed as follow: + # -> try to find an element corresponding to the variable name at + # the root of the xml tree + # -> if none is found, another search if tried at second level of + # the tree + # -> In both cases, the first match will be used so you know what + # to look at if you don't get what you expect... might be + # fixed in the future if needed. + if tags + tags_cmd = "#{EC2[:tags]} --region #{ec2region} #{deploy_id}" + for tag in tags.split(',') + token = tag.split('=') + t_regex = /^(.{1})(.*)$/ + t_match = t_regex.match(token[1]) + if t_match[1] == "$" + value = "" + element = xml.root.elements[t_match[2]] + element = xml.root.elements["*/" << t_match[2]] unless element + value = element.text.strip if element && element.text + tag = token[0].strip << "=" << value.chomp + end + tags_cmd << " -t #{tag}" + end + tags_exe = LocalCommand.run(tags_cmd, log_method(id)) + end + + if eip + if subnetid + ip_cmd = "#{EC2[:associate]} --region #{ec2region} -a #{eip} -i #{deploy_id}" + else + ip_cmd = "#{EC2[:associate]} --region #{ec2region} #{eip} -i #{deploy_id}" + end + + # Make sure instance is running state before assigning Elastic IP + if waitb4eip + pos=2 + pos=1 if subnetid + wait4instance(ec2region,id,deploy_id,pos,"running") + end + + ip_exe = LocalCommand.run(ip_cmd, log_method(id)) + if !ip_exe.stdout.match(/^ADDRESS\s*(.+?)\s/) + send_message(ACTION[:deploy],RESULT[:failure],id, + "Could not associate Elastic IP. Check template definition.") + return + end end send_message(ACTION[:deploy],RESULT[:success],id,deploy_id) @@ -185,12 +282,14 @@ class EC2Driver < VirtualMachineDriver host = msg.elements["HOST"].text deploy_id = msg.elements["DEPLOY_ID"].text - ec2_terminate(ACTION[:shutdown], id, deploy_id) + ec2_terminate(ACTION[:shutdown], id, deploy_id, host) end - - # Reboot a EC2 instance + + # Reboot a EC2 instance def reboot(id, drv_message) - cmd = "#{EC2_LOCATION}/bin/ec2-reboot-instances #{deploy_id}" + ec2region = host_info("reboot",host,"EC2REGION") + + cmd = "#{EC2_LOCATION}/bin/ec2-reboot-instances --region #{ec2region} #{deploy_id}" exe = LocalCommand.run(cmd, log_method(id)) if exe.code != 0 @@ -209,7 +308,7 @@ class EC2Driver < VirtualMachineDriver host = msg.elements["HOST"].text deploy_id = msg.elements["DEPLOY_ID"].text - ec2_terminate(ACTION[:cancel], id, deploy_id) + ec2_terminate(ACTION[:cancel], id, deploy_id, host) end # Get info (IP, and state) for a EC2 instance @@ -218,13 +317,14 @@ class EC2Driver < VirtualMachineDriver host = msg.elements["HOST"].text deploy_id = msg.elements["DEPLOY_ID"].text + ec2region = host_info("poll",host,"EC2REGION") info = "#{POLL_ATTRIBUTE[:usedmemory]}=0 " \ "#{POLL_ATTRIBUTE[:usedcpu]}=0 " \ "#{POLL_ATTRIBUTE[:nettx]}=0 " \ "#{POLL_ATTRIBUTE[:netrx]}=0" - cmd = "#{EC2[:describe]} #{deploy_id}" + cmd = "#{EC2[:describe]} --region #{ec2region} --hide-tags #{deploy_id}" exe = LocalCommand.run(cmd, log_method(id)) if exe.code != 0 @@ -255,8 +355,10 @@ class EC2Driver < VirtualMachineDriver private - def ec2_terminate(action, id, deploy_id) - cmd = "#{EC2_LOCATION}/bin/ec2-terminate-instances #{deploy_id}" + def ec2_terminate(action, id, deploy_id, host) + ec2region = host_info("terminate",host,"EC2REGION") + + cmd = "#{EC2_LOCATION}/bin/ec2-terminate-instances --region #{ec2region} #{deploy_id}" exe = LocalCommand.run(cmd, log_method(id)) if exe.code != 0 @@ -279,6 +381,48 @@ private return value end + def host_info(action,host,key) + # get EC2REGION parameter from the selected host + query_cmd = "#{ONE_LOCATION}/bin/onehost show #{host}" + query_exe = LocalCommand.run(query_cmd, log_method(id)) + + if query_exe.code != 0 + send_message(action,RESULT[:failure],host) + return + end + + if !query_exe.stdout.match(/^#{key}=(.+?)\s/) + send_message(action,RESULT[:failure],host, + "Could not find #{param} parameter for host #{host}. Use onehost update #{host} to define this paramete first") + return + end + + return $1 + end + def wait4instance(region,id,deploy_id,pos,value) + found = 0 + while found == 0 do + poll_cmd = "#{EC2[:describe]} --region #{region} --hide-tags #{deploy_id}" + poll_exe = LocalCommand.run(poll_cmd, log_method(id)) + + if poll_exe.code != 0 + send_message(ACTION[:deploy],RESULT[:failure],id, + "Error polling instance.") + return + end + + poll_exe.stdout.match(Regexp.new("INSTANCE\\s+#{deploy_id}\\s+(.+)")) + + if !$1 + send_message(ACTION[:deploy],RESULT[:failure],id, + "ERROR: Instance not found and should have been created.") + return + else + monitor_data = $1.split(/\s+/) + found = 1 if monitor_data[pos] == value + end + end + end end # EC2Driver Main program From b70a4e33ba5083f69208a48f6d437ade3fe79ea9 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Thu, 16 Feb 2012 12:43:40 +0100 Subject: [PATCH 03/12] feature #1048: Refactor one_vmm_ec2 and add suspend/reboot/resume support --- src/vmm_mad/ec2/one_vmm_ec2.rb | 536 ++++++++++++++++----------------- 1 file changed, 252 insertions(+), 284 deletions(-) diff --git a/src/vmm_mad/ec2/one_vmm_ec2.rb b/src/vmm_mad/ec2/one_vmm_ec2.rb index 3b851a835e..a4ce862b05 100755 --- a/src/vmm_mad/ec2/one_vmm_ec2.rb +++ b/src/vmm_mad/ec2/one_vmm_ec2.rb @@ -38,9 +38,9 @@ end $: << RUBY_LIB_LOCATION -require 'pp' require "VirtualMachineDriver" require "CommandManager" +require 'scripts_common' require "rexml/document" # The main class for the EC2 driver @@ -48,27 +48,113 @@ class EC2Driver < VirtualMachineDriver # EC2 commands constants EC2 = { - :run => "#{EC2_LOCATION}/bin/ec2-run-instances", - :terminate => "#{EC2_LOCATION}/bin/ec2-terminate-instances", - :describe => "#{EC2_LOCATION}/bin/ec2-describe-instances", - :associate => "#{EC2_LOCATION}/bin/ec2-associate-address", - :authorize => "#{EC2_LOCATION}/bin/ec2-authorize", - :tags => "#{EC2_LOCATION}/bin/ec2-create-tags" + :run => { + :cmd => "#{EC2_LOCATION}/bin/ec2-run-instances", + :args => { + "AKI" => { + :opt => '--kernel' + }, + "AMI" => { + :opt => '' + }, + "BLOCKDEVICEMAPPING" => { + :opt => '-b' + }, + "CLIENTTOKEN" => { + :opt => '--client-token' + }, + "INSTANCETYPE" => { + :opt => '-t' + }, + "KEYPAIR" => { + :opt => '-k' + }, + "LICENSEPOOL" => { + :opt => '--license-pool' + }, + "PLACEMENTGROUP" => { + :opt => '--placement-group' + }, + "PRIVATEIP" => { + :opt => '--private-ip-address' + }, + "RAMDISK" => { + :opt => '--ramdisk' + }, + "SUBNETID" => { + :opt => '-s' + }, + "TENANCY" => { + :opt => '--tenancy' + }, + "USERDATA" => { + :opt => '-d' + }, + "USERDATAFILE" => { + :opt => '-f' + }, + "SECURITYGROUPS" => { + :opt => '-g', + :proc => lambda {|str| str.split(',').join(' -g ')} + } + } + }, + :terminate => { + :cmd => "#{EC2_LOCATION}/bin/ec2-terminate-instances" + }, + :describe => { + :cmd => "#{EC2_LOCATION}/bin/ec2-describe-instances" + }, + :associate => { + :cmd => "#{EC2_LOCATION}/bin/ec2-associate-address", + :args => { + "SUBNETID" => { + :opt => '-a', + :proc => lambda {|str| ''} + }, + "ELASTICIP" => { + :opt => '' + } + } + }, + :authorize => { + :cmd => "#{EC2_LOCATION}/bin/ec2-authorize", + :args => { + "AUTHORIZEDPORTS" => { + :opt => '-p', + :proc => lambda {|str| str.split(',').join(' -p ')} + } + } + }, + :reboot => { + :cmd => "#{EC2_LOCATION}/bin/ec2-reboot-instances" + }, + :stop => { + :cmd => "#{EC2_LOCATION}/bin/ec2-stop-instances" + }, + :start => { + :cmd => "#{EC2_LOCATION}/bin/ec2-start-instances" + }, + :tags => { + :cmd => "#{EC2_LOCATION}/bin/ec2-create-tags", + :args => { + "TAGS" => { + :opt => '-t', + :proc => lambda {|str| str.split(',').join(' -t ')} + } + } + } } # EC2 constructor, loads defaults for the EC2Driver def initialize(ec2_conf = nil) - if !EC2_JVM_CONCURRENCY concurrency = 5 else concurrency = EC2_JVM_CONCURRENCY.to_i end - super('', - :concurrency => concurrency, - :threaded => true - ) + super('', :concurrency => concurrency, :threaded => true) @defaults = Hash.new @@ -83,18 +169,127 @@ class EC2Driver < VirtualMachineDriver return if !ec2 - @defaults["KEYPAIR"] = ec2_value(ec2,"KEYPAIR") - @defaults["AUTHORIZEDPORTS"] = ec2_value(ec2,"AUTHORIZEDPORTS") - @defaults["INSTANCETYPE"] = ec2_value(ec2,"INSTANCETYPE") + EC2.each {|action, hash| + if hash[:args] + hash[:args].each { |key, value| + @defaults[key] = value_from_xml(ec2, key) + } + end + } end end # DEPLOY action, also sets ports and ip if needed def deploy(id, drv_message) + ec2_info = get_deployment_info(drv_message) + return unless ec2_info + + if !ec2_value(ec2_info, 'AMI') + msg = "Can not find AMI in deployment file" + send_message(ACTION[:deploy], RESULT[:failure], id, msg) + return + end + + deploy_exe = exec_and_log_ec2(:run, ec2_info, id) + if deploy_exe.code != 0 + msg = deploy_exe.stderr + send_message(ACTION[:deploy], RESULT[:failure], id, msg) + return + end + + if !deploy_exe.stdout.match(/^INSTANCE\s*(.+?)\s/) + msg = "Could not find instance id. Check ec2-describe-instances" + send_message(ACTION[:deploy], RESULT[:failure], id, msg) + return + end + + deploy_id = $1 + + if ec2_value(ec2_info, 'AUTHORIZEDPORTS') + exec_and_log_ec2(:authorize, ec2_info, 'default', id) + end + + if ec2_value(ec2_info, 'TAGS') + exec_and_log_ec2(:tags, ec2_info, deploy_id, id) + end + + if ec2_value(ec2_info, 'ELASTICIP') + exec_and_log_ec2(:associate, ec2_info, "-i #{deploy_id}", id) + end + + send_message(ACTION[:deploy], RESULT[:success], id, deploy_id) + end + + # Shutdown a EC2 instance + def shutdown(id, drv_message) + ec2_action(drv_message, :terminate, ACTION[:shutdown], id) + end + + # Reboot a EC2 instance + def reboot(id, drv_message) + ec2_action(drv_message, :reboot, ACTION[:reboot], id) + end + + # Cancel a EC2 instance + def cancel(id, drv_message) + ec2_action(drv_message, :terminate, ACTION[:cancel], id) + end + + # Stop a EC2 instance + def save(id, drv_message) + ec2_action(drv_message, :stop, ACTION[:save], id) + end + + # Cancel a EC2 instance + def restore(id, drv_message) + ec2_action(drv_message, :start, ACTION[:restor], id) + end + + # Get info (IP, and state) for a EC2 instance + def poll(id, drv_message) + msg = decode(drv_message) + + deploy_id = msg.elements["DEPLOY_ID"].text + + info = "#{POLL_ATTRIBUTE[:usedmemory]}=0 " \ + "#{POLL_ATTRIBUTE[:usedcpu]}=0 " \ + "#{POLL_ATTRIBUTE[:nettx]}=0 " \ + "#{POLL_ATTRIBUTE[:netrx]}=0" + + + exe = exec_and_log_ec2(:describe, nil, deploy_id, id) + if exe.code != 0 + send_message(ACTION[:poll], RESULT[:failure], id, exe.stderr) + return + end + + exe.stdout.match(Regexp.new("INSTANCE\\s+#{deploy_id}\\s+(.+)")) + + if !$1 + info << " #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:deleted]}" + else + monitor_data = $1.split(/\s+/) + + case monitor_data[3] + when "pending" + info << " #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:active]}" + when "running" + info<<" #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:active]}"<< + " IP=#{monitor_data[1]}" + when "shutting-down","terminated" + info << " #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:deleted]}" + end + end + + send_message(ACTION[:poll], RESULT[:success], id, info) + end + +private + + def get_deployment_info(drv_message) msg = decode(drv_message) host = msg.elements["HOST"].text - local_dfile = msg.elements["LOCAL_DEPLOYMENT_FILE"].text if !local_dfile @@ -134,293 +329,66 @@ class EC2Driver < VirtualMachineDriver end end - aki = ec2_value(ec2,"AKI") - ami = ec2_value(ec2,"AMI") - ports = ec2_value(ec2,"AUTHORIZEDPORTS") - blockmapping = ec2_value(ec2,"BLOCKDEVICEMAPPING") - clienttoken = ec2_value(ec2,"CLIENTTOKEN") - ec2region = host_info("deploy",host,"EC2REGION") - eip = ec2_value(ec2,"ELASTICIP") - type = ec2_value(ec2,"INSTANCETYPE") - keypair = ec2_value(ec2,"KEYPAIR") - licensepool = ec2_value(ec2,"LICENSEPOOL") - clustergroup = ec2_value(ec2,"PLACEMENTGROUP") - privateip = ec2_value(ec2,"PRIVATEIP") - ramdisk = ec2_value(ec2,"RAMDISK") - secgroup = ec2_value(ec2,"SECURITYGROUPS") - subnetid = ec2_value(ec2,"SUBNETID") - tags = ec2_value(ec2,"TAGS") - tenancy = ec2_value(ec2,"TENANCY") - vpcid = ec2_value(ec2,"VPCID") - waitb4eip = ec2_value(ec2,"WAITFORINSTANCE") - ec2context = "" - - # get context data, if any - all_context_elements = xml.root.get_elements("CONTEXT") - context_root = all_context_elements[0] - if context_root - context_ud = ec2_value(context_root,"USERDATA") - context_udf = ec2_value(context_root,"USERDATAFILE") - ec2context << " -d '#{context_ud}'" if context_ud - ec2context << " -f #{context_udf}" if context_udf - end - - if !ami - send_message(ACTION[:deploy],RESULT[:failure],id, - "Can not find AMI in deployment file #{local_dfile}") - return - end - - deploy_cmd = "#{EC2[:run]} --region #{ec2region} #{ec2context}" - deploy_cmd << " #{ami}" - deploy_cmd << " --kernel #{aki}" if aki - deploy_cmd << " -b #{blockmapping}" if blockmapping - deploy_cmd << " --client-token #{clienttoken}" if clienttoken - deploy_cmd << " -k #{keypair}" if keypair - deploy_cmd << " --license-pool #{licensepool}" if licensepool - deploy_cmd << " -t #{type}" if type - deploy_cmd << " --ramdisk #{ramdisk}" if ramdisk - deploy_cmd << " --placement-group #{clustergroup}" if clustergroup - if subnetid - deploy_cmd << " -s #{subnetid}" - deploy_cmd << " --private-ip-address #{privateip}" if privateip - deploy_cmd << " --tenancy #{tenancy}" if tenancy - end - if secgroup - for grouptok in secgroup.split(',') - deploy_cmd << " -g #{grouptok}" - end - end - - deploy_exe = LocalCommand.run(deploy_cmd, log_method(id)) - - if deploy_exe.code != 0 - send_message(ACTION[:deploy],RESULT[:failure],id) - return - end - - if !deploy_exe.stdout.match(/^INSTANCE\s*(.+?)\s/) - send_message(ACTION[:deploy],RESULT[:failure],id, - "Could not find instance id. Check ec2-describe-instances") - return - end - - deploy_id = $1 - - if ports - ports_cmd = "#{EC2[:authorize]} --region #{ec2region} default -p #{ports}" - ports_exe = LocalCommand.run(ports_cmd, log_method(id)) - end - - # adding EC2 tags if any are defined in the EC2 section. - # Tags should be defined as a TAG=VAL comma seperated string like - # TAGS="Tag1=Val1, Tag2=Val2, ..." - # - # Notes: - # - If 'Value' starts with a '$', the code will try to resolve it as - # a variable name. For example the special tag 'Name' can be use - # to define the name of the instance visible in the AWS Console - # with the following tag definition - # TAGS="Name=$NAME, tag2=val2, ..." - # - # To resolve the variables, the instance's deployment.0 file - # is parsed as follow: - # -> try to find an element corresponding to the variable name at - # the root of the xml tree - # -> if none is found, another search if tried at second level of - # the tree - # -> In both cases, the first match will be used so you know what - # to look at if you don't get what you expect... might be - # fixed in the future if needed. - if tags - tags_cmd = "#{EC2[:tags]} --region #{ec2region} #{deploy_id}" - for tag in tags.split(',') - token = tag.split('=') - t_regex = /^(.{1})(.*)$/ - t_match = t_regex.match(token[1]) - if t_match[1] == "$" - value = "" - element = xml.root.elements[t_match[2]] - element = xml.root.elements["*/" << t_match[2]] unless element - value = element.text.strip if element && element.text - tag = token[0].strip << "=" << value.chomp - end - tags_cmd << " -t #{tag}" - end - tags_exe = LocalCommand.run(tags_cmd, log_method(id)) - end - - if eip - if subnetid - ip_cmd = "#{EC2[:associate]} --region #{ec2region} -a #{eip} -i #{deploy_id}" - else - ip_cmd = "#{EC2[:associate]} --region #{ec2region} #{eip} -i #{deploy_id}" - end - - # Make sure instance is running state before assigning Elastic IP - if waitb4eip - pos=2 - pos=1 if subnetid - wait4instance(ec2region,id,deploy_id,pos,"running") - end - - ip_exe = LocalCommand.run(ip_cmd, log_method(id)) - if !ip_exe.stdout.match(/^ADDRESS\s*(.+?)\s/) - send_message(ACTION[:deploy],RESULT[:failure],id, - "Could not associate Elastic IP. Check template definition.") - return - end - end - - send_message(ACTION[:deploy],RESULT[:success],id,deploy_id) + ec2 end - # Shutdown a EC2 instance - def shutdown(id, drv_message) + # Execute an EC2 command and send the SUCCESS or FAILURE signal + # +drv_message+: String, base64 encoded info sent by ONE + # +ec2_action+: Symbol, one of the keys of the EC2 hash constant (i.e :run) + # +one_action+: String, OpenNebula action + # +id+: String, action id + def ec2_action(drv_message, ec2_action, one_action, id) msg = decode(drv_message) - host = msg.elements["HOST"].text deploy_id = msg.elements["DEPLOY_ID"].text - ec2_terminate(ACTION[:shutdown], id, deploy_id, host) - end - - # Reboot a EC2 instance - def reboot(id, drv_message) - ec2region = host_info("reboot",host,"EC2REGION") - - cmd = "#{EC2_LOCATION}/bin/ec2-reboot-instances --region #{ec2region} #{deploy_id}" - exe = LocalCommand.run(cmd, log_method(id)) - + exe = exec_and_log_ec2(ec2_action, nil, deploy_id, id) if exe.code != 0 - result = RESULT[:failure] + send_message(one_action, RESULT[:failure], id, exe.stderr) else - result = RESULT[:success] + send_message(one_action, RESULT[:success], id) end - - send_message(action,result,id) end - # Cancel a EC2 instance - def cancel(id, drv_message) - msg = decode(drv_message) + # Execute an EC2 command and log the message if error + # This function will build the command joining the :cmd value of the EC2 + # hash, the extra_params string and the options built from the :args schema + # of the EC2 hash and the xml + # +action+: Symbol, one of the keys of the EC2 hash constant (i.e :run) + # +xml+: REXML Document, containing EC2 information + # +extra_params+: String, extra information to be added to the command + def exec_and_log_ec2(action, xml, extra_params="", id) + cmd = EC2[action][:cmd].clone + cmd << ' ' << extra_params << ' ' if extra_params - host = msg.elements["HOST"].text - deploy_id = msg.elements["DEPLOY_ID"].text - - ec2_terminate(ACTION[:cancel], id, deploy_id, host) - end - - # Get info (IP, and state) for a EC2 instance - def poll(id, drv_message) - msg = decode(drv_message) - - host = msg.elements["HOST"].text - deploy_id = msg.elements["DEPLOY_ID"].text - ec2region = host_info("poll",host,"EC2REGION") - - info = "#{POLL_ATTRIBUTE[:usedmemory]}=0 " \ - "#{POLL_ATTRIBUTE[:usedcpu]}=0 " \ - "#{POLL_ATTRIBUTE[:nettx]}=0 " \ - "#{POLL_ATTRIBUTE[:netrx]}=0" - - cmd = "#{EC2[:describe]} --region #{ec2region} --hide-tags #{deploy_id}" - exe = LocalCommand.run(cmd, log_method(id)) - - if exe.code != 0 - send_message(ACTION[:poll],RESULT[:failure],id) - return + if EC2[action][:args] + cmd << EC2[action][:args].map {|k,v| + str = ec2_value(xml, k, &v[:proc]) + v[:opt] + ' ' + str if str + }.join(' ') end - exe.stdout.match(Regexp.new("INSTANCE\\s+#{deploy_id}\\s+(.+)")) + LocalCommand.run(cmd, log_method(id)) + end - if !$1 - info << " #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:deleted]}" + # Returns the value of the xml specified by the name or the default + # one if it does not exist + # +xml+: REXML Document, containing EC2 information + # +name+: String, xpath expression to retrieve the value + # +block+: Block, block to be applied to the value before returning it + def ec2_value(xml, name, &block) + value = value_from_xml(xml, name) || @defaults[name] + if block_given? && value + block.call(value) else - monitor_data = $1.split(/\s+/) - - case monitor_data[3] - when "pending" - info << " #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:active]}" - when "running" - info<<" #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:active]}"<< - " IP=#{monitor_data[1]}" - when "shutting-down","terminated" - info << " #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:deleted]}" - end + value end - - send_message(ACTION[:poll], RESULT[:success], id, info) end -private - - def ec2_terminate(action, id, deploy_id, host) - ec2region = host_info("terminate",host,"EC2REGION") - - cmd = "#{EC2_LOCATION}/bin/ec2-terminate-instances --region #{ec2region} #{deploy_id}" - exe = LocalCommand.run(cmd, log_method(id)) - - if exe.code != 0 - result = RESULT[:failure] - else - result = RESULT[:success] - end - - send_message(action,result,id) - end - - def ec2_value(xml,name) - value = nil - element = xml.elements[name] - value = element.text.strip if element && element.text - - if !value - value = @defaults[name] - end - - return value - end - def host_info(action,host,key) - # get EC2REGION parameter from the selected host - query_cmd = "#{ONE_LOCATION}/bin/onehost show #{host}" - query_exe = LocalCommand.run(query_cmd, log_method(id)) - - if query_exe.code != 0 - send_message(action,RESULT[:failure],host) - return - end - - if !query_exe.stdout.match(/^#{key}=(.+?)\s/) - send_message(action,RESULT[:failure],host, - "Could not find #{param} parameter for host #{host}. Use onehost update #{host} to define this paramete first") - return - end - - return $1 - end - def wait4instance(region,id,deploy_id,pos,value) - found = 0 - while found == 0 do - poll_cmd = "#{EC2[:describe]} --region #{region} --hide-tags #{deploy_id}" - poll_exe = LocalCommand.run(poll_cmd, log_method(id)) - - if poll_exe.code != 0 - send_message(ACTION[:deploy],RESULT[:failure],id, - "Error polling instance.") - return - end - - poll_exe.stdout.match(Regexp.new("INSTANCE\\s+#{deploy_id}\\s+(.+)")) - - if !$1 - send_message(ACTION[:deploy],RESULT[:failure],id, - "ERROR: Instance not found and should have been created.") - return - else - monitor_data = $1.split(/\s+/) - found = 1 if monitor_data[pos] == value - end + def value_from_xml(xml, name) + if xml + element = xml.elements[name] + element.text.strip if element && element.text end end end From 502ec84ef30f61ca579e7cb0da47ed3daa726304 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 16 Feb 2012 13:54:38 +0100 Subject: [PATCH 04/12] Feature #1067: Improve VLAN support in Sunstone (cherry picked from commit 5f984c664ba9788cae308faf7b1702f228ce2b18) --- src/sunstone/public/js/plugins/hosts-tab.js | 3 +- src/sunstone/public/js/plugins/vnets-tab.js | 138 ++++++++++++++++---- 2 files changed, 117 insertions(+), 24 deletions(-) diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index bffa341124..d076b59573 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -85,11 +85,12 @@ var create_host_tmpl =
\ \ \
\
\ diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 87a153b4e9..daa3f60a3e 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -51,8 +51,25 @@ var create_vn_tmpl =
\ \
\ + \ +
\ \
\ + \ + \ + \ +
\ + \ +
\
\
\ \ @@ -530,12 +547,20 @@ function updateVNetworkInfo(request,vn){ '+tr("Group")+'\ '+vn_info.GNAME+'\ \ + \ + '+tr("Bridge")+'\ + '+ (typeof(vn_info.BRIDGE) == "object" ? "--": vn_info.BRIDGE) +'\ + \ + \ + '+tr("VLAN")+'\ + '+ (vn_info.VLAN == "0" ? "no" : "yes") +'\ + \ \ '+tr("Physical device")+'\ '+ (typeof(vn_info.PHYDEV) == "object" ? "--": vn_info.PHYDEV) +'\ \ \ - '+tr("VNET ID")+'\ + '+tr("VLAN ID")+'\ '+ (typeof(vn_info.VLAN_ID) == "object" ? "--": vn_info.VLAN_ID) +'\ \ Permissions\ @@ -704,6 +729,36 @@ function setupCreateVNetDialog() { $('div#fixed',$create_vn_dialog).hide(); $('div#ranged',$create_vn_dialog).show(); }); + + $('#network_mode',dialog).change(function(){ + $('input,select#vlan,label[for!="network_mode"]', $(this).parent()).hide(); + $('input', $(this).parent()).val(""); + switch ($(this).val()) { + case "default": + $('input#bridge,label[for="bridge"]',$create_vn_dialog).show(); + $('input#phydev,label[for="phydev"]',$create_vn_dialog).show(); + break; + case "802.1Q": + $('input#bridge,label[for="bridge"]',$create_vn_dialog).show(); + $('input#phydev,label[for="phydev"]',$create_vn_dialog).show(); + $('select#vlan,label[for="vlan"]',$create_vn_dialog).show(); + $('input#vlan_id,label[for="vlan_id"]',$create_vn_dialog).show(); + break; + case "etables": + $('input#bridge,label[for="bridge"]',$create_vn_dialog).show(); + break; + case "openvswitch": + case "vmware": + $('input#bridge,label[for="bridge"]',$create_vn_dialog).show(); + $('select#vlan,label[for="vlan"]',$create_vn_dialog).show(); + $('input#vlan_id,label[for="vlan_id"]',$create_vn_dialog).show(); + break; + }; + }); + + //Initialize shown options + $('#network_mode',dialog).trigger("change"); + $('button',dialog).button(); @@ -786,12 +841,60 @@ function setupCreateVNetDialog() { notifyError(tr("Virtual Network name missing!")); return false; } - var bridge = $('#bridge',this).val(); - var type = $('input:checked',this).val(); + var network_json = {"name" : name}; + + var network_mode = $('select#network_mode',this).val(); + var bridge = $('#bridge',this).val(); + var phydev = $('#phydev',this).val(); + var vlan = $('#vlan',this).val(); + var vlan_id = $('#vlan_id',this).val(); + switch (network_mode) { + case "default": + if (!bridge && !phydev){ + notifyError("Bridge or physical device must be specified"); + return false; + }; + if (bridge) network_json['bridge']=bridge; + if (phydev) network_json['phydev']=phydev; + break; + case "802.1Q": + if (!phydev){ + notifyError("Physical device must be specified"); + return false; + }; + network_json['phydev']=phydev; + if (bridge) network_json['bridge']=bridge; + if (vlan_id) { + network_json['vlan']=vlan; + network_json['vlan_id']=vlan_id; + }; + break; + case "etables": + if (!bridge){ + notifyError("Bridge must be specified"); + return false; + }; + network_json['bridge']=bridge; + break; + case "openvswitch": + case "vmware": + if (!bridge){ + notifyError("Bridge must be specified"); + return false; + }; + network_json['bridge']=bridge; + if (vlan_id) { + network_json['vlan']=vlan; + network_json['vlan_id']=vlan_id; + }; + break; + }; + + var type = $('input:checked',this).val(); + network_json['type']=type; //TODO: Name and bridge provided?! - var network_json = null; if (type == "fixed") { var leases = $('#leases option', this); var leases_obj=[]; @@ -807,12 +910,7 @@ function setupCreateVNetDialog() { }); //and construct the final data for the request - network_json = { - "vnet" : { - "type" : "FIXED", - "leases" : leases_obj, - "bridge" : bridge, - "name" : name }}; + network_json["leases"] = leases_obj; } else { //type ranged @@ -827,25 +925,17 @@ function setupCreateVNetDialog() { return false; }; - //we form the object for the request - network_json = { - "vnet" : { - "type" : "RANGED", - "bridge" : bridge, - "name" : name } - }; - if (network_addr.length) - network_json["vnet"]["network_address"]=network_addr; + network_json["network_address"]=network_addr; if (network_mask.length) - network_json["vnet"]["network_mask"]=network_mask; + network_json["network_mask"]=network_mask; if (custom){ if (ip_start.length) - network_json["vnet"]["ip_start"] = ip_start; + network_json["ip_start"] = ip_start; if (ip_end.length) - network_json["vnet"]["ip_end"] = ip_end; + network_json["ip_end"] = ip_end; }; }; @@ -853,11 +943,13 @@ function setupCreateVNetDialog() { $('#custom_var_vnet_box option',$create_vn_dialog).each(function(){ var attr_name = $(this).attr('name'); var attr_value = $(this).val(); - network_json["vnet"][attr_name] = attr_value; + network_json[attr_name] = attr_value; }); //Create the VNetwork. + network_json = {"vnet" : network_json}; + Sunstone.runAction("Network.create",network_json); $create_vn_dialog.dialog('close'); return false; From 997df82202ca15285ab1386b459003076ee5a7b0 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Fri, 17 Feb 2012 13:34:56 +0100 Subject: [PATCH 05/12] Add instance_type request by ID to OCCI --- src/cloud/occi/lib/OCCIServer.rb | 56 +++++++++++++++++++++++++------ src/cloud/occi/lib/occi-server.rb | 5 +++ 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/cloud/occi/lib/OCCIServer.rb b/src/cloud/occi/lib/OCCIServer.rb index 1b38ca0807..193132c30b 100755 --- a/src/cloud/occi/lib/OCCIServer.rb +++ b/src/cloud/occi/lib/OCCIServer.rb @@ -40,7 +40,7 @@ require 'pp' # OpenNebula Engine ############################################################################## -COLLECTIONS = ["compute", "instance_type", "network", "storage"] +COLLECTIONS = ["compute", "instance_type", "network", "storage", "user"] # FLAG that will filter the elements retrieved from the Pools POOL_FILTER = Pool::INFO_ALL @@ -92,18 +92,36 @@ class OCCIServer < CloudServer return xml_resp, 200 end + + INSTANCE_TYPE = %q{ + + <%= name.to_s %> + <%= name.to_s %> + <% opts.each { |elem, value| + next if elem==:template + str = elem.to_s.upcase %> + <<%= str %>><%= value %>> + <% } %> + + } + def get_instance_types(request) xml_resp = "\n" - @config[:instance_types].each { |k, v| - xml_resp << "\t\n" - xml_resp << "\t\t#{k.to_s}\n" - v.each { |elem, value| - next if elem==:template - str = elem.to_s.upcase - xml_resp << "\t\t<#{str}>#{value}\n" - } - xml_resp << "\t\n" + @config[:instance_types].each { |name, opts| + if request.params['verbose'] + begin + occi_it = ERB.new(INSTANCE_TYPE) + occi_it = occi_it.result(binding) + rescue Exception => e + error = OpenNebula::Error.new(e.message) + return error, CloudServer::HTTP_ERROR_CODE[error.errno] + end + + xml_resp << occi_it.gsub(/\n\s*/,'') + else + xml_resp << "\t\n" + end } xml_resp << "" @@ -111,6 +129,24 @@ class OCCIServer < CloudServer return xml_resp, 200 end + def get_instance_type(request, params) + name = params[:id].to_sym + unless @config[:instance_types].keys.include?(name) + error = OpenNebula::Error.new("INSTANCE_TYPE #{name} not found") + return error, 404 + else + opts = @config[:instance_types][name] + begin + occi_it = ERB.new(INSTANCE_TYPE) + occi_it = occi_it.result(binding) + rescue Exception => e + error = OpenNebula::Error.new(e.message) + return error, CloudServer::HTTP_ERROR_CODE[error.errno] + end + + return occi_it.gsub(/\n\s*/,''), 200 + end + end # Gets the pool representation of COMPUTES # request:: _Hash_ hash containing the data of the request diff --git a/src/cloud/occi/lib/occi-server.rb b/src/cloud/occi/lib/occi-server.rb index 8bee03b296..10b814e5f2 100755 --- a/src/cloud/occi/lib/occi-server.rb +++ b/src/cloud/occi/lib/occi-server.rb @@ -305,6 +305,11 @@ get '/user/:id' do treat_response(result,rc) end +get '/instance_type/:id' do + result,rc = @occi_server.get_instance_type(request, params) + treat_response(result,rc) +end + ############################################## ## OCCI UI (Self-Service) ############################################## From f1e4e3815acd850219aece58021d171d22aa9b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 17 Feb 2012 19:44:46 +0100 Subject: [PATCH 06/12] Bug: DB default configuration value was not inserted in NebulaTemplate.cc --- src/nebula/NebulaTemplate.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index 4113db6921..83ad962b83 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -138,7 +138,7 @@ void OpenNebulaTemplate::set_conf_default() vvalue.insert(make_pair("BACKEND","sqlite")); vattribute = new VectorAttribute("DB",vvalue); - conf_default.insert(make_pair(attribute->name(),vattribute)); + conf_default.insert(make_pair(vattribute->name(),vattribute)); //VNC_BASE_PORT value = "5900"; From b177159a3c30e62383c63750ae04e49ab1f623ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 17 Feb 2012 19:56:35 +0100 Subject: [PATCH 07/12] Bug #1134: Remove double object creation in VirtualNetworkPool::allocate --- src/vnm/VirtualNetworkPool.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vnm/VirtualNetworkPool.cc b/src/vnm/VirtualNetworkPool.cc index 99f3ba47cc..47b05a2e47 100644 --- a/src/vnm/VirtualNetworkPool.cc +++ b/src/vnm/VirtualNetworkPool.cc @@ -108,8 +108,6 @@ int VirtualNetworkPool::allocate ( goto error_duplicated; } - vn = new VirtualNetwork(uid, gid, uname, gname, vn_template); - *oid = PoolSQL::allocate(vn, error_str); return *oid; From ae35b6115925dd5ebe647112dbca202d51a667a4 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Mon, 20 Feb 2012 12:31:34 +0100 Subject: [PATCH 08/12] Bump to 3.3.0 --- include/Nebula.h | 4 ++-- share/man/econe-describe-images.1 | 2 +- share/man/econe-describe-instances.1 | 2 +- share/man/econe-register.1 | 2 +- share/man/econe-run-instances.1 | 2 +- share/man/econe-terminate-instances.1 | 2 +- share/man/econe-upload.1 | 2 +- share/man/occi-compute.1 | 2 +- share/man/occi-network.1 | 2 +- share/man/occi-storage.1 | 2 +- share/man/oneacl.1 | 4 ++-- share/man/onedb.1 | 2 +- share/man/onegroup.1 | 4 ++-- share/man/onehost.1 | 4 ++-- share/man/oneimage.1 | 4 ++-- share/man/onetemplate.1 | 9 ++++++--- share/man/oneuser.1 | 4 ++-- share/man/onevdc.1 | 4 ++-- share/man/onevm.1 | 4 ++-- share/man/onevnet.1 | 4 ++-- share/man/onezone.1 | 6 +++--- src/cli/one_helper.rb | 2 +- src/cloud/common/CloudClient.rb | 2 +- src/cloud/occi/lib/ui/views/index.erb | 2 +- src/ozones/Server/templates/index.html | 2 +- src/sunstone/views/index.erb | 2 +- 26 files changed, 42 insertions(+), 39 deletions(-) diff --git a/include/Nebula.h b/include/Nebula.h index 876e405808..04e2c52743 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -228,12 +228,12 @@ public: static string version() { - return "OpenNebula 3.2.0"; + return "OpenNebula 3.3.0"; }; static string db_version() { - return "3.2.0"; + return "3.3.0"; } void start(); diff --git a/share/man/econe-describe-images.1 b/share/man/econe-describe-images.1 index 85a6de9f40..4360e7d8b8 100644 --- a/share/man/econe-describe-images.1 +++ b/share/man/econe-describe-images.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands" +.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands" .SH NAME OpenNebula \- OpenNebula econe-describe-images .SH SYNOPSIS diff --git a/share/man/econe-describe-instances.1 b/share/man/econe-describe-instances.1 index 78469d5f5d..5e0a490696 100644 --- a/share/man/econe-describe-instances.1 +++ b/share/man/econe-describe-instances.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands" +.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands" .SH NAME OpenNebula \- OpenNebula econe-describe-instances .SH SYNOPSIS diff --git a/share/man/econe-register.1 b/share/man/econe-register.1 index f7efb9b2cd..5a2efa12b1 100644 --- a/share/man/econe-register.1 +++ b/share/man/econe-register.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands" +.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands" .SH NAME OpenNebula \- OpenNebula econe-register .SH SYNOPSIS diff --git a/share/man/econe-run-instances.1 b/share/man/econe-run-instances.1 index 7cb4334c2a..b1b686439f 100644 --- a/share/man/econe-run-instances.1 +++ b/share/man/econe-run-instances.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands" +.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands" .SH NAME OpenNebula \- OpenNebula econe-run-instances .SH SYNOPSIS diff --git a/share/man/econe-terminate-instances.1 b/share/man/econe-terminate-instances.1 index e786c5242f..0bb112286f 100644 --- a/share/man/econe-terminate-instances.1 +++ b/share/man/econe-terminate-instances.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands" +.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands" .SH NAME OpenNebula \- OpenNebula econe-terminate-instances .SH SYNOPSIS diff --git a/share/man/econe-upload.1 b/share/man/econe-upload.1 index ab0be4908c..3b28a415d5 100644 --- a/share/man/econe-upload.1 +++ b/share/man/econe-upload.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH OPENNEBULA "1" "September 2011" "OpenNebula 3.2.0" "User Commands" +.TH OPENNEBULA "1" "September 2011" "OpenNebula 3.3.0" "User Commands" .SH NAME OpenNebula \- OpenNebula econe-upload .SH SYNOPSIS diff --git a/share/man/occi-compute.1 b/share/man/occi-compute.1 index 9eca8b5316..8da520ee83 100644 --- a/share/man/occi-compute.1 +++ b/share/man/occi-compute.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands" +.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands" .SH NAME OpenNebula \- OpenNebula occi-compute .SH SYNOPSIS diff --git a/share/man/occi-network.1 b/share/man/occi-network.1 index 297bf94595..ab3414993a 100644 --- a/share/man/occi-network.1 +++ b/share/man/occi-network.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands" +.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands" .SH NAME OpenNebula \- OpenNebula occi-network .SH SYNOPSIS diff --git a/share/man/occi-storage.1 b/share/man/occi-storage.1 index 947c3dc368..50f340f9ad 100644 --- a/share/man/occi-storage.1 +++ b/share/man/occi-storage.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands" +.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands" .SH NAME OpenNebula \- OpenNebula occi-storage .SH SYNOPSIS diff --git a/share/man/oneacl.1 b/share/man/oneacl.1 index 21ca23b16d..96215cf3b1 100644 --- a/share/man/oneacl.1 +++ b/share/man/oneacl.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ONEACL" "1" "January 2012" "" "oneacl(1) -- manages OpenNebula ACLs" +.TH "ONEACL" "1" "February 2012" "" "oneacl(1) -- manages OpenNebula ACLs" . .SH "NAME" \fBoneacl\fR @@ -128,7 +128,7 @@ Comma\-separated list of OpenNebula ACL names or ids .IP "" 0 . .SH "LICENSE" -OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) +OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) . .P 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 diff --git a/share/man/onedb.1 b/share/man/onedb.1 index 4f08b780c7..fc460471bd 100644 --- a/share/man/onedb.1 +++ b/share/man/onedb.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ONEDB" "1" "January 2012" "" "onedb(1) -- OpenNebula database migration tool" +.TH "ONEDB" "1" "February 2012" "" "onedb(1) -- OpenNebula database migration tool" . .SH "NAME" \fBonedb\fR diff --git a/share/man/onegroup.1 b/share/man/onegroup.1 index 8a91154cd8..a3c8f50f51 100644 --- a/share/man/onegroup.1 +++ b/share/man/onegroup.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ONEGROUP" "1" "January 2012" "" "onegroup(1) -- manages OpenNebula groups" +.TH "ONEGROUP" "1" "February 2012" "" "onegroup(1) -- manages OpenNebula groups" . .SH "NAME" \fBonegroup\fR @@ -160,7 +160,7 @@ Comma\-separated list of OpenNebula GROUP names or ids .IP "" 0 . .SH "LICENSE" -OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) +OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) . .P 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 diff --git a/share/man/onehost.1 b/share/man/onehost.1 index f658877e3b..f73815a8ee 100644 --- a/share/man/onehost.1 +++ b/share/man/onehost.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ONEHOST" "1" "January 2012" "" "onehost(1) -- manages OpenNebula hosts" +.TH "ONEHOST" "1" "February 2012" "" "onehost(1) -- manages OpenNebula hosts" . .SH "NAME" \fBonehost\fR @@ -234,7 +234,7 @@ Comma\-separated list of OpenNebula HOST names or ids .IP "" 0 . .SH "LICENSE" -OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) +OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) . .P 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 diff --git a/share/man/oneimage.1 b/share/man/oneimage.1 index a6812f38c1..e63e257858 100644 --- a/share/man/oneimage.1 +++ b/share/man/oneimage.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ONEIMAGE" "1" "January 2012" "" "oneimage(1) -- manages OpenNebula images" +.TH "ONEIMAGE" "1" "February 2012" "" "oneimage(1) -- manages OpenNebula images" . .SH "NAME" \fBoneimage\fR @@ -381,7 +381,7 @@ user IMAGE of the user identified by the username .IP "" 0 . .SH "LICENSE" -OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) +OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) . .P 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 diff --git a/share/man/onetemplate.1 b/share/man/onetemplate.1 index a1b14f1fe1..cca82c5d33 100644 --- a/share/man/onetemplate.1 +++ b/share/man/onetemplate.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ONETEMPLATE" "1" "January 2012" "" "onetemplate(1) -- manages OpenNebula templates" +.TH "ONETEMPLATE" "1" "February 2012" "" "onetemplate(1) -- manages OpenNebula templates" . .SH "NAME" \fBonetemplate\fR @@ -13,7 +13,10 @@ . .nf - \-n, \-\-name vm_name Name of the new Virtual Machine + \-n, \-\-name vm_name Name of the new Virtual Machine\. When instantiating + multiple VMs you can use the"%i" wildcard to produce + different names such as vm\-0, vm\-1\.\.\. + \-m, \-\-multiple x Instance multiple VMs \-l, \-\-list x,y,z Selects columns to display with list command \-d, \-\-delay x Sets the delay in seconds for top command @@ -327,7 +330,7 @@ user VMTEMPLATE of the user identified by the username .IP "" 0 . .SH "LICENSE" -OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) +OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) . .P 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 diff --git a/share/man/oneuser.1 b/share/man/oneuser.1 index f375d552b3..12fb7016b8 100644 --- a/share/man/oneuser.1 +++ b/share/man/oneuser.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ONEUSER" "1" "January 2012" "" "oneuser(1) -- manages OpenNebula users" +.TH "ONEUSER" "1" "February 2012" "" "oneuser(1) -- manages OpenNebula users" . .SH "NAME" \fBoneuser\fR @@ -305,7 +305,7 @@ User password .IP "" 0 . .SH "LICENSE" -OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) +OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) . .P 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 diff --git a/share/man/onevdc.1 b/share/man/onevdc.1 index d52b547d16..acfe8524f9 100644 --- a/share/man/onevdc.1 +++ b/share/man/onevdc.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ONEVDC" "1" "January 2012" "" "onevdc(1) -- manages OpenNebula Virtual DataCenters" +.TH "ONEVDC" "1" "February 2012" "" "onevdc(1) -- manages OpenNebula Virtual DataCenters" . .SH "NAME" \fBonevdc\fR @@ -171,7 +171,7 @@ VDC ID .IP "" 0 . .SH "LICENSE" -OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) +OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) . .P 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 diff --git a/share/man/onevm.1 b/share/man/onevm.1 index 3f603fe6ae..3798929421 100644 --- a/share/man/onevm.1 +++ b/share/man/onevm.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ONEVM" "1" "January 2012" "" "onevm(1) -- manages OpenNebula virtual machines" +.TH "ONEVM" "1" "February 2012" "" "onevm(1) -- manages OpenNebula virtual machines" . .SH "NAME" \fBonevm\fR @@ -526,7 +526,7 @@ user VM of the user identified by the username .IP "" 0 . .SH "LICENSE" -OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) +OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) . .P 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 diff --git a/share/man/onevnet.1 b/share/man/onevnet.1 index 99b7a5834b..3e155b169f 100644 --- a/share/man/onevnet.1 +++ b/share/man/onevnet.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ONEVNET" "1" "January 2012" "" "onevnet(1) -- manages OpenNebula networks" +.TH "ONEVNET" "1" "February 2012" "" "onevnet(1) -- manages OpenNebula networks" . .SH "NAME" \fBonevnet\fR @@ -351,7 +351,7 @@ user VNET of the user identified by the username .IP "" 0 . .SH "LICENSE" -OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) +OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) . .P 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 diff --git a/share/man/onezone.1 b/share/man/onezone.1 index d55d4a72e8..ebcfe58c9c 100644 --- a/share/man/onezone.1 +++ b/share/man/onezone.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ONEZONE" "1" "January 2012" "" "onezone(1) -- manages OpenNebula zones" +.TH "ONEZONE" "1" "February 2012" "" "onezone(1) -- manages OpenNebula zones" . .SH "NAME" \fBonezone\fR @@ -43,7 +43,7 @@ show \fIzoneid\fR [\fIresource\fR] .nf Show information of a particular Zone -Available resources: host, vm, image, vn, template, user +Available resources: host, vm, image, vnet, vmtemplate, user Examples: onezone show 4 onezone show 4 host @@ -144,7 +144,7 @@ Zone ID .IP "" 0 . .SH "LICENSE" -OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) +OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org) . .P 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 diff --git a/src/cli/one_helper.rb b/src/cli/one_helper.rb index dc81700cb6..dcb3067ff5 100644 --- a/src/cli/one_helper.rb +++ b/src/cli/one_helper.rb @@ -21,7 +21,7 @@ include OpenNebula module OpenNebulaHelper ONE_VERSION=<<-EOT -OpenNebula 3.2.0 +OpenNebula 3.3.0 Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) Licensed under the Apache License, Version 2.0 (the "License"); you may diff --git a/src/cloud/common/CloudClient.rb b/src/cloud/common/CloudClient.rb index 605b211323..a6006b66dd 100644 --- a/src/cloud/common/CloudClient.rb +++ b/src/cloud/common/CloudClient.rb @@ -181,7 +181,7 @@ module CloudCLI def version_text version=< diff --git a/src/ozones/Server/templates/index.html b/src/ozones/Server/templates/index.html index 26a70fd9f1..f6d034a4cf 100644 --- a/src/ozones/Server/templates/index.html +++ b/src/ozones/Server/templates/index.html @@ -60,7 +60,7 @@
diff --git a/src/sunstone/views/index.erb b/src/sunstone/views/index.erb index 85bfa4bc12..45f277b48c 100644 --- a/src/sunstone/views/index.erb +++ b/src/sunstone/views/index.erb @@ -76,7 +76,7 @@ From b70b8e2dbe2547e93b1efb67894b1a894637043d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 21 Feb 2012 01:31:50 -0800 Subject: [PATCH 09/12] Bug #1128: Remove deprecated method from Java OCA (cherry picked from commit 3e21d79a2215846b758640b45fd4a3794d7147f6) --- .../opennebula/client/vm/VirtualMachine.java | 50 ------------------- src/oca/java/test/TemplateTest.java | 11 ---- 2 files changed, 61 deletions(-) diff --git a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java index 98b6554ad7..8775559812 100644 --- a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java +++ b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java @@ -137,56 +137,6 @@ public class VirtualMachine extends PoolElement{ return client.call(ALLOCATE, description); } - /** - * Allocates a new VM in OpenNebula from a registered Template. - * - * @param client XML-RPC Client. - * @param templateId The source Template's ID - * @param newName Name for the new VM, replaces the Template's one. - * Can be null. - * @return If successful the message contains the associated - * id generated for this VM. - */ - public static OneResponse allocateFromTemplate(Client client, - int templateId, String newName) - { - String template = "TEMPLATE_ID = " + templateId; - if( newName != null ) - { - template += "\nNAME = " + newName; - } - - return allocate(client, template); - } - - /** - * Allocates a new VM in OpenNebula from a registered Template. - * - * @param client XML-RPC Client. - * @param templateId The source Template's ID - * @return If successful the message contains the associated - * id generated for this VM. - */ - public static OneResponse allocateFromTemplate(Client client, - int templateId) - { - return allocateFromTemplate(client, templateId, null); - } - - /** - * Allocates a new VM in OpenNebula from a registered Template. - * - * @param client XML-RPC Client. - * @param template The source Template. - * @return If successful the message contains the associated - * id generated for this VM. - */ - public static OneResponse allocateFromTemplate(Client client, - Template template) - { - return allocateFromTemplate(client, template.id()); - } - /** * Retrieves the information of the given VM. * diff --git a/src/oca/java/test/TemplateTest.java b/src/oca/java/test/TemplateTest.java index d8c9f0ee43..f36204dc71 100644 --- a/src/oca/java/test/TemplateTest.java +++ b/src/oca/java/test/TemplateTest.java @@ -247,17 +247,6 @@ public class TemplateTest assertTrue( res.isError() ); } - @Test - public void allocateFromTemplate() - { - res = template.info(); - assertTrue( !res.isError() ); - - res = VirtualMachine.allocateFromTemplate(client, template); - assertTrue( !res.isError() ); - assertTrue( res.getMessage().equals("0") ); - } - @Test public void chown() { From 66e314c021a2b2ebb7da5c7a6c78947adeec9ea7 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Wed, 22 Feb 2012 17:15:13 +0100 Subject: [PATCH 10/12] Sort OCCI collections and instance_types --- src/cloud/occi/lib/OCCIServer.rb | 44 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/cloud/occi/lib/OCCIServer.rb b/src/cloud/occi/lib/OCCIServer.rb index 193132c30b..b05bf6ab43 100755 --- a/src/cloud/occi/lib/OCCIServer.rb +++ b/src/cloud/occi/lib/OCCIServer.rb @@ -81,10 +81,10 @@ class OCCIServer < CloudServer ############################################################################ def get_collections(request) - xml_resp = "\n" + xml_resp = "" - COLLECTIONS.each { |c| - xml_resp << "\t<#{c.upcase}_COLLECTION href=\"#{@base_url}/#{c}\">\n" + COLLECTIONS.sort.each { |c| + xml_resp << "<#{c.upcase}_COLLECTION href=\"#{@base_url}/#{c}\"/>" } xml_resp << "" @@ -97,7 +97,7 @@ class OCCIServer < CloudServer <%= name.to_s %> <%= name.to_s %> - <% opts.each { |elem, value| + <% opts.sort{|k1,k2| k1[0].to_s<=>k2[0].to_s}.each { |elem, value| next if elem==:template str = elem.to_s.upcase %> <<%= str %>><%= value %>> @@ -106,9 +106,11 @@ class OCCIServer < CloudServer } def get_instance_types(request) - xml_resp = "\n" + xml_resp = "" - @config[:instance_types].each { |name, opts| + @config[:instance_types].sort { |k1,k2| + k1[0].to_s<=>k2[0].to_s + }.each { |name, opts| if request.params['verbose'] begin occi_it = ERB.new(INSTANCE_TYPE) @@ -120,7 +122,7 @@ class OCCIServer < CloudServer xml_resp << occi_it.gsub(/\n\s*/,'') else - xml_resp << "\t\n" + xml_resp << "" end } @@ -163,7 +165,7 @@ class OCCIServer < CloudServer return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end - return to_occi_xml(vmpool, :status=>200, :verbose=>request.params['verbose']) + return to_occi_xml(vmpool, :code=>200, :verbose=>request.params['verbose']) end @@ -183,7 +185,7 @@ class OCCIServer < CloudServer return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end - return to_occi_xml(network_pool, :status=>200, :verbose=>request.params['verbose']) + return to_occi_xml(network_pool, :code=>200, :verbose=>request.params['verbose']) end # Gets the pool representation of STORAGES @@ -202,7 +204,7 @@ class OCCIServer < CloudServer return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end - return to_occi_xml(image_pool, :status=>200, :verbose=>request.params['verbose']) + return to_occi_xml(image_pool, :code=>200, :verbose=>request.params['verbose']) end # Gets the pool representation of USERs @@ -219,7 +221,7 @@ class OCCIServer < CloudServer return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end - return to_occi_xml(user_pool, :status=>200, :verbose=>request.params['verbose']) + return to_occi_xml(user_pool, :code=>200, :verbose=>request.params['verbose']) end ############################################################################ @@ -255,7 +257,7 @@ class OCCIServer < CloudServer # --- Prepare XML Response --- vm.info - return to_occi_xml(vm, :status=>201) + return to_occi_xml(vm, :code=>201) end # Get the representation of a COMPUTE resource @@ -274,7 +276,7 @@ class OCCIServer < CloudServer return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end - return to_occi_xml(vm, :status=>200) + return to_occi_xml(vm, :code=>200) end # Deletes a COMPUTE resource @@ -317,7 +319,7 @@ class OCCIServer < CloudServer return result, code else vm.info - return to_occi_xml(vm, :status=>code) + return to_occi_xml(vm, :code=>code) end end @@ -347,7 +349,7 @@ class OCCIServer < CloudServer # --- Prepare XML Response --- network.info - return to_occi_xml(network, :status=>201) + return to_occi_xml(network, :code=>201) end # Retrieves a NETWORK resource @@ -365,7 +367,7 @@ class OCCIServer < CloudServer return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end - return to_occi_xml(network, :status=>200) + return to_occi_xml(network, :code=>200) end # Deletes a NETWORK resource @@ -411,7 +413,7 @@ class OCCIServer < CloudServer # --- Prepare XML Response --- vnet.info - return to_occi_xml(vnet, :status=>202) + return to_occi_xml(vnet, :code=>202) end ############################################################################ @@ -457,7 +459,7 @@ class OCCIServer < CloudServer end # --- Prepare XML Response --- - return to_occi_xml(image, :status=>201) + return to_occi_xml(image, :code=>201) end # Get a STORAGE resource @@ -476,7 +478,7 @@ class OCCIServer < CloudServer end # --- Prepare XML Response --- - return to_occi_xml(image, :status=>200) + return to_occi_xml(image, :code=>200) end # Deletes a STORAGE resource (Not yet implemented) @@ -530,7 +532,7 @@ class OCCIServer < CloudServer # --- Prepare XML Response --- image.info - return to_occi_xml(image, :status=>202) + return to_occi_xml(image, :code=>202) end # Get the representation of a USER @@ -549,7 +551,7 @@ class OCCIServer < CloudServer return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end - return to_occi_xml(user, :status=>200) + return to_occi_xml(user, :code=>200) end ############################################################################ From e97040d3e5b68be31c220661a7e33bf204ae3916 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Wed, 22 Feb 2012 17:16:39 +0100 Subject: [PATCH 11/12] Add more OCCI tests --- .../occi/test/fixtures/compute/empty.xml | 1 + .../test/fixtures/compute/first_compute.xml | 20 ++ .../fixtures/compute/first_compute_done.xml | 20 ++ .../test/fixtures/compute/second_compute.xml | 20 ++ .../fixtures/compute/second_compute_done.xml | 20 ++ .../test/fixtures/instance_type/extended.xml | 20 ++ .../occi/test/fixtures/instance_type/list.xml | 5 + .../occi/test/fixtures/network/empty.xml | 1 + .../occi/test/fixtures/network/first_net.xml | 11 + .../occi/test/fixtures/network/second_net.xml | 11 + src/cloud/occi/test/fixtures/root.xml | 7 + .../occi/test/fixtures/storage/empty.xml | 1 + .../test/fixtures/storage/first_storage.xml | 13 + .../test/fixtures/storage/second_storage.xml | 13 + src/cloud/occi/test/spec/occi_spec.rb | 283 ++++++++++++++++++ src/cloud/occi/test/spec/spec.opts | 4 + src/cloud/occi/test/spec/spec_helper.rb | 152 ++++++++++ 17 files changed, 602 insertions(+) create mode 100644 src/cloud/occi/test/fixtures/compute/empty.xml create mode 100644 src/cloud/occi/test/fixtures/compute/first_compute.xml create mode 100644 src/cloud/occi/test/fixtures/compute/first_compute_done.xml create mode 100644 src/cloud/occi/test/fixtures/compute/second_compute.xml create mode 100644 src/cloud/occi/test/fixtures/compute/second_compute_done.xml create mode 100644 src/cloud/occi/test/fixtures/instance_type/extended.xml create mode 100644 src/cloud/occi/test/fixtures/instance_type/list.xml create mode 100644 src/cloud/occi/test/fixtures/network/empty.xml create mode 100644 src/cloud/occi/test/fixtures/network/first_net.xml create mode 100644 src/cloud/occi/test/fixtures/network/second_net.xml create mode 100644 src/cloud/occi/test/fixtures/root.xml create mode 100644 src/cloud/occi/test/fixtures/storage/empty.xml create mode 100644 src/cloud/occi/test/fixtures/storage/first_storage.xml create mode 100644 src/cloud/occi/test/fixtures/storage/second_storage.xml create mode 100644 src/cloud/occi/test/spec/occi_spec.rb create mode 100644 src/cloud/occi/test/spec/spec.opts diff --git a/src/cloud/occi/test/fixtures/compute/empty.xml b/src/cloud/occi/test/fixtures/compute/empty.xml new file mode 100644 index 0000000000..17ef393d05 --- /dev/null +++ b/src/cloud/occi/test/fixtures/compute/empty.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/cloud/occi/test/fixtures/compute/first_compute.xml b/src/cloud/occi/test/fixtures/compute/first_compute.xml new file mode 100644 index 0000000000..4824a2b00e --- /dev/null +++ b/src/cloud/occi/test/fixtures/compute/first_compute.xml @@ -0,0 +1,20 @@ + + 0 + + oneadmin + 1 + 1024 + Compute + small + PENDING + + + DISK + hde + + + + 192.168.1.1 + 02:00:c0:a8:01:01 + + diff --git a/src/cloud/occi/test/fixtures/compute/first_compute_done.xml b/src/cloud/occi/test/fixtures/compute/first_compute_done.xml new file mode 100644 index 0000000000..46bd2c8352 --- /dev/null +++ b/src/cloud/occi/test/fixtures/compute/first_compute_done.xml @@ -0,0 +1,20 @@ + + 0 + + oneadmin + 1 + 1024 + Compute + small + DONE + + + DISK + hde + + + + 192.168.1.1 + 02:00:c0:a8:01:01 + + diff --git a/src/cloud/occi/test/fixtures/compute/second_compute.xml b/src/cloud/occi/test/fixtures/compute/second_compute.xml new file mode 100644 index 0000000000..ee057ed43e --- /dev/null +++ b/src/cloud/occi/test/fixtures/compute/second_compute.xml @@ -0,0 +1,20 @@ + + 1 + + users + 1 + 1024 + Compute2 + small + PENDING + + + DISK + hde + + + + 192.168.2.1 + 02:00:c0:a8:02:01 + + diff --git a/src/cloud/occi/test/fixtures/compute/second_compute_done.xml b/src/cloud/occi/test/fixtures/compute/second_compute_done.xml new file mode 100644 index 0000000000..e73c28ba3b --- /dev/null +++ b/src/cloud/occi/test/fixtures/compute/second_compute_done.xml @@ -0,0 +1,20 @@ + + 1 + + users + 1 + 1024 + Compute2 + small + DONE + + + DISK + hde + + + + 192.168.2.1 + 02:00:c0:a8:02:01 + + diff --git a/src/cloud/occi/test/fixtures/instance_type/extended.xml b/src/cloud/occi/test/fixtures/instance_type/extended.xml new file mode 100644 index 0000000000..f774763320 --- /dev/null +++ b/src/cloud/occi/test/fixtures/instance_type/extended.xml @@ -0,0 +1,20 @@ + + + large + large + 8 + 8192 + + + medium + medium + 4 + 4096 + + + small + small + 1 + 1024 + + diff --git a/src/cloud/occi/test/fixtures/instance_type/list.xml b/src/cloud/occi/test/fixtures/instance_type/list.xml new file mode 100644 index 0000000000..135ae70491 --- /dev/null +++ b/src/cloud/occi/test/fixtures/instance_type/list.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/cloud/occi/test/fixtures/network/empty.xml b/src/cloud/occi/test/fixtures/network/empty.xml new file mode 100644 index 0000000000..c96d82e6ed --- /dev/null +++ b/src/cloud/occi/test/fixtures/network/empty.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/cloud/occi/test/fixtures/network/first_net.xml b/src/cloud/occi/test/fixtures/network/first_net.xml new file mode 100644 index 0000000000..24b388783d --- /dev/null +++ b/src/cloud/occi/test/fixtures/network/first_net.xml @@ -0,0 +1,11 @@ + + 0 + Network + + oneadmin + Network of the user my_first_occi_user +
192.168.1.1
+ 125 + 0 + NO +
diff --git a/src/cloud/occi/test/fixtures/network/second_net.xml b/src/cloud/occi/test/fixtures/network/second_net.xml new file mode 100644 index 0000000000..9cad2d9594 --- /dev/null +++ b/src/cloud/occi/test/fixtures/network/second_net.xml @@ -0,0 +1,11 @@ + + 1 + Network2 + + users + Network of the user my_second_occi_user +
192.168.2.1
+ 125 + 0 + NO +
diff --git a/src/cloud/occi/test/fixtures/root.xml b/src/cloud/occi/test/fixtures/root.xml new file mode 100644 index 0000000000..38843f0418 --- /dev/null +++ b/src/cloud/occi/test/fixtures/root.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/cloud/occi/test/fixtures/storage/empty.xml b/src/cloud/occi/test/fixtures/storage/empty.xml new file mode 100644 index 0000000000..622d314777 --- /dev/null +++ b/src/cloud/occi/test/fixtures/storage/empty.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/cloud/occi/test/fixtures/storage/first_storage.xml b/src/cloud/occi/test/fixtures/storage/first_storage.xml new file mode 100644 index 0000000000..c24bea57ae --- /dev/null +++ b/src/cloud/occi/test/fixtures/storage/first_storage.xml @@ -0,0 +1,13 @@ + + 0 + Storage + + oneadmin + READY + DATABLOCK + Storage of the user my_first_occi_user + 100 + ext3 + NO + NO + diff --git a/src/cloud/occi/test/fixtures/storage/second_storage.xml b/src/cloud/occi/test/fixtures/storage/second_storage.xml new file mode 100644 index 0000000000..defd5b1a56 --- /dev/null +++ b/src/cloud/occi/test/fixtures/storage/second_storage.xml @@ -0,0 +1,13 @@ + + 1 + Storage2 + + users + READY + DATABLOCK + Storage of the user my_second_occi_user + 100 + ext3 + NO + NO + diff --git a/src/cloud/occi/test/spec/occi_spec.rb b/src/cloud/occi/test/spec/occi_spec.rb new file mode 100644 index 0000000000..ba35ae94dd --- /dev/null +++ b/src/cloud/occi/test/spec/occi_spec.rb @@ -0,0 +1,283 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, 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 File.expand_path(File.dirname(__FILE__) + '/spec_helper') + +# The following methods are helpers defined in spec_helper +# - compare_xml +# - get_fixture +# - network_template +# - storage_template +# - compute_template + +describe 'OCCI tests' do + before(:all) do + @user_oneadmin = "my_first_occi_user" + `oneuser create #{@user_oneadmin} my_pass`.scan(/^ID: (\d+)/) { |uid| + `oneuser show #{uid.first}`.scan(/PASSWORD\s*:\s*(\w*)/) { |password| + @user_pass = password.first.strip + } + + `oneuser chgrp #{uid.first} 0` + } + + @user_users = "my_second_occi_user" + `oneuser create #{@user_users} my_pass2`.scan(/^ID: (\d+)/) { |uid| + `oneuser show #{uid.first}`.scan(/PASSWORD\s*:\s*(\w*)/) { |password| + @user_pass2 = password.first.strip + } + } + + # Define BRIDGE attirbute in network.erb, otherwise the NETWORK creation will + `sed -i.bck "s%^#\\(BRIDGE = \\).*$%\\1 br0%" $ONE_LOCATION/etc/occi_templates/network.erb` + end + + describe "with a user of the oneadmin group" do + before(:each) do + basic_authorize(@user_oneadmin, @user_pass) + end + + it "should retrieve the list of collections" do + get '/' + compare_xml(last_response.body, get_fixture('/root.xml')) + last_response.status.should == 200 + end + + it "should retrieve the list of INSTANCE_TYPEs" do + get '/instance_type' + compare_xml(last_response.body, get_fixture('/instance_type/list.xml')) + last_response.status.should == 200 + end + + it "should retrieve the extended list of INSTANCE_TYPEs" do + get '/instance_type', {'verbose'=>true} + compare_xml(last_response.body, get_fixture('/instance_type/extended.xml')) + last_response.status.should == 200 + end + + context "for NETWORK" do + it "should retrieve the empty list" do + get '/network' + compare_xml(last_response.body, get_fixture('/network/empty.xml')) + last_response.status.should == 200 + end + + it "should create a new NETWORK" do + network = { + :name => "Network", + :description => "Network of the user #{@user_oneadmin}", + :address => "192.168.1.0", + :size => "100", + :pubic => "YES" + } + + post '/network', network_template(network) + compare_xml(last_response.body, get_fixture('/network/first_net.xml')) + last_response.status.should == 201 + end + + it "should retrieve the NETWORK with ID 0" do + get '/network/0' + compare_xml(last_response.body, get_fixture('/network/first_net.xml')) + last_response.status.should == 200 + end + end + + context "for STORAGE" do + it "should retrieve the empty list" do + get '/storage' + compare_xml(last_response.body, get_fixture('/storage/empty.xml')) + last_response.status.should == 200 + end + + it "should create a new STORAGE, type DATABLOCK. This request waits until the IMAGE is ready in OpenNebula" do + storage = { + :name => "Storage", + :description => "Storage of the user #{@user_oneadmin}", + :type => "DATABLOCK", + :size => "100", + :fstype => "ext3" + } + + post '/storage', {'occixml' => storage_template(storage)} + compare_xml(last_response.body, get_fixture('/storage/first_storage.xml')) + last_response.status.should == 201 + end + + it "should retrieve the STORAGE with ID 0" do + get '/storage/0' + compare_xml(last_response.body, get_fixture('/storage/first_storage.xml')) + last_response.status.should == 200 + end + end + + context "for COMPUTE" do + it "should retrieve the empty list" do + get '/compute' + compare_xml(last_response.body, get_fixture('/compute/empty.xml')) + last_response.status.should == 200 + end + + it "should create a new COMPUTE using the previous NETWORK (ID=0) and STORAGE(ID=0)" do + compute = { + :name => "Compute", + :instance_type => "small", + :disk => [ {:storage => '0'} ], + :nic => [ {:network => '0'} ] + } + + post '/compute', compute_template(compute) + compare_xml(last_response.body, get_fixture('/compute/first_compute.xml')) + last_response.status.should == 201 + end + + it "should retrieve the COMPUTE with ID 0" do + get '/compute/0' + compare_xml(last_response.body, get_fixture('/compute/first_compute.xml')) + last_response.status.should == 200 + end + + it "should terminate (DONE) the COMPUTE with ID 0" do + compute = { + :id => "0", + :state => "DONE" + } + + put '/compute/0', compute_action(compute) + compare_xml(last_response.body, get_fixture('/compute/first_compute_done.xml')) + last_response.status.should == 202 + end + end + end + + describe "with a user of the users group" do + before(:each) do + basic_authorize(@user_users, @user_pass2) + end + + it "should retrieve the list of collections" do + get '/' + compare_xml(last_response.body, get_fixture('/root.xml')) + last_response.status.should == 200 + end + + it "should retrieve the list of INSTANCE_TYPEs" do + get '/instance_type' + compare_xml(last_response.body, get_fixture('/instance_type/list.xml')) + last_response.status.should == 200 + end + + it "should retrieve the extended list of INSTANCE_TYPEs" do + get '/instance_type', {'verbose'=>true} + compare_xml(last_response.body, get_fixture('/instance_type/extended.xml')) + last_response.status.should == 200 + end + + context "for NETWORK" do + it "should retrieve the empty list" do + get '/network' + compare_xml(last_response.body, get_fixture('/network/empty.xml')) + last_response.status.should == 200 + end + + it "should create a new NETWORK" do + network = { + :name => "Network2", + :description => "Network of the user #{@user_users}", + :address => "192.168.2.0", + :size => "100", + :pubic => "YES" + } + + post '/network', network_template(network) + compare_xml(last_response.body, get_fixture('/network/second_net.xml')) + last_response.status.should == 201 + end + + it "should retrieve the NETWORK with ID 1" do + get '/network/1' + compare_xml(last_response.body, get_fixture('/network/second_net.xml')) + last_response.status.should == 200 + end + end + + context "for STORAGE" do + it "should retrieve the empty list" do + get '/storage' + compare_xml(last_response.body, get_fixture('/storage/empty.xml')) + last_response.status.should == 200 + end + + it "should create a new STORAGE, type DATABLOCK. This request waits until the IMAGE is ready in OpenNebula" do + storage = { + :name => "Storage2", + :description => "Storage of the user #{@user_users}", + :type => "DATABLOCK", + :size => "100", + :fstype => "ext3" + } + + post '/storage', {'occixml' => storage_template(storage)} + compare_xml(last_response.body, get_fixture('/storage/second_storage.xml')) + last_response.status.should == 201 + end + + it "should retrieve the STORAGE with ID 1" do + get '/storage/1' + compare_xml(last_response.body, get_fixture('/storage/second_storage.xml')) + last_response.status.should == 200 + end + end + + context "for COMPUTE" do + it "should retrieve the empty list" do + get '/compute' + compare_xml(last_response.body, get_fixture('/compute/empty.xml')) + last_response.status.should == 200 + end + + it "should create a new COMPUTE using the previous NETWORK (ID=1) and STORAGE(ID=1)" do + compute = { + :name => "Compute2", + :instance_type => "small", + :disk => [ {:storage => '1'} ], + :nic => [ {:network => '1'} ] + } + + post '/compute', compute_template(compute) + compare_xml(last_response.body, get_fixture('/compute/second_compute.xml')) + last_response.status.should == 201 + end + + it "should retrieve the COMPUTE with ID 1" do + get '/compute/1' + compare_xml(last_response.body, get_fixture('/compute/second_compute.xml')) + last_response.status.should == 200 + end + + it "should terminate (DONE) the COMPUTE with ID 1" do + compute = { + :id => "1", + :state => "DONE" + } + + put '/compute/1', compute_action(compute) + compare_xml(last_response.body, get_fixture('/compute/second_compute_done.xml')) + last_response.status.should == 202 + end + end + end +end \ No newline at end of file diff --git a/src/cloud/occi/test/spec/spec.opts b/src/cloud/occi/test/spec/spec.opts new file mode 100644 index 0000000000..ad561bd258 --- /dev/null +++ b/src/cloud/occi/test/spec/spec.opts @@ -0,0 +1,4 @@ +--colour +--format progress +--loadby mtime +--reverse \ No newline at end of file diff --git a/src/cloud/occi/test/spec/spec_helper.rb b/src/cloud/occi/test/spec/spec_helper.rb index b2a2917a97..0d7423a2fc 100644 --- a/src/cloud/occi/test/spec/spec_helper.rb +++ b/src/cloud/occi/test/spec/spec_helper.rb @@ -24,6 +24,8 @@ require 'rubygems' require 'rspec' require 'rack/test' +require 'rexml/document' + # Load the Sinatra app require 'occi-server' @@ -39,3 +41,153 @@ set :environment, :test def app Sinatra::Application end + + + +def get_fixture(path) + File.read(FIXTURES_PATH + path).strip +end + + +def compare_xml(a, b) + a = REXML::Document.new(a.to_s) + b = REXML::Document.new(b.to_s) + + normalized = Class.new(REXML::Formatters::Pretty) do + def write_text(node, output) + super(node.to_s.strip, output) + end + end + + normalized.new(indentation=0,ie_hack=false).write(node=a, a_normalized='') + normalized.new(indentation=0,ie_hack=false).write(node=b, b_normalized='') + + a_normalized.should == b_normalized +end + + +OCCI_NETWORK = %q{ + + <% if hash[:name] %> + <%= hash[:name] %> + <% end %> + + <% if hash[:description] %> + <%= hash[:description] %> + <% end %> + + <% if hash[:address] %> +
<%= hash[:address] %>
+ <% end %> + + <% if hash[:size] %> + <%= hash[:size] %> + <% end %> + + <% if hash[:public] %> + <%= hash[:public] %> + <% end %> +
+} + +def network_template(hash) + ERB.new(OCCI_NETWORK).result(binding) +end + +OCCI_IMAGE = %q{ + + <% if hash[:name] %> + <%= hash[:name] %> + <% end %> + + <% if hash[:type] %> + <%= hash[:type] %> + <% end %> + + <% if hash[:description] %> + <%= hash[:description] %> + <% end %> + + <% if hash[:size] %> + <%= hash[:size] %> + <% end %> + + <% if hash[:fstype] %> + <%= hash[:fstype] %> + <% end %> + + <% if hash[:public] %> + <%= hash[:public] %> + <% end %> + + <% if hash[:persistent] %> + <%= hash[:persistent] %> + <% end %> + +} + +def storage_template(hash) + ERB.new(OCCI_IMAGE).result(binding) +end + +OCCI_VM = %q{ + + <% if hash[:name] %> + <%= hash[:name] %> + <% end %> + + <% if hash[:instance_type] %> + + <% end %> + + <% if hash[:disk] %> + <% hash[:disk].each { |disk| %> + + <% if disk[:storage] %> + + <% end %> + + <% } %> + <% end %> + + <% if hash[:nic] %> + <% hash[:nic].each { |nic| %> + + <% if nic[:network] %> + + <% end %> + <% if nic[:ip] %> + <%= nic[:ip] %> + <% end %> + + <% } %> + <% end %> + + <% if hash[:context] %> + + <% hash[:context].each { |key, value| %> + <<%= key.to_s.upcase %>><%= value %>> + <% } %> + + <% end %> + +} + +OCCI_VM_ACTION = %q{ + + <% if hash[:id] %> + <%= hash[:id] %> + <% end %> + <% if hash[:state] %> + <%= hash[:state] %> + <% end %> + +} + +def compute_template(hash) + ERB.new(OCCI_VM).result(binding) +end + +def compute_action(hash) + ERB.new(OCCI_VM_ACTION).result(binding) +end From f3eaf649ef833e3e214e61a0de105e4308e019a4 Mon Sep 17 00:00:00 2001 From: Tino Vazquez Date: Tue, 28 Feb 2012 12:47:20 +0100 Subject: [PATCH 12/12] Fix bad variable returning - VMware --- src/im_mad/remotes/vmware.d/vmware.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/im_mad/remotes/vmware.d/vmware.rb b/src/im_mad/remotes/vmware.d/vmware.rb index b4c061656c..ea6920571e 100755 --- a/src/im_mad/remotes/vmware.d/vmware.rb +++ b/src/im_mad/remotes/vmware.d/vmware.rb @@ -106,7 +106,7 @@ conf = YAML::load(File.read(CONF_FILE)) rc, data = do_action("virsh -c #{@uri} --readonly nodeinfo") if rc == false - exit info + exit data end data.split(/\n/).each{|line|