diff --git a/README b/README new file mode 100644 index 0000000000..20db33daaf --- /dev/null +++ b/README @@ -0,0 +1,135 @@ + +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 + + +## 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/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/install.sh b/install.sh index ecbbf07355..9ea116bf62 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" @@ -228,6 +232,7 @@ 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" @@ -587,6 +592,18 @@ 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" + #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # INSTALL.SH SCRIPT diff --git a/share/man/oneauth.8.gz b/share/man/oneauth.8.gz new file mode 100644 index 0000000000..82e9a396f0 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..dfdf2ef1bd 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..417ea78895 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..ab7dcd0355 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..f216029883 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..bdbf313fe2 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..9ce807284b Binary files /dev/null and b/share/man/onevnet.8.gz differ diff --git a/src/authm_mad/oneauth b/src/authm_mad/oneauth index 4aeafb1674..435c0aac38 100755 --- a/src/authm_mad/oneauth +++ b/src/authm_mad/oneauth @@ -38,6 +38,7 @@ require 'sequel' require 'quota' require 'ssh_auth' require 'client_utilities' +require 'command_parse' COMMANDS_HELP=<<-EOT @@ -129,6 +130,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 b43c865b6d..935d3f81b5 100644 --- a/src/cli/command_parse.rb +++ b/src/cli/command_parse.rb @@ -33,6 +33,10 @@ EOT ONE_VERSION=<<-EOT OpenNebula 1.9.85 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/oneimage b/src/cli/oneimage index eafbcc0e8b..7b06df07b9 100755 --- a/src/cli/oneimage +++ b/src/cli/oneimage @@ -239,6 +239,7 @@ Commands: where filter_flag can be 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 diff --git a/src/cli/onevnet b/src/cli/onevnet index b45f4bb249..4f7a7d9c92 100755 --- a/src/cli/onevnet +++ b/src/cli/onevnet @@ -161,6 +161,7 @@ Commands: where filter_flag can be 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 EOT diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index 094c267292..1f3c31f63b 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -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/test.sh b/src/oca/java/test/test.sh new file mode 100755 index 0000000000..849649fefd --- /dev/null +++ b/src/oca/java/test/test.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# Usage: test.sh +# For instance: test.sh ImageTest + +JUNIT_JAR="/usr/share/java/junit4.jar" +ONEDB="$ONE_LOCATION/var/one.db" + + +oned +sleep 4s; + +java -cp ../lib/*:../jar/*:$JUNIT_JAR:. org.junit.runner.JUnitCore $1 + +pkill oned; +sleep 4s; +pkill -9 oned; +rm $ONEDB diff --git a/src/oca/ruby/test/User_spec.rb b/src/oca/ruby/test/User_spec.rb index 1a4085d4e2..a02911f03e 100644 --- a/src/oca/ruby/test/User_spec.rb +++ b/src/oca/ruby/test/User_spec.rb @@ -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/fixtures/user.xml b/src/oca/ruby/test/fixtures/user.xml index eab4482685..62749e8b6e 100644 --- a/src/oca/ruby/test/fixtures/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/fixtures/userpool.xml b/src/oca/ruby/test/fixtures/userpool.xml index d6d5565131..1f61bcfb96 100644 --- a/src/oca/ruby/test/fixtures/userpool.xml +++ b/src/oca/ruby/test/fixtures/userpool.xml @@ -3,12 +3,12 @@ 0 oneadmin f13a1234833436f71ab846572d251c0d40391e72 - True + 0 1 dan d22a12348334v33f71ba846572d25250d40701e72 - False + 0 \ No newline at end of file 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/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/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/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 {