diff --git a/NOTICE b/NOTICE index 212910e936..39e1fb5a94 100644 --- a/NOTICE +++ b/NOTICE @@ -3,16 +3,18 @@ Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) ----------------------------------------- You can find more information about the project, release notes and -documentation at www.OpenNebula.org +documentation at www.OpenNebula.org AUTHORS - Ruben Santiago Montero (rubensm@dacya.ucm.es) -- Ignacio Martín Llorente (llorente@dacya.ucm.es) +- Ignacio Martin Llorente (llorente@dacya.ucm.es) ACKNOWLEDGEMENTS The following people have contributed to the development of the technology -- Javier Fontán Muiños (jfontan@fdi.ucm.es) -- Constantino Vázquez Blanco (tinova@fdi.ucm.es) +- Javier Fontan Muiños (jfontan@fdi.ucm.es) +- Constantino Vazquez Blanco (tinova@fdi.ucm.es) - Jaime Melis Bayo (j.melis@fdi.ucm.es) +- Carlos Martin Sanchez (cmartins@fdi.ucm.es) +- Daniel Molina Aranda (danmolin@pdi.ucm.es) diff --git a/README b/README new file mode 100644 index 0000000000..2701cce474 --- /dev/null +++ b/README @@ -0,0 +1,140 @@ + +OpenNebula - The OpenSource Toolkit for Cloud Computing + +## DESCRIPTION + +OpenNebula is an open-source project aimed at building the industry standard +open source cloud computing tool to manage the complexity and heterogeneity of +distributed data center infrastructures. + +Complete documentation can be found at + + http://opennebula.org/documentation:rel2.0 + +## INSTALLATION + +### REQUISITES + +This machine will act as the OpenNebula server and therefore needs to have +installed the following software: + +* **ruby** >= 1.8.5 +* **sqlite3** >= 3.5.2 +* **xmlrpc-c** >= 1.06 +* **openssl** >= 0.9 +* **ssh** +* **sqlite3-ruby** gem + +Additionally, to build OpenNebula from source you need: + +* Development versions of the **sqlite3**, **xmlrpc-c** and **openssl** + packages, if your distribution does not install them with the libraries. +* **scons** >= 0.97 +* **g++** >= 4 +* **flex** >= 2.5 (optional, only needed to rebuild the parsers) +* **bison** >= 2.3 (optional, only needed to rebuild the parsers) +* **libxml2-dev** + + +### OPTIONAL PACKAGES + +These packages are not needed to run or build OpenNebula. They improve the +performance of the user-land libraries and tools of OpenNebula, nor the core +system. You will probably experiment a more responsive CLI. + +First install rubygems and ruby development libraries + +* **ruby-dev** +* **rubygems** +* **rake** +* **make** + +Then install the following packages: + +* **ruby xmlparser**, some distributions include a binary package for this + (**libxml-parser-ruby1.8**). If it is not available in your distribution + install expat libraries with its development files and install xmlparser + using gem: + + $ sudo gem install xmlparser --no-ri --no-rdoc + + Note the extra parameters to gem install. Some versions of xmlparser have + problems building the documentation and we can use it without documentation + installed. + +* **ruby nokogiri**, to install this gem you will need **libxml2** and + **libxslt** libraries and their development versions. The we can install + nokogiri library: + + $ sudo gem install nokogiri --no-ri --no-rdoc + + +### BUILDING + +Compilation is done using **scons** command: + + $ scons [OPTION=VALUE] + +The argument expression *[OPTIONAL]* is used to set non-default values for: + + OPTION VALUE + sqlite_db path-to-sqlite-install + sqlite no if you don't want to build sqlite support + mysql yes if you want to build mysql support + xmlrpc path-to-xmlrpc-install + parsers yes if you want to rebuild flex/bison files + + +### INSTALLATION + +* OpenNebula can be installed in two modes: system-wide, or in self-contained + directory. In either case, you do not need to run OpenNebula as root. These + options can be specified when running the install script: + + $ ./install.sh install_options + +where **install_options** can be one or more of: + + OPTION VALUE + -u user that will run OpenNebula, defaults to user executing + install.sh + -g group of the user that will run OpenNebula, defaults to user + executing install.sh + -k keep current configuration files, useful when upgrading + -d target installation directory. If defined, it will specified + the path for the self-contained install. If not defined, the + installation will be performed system wide + -r remove Opennebula, only useful if -d was not specified, + otherwise rm -rf $ONE_LOCATION would do the job + -h prints installer help + + +## CONFIGURATION + +Information on how to configure OpenNebula is located at http://opennebula.org/documentation:rel2.0 + + +## CONTACT + +OpenNebula web page: http://opennebula.org + +Development and issue tracking: http://dev.opennebula.org + +Support mailing list: http://opennebula.org/support:support + + +## LICENSE + +Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + +Licensed under the Apache License, Version 2.0 (the "License"); you may +not use this file except in compliance with the License. You may obtain +a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + diff --git a/SConstruct b/SConstruct index 5401320d0e..89a2747034 100644 --- a/SConstruct +++ b/SConstruct @@ -81,7 +81,7 @@ main_env.Append(CPPFLAGS=[ ]) # Linking flags -main_env.Append(LINKFLAGS=["-g"]) +main_env.Append(LINKFLAGS=['-g', '-pthread']) ####################### # EXTRA CONFIGURATION # diff --git a/include/Hook.h b/include/Hook.h index 99ed350328..6d01c7a09e 100644 --- a/include/Hook.h +++ b/include/Hook.h @@ -51,7 +51,7 @@ public: Hook(const string &_name, const string &_cmd, const string &_args, - HookType _ht, + int _ht, bool _remote): name(_name), cmd(_cmd), args(_args), hook_type(_ht), remote(_remote){}; @@ -63,7 +63,7 @@ public: /** * Returns the hook_type */ - HookType type() const + int type() const { return hook_type; } @@ -93,7 +93,7 @@ protected: /** * The Hook Type */ - HookType hook_type; + int hook_type; /** * True if the command is to be executed remotely diff --git a/include/LibVirtDriver.h b/include/LibVirtDriver.h index 814e72b328..974aba5831 100644 --- a/include/LibVirtDriver.h +++ b/include/LibVirtDriver.h @@ -1,18 +1,18 @@ -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ /* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ -/* not use this file except in compliance with the License. You may obtain */ -/* a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -/* See the License for the specific language governing permissions and */ -/* limitations under the License. */ -/* -------------------------------------------------------------------------- */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------- */ #ifndef LIBVIRT_DRIVER_H_ #define LIBVIRT_DRIVER_H_ @@ -41,9 +41,31 @@ public: private: int deployment_description( - const VirtualMachine * vm, + const VirtualMachine * vm, + const string& file_name) const + { + int rc = -1; + + if (emulator == "kvm") + { + rc = deployment_description_kvm(vm,file_name); + } + else if (emulator == "vmware") + { + rc = deployment_description_vmware(vm,file_name); + } + + return rc; + } + + int deployment_description_kvm( + const VirtualMachine * vm, const string& file_name) const; - + + int deployment_description_vmware( + const VirtualMachine * vm, + const string& file_name) const; + const string emulator; }; diff --git a/include/Mad.h b/include/Mad.h index ae3c093c9e..7ec5f4dd19 100644 --- a/include/Mad.h +++ b/include/Mad.h @@ -68,11 +68,12 @@ protected: { string str; const char * cstr; + size_t retval; str = os.str(); cstr = str.c_str(); - ::write(nebula_mad_pipe, cstr, str.size()); + retval = ::write(nebula_mad_pipe, cstr, str.size()); }; /** diff --git a/include/Nebula.h b/include/Nebula.h index baf4b31159..15e5268775 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -203,7 +203,7 @@ public: static string version() { - return "OpenNebula 1.9.80"; + return "OpenNebula 2.0.0"; }; void start(); diff --git a/include/RequestManager.h b/include/RequestManager.h index e0d5a2cb39..f9a5350f11 100644 --- a/include/RequestManager.h +++ b/include/RequestManager.h @@ -983,6 +983,27 @@ private: /* ---------------------------------------------------------------------- */ + class UserInfo: public xmlrpc_c::method + { + public: + UserInfo(UserPool * _upool):upool(_upool) + { + _signature="A:si"; + _help="Returns the information for a user"; + }; + + ~UserInfo(){}; + + void execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retvalP); + + private: + UserPool * upool; + }; + + /* ---------------------------------------------------------------------- */ + class UserPoolInfo: public xmlrpc_c::method { public: diff --git a/include/VirtualMachineHook.h b/include/VirtualMachineHook.h index 3a9fcca190..7ccdf1862a 100644 --- a/include/VirtualMachineHook.h +++ b/include/VirtualMachineHook.h @@ -68,7 +68,7 @@ protected: const string& cmd, const string& args, bool remote): - Hook(name, cmd, args, Hook::UPDATE, remote){}; + Hook(name, cmd, args, Hook::UPDATE | Hook::ALLOCATE, remote){}; virtual ~VirtualMachineStateMapHook(){}; diff --git a/include/test/PoolTest.h b/include/test/PoolTest.h index 25a87bbe18..91a90654cf 100644 --- a/include/test/PoolTest.h +++ b/include/test/PoolTest.h @@ -36,6 +36,8 @@ #include "PoolSQL.h" #include "Nebula.h" +#include "test/one_test_common.h" + // Use this macro in sub-classes to add all the tests defined here #define ALL_POOLTEST_CPPUNIT_TESTS() \ CPPUNIT_TEST (oid_assignment); \ @@ -339,6 +341,9 @@ public: NebulaLog::log("Test", Log::INFO, "Test started"); CppUnit::TextUi::TestRunner runner; + + SETUP_XML_WRITER(runner, "output.xml") + runner.addTest( suite ); if (sqlite_flag) @@ -356,6 +361,8 @@ public: runner.run(); + END_XML_WRITER + if (!log_flag) remove("test.log"); diff --git a/include/test/one_test_common.h b/include/test/one_test_common.h new file mode 100644 index 0000000000..857f2be6c6 --- /dev/null +++ b/include/test/one_test_common.h @@ -0,0 +1,12 @@ + +#include + +#define SETUP_XML_WRITER(runner, output) \ + ofstream outputFile(output); \ + CppUnit::XmlOutputter* outputter = \ + new CppUnit::XmlOutputter(&runner.result(), outputFile); \ + \ + runner.setOutputter(outputter); + +#define END_XML_WRITER outputFile.close(); + diff --git a/install.sh b/install.sh index 7da1b48534..819e31f269 100755 --- a/install.sh +++ b/install.sh @@ -100,11 +100,13 @@ if [ -z "$ROOT" ] ; then LOCK_LOCATION="/var/lock/one" INCLUDE_LOCATION="/usr/include" SHARE_LOCATION="/usr/share/one" + MAN_LOCATION="/usr/share/man/man8" if [ "$CLIENT" = "no" ]; then MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $ETC_LOCATION $VAR_LOCATION \ $INCLUDE_LOCATION $SHARE_LOCATION \ - $LOG_LOCATION $RUN_LOCATION $LOCK_LOCATION $IMAGES_LOCATION" + $LOG_LOCATION $RUN_LOCATION $LOCK_LOCATION \ + $IMAGES_LOCATION $MAN_LOCATION" DELETE_DIRS="$LIB_LOCATION $ETC_LOCATION $LOG_LOCATION $VAR_LOCATION \ $RUN_LOCATION $SHARE_DIRS" @@ -126,10 +128,12 @@ else IMAGES_LOCATION="$VAR_LOCATION/images" INCLUDE_LOCATION="$ROOT/include" SHARE_LOCATION="$ROOT/share" + MAN_LOCATION="$ROOT/share/man/man8" if [ "$CLIENT" = "no" ]; then MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $ETC_LOCATION $VAR_LOCATION \ - $INCLUDE_LOCATION $SHARE_LOCATION $IMAGES_LOCATION" + $INCLUDE_LOCATION $SHARE_LOCATION $IMAGES_LOCATION \ + $MAN_LOCATION" DELETE_DIRS="$MAKE_DIRS" @@ -151,6 +155,7 @@ ETC_DIRS="$ETC_LOCATION/im_kvm \ $ETC_LOCATION/im_xen \ $ETC_LOCATION/im_ec2 \ $ETC_LOCATION/vmm_ec2 \ + $ETC_LOCATION/vmm_ssh \ $ETC_LOCATION/vmm_sh \ $ETC_LOCATION/tm_nfs \ $ETC_LOCATION/tm_ssh \ @@ -163,7 +168,6 @@ ETC_DIRS="$ETC_LOCATION/im_kvm \ LIB_DIRS="$LIB_LOCATION/remotes \ $LIB_LOCATION/remotes/im \ - $LIB_LOCATION/remotes/im/common.d \ $LIB_LOCATION/remotes/im/kvm.d \ $LIB_LOCATION/remotes/im/xen.d \ $LIB_LOCATION/remotes/vmm/xen \ @@ -211,24 +215,24 @@ INSTALL_FILES[3]="RUBY_LIB_FILES:$LIB_LOCATION/ruby" INSTALL_FILES[4]="RUBY_OPENNEBULA_LIB_FILES:$LIB_LOCATION/ruby/OpenNebula" INSTALL_FILES[5]="MADS_LIB_FILES:$LIB_LOCATION/mads" INSTALL_FILES[6]="IM_PROBES_FILES:$LIB_LOCATION/remotes/im" -INSTALL_FILES[7]="IM_PROBES_COMMON_FILES:$LIB_LOCATION/remotes/im/common.d" -INSTALL_FILES[8]="IM_PROBES_KVM_FILES:$LIB_LOCATION/remotes/im/kvm.d" -INSTALL_FILES[9]="IM_PROBES_XEN_FILES:$LIB_LOCATION/remotes/im/xen.d" -INSTALL_FILES[10]="VMM_SH_KVM_SCRIPTS:$LIB_LOCATION/remotes/vmm/kvm" -INSTALL_FILES[11]="VMM_SH_XEN_SCRIPTS:$LIB_LOCATION/remotes/vmm/xen" -INSTALL_FILES[12]="NFS_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/nfs" -INSTALL_FILES[13]="SSH_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/ssh" -INSTALL_FILES[14]="DUMMY_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/dummy" -INSTALL_FILES[15]="LVM_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/lvm" -INSTALL_FILES[16]="EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples" -INSTALL_FILES[17]="TM_EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples/tm" -INSTALL_FILES[18]="HOOK_SHARE_FILES:$SHARE_LOCATION/hooks" -INSTALL_FILES[19]="COMMON_CLOUD_LIB_FILES:$LIB_LOCATION/ruby/cloud" -INSTALL_FILES[20]="ECO_LIB_FILES:$LIB_LOCATION/ruby/cloud/econe" -INSTALL_FILES[21]="ECO_LIB_VIEW_FILES:$LIB_LOCATION/ruby/cloud/econe/views" -INSTALL_FILES[22]="ECO_BIN_FILES:$BIN_LOCATION" -INSTALL_FILES[23]="OCCI_LIB_FILES:$LIB_LOCATION/ruby/cloud/occi" -INSTALL_FILES[24]="OCCI_BIN_FILES:$BIN_LOCATION" +INSTALL_FILES[7]="IM_PROBES_KVM_FILES:$LIB_LOCATION/remotes/im/kvm.d" +INSTALL_FILES[8]="IM_PROBES_XEN_FILES:$LIB_LOCATION/remotes/im/xen.d" +INSTALL_FILES[9]="VMM_SSH_KVM_SCRIPTS:$LIB_LOCATION/remotes/vmm/kvm" +INSTALL_FILES[10]="VMM_SSH_XEN_SCRIPTS:$LIB_LOCATION/remotes/vmm/xen" +INSTALL_FILES[11]="NFS_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/nfs" +INSTALL_FILES[12]="SSH_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/ssh" +INSTALL_FILES[13]="DUMMY_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/dummy" +INSTALL_FILES[14]="LVM_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/lvm" +INSTALL_FILES[15]="EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples" +INSTALL_FILES[16]="TM_EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples/tm" +INSTALL_FILES[17]="HOOK_SHARE_FILES:$SHARE_LOCATION/hooks" +INSTALL_FILES[18]="COMMON_CLOUD_LIB_FILES:$LIB_LOCATION/ruby/cloud" +INSTALL_FILES[19]="ECO_LIB_FILES:$LIB_LOCATION/ruby/cloud/econe" +INSTALL_FILES[20]="ECO_LIB_VIEW_FILES:$LIB_LOCATION/ruby/cloud/econe/views" +INSTALL_FILES[21]="ECO_BIN_FILES:$BIN_LOCATION" +INSTALL_FILES[22]="OCCI_LIB_FILES:$LIB_LOCATION/ruby/cloud/occi" +INSTALL_FILES[23]="OCCI_BIN_FILES:$BIN_LOCATION" +INSTALL_FILES[24]="MAN_FILES:$MAN_LOCATION" INSTALL_ECO_CLIENT_FILES[0]="COMMON_CLOUD_CLIENT_LIB_FILES:$LIB_LOCATION/ruby/cloud" INSTALL_ECO_CLIENT_FILES[1]="ECO_LIB_CLIENT_FILES:$LIB_LOCATION/ruby/cloud/econe" @@ -240,18 +244,19 @@ INSTALL_OCCI_CLIENT_FILES[2]="OCCI_BIN_CLIENT_FILES:$BIN_LOCATION" INSTALL_ETC_FILES[0]="ETC_FILES:$ETC_LOCATION" INSTALL_ETC_FILES[1]="VMM_EC2_ETC_FILES:$ETC_LOCATION/vmm_ec2" -INSTALL_ETC_FILES[2]="VMM_SH_ETC_FILES:$ETC_LOCATION/vmm_sh" -INSTALL_ETC_FILES[3]="IM_EC2_ETC_FILES:$ETC_LOCATION/im_ec2" -INSTALL_ETC_FILES[4]="TM_NFS_ETC_FILES:$ETC_LOCATION/tm_nfs" -INSTALL_ETC_FILES[5]="TM_SSH_ETC_FILES:$ETC_LOCATION/tm_ssh" -INSTALL_ETC_FILES[6]="TM_DUMMY_ETC_FILES:$ETC_LOCATION/tm_dummy" -INSTALL_ETC_FILES[7]="TM_LVM_ETC_FILES:$ETC_LOCATION/tm_lvm" -INSTALL_ETC_FILES[8]="HM_ETC_FILES:$ETC_LOCATION/hm" -INSTALL_ETC_FILES[9]="AUTH_ETC_FILES:$ETC_LOCATION/auth" -INSTALL_ETC_FILES[10]="ECO_ETC_FILES:$ETC_LOCATION" -INSTALL_ETC_FILES[11]="ECO_ETC_TEMPLATE_FILES:$ETC_LOCATION/ec2query_templates" -INSTALL_ETC_FILES[12]="OCCI_ETC_FILES:$ETC_LOCATION" -INSTALL_ETC_FILES[13]="OCCI_ETC_TEMPLATE_FILES:$ETC_LOCATION/occi_templates" +INSTALL_ETC_FILES[2]="VMM_SSH_ETC_FILES:$ETC_LOCATION/vmm_ssh" +INSTALL_ETC_FILES[3]="VMM_SH_ETC_FILES:$ETC_LOCATION/vmm_sh" +INSTALL_ETC_FILES[4]="IM_EC2_ETC_FILES:$ETC_LOCATION/im_ec2" +INSTALL_ETC_FILES[5]="TM_NFS_ETC_FILES:$ETC_LOCATION/tm_nfs" +INSTALL_ETC_FILES[6]="TM_SSH_ETC_FILES:$ETC_LOCATION/tm_ssh" +INSTALL_ETC_FILES[7]="TM_DUMMY_ETC_FILES:$ETC_LOCATION/tm_dummy" +INSTALL_ETC_FILES[8]="TM_LVM_ETC_FILES:$ETC_LOCATION/tm_lvm" +INSTALL_ETC_FILES[9]="HM_ETC_FILES:$ETC_LOCATION/hm" +INSTALL_ETC_FILES[10]="AUTH_ETC_FILES:$ETC_LOCATION/auth" +INSTALL_ETC_FILES[11]="ECO_ETC_FILES:$ETC_LOCATION" +INSTALL_ETC_FILES[12]="ECO_ETC_TEMPLATE_FILES:$ETC_LOCATION/ec2query_templates" +INSTALL_ETC_FILES[13]="OCCI_ETC_FILES:$ETC_LOCATION" +INSTALL_ETC_FILES[14]="OCCI_ETC_TEMPLATE_FILES:$ETC_LOCATION/occi_templates" #------------------------------------------------------------------------------- # Binary files, to be installed under $BIN_LOCATION @@ -317,6 +322,8 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \ MADS_LIB_FILES="src/mad/sh/madcommon.sh \ src/tm_mad/tm_common.sh \ + src/vmm_mad/ssh/one_vmm_ssh.rb \ + src/vmm_mad/ssh/one_vmm_ssh \ src/vmm_mad/sh/one_vmm_sh.rb \ src/vmm_mad/sh/one_vmm_sh \ src/vmm_mad/ec2/one_vmm_ec2.rb \ @@ -325,6 +332,8 @@ MADS_LIB_FILES="src/mad/sh/madcommon.sh \ src/vmm_mad/dummy/one_vmm_dummy \ src/im_mad/im_ssh/one_im_ssh.rb \ src/im_mad/im_ssh/one_im_ssh \ + src/im_mad/im_sh/one_im_sh.rb \ + src/im_mad/im_sh/one_im_sh \ src/im_mad/ec2/one_im_ec2.rb \ src/im_mad/ec2/one_im_ec2 \ src/im_mad/dummy/one_im_dummy.rb \ @@ -340,7 +349,7 @@ MADS_LIB_FILES="src/mad/sh/madcommon.sh \ # VMM SH Driver KVM scripts, to be installed under $REMOTES_LOCATION/vmm/kvm #------------------------------------------------------------------------------- -VMM_SH_KVM_SCRIPTS="src/vmm_mad/remotes/kvm/cancel \ +VMM_SSH_KVM_SCRIPTS="src/vmm_mad/remotes/kvm/cancel \ src/vmm_mad/remotes/kvm/deploy \ src/vmm_mad/remotes/kvm/kvmrc \ src/vmm_mad/remotes/kvm/migrate \ @@ -353,7 +362,7 @@ VMM_SH_KVM_SCRIPTS="src/vmm_mad/remotes/kvm/cancel \ # VMM SH Driver Xen scripts, to be installed under $REMOTES_LOCATION/vmm/xen #------------------------------------------------------------------------------- -VMM_SH_XEN_SCRIPTS="src/vmm_mad/remotes/xen/cancel \ +VMM_SSH_XEN_SCRIPTS="src/vmm_mad/remotes/xen/cancel \ src/vmm_mad/remotes/xen/deploy \ src/vmm_mad/remotes/xen/xenrc \ src/vmm_mad/remotes/xen/migrate \ @@ -368,13 +377,15 @@ VMM_SH_XEN_SCRIPTS="src/vmm_mad/remotes/xen/cancel \ IM_PROBES_FILES="src/im_mad/remotes/run_probes" -IM_PROBES_COMMON_FILES="src/im_mad/remotes/common.d/architecture.sh \ - src/im_mad/remotes/common.d/cpu.sh \ - src/im_mad/remotes/common.d/name.sh" +IM_PROBES_XEN_FILES="src/im_mad/remotes/xen.d/xen.rb \ + src/im_mad/remotes/xen.d/architecture.sh \ + src/im_mad/remotes/xen.d/cpu.sh \ + src/im_mad/remotes/xen.d/name.sh" -IM_PROBES_XEN_FILES="src/im_mad/remotes/xen.d/xen.rb" - -IM_PROBES_KVM_FILES="src/im_mad/remotes/kvm.d/kvm.rb" +IM_PROBES_KVM_FILES="src/im_mad/remotes/kvm.d/kvm.rb \ + src/im_mad/remotes/kvm.d/architecture.sh \ + src/im_mad/remotes/kvm.d/cpu.sh \ + src/im_mad/remotes/kvm.d/name.sh" #------------------------------------------------------------------------------- @@ -422,14 +433,17 @@ ETC_FILES="share/etc/oned.conf \ # Virtualization drivers config. files, to be installed under $ETC_LOCATION # - ec2, $ETC_LOCATION/vmm_ec2 # - sh, $ETC_LOCATION/vmm_sh +# - ssh, $ETC_LOCATION/vmm_ssh #------------------------------------------------------------------------------- VMM_EC2_ETC_FILES="src/vmm_mad/ec2/vmm_ec2rc \ src/vmm_mad/ec2/vmm_ec2.conf" -VMM_SH_ETC_FILES="src/vmm_mad/sh/vmm_shrc \ - src/vmm_mad/sh/vmm_sh_kvm.conf \ - src/vmm_mad/sh/vmm_sh_xen.conf" +VMM_SSH_ETC_FILES="src/vmm_mad/ssh/vmm_sshrc \ + src/vmm_mad/ssh/vmm_ssh_kvm.conf \ + src/vmm_mad/ssh/vmm_ssh_xen.conf" + +VMM_SH_ETC_FILES="src/vmm_mad/sh/vmm_shrc" #------------------------------------------------------------------------------- # Information drivers config. files, to be installed under $ETC_LOCATION @@ -578,6 +592,27 @@ OCCI_ETC_TEMPLATE_FILES="src/cloud/occi/etc/templates/small.erb \ src/cloud/occi/etc/templates/medium.erb \ src/cloud/occi/etc/templates/large.erb" +#----------------------------------------------------------------------------- +# MAN files +#----------------------------------------------------------------------------- + +MAN_FILES="share/man/oneauth.8.gz \ + share/man/onecluster.8.gz \ + share/man/onehost.8.gz \ + share/man/oneimage.8.gz \ + share/man/oneuser.8.gz \ + share/man/onevm.8.gz \ + share/man/onevnet.8.gz \ + share/man/econe-describe-images.8.gz \ + share/man/econe-describe-instances.8.gz \ + share/man/econe-register.8.gz \ + share/man/econe-run-instances.8.gz \ + share/man/econe-terminate-instances.8.gz \ + share/man/econe-upload.8.gz \ + share/man/occi-compute.8.gz \ + share/man/occi-network.8.gz \ + share/man/occi-storage.8.gz" + #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # INSTALL.SH SCRIPT @@ -653,8 +688,8 @@ if [ "$UNINSTALL" = "no" ] ; then # --- Set correct permissions for Image Repository --- - if [ -d "$IMAGES_LOCATION" ]; then - chmod 3770 $IMAGES_LOCATION + if [ -d "$DESTDIR$IMAGES_LOCATION" ]; then + chmod 3770 $DESTDIR$IMAGES_LOCATION fi else for d in `echo $DELETE_DIRS | awk '{for (i=NF;i>=1;i--) printf $i" "}'`; do diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 4033353643..35dfd523e1 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -35,6 +35,8 @@ VM_POLLING_INTERVAL = 600 #VM_DIR=/srv/cloud/one/var +SCRIPTS_REMOTE_DIR=/var/tmp/one + PORT=2633 DB = [ backend = "sqlite" ] @@ -46,7 +48,7 @@ DB = [ backend = "sqlite" ] # passwd = "oneadmin", # db_name = "opennebula" ] -VNC_BASE_PORT = 5000 +VNC_BASE_PORT = 5900 DEBUG_LEVEL=3 @@ -162,9 +164,9 @@ IM_MAD = [ #------------------------------------------------------------------------------- VM_MAD = [ name = "vmm_kvm", - executable = "one_vmm_sh", + executable = "one_vmm_ssh", arguments = "kvm", - default = "vmm_sh/vmm_sh_kvm.conf", + default = "vmm_ssh/vmm_ssh_kvm.conf", type = "kvm" ] #------------------------------------------------------------------------------- @@ -173,9 +175,9 @@ VM_MAD = [ #------------------------------------------------------------------------------- #VM_MAD = [ # name = "vmm_xen", -# executable = "one_vmm_sh", +# executable = "one_vmm_ssh", # arguments = "xen", -# default = "vmm_sh/vmm_sh_xen.conf", +# default = "vmm_ssh/vmm_ssh_xen.conf", # type = "xen" ] #------------------------------------------------------------------------------- diff --git a/share/hooks/image.rb b/share/hooks/image.rb index 8709a7d65f..7625810312 100755 --- a/share/hooks/image.rb +++ b/share/hooks/image.rb @@ -36,7 +36,13 @@ if !(vm_id=ARGV[0]) end -client = Client.new() +begin + client = Client.new() +rescue Exception => e + puts "Error: #{e}" + exit(-1) +end + img_repo = ImageRepository.new vm = VirtualMachine.new( diff --git a/share/man/econe-describe-images.8.gz b/share/man/econe-describe-images.8.gz new file mode 100644 index 0000000000..c0aa5db454 Binary files /dev/null and b/share/man/econe-describe-images.8.gz differ diff --git a/share/man/econe-describe-instances.8.gz b/share/man/econe-describe-instances.8.gz new file mode 100644 index 0000000000..143bb28a5f Binary files /dev/null and b/share/man/econe-describe-instances.8.gz differ diff --git a/share/man/econe-register.8.gz b/share/man/econe-register.8.gz new file mode 100644 index 0000000000..bc5e8b13f3 Binary files /dev/null and b/share/man/econe-register.8.gz differ diff --git a/share/man/econe-run-instances.8.gz b/share/man/econe-run-instances.8.gz new file mode 100644 index 0000000000..22e1d8d65b Binary files /dev/null and b/share/man/econe-run-instances.8.gz differ diff --git a/share/man/econe-terminate-instances.8.gz b/share/man/econe-terminate-instances.8.gz new file mode 100644 index 0000000000..ba19ff45c7 Binary files /dev/null and b/share/man/econe-terminate-instances.8.gz differ diff --git a/share/man/econe-upload.8.gz b/share/man/econe-upload.8.gz new file mode 100644 index 0000000000..fb0704f662 Binary files /dev/null and b/share/man/econe-upload.8.gz differ diff --git a/share/man/occi-compute.8.gz b/share/man/occi-compute.8.gz new file mode 100644 index 0000000000..11842ea221 Binary files /dev/null and b/share/man/occi-compute.8.gz differ diff --git a/share/man/occi-network.8.gz b/share/man/occi-network.8.gz new file mode 100644 index 0000000000..35e512a6fd Binary files /dev/null and b/share/man/occi-network.8.gz differ diff --git a/share/man/occi-storage.8.gz b/share/man/occi-storage.8.gz new file mode 100644 index 0000000000..2cdb242469 Binary files /dev/null and b/share/man/occi-storage.8.gz differ diff --git a/share/man/oneauth.8.gz b/share/man/oneauth.8.gz new file mode 100644 index 0000000000..95554bb729 Binary files /dev/null and b/share/man/oneauth.8.gz differ diff --git a/share/man/onecluster.8.gz b/share/man/onecluster.8.gz new file mode 100644 index 0000000000..69544f59c9 Binary files /dev/null and b/share/man/onecluster.8.gz differ diff --git a/share/man/onehost.8.gz b/share/man/onehost.8.gz new file mode 100644 index 0000000000..fcecb4540e Binary files /dev/null and b/share/man/onehost.8.gz differ diff --git a/share/man/oneimage.8.gz b/share/man/oneimage.8.gz new file mode 100644 index 0000000000..ea2abbb5fb Binary files /dev/null and b/share/man/oneimage.8.gz differ diff --git a/share/man/oneuser.8.gz b/share/man/oneuser.8.gz new file mode 100644 index 0000000000..73e54fb803 Binary files /dev/null and b/share/man/oneuser.8.gz differ diff --git a/share/man/onevm.8.gz b/share/man/onevm.8.gz new file mode 100644 index 0000000000..80943fde9b Binary files /dev/null and b/share/man/onevm.8.gz differ diff --git a/share/man/onevnet.8.gz b/share/man/onevnet.8.gz new file mode 100644 index 0000000000..6d4825c056 Binary files /dev/null and b/share/man/onevnet.8.gz differ diff --git a/src/authm/test/AuthManagerTest.cc b/src/authm/test/AuthManagerTest.cc index 882d8b4a91..452419fa52 100644 --- a/src/authm/test/AuthManagerTest.cc +++ b/src/authm/test/AuthManagerTest.cc @@ -34,6 +34,8 @@ #include #include +#include "test/one_test_common.h" + using namespace std; @@ -291,10 +293,14 @@ int main(int argc, char ** argv) NebulaLog::init_log_system(NebulaLog::FILE, Log::DEBUG,"test.log"); NebulaLog::log("Test", Log::INFO, "Test started"); + SETUP_XML_WRITER(runner, "AuthManagerTest.xml"); + runner.addTest(AuthManagerTest::suite()); runner.run(); + END_XML_WRITER + NebulaLog::finalize_log_system(); return 0; diff --git a/src/authm_mad/one_auth_mad.rb b/src/authm_mad/one_auth_mad.rb index 6832e7cafc..0a36f4b1cc 100755 --- a/src/authm_mad/one_auth_mad.rb +++ b/src/authm_mad/one_auth_mad.rb @@ -84,7 +84,12 @@ class AuthorizationManager < OpenNebulaDriver end def action_authorize(request_id, user_id, *tokens) - auth=@permissions.auth(user_id, tokens.flatten) + begin + auth=@permissions.auth(user_id, tokens.flatten) + rescue Exception => e + auth="Error: #{e}" + end + if auth==true send_message('AUTHORIZE', RESULT[:success], request_id, 'success') @@ -95,7 +100,12 @@ class AuthorizationManager < OpenNebulaDriver end end +begin + am=AuthorizationManager.new +rescue Exception => e + puts "Error: #{e}" + exit(-1) +end -am=AuthorizationManager.new am.start_driver diff --git a/src/authm_mad/oneauth b/src/authm_mad/oneauth index 1f3d39c6f3..3f5581620c 100755 --- a/src/authm_mad/oneauth +++ b/src/authm_mad/oneauth @@ -38,12 +38,19 @@ require 'sequel' require 'quota' require 'ssh_auth' require 'client_utilities' +require 'command_parse' COMMANDS_HELP=<<-EOT Usage: oneauth [] + +Description: + +This command contains a set of utilities to manage authorization module. + + Commands: * quota set (sets quota for a user) @@ -91,7 +98,13 @@ when "quota" when 'set' check_parameters("quota set", 3) Dir.chdir VAR_LOCATION - add_quota(*ARGV[1..3]) + + begin + add_quota(*ARGV[1..3]) + rescue Exception => e + puts "Error starting server: #{e}" + exit(-1) + end else #default end @@ -123,6 +136,9 @@ when "help" print_help exit 0 +when "--version" + puts CommandParse::ONE_VERSION + else print_help exit -1 diff --git a/src/cli/command_parse.rb b/src/cli/command_parse.rb index 67bc4c1d91..e1c406e147 100644 --- a/src/cli/command_parse.rb +++ b/src/cli/command_parse.rb @@ -31,8 +31,12 @@ Options: EOT ONE_VERSION=<<-EOT -OpenNebula 1.9.80 +OpenNebula 2.0.0 Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + +Licensed under the Apache License, Version 2.0 (the "License"); you may +not use this file except in compliance with the License. You may obtain +a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 EOT def initialize(standard_options=nil) diff --git a/src/cli/onecluster b/src/cli/onecluster index 933073bb4f..e5128e2614 100755 --- a/src/cli/onecluster +++ b/src/cli/onecluster @@ -88,6 +88,14 @@ end class OneUPParse < CommandParse COMMANDS_HELP=<<-EOT + +Description: + +This command enables the OpenNebula administrator to manage clusters. The +administrator can create, delete, as well as add and remove hosts from them. +Any user can list available clusters. + + Commands: * create (Creates a new user) diff --git a/src/cli/onehost b/src/cli/onehost index c05c18fd32..2bf1ec1eb3 100755 --- a/src/cli/onehost +++ b/src/cli/onehost @@ -166,6 +166,14 @@ end class OnehostParse < CommandParse COMMANDS_HELP=<<-EOT + +Description: + +This command enables the user to manage hosts in the Open Nebula server. It +provides functionality to allocate, get information and delete a particular +host or to list all the available hosts. + + Commands: * create (Adds a new machine to the pool) @@ -191,6 +199,20 @@ Commands: * sync (synchronizes probes with remote hosts) onehost sync + + +Information Columns: + +* HID Host ID +* NAME Host name +* RVM Number of running VMs +* TCPU Total CPU (percentage) +* FCPU Free CPU (percentage) +* ACPU Available CPU (not allocated by VMs) +* TMEM Total memory +* FMEM Free memory +* STAT Host status + EOT diff --git a/src/cli/oneimage b/src/cli/oneimage index 878f3e4a3d..c1a7564fb0 100755 --- a/src/cli/oneimage +++ b/src/cli/oneimage @@ -199,6 +199,12 @@ end class OneImageParse < CommandParse COMMANDS_HELP=<<-EOT + +Description: + +This command enables the user to manage images. + + Commands: * register (Registers an image, copying it to the repository if it applies) @@ -206,6 +212,9 @@ Commands: template is a file name where the Image description is located +* addattr (Add a new image attribute) + oneimage addattr + * update (Modifies an image attribute) oneimage update @@ -234,11 +243,11 @@ Commands: oneimage list where filter_flag can be - a, all --> all the known Images (admin users) - m, mine --> the Images belonging to the user in ONE_AUTH - and all the Public Images - uid --> Images of the user identified by this uid (admin users) - user --> Images of the user identified by the username (admin users) + a, all --> all the known Images + m, mine --> the Images belonging to the user in ONE_AUTH + and all the Public Images + uid --> Images of the user identified by this uid + user --> Images of the user identified by the username * top (Lists Images continuously) onevm top @@ -263,12 +272,6 @@ EOT table=ShowTable.new(ShowTableImage) table.print_help end - - def special_options(opts, options) - opts.on_tail("-n", "--no-cp", "Do not copy the source") do |o| - options[:no_cp]=true - end - end end @@ -327,13 +330,13 @@ when "register", "create", "add" image = OpenNebula::Image.new(OpenNebula::Image.build_xml, get_one_client) - result = img_repo.create(image, template, !ops[:no_cp]) + result = img_repo.create(image, template) if is_successful?(result) puts "ID: " + image.id.to_s if ops[:verbose] end -when "update" +when "update", "addattr" check_parameters("update", 3) image_id=get_image_id(ARGV[0]) @@ -473,7 +476,11 @@ when "show" else public_str = "No" end - puts str % ["PUBLIC", public_str] + puts str % ["PUBLIC", public_str] + + persistent_str=(image["PERSISTENT"].to_i==1 ? "Yes" : "No") + puts str % ["PERSISTENT", persistent_str] + puts str % ["SOURCE", image['SOURCE']] puts str % ["STATE", image.short_state_str] puts str % ["RUNNING_VMS", image['RUNNING_VMS']] diff --git a/src/cli/oneuser b/src/cli/oneuser index b42d960c79..0ca2ad1a59 100755 --- a/src/cli/oneuser +++ b/src/cli/oneuser @@ -92,6 +92,16 @@ end class OneUPParse < CommandParse COMMANDS_HELP=<<-EOT + +Description: + +This command enables the OpenNebula administrator to manage users, adding, +listing and deleting them. + +The create and passwd commands accept the [-r, –read-file] option. Use this +option to store the contents of a file (without hashing it) as the password. + + Commands: * create (Creates a new user) @@ -106,6 +116,15 @@ Commands: * passwd (Changes the given user's password) oneuser passwd password + +Information Columns: + +* UID User ID +* NAME Name of the user +* PASSWORD SHA1 encrypted password +* ENABLE Whether the user is enabled or not + + EOT def text_commands @@ -148,7 +167,7 @@ when "create" if ops[:read_file] begin - password = File.read(ARGV[1]) + password = File.read(ARGV[1]).split("\n").first rescue puts "Can not read file: #{ARGV[1]}" exit -1 @@ -218,7 +237,7 @@ when "passwd" if ops[:read_file] begin - password = File.read(ARGV[1]) + password = File.read(ARGV[1]).split("\n").first rescue puts "Can not read file: #{ARGV[1]}" exit -1 diff --git a/src/cli/onevm b/src/cli/onevm index 955b3b6c43..e454e20cc5 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -307,6 +307,14 @@ end class OnevmParse < CommandParse COMMANDS_HELP=<<-EOT + +Description: + +This command enables the user to manage virtual machines in the ONE server. +The user can allocate, deploy, migrate, suspend, resume and shutdown a virtual +machine with the functionality present in onevm. + + Commands: * create (Submits a new virtual machine, adding it to the ONE VM pool) @@ -363,7 +371,7 @@ Commands: a, all --> all the known VMs m, mine --> the VMs belonging to the user in ONE_AUTH uid --> VMs of the user identified by this uid - user--> VMs of the user identified by the username + user --> VMs of the user identified by the username * show (Gets information about a specific VM) onevm show @@ -376,6 +384,35 @@ Commands: if no vm_id is provided it will list history for all known VMs + +Information Columns: + +* ID ONE VM identifier +* USER Username of the VM owner +* NAME Name of the ONE +* STAT Status of the VM +* CPU CPU percentage used by the VM +* MEM Memory used by the VM +* HOSTNAME Host where the VM is being or was run +* TIME Time since the submission of the VM (days hours:minutes:seconds) + + +VM States: + +* pend pending +* hold VM on hold (not runnable) +* stop stopped +* susp suspended +* done finished +* prol prolog +* boot booting +* runn running +* migr migrating +* save saving the VM to disk +* epil epilog +* shut shutting down +* fail failed + EOT def text_commands @@ -707,7 +744,13 @@ when "saveas" else image_id = vm["TEMPLATE/DISK[DISK_ID=\"#{disk_id}\"]/IMAGE_ID"] - if (image_id != nil) + if (image_id != nil) + if vm["TEMPLATE/DISK[DISK_ID=\"#{disk_id}\"]/SAVE_AS"] + puts "Error: The disk #{disk_id} is already" << + " suppossed to be saved" + exit -1 + end + # Get the image type image = OpenNebula::Image.new( OpenNebula::Image.build_xml(image_id), @@ -718,7 +761,7 @@ when "saveas" puts result.message exit -1 end - + image_type = image.type_str end end @@ -733,13 +776,19 @@ when "saveas" get_one_client) result = image.allocate(template) - if !is_successful?(result) puts result.message exit -1 end result = vm.save_as(disk_id.to_i, image.id) + if is_successful?(result) + puts "VM disk with ID #{disk_id} is prepared to be" << + " saved" if ops[:verbose] + else + image.delete + end + when "show" check_parameters("get_info", 1) diff --git a/src/cli/onevnet b/src/cli/onevnet index 403db47135..c8abec8361 100755 --- a/src/cli/onevnet +++ b/src/cli/onevnet @@ -137,6 +137,14 @@ end class OneVNParse < CommandParse COMMANDS_HELP=<<-EOT + +Description: + +This command enables the user to manage virtual networks in the OpenNebula +server. It provides functionality to create, get information and delete a +particular network or to list available and used IP's. + + Commands: * create (Creates a new virtual network) @@ -159,10 +167,21 @@ Commands: * list (Lists virtual networks in the pool) onevnet list where filter_flag can be - a, all --> all the known VNs - m, mine --> the VNs belonging to the user in ONE_AUTH - uid --> VNs of the user identified by this uid - user --> VNs of the user identified by the username + a, all : all the known VNs + m, mine : the VNs belonging to the user in ONE_AUTH + and all the Public VNs + uid : VNs of the user identified by this uid + user : VNs of the user identified by the username + + +Information columns: + +* NID Network ID +* NAME Name of the virtual network +* TYPE Type of virtual network (0=ranged, 1=fixed) +* BRIDGE Bridge associated to the virtual network +* LEASES Number of leases used from this virtual network + EOT def text_commands @@ -238,9 +257,6 @@ when "show" else puts vn.to_xml(true) end - else - puts "Error: "+result.message - break end end diff --git a/src/cloud/common/CloudClient.rb b/src/cloud/common/CloudClient.rb index abbafd27ec..8f725b509d 100644 --- a/src/cloud/common/CloudClient.rb +++ b/src/cloud/common/CloudClient.rb @@ -135,4 +135,15 @@ module CloudCLI def cmd_name File.basename($0) end + + def version_text + version=<, -K : + --access-key , -K The username of the user - --secret-key , -S : + --secret-key , -S The password of the user - --url , -U : + --url , -U Set url as the web service url to use - --headers, -H: + --headers, -H Display column headers EOT @@ -65,6 +63,7 @@ include CloudCLI opts = GetoptLong.new( ['--help', '-h',GetoptLong::NO_ARGUMENT], + ['--version', '-v',GetoptLong::NO_ARGUMENT], ['--access-key', '-K',GetoptLong::REQUIRED_ARGUMENT], ['--secret-key', '-S',GetoptLong::REQUIRED_ARGUMENT], ['--url', '-U',GetoptLong::REQUIRED_ARGUMENT], @@ -83,6 +82,9 @@ begin when '--help' puts COMMANDS_HELP return + when '--version' + puts CloudCLI.version_text + exit 0 when '--access-key' access = arg when '--secret-key' diff --git a/src/cloud/ec2/bin/econe-describe-instances b/src/cloud/ec2/bin/econe-describe-instances index 05f5605c13..66c2d9830b 100755 --- a/src/cloud/ec2/bin/econe-describe-instances +++ b/src/cloud/ec2/bin/econe-describe-instances @@ -27,29 +27,28 @@ $: << RUBY_LIB_LOCATION $: << RUBY_LIB_LOCATION+"/cloud" COMMANDS_HELP=<<-EOT - ** Synopsis - ----------- - econe-describe-instances - - List and describe running instances +econe-describe-instances - ** Usage - -------- +List and describe running instances + +Usage: econe-describe-instances [OPTIONS] + +Options: - --help, -h: + --help, -h Show help - --access-key , -K : + --access-key , -K The username of the user - --secret-key , -S : + --secret-key , -S The password of the user - --url , -U : + --url , -U Set url as the web service url to use - --headers, -H: + --headers, -H Display column headers EOT @@ -62,6 +61,7 @@ include CloudCLI opts = GetoptLong.new( ['--help', '-h',GetoptLong::NO_ARGUMENT], + ['--version', '-v',GetoptLong::NO_ARGUMENT], ['--access-key', '-K',GetoptLong::REQUIRED_ARGUMENT], ['--secret-key', '-S',GetoptLong::REQUIRED_ARGUMENT], ['--url', '-U',GetoptLong::REQUIRED_ARGUMENT], @@ -80,6 +80,9 @@ begin when '--help' puts COMMANDS_HELP return + when '--version' + puts CloudCLI.version_text + exit 0 when '--access-key' access = arg when '--secret-key' diff --git a/src/cloud/ec2/bin/econe-register b/src/cloud/ec2/bin/econe-register index 917bc49abf..3cdd7b556e 100755 --- a/src/cloud/ec2/bin/econe-register +++ b/src/cloud/ec2/bin/econe-register @@ -27,34 +27,33 @@ $: << RUBY_LIB_LOCATION $: << RUBY_LIB_LOCATION+"/cloud" COMMANDS_HELP=<<-EOT - ** Synopsis - ----------- - econe-register - - Register a previously uploaded image for use with an - OpenNebula Cloud. +econe-register - ** Usage - -------- +Register a previously uploaded image for use with an +OpenNebula Cloud. + +Usage: econe-register [OPTIONS] IMAGE-ID - --help, -h: +Options: + + --help, -h Show help - --access-key , -K : + --access-key , -K The username of the user - --secret-key , -S : + --secret-key , -S The password of the user - --url , -U : + --url , -U Set url as the web service url to use - --headers, -H: + --headers, -H Display column headers - IMAGE-ID: The image identification as returned by - the econe-upload command +IMAGE-ID: The image identification as returned by +the econe-upload command EOT @@ -66,6 +65,7 @@ include CloudCLI opts = GetoptLong.new( ['--help', '-h',GetoptLong::NO_ARGUMENT], + ['--version', '-v',GetoptLong::NO_ARGUMENT], ['--access-key', '-K',GetoptLong::REQUIRED_ARGUMENT], ['--secret-key', '-S',GetoptLong::REQUIRED_ARGUMENT], ['--url', '-U',GetoptLong::REQUIRED_ARGUMENT], @@ -84,6 +84,9 @@ begin when '--help' puts COMMANDS_HELP return + when '--version' + puts CloudCLI.version_text + exit 0 when '--access-key' access = arg when '--secret-key' diff --git a/src/cloud/ec2/bin/econe-run-instances b/src/cloud/ec2/bin/econe-run-instances index cfa51b3e7d..6633bf8092 100755 --- a/src/cloud/ec2/bin/econe-run-instances +++ b/src/cloud/ec2/bin/econe-run-instances @@ -28,40 +28,39 @@ $: << RUBY_LIB_LOCATION $: << RUBY_LIB_LOCATION+"/cloud" COMMANDS_HELP=<<-EOT - ** Synopsis - ----------- - econe-run-instances - - Runs an instance of a particular image +econe-run-instances - ** Usage - -------- +Runs an instance of a particular image + +Usage: econe-run-instances [OPTIONS] IMAGE-ID - --help, -h: +Options: + + --help, -h Show help - --access-key , -K : + --access-key , -K The username of the user - --secret-key , -S : + --secret-key , -S The password of the user - --url , -U : + --url , -U Set url as the web service url to use - --type , -t : + --type , -t OpenNebula template in which is based this instance - -–user-data, -d: + --user-data, -d Specifies Base64-encoded MIME user data to be made available to the instance - --headers, -H: + --headers, -H Display column headers - IMAGE-ID: The image identification as returned by - the econe-upload command +IMAGE-ID: The image identification as returned by +the econe-upload command EOT @@ -73,6 +72,7 @@ include CloudCLI opts = GetoptLong.new( ['--help', '-h',GetoptLong::NO_ARGUMENT], + ['--version', '-v',GetoptLong::NO_ARGUMENT], ['--access-key', '-K',GetoptLong::REQUIRED_ARGUMENT], ['--secret-key', '-S',GetoptLong::REQUIRED_ARGUMENT], ['--url', '-U',GetoptLong::REQUIRED_ARGUMENT], @@ -95,6 +95,9 @@ begin when '--help' puts COMMANDS_HELP return + when '--version' + puts CloudCLI.version_text + exit 0 when '--access-key' access = arg when '--secret-key' diff --git a/src/cloud/ec2/bin/econe-terminate-instances b/src/cloud/ec2/bin/econe-terminate-instances index cc613980fe..f361fc5ca2 100755 --- a/src/cloud/ec2/bin/econe-terminate-instances +++ b/src/cloud/ec2/bin/econe-terminate-instances @@ -28,30 +28,29 @@ $: << RUBY_LIB_LOCATION $: << RUBY_LIB_LOCATION+"/cloud" COMMANDS_HELP=<<-EOT - ** Synopsis - ----------- - econe-terminate-instances - - Terminate the selected running instance +econe-terminate-instances - ** Usage - -------- +Terminate the selected running instance + +Usage: econe-register [OPTIONS] INSTANCE-ID - --help, -h: +Options: + + --help, -h Show help - --access-key , -K : + --access-key , -K The username of the user - --secret-key , -S : + --secret-key , -S The password of the user - --url , -U : + --url , -U Set url as the web service url to use - INSTANCE-ID: The instance identification as returned by - the econe-run-instances command +INSTANCE-ID: The instance identification as returned by +the econe-run-instances command EOT @@ -63,6 +62,7 @@ include CloudCLI opts = GetoptLong.new( ['--help', '-h',GetoptLong::NO_ARGUMENT], + ['--version', '-v',GetoptLong::NO_ARGUMENT], ['--access-key', '-K',GetoptLong::REQUIRED_ARGUMENT], ['--secret-key', '-S',GetoptLong::REQUIRED_ARGUMENT], ['--url', '-U',GetoptLong::REQUIRED_ARGUMENT] @@ -79,6 +79,9 @@ begin when '--help' puts COMMANDS_HELP return + when '--version' + puts CloudCLI.version_text + exit 0 when '--access-key' access = arg when '--secret-key' diff --git a/src/cloud/ec2/bin/econe-upload b/src/cloud/ec2/bin/econe-upload index 2455b91fa6..ab81f5d6d2 100755 --- a/src/cloud/ec2/bin/econe-upload +++ b/src/cloud/ec2/bin/econe-upload @@ -27,33 +27,32 @@ $: << RUBY_LIB_LOCATION $: << RUBY_LIB_LOCATION+"/cloud" COMMANDS_HELP=<<-EOT - ** Synopsis - ----------- - econe-upload - - Uploads an image for use with an OpenNebula Cloud. This image should - be later register with econe-register using the returned ImageId +econe-upload - ** Usage - -------- +Uploads an image for use with an OpenNebula Cloud. This image should +be later register with econe-register using the returned ImageId + +Usage: econe-upload [OPTIONS] IMAGE-PATH - --help, -h: +Options: + + --help, -h Show help - --access-key , -K : + --access-key , -K The username of the user - --secret-key , -S : + --secret-key , -S The password of the user - --url , -U : + --url , -U Set url as the web service url to use - --multipart, -M: + --multipart, -M Use 'multipart-post' library instead of Curb/Curl - IMAGE-PATH: Path to the image to upload +IMAGE-PATH: Path to the image to upload EOT @@ -65,6 +64,7 @@ include CloudCLI opts = GetoptLong.new( ['--help', '-h',GetoptLong::NO_ARGUMENT], + ['--version', '-v',GetoptLong::NO_ARGUMENT], ['--access-key', '-K',GetoptLong::REQUIRED_ARGUMENT], ['--secret-key', '-S',GetoptLong::REQUIRED_ARGUMENT], ['--url', '-U',GetoptLong::REQUIRED_ARGUMENT], @@ -83,6 +83,9 @@ begin when '--help' puts COMMANDS_HELP return + when '--version' + puts CloudCLI.version_text + exit 0 when '--access-key' access = arg when '--secret-key' diff --git a/src/cloud/ec2/lib/econe-server.rb b/src/cloud/ec2/lib/econe-server.rb index dcb8440525..6bcf972bed 100644 --- a/src/cloud/ec2/lib/econe-server.rb +++ b/src/cloud/ec2/lib/econe-server.rb @@ -45,8 +45,13 @@ require 'EC2QueryServer' include OpenNebula -$econe_server = EC2QueryServer.new(CONFIGURATION_FILE, - TEMPLATE_LOCATION, VIEWS_LOCATION) +begin + $econe_server = EC2QueryServer.new(CONFIGURATION_FILE, + TEMPLATE_LOCATION, VIEWS_LOCATION) +rescue Exception => e + puts "Error starting server: #{e}" + exit(-1) +end if CloudServer.is_port_open?($econe_server.config[:server], $econe_server.config[:port]) diff --git a/src/cloud/occi/bin/occi-compute b/src/cloud/occi/bin/occi-compute index 76018c5448..0332e48c48 100755 --- a/src/cloud/occi/bin/occi-compute +++ b/src/cloud/occi/bin/occi-compute @@ -29,51 +29,48 @@ $: << RUBY_LIB_LOCATION $: << RUBY_LIB_LOCATION+"/cloud" COMMANDS_HELP=<<-EOT -** Synopsis -occi-compute +occi-compute - Manages compute resources -Manages compute resources +Usage: + occi-compute [OPTIONS] [ARGUMENTS] -** Usage -occi-compute [OPTIONS] [ARGUMENTS] +Commands: -COMMANDS - -create +* create creates a new compute resource described by the provided -list +* list lists available compute resources -show +* show retrieves the OCCI XML representation of the compute resource identified by -update +* update updates the representation of the compute resource represented by the provided -delete +* delete deletes the compute resource idenfitied by -OPTIONS +Options: ---help, -h: +--help, -h Show help ---username , -U : +--username , -U The username of the user ---password , -P : +--password , -P The password of the user ---url , -R : +--url , -R Set url as the web service url to use --timeout , -T - Sets a timeout for the http connection + Sets a timeout for the http connection --debug, -D Enables verbosity @@ -88,6 +85,7 @@ include CloudCLI opts = GetoptLong.new( ['--help', '-h',GetoptLong::NO_ARGUMENT], + ['--version', '-v',GetoptLong::NO_ARGUMENT], ['--username', '-U',GetoptLong::REQUIRED_ARGUMENT], ['--password', '-P',GetoptLong::REQUIRED_ARGUMENT], ['--url', '-R',GetoptLong::REQUIRED_ARGUMENT], @@ -108,6 +106,9 @@ begin when '--help' puts COMMANDS_HELP return + when '--version' + puts CloudCLI.version_text + exit 0 when '--username' username = arg when '--password' diff --git a/src/cloud/occi/bin/occi-network b/src/cloud/occi/bin/occi-network index 42b8d6eaf9..2d1387ed79 100755 --- a/src/cloud/occi/bin/occi-network +++ b/src/cloud/occi/bin/occi-network @@ -29,15 +29,12 @@ $: << RUBY_LIB_LOCATION $: << RUBY_LIB_LOCATION+"/cloud" COMMANDS_HELP=<<-EOT -** Synopsis -occi-network +occi-network - Manages virtual networks -Manages virtual networks +Usage: + occi-network [OPTIONS] [ARGUMENTS] -** Usage -occi-network [OPTIONS] [ARGUMENTS] - -COMMANDS +Commands: create creates a new virtual network described by the provided @@ -55,18 +52,18 @@ delete -OPTIONS +Options: ---help, -h: +--help, -h Show help ---username , -U : +--username , -U The username of the user ---password , -P : +--password , -P The password of the user ---url , -R : +--url , -R Set url as the web service url to use --timeout , -T @@ -75,7 +72,7 @@ OPTIONS --debug, -D Enables verbosity ---multipart, -M: +--multipart, -M Use 'multipart-post' library instead of Curb/Curl EOT @@ -89,6 +86,7 @@ include CloudCLI opts = GetoptLong.new( ['--help', '-h',GetoptLong::NO_ARGUMENT], + ['--version', '-v',GetoptLong::NO_ARGUMENT], ['--username', '-U',GetoptLong::REQUIRED_ARGUMENT], ['--password', '-P',GetoptLong::REQUIRED_ARGUMENT], ['--url', '-R',GetoptLong::REQUIRED_ARGUMENT], @@ -109,6 +107,9 @@ begin when '--help' puts COMMANDS_HELP return + when '--version' + puts CloudCLI.version_text + exit 0 when '--username' username = arg when '--password' diff --git a/src/cloud/occi/bin/occi-storage b/src/cloud/occi/bin/occi-storage index 4387b2ab27..5085656090 100755 --- a/src/cloud/occi/bin/occi-storage +++ b/src/cloud/occi/bin/occi-storage @@ -29,15 +29,12 @@ $: << RUBY_LIB_LOCATION $: << RUBY_LIB_LOCATION+"/cloud" COMMANDS_HELP=<<-EOT -** Synopsis -occi-storage +occi-storage - Manages OCCI storage resource -Manages OCCI storage resource +Usage: + occi-storage [OPTIONS] [PARAMETERS] -** Usage -occi-storage [OPTIONS] [PARAMETERS] - -COMMANDS +Commands: create creates a new storage resource described by the provided @@ -54,17 +51,18 @@ delete deletes the storage resource idenfitied by -OPTIONS ---help, -h: +Options: + +--help, -h Show help ---username , -U : +--username , -U The username of the user ---password , -P : +--password , -P The password of the user ---url , -R : +--url , -R Set url as the web service url to use --timeout , -T @@ -73,7 +71,7 @@ OPTIONS --debug, -D Enables verbosity ---multipart, -M: +--multipart, -M Use 'multipart-post' library instead of Curb/Curl EOT @@ -87,6 +85,7 @@ include CloudCLI opts = GetoptLong.new( ['--help', '-h',GetoptLong::NO_ARGUMENT], + ['--version', '-v',GetoptLong::NO_ARGUMENT], ['--username', '-U',GetoptLong::REQUIRED_ARGUMENT], ['--password', '-P',GetoptLong::REQUIRED_ARGUMENT], ['--url', '-R',GetoptLong::REQUIRED_ARGUMENT], @@ -109,6 +108,9 @@ begin when '--help' puts COMMANDS_HELP return + when '--version' + puts CloudCLI.version_text + exit 0 when '--username' username = arg when '--password' diff --git a/src/cloud/occi/etc/templates/common.erb b/src/cloud/occi/etc/templates/common.erb new file mode 100644 index 0000000000..0a2756e5b3 --- /dev/null +++ b/src/cloud/occi/etc/templates/common.erb @@ -0,0 +1,42 @@ +# +# This template is processed by the OCCI Server to include specific data for the +# instance, you should not need to modify the <% ... %> compounds. +# You can add common attributes for your cloud templates (e.g. OS) +# + +NAME = "<%= @vm_info['NAME'] %>" + +<% @vm_info.each('DISK') do |disk| %> + <% if disk.attr('STORAGE','href') %> + DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %> + ] + <% end %> +<% end %> + +<% @vm_info.each('NIC') do |nic| %> + <% if nic.attr('NETWORK','href') %> + NIC = [ NETWORK_ID = <%= nic.attr('NETWORK','href').split('/').last %> + <% if nic['IP'] %> + ,IP = <%= nic['IP'] %> + <% end %> + ] + <% end %> +<% end %> + +<% if @vm_info.has_elements?('CONTEXT') %> + CONTEXT = [ + <% first = true %> + <% @vm_info.each('CONTEXT/*') do |cont| %> + <% if cont.text %> + <% if first %> + <%= cont.name %> = "<%= cont.text %>" + <% first = false %> + <% else %> + ,<%= cont.name %> = "<%= cont.text %>" + <% end %> + <% end %> + <% end %> + ] +<% end %> + +INSTANCE_TYPE = <%= @vm_info['INSTANCE_TYPE']%> \ No newline at end of file diff --git a/src/cloud/occi/etc/templates/large.erb b/src/cloud/occi/etc/templates/large.erb index cc1cc7a98f..0af7a6ce14 100644 --- a/src/cloud/occi/etc/templates/large.erb +++ b/src/cloud/occi/etc/templates/large.erb @@ -1,34 +1,8 @@ # # Virtual Machine Template generated for large instance types. Adjust this # by setting the desired capacity (CPU,MEMORY) or adding specific -# attributes for your cloud (e.g. OS). You should not need to change the DISK -# and NIC sections +# attributes for your cloud (e.g. OS). # CPU = 8 MEMORY = 8192 - -NAME = "<%= @vm_info['NAME'] %>" - -<% if @vm_info['DISK'] %> - <% @vm_info.each('DISK') do |disk| %> - <% if disk['STORAGE'] && disk.attr('STORAGE','href') %> - DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %> - ] - <% end %> - <% end %> -<% end %> - -<% if @vm_info['NIC'] %> - <% @vm_info.each('NIC') do |nic| %> - <% if nic['NETWORK'] && nic.attr('NETWORK','href') %> - NIC = [ NETWORK_ID = <%= nic.attr('NETWORK','href').split('/').last %> - <% if nic['IP'] %> - ,IP = <%= nic['IP'] %> - <% end %> - ] - <% end %> - <% end %> -<% end %> - -INSTANCE_TYPE = <%= @vm_info['INSTANCE_TYPE']%> \ No newline at end of file diff --git a/src/cloud/occi/etc/templates/medium.erb b/src/cloud/occi/etc/templates/medium.erb index 074f5d31fd..873a0a3d19 100644 --- a/src/cloud/occi/etc/templates/medium.erb +++ b/src/cloud/occi/etc/templates/medium.erb @@ -1,35 +1,9 @@ # # Virtual Machine Template generated for medium instance types. Adjust this # by setting the desired capacity (CPU,MEMORY) or adding specific -# attributes for your cloud (e.g. OS). You should not need to change the DISK -# and NIC sections +# attributes for your cloud (e.g. OS). # CPU = 4 MEMORY = 4096 -NAME = "<%= @vm_info['NAME'] %>" - -<% if @vm_info['DISK'] %> - <% @vm_info.each('DISK') do |disk| %> - <% if disk['STORAGE'] && disk.attr('STORAGE','href') %> - DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %> - ] - <% end %> - <% end %> -<% end %> - -<% if @vm_info['NIC'] %> - <% @vm_info.each('NIC') do |nic| %> - <% if nic['NETWORK'] && nic.attr('NETWORK','href') %> - NIC = [ NETWORK_ID = <%= nic.attr('NETWORK','href').split('/').last %> - <% if nic['IP'] %> - ,IP = <%= nic['IP'] %> - <% end %> - ] - <% end %> - <% end %> -<% end %> - -INSTANCE_TYPE = <%= @vm_info['INSTANCE_TYPE']%> - diff --git a/src/cloud/occi/etc/templates/small.erb b/src/cloud/occi/etc/templates/small.erb index 65f8100f86..7320831643 100644 --- a/src/cloud/occi/etc/templates/small.erb +++ b/src/cloud/occi/etc/templates/small.erb @@ -1,35 +1,9 @@ # # Virtual Machine Template generated for small instance types. Adjust this # by setting the desired capacity (CPU,MEMORY) or adding specific -# attributes for your cloud (e.g. OS). You should not need to change the DISK -# and NIC sections +# attributes for your cloud (e.g. OS). # CPU = 1 MEMORY = 1024 -NAME = "<%= @vm_info['NAME'] %>" - -<% if @vm_info['DISK'] %> - <% @vm_info.each('DISK') do |disk| %> - <% if disk['STORAGE'] && disk.attr('STORAGE','href') %> - DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %> - ] - <% end %> - <% end %> -<% end %> - -<% if @vm_info['NIC'] %> - <% @vm_info.each('NIC') do |nic| %> - <% if nic['NETWORK'] && nic.attr('NETWORK','href') %> - NIC = [ NETWORK_ID = <%= nic.attr('NETWORK','href').split('/').last %> - <% if nic['IP'] %> - ,IP = <%= nic['IP'] %> - <% end %> - ] - <% end %> - <% end %> -<% end %> - -INSTANCE_TYPE = <%= @vm_info['INSTANCE_TYPE']%> - diff --git a/src/cloud/occi/lib/VirtualMachineOCCI.rb b/src/cloud/occi/lib/VirtualMachineOCCI.rb index 1568f9ea7c..c72c645525 100755 --- a/src/cloud/occi/lib/VirtualMachineOCCI.rb +++ b/src/cloud/occi/lib/VirtualMachineOCCI.rb @@ -27,17 +27,14 @@ class VirtualMachineOCCI < VirtualMachine <%= self['TEMPLATE/INSTANCE_TYPE'] %> <% end %> <%= self.state_str %> - <% if self['TEMPLATE/DISK'] %> - <% self.each('TEMPLATE/DISK') do |disk| %> + <% self.each('TEMPLATE/DISK') do |disk| %> <%= disk['TYPE'] %> <%= disk['TARGET'] %> - <% end %> <% end %> - <% if self['TEMPLATE/NIC'] %> - <% self.each('TEMPLATE/NIC') do |nic| %> + <% self.each('TEMPLATE/NIC') do |nic| %> <% if nic['IP'] %> @@ -47,32 +44,41 @@ class VirtualMachineOCCI < VirtualMachine <%= nic['MAC'] %> <% end %> + <% end %> + <% if self['TEMPLATE/CONTEXT'] %> + + <% self.each('TEMPLATE/CONTEXT/*') do |cont| %> + <% if cont.text %> + <<%= cont.name %>><%= cont.text %>> <% end %> <% end %> + + <% end %> } - + # Class constructor - def initialize(xml, client, xml_info = nil, types=nil, base=nil) + def initialize(xml, client, xml_info=nil, types=nil, base=nil) super(xml, client) @vm_info = nil @template = nil - + @common_template = base + '/common.erb' if base + if xml_info != nil xmldoc = XMLElement.build_xml(xml_info, 'COMPUTE') @vm_info = XMLElement.new(xmldoc) if xmldoc != nil end - + if @vm_info != nil itype = @vm_info['INSTANCE_TYPE'] - + if itype != nil and types[itype] != nil @template = base + "/#{types[itype]['TEMPLATE']}" end end - + end - + def mk_action(action_str) case action_str.downcase when "stopped" @@ -92,31 +98,31 @@ class VirtualMachineOCCI < VirtualMachine error = OpenNebula::Error.new(error_msg) return error end - + return rc end - + def to_one_template() if @vm_info == nil error_msg = "Missing COMPUTE section in the XML body" return OpenNebula::Error.new(error_msg), 400 end - + if @template == nil return OpenNebula::Error.new("Bad instance type"), 500 end - + begin - template = ERB.new(File.read(@template)) - template_text = template.result(binding) + template = ERB.new(File.read(@common_template)).result(binding) + template << ERB.new(File.read(@template)).result(binding) rescue Exception => e error = OpenNebula::Error.new(e.message) return error end - - return template_text + + return template end - + # Creates the VMI representation of a Virtual Machine def to_occi(base_url) begin @@ -127,6 +133,7 @@ class VirtualMachineOCCI < VirtualMachine return error end + return occi_vm_text.gsub(/\n\s*/,'') end end diff --git a/src/cloud/occi/lib/occi-server.rb b/src/cloud/occi/lib/occi-server.rb index daaf85a439..82624fdf94 100755 --- a/src/cloud/occi/lib/occi-server.rb +++ b/src/cloud/occi/lib/occi-server.rb @@ -49,7 +49,12 @@ require 'OpenNebula' include OpenNebula -$occi_server = OCCIServer.new(CONFIGURATION_FILE, TEMPLATE_LOCATION) +begin + $occi_server = OCCIServer.new(CONFIGURATION_FILE, TEMPLATE_LOCATION) +rescue Exception => e + puts "Error starting server: #{e}" + exit(-1) +end if CloudServer.is_port_open?($occi_server.config[:server], $occi_server.config[:port]) diff --git a/src/common/test/action_manager.cc b/src/common/test/action_manager.cc index 134c30e899..87f71017d9 100644 --- a/src/common/test/action_manager.cc +++ b/src/common/test/action_manager.cc @@ -10,6 +10,8 @@ #include #include +#include "test/one_test_common.h" + using namespace std; extern "C" void * addsub_loop(void *arg); @@ -175,9 +177,13 @@ int main(int argc, char ** argv) { CppUnit::TextUi::TestRunner tr; + + SETUP_XML_WRITER(tr, "action_manager.xml"); tr.addTest(ActionManagerTest::suite()); tr.run(); + END_XML_WRITER + return 0; } diff --git a/src/common/test/mem_collector.cc b/src/common/test/mem_collector.cc index 19397c2031..b7fe391738 100644 --- a/src/common/test/mem_collector.cc +++ b/src/common/test/mem_collector.cc @@ -27,6 +27,8 @@ extern "C" #include #include +#include "test/one_test_common.h" + using namespace std; class MemCollectorTest : public CppUnit::TestFixture @@ -110,8 +112,12 @@ int main(int argc, char ** argv) { CppUnit::TextUi::TestRunner tr; + SETUP_XML_WRITER(tr, "mem_collector.xml"); + tr.addTest(MemCollectorTest::suite()); tr.run(); + END_XML_WRITER + return 0; } diff --git a/src/common/test/single_attribute.cc b/src/common/test/single_attribute.cc index cd9462e0d4..6a02e47914 100644 --- a/src/common/test/single_attribute.cc +++ b/src/common/test/single_attribute.cc @@ -9,6 +9,8 @@ #include #include +#include "test/one_test_common.h" + using namespace std; class SingleAttributeTest : public CppUnit::TestFixture @@ -123,9 +125,13 @@ public: int main(int argc, char ** argv) { CppUnit::TextUi::TestRunner tr; + + SETUP_XML_WRITER(tr, "single_attribute.xml"); tr.addTest(SingleAttributeTest::suite()); tr.run(); + END_XML_WRITER + return 0; } diff --git a/src/common/test/vector_attribute.cc b/src/common/test/vector_attribute.cc index 5c6b3d634d..54b18a3a40 100644 --- a/src/common/test/vector_attribute.cc +++ b/src/common/test/vector_attribute.cc @@ -10,6 +10,8 @@ #include #include +#include "test/one_test_common.h" + using namespace std; class VectorAttributeTest : public CppUnit::TestFixture @@ -156,9 +158,13 @@ int main(int argc, char ** argv) { CppUnit::TextUi::TestRunner tr; + + SETUP_XML_WRITER(tr, "vector_attribute.xml"); tr.addTest(VectorAttributeTest::suite()); tr.run(); + END_XML_WRITER + return 0; } diff --git a/src/im_mad/vmware/one_im_vmware b/src/im_mad/im_sh/one_im_sh similarity index 73% rename from src/im_mad/vmware/one_im_vmware rename to src/im_mad/im_sh/one_im_sh index 93ea86abea..f69a206563 100755 --- a/src/im_mad/vmware/one_im_vmware +++ b/src/im_mad/im_sh/one_im_sh @@ -16,16 +16,17 @@ # limitations under the License. # #--------------------------------------------------------------------------- # - #Setup driver variables -DRIVER_NAME="im_vmware" +DRIVER_NAME=`basename $0 | cut -d. -f1` if [ -z "${ONE_LOCATION}" ]; then DRIVERRC=/etc/one/${DRIVER_NAME}/${DRIVER_NAME}rc MADCOMMON=/usr/lib/one/mads/madcommon.sh + VAR_LOCATION=/var/lib/one else DRIVERRC=$ONE_LOCATION/etc/${DRIVER_NAME}/${DRIVER_NAME}rc MADCOMMON=$ONE_LOCATION/lib/mads/madcommon.sh + VAR_LOCATION=$ONE_LOCATION/var fi . $MADCOMMON @@ -34,22 +35,10 @@ fi export_rc_vars $DRIVERRC +# Go to var directory ONE_LOCATION/var or /var/lib/one +cd $VAR_LOCATION + LOG_FILE=$DRIVER_NAME -MAD_FILE="OneImVmware" - -if [ -z "${ONE_LOCATION}" ]; then - MAD_LOG_PATH=/var/log/one/$LOG_FILE.log -else - MAD_LOG_PATH=$ONE_LOCATION/var/$LOG_FILE.log -fi - # Execute the actual MAD -if [ -n "${ONE_MAD_DEBUG}" ]; then - exec nice -n $PRIORITY java -cp $ONE_LOCATION/lib/mads:$CLASSPATH -Ddebug=$ONE_MAD_DEBUG -Djavax.net.ssl.trustStore=$VMWARE_TRUSTORE -Xmx1024M $MAD_FILE $* 2>> $MAD_LOG_PATH -else - exec nice -n $PRIORITY java -cp $ONE_LOCATION/lib/mads:$CLASSPATH -Ddebug=$ONE_MAD_DEBUG -Djavax.net.ssl.trustStore=$VMWARE_TRUSTORE -Xmx1024M $MAD_FILE $* 2> /dev/null -fi - - - +execute_mad $* diff --git a/src/im_mad/im_sh/one_im_sh.rb b/src/im_mad/im_sh/one_im_sh.rb new file mode 100755 index 0000000000..c2ab321cef --- /dev/null +++ b/src/im_mad/im_sh/one_im_sh.rb @@ -0,0 +1,87 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +ONE_LOCATION=ENV["ONE_LOCATION"] + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" + ETC_LOCATION="/etc/one/" + PROBE_LOCATION="/usr/lib/one/im_probes/" + REMOTES_LOCATION="/usr/lib/one/remotes" +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" + ETC_LOCATION=ONE_LOCATION+"/etc/" + PROBE_LOCATION=ONE_LOCATION+"/lib/im_probes/" + REMOTES_LOCATION=ONE_LOCATION+"/lib/remotes/" +end + +$: << RUBY_LIB_LOCATION + +require 'OpenNebulaDriver' +require 'CommandManager' + +#------------------------------------------------------------------------------- +# The Local Information Manager Driver +#------------------------------------------------------------------------------- +class InformationManager < OpenNebulaDriver + + #--------------------------------------------------------------------------- + # Init the driver + #--------------------------------------------------------------------------- + def initialize(hypervisor, num) + super(num, true) + + @config = read_configuration + @hypervisor = hypervisor + + @cmd_path = "#{ENV['ONE_LOCATION']}/lib/remotes/im" + + # register actions + register_action(:MONITOR, method("action_monitor")) + end + + #--------------------------------------------------------------------------- + # Execute the run_probes in the remote host + #--------------------------------------------------------------------------- + def action_monitor(number, host, unused) + log_lambda=lambda do |message| + log(number, message) + end + + cmd_string = "#{@cmd_path}/run_probes #{@hypervisor} #{host}" + monitor_exe = LocalCommand.run(cmd_string, host, log_method(id)) + + if monitor_exe.code == 0 + send_message("MONITOR", RESULT[:success], number, monitor_exe.stdout) + else + send_message("MONITOR", RESULT[:failure], number, + "Could not monitor host #{host}.") + end + end + +end + +#------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- +# Information Manager main program +#------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- + +hypervisor = ARGV[0] +im = InformationManager.new(hypervisor, 15) +im.start_driver diff --git a/src/im_mad/im_ssh/one_im_ssh b/src/im_mad/im_ssh/one_im_ssh index af34f360a1..e00f67f818 100755 --- a/src/im_mad/im_ssh/one_im_ssh +++ b/src/im_mad/im_ssh/one_im_ssh @@ -26,7 +26,7 @@ done shift $(($OPTIND - 1)) #Setup driver variables -DRIVER_NAME=`basename $1 | cut -d. -f1` +DRIVER_NAME=`basename $0 | cut -d. -f1` if [ -z "${ONE_LOCATION}" ]; then DRIVERRC=/etc/one/${DRIVER_NAME}/${DRIVER_NAME}rc diff --git a/src/im_mad/im_ssh/one_im_ssh.rb b/src/im_mad/im_ssh/one_im_ssh.rb index 243df86f1a..0ab0b31794 100755 --- a/src/im_mad/im_ssh/one_im_ssh.rb +++ b/src/im_mad/im_ssh/one_im_ssh.rb @@ -43,11 +43,13 @@ class InformationManager < OpenNebulaDriver #--------------------------------------------------------------------------- # Init the driver #--------------------------------------------------------------------------- - def initialize(remote_dir, hypervisor, num) + def initialize(hypervisor, num) super(num, true) + @config = read_configuration + @hypervisor = hypervisor - @remote_dir = remote_dir + @remote_dir = @config['SCRIPTS_REMOTE_DIR'] || '/tmp/one' # register actions register_action(:MONITOR, method("action_monitor")) @@ -57,18 +59,21 @@ class InformationManager < OpenNebulaDriver # Execute the run_probes in the remote host #--------------------------------------------------------------------------- def action_monitor(number, host, do_update) + log_lambda=lambda do |message| + log(number, message) + end + if do_update == "1" # Use SCP to sync: sync_cmd = "scp -r #{REMOTES_LOCATION}/. #{host}:#{@remote_dir}" - + # Use rsync to sync: # sync_cmd = "rsync -Laz #{REMOTES_LOCATION} #{host}:#{@remote_dir}" - LocalCommand.run(sync_cmd) - else + LocalCommand.run(sync_cmd, log_lambda) end - cmd = SSHCommand.run("#{@remote_dir}/im/run_probes #{@hypervisor}", - host) + cmd_string = "#{@remote_dir}/im/run_probes #{@hypervisor} #{host}" + cmd = SSHCommand.run(cmd_string, host, log_lambda) if cmd.code == 0 send_message("MONITOR", RESULT[:success], number, cmd.stdout) @@ -86,9 +91,6 @@ end #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- -remote_dir = ENV["IM_REMOTE_DIR"] -remote_dir = "/tmp/one" if !remote_dir - hypervisor = ARGV[0]||'' -im = InformationManager.new(remote_dir, hypervisor, 15) +im = InformationManager.new(hypervisor, 15) im.start_driver diff --git a/src/im_mad/remotes/common.d/architecture.sh b/src/im_mad/remotes/kvm.d/architecture.sh similarity index 100% rename from src/im_mad/remotes/common.d/architecture.sh rename to src/im_mad/remotes/kvm.d/architecture.sh diff --git a/src/im_mad/remotes/common.d/cpu.sh b/src/im_mad/remotes/kvm.d/cpu.sh similarity index 100% rename from src/im_mad/remotes/common.d/cpu.sh rename to src/im_mad/remotes/kvm.d/cpu.sh diff --git a/src/im_mad/remotes/kvm.d/kvm.rb b/src/im_mad/remotes/kvm.d/kvm.rb index 0b7c664d7b..eb91910a9f 100755 --- a/src/im_mad/remotes/kvm.d/kvm.rb +++ b/src/im_mad/remotes/kvm.d/kvm.rb @@ -16,15 +16,21 @@ # limitations under the License. # #--------------------------------------------------------------------------- # +def print_info(name, value) + value = "0" if value.nil? or value.to_s.strip.empty? + puts "#{name}=#{value}" +end + ###### # First, get all the posible info out of virsh # TODO : use virsh freecell when available ###### nodeinfo_text = `virsh -c qemu:///system nodeinfo` +exit(-1) if $?!=0 nodeinfo_text.split(/\n/).each{|line| - if line.match('^CPU\(s\)') + if line.match('^CPU\(s\)') $total_cpu = line.split(":")[1].strip.to_i * 100 elsif line.match('^CPU frequency') $cpu_speed = line.split(":")[1].strip.split(" ")[0] @@ -40,10 +46,12 @@ nodeinfo_text.split(/\n/).each{|line| NETINTERFACE = "eth1" top_text=`top -bin2` +exit(-1) if $?!=0 + top_text.gsub!(/^top.*^top.*?$/m, "") # Strip first top output top_text.split(/\n/).each{|line| - if line.match('^Mem') + if line.match('^Mem') line[4..-1].split(",").each{|elemento| temp = elemento.strip.split("k ") if temp[1] == "used" @@ -55,9 +63,9 @@ top_text.split(/\n/).each{|line| line[7..-1].split(",").each{|elemento| temp = elemento.strip.split("%") if temp[1]=="id" - idle = temp[0] - $free_cpu = idle.to_f * $total_cpu.to_f / 100 - $used_cpu = $total_cpu.to_f - $free_cpu + idle = temp[0] + $free_cpu = idle.to_f * $total_cpu.to_f / 100 + $used_cpu = $total_cpu.to_f - $free_cpu break end @@ -68,6 +76,7 @@ top_text.split(/\n/).each{|line| $free_memory=`free -k|grep "buffers\/cache"|awk '{print $4}'` net_text=`cat /proc/net/dev` +exit(-1) if $?!=0 net_text.split(/\n/).each{|line| if line.match("^ *#{NETINTERFACE}") @@ -78,18 +87,18 @@ net_text.split(/\n/).each{|line| end } -puts "HYPERVISOR=kvm" +print_info("HYPERVISOR","kvm") -puts "TOTALCPU=#{$total_cpu}" -puts "CPUSPEED=#{$cpu_speed}" +print_info("TOTALCPU",$total_cpu) +print_info("CPUSPEED",$cpu_speed) -puts "TOTALMEMORY=#{$total_memory}" -puts "USEDMEMORY=#{$used_memory}" -puts "FREEMEMORY=#{$free_memory}" +print_info("TOTALMEMORY",$total_memory) +print_info("USEDMEMORY",$used_memory) +print_info("FREEMEMORY",$free_memory) -puts "FREECPU=#{$free_cpu}" -puts "USEDCPU=#{$used_cpu}" +print_info("FREECPU",$free_cpu) +print_info("USEDCPU",$used_cpu) -puts "NETRX=#{$netrx}" -puts "NETTX=#{$nettx}" +print_info("NETRX",$netrx) +print_info("NETTX",$nettx) diff --git a/src/im_mad/remotes/common.d/name.sh b/src/im_mad/remotes/kvm.d/name.sh similarity index 100% rename from src/im_mad/remotes/common.d/name.sh rename to src/im_mad/remotes/kvm.d/name.sh diff --git a/src/im_mad/remotes/run_probes b/src/im_mad/remotes/run_probes index f92bcd6564..3209b285bc 100755 --- a/src/im_mad/remotes/run_probes +++ b/src/im_mad/remotes/run_probes @@ -17,28 +17,37 @@ #--------------------------------------------------------------------------- # HYPERVISOR_DIR=$1.d +ARGUMENTS=$* SCRIPTS_DIR=`dirname $0` cd $SCRIPTS_DIR - function run_dir { ( - DIR=$1 - cd $DIR + cd $1 for i in `ls *`;do if [ -x "$i" ]; then - ./$i + ./$i $ARGUMENTS + EXIT_CODE=$? + if [ "x$EXIT_CODE" != "x0" ]; then + echo "Error executing $i" 1>&2 + exit $EXIT_CODE + fi fi done ) } data=$( - run_dir 'common.d' if [ -d "$HYPERVISOR_DIR" ]; then - run_dir $HYPERVISOR_DIR + run_dir "$HYPERVISOR_DIR" fi ) +EXIT_CODE=$? + echo $data | tr '\n' ' ' + +if [ "x$EXIT_CODE" != "x0" ]; then + exit $EXIT_CODE +fi diff --git a/src/tm_mad/vmware/tm_vmwarerc b/src/im_mad/remotes/xen.d/architecture.sh old mode 100644 new mode 100755 similarity index 90% rename from src/tm_mad/vmware/tm_vmwarerc rename to src/im_mad/remotes/xen.d/architecture.sh index b35183e2b8..1565665945 --- a/src/tm_mad/vmware/tm_vmwarerc +++ b/src/im_mad/remotes/xen.d/architecture.sh @@ -1,3 +1,5 @@ +#!/bin/sh + # -------------------------------------------------------------------------- # # Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) # # # @@ -14,8 +16,4 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# Uncomment the following line to active MAD debug -#ONE_MAD_DEBUG=1 - -# Local path of the datastore -DATASTORE_PATH=/images/vmware +echo ARCH=`uname -m` diff --git a/src/im_mad/vmware/im_vmwarerc b/src/im_mad/remotes/xen.d/cpu.sh old mode 100644 new mode 100755 similarity index 85% rename from src/im_mad/vmware/im_vmwarerc rename to src/im_mad/remotes/xen.d/cpu.sh index caf3af784f..12bc9bea8e --- a/src/im_mad/vmware/im_vmwarerc +++ b/src/im_mad/remotes/xen.d/cpu.sh @@ -1,3 +1,5 @@ +#!/bin/sh + # -------------------------------------------------------------------------- # # Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) # # # @@ -14,10 +16,10 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# This must point to a java keystore with appropriate certificates for accessing -# all the ESXi hosts -#VMWARE_TRUSTORE= +if [ -f /proc/cpuinfo ]; then -# Uncomment the following line to active MAD debug -#ONE_MAD_DEBUG=1 + echo -n "MODELNAME=\"" + grep -m 1 "model name" /proc/cpuinfo | cut -d: -f2 | sed -e 's/^ *//' | sed -e 's/$/"/' + +fi diff --git a/src/vmm_mad/vmware/vmm_vmwarerc b/src/im_mad/remotes/xen.d/name.sh old mode 100644 new mode 100755 similarity index 79% rename from src/vmm_mad/vmware/vmm_vmwarerc rename to src/im_mad/remotes/xen.d/name.sh index 99efd415cc..90611577a8 --- a/src/vmm_mad/vmware/vmm_vmwarerc +++ b/src/im_mad/remotes/xen.d/name.sh @@ -1,3 +1,5 @@ +#!/bin/sh + # -------------------------------------------------------------------------- # # Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) # # # @@ -14,15 +16,6 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# This must point to a java keystore with appropriate certificates for accessing -# all the ESXi hosts -#VMWARE_TRUSTORE= +echo HOSTNAME=`uname -n` -# Uncomment the following line to active MAD debug -#ONE_MAD_DEBUG=1 -# Datastore name -VMWARE_DATASTORE=datastore1 - -# Datacenter name -VMWARE_DATACENTER=ha-datacenter diff --git a/src/im_mad/remotes/xen.d/xen.rb b/src/im_mad/remotes/xen.d/xen.rb index 7c35f4d870..e4f89ec1ec 100755 --- a/src/im_mad/remotes/xen.d/xen.rb +++ b/src/im_mad/remotes/xen.d/xen.rb @@ -21,8 +21,16 @@ require "pp" XENTOP_PATH="/usr/sbin/xentop" XM_PATH="/usr/sbin/xm" +def print_info(name, value) + value = "0" if value.nil? or value.to_s.strip.empty? + puts "#{name}=#{value}" +end + xentop_text=`sudo #{XENTOP_PATH} -bi2` +exit(-1) if $?!=0 + xm_text=`sudo #{XM_PATH} info` +exit(-1) if $?!=0 xentop_text.gsub!(/^xentop.*^xentop.*?$/m, "") # Strip first top output xentop_text.gsub!("no limit", "no_limit") @@ -85,13 +93,13 @@ domains_info.each {|line| # WRITE INFO -puts "HYPERVISOR=xen" -puts "TOTALCPU=" + cpu_info[:total].round.to_s -puts "CPUSPEED=" + cpu_info[:speed] -puts "TOTALMEMORY=" + memory_info[:total].to_s -puts "FREEMEMORY=" + memory_info[:free].to_s -puts "USEDMEMORY=" + memory_info[:used].to_s -puts "USEDCPU=" + vm_info[:cpu].round.to_s -puts "FREECPU=" + (cpu_info[:total]-vm_info[:cpu]).round.to_s -puts "NETTX=" + vm_info[:nettx].to_s -puts "NETRX=" + vm_info[:netrx].to_s +print_info("HYPERVISOR","xen") +print_info("TOTALCPU",cpu_info[:total].round.to_s) +print_info("CPUSPEED",cpu_info[:speed]) +print_info("TOTALMEMORY",memory_info[:total].to_s) +print_info("FREEMEMORY",memory_info[:free].to_s) +print_info("USEDMEMORY",memory_info[:used].to_s) +print_info("USEDCPU",vm_info[:cpu].round.to_s) +print_info("FREECPU",(cpu_info[:total]-vm_info[:cpu]).round.to_s) +print_info("NETTX",vm_info[:nettx].to_s) +print_info("NETRX",vm_info[:netrx].to_s) diff --git a/src/im_mad/vmware/GetProperty.java b/src/im_mad/vmware/GetProperty.java deleted file mode 100644 index 18da7c4067..0000000000 --- a/src/im_mad/vmware/GetProperty.java +++ /dev/null @@ -1,304 +0,0 @@ -/* -------------------------------------------------------------------------- */ -/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ -/* not use this file except in compliance with the License. You may obtain */ -/* a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -/* See the License for the specific language governing permissions and */ -/* limitations under the License. */ -/* -------------------------------------------------------------------------- */ - - -import com.vmware.vim.*; -import com.vmware.apputils.*; -import com.vmware.apputils.vim.*; - -import java.util.*; -import java.io.*; - -import java.lang.*; - -import java.rmi.RemoteException; - - -/* - * Used to obtain properties from Managed Object Reference from ESXi - */ - -public class GetProperty -{ - String[] args; - String entity; - String entityName; - - // Helpers from VI samples - private static ServiceContent content; - private static AppUtil cb = null; - private static VimPortType service; - private ManagedObjectReference moRef; - - // Measure of the property - private double measure; - - /* - * Gets first property that matches propertyName - * @param moRef, objet to get property from - * @param propertyName, name of the property - * @return representation of the property - */ - Object getObjectProperty(String propertyName) - throws RuntimeFault, RemoteException - { - return getProperties(new String[] { propertyName })[0]; - } - - /* - * Gets properties that matches any of the strings - * @param moRef, objet to get properties from - * @param propertyName, name of the property - * @return representation of the properties - */ - Object[] getProperties(String[] properties) - throws RuntimeFault, RemoteException - { - // PropertySpec specifies what properties to - // retrieve and from type of Managed Object - PropertySpec pSpec = new PropertySpec(); - pSpec.setType(moRef.getType()); - pSpec.setPathSet(properties); - - // ObjectSpec specifies the starting object and - // any TraversalSpecs used to specify other objects - // for consideration - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(moRef); - - // PropertyFilterSpec is used to hold the ObjectSpec and - // PropertySpec for the call - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.setPropSet(new PropertySpec[] {pSpec}); - pfSpec.setObjectSet(new ObjectSpec[] {oSpec}); - - // retrieveProperties() returns the properties - // selected from the PropertyFilterSpec - ObjectContent[] ocs = service.retrieveProperties( - content.getPropertyCollector(), - new PropertyFilterSpec[] {pfSpec}); - - // Return value, one object for each property specified - Object[] ret = new Object[properties.length]; - - if(ocs != null) - { - for(int i=0; i=1) - { - measure = longs[(longs.length-1)]; - return true; - } - } - } - } - } - } - } - } - else - { - return false; - } - } - return false; - } - - - private PerfEntityMetricBase[] getPerfIdsAvailable(PerfQuerySpec[] querySpecs, - ManagedObjectReference entityMoRef) throws Exception - { - PerfEntityMetricBase[] perfEntity = null; - - if (entityMoRef != null) - { - try - { - perfEntity - = cb.getConnection().getService().queryPerf(entityMoRef, querySpecs); - } - catch (Exception e) - { - - } - } - return perfEntity; - } - - public double getMeasure() - { - return measure; - } - - public boolean connect() - { - try - { - cb = AppUtil.initialize("GetProperty", null, args); - cb.connect(); - moRef = cb.getServiceUtil().getDecendentMoRef(null,entity, - entityName); - - com.vmware.apputils.vim.ServiceConnection sc = cb.getConnection(); - content = sc.getServiceContent(); - service = sc.getService(); - return true; - } - catch(Exception e) - { - return false; - } - - } - - public void disconnect() - { - try - { - cb.disConnect(); - } - catch(Exception e){} - } - - GetProperty(String[] arguments, String _entity, String _entityName) - { - args = arguments; - entity = _entity; - entityName = _entityName; - } -} diff --git a/src/im_mad/vmware/OneImVmware.java b/src/im_mad/vmware/OneImVmware.java deleted file mode 100644 index 403c325b7b..0000000000 --- a/src/im_mad/vmware/OneImVmware.java +++ /dev/null @@ -1,321 +0,0 @@ -/* -# -------------------------------------------------------------------------# -# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------# -*/ - - -import java.io.*; -import java.text.*; -import java.util.*; - -import com.vmware.vim.*; -import com.vmware.apputils.*; -import com.vmware.apputils.vim.*; - - -/************************************ - * Monitors physical VMware hosts * - * through the VI API * - ************************************/ -class OneImVmware extends Thread -{ - - private String[] arguments; - - boolean debug; - - PrintStream stdout; - PrintStream stderr; - - // Entry point - main procedure - public static void main(String[] args) - { - boolean debug_flag; - - if (System.getProperty("debug").equals("1")) - { - debug_flag=true; - } - else - { - debug_flag=false; - } - - OneImVmware oiv = new OneImVmware(args,debug_flag); - oiv.loop(); - } - - // Constructor - OneImVmware(String[] args,boolean _debug) - { - debug = _debug; - arguments = args; - - // Get out and err descriptors - stdout = System.out; - stderr = System.err; - - // No VMware library output to standard out - // or err. This will be activated when needed - disable_standard_output(); - disable_standard_error(); - } - - - // Main loop - void loop() - { - String str = null; - String action = null; - String host; - String hid_str = null; - String hostToMonitor; - boolean end = false; - - BufferedReader in = new BufferedReader( - new InputStreamReader(System.in)); - - while (!end) - { - // Read a line a parse it - try - { - str = in.readLine(); - } - catch (IOException e) - { - String message = e.getMessage().replace('\n', ' '); - send_message(action + " FAILURE " + hid_str + " " + message); - send_error (action + " FAILURE " + hid_str + - " Action malformed. Reason: " + message); - } - - String str_split[] = str.split(" ", 4); - action = str_split[0].toUpperCase(); - - // Perform the action - if (action.equals("INIT")) - { - init(); - } - else if (action.equals("FINALIZE")) - { - finalize_mad(); - end = true; - } else if (str_split.length != 3) - { - send_message("FAILURE Unknown command"); - } - else - { - action = str_split[0].toUpperCase(); - hid_str = str_split[1]; - hostToMonitor = str_split[2]; - - if (action.equals("MONITOR")) - { - // Let's gather data from the host - - GetProperty gP; - boolean rf; - String response = "HYPERVISOR=vmware"; - - String[] argsWithHost = - new String[arguments.length+2]; - - for(int i=0;i::iterator it; @@ -189,7 +191,7 @@ int Mad::start() fcntl(nebula_mad_pipe, F_SETFD, FD_CLOEXEC); fcntl(mad_nebula_pipe, F_SETFD, FD_CLOEXEC); - ::write(nebula_mad_pipe, buf, strlen(buf)); + retval = ::write(nebula_mad_pipe, buf, strlen(buf)); do { @@ -289,10 +291,11 @@ int Mad::reload() int status; int rc; pid_t rp; + size_t retval; // Finish the driver - ::write(nebula_mad_pipe, buf, strlen(buf)); + retval = ::write(nebula_mad_pipe, buf, strlen(buf)); close(nebula_mad_pipe); close(mad_nebula_pipe); diff --git a/src/mad/MadManager.cc b/src/mad/MadManager.cc index 862fcc9724..c5b44125c0 100644 --- a/src/mad/MadManager.cc +++ b/src/mad/MadManager.cc @@ -147,6 +147,7 @@ int MadManager::add(Mad *mad) { char buf = 'A'; int rc; + size_t retval; if ( mad == 0 ) { @@ -166,7 +167,7 @@ int MadManager::add(Mad *mad) mads.push_back(mad); - write(pipe_w, &buf, sizeof(char)); + retval = write(pipe_w, &buf, sizeof(char)); unlock(); @@ -215,6 +216,7 @@ void MadManager::listener() int greater; unsigned int i,j; int rc,mrc; + size_t retval; char c; @@ -262,7 +264,7 @@ void MadManager::listener() { if ( fd == pipe_r ) // Driver added, update the fd vector { - read(fd, (void *) &c, sizeof(char)); + retval = read(fd, (void *) &c, sizeof(char)); lock(); diff --git a/src/mad/ruby/ActionManager.rb b/src/mad/ruby/ActionManager.rb index 5b26809802..a7feb2893c 100644 --- a/src/mad/ruby/ActionManager.rb +++ b/src/mad/ruby/ActionManager.rb @@ -177,6 +177,40 @@ class ActionManager private + def read_configuration + one_config=nil + + if ENV['ONE_LOCATION'] + one_config=ENV['ONE_LOCATION']+'/var/config' + else + one_config='/var/log/one/config' + end + + config=Hash.new + cfg='' + + begin + open(one_config) do |file| + cfg=file.read + end + + cfg.split(/\n/).each do |line| + m=line.match(/^([^=]+)=(.*)$/) + + if m + name=m[1].strip.upcase + value=m[2].strip + config[name]=value + end + end + rescue Exception => e + STDERR.puts "Error reading config: #{e.inspect}" + STDERR.flush + end + + config + end + def delete_running_action(action_id) @action_running.delete(action_id) end diff --git a/src/mad/ruby/VirtualMachineDriver.rb b/src/mad/ruby/VirtualMachineDriver.rb index ec42758be4..9c69c4c617 100644 --- a/src/mad/ruby/VirtualMachineDriver.rb +++ b/src/mad/ruby/VirtualMachineDriver.rb @@ -118,6 +118,21 @@ class VirtualMachineDriver < OpenNebulaDriver send_message(ACTION[action],RESULT[result],id) end + + # ------------------------------------------------------------------------- + # Execute a command associated to an action and id on localhost + # ------------------------------------------------------------------------- + def local_action(command, id, action) + command_exe = LocalCommand.run(command) + + if command_exe.code == 0 + result = :success + else + result = :failure + end + + send_message(ACTION[action],RESULT[result],id) + end # ------------------------------------------------------------------------- # Virtual Machine Manager Protocol Actions (generic implementation @@ -168,11 +183,16 @@ private end def get_first_runable - action_index=@action_queue.index do |action| - if action[:args][HOST_ARG] - !@hosts.include? action[:args][HOST_ARG] + action_index=nil + @action_queue.each_with_index do |action, index| + if action[:args][HOST_ARG] + if !@hosts.include?(action[:args][HOST_ARG]) + action_index=index + break + end else - true + action_index=index + break end end diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 82ad1f3b2a..1f3c31f63b 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -64,7 +64,7 @@ void Nebula::start() throw runtime_error("Could not load nebula configuration file."); } - string config_fname = log_location + "config"; + string config_fname = var_location + "config"; ofstream config_file(config_fname.c_str(), ios_base::trunc & ios_base::out); if (config_file.fail() == false) @@ -267,7 +267,7 @@ void Nebula::start() // Close stds, we no longer need them // ----------------------------------------------------------- - fd = open("/dev/null", O_RDWR|O_CREAT); + fd = open("/dev/null", O_RDWR); dup2(fd,0); dup2(fd,1); diff --git a/src/oca/java/build.sh b/src/oca/java/build.sh index 967aa00e3f..f9a15d9a1f 100755 --- a/src/oca/java/build.sh +++ b/src/oca/java/build.sh @@ -25,36 +25,41 @@ BIN_DIR="./bin" JAR_DIR="./jar" LIB_DIR="./lib" EXA_DIR="./share/examples" +TEST_DIR="./test" OCA_JAR=$JAR_DIR"/org.opennebula.client.jar" +JUNIT_JAR="/usr/share/java/junit4.jar" #------------------------------------------------------------------------------- # COMMAND LINE PARSING #------------------------------------------------------------------------------- usage() { echo - echo "Usage: build.sh [-d ] [-h] [-s]" + echo "Usage: build.sh [-d ] [-h] [-s] [-t]" echo echo "-d: build the documentation" echo "-s: compile the examples" echo "-c: clean compilation files" + echo "-t: build the tests" echo "-h: prints this help" } #------------------------------------------------------------------------------- -TEMP_OPT=`getopt -o hsdc -n 'build.sh' -- "$@"` +TEMP_OPT=`getopt -o hsdct -n 'build.sh' -- "$@"` eval set -- "$TEMP_OPT" DO_DOC="no" DO_EXA="no" DO_CLEAN="no" +DO_TESTS="no" while true ; do case "$1" in -h) usage; exit 0;; -d) DO_DOC="yes"; shift ;; -s) DO_EXA="yes"; shift ;; + -t) DO_TESTS="yes"; shift ;; -c) DO_CLEAN="yes"; shift ;; --) shift ; break ;; *) usage; exit 1 ;; @@ -105,12 +110,19 @@ do_examples() javac -d $EXA_DIR -classpath $OCA_JAR:$LIB_DIR `find share/examples -name *.java` } +do_tests() +{ + echo "Compiling OpenNebula Cloud API Tests..." + javac -d $TEST_DIR -classpath $OCA_JAR:$LIB_DIR:$JUNIT_JAR `find $TEST_DIR -name *.java` +} + do_clean() { rm -rf $BIN_DIR > /dev/null 2>&1 mkdir -p $BIN_DIR find share/examples -name '*.class' -delete + find test/ -name '*.class' -delete } if [ "$DO_CLEAN" = "yes" ] ; then @@ -128,3 +140,7 @@ if [ "$DO_EXA" = "yes" ] ; then do_examples fi +if [ "$DO_TESTS" = "yes" ] ; then + do_tests +fi + diff --git a/src/oca/java/src/org/opennebula/client/Client.java b/src/oca/java/src/org/opennebula/client/Client.java index de8b9499a9..13f3b50d9c 100644 --- a/src/oca/java/src/org/opennebula/client/Client.java +++ b/src/oca/java/src/org/opennebula/client/Client.java @@ -23,8 +23,6 @@ import java.net.MalformedURLException; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.apache.xmlrpc.XmlRpcException; import org.apache.xmlrpc.client.XmlRpcClient; diff --git a/src/oca/java/src/org/opennebula/client/PoolElement.java b/src/oca/java/src/org/opennebula/client/PoolElement.java index faf4c3985e..068058b804 100644 --- a/src/oca/java/src/org/opennebula/client/PoolElement.java +++ b/src/oca/java/src/org/opennebula/client/PoolElement.java @@ -73,7 +73,7 @@ public abstract class PoolElement { this.xml = xmlElement; this.client = client; - this.id = Integer.parseInt(xpath("id")); + this.id = Integer.parseInt(xpath("ID")); } /** @@ -109,13 +109,18 @@ public abstract class PoolElement { return Integer.toString(id); } + public int id() + { + return id; + } + /** * Returns the element's name. * @return the element's name. */ public String getName() { - return xpath("name"); + return xpath("NAME"); } /** @@ -124,7 +129,7 @@ public abstract class PoolElement { */ public int state() { - String state = xpath("state"); + String state = xpath("STATE"); return state != null ? Integer.parseInt( state ) : -1; } @@ -145,7 +150,7 @@ public abstract class PoolElement { try { - result = xpath.evaluate(expression.toUpperCase(), xml); + result = xpath.evaluate(expression, xml); } catch (XPathExpressionException e) {} diff --git a/src/oca/java/src/org/opennebula/client/cluster/Cluster.java b/src/oca/java/src/org/opennebula/client/cluster/Cluster.java new file mode 100644 index 0000000000..5122c6cf3b --- /dev/null +++ b/src/oca/java/src/org/opennebula/client/cluster/Cluster.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +package org.opennebula.client.cluster; + +import org.opennebula.client.Client; +import org.opennebula.client.OneResponse; +import org.opennebula.client.PoolElement; +import org.opennebula.client.host.Host; +import org.w3c.dom.Node; + +/** + * This class represents an OpenNebula cluster. + * It also offers static XML-RPC call wrappers. + */ +public class Cluster extends PoolElement +{ + + private static final String METHOD_PREFIX = "cluster."; + private static final String ALLOCATE = METHOD_PREFIX + "allocate"; + private static final String INFO = METHOD_PREFIX + "info"; + private static final String DELETE = METHOD_PREFIX + "delete"; + private static final String ADD = METHOD_PREFIX + "add"; + private static final String REMOVE = METHOD_PREFIX + "remove"; + + + /** + * Creates a new Image representation. + * @param id The image id. + * @param client XML-RPC Client. + */ + public Cluster(int id, Client client) + { + super(id, client); + } + + /** + * @see PoolElement + */ + protected Cluster(Node xmlElement, Client client) + { + super(xmlElement, client); + } + + + // ================================= + // Static XML-RPC methods + // ================================= + + + /** + * Allocates a new Cluster in OpenNebula. + * + * @param client XML-RPC Client. + * @param name Name for the cluster we want to add. + * @return If successful the message contains the associated + * id generated for this Cluster. + */ + public static OneResponse allocate(Client client, String name) + { + return client.call(ALLOCATE, name); + } + + /** + * Retrieves the information of the given Cluster. + * + * @param client XML-RPC Client. + * @param id The cluster id for the cluster to retrieve the information from + * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public static OneResponse info(Client client, int id) + { + return client.call(INFO, id); + } + + /** + * Deletes a cluster from OpenNebula. + * + * @param client XML-RPC Client. + * @param id The cluster id of the target cluster we want to delete. + * @return A encapsulated response. + */ + public static OneResponse delete(Client client, int id) + { + return client.call(DELETE, id); + } + + /** + * Adds a host to a cluster. + * + * @param client XML-RPC Client. + * @param id The cluster id of the cluster where the host will be assigned. + * @param hid The host id (hid) of the host. + * @return If an error occurs the error message contains the reason. + */ + public static OneResponse add(Client client, int id, int hid) + { + return client.call(ADD, hid, id); + } + + /** + * Removes a host from its cluster. + * + * @param client XML-RPC Client. + * @param hid The host id (hid) of the host. + * @return If an error occurs the error message contains the reason. + */ + public static OneResponse remove(Client client, int hid) + { + return client.call(REMOVE, hid); + } + + + // ================================= + // Instanced object XML-RPC methods + // ================================= + + + /** + * Retrieves the information of the Cluster. + * + * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public OneResponse info() + { + OneResponse response = info(client, id); + super.processInfo(response); + return response; + } + + /** + * Deletes the cluster from OpenNebula. + * + * @return A encapsulated response. + */ + public OneResponse delete() + { + return delete(client, id); + } + + /** + * Adds a host to the cluster. + * + * @param hid The host id (hid) of the host. + * @return If an error occurs the error message contains the reason. + */ + public OneResponse add(int hid) + { + return add(client, id, hid); + } + + /** + * Adds a host to the cluster. + * + * @param host The Host to add. + * @return If an error occurs the error message contains the reason. + */ + public OneResponse add(Host host) + { + return add(client, id, host.id()); + } + + /** + * Removes a host from its cluster. + * + * @param hid The host id (hid) of the host. + * @return If an error occurs the error message contains the reason. + */ + public OneResponse remove(int hid) + { + return remove(client, hid); + } + + /** + * Removes a host from its cluster. + * + * @param host The Host to remove. + * @return If an error occurs the error message contains the reason. + */ + public OneResponse remove(Host host) + { + return remove(client, host.id()); + } +} diff --git a/src/oca/java/src/org/opennebula/client/cluster/ClusterPool.java b/src/oca/java/src/org/opennebula/client/cluster/ClusterPool.java new file mode 100644 index 0000000000..7dfe1bd4a3 --- /dev/null +++ b/src/oca/java/src/org/opennebula/client/cluster/ClusterPool.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +package org.opennebula.client.cluster; + +import java.util.AbstractList; +import java.util.Iterator; + +import org.opennebula.client.Client; +import org.opennebula.client.OneResponse; +import org.opennebula.client.Pool; +import org.opennebula.client.PoolElement; +import org.w3c.dom.Node; + +/** + * This class represents an OpenNebula Cluster pool. + * It also offers static XML-RPC call wrappers. + */ +public class ClusterPool extends Pool implements Iterable +{ + private static final String ELEMENT_NAME = "CLUSTER"; + private static final String INFO_METHOD = "clusterpool.info"; + + /** + * Creates a new Image pool + * + * @param client XML-RPC Client. + */ + public ClusterPool(Client client) + { + super(ELEMENT_NAME, client); + } + + /* (non-Javadoc) + * @see org.opennebula.client.Pool#factory(org.w3c.dom.Node) + */ + @Override + public PoolElement factory(Node node) + { + return new Cluster(node, client); + } + + /** + * Returns the Cluster pool information. + * + * @param client XML-RPC Client. + * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public static OneResponse info(Client client) + { + return client.call(INFO_METHOD); + } + + /** + * Loads the xml representation of the Cluster pool. + * + * @see ClusterPool#info(Client) + */ + public OneResponse info() + { + OneResponse response = info(client); + super.processInfo(response); + return response; + } + + public Iterator iterator() + { + AbstractList ab = new AbstractList() + { + public int size() + { + return getLength(); + } + + public Cluster get(int index) + { + return (Cluster) item(index); + } + }; + + return ab.iterator(); + } +} diff --git a/src/oca/java/src/org/opennebula/client/host/Host.java b/src/oca/java/src/org/opennebula/client/host/Host.java index beaf9eb567..3fc51ee70c 100644 --- a/src/oca/java/src/org/opennebula/client/host/Host.java +++ b/src/oca/java/src/org/opennebula/client/host/Host.java @@ -161,6 +161,26 @@ public class Host extends PoolElement{ return enable(client, id, enable); } + /** + * Enables the host. + * + * @return A encapsulated response. + */ + public OneResponse enable() + { + return enable(true); + } + + /** + * Disables the host + * + * @return A encapsulated response. + */ + public OneResponse disable() + { + return enable(false); + } + // ================================= // Helpers // ================================= @@ -197,4 +217,24 @@ public class Host extends PoolElement{ else return "on"; } + + /** + * Returns true if the host is enabled. + * + * @return True if the host is enabled. + */ + public boolean isEnabled() + { + return state() != 4; + } + + /** + * Returns the name of the cluster this host is assigned to. + * + * @return The name of the cluster this host is assigned to. + */ + public String getCluster() + { + return xpath("CLUSTER"); + } } diff --git a/src/oca/java/src/org/opennebula/client/image/Image.java b/src/oca/java/src/org/opennebula/client/image/Image.java new file mode 100644 index 0000000000..aa0014cb1f --- /dev/null +++ b/src/oca/java/src/org/opennebula/client/image/Image.java @@ -0,0 +1,362 @@ +/******************************************************************************* + * Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +package org.opennebula.client.image; + +import org.opennebula.client.Client; +import org.opennebula.client.OneResponse; +import org.opennebula.client.PoolElement; +import org.w3c.dom.Node; + +/** + * This class represents an OpenNebula image. + * It also offers static XML-RPC call wrappers. + */ +public class Image extends PoolElement +{ + + private static final String METHOD_PREFIX = "image."; + private static final String ALLOCATE = METHOD_PREFIX + "allocate"; + private static final String INFO = METHOD_PREFIX + "info"; + private static final String DELETE = METHOD_PREFIX + "delete"; + private static final String UPDATE = METHOD_PREFIX + "update"; + private static final String RMATTR = METHOD_PREFIX + "rmattr"; + private static final String ENABLE = METHOD_PREFIX + "enable"; + private static final String PUBLISH = METHOD_PREFIX + "publish"; + + private static final String[] IMAGE_STATES = + {"INIT", "READY", "USED", "DISABLED"}; + + private static final String[] SHORT_IMAGE_STATES = + {"init", "rdy", "used", "disa"}; + + private static final String[] IMAGE_TYPES = + {"OS", "CDROM", "DATABLOCK"}; + + private static final String[] SHORT_IMAGE_TYPES = + {"OS", "CD", "DB"}; + + /** + * Creates a new Image representation. + * @param id The image id. + * @param client XML-RPC Client. + */ + public Image(int id, Client client) + { + super(id, client); + } + + /** + * @see PoolElement + */ + protected Image(Node xmlElement, Client client) + { + super(xmlElement, client); + } + + // ================================= + // Static XML-RPC methods + // ================================= + + + /** + * Allocates a new Image in OpenNebula. + * + * @param client XML-RPC Client. + * @param description A string containing the template of the image. + * @return If successful the message contains the associated + * id generated for this Image. + */ + public static OneResponse allocate(Client client, String description) + { + return client.call(ALLOCATE, description); + } + + /** + * Retrieves the information of the given Image. + * + * @param client XML-RPC Client. + * @param id The image id for the image to retrieve the information from + * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public static OneResponse info(Client client, int id) + { + return client.call(INFO, id); + } + + /** + * Deletes an image from OpenNebula. + * + * @param client XML-RPC Client. + * @param id The image id of the target image we want to delete. + * @return A encapsulated response. + */ + public static OneResponse delete(Client client, int id) + { + return client.call(DELETE, id); + } + + /** + * Modifies an image attribute. + * + * @param client XML-RPC Client. + * @param id The image id of the target image we want to modify. + * @param att_name The name of the attribute to update. + * @param att_val The new value for the attribute. + * @return If successful the message contains the image id. + */ + public static OneResponse update(Client client, int id, + String att_name, String att_val) + { + return client.call(UPDATE, id, att_name, att_val); + } + + /** + * Removes an image attribute. + * + * @param client XML-RPC Client. + * @param id The image id of the target image we want to modify. + * @param att_name The name of the attribute to remove. + * @return If successful the message contains the image id. + */ + public static OneResponse rmattr(Client client, int id, String att_name) + { + return client.call(RMATTR, id, att_name); + } + + /** + * Enables or disables an image. + * + * @param client XML-RPC Client. + * @param id The image id of the target image we want to modify. + * @param enable True for enabling, false for disabling. + * @return If successful the message contains the image id. + */ + public static OneResponse enable(Client client, int id, boolean enable) + { + return client.call(ENABLE, id, enable); + } + + /** + * Publishes or unpublishes an image. + * + * @param client XML-RPC Client. + * @param id The image id of the target image we want to modify. + * @param publish True for publishing, false for unpublishing. + * @return If successful the message contains the image id. + */ + public static OneResponse publish(Client client, int id, boolean publish) + { + return client.call(PUBLISH, id, publish); + } + + + // ================================= + // Instanced object XML-RPC methods + // ================================= + + /** + * Retrieves the information of the Image. + * + * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public OneResponse info() + { + OneResponse response = info(client, id); + super.processInfo(response); + return response; + } + + /** + * Deletes the image from OpenNebula. + * + * @return A encapsulated response. + */ + public OneResponse delete() + { + return delete(client, id); + } + + /** + * Modifies an image attribute. + * + * @param att_name The name of the attribute to update. + * @param att_val The new value for the attribute. + * @return If successful the message contains the image id. + */ + public OneResponse update(String att_name, String att_val) + { + return update(client, id, att_name, att_val); + } + + /** + * Removes an image attribute. + * + * @param att_name The name of the attribute to remove. + * @return If successful the message contains the image id. + */ + public OneResponse rmattr(String att_name) + { + return rmattr(client, id, att_name); + } + + /** + * Enables or disables the image. + * + * @param enable True for enabling, false for disabling. + * @return If successful the message contains the image id. + */ + public OneResponse enable(boolean enable) + { + return enable(client, id, enable); + } + + /** + * Enables the image. + * + * @return If successful the message contains the image id. + */ + public OneResponse enable() + { + return enable(true); + } + + /** + * Disables the image. + * + * @return If successful the message contains the image id. + */ + public OneResponse disable() + { + return enable(false); + } + + /** + * Publishes or unpublishes the image. + * + * @param publish True for publishing, false for unpublishing. + * @return If successful the message contains the image id. + */ + public OneResponse publish(boolean publish) + { + return publish(client, id, publish); + } + + /** + * Publishes the image. + * + * @return If successful the message contains the image id. + */ + public OneResponse publish() + { + return publish(true); + } + + /** + * Unpublishes the image. + * + * @return If successful the message contains the image id. + */ + public OneResponse unpublish() + { + return publish(false); + } + + // ================================= + // Helpers + // ================================= + + /** + * Returns the state of the Image. + *
+ * The method {@link Image#info()} must be called before. + * + * @return The state of the Image. + */ + public String stateString() + { + int state = state(); + return state != -1 ? IMAGE_STATES[state] : null; + } + + /** + * Returns the short length string state of the Image. + *
+ * The method {@link Image#info()} must be called before. + * + * @return The short length string state of the Image. + */ + public String shortStateStr() + { + int state = state(); + return state != -1 ? SHORT_IMAGE_STATES[state] : null; + } + + /** + * Returns the type of the Image. + * + * @return The type of the Image. + */ + public int type() + { + String state = xpath("TYPE"); + return state != null ? Integer.parseInt( state ) : -1; + } + + /** + * Returns the type of the Image as a String. + * + * @return The type of the Image as a String. + */ + public String typeStr() + { + int type = type(); + return type != -1 ? IMAGE_TYPES[type] : null; + } + + /** + * Returns the type of the Image as a short String. + * + * @return The type of the Image as a short String. + */ + public String shortTypeStr() + { + int type = type(); + return type != -1 ? SHORT_IMAGE_TYPES[type] : null; + } + + /** + * Returns true if the image is enabled. + * + * @return True if the image is enabled. + */ + public boolean isEnabled() + { + return state() != 3; + } + + /** + * Returns true if the image is public. + * + * @return True if the image is public. + */ + public boolean isPublic() + { + String isPub = xpath("PUBLIC"); + return isPub != null && isPub.equals("1"); + } +} diff --git a/src/oca/java/src/org/opennebula/client/image/ImagePool.java b/src/oca/java/src/org/opennebula/client/image/ImagePool.java new file mode 100644 index 0000000000..3ca79680a5 --- /dev/null +++ b/src/oca/java/src/org/opennebula/client/image/ImagePool.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +package org.opennebula.client.image; + +import java.util.AbstractList; +import java.util.Iterator; + +import org.opennebula.client.Client; +import org.opennebula.client.OneResponse; +import org.opennebula.client.Pool; +import org.opennebula.client.PoolElement; +import org.opennebula.client.vm.VirtualMachinePool; +import org.w3c.dom.Node; + +/** + * This class represents an OpenNebula Image pool. + * It also offers static XML-RPC call wrappers. + */ +public class ImagePool extends Pool implements Iterable +{ + private static final String ELEMENT_NAME = "IMAGE"; + private static final String INFO_METHOD = "imagepool.info"; + + private int filter; + + /** + * Creates a new Image pool with the default filter flag value + * set to 0 (Images belonging to user with UID 0) + * + * @param client XML-RPC Client. + * + * @see VirtualMachinePool#VirtualMachinePool(Client, int) + */ + public ImagePool(Client client) + { + super(ELEMENT_NAME, client); + this.filter = 0; + } + + /** + * Creates a new Image pool. + * + * @param client XML-RPC Client. + * @param filter Filter flag used by default in the method + * {@link ImagePool#info()}. Possible values: + *
    + *
  • <= -2: All Images
  • + *
  • -1: Connected user's Images
  • + *
  • >= 0: UID User's VMs
  • + *
+ */ + public ImagePool(Client client, int filter) + { + super(ELEMENT_NAME, client); + this.filter = filter; + } + + /* (non-Javadoc) + * @see org.opennebula.client.Pool#factory(org.w3c.dom.Node) + */ + @Override + public PoolElement factory(Node node) + { + return new Image(node, client); + } + + /** + * Retrieves all or part of the images in the pool. + * + * @param client XML-RPC Client. + * @param filter Filter flag used by default in the method + * {@link ImagePool#info()}. Possible values: + *
    + *
  • <= -2: All Images
  • + *
  • -1: Connected user's Images
  • + *
  • >= 0: UID User's VMs
  • + *
+ * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public static OneResponse info(Client client, int filter) + { + return client.call(INFO_METHOD, filter); + } + + /** + * Loads the xml representation of all or part of the + * Images in the pool. The filter used is the one set in + * the constructor. + * + * @see ImagePool#info(Client, int) + * + * @return If successful the message contains the string + * with the information returned by OpenNebula. + */ + public OneResponse info() + { + OneResponse response = info(client, filter); + super.processInfo(response); + return response; + } + + public Iterator iterator() + { + AbstractList ab = new AbstractList() + { + public int size() + { + return getLength(); + } + + public Image get(int index) + { + return (Image) item(index); + } + }; + + return ab.iterator(); + } +} diff --git a/src/oca/java/src/org/opennebula/client/user/User.java b/src/oca/java/src/org/opennebula/client/user/User.java index 931e35becb..eb9d5ceb06 100644 --- a/src/oca/java/src/org/opennebula/client/user/User.java +++ b/src/oca/java/src/org/opennebula/client/user/User.java @@ -31,6 +31,7 @@ public class User extends PoolElement{ private static final String ALLOCATE = METHOD_PREFIX + "allocate"; private static final String INFO = METHOD_PREFIX + "info"; private static final String DELETE = METHOD_PREFIX + "delete"; + private static final String PASSWD = METHOD_PREFIX + "passwd"; /** * Creates a new User representation. @@ -76,15 +77,15 @@ public class User extends PoolElement{ * * @param client XML-RPC Client. * @param id The user id (uid) for the user to - * retrieve the information from. + * retrieve the information from. * @return if successful the message contains the - * string with the information about the user returned by OpenNebula. + * string with the information about the user returned by OpenNebula. */ public static OneResponse info(Client client, int id) { return client.call(INFO, id); } - + /** * Deletes a user from OpenNebula. * @@ -97,10 +98,23 @@ public class User extends PoolElement{ return client.call(DELETE, id); } + /** + * Changes the password for the given user. + * + * @param client XML-RPC Client. + * @param id The user id (uid) of the target user we want to modify. + * @param password The new password. + * @return If an error occurs the error message contains the reason. + */ + public static OneResponse passwd(Client client, int id, String password) + { + return client.call(PASSWD, id, password); + } + // ================================= // Instanced object XML-RPC methods // ================================= - + /** * Loads the xml representation of the user. * The info is also stored internally. @@ -110,7 +124,6 @@ public class User extends PoolElement{ public OneResponse info() { OneResponse response = info(client, id); - super.processInfo(response); return response; @@ -125,4 +138,30 @@ public class User extends PoolElement{ { return delete(client, id); } + + /** + * Changes the password for the user. + * + * @param password The new password. + * @return If an error occurs the error message contains the reason. + */ + public OneResponse passwd(String password) + { + return passwd(client, id, password); + } + + // ================================= + // Helpers + // ================================= + + /** + * Returns true if the user is enabled. + * + * @return True if the user is enabled. + */ + public boolean isEnabled() + { + String enabled = xpath("ENABLED"); + return enabled != null && enabled.equals("1"); + } } 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 7e92fa1a2c..08cbf3e692 100644 --- a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java +++ b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java @@ -33,6 +33,7 @@ public class VirtualMachine extends PoolElement{ private static final String DEPLOY = METHOD_PREFIX + "deploy"; private static final String ACTION = METHOD_PREFIX + "action"; private static final String MIGRATE = METHOD_PREFIX + "migrate"; + private static final String SAVEDISK = METHOD_PREFIX + "savedisk"; private static final String[] VM_STATES = { @@ -216,6 +217,18 @@ public class VirtualMachine extends PoolElement{ return client.call(MIGRATE, id, hostId, live); } + /** + * Sets the specified vm's disk to be saved in a new image when the + * VirtualMachine shutdowns. + * + * @param diskId ID of the disk to be saved. + * @param imageId ID of the image where the disk will be saved. + * @return If an error occurs the error message contains the reason. + */ + public OneResponse savedisk(int diskId, int imageId) + { + return client.call(SAVEDISK, diskId, imageId); + } // ================================= // Helpers @@ -391,4 +404,5 @@ public class VirtualMachine extends PoolElement{ } return shortStateStr; } + } diff --git a/src/oca/java/src/org/opennebula/client/vnet/VirtualNetwork.java b/src/oca/java/src/org/opennebula/client/vnet/VirtualNetwork.java index 3fcc3f9d0b..b01c781015 100644 --- a/src/oca/java/src/org/opennebula/client/vnet/VirtualNetwork.java +++ b/src/oca/java/src/org/opennebula/client/vnet/VirtualNetwork.java @@ -31,6 +31,7 @@ public class VirtualNetwork extends PoolElement{ private static final String ALLOCATE = METHOD_PREFIX + "allocate"; private static final String INFO = METHOD_PREFIX + "info"; private static final String DELETE = METHOD_PREFIX + "delete"; + private static final String PUBLISH = METHOD_PREFIX + "publish"; /** @@ -96,6 +97,18 @@ public class VirtualNetwork extends PoolElement{ return client.call(DELETE, id); } + /** + * Publishes or unpublishes a virtual network. + * + * @param client XML-RPC Client. + * @param id The virtual network id (nid) of the target network. + * @param publish True for publishing, false for unpublishing. + * @return If successful the message contains the image id. + */ + public static OneResponse publish(Client client, int id, boolean publish) + { + return client.call(PUBLISH, id, publish); + } // ================================= // Instanced object XML-RPC methods @@ -123,4 +136,50 @@ public class VirtualNetwork extends PoolElement{ { return delete(client, id); } + + /** + * Publishes or unpublishes the virtual network. + * + * @param publish True for publishing, false for unpublishing. + * @return If successful the message contains the image id. + */ + public OneResponse publish(boolean publish) + { + return publish(client, id, publish); + } + + /** + * Publishes the virtual network. + * + * @return If successful the message contains the image id. + */ + public OneResponse publish() + { + return publish(true); + } + + /** + * Unpublishes the virtual network. + * + * @return If successful the message contains the image id. + */ + public OneResponse unpublish() + { + return publish(false); + } + + // ================================= + // Helpers + // ================================= + + /** + * Returns true if the Virtual Network is public. + * + * @return True if the Virtual Network is public. + */ + public boolean isPublic() + { + String isPub = xpath("PUBLIC"); + return isPub != null && isPub.equals("1"); + } } diff --git a/src/oca/java/test/ClusterTest.java b/src/oca/java/test/ClusterTest.java new file mode 100644 index 0000000000..de51e007b8 --- /dev/null +++ b/src/oca/java/test/ClusterTest.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.opennebula.client.Client; +import org.opennebula.client.OneResponse; +import org.opennebula.client.cluster.Cluster; +import org.opennebula.client.cluster.ClusterPool; +import org.opennebula.client.host.Host; + + +public class ClusterTest +{ + + private static Cluster cluster; + private static ClusterPool clusterPool; + + private static Host host; + + private static Client client; + + private static OneResponse res; + private static String name = "new_test_cluster"; + private static int hid = -1; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + client = new Client(); + clusterPool = new ClusterPool(client); + + res = Host.allocate(client, "new_test_host", + "im_dummy", "vmm_dummy", "tm_dummy"); + try{ + hid = Integer.parseInt( res.getMessage() ); + }catch(NumberFormatException e) + { + System.err.println("Test initilization failed (setUpBeforeClass)."); + } + host = new Host(hid, client); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception + { + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + res = Cluster.allocate(client, name); + + int clid = Integer.parseInt(res.getMessage()); + cluster = new Cluster(clid, client); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + cluster.delete(); + } + + @Test + public void allocate() + { + String allocate_name = "allocation_test"; + res = Cluster.allocate(client, allocate_name); + assertTrue( !res.isError() ); + + clusterPool.info(); + + boolean found = false; + for(Cluster c : clusterPool) + { + found = found || c.getName().equals(allocate_name); + } + + assertTrue( found ); + } + + @Test + public void update() + { + res = cluster.info(); + assertTrue( !res.isError() ); + +// assertTrue( cluster.getId().equals("1") ); +// assertTrue( cluster.id() == 1 ); + assertTrue( cluster.getName().equals(name) ); + } + + @Test + public void addHost() + { + res = cluster.add(hid); + assertTrue( !res.isError() ); + + res = host.info(); + assertTrue( !res.isError() ); + assertTrue( host.getCluster().equals(name) ); + } + + @Test + public void removeHost() + { + assertTrue( hid > -1 ); + + res = cluster.remove(hid); + assertTrue( !res.isError() ); + + res = host.info(); + assertTrue( !res.isError() ); + + assertTrue( host.getCluster().equals("default") ); + } + + @Test + public void attributes() + { + res = cluster.info(); + assertTrue( !res.isError() ); + +// assertTrue( cluster.xpath("ID").equals("1") ); + assertTrue( cluster.xpath("NAME").equals(name) ); + } + + @Test + public void delete() + { + res = cluster.delete(); + assertTrue( !res.isError() ); + + res = cluster.info(); + assertTrue( res.isError() ); + } +} diff --git a/src/oca/java/test/HostTest.java b/src/oca/java/test/HostTest.java new file mode 100644 index 0000000000..22278c7dd9 --- /dev/null +++ b/src/oca/java/test/HostTest.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.opennebula.client.Client; +import org.opennebula.client.OneResponse; +import org.opennebula.client.host.Host; +import org.opennebula.client.host.HostPool; +import org.w3c.dom.Node; + +public class HostTest +{ + class HostXML extends Host + { + public HostXML(Node node, Client client){ super(node, client); } + } + + private static Host host; + private static HostPool hostPool; + private static Client client; + private OneResponse res; + private static String name = "new_test_host"; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + client = new Client(); + hostPool = new HostPool(client); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception + { + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + res = Host.allocate(client, name, "im_dummy", "vmm_dummy", "tm_dummy"); + + int hid = !res.isError() ? Integer.parseInt(res.getMessage()) : -1; + host = new Host(hid, client); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + host.delete(); + } + + @Test + public void allocate() + { + String name = "allocate_test"; + + res = Host.allocate(client, name, "im_dummy", "vmm_dummy", "tm_dummy"); + assertTrue( !res.isError() ); +// assertTrue( res.getMessage().equals("0") ); + + hostPool.info(); + + boolean found = false; + for(Host h : hostPool) + { + found = found || h.getName().equals(name); + } + + assertTrue( found ); + } + + @Test + public void update() + { + res = host.info(); + assertTrue( !res.isError() ); + +// assertTrue( host.getId().equals("0") ); + assertTrue( host.id() >= 0 ); + + assertTrue( host.shortStateStr().equals("on") ); + } + + @Test + public void enable() + { + res = host.enable(); + assertTrue( !res.isError() ); + + host.info(); + assertTrue( host.isEnabled() ); + } + + @Test + public void disable() + { + res = host.disable(); + assertTrue( !res.isError() ); + + host.info(); + assertTrue( !host.isEnabled() ); + } + + @Test + public void delete() + { + String name = host.getName(); + + res = host.delete(); + assertTrue( !res.isError() ); + + res = host.info(); + assertTrue( res.isError() ); + + res = hostPool.info(); + assertTrue( !res.isError() ); + + boolean found = false; + for(Host h : hostPool) + { + found = found || h.getName().equals(name); + } + + assertTrue( !found ); + } +/* + @Test + public void attributes() + { + DocumentBuilder builder; + Document doc; + Element xml; + + try + { + builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + + doc = builder.parse( new File("./fixtures/host.xml") ); + xml = doc.getDocumentElement(); + + host = new HostXML(xml, client); + + assertTrue( host.xpath("ID").equals("7") ); + assertTrue( host.xpath("NAME").equals("dummyhost") ); + assertTrue( host.xpath("STATE").equals("2") ); + assertTrue( host.xpath("IM_MAD").equals("im_dummy") ); + assertTrue( host.xpath("LAST_MON_TIME").equals("1277733596") ); + assertTrue( host.xpath("HOST_SHARE/MEM_USAGE").equals("1572864") ); + assertTrue( host.xpath("HOST_SHARE/CPU_USAGE").equals("300") ); + assertTrue( host.xpath("HOST_SHARE/FREE_CPU").equals("800") ); + assertTrue( host.xpath("HOST_SHARE/RUNNING_VMS").equals("3") ); + assertTrue( host.xpath("TEMPLATE/CPUSPEED").equals("2.2GHz") ); + assertTrue( host.xpath("TEMPLATE/HYPERVISOR").equals("dummy") ); + assertTrue( host.xpath("TEMPLATE/TOTALMEMORY").equals("16777216") ); + + } catch (Exception e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +*/ +} diff --git a/src/oca/java/test/ImageTest.java b/src/oca/java/test/ImageTest.java new file mode 100644 index 0000000000..883388a55f --- /dev/null +++ b/src/oca/java/test/ImageTest.java @@ -0,0 +1,209 @@ +/******************************************************************************* + * Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.opennebula.client.Client; +import org.opennebula.client.OneResponse; +import org.opennebula.client.image.*; + + + +public class ImageTest +{ + + private static Image image; + private static ImagePool imagePool; + + private static Client client; + + private static OneResponse res; + private static String name = "new_test_img"; + + + private static String template = + "NAME = \"" + name + "\"\n" + + "ATT1 = \"val1\""; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + client = new Client(); + imagePool = new ImagePool(client); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception + { + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + res = Image.allocate(client, template); + + int imgid = res.isError() ? -1 : Integer.parseInt(res.getMessage()); + image = new Image(imgid, client); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + image.delete(); + } + + @Test + public void allocate() + { + image.delete(); + + res = Image.allocate(client, template); + assertTrue( !res.isError() ); + + int imgid = res.isError() ? -1 : Integer.parseInt(res.getMessage()); + image = new Image(imgid, client); + + + imagePool.info(); + + boolean found = false; + for(Image img : imagePool) + { + found = found || img.getName().equals(name); + } + + assertTrue( found ); + } + + @Test + public void info() + { + res = image.info(); + assertTrue( !res.isError() ); + +// assertTrue( image.getId().equals("0") ); +// assertTrue( image.id() == 0 ); + assertTrue( image.getName().equals(name) ); + } + + @Test + public void update() + { + // Update an existing att. + res = image.update("ATT1", "new_val_1"); + assertTrue( !res.isError() ); + + res = image.info(); + assertTrue( !res.isError() ); + assertTrue( image.xpath("TEMPLATE/ATT1").equals("new_val_1") ); + + // Create a new att. + res = image.update("ATT2", "new_val_2"); + assertTrue( !res.isError() ); + + res = image.info(); + assertTrue( !res.isError() ); + assertTrue( image.xpath("TEMPLATE/ATT2").equals("new_val_2") ); + } + + @Test + public void rmattr() + { + res = image.rmattr("ATT1"); + assertTrue( !res.isError() ); + + res = image.info(); + assertTrue( !res.isError() ); + + assertTrue( image.xpath("ATT1").equals("") ); + } + + @Test + public void enable() + { + res = image.enable(); + assertTrue( !res.isError() ); + + image.info(); + assertTrue( image.isEnabled() ); + } + + @Test + public void disable() + { + res = image.disable(); + assertTrue( !res.isError() ); + + image.info(); + assertTrue( !image.isEnabled() ); + } + + @Test + public void publish() + { + res = image.publish(); + assertTrue( !res.isError() ); + + image.info(); + assertTrue( image.isPublic() ); + } + + @Test + public void unpublish() + { + res = image.unpublish(); + assertTrue( !res.isError() ); + + image.info(); + assertTrue( !image.isPublic() ); + } + + @Test + public void attributes() + { + res = image.info(); + assertTrue( !res.isError() ); + +// assertTrue( image.xpath("ID").equals("0") ); + assertTrue( image.xpath("NAME").equals(name) ); + } + +// @Test + public void delete() + { + res = image.delete(); + assertTrue( !res.isError() ); + + res = image.info(); + assertTrue( res.isError() ); + } +} diff --git a/src/oca/java/test/SessionTest.java b/src/oca/java/test/SessionTest.java new file mode 100644 index 0000000000..d5f9d5b72f --- /dev/null +++ b/src/oca/java/test/SessionTest.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import org.junit.Test; +import org.opennebula.client.Client; + +public class SessionTest { + + @Test + public void createSession() + { + Client oneClient = null; + try + { + oneClient = new Client(); + } + catch (Exception e) + { + System.out.println(e.getMessage()); + } + + assertNotNull(oneClient); + } + + @Test + public void wrong_token() + { + Client oneClient = null; + + try + { + // The secret string should be user:password. The url is null, so it + // will be set to default. + oneClient = new Client("wrong_password_token",null); + } + catch (Exception e) + { +// System.out.println(e.getMessage()); + } + + assertNull("Client should complain about the wrong token", oneClient); + } + + @Test + public void wrong_url() + { + Client oneClient = null; + try + { + // The HTTP is misspelled + oneClient = new Client(null,"HTP://localhost:2633/RPC2"); + } + catch (Exception e) + { +// System.out.println(e.getMessage()); + } + + assertNull("Client should complain about misspelled url", oneClient); + } +} diff --git a/src/oca/java/test/UserTest.java b/src/oca/java/test/UserTest.java new file mode 100644 index 0000000000..c47230c17a --- /dev/null +++ b/src/oca/java/test/UserTest.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.opennebula.client.Client; +import org.opennebula.client.OneResponse; +import org.opennebula.client.user.User; +import org.opennebula.client.user.UserPool; + +public class UserTest +{ + + private static User user; + private static UserPool userPool; + + private static Client client; + + private static OneResponse res; + private static String name = "new_test_user"; + private static String password = "new_test_password"; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + client = new Client(); + userPool = new UserPool(client); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception + { + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + res = User.allocate(client, name, password); + + int uid = res.isError() ? -1 : Integer.parseInt(res.getMessage()); + user = new User(uid, client); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + user.delete(); + } + + + @Test + public void allocate() + { + userPool.info(); + + boolean found = false; + for(User u : userPool) + { + found = found || u.getName().equals(name); + } + + assertTrue( found ); + } + + @Test + public void update() + { + res = user.info(); + assertTrue( res.getErrorMessage(), !res.isError() ); + + assertTrue( user.id() >= 0 ); + assertTrue( user.getName().equals(name) ); + } + + @Test + public void attributes() + { + res = user.info(); + assertTrue( res.getErrorMessage(), !res.isError() ); + + assertTrue( user.xpath("NAME").equals(name) ); + assertTrue( user.xpath("ENABLED").equals("1") ); + } + + @Test + public void delete() + { + res = user.info(); + assertTrue( res.getErrorMessage(), !res.isError() ); + assertTrue( user.isEnabled() ); + + res = user.delete(); + assertTrue( res.getErrorMessage(), !res.isError() ); + + res = user.info(); + assertTrue( res.getErrorMessage(), res.isError() ); + } +} diff --git a/src/oca/java/test/VirtualMachineTest.java b/src/oca/java/test/VirtualMachineTest.java new file mode 100644 index 0000000000..84f8f60a86 --- /dev/null +++ b/src/oca/java/test/VirtualMachineTest.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.opennebula.client.Client; +import org.opennebula.client.OneResponse; +import org.opennebula.client.host.Host; +import org.opennebula.client.vm.VirtualMachine; +import org.opennebula.client.vm.VirtualMachinePool; + + +public class VirtualMachineTest +{ + + private static VirtualMachine vm; + private static VirtualMachinePool vmPool; + + private static Client client; + + private static int hid_A, hid_B; + + private static OneResponse res; + private static String name = "new_test_machine"; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + client = new Client(); + vmPool = new VirtualMachinePool(client); + + + res = Host.allocate(client, "host_A", + "im_dummy", "vmm_dummy", "tm_dummy"); + hid_A = Integer.parseInt( res.getMessage() ); + + res = Host.allocate(client, "host_B", + "im_dummy", "vmm_dummy", "tm_dummy"); + hid_B = Integer.parseInt( res.getMessage() ); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception + { + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + String template = "NAME = " + name + "\n"+ + "MEMORY = 512\n" + + "CONTEXT = [DNS = 192.169.1.4]"; + + res = VirtualMachine.allocate(client, template); + int vmid = !res.isError() ? Integer.parseInt(res.getMessage()) : -1; + + vm = new VirtualMachine(vmid, client); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + vm.finalizeVM(); + } + + @Test + public void allocate() + { +// String template = "NAME = " + name + "\n"+ +// "MEMORY = 512\n" + +// "CONTEXT = [DNS = 192.169.1.4]"; +// +// res = VirtualMachine.allocate(client, template); +// assertTrue( !res.isError() ); +// assertTrue( res.getMessage().equals("0") ); + + vmPool.info(); + + boolean found = false; + for(VirtualMachine vm : vmPool) + { + found = found || vm.getName().equals(name); + } + + assertTrue( found ); + } + + @Test + public void update() + { + res = vm.info(); + assertTrue( !res.isError() ); + +// assertTrue( vm.getId().equals("0") ); +// assertTrue( vm.id() == 0 ); + assertTrue( vm.getName().equals(name) ); + } + + @Test + public void hold() + { + res = vm.hold(); + assertTrue( !res.isError() ); + } + + @Test + public void release() + { + vm.hold(); + + res = vm.release(); + assertTrue( !res.isError() ); + } + + @Test + public void deploy() + { + res = vm.deploy(hid_A); + assertTrue( !res.isError() ); + } + + @Test + public void migrate() + { + vm.deploy(hid_A); + try{ Thread.sleep(5000); } catch (Exception e){} + + res = vm.migrate(hid_B); + assertTrue( !res.isError() ); + } + + @Test + public void liveMigrate() + { + vm.deploy(hid_A); + try{ Thread.sleep(5000); } catch (Exception e){} + + res = vm.liveMigrate(hid_B); + assertTrue( !res.isError() ); + } + + @Test + public void shutdown() + { + vm.deploy(hid_A); + try{ Thread.sleep(5000); } catch (Exception e){} + + res = vm.shutdown(); + assertTrue( !res.isError() ); + } + + @Test + public void cancel() + { + vm.deploy(hid_A); + try{ Thread.sleep(5000); } catch (Exception e){} + + res = vm.cancel(); + assertTrue( !res.isError() ); + } + + @Test + public void stop() + { + vm.deploy(hid_A); + try{ Thread.sleep(5000); } catch (Exception e){} + + res = vm.stop(); + assertTrue( !res.isError() ); + } + + @Test + public void suspend() + { + vm.deploy(hid_A); + try{ Thread.sleep(5000); } catch (Exception e){} + + res = vm.suspend(); + assertTrue( !res.isError() ); + } + + @Test + public void resume() + { + vm.deploy(hid_A); + try{ Thread.sleep(5000); } catch (Exception e){} + vm.suspend(); + try{ Thread.sleep(5000); } catch (Exception e){} + + res = vm.resume(); + assertTrue( !res.isError() ); + } + + @Test + public void finalize() + { + res = vm.finalizeVM(); + assertTrue( !res.isError() ); + } + + @Test + public void restart() + { + // TODO + } + + @Test + public void attributes() + { + res = vm.info(); + assertTrue( !res.isError() ); + + assertTrue( vm.xpath("NAME").equals(name) ); + assertTrue( vm.xpath("TEMPLATE/MEMORY").equals("512") ); +// assertTrue( vm.xpath("ID").equals("0") ); + assertTrue( vm.xpath("TEMPLATE/MEMORY").equals("512") ); + assertTrue( vm.xpath("TEMPLATE/CONTEXT/DNS").equals("192.169.1.4") ); + } +} diff --git a/src/oca/java/test/VirtualNetworkTest.java b/src/oca/java/test/VirtualNetworkTest.java new file mode 100644 index 0000000000..cbc232b2eb --- /dev/null +++ b/src/oca/java/test/VirtualNetworkTest.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.opennebula.client.Client; +import org.opennebula.client.OneResponse; +import org.opennebula.client.vnet.VirtualNetwork; +import org.opennebula.client.vnet.VirtualNetworkPool; + +public class VirtualNetworkTest +{ + + private static VirtualNetwork vnet; + private static VirtualNetworkPool vnetPool; + + private static Client client; + + private static OneResponse res; + private static String name = "new_test_vnet"; + + + private static String template = + "NAME = " + name + "\n"+ + "TYPE = RANGED\n" + + "PUBLIC = NO\n" + + "BRIDGE = vbr0\n" + + "NETWORK_SIZE = C\n" + + "NETWORK_ADDRESS = 192.168.0.0\n"; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + client = new Client(); + vnetPool = new VirtualNetworkPool(client); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception + { + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + res = VirtualNetwork.allocate(client, template); + + int vnid = !res.isError() ? Integer.parseInt(res.getMessage()) : -1; + vnet = new VirtualNetwork(vnid, client); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + vnet.delete(); + } + + + @Test + public void allocate() + { +// String template = "NAME = " + name + "\n"+ +// "TYPE = RANGED\n" + +// "PUBLIC = NO\n" + +// "BRIDGE = vbr0\n" + +// "NETWORK_SIZE = C\n" + +// "NETWORK_ADDRESS = 192.168.0.0\n"; +// +// res = VirtualNetwork.allocate(client, template); +// assertTrue( !res.isError() ); +// assertTrue( res.getMessage().equals("0") ); + + vnetPool.info(); + + boolean found = false; + for(VirtualNetwork vn : vnetPool) + { + found = found || vn.getName().equals(name); + } + + assertTrue( found ); + } + + @Test + public void update() + { + res = vnet.info(); + assertTrue( !res.isError() ); + +// assertTrue( vnet.getId().equals("0") ); +// assertTrue( vnet.id() == 0 ); + assertTrue( vnet.getName().equals(name) ); + } + + @Test + public void attributes() + { + res = vnet.info(); + assertTrue( !res.isError() ); + +// assertTrue( vnet.xpath("ID").equals("0") ); + assertTrue( vnet.xpath("NAME").equals(name) ); + assertTrue( vnet.xpath("BRIDGE").equals("vbr0") ); + assertTrue( vnet.xpath("TEMPLATE/NETWORK_ADDRESS").equals("192.168.0.0") ); + assertTrue( vnet.xpath("TEMPLATE/TYPE").equals("RANGED") ); + } + + @Test + public void delete() + { + res = vnet.delete(); + assertTrue( !res.isError() ); + + res = vnet.info(); + assertTrue( res.isError() ); + } +} diff --git a/src/oca/java/test/all_tests.sh b/src/oca/java/test/all_tests.sh new file mode 100755 index 0000000000..404f38575d --- /dev/null +++ b/src/oca/java/test/all_tests.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +./test.sh ClusterTest +./test.sh HostTest +./test.sh ImageTest +./test.sh SessionTest +./test.sh UserTest +./test.sh VirtualMachineTest +./test.sh VirtualNetworkTest \ No newline at end of file diff --git a/src/oca/java/test/oned.conf b/src/oca/java/test/oned.conf new file mode 100644 index 0000000000..d433ee488f --- /dev/null +++ b/src/oca/java/test/oned.conf @@ -0,0 +1,343 @@ +#******************************************************************************* +# OpenNebula Configuration file +#******************************************************************************* + +#******************************************************************************* +# Daemon configuration attributes +#------------------------------------------------------------------------------- +# HOST_MONITORING_INTERVAL: Time in seconds between host monitorization +# +# VM_POLLING_INTERVAL: Time in seconds between virtual machine monitorization. +# (use 0 to disable VM monitoring). +# +# VM_DIR: Remote path to store the VM images, it should be shared between all +# the cluster nodes to perform live migrations. This variable is the default +# for all the hosts in the cluster. +# +# PORT: Port where oned will listen for xmlrpc calls. +# +# DB: Configuration attributes for the database backend +# backend : can be sqlite or mysql (default is sqlite) +# server : (mysql) host name or an IP address for the MySQL server +# user : (mysql) user's MySQL login ID +# passwd : (mysql) the password for user +# db_name : (mysql) the database name +# +# VNC_BASE_PORT: VNC ports for VMs can be automatically set to VNC_BASE_PORT + +# VMID +# +# DEBUG_LEVEL: 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG +#******************************************************************************* + +HOST_MONITORING_INTERVAL = 600 + +VM_POLLING_INTERVAL = 600 + +#VM_DIR=/srv/cloud/one/var + +SCRIPTS_REMOTE_DIR=/tmp/one + +PORT=2666 + +DB = [ backend = "sqlite" ] + +# Sample configuration for MySQL +# DB = [ backend = "mysql", +# server = "localhost", +# user = "oneadmin", +# passwd = "oneadmin", +# db_name = "opennebula" ] + +VNC_BASE_PORT = 5900 + +DEBUG_LEVEL=3 + +#******************************************************************************* +# Physical Networks configuration +#******************************************************************************* +# NETWORK_SIZE: Here you can define the default size for the virtual networks +# +# MAC_PREFIX: Default MAC prefix to be used to create the auto-generated MAC +# addresses is defined here (this can be overrided by the Virtual Network +# template) +#******************************************************************************* + +NETWORK_SIZE = 254 + +MAC_PREFIX = "02:00" + +#******************************************************************************* +# Image Repository Configuration +#******************************************************************************* +# IMAGE_REPOSITORY_PATH: Define the path to the image repository, by default +# is set to $ONE_LOCATION/var +# +# DEFAULT_IMAGE_TYPE: This can take values +# OS Image file holding an operating system +# CDROM Image file holding a CDROM +# DATABLOCK Image file holding a datablock, +# always created as an empty block +# DEFAULT_DEVICE_PREFIX: This can be set to +# hd IDE prefix +# sd SCSI +# xvd XEN Virtual Disk +# vd KVM virtual disk +#******************************************************************************* + +#IMAGE_REPOSITORY_PATH = /srv/cloud/var/images +DEFAULT_IMAGE_TYPE = "OS" +DEFAULT_DEVICE_PREFIX = "hd" + +#******************************************************************************* +# Information Driver Configuration +#******************************************************************************* +# You can add more information managers with different configurations but make +# sure it has different names. +# +# name : name for this information manager +# +# executable: path of the information driver executable, can be an +# absolute path or relative to $ONE_LOCATION/lib/mads (or +# /usr/lib/one/mads/ if OpenNebula was installed in /) +# +# arguments : for the driver executable, usually a probe configuration file, +# can be an absolute path or relative to $ONE_LOCATION/etc (or +# /etc/one/ if OpenNebula was installed in /) +#******************************************************************************* + +#------------------------------------------------------------------------------- +# KVM Information Driver Manager Configuration +#------------------------------------------------------------------------------- +IM_MAD = [ + name = "im_kvm", + executable = "one_im_ssh", + arguments = "kvm" ] +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# XEN Information Driver Manager Configuration +#------------------------------------------------------------------------------- +#IM_MAD = [ +# name = "im_xen", +# executable = "one_im_ssh", +# arguments = "xen" ] +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# EC2 Information Driver Manager Configuration +#------------------------------------------------------------------------------- +#IM_MAD = [ +# name = "im_ec2", +# executable = "one_im_ec2", +# arguments = "im_ec2/im_ec2.conf" ] +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# Dummy Information Driver Manager Configuration +#------------------------------------------------------------------------------- +IM_MAD = [ name="im_dummy", executable="one_im_dummy"] +#------------------------------------------------------------------------------- + +#******************************************************************************* +# Virtualization Driver Configuration +#******************************************************************************* +# You can add more virtualization managers with different configurations but +# make sure it has different names. +# +# name : name of the virtual machine manager driver +# +# executable: path of the virtualization driver executable, can be an +# absolute path or relative to $ONE_LOCATION/lib/mads (or +# /usr/lib/one/mads/ if OpenNebula was installed in /) +# +# arguments : for the driver executable +# +# default : default values and configuration parameters for the driver, can +# be an absolute path or relative to $ONE_LOCATION/etc (or +# /etc/one/ if OpenNebula was installed in /) +# +# type : driver type, supported drivers: xen, kvm, xml +#******************************************************************************* + +#------------------------------------------------------------------------------- +# KVM Virtualization Driver Manager Configuration +#------------------------------------------------------------------------------- +VM_MAD = [ + name = "vmm_kvm", + executable = "one_vmm_ssh", + arguments = "kvm", + default = "vmm_ssh/vmm_ssh_kvm.conf", + type = "kvm" ] +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# XEN Virtualization Driver Manager Configuration +#------------------------------------------------------------------------------- +#VM_MAD = [ +# name = "vmm_xen", +# executable = "one_vmm_ssh", +# arguments = "xen", +# default = "vmm_ssh/vmm_ssh_xen.conf", +# type = "xen" ] +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# EC2 Virtualization Driver Manager Configuration +# arguments: default values for the EC2 driver, can be an absolute path or +# relative to $ONE_LOCATION/etc (or /etc/one/ if OpenNebula was +# installed in /). +#------------------------------------------------------------------------------- +#VM_MAD = [ +# name = "vmm_ec2", +# executable = "one_vmm_ec2", +# arguments = "vmm_ec2/vmm_ec2.conf", +# type = "xml" ] +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# Dummy Virtualization Driver Configuration +#------------------------------------------------------------------------------- +VM_MAD = [ name="vmm_dummy", executable="one_vmm_dummy", type="xml" ] +#------------------------------------------------------------------------------- + +#******************************************************************************* +# Transfer Manager Driver Configuration +#******************************************************************************* +# You can add more transfer managers with different configurations but make +# sure it has different names. +# name : name for this transfer driver +# +# executable: path of the transfer driver executable, can be an +# absolute path or relative to $ONE_LOCATION/lib/mads (or +# /usr/lib/one/mads/ if OpenNebula was installed in /) +# +# arguments : for the driver executable, usually a commands configuration file +# , can be an absolute path or relative to $ONE_LOCATION/etc (or +# /etc/one/ if OpenNebula was installed in /) +#******************************************************************************* + +#------------------------------------------------------------------------------- +# NFS Transfer Manager Driver Configuration +#------------------------------------------------------------------------------- +TM_MAD = [ + name = "tm_nfs", + executable = "one_tm", + arguments = "tm_nfs/tm_nfs.conf" ] +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# SSH Transfer Manager Driver Configuration +#------------------------------------------------------------------------------- +#TM_MAD = [ +# name = "tm_ssh", +# executable = "one_tm", +# arguments = "tm_ssh/tm_ssh.conf" ] +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# Dummy Transfer Manager Driver Configuration +#------------------------------------------------------------------------------- +TM_MAD = [ + name = "tm_dummy", + executable = "one_tm", + arguments = "tm_dummy/tm_dummy.conf" ] +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# LVM Transfer Manager Driver Configuration +#------------------------------------------------------------------------------- +#TM_MAD = [ +# name = "tm_lvm", +# executable = "one_tm", +# arguments = "tm_lvm/tm_lvm.conf" ] +#------------------------------------------------------------------------------- + +#******************************************************************************* +# Hook Manager Configuration +#******************************************************************************* +# The Driver (HM_MAD), used to execute the Hooks +# executable: path of the hook driver executable, can be an +# absolute path or relative to $ONE_LOCATION/lib/mads (or +# /usr/lib/one/mads/ if OpenNebula was installed in /) +# +# arguments : for the driver executable, can be an absolute path or relative +# to $ONE_LOCATION/etc (or /etc/one/ if OpenNebula was installed +# in /) +# +# Virtual Machine Hooks (VM_HOOK) defined by: +# name : for the hook, useful to track the hook (OPTIONAL) +# on : when the hook should be executed, +# - CREATE, when the VM is created (onevm create) +# - RUNNING, after the VM is successfully booted +# - SHUTDOWN, after the VM is shutdown +# - STOP, after the VM is stopped (including VM image transfers) +# - DONE, after the VM is deleted or shutdown +# command : path can be absolute or relative to $ONE_LOCATION/share/hooks +# case of self-contained installation or relative to +# /usr/share/one/hooks in case of system-wide installation +# arguments : for the hook. You can access to VM template variables with $ +# - $ATTR, the value of an attribute e.g. $NAME or $VMID +# - $ATTR[VAR], the value of a vector e.g. $NIC[MAC] +# - $ATTR[VAR, COND], same of previous but COND select between +# multiple ATTRs e.g. $NIC[MAC, NETWORK="Public"] +# remote : values, +# - YES, The hook is executed in the host where the VM was +# allocated +# - NO, The hook is executed in the OpenNebula server (default) +#------------------------------------------------------------------------------- + +HM_MAD = [ + executable = "one_hm" ] + +#-------------------------------- Image Hook ----------------------------------- +# This hook is used to handle image saving and overwriting when virtual machines +# reach the DONE state after being shutdown. + +VM_HOOK = [ + name = "image", + on = "DONE", + command = "image.rb", + arguments = "$VMID" ] + +#------------------------------------------------------------------------------- + +#-------------------------------- Hook Examples -------------------------------- +#VM_HOOK = [ +# name = "dhcp", +# on = "create", +# command = "/bin/echo", +# arguments = "$NAME > /tmp/test.$VMID" ] +#------------------------------------------------------------------------------- +#VM_HOOK = [ +# name = "ebtables", +# on = "running", +# command = "/usr/local/one/bin/set_net", +# arguments = '$NIC[MAC, Network = "Private"]', +# remote = "yes" ] +#------------------------------------------------------------------------------- +#VM_HOOK = [ +# name = "mail", +# on = "running", +# command = "/usr/local/one/bin/send_mail", +# arguments = "$VMID $NAME", +# remote = "no" ] +#------------------------------------------------------------------------------ + +#******************************************************************************* +# Auth Manager Configuration +#******************************************************************************* +# The Driver (AUTHM_MAD) that will be used to authenticate and authorize +# OpenNebula requests. If not defined OpenNebula will use the built-in auth +# policies +# executable: path of the auth driver executable, can be an +# absolute path or relative to $ONE_LOCATION/lib/mads (or +# /usr/lib/one/mads/ if OpenNebula was installed in /) +# +# arguments : for the driver executable, can be an absolute path or relative +# to $ONE_LOCATION/etc (or /etc/one/ if OpenNebula was installed +# in /) +#------------------------------------------------------------------------------- + +#AUTH_MAD = [ +# executable = "one_auth_mad" ] + diff --git a/src/oca/java/test/test.sh b/src/oca/java/test/test.sh new file mode 100755 index 0000000000..22f418cad0 --- /dev/null +++ b/src/oca/java/test/test.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Usage: test.sh +# For instance: test.sh ImageTest + +JUNIT_JAR="/usr/share/java/junit4.jar" +ONEDB="$ONE_LOCATION/var/one.db" + +PID=$$ + +oned -f & + +sleep 4s; + +java -cp ../lib/*:../jar/*:$JUNIT_JAR:. org.junit.runner.JUnitCore $1 + +CODE=$? + +pkill -P $PID oned +sleep 4s; +pkill -9 -P $PID oned +rm $ONEDB + +exit $CODE \ No newline at end of file diff --git a/src/oca/ruby/OpenNebula.rb b/src/oca/ruby/OpenNebula.rb index 93b82525a5..6affea51ea 100644 --- a/src/oca/ruby/OpenNebula.rb +++ b/src/oca/ruby/OpenNebula.rb @@ -74,13 +74,11 @@ module OpenNebula elsif File.file?(ENV["HOME"]+"/.one/one_auth") one_secret=File.read(ENV["HOME"]+"/.one/one_auth") else - puts "ONE_AUTH file not present" - exit -1 + raise "ONE_AUTH file not present" end if !one_secret.match(".+:.+") - puts "Authorization file malformed" - exit -1 + raise "Authorization file malformed" end diff --git a/src/oca/ruby/OpenNebula/ImageRepository.rb b/src/oca/ruby/OpenNebula/ImageRepository.rb index f80638cc83..a3fcb4cfd0 100644 --- a/src/oca/ruby/OpenNebula/ImageRepository.rb +++ b/src/oca/ruby/OpenNebula/ImageRepository.rb @@ -2,38 +2,45 @@ require 'OpenNebula/Image' require 'fileutils' module OpenNebula - class ImageRepository - def create(image, template, copy=true) + ############################################################################ + # The ImageRepository class represents and abstraction of the Image + # Repository, and it provides basic operations to manage and mantain it. + # This class is used by the OpenNebula daemon (through the image hook) to + # save and update images, and by the OpenNebula CLI to create and delete + # them + ############################################################################ + class ImageRepository + ######################################################################## + # + ######################################################################## + def create(image, template) if image.nil? error_msg = "Image could not be found, aborting." - result = OpenNebula::Error.new(error_msg) + return OpenNebula::Error.new(error_msg) end # ------ Allocate the Image ------ result = image.allocate(template) if OpenNebula.is_error?(result) - puts result.message - exit -1 + return result end # ------ Copy the Image file ------ image.info - if image['TEMPLATE/PATH'] - if copy - # --- CDROM, DATABLOCK or OS based on a PATH --- - file_path = image['TEMPLATE/PATH'] + if image['TEMPLATE/PATH'] and image['TEMPLATE/SOURCE'].nil? + # --- CDROM, DATABLOCK or OS based on a PATH --- + file_path = image['TEMPLATE/PATH'] - if !File.exists?(file_path) - error_msg = "Image file could not be found, aborting." - result = OpenNebula::Error.new(error_msg) - end - - result = copy(file_path, image['SOURCE']) + if !File.exists?(file_path) + error_msg = "Image file could not be found, aborting." + return OpenNebula::Error.new(error_msg) end + + result = copy(file_path, image['SOURCE']) elsif image['TEMPLATE/SIZE'] and image['TEMPLATE/FSTYPE'] and \ image['TEMPLATE/TYPE'] == 'DATABLOCK' # --- Empty DATABLOCK --- @@ -42,8 +49,12 @@ module OpenNebula if !OpenNebula.is_error?(result) result = mkfs(image['TEMPLATE/FSTYPE'], image['SOURCE']) end - else - error_msg = "Image not present, aborting." + elsif image['TEMPLATE/PATH'].nil? and image['TEMPLATE/SOURCE'].nil? + error_msg = "Image path not present, aborting." + result = OpenNebula::Error.new(error_msg) + elsif image['TEMPLATE/PATH'] and image['TEMPLATE/SOURCE'] + error_msg = "Template malformed, PATH and SOURCE are" << + " mutuallly exclusive" result = OpenNebula::Error.new(error_msg) end @@ -58,10 +69,13 @@ module OpenNebula return result end + ######################################################################## + # + ######################################################################## def delete(image) if image.nil? error_msg = "Image could not be found, aborting." - result = OpenNebula::Error.new(error_msg) + return OpenNebula::Error.new(error_msg) end result = image.info @@ -79,10 +93,13 @@ module OpenNebula return result end + ######################################################################## + # + ######################################################################## def update_source(image, source) if image.nil? error_msg = "Image could not be found, aborting." - result = OpenNebula::Error.new(error_msg) + return OpenNebula::Error.new(error_msg) end result = image.info @@ -97,12 +114,27 @@ module OpenNebula end private - FS_UTILS = { :dd => "env dd", :mkfs => "env mkfs" } + ######################################################################## + # + ######################################################################## + def set_permissions(source) + if File.directory?(source) + perms = 0770 + else + perms = 0660 + end + + FileUtils.chmod(perms, source) + end + + ######################################################################## + # + ######################################################################## def copy(path, source) if source.nil? or path.nil? return OpenNebula::Error.new("copy Image: missing parameters.") @@ -110,7 +142,7 @@ module OpenNebula begin FileUtils.copy(path, source) - FileUtils.chmod(0660, source) + set_permissions(source) rescue Exception => e return OpenNebula::Error.new(e.message) end @@ -118,14 +150,17 @@ module OpenNebula return nil end + ######################################################################## + # + ######################################################################## def move(path, source) - if source.nil? or path.nil? - return OpenNebula::Error.new("copy Image: missing parameters.") + if source.nil? || path.nil? || File.identical?(path,source) + return nil end begin FileUtils.move(path, source) - FileUtils.chmod(0660, source) + set_permissions(source) rescue Exception => e return OpenNebula::Error.new(e.message) end @@ -133,6 +168,9 @@ module OpenNebula return nil end + ######################################################################## + # + ######################################################################## def dd(size, source) if source.nil? or size.nil? return OpenNebula::Error.new("dd Image: missing parameters.") @@ -152,6 +190,9 @@ module OpenNebula return nil end + ######################################################################## + # + ######################################################################## def mkfs(fstype, source) if source.nil? or fstype.nil? return OpenNebula::Error.new("mkfs Image: missing parameters.") @@ -170,16 +211,25 @@ module OpenNebula return nil end + ######################################################################## + # + ######################################################################## def remove(source) - if File.exists?(source) - begin + if !File.exists?(source) + return nil + end + + begin + if File.directory?(source) + FileUtils.rmdir(source) + else FileUtils.rm(source) - rescue Exception => e - return OpenNebula::Error.new(e.message) end + rescue Exception => e + return OpenNebula::Error.new(e.message) end return nil end end -end \ No newline at end of file +end diff --git a/src/oca/ruby/OpenNebula/XMLUtils.rb b/src/oca/ruby/OpenNebula/XMLUtils.rb index 4ff16187e2..48bb2fd373 100644 --- a/src/oca/ruby/OpenNebula/XMLUtils.rb +++ b/src/oca/ruby/OpenNebula/XMLUtils.rb @@ -8,7 +8,6 @@ module OpenNebula NOKOGIRI=false end - ########################################################################### # The XMLElement class provides an abstraction of the underlying # XML parser engine. It provides XML-related methods for the Pool and @@ -112,6 +111,28 @@ module OpenNebula end end + def name + @xml.name + end + + def text + if NOKOGIRI + @xml.content + else + @xml.text + end + end + + def has_elements?(xpath_str) + if NOKOGIRI + element = @xml.xpath(xpath_str.to_s.upcase) + return element != nil && element.children.size > 0 + else + element = @xml.elements[xpath_str.to_s] + return element != nil && element.has_elements? + end + end + def template_str(indent=true) template_like_str('TEMPLATE', indent) end @@ -199,5 +220,3 @@ module OpenNebula end end - - diff --git a/src/oca/ruby/test/ClusterPool_spec.rb b/src/oca/ruby/test/ClusterPool_spec.rb index e68f052ba4..fd30f0fdb3 100644 --- a/src/oca/ruby/test/ClusterPool_spec.rb +++ b/src/oca/ruby/test/ClusterPool_spec.rb @@ -1,7 +1,7 @@ $: << '../' require 'OpenNebula' -require 'MockClient' +require 'helpers/MockClient' module OpenNebula diff --git a/src/oca/ruby/test/Cluster_spec.rb b/src/oca/ruby/test/Cluster_spec.rb index 953d1b99f8..bb2a30889a 100644 --- a/src/oca/ruby/test/Cluster_spec.rb +++ b/src/oca/ruby/test/Cluster_spec.rb @@ -1,7 +1,7 @@ $: << '../' require 'OpenNebula' -require 'MockClient' +require 'helpers/MockClient' module OpenNebula diff --git a/src/oca/ruby/test/HostPool_spec.rb b/src/oca/ruby/test/HostPool_spec.rb index 52a02ba019..5d08319618 100644 --- a/src/oca/ruby/test/HostPool_spec.rb +++ b/src/oca/ruby/test/HostPool_spec.rb @@ -1,7 +1,7 @@ $: << '../' require 'OpenNebula' -require 'MockClient' +require 'helpers/MockClient' module OpenNebula diff --git a/src/oca/ruby/test/Host_spec.rb b/src/oca/ruby/test/Host_spec.rb index 08af3d377e..e2d8cb39e4 100644 --- a/src/oca/ruby/test/Host_spec.rb +++ b/src/oca/ruby/test/Host_spec.rb @@ -1,7 +1,7 @@ $: << '../' require 'OpenNebula' -require 'MockClient' +require 'helpers/MockClient' module OpenNebula diff --git a/src/oca/ruby/test/UserPool_spec.rb b/src/oca/ruby/test/UserPool_spec.rb index 6bd5fcba8c..7465cfc485 100644 --- a/src/oca/ruby/test/UserPool_spec.rb +++ b/src/oca/ruby/test/UserPool_spec.rb @@ -1,7 +1,7 @@ $: << '../' require 'OpenNebula' -require 'MockClient' +require 'helpers/MockClient' module OpenNebula @@ -24,11 +24,11 @@ module OpenNebula if user.id == 0 user.name.should eql('oneadmin') user['PASSWORD'].should eql('f13a1234833436f71ab846572d251c0d40391e72') - user['ENABLED'].should eql('True') + user['ENABLED'].should eql('1') elsif user.id == 1 user.name.should eql('dan') user['PASSWORD'].should eql('d22a12348334v33f71ba846572d25250d40701e72') - user['ENABLED'].should eql('False') + user['ENABLED'].should eql('0') end } end @@ -53,11 +53,11 @@ module OpenNebula if user.id == 0 user.name.should eql('oneadmin') user['PASSWORD'].should eql('f13a1234833436f71ab846572d251c0d40391e72') - user['ENABLED'].should eql('True') + user['ENABLED'].should eql('1') elsif user.id == 1 user.name.should eql('dan') user['PASSWORD'].should eql('d22a12348334v33f71ba846572d25250d40701e72') - user['ENABLED'].should eql('False') + user['ENABLED'].should eql('0') end } end diff --git a/src/oca/ruby/test/User_spec.rb b/src/oca/ruby/test/User_spec.rb index e0f43f8f61..a02911f03e 100644 --- a/src/oca/ruby/test/User_spec.rb +++ b/src/oca/ruby/test/User_spec.rb @@ -1,7 +1,7 @@ $: << '../' require 'OpenNebula' -require 'MockClient' +require 'helpers/MockClient' module OpenNebula @@ -42,7 +42,7 @@ module OpenNebula @user['ID'].should eql('3') @user['NAME'].should eql('dan') @user['PASSWORD'].should eql('d22a12348334v33f71ba846572d25250d40701e72') - @user['ENABLED'].should eql('False') + @user['ENABLED'].should eql('0') end end @@ -83,7 +83,7 @@ module OpenNebula @user['ID'].should eql('3') @user['NAME'].should eql('dan') @user['PASSWORD'].should eql('d22a12348334v33f71ba846572d25250d40701e72') - @user['ENABLED'].should eql('False') + @user['ENABLED'].should eql('0') end end diff --git a/src/oca/ruby/test/VirtualMachinePool_spec.rb b/src/oca/ruby/test/VirtualMachinePool_spec.rb index 8e7c81acba..28ffb96dd3 100644 --- a/src/oca/ruby/test/VirtualMachinePool_spec.rb +++ b/src/oca/ruby/test/VirtualMachinePool_spec.rb @@ -1,7 +1,7 @@ $: << '../' require 'OpenNebula' -require 'MockClient' +require 'helpers/MockClient' module OpenNebula diff --git a/src/oca/ruby/test/VirtualMachine_spec.rb b/src/oca/ruby/test/VirtualMachine_spec.rb index e2fc6571ff..53c4397e05 100644 --- a/src/oca/ruby/test/VirtualMachine_spec.rb +++ b/src/oca/ruby/test/VirtualMachine_spec.rb @@ -1,7 +1,7 @@ $: << '../' require 'OpenNebula' -require 'MockClient' +require 'helpers/MockClient' module OpenNebula diff --git a/src/oca/ruby/test/VirtualNetworkPool_spec.rb b/src/oca/ruby/test/VirtualNetworkPool_spec.rb index 51013dc20f..fd107827c6 100644 --- a/src/oca/ruby/test/VirtualNetworkPool_spec.rb +++ b/src/oca/ruby/test/VirtualNetworkPool_spec.rb @@ -1,7 +1,7 @@ $: << '../' require 'OpenNebula' -require 'MockClient' +require 'helpers/MockClient' module OpenNebula diff --git a/src/oca/ruby/test/VirtualNetwork_spec.rb b/src/oca/ruby/test/VirtualNetwork_spec.rb index 0b19f675f9..b74982bf52 100644 --- a/src/oca/ruby/test/VirtualNetwork_spec.rb +++ b/src/oca/ruby/test/VirtualNetwork_spec.rb @@ -1,7 +1,7 @@ $: << '../' require 'OpenNebula' -require 'MockClient' +require 'helpers/MockClient' module OpenNebula diff --git a/src/oca/ruby/test/xml_test/cluster.xml b/src/oca/ruby/test/fixtures/cluster.xml similarity index 100% rename from src/oca/ruby/test/xml_test/cluster.xml rename to src/oca/ruby/test/fixtures/cluster.xml diff --git a/src/oca/ruby/test/xml_test/clusterpool.xml b/src/oca/ruby/test/fixtures/clusterpool.xml similarity index 100% rename from src/oca/ruby/test/xml_test/clusterpool.xml rename to src/oca/ruby/test/fixtures/clusterpool.xml diff --git a/src/oca/ruby/test/xml_test/host.xml b/src/oca/ruby/test/fixtures/host.xml similarity index 100% rename from src/oca/ruby/test/xml_test/host.xml rename to src/oca/ruby/test/fixtures/host.xml diff --git a/src/oca/ruby/test/xml_test/hostpool.xml b/src/oca/ruby/test/fixtures/hostpool.xml similarity index 100% rename from src/oca/ruby/test/xml_test/hostpool.xml rename to src/oca/ruby/test/fixtures/hostpool.xml diff --git a/src/oca/ruby/test/xml_test/user.xml b/src/oca/ruby/test/fixtures/user.xml similarity index 75% rename from src/oca/ruby/test/xml_test/user.xml rename to src/oca/ruby/test/fixtures/user.xml index eab4482685..62749e8b6e 100644 --- a/src/oca/ruby/test/xml_test/user.xml +++ b/src/oca/ruby/test/fixtures/user.xml @@ -2,5 +2,5 @@ 3 dan d22a12348334v33f71ba846572d25250d40701e72 - False + 0 \ No newline at end of file diff --git a/src/oca/ruby/test/xml_test/userpool.xml b/src/oca/ruby/test/fixtures/userpool.xml similarity index 79% rename from src/oca/ruby/test/xml_test/userpool.xml rename to src/oca/ruby/test/fixtures/userpool.xml index d6d5565131..d369d1bd11 100644 --- a/src/oca/ruby/test/xml_test/userpool.xml +++ b/src/oca/ruby/test/fixtures/userpool.xml @@ -3,12 +3,12 @@ 0 oneadmin f13a1234833436f71ab846572d251c0d40391e72 - True + 1 1 dan d22a12348334v33f71ba846572d25250d40701e72 - False + 0 \ No newline at end of file diff --git a/src/oca/ruby/test/xml_test/vm.xml b/src/oca/ruby/test/fixtures/vm.xml similarity index 100% rename from src/oca/ruby/test/xml_test/vm.xml rename to src/oca/ruby/test/fixtures/vm.xml diff --git a/src/oca/ruby/test/xml_test/vmpool.xml b/src/oca/ruby/test/fixtures/vmpool.xml similarity index 100% rename from src/oca/ruby/test/xml_test/vmpool.xml rename to src/oca/ruby/test/fixtures/vmpool.xml diff --git a/src/oca/ruby/test/xml_test/vnet.xml b/src/oca/ruby/test/fixtures/vnet.xml similarity index 100% rename from src/oca/ruby/test/xml_test/vnet.xml rename to src/oca/ruby/test/fixtures/vnet.xml diff --git a/src/oca/ruby/test/xml_test/vnetpool.xml b/src/oca/ruby/test/fixtures/vnetpool.xml similarity index 100% rename from src/oca/ruby/test/xml_test/vnetpool.xml rename to src/oca/ruby/test/fixtures/vnetpool.xml diff --git a/src/oca/ruby/test/MockClient.rb b/src/oca/ruby/test/helpers/MockClient.rb similarity index 72% rename from src/oca/ruby/test/MockClient.rb rename to src/oca/ruby/test/helpers/MockClient.rb index 4fa7ed7b6d..d119eb552a 100644 --- a/src/oca/ruby/test/MockClient.rb +++ b/src/oca/ruby/test/helpers/MockClient.rb @@ -5,13 +5,13 @@ class MockClient case xmlrpc_action when "one.vn.info" - return File.read("xml_test/vnet.xml") + return File.read("fixtures/vnet.xml") when "one.vn.allocate" return 3 when "one.vn.delete" return nil when "one.vm.info" - return File.read("xml_test/vm.xml") + return File.read("fixtures/vm.xml") when "one.vm.allocate" return 6 when "one.vm.delete" @@ -23,7 +23,7 @@ class MockClient when "one.vm.migrate" return nil when "one.host.info" - return File.read("xml_test/host.xml") + return File.read("fixtures/host.xml") when "one.host.allocate" return 7 when "one.host.delete" @@ -33,13 +33,13 @@ class MockClient when "one.user.allocate" return 3 when "one.user.info" - return File.read("xml_test/user.xml") + return File.read("fixtures/user.xml") when "one.user.delete" return nil when "one.cluster.allocate" return 5 when "one.cluster.info" - return File.read("xml_test/cluster.xml") + return File.read("fixtures/cluster.xml") when "one.cluster.delete" return nil when "one.cluster.addhost" @@ -47,15 +47,15 @@ class MockClient when "one.cluster.removehost" return nil when "one.vnpool.info" - return File.read("xml_test/vnetpool.xml") + return File.read("fixtures/vnetpool.xml") when "one.vmpool.info" - return File.read("xml_test/vmpool.xml") + return File.read("fixtures/vmpool.xml") when "one.hostpool.info" - return File.read("xml_test/hostpool.xml") + return File.read("fixtures/hostpool.xml") when "one.userpool.info" - return File.read("xml_test/userpool.xml") + return File.read("fixtures/userpool.xml") when "one.clusterpool.info" - return File.read("xml_test/clusterpool.xml") + return File.read("fixtures/clusterpool.xml") end end end \ No newline at end of file diff --git a/src/pool/test/pool.cc b/src/pool/test/pool.cc index 5b2580ae8b..f12e95cb3f 100644 --- a/src/pool/test/pool.cc +++ b/src/pool/test/pool.cc @@ -32,6 +32,8 @@ #include "MySqlDB.h" #include "SqlDB.h" +#include "test/one_test_common.h" + using namespace std; /* ************************************************************************* */ @@ -287,12 +289,16 @@ int main(int argc, char ** argv) cout << "\nRunning MySQL tests...\n"; } + SETUP_XML_WRITER(runner, "pool.xml") + runner.addTest( PoolTest::suite() ); runner.run(); if (!log_flag) remove("test.log"); + END_XML_WRITER + NebulaLog::finalize_log_system(); return 0; diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 46685c20c2..0c9c4fbeff 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -288,6 +288,9 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr user_delete(new RequestManager::UserDelete(upool)); + xmlrpc_c::methodPtr user_info(new + RequestManager::UserInfo(upool)); + xmlrpc_c::methodPtr user_change_password(new RequestManager::UserChangePassword(upool)); @@ -323,40 +326,40 @@ void RequestManager::register_xml_methods() /* VM related methods */ - RequestManagerRegistry.addMethod("one.vm.allocate",vm_allocate); - RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy); - RequestManagerRegistry.addMethod("one.vm.action", vm_action); + RequestManagerRegistry.addMethod("one.vm.allocate", vm_allocate); + RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy); + RequestManagerRegistry.addMethod("one.vm.action", vm_action); RequestManagerRegistry.addMethod("one.vm.migrate", vm_migrate); - RequestManagerRegistry.addMethod("one.vm.info", vm_info); - RequestManagerRegistry.addMethod("one.vm.savedisk",vm_savedisk); + RequestManagerRegistry.addMethod("one.vm.info", vm_info); + RequestManagerRegistry.addMethod("one.vm.savedisk", vm_savedisk); RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info); /* Host related methods*/ RequestManagerRegistry.addMethod("one.host.allocate", host_allocate); - RequestManagerRegistry.addMethod("one.host.info", host_info); - RequestManagerRegistry.addMethod("one.host.delete", host_delete); - RequestManagerRegistry.addMethod("one.host.enable", host_enable); + RequestManagerRegistry.addMethod("one.host.info", host_info); + RequestManagerRegistry.addMethod("one.host.delete", host_delete); + RequestManagerRegistry.addMethod("one.host.enable", host_enable); RequestManagerRegistry.addMethod("one.hostpool.info", hostpool_info); /* Cluster related methods */ RequestManagerRegistry.addMethod("one.cluster.allocate", cluster_allocate); - RequestManagerRegistry.addMethod("one.cluster.info", cluster_info); - RequestManagerRegistry.addMethod("one.cluster.delete", cluster_delete); - RequestManagerRegistry.addMethod("one.cluster.add", cluster_add); - RequestManagerRegistry.addMethod("one.cluster.remove", cluster_remove); + RequestManagerRegistry.addMethod("one.cluster.info", cluster_info); + RequestManagerRegistry.addMethod("one.cluster.delete", cluster_delete); + RequestManagerRegistry.addMethod("one.cluster.add", cluster_add); + RequestManagerRegistry.addMethod("one.cluster.remove", cluster_remove); RequestManagerRegistry.addMethod("one.clusterpool.info", clusterpool_info); /* Network related methods*/ RequestManagerRegistry.addMethod("one.vn.allocate", vn_allocate); - RequestManagerRegistry.addMethod("one.vn.info", vn_info); - RequestManagerRegistry.addMethod("one.vn.publish", vn_publish); - RequestManagerRegistry.addMethod("one.vn.delete", vn_delete); + RequestManagerRegistry.addMethod("one.vn.info", vn_info); + RequestManagerRegistry.addMethod("one.vn.publish", vn_publish); + RequestManagerRegistry.addMethod("one.vn.delete", vn_delete); RequestManagerRegistry.addMethod("one.vnpool.info", vnpool_info); @@ -364,23 +367,24 @@ void RequestManager::register_xml_methods() /* User related methods*/ RequestManagerRegistry.addMethod("one.user.allocate", user_allocate); - RequestManagerRegistry.addMethod("one.user.delete", user_delete); - RequestManagerRegistry.addMethod("one.user.passwd", user_change_password); + RequestManagerRegistry.addMethod("one.user.delete", user_delete); + RequestManagerRegistry.addMethod("one.user.info", user_info); + RequestManagerRegistry.addMethod("one.user.passwd", user_change_password); RequestManagerRegistry.addMethod("one.userpool.info", userpool_info); /* Image related methods*/ - RequestManagerRegistry.addMethod("one.image.allocate", image_allocate); - RequestManagerRegistry.addMethod("one.image.delete", image_delete); - RequestManagerRegistry.addMethod("one.image.info", image_info); - RequestManagerRegistry.addMethod("one.image.update", image_update); - RequestManagerRegistry.addMethod("one.image.rmattr", image_rm_attribute); - RequestManagerRegistry.addMethod("one.image.publish", image_publish); - RequestManagerRegistry.addMethod("one.image.persistent", image_persistent); - RequestManagerRegistry.addMethod("one.image.enable", image_enable); + RequestManagerRegistry.addMethod("one.image.allocate", image_allocate); + RequestManagerRegistry.addMethod("one.image.delete", image_delete); + RequestManagerRegistry.addMethod("one.image.info", image_info); + RequestManagerRegistry.addMethod("one.image.update", image_update); + RequestManagerRegistry.addMethod("one.image.rmattr", image_rm_attribute); + RequestManagerRegistry.addMethod("one.image.publish", image_publish); + RequestManagerRegistry.addMethod("one.image.persistent", image_persistent); + RequestManagerRegistry.addMethod("one.image.enable", image_enable); - RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info); + RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info); }; diff --git a/src/rm/RequestManagerImagePoolInfo.cc b/src/rm/RequestManagerImagePoolInfo.cc index d634243c3e..33a6b2c4ac 100755 --- a/src/rm/RequestManagerImagePoolInfo.cc +++ b/src/rm/RequestManagerImagePoolInfo.cc @@ -23,16 +23,15 @@ void RequestManager::ImagePoolInfo::execute( xmlrpc_c::paramList const& paramList, xmlrpc_c::value * const retval) -{ +{ string session; ostringstream oss; ostringstream where_string; int rc; - int uid; int filter_flag; - + const string method_name = "ImagePoolInfo"; /* -- RPC specific vars -- */ @@ -46,19 +45,17 @@ void RequestManager::ImagePoolInfo::execute( filter_flag = xmlrpc_c::value_int(paramList.getInt(1)); // Check if it is a valid user - uid = ImagePoolInfo::upool->authenticate(session); + rc = ImagePoolInfo::upool->authenticate(session); - if ( uid == -1 ) + if ( rc == -1 ) { goto error_authenticate; } - - where_string.str(""); - + /** Filter flag meaning table - * -2 :: All Images (just for oneadmin) + * -2 :: All Images * -1 :: User's Images AND public images belonging to any user - * >= 0 :: UID User's Images (just for oneadmin) + * >= 0 :: UID User's Images **/ if ( filter_flag < -2 ) { @@ -69,10 +66,9 @@ void RequestManager::ImagePoolInfo::execute( { case -2: // TODO define authentication bug #278 - // where remains empty. break; case -1: - where_string << "UID=" << uid << " OR public = 'YES'"; + where_string << "UID=" << rc << " OR PUBLIC=1"; break; default: where_string << "UID=" << filter_flag; @@ -87,7 +83,7 @@ void RequestManager::ImagePoolInfo::execute( } // All nice, return pool info to the client - arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS + arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS arrayData.push_back(xmlrpc_c::value_string(oss.str())); arrayresult = new xmlrpc_c::value_array(arrayData); @@ -101,7 +97,7 @@ void RequestManager::ImagePoolInfo::execute( return; error_authenticate: - oss.str(authenticate_error(method_name)); + oss.str(authenticate_error(method_name)); goto error_common; error_filter_flag: @@ -115,13 +111,13 @@ error_dump: error_common: arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE arrayData.push_back(xmlrpc_c::value_string(oss.str())); - - NebulaLog::log("ReM",Log::ERROR,oss); - + + NebulaLog::log("ReM",Log::ERROR,oss); + xmlrpc_c::value_array arrayresult_error(arrayData); *retval = arrayresult_error; - + return; } diff --git a/src/rm/RequestManagerImagePublish.cc b/src/rm/RequestManagerImagePublish.cc index 8c48677097..1e5850ec5e 100644 --- a/src/rm/RequestManagerImagePublish.cc +++ b/src/rm/RequestManagerImagePublish.cc @@ -105,6 +105,8 @@ void RequestManager::ImagePublish::execute( if (!response) { + image->unlock(); + goto error_publish; } diff --git a/src/rm/RequestManagerPoolInfo.cc b/src/rm/RequestManagerPoolInfo.cc index c9e0e3acf2..17ee97960f 100644 --- a/src/rm/RequestManagerPoolInfo.cc +++ b/src/rm/RequestManagerPoolInfo.cc @@ -57,6 +57,7 @@ void RequestManager::VirtualMachinePoolInfo::execute( break; default: paramList.verifyEnd(4); + return; } // Get the parameters diff --git a/src/rm/RequestManagerSaveDisk.cc b/src/rm/RequestManagerSaveDisk.cc index bfb1e13c29..8392de1794 100644 --- a/src/rm/RequestManagerSaveDisk.cc +++ b/src/rm/RequestManagerSaveDisk.cc @@ -112,7 +112,13 @@ void RequestManager::VirtualMachineSaveDisk::execute( goto error_vm_get; } - vm->save_disk(disk_id, img_id); + rc = vm->save_disk(disk_id, img_id); + + if ( rc == -1 ) + { + vm->unlock(); + goto error_vm_get_disk_id; + } VirtualMachineSaveDisk::vmpool->update(vm); @@ -137,16 +143,17 @@ error_vm_get: oss.str(get_error(method_name, "VM", vm_id)); goto error_common; +error_vm_get_disk_id: + oss.str(get_error(method_name, "DISK from VM", vm_id)); + goto error_common; + error_authenticate: oss.str(authenticate_error(method_name)); - goto error_common_lock; + goto error_common; error_authorize: oss.str(authorization_error(method_name, "MANAGE", "VM/IMAGE", rc, vm_id)); - goto error_common_lock; - -error_common_lock: - vm->unlock(); + goto error_common; error_common: arrayData.push_back(xmlrpc_c::value_boolean(false)); diff --git a/src/rm/RequestManagerUserInfo.cc b/src/rm/RequestManagerUserInfo.cc new file mode 100644 index 0000000000..4a1a347eea --- /dev/null +++ b/src/rm/RequestManagerUserInfo.cc @@ -0,0 +1,122 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#include "RequestManager.h" +#include "NebulaLog.h" + +#include "AuthManager.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void RequestManager::UserInfo::execute( + xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const retval) +{ + string session; + int the_uid, uid; + + User * user; + ostringstream oss; + + const string method_name = "UserInfo"; + + /* -- RPC specific vars -- */ + vector arrayData; + xmlrpc_c::value_array * arrayresult; + + NebulaLog::log("ReM",Log::DEBUG,"UserInfo method invoked"); + + // Get the parameters + session = xmlrpc_c::value_string(paramList.getString(0)); + the_uid = xmlrpc_c::value_int(paramList.getInt(1)); + + // Only oneadmin can retrieve user information + uid = UserInfo::upool->authenticate(session); + + if ( uid == -1 ) + { + goto error_authenticate; + } + + //Authorize the operation + if ( uid != 0 ) // uid == 0 means oneadmin + { + AuthRequest ar(uid); + + ar.add_auth(AuthRequest::USER, + the_uid, + AuthRequest::INFO, + 0, + false); + + if (UserPool::authorize(ar) == -1) + { + goto error_authorize; + } + } + // Now let's get the user + user = UserInfo::upool->get(the_uid,true); + + if ( user == 0 ) + { + goto error_get_user; + } + + oss << *user; + + user->unlock(); + + // All nice, return the new uid to client + arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS + arrayData.push_back(xmlrpc_c::value_string(oss.str())); + + // Copy arrayresult into retval mem space + arrayresult = new xmlrpc_c::value_array(arrayData); + *retval = *arrayresult; + + delete arrayresult; // and get rid of the original + + return; + +error_authenticate: + oss.str(authenticate_error(method_name)); + goto error_common; + +error_authorize: + oss.str(authorization_error(method_name, "INFO", "USER", uid, -1)); + goto error_common; + +error_get_user: + oss.str(get_error(method_name, "USER", the_uid)); + goto error_common; + +error_common: + + arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE + arrayData.push_back(xmlrpc_c::value_string(oss.str())); + + NebulaLog::log("ReM",Log::ERROR,oss); + + xmlrpc_c::value_array arrayresult_error(arrayData); + + *retval = arrayresult_error; + + return; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerVirtualNetworkDelete.cc b/src/rm/RequestManagerVirtualNetworkDelete.cc index d365f36ca3..4a44d445c2 100644 --- a/src/rm/RequestManagerVirtualNetworkDelete.cc +++ b/src/rm/RequestManagerVirtualNetworkDelete.cc @@ -25,7 +25,7 @@ void RequestManager::VirtualNetworkDelete::execute( xmlrpc_c::paramList const& paramList, xmlrpc_c::value * const retval) -{ +{ string session; string name; @@ -33,10 +33,13 @@ void RequestManager::VirtualNetworkDelete::execute( int uid; VirtualNetwork * vn; - - int rc; + + int network_owner; + bool is_public; + + int rc; ostringstream oss; - + const string method_name = "VirtualNetworkDelete"; /* -- RPC specific vars -- */ @@ -48,57 +51,75 @@ void RequestManager::VirtualNetworkDelete::execute( // Get the parameters & host session = xmlrpc_c::value_string(paramList.getString(0)); nid = xmlrpc_c::value_int (paramList.getInt (1)); - - // Only oneadmin or the VN owner can perform operations upon the VN + + // First, we need to authenticate the user rc = VirtualNetworkDelete::upool->authenticate(session); - - if ( rc == -1 ) - { - goto error_authenticate; + + if ( rc == -1 ) + { + goto error_authenticate; } - + + // Retrieve VN from the pool + vn = vnpool->get(nid,true); + + if ( vn == 0 ) + { + goto error_vn_get; + } + + network_owner = vn->get_uid(); + is_public = vn->isPublic(); + + vn->unlock(); + + //Authorize the operation if ( rc != 0 ) // rc == 0 means oneadmin { AuthRequest ar(rc); - ar.add_auth(AuthRequest::NET,nid,AuthRequest::DELETE,0,false); + ar.add_auth(AuthRequest::NET, + nid, + AuthRequest::DELETE, + network_owner, + is_public); if (UserPool::authorize(ar) == -1) { goto error_authorize; } } - - // Retrieve VN from the pool - vn = vnpool->get(nid,true); - - if ( vn == 0 ) - { - goto error_vn_get; + + // Retrieve VN from the pool + vn = vnpool->get(nid,true); + + if ( vn == 0 ) + { + goto error_vn_get; } uid = vn->get_uid(); - + rc = vnpool->drop(vn); vn->unlock(); - - // All nice, return the host info to the client + + // All nice, return the host info to the client arrayData.push_back(xmlrpc_c::value_boolean( rc == 0 )); // SUCCESS arrayresult = new xmlrpc_c::value_array(arrayData); - + // Copy arrayresult into retval mem space *retval = *arrayresult; // and get rid of the original delete arrayresult; - + return; error_authenticate: oss.str(authenticate_error(method_name)); goto error_common; - + error_authorize: oss.str(authorization_error(method_name, "DELETE", "NET", rc, nid)); goto error_common; @@ -106,17 +127,17 @@ error_authorize: error_vn_get: oss.str(get_error(method_name, "NET", nid)); goto error_common; - + error_common: NebulaLog::log ("ReM",Log::ERROR,oss); - + arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE arrayData.push_back(xmlrpc_c::value_string(oss.str())); - + xmlrpc_c::value_array arrayresult_error(arrayData); - + *retval = arrayresult_error; - + return; } diff --git a/src/rm/RequestManagerVirtualNetworkPoolInfo.cc b/src/rm/RequestManagerVirtualNetworkPoolInfo.cc index ba36bffaa5..964ff6c4de 100755 --- a/src/rm/RequestManagerVirtualNetworkPoolInfo.cc +++ b/src/rm/RequestManagerVirtualNetworkPoolInfo.cc @@ -23,7 +23,7 @@ void RequestManager::VirtualNetworkPoolInfo::execute( xmlrpc_c::paramList const& paramList, xmlrpc_c::value * const retval) -{ +{ string session; string username; string password; @@ -34,8 +34,6 @@ void RequestManager::VirtualNetworkPoolInfo::execute( int rc; int filter_flag; - User * user; - const string method_name = "VirtualNetworkPoolInfo"; /* -- RPC specific vars -- */ @@ -56,46 +54,37 @@ void RequestManager::VirtualNetworkPoolInfo::execute( goto error_authenticate; } - where_string.str(""); - /** Filter flag meaning table - * <=-2 :: ALL VMs - * -1 :: User's VMs - * >=0 :: UID User's VMs + * <=-2 :: ALL Networks + * -1 :: User's Networks plus Public ones + * >=0 :: UID User's Networks **/ - - // TODO define authorization (bug #278) - if (filter_flag == -1) + if ( filter_flag < -2 ) { - User::split_secret(session,username,password); - - // Now let's get the user - user = VirtualNetworkPoolInfo::upool->get(username,true); - - if ( user == 0 ) - { - goto error_get_user; - } - - where_string << "UID=" << user->get_uid(); - - user->unlock(); + goto error_filter_flag; + } + + switch(filter_flag) + { + case -2: + // TODO define authentication bug #278 + break; + case -1: + where_string << "UID=" << rc << " OR PUBLIC=1"; + break; + default: + where_string << "UID=" << filter_flag; } - else if (filter_flag>=0) - { - where_string << "UID=" << filter_flag; - } - // Perform the allocation in the vmpool rc = VirtualNetworkPoolInfo::vnpool->dump(oss,where_string.str()); - + if ( rc != 0 ) - { + { goto error_dump; } - - //All nice, return the host info to the client - arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS + + //All nice, return the host info to the client + arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS arrayData.push_back(xmlrpc_c::value_string(oss.str())); arrayresult = new xmlrpc_c::value_array(arrayData); @@ -112,25 +101,25 @@ error_authenticate: oss.str(authenticate_error(method_name)); goto error_common; -error_get_user: - oss.str(get_error(method_name, "USER", -1)); +error_filter_flag: + oss << "Incorrect filter_flag, must be >= -2."; goto error_common; error_dump: - oss.str(get_error(method_name, "HOST", -1)); + oss.str(get_error(method_name, "NETWORK", -1)); goto error_common; error_common: arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE arrayData.push_back(xmlrpc_c::value_string(oss.str())); - - NebulaLog::log("ReM",Log::ERROR,oss); - + + NebulaLog::log("ReM",Log::ERROR,oss); + xmlrpc_c::value_array arrayresult_error(arrayData); *retval = arrayresult_error; - + return; } diff --git a/src/rm/RequestManagerVirtualNetworkPublish.cc b/src/rm/RequestManagerVirtualNetworkPublish.cc index c8d0befb6e..8c3011f959 100644 --- a/src/rm/RequestManagerVirtualNetworkPublish.cc +++ b/src/rm/RequestManagerVirtualNetworkPublish.cc @@ -31,11 +31,14 @@ void RequestManager::VirtualNetworkPublish::execute( string session; int nid; - bool publish_flag; + bool publish_flag; int uid; - + VirtualNetwork * vn; + int network_owner; + bool is_public; + ostringstream oss; const string method_name = "VirtualNetworkPublish"; @@ -57,15 +60,20 @@ void RequestManager::VirtualNetworkPublish::execute( { goto error_authenticate; } - + // Get virtual network from the VirtualNetworkPool - vn = VirtualNetworkPublish::vnpool->get(nid,true); - - if ( vn == 0 ) - { - goto error_vn_get; + vn = VirtualNetworkPublish::vnpool->get(nid,true); + + if ( vn == 0 ) + { + goto error_vn_get; } - + + network_owner = vn->get_uid(); + is_public = vn->isPublic(); + + vn->unlock(); + //Authorize the operation if ( uid != 0 ) // uid == 0 means oneadmin { @@ -74,8 +82,8 @@ void RequestManager::VirtualNetworkPublish::execute( ar.add_auth(AuthRequest::NET, nid, AuthRequest::MANAGE, - 0, - vn->isPublic()); + network_owner, + is_public); if (UserPool::authorize(ar) == -1) { @@ -83,10 +91,18 @@ void RequestManager::VirtualNetworkPublish::execute( } } + // Get virtual network from the VirtualNetworkPool + vn = VirtualNetworkPublish::vnpool->get(nid,true); + + if ( vn == 0 ) + { + goto error_vn_get; + } + vn->publish(publish_flag); - + VirtualNetworkPublish::vnpool->update(vn); - + vn->unlock(); arrayData.push_back(xmlrpc_c::value_boolean(true)); @@ -103,11 +119,11 @@ void RequestManager::VirtualNetworkPublish::execute( error_authenticate: oss.str(authenticate_error(method_name)); goto error_common; - + error_vn_get: oss.str(get_error(method_name, "NET", nid)); goto error_common; - + error_authorize: oss.str(authorization_error(method_name, "MANAGE", "NET", uid, nid)); vn->unlock(); diff --git a/src/rm/SConstruct b/src/rm/SConstruct index 42a9da1f83..f1a27a45e5 100644 --- a/src/rm/SConstruct +++ b/src/rm/SConstruct @@ -58,6 +58,7 @@ source_files=[ 'RequestManagerUserAllocate.cc', 'RequestManagerUserDelete.cc', 'RequestManagerUserChangePassword.cc', + 'RequestManagerUserInfo.cc', 'RequestManagerUserPoolInfo.cc' ] diff --git a/src/scheduler/SConstruct b/src/scheduler/SConstruct index 98f78d6cb4..4c78abb358 100644 --- a/src/scheduler/SConstruct +++ b/src/scheduler/SConstruct @@ -55,7 +55,7 @@ main_env.Append(CPPFLAGS=[ ]) # Linking flags -main_env.Append(LINKFLAGS=["-g"]) +main_env.Append(LINKFLAGS=['-g', '-pthread']) ################################################################################ # EXTRA CONFIGURATION diff --git a/src/scheduler/src/pool/test/HostXMLTest.cc b/src/scheduler/src/pool/test/HostXMLTest.cc index 1fbca65e84..e178097976 100644 --- a/src/scheduler/src/pool/test/HostXMLTest.cc +++ b/src/scheduler/src/pool/test/HostXMLTest.cc @@ -31,6 +31,8 @@ #include "ObjectXML.h" #include "HostPoolXML.h" +#include "test/one_test_common.h" + /* ************************************************************************* */ /* ************************************************************************* */ @@ -263,10 +265,15 @@ int main(int argc, char ** argv) CppUnit::TextUi::TestRunner runner; + SETUP_XML_WRITER(runner, "HostXMLTest.xml") + runner.addTest(HostXMLTest::suite()); runner.run(); + END_XML_WRITER + + // remove("test.log"); NebulaLog::finalize_log_system(); diff --git a/src/scheduler/src/pool/test/VirtualMachineXMLTest.cc b/src/scheduler/src/pool/test/VirtualMachineXMLTest.cc index 9b446e9eeb..aac5f1750b 100644 --- a/src/scheduler/src/pool/test/VirtualMachineXMLTest.cc +++ b/src/scheduler/src/pool/test/VirtualMachineXMLTest.cc @@ -32,6 +32,8 @@ #include "VirtualMachinePoolXML.h" #include "HostPoolXML.h" +#include "test/one_test_common.h" + /* ************************************************************************* */ /* ************************************************************************* */ @@ -317,9 +319,13 @@ int main(int argc, char ** argv) CppUnit::TextUi::TestRunner runner; + SETUP_XML_WRITER(runner, "VirtualMachineXMLTest.xml") + runner.addTest(VirtualMachineXMLTest::suite()); runner.run(); + END_XML_WRITER + remove("test.log"); NebulaLog::finalize_log_system(); diff --git a/src/scheduler/src/xml/expr_bool.cc b/src/scheduler/src/xml/expr_bool.cc index d1b86f1d85..0d9c80598f 100644 --- a/src/scheduler/src/xml/expr_bool.cc +++ b/src/scheduler/src/xml/expr_bool.cc @@ -1,9 +1,9 @@ -/* A Bison parser, made by GNU Bison 2.4.2. */ +/* A Bison parser, made by GNU Bison 2.4.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software - Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -45,7 +45,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.4.2" +#define YYBISON_VERSION "2.4.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -1243,7 +1243,7 @@ YYLTYPE yylloc; YYLTYPE *yylsp; /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; + YYLTYPE yyerror_range[3]; YYSIZE_T yystacksize; @@ -1556,7 +1556,7 @@ yyreduce: /* Line 1464 of yacc.c */ #line 137 "expr_bool.y" - {float val; + { float val; get_xml_attribute(oxml,(yyvsp[(1) - (3)].val_str),val); (yyval.val_int) = val > (yyvsp[(3) - (3)].val_float);;} @@ -1566,7 +1566,7 @@ yyreduce: /* Line 1464 of yacc.c */ #line 142 "expr_bool.y" - {float val; + { float val; get_xml_attribute(oxml,(yyvsp[(1) - (3)].val_str),val); (yyval.val_int) = val < (yyvsp[(3) - (3)].val_float);;} @@ -1579,7 +1579,7 @@ yyreduce: { string val; get_xml_attribute(oxml,(yyvsp[(1) - (3)].val_str),val); - (yyval.val_int) = val.empty() ? false :fnmatch((yyvsp[(3) - (3)].val_str), val.c_str(), 0) == 0;;} + (yyval.val_int) = (val.empty() || (yyvsp[(3) - (3)].val_str)==0) ? false : fnmatch((yyvsp[(3) - (3)].val_str),val.c_str(),0)==0;;} break; case 13: @@ -1589,7 +1589,7 @@ yyreduce: { string val; get_xml_attribute(oxml,(yyvsp[(1) - (4)].val_str),val); - (yyval.val_int) = val.empty() ? false : fnmatch((yyvsp[(4) - (4)].val_str), val.c_str(), 0) != 0;;} + (yyval.val_int) = (val.empty() || (yyvsp[(4) - (4)].val_str)==0) ? false : fnmatch((yyvsp[(4) - (4)].val_str),val.c_str(),0)!=0;;} break; case 14: @@ -1695,7 +1695,7 @@ yyerrlab: #endif } - yyerror_range[0] = yylloc; + yyerror_range[1] = yylloc; if (yyerrstatus == 3) { @@ -1732,7 +1732,7 @@ yyerrorlab: if (/*CONSTCOND*/ 0) goto yyerrorlab; - yyerror_range[0] = yylsp[1-yylen]; + yyerror_range[1] = yylsp[1-yylen]; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); @@ -1766,7 +1766,7 @@ yyerrlab1: if (yyssp == yyss) YYABORT; - yyerror_range[0] = *yylsp; + yyerror_range[1] = *yylsp; yydestruct ("Error: popping", yystos[yystate], yyvsp, yylsp, mc, oxml, result, error_msg); YYPOPSTACK (1); @@ -1776,10 +1776,10 @@ yyerrlab1: *++yyvsp = yylval; - yyerror_range[1] = yylloc; + yyerror_range[2] = yylloc; /* Using YYLLOC is tempting, but would change the location of the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + YYLLOC_DEFAULT (yyloc, yyerror_range, 2); *++yylsp = yyloc; /* Shift the error token. */ diff --git a/src/scheduler/src/xml/expr_bool.h b/src/scheduler/src/xml/expr_bool.h index 41d20a621f..3e0c95e1f6 100644 --- a/src/scheduler/src/xml/expr_bool.h +++ b/src/scheduler/src/xml/expr_bool.h @@ -1,9 +1,9 @@ -/* A Bison parser, made by GNU Bison 2.4.2. */ +/* A Bison parser, made by GNU Bison 2.4.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software - Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/scheduler/src/xml/expr_bool.y b/src/scheduler/src/xml/expr_bool.y index 0a1bb7199c..fc7adc891d 100644 --- a/src/scheduler/src/xml/expr_bool.y +++ b/src/scheduler/src/xml/expr_bool.y @@ -134,12 +134,12 @@ expr: STRING '=' INTEGER { int val; get_xml_attribute(oxml,$1,val); $$ = val != $4;} - | STRING '>' FLOAT {float val; + | STRING '>' FLOAT { float val; get_xml_attribute(oxml,$1,val); $$ = val > $3;} - | STRING '<' FLOAT {float val; + | STRING '<' FLOAT { float val; get_xml_attribute(oxml,$1,val); $$ = val < $3;} @@ -147,12 +147,12 @@ expr: STRING '=' INTEGER { int val; | STRING '=' STRING { string val; get_xml_attribute(oxml,$1,val); - $$ = val.empty() ? false :fnmatch($3, val.c_str(), 0) == 0;} + $$ = (val.empty() || $3==0) ? false : fnmatch($3,val.c_str(),0)==0;} | STRING '!''=' STRING { string val; get_xml_attribute(oxml,$1,val); - $$ = val.empty() ? false : fnmatch($4, val.c_str(), 0) != 0;} + $$ = (val.empty() || $4==0) ? false : fnmatch($4,val.c_str(),0)!=0;} | expr '&' expr { $$ = $1 && $3; } | expr '|' expr { $$ = $1 || $3; } diff --git a/src/scheduler/src/xml/test/ObjectXMLTest.cc b/src/scheduler/src/xml/test/ObjectXMLTest.cc index 8a3ef1b809..6652e0e765 100644 --- a/src/scheduler/src/xml/test/ObjectXMLTest.cc +++ b/src/scheduler/src/xml/test/ObjectXMLTest.cc @@ -30,6 +30,8 @@ #include "ObjectXML.h" +#include "test/one_test_common.h" + /* ************************************************************************* */ /* ************************************************************************* */ @@ -331,9 +333,13 @@ int main(int argc, char ** argv) { CppUnit::TextUi::TestRunner runner; + SETUP_XML_WRITER(runner, "ObjectXMLTest.xml"); + runner.addTest(ObjectXMLTest::suite()); runner.run(); + END_XML_WRITER + return 0; } diff --git a/src/scheduler/src/xml/test/SConstruct b/src/scheduler/src/xml/test/SConstruct index f17f7e4cf6..d750c4e7c5 100644 --- a/src/scheduler/src/xml/test/SConstruct +++ b/src/scheduler/src/xml/test/SConstruct @@ -29,6 +29,7 @@ main_env['ENV']['PATH']=os.environ['PATH'] # Include dirs main_env.Append(CPPPATH=[ cwd+'/../../../include', + cwd+'/../../../../../include', '/usr/include/cppunit/' ]) diff --git a/src/template/test/template.cc b/src/template/test/template.cc index dfdd060a18..bcab8f6ba4 100644 --- a/src/template/test/template.cc +++ b/src/template/test/template.cc @@ -9,6 +9,8 @@ #include #include +#include "test/one_test_common.h" + using namespace std; /* ************************************************************************* */ @@ -64,13 +66,13 @@ public: ""; test_ok_str= - "\n\tCPU=4" - "\n\tDISK=EXTRA=disk attribute ,FILE=path1" - "\n\tDISK=EXTRA=str,FILE=path2,TYPE=disk" - "\n\tEMPTY_VAR=" - "\n\tGRAPHICS=PORT=12,VNC=127.0.0.1" - "\n\tMEMORY=345" - "\n\tREQUIREMENTS=HOSTNAME = \"host*.com\""; + "CPU=4\n" + "DISK=EXTRA=disk attribute ,FILE=path1\n" + "DISK=EXTRA=str,FILE=path2,TYPE=disk\n" + "EMPTY_VAR=\n" + "GRAPHICS=PORT=12,VNC=127.0.0.1\n" + "MEMORY=345\n" + "REQUIREMENTS=HOSTNAME = \"host*.com\"\n"; } ~TemplateTest(){}; @@ -400,8 +402,12 @@ int main(int argc, char ** argv) { CppUnit::TextUi::TestRunner tr; + SETUP_XML_WRITER(tr, "template.xml") + tr.addTest(TemplateTest::suite()); tr.run(); + END_XML_WRITER + return 0; } diff --git a/src/tm_mad/nfs/tm_clone.sh b/src/tm_mad/nfs/tm_clone.sh index 2bba596e24..f1a904ab6c 100755 --- a/src/tm_mad/nfs/tm_clone.sh +++ b/src/tm_mad/nfs/tm_clone.sh @@ -51,7 +51,7 @@ http://*) *) log "Cloning $SRC_PATH" - exec_and_log "cp $SRC_PATH $DST_PATH" + exec_and_log "cp -r $SRC_PATH $DST_PATH" ;; esac diff --git a/src/tm_mad/tm_common.sh b/src/tm_mad/tm_common.sh index aff902102c..32628fb7b1 100644 --- a/src/tm_mad/tm_common.sh +++ b/src/tm_mad/tm_common.sh @@ -42,26 +42,44 @@ WGET=/usr/bin/wget function get_vmdir { VMDIR=`grep '^VM_DIR=' $ONE_LOCAL_VAR/config | cut -d= -f2` + fix_var_slashes +} + +# Takes out uneeded slashes. Repeated and final directory slashes: +# /some//path///somewhere/ -> /some/path/somewhere +function fix_dir_slashes +{ + dirname "$1/file" | sed -E 's/\/+/\//g' +} + +function fix_var_slashes +{ + ONE_LOCAL_VAR=`fix_dir_slashes "$ONE_LOCAL_VAR"` + VMDIR=`fix_dir_slashes "$VMDIR"` } function fix_paths { - if [ -n "$VMDIR" ]; then + if [ "x$ONE_LOCAL_VAR" != "x$VMDIR" ]; then + SRC_PATH=`fix_dir_slashes "$SRC_PATH"` SRC_PATH=${SRC_PATH/$VMDIR/$ONE_LOCAL_VAR} + DST_PATH=`fix_dir_slashes "$DST_PATH"` DST_PATH=${DST_PATH/$VMDIR/$ONE_LOCAL_VAR} fi } function fix_src_path { - if [ -n "$VMDIR" ]; then + if [ "x$ONE_LOCAL_VAR" != "x$VMDIR" ]; then + SRC_PATH=`fix_dir_slashes "$SRC_PATH"` SRC_PATH=${SRC_PATH/$VMDIR/$ONE_LOCAL_VAR} fi } function fix_dst_path { - if [ -n "$VMDIR" ]; then + if [ "x$ONE_LOCAL_VAR" != "x$VMDIR" ]; then + DST_PATH=`fix_dir_slashes "$DST_PATH"` DST_PATH=${DST_PATH/$VMDIR/$ONE_LOCAL_VAR} fi } diff --git a/src/tm_mad/vmware/tm_clone.sh b/src/tm_mad/vmware/tm_clone.sh deleted file mode 100755 index d099beb7b3..0000000000 --- a/src/tm_mad/vmware/tm_clone.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -SRC=$1 -DST=$2 - -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/usr/lib/one/mads/tm_common.sh -else - TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh -fi - -. $TMCOMMON - -SRC_PATH=`arg_path $SRC` - -log "$1 $2" - -case $SRC in -http://*) - log "Downloading $SRC" - exec_and_log "$SSH $DST_HOST $WGET -O $DST_PATH $SRC_PATH" - ;; - -*) - log "Cloning $SRC" - VM_ID=`echo $DST | $SED -e 's/.*\/\([0-9]\+\)\/images\/.*/\1/'` - cp -r $SRC_PATH $DATASTORE_PATH/one-$VM_ID &>/dev/null - mv $DATASTORE_PATH/one-$VM_ID/*.vmx $DATASTORE_PATH/one-$VM_ID/one-$VM_ID.vmx - ;; -esac - - diff --git a/src/tm_mad/vmware/tm_vmware.conf b/src/tm_mad/vmware/tm_vmware.conf deleted file mode 100644 index 7930a3b12f..0000000000 --- a/src/tm_mad/vmware/tm_vmware.conf +++ /dev/null @@ -1,6 +0,0 @@ -CLONE = vmware/tm_clone.sh -LN = dummy/tm_dummy.sh -MKSWAP = dummy/tm_dummy.sh -MKIMAGE = dummy/tm_dummy.sh -DELETE = vmware/tm_delete.sh -MV = dummy/tm_dummy.sh diff --git a/src/um/User.cc b/src/um/User.cc index 6c2c077183..52a70f6bc1 100644 --- a/src/um/User.cc +++ b/src/um/User.cc @@ -216,14 +216,12 @@ int User::dump(ostringstream& oss, int num, char **values, char **names) return -1; } - string str_enabled = (atoi(values[ENABLED])==0)?"Fase":"True"; - oss << "" << "" << values[OID] <<"" << "" << values[USERNAME]<<"" << ""<< values[PASSWORD]<<""<< - "" << str_enabled <<"" << + "" << values[ENABLED] <<"" << ""; return 0; diff --git a/src/um/test/UserPoolTest.cc b/src/um/test/UserPoolTest.cc index fb79eb878d..81388609a0 100644 --- a/src/um/test/UserPoolTest.cc +++ b/src/um/test/UserPoolTest.cc @@ -32,24 +32,24 @@ const string passwords[] = { "A pass", "B pass", "C pass", "D pass", "E pass" }; const string dump_result = "0one_user_test" "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" - "True1a" - "pTrue" + "11a" + "p1" "2a namepass" - "True3a_name" - "passwordTrue" + "13a_name" + "password1" "4another namesecret" - "True5user" - "1234True" + "15user" + "12341" ""; const string dump_where_result = "1a" - "pTrue" + "p1" "2a namepass" - "True3a_name" - "passwordTrue" + "13a_name" + "password1" "4another namesecret" - "True"; + "1"; class UserPoolTest : public PoolTest { diff --git a/src/vmm/LibVirtDriver.cc b/src/vmm/LibVirtDriverKVM.cc similarity index 99% rename from src/vmm/LibVirtDriver.cc rename to src/vmm/LibVirtDriverKVM.cc index c55468defd..f40ebbca98 100644 --- a/src/vmm/LibVirtDriver.cc +++ b/src/vmm/LibVirtDriverKVM.cc @@ -19,13 +19,12 @@ #include "Nebula.h" #include #include +#include - -int LibVirtDriver::deployment_description( - const VirtualMachine * vm, - const string& file_name) const +int LibVirtDriver::deployment_description_kvm( + const VirtualMachine * vm, + const string& file_name) const { - ofstream file; int num; @@ -588,3 +587,4 @@ error_disk: file.close(); return -1; } + diff --git a/src/vmm/LibVirtDriverVMware.cc b/src/vmm/LibVirtDriverVMware.cc new file mode 100644 index 0000000000..1429d73c46 --- /dev/null +++ b/src/vmm/LibVirtDriverVMware.cc @@ -0,0 +1,386 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#include "LibVirtDriver.h" + +#include "Nebula.h" +#include +#include +#include + +int LibVirtDriver::deployment_description_vmware( + const VirtualMachine * vm, + const string& file_name) const +{ + ofstream file; + + int num; + vector attrs; + + string vcpu; + string memory; + + int memory_in_kb = 0; + + string arch = ""; + + const VectorAttribute * disk; + const VectorAttribute * context; + + string type = ""; + string target = ""; + string bus = ""; + string ro = ""; + string source = ""; + string datastore = ""; + bool readonly; + + const VectorAttribute * nic; + + string mac = ""; + string bridge = ""; + string script = ""; + string model = ""; + + const VectorAttribute * raw; + string data; + + // ------------------------------------------------------------------------ + + file.open(file_name.c_str(), ios::out); + + if (file.fail() == true) + { + goto error_vmware_file; + } + + // ------------------------------------------------------------------------ + // Starting XML document + // ------------------------------------------------------------------------ + + file << "" << endl; + + // ------------------------------------------------------------------------ + // Domain name + // ------------------------------------------------------------------------ + + file << "\tone-" << vm->get_oid() << "" << endl; + + // ------------------------------------------------------------------------ + // CPU + // ------------------------------------------------------------------------ + + vm->get_template_attribute("VCPU", vcpu); + + if(vcpu.empty()) + { + get_default("VCPU", vcpu); + } + + if (!vcpu.empty()) + { + file << "\t" << vcpu << "" << endl; + } + + // ------------------------------------------------------------------------ + // Memory + // ------------------------------------------------------------------------ + + vm->get_template_attribute("MEMORY",memory); + + if (memory.empty()) + { + get_default("MEMORY",memory); + } + + if (!memory.empty()) + { + memory_in_kb = atoi(memory.c_str()) * 1024; + + file << "\t" << memory_in_kb << "" << endl; + } + else + { + goto error_vmware_memory; + } + + // ------------------------------------------------------------------------ + // OS and boot options + // ------------------------------------------------------------------------ + + num = vm->get_template_attribute("OS",attrs); + + // Get values & defaults + if ( num > 0 ) + { + const VectorAttribute * os; + + os = dynamic_cast(attrs[0]); + + if( os != 0 ) + { + arch = os->vector_value("ARCHITECTURE"); + } + } + + + // Start writing to the file with the info we got + + file << "\t" << endl; + + + if ( arch.empty() ) + { + get_default("OS","ARCHITECTURE",arch); + } + + if (arch.empty()) + { + goto error_vmware_arch; + } + + file << "\t\thvm" << endl; + + file << "\t" << endl; + + attrs.clear(); + + // ------------------------------------------------------------------------ + // Disks + // ------------------------------------------------------------------------ + + file << "\t" << endl; + + num = vm->get_template_attribute("DISK",attrs); + + if (num!=0) + { + get_default("DATASTORE", datastore); + } + + for (int i=0; i < num ;i++) + { + disk = dynamic_cast(attrs[i]); + + if ( disk == 0 ) + { + continue; + } + + type = disk->vector_value("TYPE"); + target = disk->vector_value("TARGET"); + ro = disk->vector_value("READONLY"); + bus = disk->vector_value("BUS"); + source = disk->vector_value("SOURCE"); + + if (target.empty()) + { + goto error_vmware_disk; + } + + readonly = false; + + if ( !ro.empty() ) + { + transform(ro.begin(),ro.end(),ro.begin(),(int(*)(int))toupper); + + if ( ro == "YES" ) + { + readonly = true; + } + } + + if (type.empty() == false) + { + transform(type.begin(),type.end(),type.begin(),(int(*)(int))toupper); + } + + if ( type == "BLOCK" ) + { + file << "\t\t" << endl; + file << "\t\t\t" << endl; + } + else if ( type == "CDROM" ) + { + file << "\t\t" << endl; + file << "\t\t\t" << endl; + } + else + { + file << "\t\t" << endl + << "\t\t\t" << endl; + } + + file << "\t\t\t" << endl; + } + else + { + file << "/>" << endl; + } + + if (readonly) + { + file << "\t\t\t" << endl; + } + + file << "\t\t" << endl; + } + + attrs.clear(); + + // ------------------------------------------------------------------------ + // Context Device + // ------------------------------------------------------------------------ + + if ( vm->get_template_attribute("CONTEXT",attrs) == 1 ) + { + context = dynamic_cast(attrs[0]); + target = context->vector_value("TARGET"); + + if ( !target.empty() ) + { + file << "\t\t" << endl; + file << "\t\t\t" << endl; + file << "\t\t\t" << endl; + file << "\t\t\t" << endl; + file << "\t\t" << endl; + } + else + { + vm->log("VMM", Log::WARNING, "Could not find target device to" + " attach context, will continue without it."); + } + } + + attrs.clear(); + + // ------------------------------------------------------------------------ + // Network interfaces + // ------------------------------------------------------------------------ + + num = vm->get_template_attribute("NIC",attrs); + + for(int i=0; i(attrs[i]); + + if ( nic == 0 ) + { + continue; + } + + bridge = nic->vector_value("BRIDGE"); + mac = nic->vector_value("MAC"); + target = nic->vector_value("TARGET"); + script = nic->vector_value("SCRIPT"); + model = nic->vector_value("MODEL"); + + if ( bridge.empty() ) + { + file << "\t\t" << endl; + } + else + { + file << "\t\t" << endl; + file << "\t\t\t" << endl; + } + + if( !mac.empty() ) + { + file << "\t\t\t" << endl; + } + + if( !target.empty() ) + { + file << "\t\t\t" << endl; + } + + if( !script.empty() ) + { + file << "\t\t\t