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=<\n" + COLLECTIONS.sort.each { |c| + xml_resp << "<#{c.upcase}_COLLECTION href=\"#{@base_url}/#{c}\"/>" } xml_resp << "" @@ -92,18 +92,38 @@ class OCCIServer < CloudServer return xml_resp, 200 end - 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" + INSTANCE_TYPE = %q{ + + <%= name.to_s %> + <%= name.to_s %> + <% 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 %>> + <% } %> + + } + + def get_instance_types(request) + xml_resp = "" + + @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) + 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 << "" + end } xml_resp << "" @@ -111,6 +131,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 @@ -127,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 @@ -147,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 @@ -166,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 @@ -183,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 ############################################################################ @@ -219,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 @@ -238,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 @@ -281,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 @@ -311,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 @@ -329,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 @@ -375,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 ############################################################################ @@ -421,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 @@ -440,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) @@ -494,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 @@ -513,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 ############################################################################ 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) ############################################## diff --git a/src/cloud/occi/lib/ui/views/index.erb b/src/cloud/occi/lib/ui/views/index.erb index fffd276a10..90278f85bc 100644 --- a/src/cloud/occi/lib/ui/views/index.erb +++ b/src/cloud/occi/lib/ui/views/index.erb @@ -75,7 +75,7 @@ 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 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| 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"; 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() { 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/models/SunstoneServer.rb b/src/sunstone/models/SunstoneServer.rb index 5829b95c4d..dbc21f9a3f 100644 --- a/src/sunstone/models/SunstoneServer.rb +++ b/src/sunstone/models/SunstoneServer.rb @@ -231,7 +231,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 @@ -242,13 +242,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 156c302248..2e09422136 100755 --- a/src/sunstone/sunstone-server.rb +++ b/src/sunstone/sunstone-server.rb @@ -269,7 +269,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 @@ -277,7 +278,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 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 @@ diff --git a/src/vmm_mad/ec2/one_vmm_ec2.rb b/src/vmm_mad/ec2/one_vmm_ec2.rb index cd7b36b17b..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", - :reboot => "#{EC2_LOCATION}/bin/ec2-reboot-instances", - :authorize => "#{EC2_LOCATION}/bin/ec2-authorize" + :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,150 +329,67 @@ 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") - - if !ami - send_message(ACTION[:deploy],RESULT[:failure],id, - "Can not find AMI in deployment file #{local_dfile}") - return - end - - deploy_cmd = "#{EC2[:run]} #{ami}" - deploy_cmd << " -k #{keypair}" if keypair - deploy_cmd << " -t #{type}" if type - - 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 eip - ip_cmd = "#{EC2[:associate]} #{eip} -i #{deploy_id}" - ip_exe = LocalCommand.run(ip_cmd, log_method(id)) - end - - if ports - ports_cmd = "#{EC2[:authorize]} default -p #{ports}" - ports_exe = LocalCommand.run(ports_cmd, log_method(id)) - 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) - end - - # Reboot a EC2 instance - def reboot(id, drv_message) - cmd = "#{EC2_LOCATION}/bin/ec2-reboot-instances #{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) - 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 - - info = "#{POLL_ATTRIBUTE[:usedmemory]}=0 " \ - "#{POLL_ATTRIBUTE[:usedcpu]}=0 " \ - "#{POLL_ATTRIBUTE[:nettx]}=0 " \ - "#{POLL_ATTRIBUTE[:netrx]}=0" - - cmd = "#{EC2[:describe]} #{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) - cmd = "#{EC2_LOCATION}/bin/ec2-terminate-instances #{deploy_id}" - exe = LocalCommand.run(cmd, log_method(id)) - - if exe.code != 0 - result = RESULT[:failure] - else - result = RESULT[:success] + def value_from_xml(xml, name) + if xml + element = xml.elements[name] + element.text.strip if element && element.text 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 end 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;